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(); } }
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(); } }
void GNEDetectorE2::updateGeometry() { // Clear all containers myGeometry.clearGeometry(); // declare variables for start and end positions double startPosFixed, endPosFixed; // calculate start and end positions dependin of number of lanes if (getLaneParents().size() == 1) { // set shape lane as detector shape myGeometry.shape = getLaneParents().front()->getGeometry().shape; // set start position if (myPositionOverLane < 0) { startPosFixed = 0; } else if (myPositionOverLane > getLaneParents().back()->getParentEdge().getNBEdge()->getFinalLength()) { startPosFixed = getLaneParents().back()->getParentEdge().getNBEdge()->getFinalLength(); } else { startPosFixed = myPositionOverLane; } // set end position if ((myPositionOverLane + myLength) < 0) { endPosFixed = 0; } else if ((myPositionOverLane + myLength) > getLaneParents().back()->getParentEdge().getNBEdge()->getFinalLength()) { endPosFixed = getLaneParents().back()->getParentEdge().getNBEdge()->getFinalLength(); } else { endPosFixed = (myPositionOverLane + myLength); } // Cut shape using as delimitators fixed start position and fixed end position myGeometry.shape = myGeometry.shape.getSubpart(startPosFixed * getLaneParents().front()->getLengthGeometryFactor(), endPosFixed * getLaneParents().back()->getLengthGeometryFactor()); // Get calculate lenghts and rotations myGeometry.calculateShapeRotationsAndLengths(); // Set block icon position myBlockIcon.position = myGeometry.shape.getLineCenter(); } else if (getLaneParents().size() > 1) { // start with the first lane shape myGeometry.multiShape.push_back(getLaneParents().front()->getGeometry().shape); // set start position if (myPositionOverLane < 0) { startPosFixed = 0; } else if (myPositionOverLane > getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength()) { startPosFixed = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength(); } else { startPosFixed = myPositionOverLane; } // Cut shape using as delimitators fixed start position and fixed end position myGeometry.multiShape[0] = myGeometry.multiShape[0].getSubpart(startPosFixed * getLaneParents().front()->getLengthGeometryFactor(), getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength()); // declare last shape PositionVector lastShape = getLaneParents().back()->getGeometry().shape; // set end position if (myEndPositionOverLane < 0) { endPosFixed = 0; } else if (myEndPositionOverLane > getLaneParents().back()->getParentEdge().getNBEdge()->getFinalLength()) { endPosFixed = getLaneParents().back()->getParentEdge().getNBEdge()->getFinalLength(); } else { endPosFixed = myEndPositionOverLane; } // Cut shape using as delimitators fixed start position and fixed end position lastShape = lastShape.getSubpart(0, endPosFixed * getLaneParents().back()->getLengthGeometryFactor()); // add first shape connection (if exist, in other case leave it empty) myGeometry.multiShape.push_back(PositionVector{getLaneParents().at(0)->getGeometry().shape.back(), getLaneParents().at(1)->getGeometry().shape.front()}); for (auto j : getLaneParents().at(0)->getParentEdge().getGNEConnections()) { if (j->getLaneTo() == getLaneParents().at(1)) { myGeometry.multiShape.back() = j->getGeometry().shape; } } // append shapes of intermediate lanes AND connections (if exist) for (int i = 1; i < ((int)getLaneParents().size() - 1); i++) { // add lane shape myGeometry.multiShape.push_back(getLaneParents().at(i)->getGeometry().shape); // add empty shape for connection myGeometry.multiShape.push_back(PositionVector{getLaneParents().at(i)->getGeometry().shape.back(), getLaneParents().at(i + 1)->getGeometry().shape.front()}); // set connection shape (if exist). In other case, insert an empty shape for (auto j : getLaneParents().at(i)->getParentEdge().getGNEConnections()) { if (j->getLaneTo() == getLaneParents().at(i + 1)) { myGeometry.multiShape.back() = j->getGeometry().shape; } } } // append last shape myGeometry.multiShape.push_back(lastShape); // calculate multi shape rotation and lengths myGeometry.calculateMultiShapeRotationsAndLengths(); // calculate unified shape myGeometry.calculateMultiShapeUnified(); // Set block icon position myBlockIcon.position = myGeometry.multiShape.front().getLineCenter(); // check integrity checkE2MultilaneIntegrity(); } // Set offset of the block icon myBlockIcon.offset = Position(-0.75, 0); // Set block icon rotation, and using their rotation for draw logo myBlockIcon.setRotation(getLaneParents().front()); }