void NWWriter_DlrNavteq::writeLinksUnsplitted(const OptionsCont& oc, NBEdgeCont& ec) { std::map<const std::string, std::string> nameIDs; OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_links_unsplitted.txt"); writeHeader(device, oc); // write format specifier device << "# LINK_ID\tNODE_ID_FROM\tNODE_ID_TO\tBETWEEN_NODE_ID\tLENGTH\tVEHICLE_TYPE\tFORM_OF_WAY\tBRUNNEL_TYPE\tFUNCTIONAL_ROAD_CLASS\tSPEED_CATEGORY\tNUMBER_OF_LANES\tSPEED_LIMIT\tSPEED_RESTRICTION\tNAME_ID1_REGIONAL\tNAME_ID2_LOCAL\tHOUSENUMBERS_RIGHT\tHOUSENUMBERS_LEFT\tZIP_CODE\tAREA_ID\tSUBAREA_ID\tTHROUGH_TRAFFIC\tSPECIAL_RESTRICTIONS\tEXTENDED_NUMBER_OF_LANES\tISRAMP\tCONNECTION\n"; // write edges for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { NBEdge* e = (*i).second; const int kph = speedInKph(e->getSpeed()); const std::string& betweenNodeID = (e->getGeometry().size() > 2) ? e->getID() : UNDEFINED; std::string nameID = UNDEFINED; if (oc.getBool("output.street-names")) { const std::string& name = i->second->getStreetName(); if (name != "" && nameIDs.count(name) == 0) { nameID = toString(nameIDs.size()); nameIDs[name] = nameID; } } device << e->getID() << "\t" << e->getFromNode()->getID() << "\t" << e->getToNode()->getID() << "\t" << betweenNodeID << "\t" << getGraphLength(e) << "\t" << getAllowedTypes(e->getPermissions()) << "\t" << "3\t" // Speed Category 1-8 XXX refine this << UNDEFINED << "\t" // no special brunnel type (we don't know yet) << getRoadClass(e) << "\t" << getSpeedCategory(kph) << "\t" << getNavteqLaneCode(e->getNumLanes()) << "\t" << getSpeedCategoryUpperBound(kph) << "\t" << kph << "\t" << nameID << "\t" // NAME_ID1_REGIONAL XXX << UNDEFINED << "\t" // NAME_ID2_LOCAL XXX << UNDEFINED << "\t" // housenumbers_right << UNDEFINED << "\t" // housenumbers_left << UNDEFINED << "\t" // ZIP_CODE << UNDEFINED << "\t" // AREA_ID << UNDEFINED << "\t" // SUBAREA_ID << "1\t" // through_traffic (allowed) << UNDEFINED << "\t" // special_restrictions << UNDEFINED << "\t" // extended_number_of_lanes << UNDEFINED << "\t" // isRamp << "0\t" // connection (between nodes always in order) << "\n"; } if (oc.getBool("output.street-names")) { OutputDevice& namesDevice = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_names.txt"); writeHeader(namesDevice, oc); // write format specifier namesDevice << "# NAME_ID\tName\n" << nameIDs.size() << "\n"; for (std::map<const std::string, std::string>::const_iterator i = nameIDs.begin(); i != nameIDs.end(); ++i) { namesDevice << i->second << "\t" << i->first << "\n"; } } }
void NWWriter_XML::writeStreetSigns(const OptionsCont& oc, NBEdgeCont& ec) { OutputDevice& device = OutputDevice::getDevice(oc.getString("street-sign-output")); device.writeXMLHeader("pois", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/poi_file.xsd\""); for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { NBEdge* e = (*i).second; const std::vector<NBSign>& signs = e->getSigns(); for (std::vector<NBSign>::const_iterator it = signs.begin(); it != signs.end(); ++it) { it->writeAsPOI(device, e); } } device.close(); }
void NWWriter_DlrNavteq::writeNodesUnsplitted(const OptionsCont& oc, NBNodeCont& nc, NBEdgeCont& ec) { // For "real" nodes we simply use the node id. // For internal nodes (geometry vectors describing edge geometry in the parlance of this format) // we use the id of the edge and do not bother with // compression (each direction gets its own internal node). // XXX add option for generating numerical ids in case the input network has string ids and the target process needs integers OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_nodes_unsplitted.txt"); writeHeader(device, oc); const GeoConvHelper& gch = GeoConvHelper::getFinal(); const bool haveGeo = gch.usingGeoProjection(); const SUMOReal geoScale = pow(10.0f, haveGeo ? 5 : 2); // see NIImporter_DlrNavteq::GEO_SCALE device.setPrecision(0); if (!haveGeo) { WRITE_WARNING("DlrNavteq node data will be written in (floating point) cartesian coordinates"); } // write format specifier device << "# NODE_ID\tIS_BETWEEN_NODE\tamount_of_geocoordinates\tx1\ty1\t[x2 y2 ... xn yn]\n"; // write normal nodes for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { NBNode* n = (*i).second; Position pos = n->getPosition(); gch.cartesian2geo(pos); pos.mul(geoScale); device << n->getID() << "\t0\t1\t" << pos.x() << "\t" << pos.y() << "\n"; } // write "internal" nodes for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { NBEdge* e = (*i).second; const PositionVector& geom = e->getGeometry(); if (geom.size() > 2) { std::string internalNodeID = e->getID(); if (internalNodeID == UNDEFINED || (nc.retrieve(internalNodeID) != 0)) { // need to invent a new name to avoid clashing with the id of a 'real' node or a reserved name internalNodeID += "_geometry"; } device << internalNodeID << "\t1\t" << geom.size() - 2; for (size_t ii = 1; ii < geom.size() - 1; ++ii) { Position pos = geom[(int)ii]; gch.cartesian2geo(pos); pos.mul(geoScale); device << "\t" << pos.x() << "\t" << pos.y(); } device << "\n"; } } device.close(); }
void NWWriter_XML::writeTrafficLights(const OptionsCont& oc, NBTrafficLightLogicCont& tc, NBEdgeCont& ec) { OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".tll.xml"); device.writeXMLHeader("tlLogics", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/tllogic_file.xsd\""); NWWriter_SUMO::writeTrafficLights(device, tc); // we also need to remember the associations between tlLogics and connections // since the information in con.xml is insufficient for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { NBEdge* e = (*i).second; // write this edge's tl-controlled connections const std::vector<NBEdge::Connection> connections = e->getConnections(); for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) { if (c->tlID != "") { NWWriter_SUMO::writeConnection(device, *e, *c, false, NWWriter_SUMO::TLL); } } } device.close(); }
void NWWriter_DlrNavteq::writeNodesUnsplitted(const OptionsCont& oc, NBNodeCont& nc, NBEdgeCont& ec, std::map<NBEdge*, std::string>& internalNodes) { // For "real" nodes we simply use the node id. // For internal nodes (geometry vectors describing edge geometry in the parlance of this format) // we use the id of the edge and do not bother with // compression (each direction gets its own internal node). OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_nodes_unsplitted.txt"); writeHeader(device, oc); const GeoConvHelper& gch = GeoConvHelper::getFinal(); const bool haveGeo = gch.usingGeoProjection(); const double geoScale = pow(10.0f, haveGeo ? 5 : 2); // see NIImporter_DlrNavteq::GEO_SCALE device.setPrecision(oc.getInt("dlr-navteq.precision")); if (!haveGeo) { WRITE_WARNING("DlrNavteq node data will be written in (floating point) cartesian coordinates"); } // write format specifier device << "# NODE_ID\tIS_BETWEEN_NODE\tamount_of_geocoordinates\tx1\ty1\t[x2 y2 ... xn yn]\n"; // write header Boundary boundary = gch.getConvBoundary(); Position min(boundary.xmin(), boundary.ymin()); Position max(boundary.xmax(), boundary.ymax()); gch.cartesian2geo(min); min.mul(geoScale); gch.cartesian2geo(max); max.mul(geoScale); int multinodes = 0; for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { if ((*i).second->getGeometry().size() > 2) { multinodes++; } } device << "# [xmin_region] " << min.x() << "\n"; device << "# [xmax_region] " << max.x() << "\n"; device << "# [ymin_region] " << min.y() << "\n"; device << "# [ymax_region] " << max.y() << "\n"; device << "# [elements_multinode] " << multinodes << "\n"; device << "# [elements_normalnode] " << nc.size() << "\n"; device << "# [xmin] " << min.x() << "\n"; device << "# [xmax] " << max.x() << "\n"; device << "# [ymin] " << min.y() << "\n"; device << "# [ymax] " << max.y() << "\n"; // write normal nodes for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { NBNode* n = (*i).second; Position pos = n->getPosition(); gch.cartesian2geo(pos); pos.mul(geoScale); device << n->getID() << "\t0\t1\t" << pos.x() << "\t" << pos.y() << "\n"; } // write "internal" nodes std::vector<std::string> avoid; std::set<std::string> reservedNodeIDs; const bool numericalIDs = oc.getBool("numerical-ids"); if (oc.isSet("reserved-ids")) { NBHelpers::loadPrefixedIDsFomFile(oc.getString("reserved-ids"), "node:", reservedNodeIDs); // backward compatibility NBHelpers::loadPrefixedIDsFomFile(oc.getString("reserved-ids"), "junction:", reservedNodeIDs); // selection format } if (numericalIDs) { avoid = nc.getAllNames(); std::vector<std::string> avoid2 = ec.getAllNames(); avoid.insert(avoid.end(), avoid2.begin(), avoid2.end()); avoid.insert(avoid.end(), reservedNodeIDs.begin(), reservedNodeIDs.end()); } IDSupplier idSupplier("", avoid); for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { NBEdge* e = (*i).second; PositionVector geom = e->getGeometry(); if (geom.size() > 2) { // the import NIImporter_DlrNavteq checks for the presence of a // negated edge id to determine spread type. We may need to do some // shifting to make this consistent const bool hasOppositeID = ec.getOppositeByID(e->getID()) != nullptr; if (e->getLaneSpreadFunction() == LANESPREAD_RIGHT && !hasOppositeID) { // need to write center-line geometry instead try { geom.move2side(e->getTotalWidth() / 2); } catch (InvalidArgument& exception) { WRITE_WARNING("Could not reconstruct shape for edge:'" + e->getID() + "' (" + exception.what() + ")."); } } else if (e->getLaneSpreadFunction() == LANESPREAD_CENTER && hasOppositeID) { // need to write left-border geometry instead try { geom.move2side(-e->getTotalWidth() / 2); } catch (InvalidArgument& exception) { WRITE_WARNING("Could not reconstruct shape for edge:'" + e->getID() + "' (" + exception.what() + ")."); } } std::string internalNodeID = e->getID(); if (internalNodeID == UNDEFINED || (nc.retrieve(internalNodeID) != nullptr) || reservedNodeIDs.count(internalNodeID) > 0 ) { // need to invent a new name to avoid clashing with the id of a 'real' node or a reserved name if (numericalIDs) { internalNodeID = idSupplier.getNext(); } else { internalNodeID += "_geometry"; } } internalNodes[e] = internalNodeID; device << internalNodeID << "\t1\t" << geom.size() - 2; for (int ii = 1; ii < (int)geom.size() - 1; ++ii) { Position pos = geom[(int)ii]; gch.cartesian2geo(pos); pos.mul(geoScale); device << "\t" << pos.x() << "\t" << pos.y(); } device << "\n"; } } device.close(); }
void NWWriter_XML::writeEdgesAndConnections(const OptionsCont& oc, NBNodeCont& nc, NBEdgeCont& ec) { const GeoConvHelper& gch = GeoConvHelper::getFinal(); bool useGeo = oc.exists("proj.plain-geo") && oc.getBool("proj.plain-geo"); const bool geoAccuracy = useGeo || gch.usingInverseGeoProjection(); OutputDevice& edevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".edg.xml"); edevice.writeXMLHeader("edges", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/edges_file.xsd\""); OutputDevice& cdevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".con.xml"); cdevice.writeXMLHeader("connections", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/connections_file.xsd\""); bool noNames = !oc.getBool("output.street-names"); for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { // write the edge itself to the edges-files NBEdge* e = (*i).second; edevice.openTag(SUMO_TAG_EDGE); edevice.writeAttr(SUMO_ATTR_ID, e->getID()); edevice.writeAttr(SUMO_ATTR_FROM, e->getFromNode()->getID()); edevice.writeAttr(SUMO_ATTR_TO, e->getToNode()->getID()); if (!noNames && e->getStreetName() != "") { edevice.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(e->getStreetName())); } edevice.writeAttr(SUMO_ATTR_PRIORITY, e->getPriority()); // write the type if given if (e->getTypeID() != "") { edevice.writeAttr(SUMO_ATTR_TYPE, e->getTypeID()); } edevice.writeAttr(SUMO_ATTR_NUMLANES, e->getNumLanes()); if (!e->hasLaneSpecificSpeed()) { edevice.writeAttr(SUMO_ATTR_SPEED, e->getSpeed()); } // write non-default geometry if (!e->hasDefaultGeometry()) { PositionVector geom = e->getGeometry(); if (useGeo) { for (int i = 0; i < (int) geom.size(); i++) { gch.cartesian2geo(geom[i]); } } if (geoAccuracy) { edevice.setPrecision(GEO_OUTPUT_ACCURACY); } edevice.writeAttr(SUMO_ATTR_SHAPE, geom); if (geoAccuracy) { edevice.setPrecision(); } } // write the spread type if not default ("right") if (e->getLaneSpreadFunction() != LANESPREAD_RIGHT) { edevice.writeAttr(SUMO_ATTR_SPREADTYPE, toString(e->getLaneSpreadFunction())); } // write the length if it was specified if (e->hasLoadedLength()) { edevice.writeAttr(SUMO_ATTR_LENGTH, e->getLoadedLength()); } // some attributes can be set by edge default or per lane. Write as default if possible (efficiency) if (e->getLaneWidth() != NBEdge::UNSPECIFIED_WIDTH && !e->hasLaneSpecificWidth()) { edevice.writeAttr(SUMO_ATTR_WIDTH, e->getLaneWidth()); } if (e->getOffset() != NBEdge::UNSPECIFIED_OFFSET && !e->hasLaneSpecificOffset()) { edevice.writeAttr(SUMO_ATTR_OFFSET, e->getOffset()); } if (!e->needsLaneSpecificOutput()) { edevice.closeTag(); } else { for (unsigned int i = 0; i < e->getLanes().size(); ++i) { const NBEdge::Lane& lane = e->getLanes()[i]; edevice.openTag(SUMO_TAG_LANE); edevice.writeAttr(SUMO_ATTR_INDEX, i); // write allowed lanes NWWriter_SUMO::writePermissions(edevice, lane.permissions); NWWriter_SUMO::writePreferences(edevice, lane.preferred); // write other attributes if (lane.width != NBEdge::UNSPECIFIED_WIDTH && e->hasLaneSpecificWidth()) { edevice.writeAttr(SUMO_ATTR_WIDTH, lane.width); } if (lane.offset != NBEdge::UNSPECIFIED_OFFSET && e->hasLaneSpecificOffset()) { edevice.writeAttr(SUMO_ATTR_OFFSET, lane.offset); } if (e->hasLaneSpecificSpeed()) { edevice.writeAttr(SUMO_ATTR_SPEED, lane.speed); } edevice.closeTag(); } edevice.closeTag(); } // write this edge's connections to the connections-files e->sortOutgoingConnectionsByIndex(); const std::vector<NBEdge::Connection> connections = e->getConnections(); for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) { NWWriter_SUMO::writeConnection(cdevice, *e, *c, false, NWWriter_SUMO::PLAIN); } if (connections.size() > 0) { cdevice << "\n"; } } // write loaded prohibitions to the connections-file for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { NWWriter_SUMO::writeProhibitions(cdevice, i->second->getProhibitions()); } edevice.close(); cdevice.close(); }