// =========================================================================== // method definitions // =========================================================================== GUIContainerStop::GUIContainerStop(const std::string& id, const std::vector<std::string>& lines, MSLane& lane, SUMOReal frompos, SUMOReal topos) : MSStoppingPlace(id, lines, lane, frompos, topos), GUIGlObject_AbstractAdd("containerStop", GLO_TRIGGER, id) { myFGShape = lane.getShape(); myFGShape.move2side((SUMOReal) 1.65); myFGShape = myFGShape.getSubpart(frompos, topos); myFGShapeRotations.reserve(myFGShape.size() - 1); myFGShapeLengths.reserve(myFGShape.size() - 1); int e = (int) myFGShape.size() - 1; for (int i = 0; i < e; ++i) { const Position& f = myFGShape[i]; const Position& s = myFGShape[i + 1]; myFGShapeLengths.push_back(f.distanceTo(s)); myFGShapeRotations.push_back((SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI); } PositionVector tmp = myFGShape; tmp.move2side(1.5); myFGSignPos = tmp.getLineCenter(); myFGSignRot = 0; if (tmp.length() != 0) { myFGSignRot = myFGShape.rotationDegreeAtOffset(SUMOReal((myFGShape.length() / 2.))); myFGSignRot -= 90; } }
SUMOReal NWWriter_DlrNavteq::getGraphLength(NBEdge* edge) { PositionVector geom = edge->getGeometry(); geom.push_back_noDoublePos(edge->getToNode()->getPosition()); geom.push_front_noDoublePos(edge->getFromNode()->getPosition()); return geom.length(); }
Position GNECalibrator::getPositionInView() const { PositionVector shape = (getLaneParents().size() > 0) ? getLaneParents().front()->getGeometry().shape : getEdgeParents().front()->getLanes().at(0)->getGeometry().shape; if (myPositionOverLane < 0) { return shape.front(); } else if (myPositionOverLane > shape.length()) { return shape.back(); } else { return shape.positionAtOffset(myPositionOverLane); } }
void NWWriter_SUMO::writeLane(OutputDevice& into, const std::string& eID, const std::string& lID, SUMOReal speed, SVCPermissions permissions, SVCPermissions preferred, SUMOReal endOffset, SUMOReal width, PositionVector shape, const std::string& origID, SUMOReal length, unsigned int index, bool origNames, const NBNode* node) { // output the lane's attributes into.openTag(SUMO_TAG_LANE).writeAttr(SUMO_ATTR_ID, lID); // the first lane of an edge will be the depart lane into.writeAttr(SUMO_ATTR_INDEX, index); // write the list of allowed/disallowed vehicle classes if (permissions != SVC_UNSPECIFIED) { writePermissions(into, permissions); } writePreferences(into, preferred); // some further information if (speed == 0) { WRITE_WARNING("Lane #" + toString(index) + " of edge '" + eID + "' has a maximum velocity of 0."); } else if (speed < 0) { throw ProcessError("Negative velocity (" + toString(speed) + " on edge '" + eID + "' lane#" + toString(index) + "."); } if (endOffset > 0) { length = length - endOffset; } into.writeAttr(SUMO_ATTR_SPEED, speed); into.writeAttr(SUMO_ATTR_LENGTH, length); if (endOffset != NBEdge::UNSPECIFIED_OFFSET) { into.writeAttr(SUMO_ATTR_ENDOFFSET, endOffset); } if (width != NBEdge::UNSPECIFIED_WIDTH) { into.writeAttr(SUMO_ATTR_WIDTH, width); } if (node != 0) { const NBNode::CustomShapeMap& cs = node->getCustomLaneShapes(); NBNode::CustomShapeMap::const_iterator it = cs.find(lID); if (it != cs.end()) { shape = it->second; into.writeAttr(SUMO_ATTR_CUSTOMSHAPE, true); } } into.writeAttr(SUMO_ATTR_SHAPE, endOffset > 0 ? shape.getSubpart(0, shape.length() - endOffset) : shape); if (origNames && origID != "") { into.openTag(SUMO_TAG_PARAM); into.writeAttr(SUMO_ATTR_KEY, "origId"); into.writeAttr(SUMO_ATTR_VALUE, origID); into.closeTag(); into.closeTag(); } else { into.closeTag(); } }
bool NGRandomNetBuilder::canConnect(NGNode* baseNode, NGNode* newNode) { bool connectable = true; const PositionVector n(baseNode->getPosition(), newNode->getPosition()); // check for range between Basenode and Newnode if (connectable) { SUMOReal dist = n.length(); if ((dist < myMinDistance) || (dist > myMaxDistance)) { connectable = false; } } // check for angle restrictions if (connectable) { connectable = checkAngles(baseNode); } if (connectable) { connectable = checkAngles(newNode); } // check for intersections and range restrictions with outer links if (connectable) { NGEdgeList::iterator li; li = myOuterLinks.begin(); while (connectable && (li != myOuterLinks.end())) { // check intersection only if links don't share a node const NGNode* const start = (*li)->getStartNode(); const NGNode* const end = (*li)->getEndNode(); const Position& p1 = start->getPosition(); const Position& p2 = end->getPosition(); if ((baseNode != start) && (baseNode != end) && (newNode != start) && (newNode != end)) { connectable = !n.intersects(p1, p2); } // check NewNode-To-Links distance only, if NewNode isn't part of link if (connectable && (newNode != start) && (newNode != end)) { const SUMOReal offset = GeomHelper::nearest_offset_on_line_to_point2D(p1, p2, n[1]); if (offset != GeomHelper::INVALID_OFFSET) { const Position p = PositionVector(p1, p2).positionAtOffset2D(offset); const SUMOReal dist = p.distanceTo2D(n[1]); if (dist < myMinDistance) { connectable = false; } } } ++li; } } return connectable; }
void NWWriter_SUMO::writeEdge(OutputDevice& into, const NBEdge& e, bool noNames, bool origNames) { // write the edge's begin into.openTag(SUMO_TAG_EDGE).writeAttr(SUMO_ATTR_ID, e.getID()); into.writeAttr(SUMO_ATTR_FROM, e.getFromNode()->getID()); into.writeAttr(SUMO_ATTR_TO, e.getToNode()->getID()); if (!noNames && e.getStreetName() != "") { into.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(e.getStreetName())); } into.writeAttr(SUMO_ATTR_PRIORITY, e.getPriority()); if (e.getTypeID() != "") { into.writeAttr(SUMO_ATTR_TYPE, e.getTypeID()); } if (e.isMacroscopicConnector()) { into.writeAttr(SUMO_ATTR_FUNCTION, EDGEFUNC_CONNECTOR); } // write the spread type if not default ("right") if (e.getLaneSpreadFunction() != LANESPREAD_RIGHT) { into.writeAttr(SUMO_ATTR_SPREADTYPE, e.getLaneSpreadFunction()); } if (e.hasLoadedLength()) { into.writeAttr(SUMO_ATTR_LENGTH, e.getLoadedLength()); } if (!e.hasDefaultGeometry()) { into.writeAttr(SUMO_ATTR_SHAPE, e.getGeometry()); } // write the lanes const std::vector<NBEdge::Lane>& lanes = e.getLanes(); SUMOReal length = e.getLoadedLength(); if (OptionsCont::getOptions().getBool("no-internal-links") && !e.hasLoadedLength()) { // use length to junction center even if a modified geometry was given PositionVector geom = e.cutAtIntersection(e.getGeometry()); geom.push_back_noDoublePos(e.getToNode()->getCenter()); geom.push_front_noDoublePos(e.getFromNode()->getCenter()); length = geom.length(); } if (length <= 0) { length = POSITION_EPS; } for (unsigned int i = 0; i < (unsigned int) lanes.size(); i++) { const NBEdge::Lane& l = lanes[i]; writeLane(into, e.getID(), e.getLaneID(i), l.speed, l.permissions, l.preferred, l.endOffset, l.width, l.shape, l.origID, length, i, origNames); } // close the edge into.closeTag(); }
bool GNECalibrator::isValid(SumoXMLAttr key, const std::string& value) { switch (key) { case SUMO_ATTR_ID: return isValidAdditionalID(value); case SUMO_ATTR_EDGE: if (myViewNet->getNet()->retrieveEdge(value, false) != nullptr) { return true; } else { return false; } case SUMO_ATTR_LANE: if (myViewNet->getNet()->retrieveLane(value, false) != nullptr) { return true; } else { return false; } case SUMO_ATTR_POSITION: if (canParse<double>(value)) { // obtain position and check if is valid double newPosition = parse<double>(value); PositionVector shape = (getLaneParents().size() > 0) ? getLaneParents().front()->getGeometry().shape : getEdgeParents().front()->getLanes().at(0)->getGeometry().shape; if ((newPosition < 0) || (newPosition > shape.length())) { return false; } else { return true; } } else { return false; } case SUMO_ATTR_FREQUENCY: return (canParse<double>(value) && parse<double>(value) >= 0); case SUMO_ATTR_NAME: return SUMOXMLDefinitions::isValidAttribute(value); case SUMO_ATTR_OUTPUT: return SUMOXMLDefinitions::isValidFilename(value); case SUMO_ATTR_ROUTEPROBE: return SUMOXMLDefinitions::isValidNetID(value); case GNE_ATTR_SELECTED: return canParse<bool>(value); case GNE_ATTR_GENERIC: return isGenericParametersValid(value); default: throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'"); } }
void NWWriter_SUMO::writeLane(OutputDevice& into, const std::string& eID, const std::string& lID, const NBEdge::Lane& lane, SUMOReal length, unsigned int index, bool origNames) { // output the lane's attributes into.openTag(SUMO_TAG_LANE).writeAttr(SUMO_ATTR_ID, lID); // the first lane of an edge will be the depart lane into.writeAttr(SUMO_ATTR_INDEX, index); // write the list of allowed/disallowed vehicle classes writePermissions(into, lane.permissions); writePreferences(into, lane.preferred); // some further information if (lane.speed == 0) { WRITE_WARNING("Lane #" + toString(index) + " of edge '" + eID + "' has a maximum velocity of 0."); } else if (lane.speed < 0) { throw ProcessError("Negative velocity (" + toString(lane.speed) + " on edge '" + eID + "' lane#" + toString(index) + "."); } if (lane.offset > 0) { length = length - lane.offset; } into.writeAttr(SUMO_ATTR_SPEED, lane.speed); into.writeAttr(SUMO_ATTR_LENGTH, length); if (lane.offset != NBEdge::UNSPECIFIED_OFFSET) { into.writeAttr(SUMO_ATTR_ENDOFFSET, lane.offset); } if (lane.width != NBEdge::UNSPECIFIED_WIDTH) { into.writeAttr(SUMO_ATTR_WIDTH, lane.width); } PositionVector shape = lane.shape; if (lane.offset > 0) { shape = shape.getSubpart(0, shape.length() - lane.offset); } into.writeAttr(SUMO_ATTR_SHAPE, shape); if (origNames && lane.origID != "") { into.openTag(SUMO_TAG_PARAM); into.writeAttr(SUMO_ATTR_KEY, "origId"); into.writeAttr(SUMO_ATTR_VALUE, lane.origID); into.closeTag(); into.closeTag(); } else { into.closeTag(); } }
// =========================================================================== // method definitions // =========================================================================== GUIChargingStation::GUIChargingStation(const std::string& id, MSLane& lane, SUMOReal frompos, SUMOReal topos, SUMOReal chargingPower, SUMOReal efficiency, bool chargeInTransit, int chargeDelay) : MSChargingStation(id, lane, frompos, topos, chargingPower, efficiency, chargeInTransit, chargeDelay), GUIGlObject_AbstractAdd("chargingStation", GLO_TRIGGER, id) { myFGShape = lane.getShape(); myFGShape = myFGShape.getSubpart(frompos, topos); myFGShapeRotations.reserve(myFGShape.size() - 1); myFGShapeLengths.reserve(myFGShape.size() - 1); int e = (int) myFGShape.size() - 1; for (int i = 0; i < e; ++i) { const Position& f = myFGShape[i]; const Position& s = myFGShape[i + 1]; myFGShapeLengths.push_back(f.distanceTo(s)); myFGShapeRotations.push_back((SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI); } PositionVector tmp = myFGShape; tmp.move2side(1.5); myFGSignPos = tmp.getLineCenter(); myFGSignRot = 0; if (tmp.length() != 0) { myFGSignRot = myFGShape.rotationDegreeAtOffset(SUMOReal((myFGShape.length() / 2.))); myFGSignRot -= 90; } }
// =========================================================================== // method definitions // =========================================================================== GUIParkingArea::GUIParkingArea(const std::string& id, const std::vector<std::string>& lines, MSLane& lane, SUMOReal frompos, SUMOReal topos, unsigned int capacity, SUMOReal width, SUMOReal length, SUMOReal angle) : MSParkingArea(id, lines, lane, frompos, topos, capacity, width, length, angle), GUIGlObject_AbstractAdd("parkingArea", GLO_TRIGGER, id) { myShapeRotations.reserve(myShape.size() - 1); myShapeLengths.reserve(myShape.size() - 1); int e = (int) myShape.size() - 1; for (int i = 0; i < e; ++i) { const Position& f = myShape[i]; const Position& s = myShape[i + 1]; myShapeLengths.push_back(f.distanceTo(s)); myShapeRotations.push_back((SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI); } PositionVector tmp = myShape; tmp.move2side(lane.getWidth() + myWidth); mySignPos = tmp.getLineCenter(); mySignRot = 0; if (tmp.length() != 0) { mySignRot = myShape.rotationDegreeAtOffset(SUMOReal((myShape.length() / 2.))); mySignRot -= 90; } }
// =========================================================================== // method definitions // =========================================================================== GUIParkingArea::GUIParkingArea(const std::string& id, const std::vector<std::string>& lines, MSLane& lane, double frompos, double topos, unsigned int capacity, double width, double length, double angle, const std::string& name) : MSParkingArea(id, lines, lane, frompos, topos, capacity, width, length, angle, name), GUIGlObject_AbstractAdd(GLO_PARKING_AREA, id) { const double offsetSign = MSNet::getInstance()->lefthand() ? -1 : 1; myShapeRotations.reserve(myShape.size() - 1); myShapeLengths.reserve(myShape.size() - 1); int e = (int) myShape.size() - 1; for (int i = 0; i < e; ++i) { const Position& f = myShape[i]; const Position& s = myShape[i + 1]; myShapeLengths.push_back(f.distanceTo(s)); myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) M_PI); } PositionVector tmp = myShape; tmp.move2side((lane.getWidth() + myWidth) * offsetSign); mySignPos = tmp.getLineCenter(); mySignRot = 0; if (tmp.length() != 0) { mySignRot = myShape.rotationDegreeAtOffset(double((myShape.length() / 2.))); mySignRot -= 90; } }
void NWWriter_SUMO::writeInternalEdge(OutputDevice& into, const std::string& id, SUMOReal vmax, const PositionVector& shape, const std::string& origID) { SUMOReal length = MAX2(shape.length(), (SUMOReal)POSITION_EPS); // microsim needs positive length into.openTag(SUMO_TAG_EDGE); into.writeAttr(SUMO_ATTR_ID, id); into.writeAttr(SUMO_ATTR_FUNCTION, EDGEFUNC_INTERNAL); into.openTag(SUMO_TAG_LANE); into.writeAttr(SUMO_ATTR_ID, id + "_0"); into.writeAttr(SUMO_ATTR_INDEX, 0); into.writeAttr(SUMO_ATTR_SPEED, vmax); into.writeAttr(SUMO_ATTR_LENGTH, length); into.writeAttr(SUMO_ATTR_SHAPE, shape); if (origID != "") { into.openTag(SUMO_TAG_PARAM); into.writeAttr(SUMO_ATTR_KEY, "origId"); into.writeAttr(SUMO_ATTR_VALUE, origID); into.closeTag(); into.closeTag(); } else { into.closeTag(); } into.closeTag(); }
void GNEConnection::updateGeometry(bool updateGrid) { // Get shape of from and to lanes NBEdge::Connection& nbCon = getNBEdgeConnection(); if (myShapeDeprecated) { // first check if object has to be removed from grid (SUMOTree) if (updateGrid) { myNet->removeGLObjectFromGrid(this); } // Clear containers myShape.clear(); myShapeRotations.clear(); myShapeLengths.clear(); PositionVector laneShapeFrom; if ((int)getEdgeFrom()->getNBEdge()->getLanes().size() > nbCon.fromLane) { laneShapeFrom = getEdgeFrom()->getNBEdge()->getLanes().at(nbCon.fromLane).shape; } else { return; } PositionVector laneShapeTo; if ((int)nbCon.toEdge->getLanes().size() > nbCon.toLane) { laneShapeTo = nbCon.toEdge->getLanes().at(nbCon.toLane).shape; } else { return; } // Calculate shape of connection depending of the size of Junction shape // value obtanied from GNEJunction::drawgl if (nbCon.customShape.size() != 0) { myShape = nbCon.customShape; } else if (getEdgeFrom()->getNBEdge()->getToNode()->getShape().area() > 4) { if (nbCon.shape.size() != 0) { myShape = nbCon.shape; // only append via shape if it exists if (nbCon.haveVia) { myShape.append(nbCon.viaShape); } } else { // Calculate shape so something can be drawn immidiately myShape = getEdgeFrom()->getNBEdge()->getToNode()->computeSmoothShape( laneShapeFrom, laneShapeTo, NUM_POINTS, getEdgeFrom()->getNBEdge()->getTurnDestination() == nbCon.toEdge, (double) 5. * (double) getEdgeFrom()->getNBEdge()->getNumLanes(), (double) 5. * (double) nbCon.toEdge->getNumLanes()); } } else { myShape.clear(); myShape.push_back(laneShapeFrom.positionAtOffset(MAX2(0.0, laneShapeFrom.length() - 1))); myShape.push_back(laneShapeTo.positionAtOffset(MIN2(1.0, laneShapeFrom.length()))); } // check if internal junction marker must be calculated if (nbCon.haveVia && (nbCon.shape.size() != 0)) { // create marker for interal junction waiting position (contPos) const double orthoLength = 0.5; Position pos = nbCon.shape.back(); myInternalJunctionMarker = nbCon.shape.getOrthogonal(pos, 10, true, 0.1); if (myInternalJunctionMarker.length() < orthoLength) { myInternalJunctionMarker.extrapolate(orthoLength - myInternalJunctionMarker.length()); } } else { myInternalJunctionMarker.clear(); } // Obtain lengths and shape rotations int segments = (int) myShape.size() - 1; if (segments >= 0) { myShapeRotations.reserve(segments); myShapeLengths.reserve(segments); for (int i = 0; i < segments; ++i) { const Position& f = myShape[i]; const Position& s = myShape[i + 1]; myShapeLengths.push_back(f.distanceTo2D(s)); myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double)M_PI); } } // mark connection as non-deprecated myShapeDeprecated = false; // last step is to check if object has to be added into grid (SUMOTree) again if (updateGrid) { myNet->addGLObjectIntoGrid(this); } } }