void GLHelper::drawShapeDottedContour(const int type, const PositionVector& shape, const double width) { glPushMatrix(); // build contour using shapes of first and last lane shapes PositionVector contourFront = shape; // only add an contourback if width is greather of 0 if (width > 0) { PositionVector contourback = contourFront; contourFront.move2side(width); contourback.move2side(-width); contourback = contourback.reverse(); for (auto i : contourback) { contourFront.push_back(i); } contourFront.push_back(shape.front()); } // resample shape PositionVector resampledShape = contourFront.resample(1); // draw contour over shape glTranslated(0, 0, type + 2); // set custom line width glLineWidth(3); // draw contour drawLine(resampledShape, getDottedcontourColors((int)resampledShape.size())); //restore line width glLineWidth(1); glPopMatrix(); }
void GLHelper::drawShapeDottedContour(const int type, const PositionVector& frontShape, const double offsetFrontShape, const PositionVector& backShape, const double offsetBackShape) { glPushMatrix(); // build contour using shapes of first and last lane shapes PositionVector contourFront = frontShape; PositionVector contourback = backShape; contourFront.move2side(offsetFrontShape); contourback.move2side(offsetBackShape); contourback = contourback.reverse(); for (auto i : contourback) { contourFront.push_back(i); } contourFront.push_back(frontShape.front()); // resample shape PositionVector resampledShape = contourFront.resample(1); // draw contour over shape glTranslated(0, 0, type + 2); // set custom line width glLineWidth(3); // draw contour GLHelper::drawLine(resampledShape, getDottedcontourColors((int)resampledShape.size())); //restore line width glLineWidth(1); glPopMatrix(); }
GNEEdge* GNENet::addReversedEdge(GNEEdge* edge, GNEUndoList* undoList) { undoList->p_begin("add reversed edge"); GNEEdge* reversed = 0; if (edge->getNBEdge()->getLaneSpreadFunction() == LANESPREAD_RIGHT) { GNEEdge* reversed = createEdge(edge->getDest(), edge->getSource(), edge, undoList, "-" + edge->getID(), false, true); assert(reversed != 0); reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList); } else { // if the edge is centered it should probably connect somewhere else // make it easy to move and reconnect it PositionVector orig = edge->getNBEdge()->getGeometry(); PositionVector origInner = edge->getNBEdge()->getInnerGeometry(); const SUMOReal tentativeShift = edge->getNBEdge()->getTotalWidth() + 2; orig.move2side(-tentativeShift); origInner.move2side(-tentativeShift); GNEJunction* src = createJunction(orig.back(), undoList); GNEJunction* dest = createJunction(orig.front(), undoList); GNEEdge* reversed = createEdge(src, dest, edge, undoList, "-" + edge->getID(), false, true); assert(reversed != 0); reversed->setAttribute(SUMO_ATTR_SHAPE, toString(origInner.reverse()), undoList); // select the new edge and its nodes std::set<GUIGlID> toSelect; toSelect.insert(reversed->getGlID()); toSelect.insert(src->getGlID()); toSelect.insert(dest->getGlID()); undoList->add(new GNEChange_Selection(toSelect, gSelected.getSelected(), true), true); } undoList->p_end(); return reversed; }
void GNECrossing::drawTLSLinkNo(const GUIVisualizationSettings& s) const { auto crossing = myParentJunction->getNBNode()->getCrossing(myCrossingEdges); glPushMatrix(); glTranslated(0, 0, GLO_JUNCTION + 0.5); PositionVector shape = crossing->shape; shape.extrapolate(0.5); // draw on top of the walking area int linkNo = crossing->tlLinkIndex; int linkNo2 = crossing->tlLinkIndex2 > 0 ? crossing->tlLinkIndex2 : linkNo; GLHelper::drawTextAtEnd(toString(linkNo2), shape, 0, s.drawLinkTLIndex.size, s.drawLinkTLIndex.color); GLHelper::drawTextAtEnd(toString(linkNo), shape.reverse(), 0, s.drawLinkTLIndex.size, s.drawLinkTLIndex.color); glPopMatrix(); }
void NIImporter_VISUM::parse_AreaSubPartElement() { SUMOLong id = TplConvert::_2long(myLineParser.get("TFLAECHEID").c_str()); SUMOLong edgeid = TplConvert::_2long(myLineParser.get("KANTEID").c_str()); if (myEdges.find(edgeid) == myEdges.end()) { WRITE_ERROR("Unknown edge in TEILFLAECHENELEMENT"); return; } std::string dir = myLineParser.get("RICHTUNG"); // get index (unused) // std::string indexS = NBHelpers::normalIDRepresentation(myLineParser.get("INDEX")); // int index = -1; // try { // index = TplConvert::_2int(indexS.c_str()) - 1; // } catch (NumberFormatException&) { // WRITE_ERROR("An index for a TEILFLAECHENELEMENT is not numeric (id='" + toString(id) + "')."); // return; // } PositionVector shape; shape.push_back(myPoints[myEdges[edgeid].first]); shape.push_back(myPoints[myEdges[edgeid].second]); if (dir.length() > 0 && dir[0] == '1') { shape = shape.reverse(); } if (mySubPartsAreas.find(id) == mySubPartsAreas.end()) { WRITE_ERROR("Unkown are for area part '" + myCurrentID + "'."); return; } const std::vector<SUMOLong>& areas = mySubPartsAreas.find(id)->second; for (std::vector<SUMOLong>::const_iterator i = areas.begin(); i != areas.end(); ++i) { NBDistrict* d = myShapeDistrictMap[*i]; if (d == 0) { continue; } if (myDistrictShapes.find(d) == myDistrictShapes.end()) { myDistrictShapes[d] = PositionVector(); } if (dir.length() > 0 && dir[0] == '1') { myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].second]); myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].first]); } else { myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].first]); myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].second]); } } }
bool NIImporter_DlrNavteq::EdgesHandler::report(const std::string& result) { // parse version number from first comment line and initialize column definitions if (result[0] == '#') { if (!myColumns.empty()) { return true; } const double version = readVersion(result, myFile); if (version > 0) { myVersion = version; // init columns const int NUM_COLUMNS = 25; // @note arrays must match this size! const int MC = MISSING_COLUMN; if (myVersion < 3) { const int columns[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, MC, 12, 13, 14, 15, 16, 17, 18, 19, 20, MC, MC, -21}; myColumns = std::vector<int>(columns, columns + NUM_COLUMNS); } else if (myVersion < 6) { const int columns[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, MC, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, -23}; myColumns = std::vector<int>(columns, columns + NUM_COLUMNS); } else { const int columns[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}; myColumns = std::vector<int>(columns, columns + NUM_COLUMNS); } } return true; } if (myColumns.empty()) { throw ProcessError("Missing version string in file '" + myFile + "'."); } // interpret link attributes StringTokenizer st(result, StringTokenizer::WHITECHARS); const std::string id = getColumn(st, LINK_ID); // form of way (for priority and permissions) int form_of_way; try { form_of_way = StringUtils::toInt(getColumn(st, FORM_OF_WAY)); } catch (NumberFormatException&) { throw ProcessError("Non-numerical value for form_of_way of link '" + id + "'."); } // brunnel type (bridge/tunnel/ferry (for permissions) int brunnel_type; try { brunnel_type = StringUtils::toInt(getColumn(st, BRUNNEL_TYPE)); } catch (NumberFormatException&) { throw ProcessError("Non-numerical value for brunnel_type of link '" + id + "'."); } // priority based on street_type / frc int priority; try { priority = -StringUtils::toInt(getColumn(st, FUNCTIONAL_ROAD_CLASS)); // lower priority using form_of_way if (form_of_way == 11) { priority -= 1; // frontage road, very often with lowered curb } else if (form_of_way > 11) { priority -= 2; // parking/service access assume lowered curb } } catch (NumberFormatException&) { throw ProcessError("Non-numerical value for street_type of link '" + id + "')."); } // street name std::string streetName = getStreetNameFromIDs( getColumn(st, NAME_ID1_REGIONAL), getColumn(st, NAME_ID2_LOCAL)); // try to get the nodes const std::string fromID = getColumn(st, NODE_ID_FROM); const std::string toID = getColumn(st, NODE_ID_TO); NBNode* from = myNodeCont.retrieve(fromID); NBNode* to = myNodeCont.retrieve(toID); if (from == nullptr) { throw ProcessError("The from-node '" + fromID + "' of link '" + id + "' could not be found"); } if (to == nullptr) { throw ProcessError("The to-node '" + toID + "' of link '" + id + "' could not be found"); } // speed double speed; try { speed = StringUtils::toInt(getColumn(st, SPEED_RESTRICTION, "-1")) / 3.6; } catch (NumberFormatException&) { throw ProcessError("Non-numerical value for the SPEED_RESTRICTION of link '" + id + "'."); } if (speed < 0) { // speed category as fallback speed = NINavTeqHelper::getSpeed(id, getColumn(st, SPEED_CATEGORY)); } // number of lanes int numLanes; try { // EXTENDED_NUMBER_OF_LANES is prefered but may not be defined numLanes = StringUtils::toInt(getColumn(st, EXTENDED_NUMBER_OF_LANES, "-1")); if (numLanes == -1) { numLanes = NINavTeqHelper::getLaneNumber(id, getColumn(st, NUMBER_OF_LANES), speed); } } catch (NumberFormatException&) { throw ProcessError("Non-numerical value for the number of lanes of link '" + id + "'."); } const std::string navTeqTypeId = getColumn(st, VEHICLE_TYPE) + "_" + getColumn(st, FORM_OF_WAY); // build the edge NBEdge* e = nullptr; const std::string interID = getColumn(st, BETWEEN_NODE_ID); if (interID == "-1") { e = new NBEdge(id, from, to, myTypeCont.knows(navTeqTypeId) ? navTeqTypeId : "", speed, numLanes, priority, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, streetName); } else { PositionVector geoms = myGeoms[interID]; if (getColumn(st, CONNECTION, "0") == "1") { geoms = geoms.reverse(); } geoms.insert(geoms.begin(), from->getPosition()); geoms.push_back(to->getPosition()); const std::string origID = OptionsCont::getOptions().getBool("output.original-names") ? id : ""; e = new NBEdge(id, from, to, myTypeCont.knows(navTeqTypeId) ? navTeqTypeId : "", speed, numLanes, priority, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, geoms, streetName, origID, LANESPREAD_CENTER); } // NavTeq imports can be done with a typemap (if supplied), if not, the old defaults are used if (myTypeCont.knows(navTeqTypeId)) { e->setPermissions(myTypeCont.getPermissions(navTeqTypeId)); } else { // add vehicle type information to the edge if (myVersion < 6.0) { NINavTeqHelper::addVehicleClasses(*e, getColumn(st, VEHICLE_TYPE)); } else { NINavTeqHelper::addVehicleClassesV6(*e, getColumn(st, VEHICLE_TYPE)); } if (e->getPermissions() == SVCAll) { e->setPermissions(myTypeCont.getPermissions("")); } // permission modifications based on form_of_way if (form_of_way == 14) { // pedestrian area (fussgaengerzone) // unfortunately, the veh_type string is misleading in this case e->disallowVehicleClass(-1, SVC_PASSENGER); } // permission modifications based on brunnel_type if (brunnel_type == 10) { // ferry e->setPermissions(SVC_SHIP, -1); } } // insert the edge to the network if (!myEdgeCont.insert(e)) { delete e; throw ProcessError("Could not add edge '" + id + "'."); } return true; }
void NIImporter_ArcView::load() { #ifdef HAVE_GDAL PROGRESS_BEGIN_MESSAGE("Loading data from '" + mySHPName + "'"); #if GDAL_VERSION_MAJOR < 2 OGRRegisterAll(); OGRDataSource* poDS = OGRSFDriverRegistrar::Open(mySHPName.c_str(), FALSE); #else GDALAllRegister(); GDALDataset* poDS = (GDALDataset*)GDALOpenEx(mySHPName.c_str(), GDAL_OF_VECTOR | GA_ReadOnly, NULL, NULL, NULL); #endif if (poDS == NULL) { WRITE_ERROR("Could not open shape description '" + mySHPName + "'."); return; } // begin file parsing OGRLayer* poLayer = poDS->GetLayer(0); poLayer->ResetReading(); // build coordinate transformation OGRSpatialReference* origTransf = poLayer->GetSpatialRef(); OGRSpatialReference destTransf; // use wgs84 as destination destTransf.SetWellKnownGeogCS("WGS84"); OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(origTransf, &destTransf); if (poCT == NULL) { if (myOptions.isSet("shapefile.guess-projection")) { OGRSpatialReference origTransf2; origTransf2.SetWellKnownGeogCS("WGS84"); poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf); } if (poCT == 0) { WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed."); } } OGRFeature* poFeature; poLayer->ResetReading(); while ((poFeature = poLayer->GetNextFeature()) != NULL) { // read in edge attributes std::string id, name, from_node, to_node; if (!getStringEntry(poFeature, "shapefile.street-id", "LINK_ID", true, id)) { WRITE_ERROR("Needed field '" + id + "' (from node id) is missing."); } if (id == "") { WRITE_ERROR("Could not obtain edge id."); return; } getStringEntry(poFeature, "shapefile.street-id", "ST_NAME", true, name); name = StringUtils::replace(name, "&", "&"); if (!getStringEntry(poFeature, "shapefile.from-id", "REF_IN_ID", true, from_node)) { WRITE_ERROR("Needed field '" + from_node + "' (from node id) is missing."); } if (!getStringEntry(poFeature, "shapefile.to-id", "NREF_IN_ID", true, to_node)) { WRITE_ERROR("Needed field '" + to_node + "' (to node id) is missing."); } if (from_node == "" || to_node == "") { from_node = toString(myRunningNodeID++); to_node = toString(myRunningNodeID++); } std::string type; if (myOptions.isSet("shapefile.type-id") && poFeature->GetFieldIndex(myOptions.getString("shapefile.type-id").c_str()) >= 0) { type = poFeature->GetFieldAsString(myOptions.getString("shapefile.type-id").c_str()); } else if (poFeature->GetFieldIndex("ST_TYP_AFT") >= 0) { type = poFeature->GetFieldAsString("ST_TYP_AFT"); } SUMOReal width = myTypeCont.getWidth(type); SUMOReal speed = getSpeed(*poFeature, id); int nolanes = getLaneNo(*poFeature, id, speed); int priority = getPriority(*poFeature, id); if (nolanes == 0 || speed == 0) { if (myOptions.getBool("shapefile.use-defaults-on-failure")) { nolanes = myTypeCont.getNumLanes(""); speed = myTypeCont.getSpeed(""); } else { OGRFeature::DestroyFeature(poFeature); WRITE_ERROR("The description seems to be invalid. Please recheck usage of types."); return; } } if (mySpeedInKMH) { speed = speed / (SUMOReal) 3.6; } // read in the geometry OGRGeometry* poGeometry = poFeature->GetGeometryRef(); OGRwkbGeometryType gtype = poGeometry->getGeometryType(); assert(gtype == wkbLineString); UNUSED_PARAMETER(gtype); // ony used for assertion OGRLineString* cgeom = (OGRLineString*) poGeometry; if (poCT != 0) { // try transform to wgs84 cgeom->transform(poCT); } PositionVector shape; for (int j = 0; j < cgeom->getNumPoints(); j++) { Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j)); if (!NBNetBuilder::transformCoordinate(pos)) { WRITE_WARNING("Unable to project coordinates for edge '" + id + "'."); } shape.push_back_noDoublePos(pos); } // build from-node NBNode* from = myNodeCont.retrieve(from_node); if (from == 0) { Position from_pos = shape[0]; from = myNodeCont.retrieve(from_pos); if (from == 0) { from = new NBNode(from_node, from_pos); if (!myNodeCont.insert(from)) { WRITE_ERROR("Node '" + from_node + "' could not be added"); delete from; continue; } } } // build to-node NBNode* to = myNodeCont.retrieve(to_node); if (to == 0) { Position to_pos = shape[-1]; to = myNodeCont.retrieve(to_pos); if (to == 0) { to = new NBNode(to_node, to_pos); if (!myNodeCont.insert(to)) { WRITE_ERROR("Node '" + to_node + "' could not be added"); delete to; continue; } } } if (from == to) { WRITE_WARNING("Edge '" + id + "' connects identical nodes, skipping."); continue; } // retrieve the information whether the street is bi-directional std::string dir; int index = poFeature->GetDefnRef()->GetFieldIndex("DIR_TRAVEL"); if (index >= 0 && poFeature->IsFieldSet(index)) { dir = poFeature->GetFieldAsString(index); } // add positive direction if wanted if (dir == "B" || dir == "F" || dir == "" || myOptions.getBool("shapefile.all-bidirectional")) { if (myEdgeCont.retrieve(id) == 0) { LaneSpreadFunction spread = dir == "B" || dir == "FALSE" ? LANESPREAD_RIGHT : LANESPREAD_CENTER; NBEdge* edge = new NBEdge(id, from, to, type, speed, nolanes, priority, width, NBEdge::UNSPECIFIED_OFFSET, shape, name, id, spread); myEdgeCont.insert(edge); checkSpread(edge); } } // add negative direction if wanted if (dir == "B" || dir == "T" || myOptions.getBool("shapefile.all-bidirectional")) { if (myEdgeCont.retrieve("-" + id) == 0) { LaneSpreadFunction spread = dir == "B" || dir == "FALSE" ? LANESPREAD_RIGHT : LANESPREAD_CENTER; NBEdge* edge = new NBEdge("-" + id, to, from, type, speed, nolanes, priority, width, NBEdge::UNSPECIFIED_OFFSET, shape.reverse(), name, id, spread); myEdgeCont.insert(edge); checkSpread(edge); } } // OGRFeature::DestroyFeature(poFeature); } #if GDAL_VERSION_MAJOR < 2 OGRDataSource::DestroyDataSource(poDS); #else GDALClose(poDS); #endif PROGRESS_DONE_MESSAGE(); #else WRITE_ERROR("SUMO was compiled without GDAL support."); #endif }
void NIImporter_OpenStreetMap::insertEdge(Edge* e, int index, NBNode* from, NBNode* to, const std::vector<int> &passed, NBEdgeCont& ec, NBTypeCont& tc) { // patch the id std::string id = e->id; if (index >= 0) { id = id + "#" + toString(index); } // convert the shape PositionVector shape; for (std::vector<int>::const_iterator i = passed.begin(); i != passed.end(); ++i) { NIOSMNode* n = myOSMNodes.find(*i)->second; Position pos(n->lon, n->lat); if (!NILoader::transformCoordinates(pos, true)) { throw ProcessError("Unable to project coordinates for edge " + id + "."); } shape.push_back_noDoublePos(pos); } std::string type = e->myHighWayType; if (!tc.knows(type)) { if (type.find(compoundTypeSeparator) != std::string::npos) { // this edge has a combination type which does not yet exist in the TypeContainer StringTokenizer tok = StringTokenizer(type, compoundTypeSeparator); std::set<std::string> types; while (tok.hasNext()) { std::string t = tok.next(); if (tc.knows(t)) { types.insert(t); } else { WRITE_WARNING("Discarding edge " + id + " with type \"" + type + "\" (unknown compound \"" + t + "\")."); return; } } if (types.size() == 2 && types.count("railway.tram") == 1) { // compound types concern mostly the special case of tram tracks on a normal road. // in this case we simply discard the tram information since the default for road is to allow all vclasses types.erase("railway.tram"); std::string otherCompound = *(types.begin()); // XXX if otherCompound does not allow all vehicles (e.g. SVC_DELIVERY), tram will still not be allowed type = otherCompound; } else { // other cases not implemented yet WRITE_WARNING("Discarding edge " + id + " with unknown type \"" + type + "\"."); return; } } else { // we do not know the type -> something else, ignore //WRITE_WARNING("Discarding edge " + id + " with unknown type \"" + type + "\"."); return; } } // otherwise it is not an edge and will be ignored int noLanes = tc.getNumLanes(type); SUMOReal speed = tc.getSpeed(type); bool defaultsToOneWay = tc.getIsOneWay(type); SUMOVehicleClasses allowedClasses = tc.getAllowedClasses(type); SUMOVehicleClasses disallowedClasses = tc.getDisallowedClasses(type); // check directions bool addSecond = true; if (e->myIsOneWay == "true" || e->myIsOneWay == "yes" || e->myIsOneWay == "1" || (defaultsToOneWay && e->myIsOneWay != "no" && e->myIsOneWay != "false" && e->myIsOneWay != "0")) { addSecond = false; } // if we had been able to extract the number of lanes, override the highway type default if (e->myNoLanes >= 0) { if (!addSecond) { noLanes = e->myNoLanes; } else { noLanes = e->myNoLanes / 2; } } // if we had been able to extract the maximum speed, override the type's default if (e->myMaxSpeed != MAXSPEED_UNGIVEN) { speed = (SUMOReal)(e->myMaxSpeed / 3.6); } if (noLanes != 0 && speed != 0) { if (e->myIsOneWay != "" && e->myIsOneWay != "false" && e->myIsOneWay != "no" && e->myIsOneWay != "true" && e->myIsOneWay != "yes" && e->myIsOneWay != "-1" && e->myIsOneWay != "1") { WRITE_WARNING("New value for oneway found: " + e->myIsOneWay); } LaneSpreadFunction lsf = addSecond ? LANESPREAD_RIGHT : LANESPREAD_CENTER; if (e->myIsOneWay != "-1") { NBEdge* nbe = new NBEdge(id, from, to, type, speed, noLanes, tc.getPriority(type), tc.getWidth(type), NBEdge::UNSPECIFIED_OFFSET, shape, e->streetName, lsf); nbe->setVehicleClasses(allowedClasses, disallowedClasses); if (!ec.insert(nbe)) { delete nbe; throw ProcessError("Could not add edge '" + id + "'."); } } if (addSecond) { if (e->myIsOneWay != "-1") { id = "-" + id; } NBEdge* nbe = new NBEdge(id, to, from, type, speed, noLanes, tc.getPriority(type), tc.getWidth(type), NBEdge::UNSPECIFIED_OFFSET, shape.reverse(), e->streetName, lsf); nbe->setVehicleClasses(allowedClasses, disallowedClasses); if (!ec.insert(nbe)) { delete nbe; throw ProcessError("Could not add edge '-" + id + "'."); } } } }