Position MSPerson::MSPersonStage::getEdgePosition(const MSEdge* e, SUMOReal at, SUMOReal offset) const { // @todo: well, definitely not the nicest way... Should be precomputed const MSLane* lane = e->getLanes()[0]; PositionVector shp = lane->getShape(); shp.move2side(offset); return shp.positionAtOffset(lane->interpolateLanePosToGeometryPos(at)); }
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 NBSign::writeAsPOI(OutputDevice& into, const NBEdge* edge) const { PositionVector shp = edge->getLanes()[0].shape; try { shp.move2side(3); } catch (InvalidArgument&) { // we do not write anything, maybe we should } Position pos = shp.positionAtOffset(myOffset); into.openTag(SUMO_TAG_POI); into.writeAttr(SUMO_ATTR_ID, edge->getID() + "." + toString(myOffset)); into.writeAttr(SUMO_ATTR_TYPE, SignTypeStrings.getString(myType)); switch (myType) { /// XXX @todo add default colors case SIGN_TYPE_SPEED: case SIGN_TYPE_SLOPE: case SIGN_TYPE_CITY: case SIGN_TYPE_INFO: into.writeAttr(SUMO_ATTR_COLOR, RGBColor::GREY); break; case SIGN_TYPE_YIELD: case SIGN_TYPE_STOP: case SIGN_TYPE_ALLWAY_STOP: case SIGN_TYPE_ON_RAMP: case SIGN_TYPE_RAIL_CROSSING: into.writeAttr(SUMO_ATTR_COLOR, RGBColor::RED); break; case SIGN_TYPE_PRIORITY: into.writeAttr(SUMO_ATTR_COLOR, RGBColor::YELLOW); break; case SIGN_TYPE_RIGHT_BEFORE_LEFT: into.writeAttr(SUMO_ATTR_COLOR, RGBColor(255, 153, 0, 255)); break; case SIGN_TYPE_ROUNDABOUT: into.writeAttr(SUMO_ATTR_COLOR, RGBColor::BLUE); break; } into.writeAttr(SUMO_ATTR_X, pos.x()); into.writeAttr(SUMO_ATTR_Y, pos.y()); into.writeAttr(SUMO_ATTR_ANGLE, 0); // XXX use road angle? // @todo add image resources and default images for all signs //into.writeAttr(SUMO_ATTR_IMGFILE, p->getImgFile()); //into.writeAttr(SUMO_ATTR_WIDTH, p->getWidth()); //into.writeAttr(SUMO_ATTR_HEIGHT, p->getHeight()); 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); } } }