30#include <jupedsim/jupedsim.h>
69 myNetwork(net), myShapeContainer(net->getShapeContainer()), myJPSDeltaT(
string2time(oc.getString(
"pedestrian.jupedsim.step-length"))),
70 myExitTolerance(oc.getFloat(
"pedestrian.jupedsim.exit-tolerance")), myGEOSPedestrianNetworkLargestComponent(nullptr),
71 myHaveAdditionalWalkableAreas(false) {
72 std::string model = oc.
getString(
"pedestrian.jupedsim.model");
73 if (model ==
"CollisionFreeSpeed") {
75 }
else if (model ==
"CollisionFreeSpeedV2") {
77 }
else if (model ==
"GeneralizedCentrifugalForce") {
79 }
else if (model ==
"SocialForce") {
90 (*myPythonScript) <<
"while simulation.agent_count() > 0 and simulation.iteration_count() < 160 * 100: simulation.iterate()\n";
110 JPS_Point orientation;
111 if (fabs(angle -
M_PI / 2) < NUMERICAL_EPS) {
112 orientation = JPS_Point{0., 1.};
113 }
else if (fabs(angle +
M_PI / 2) < NUMERICAL_EPS) {
114 orientation = JPS_Point{0., -1.};
116 orientation = JPS_Point{1., tan(angle)};
119 JPS_AgentId agentId = 0;
120 JPS_ErrorMessage message =
nullptr;
124 JPS_CollisionFreeSpeedModelAgentParameters agentParameters{};
125 agentParameters.position = {p.
x(), p.
y()};
127 agentParameters.stageId = state->
getStageId();
129 agentParameters.radius =
getRadius(type);
130 agentId = JPS_Simulation_AddCollisionFreeSpeedModelAgent(
myJPSSimulation, agentParameters, &message);
134 JPS_CollisionFreeSpeedModelV2AgentParameters agentParameters{};
135 agentParameters.position = {p.
x(), p.
y()};
137 agentParameters.stageId = state->
getStageId();
139 agentParameters.radius =
getRadius(type);
140 agentId = JPS_Simulation_AddCollisionFreeSpeedModelV2Agent(
myJPSSimulation, agentParameters, &message);
144 JPS_GeneralizedCentrifugalForceModelAgentParameters agentParameters{};
145 agentParameters.position = {p.
x(), p.
y()};
146 agentParameters.orientation = orientation;
148 agentParameters.stageId = state->
getStageId();
150 agentId = JPS_Simulation_AddGeneralizedCentrifugalForceModelAgent(
myJPSSimulation, agentParameters, &message);
154 JPS_SocialForceModelAgentParameters agentParameters{};
155 agentParameters.position = {p.
x(), p.
y()};
156 agentParameters.orientation = orientation;
158 agentParameters.stageId = state->
getStageId();
160 agentParameters.radius =
getRadius(type);
161 agentId = JPS_Simulation_AddSocialForceModelAgent(
myJPSSimulation, agentParameters, &message);
165 if (message !=
nullptr) {
167 JPS_ErrorMessage_Free(message);
176 JPS_ErrorMessage message =
nullptr;
177 if (predecessor != 0) {
178 const JPS_Transition transition = JPS_Transition_CreateFixedTransition(stage, &message);
179 if (message !=
nullptr) {
180 WRITE_WARNINGF(
TL(
"Error while creating fixed transition for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
181 JPS_ErrorMessage_Free(message);
184 JPS_JourneyDescription_SetTransitionForStage(journey, predecessor, transition, &message);
185 if (message !=
nullptr) {
186 WRITE_WARNINGF(
TL(
"Error while setting transition for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
187 JPS_ErrorMessage_Free(message);
190 JPS_Transition_Free(transition);
192 JPS_JourneyDescription_AddStage(journey, stage);
200 JPS_ErrorMessage message =
nullptr;
201 const Position& coords = std::get<1>(waypoint);
202 const JPS_StageId waypointId = JPS_Simulation_AddStageWaypoint(
myJPSSimulation, {coords.
x(), coords.
y()},
203 std::get<2>(waypoint), &message);
204 if (message !=
nullptr) {
205 WRITE_WARNINGF(
TL(
"Error while adding waypoint for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
206 JPS_ErrorMessage_Free(message);
209 const JPS_StageId waiting = std::get<0>(waypoint);
212 (*myPythonScript) <<
"journey.add(" << waiting <<
")\n";
213 if (predecessor != 0) {
214 (*myPythonScript) <<
"journey.set_transition_for_stage(" << predecessor <<
", jps.Transition.create_fixed_transition(" << waiting <<
"))\n";
217 if (!
addStage(journey, predecessor, agentID, waiting)) {
222 (*myPythonScript) <<
"ws = simulation.add_waypoint_stage((" << coords.
x() <<
"," << coords.
y() <<
"), " << std::get<2>(waypoint) <<
")\n"
224 if (predecessor != 0) {
225 (*myPythonScript) <<
"journey.set_transition_for_stage(" << predecessor <<
", jps.Transition.create_fixed_transition(ws))\n";
228 if (!
addStage(journey, predecessor, agentID, waypointId)) {
240 const MSLane*
const departureLane = getSidewalk<MSEdge, MSLane>(stage->
getRoute().front());
241 if (departureLane ==
nullptr) {
242 const char* error =
TL(
"Person '%' could not find sidewalk on edge '%', time=%.");
255 if (tazShape ==
nullptr) {
268 const double halfDepartureLaneWidth = departureLane->
getWidth() / 2.0;
271 departureRelativePositionY = 0.0;
274 departureRelativePositionY =
RandHelper::rand(-halfDepartureLaneWidth, halfDepartureLaneWidth);
279 std::vector<WaypointDesc> waypoints;
280 const MSEdge* prev =
nullptr;
282 const MSLane*
const lane = getSidewalk<MSEdge, MSLane>(e);
283 JPS_StageId waitingStage = 0;
284 if (prev !=
nullptr) {
294 for (
const MSEdge*
const ce : crossingRoute) {
295 if (ce->isCrossing()) {
296 const MSLane*
const crossing = getSidewalk<MSEdge, MSLane>(ce);
298 const MSLane*
const prevLane = getSidewalk<MSEdge, MSLane>(prev);
301 if (crossing->
getShape().front().distanceSquaredTo(startPos) < crossing->
getShape().back().distanceSquaredTo(startPos)) {
313 waypoints.push_back({waitingStage, lane->
getShape().positionAtOffset(e->getLength() / 2.), lane->
getWidth() / 2.});
316 const JPS_StageId finalWait = std::get<0>(waypoints.back());
317 waypoints.pop_back();
318 if (!waypoints.empty()) {
319 waypoints.erase(waypoints.begin());
325 JPS_JourneyDescription journeyDesc = JPS_JourneyDescription_Create();
327 (*myPythonScript) <<
"\njourney = jps.JourneyDescription()\n";
329 JPS_StageId startingStage = 0;
330 JPS_StageId predecessor = 0;
331 for (
const auto& p : waypoints) {
333 JPS_JourneyDescription_Free(journeyDesc);
336 if (startingStage == 0) {
337 startingStage = std::get<0>(waypoints.front()) == 0 ? predecessor : std::get<0>(waypoints.front());
340 JPS_ErrorMessage message =
nullptr;
341 JPS_JourneyId journeyId = JPS_Simulation_AddJourney(
myJPSSimulation, journeyDesc, &message);
342 JPS_JourneyDescription_Free(journeyDesc);
343 if (message !=
nullptr) {
344 WRITE_WARNINGF(
TL(
"Error while adding a journey for person '%': %"), person->
getID(), JPS_ErrorMessage_GetMessage(message));
345 JPS_ErrorMessage_Free(message);
351 if (pstate->getPerson() == person) {
356 if (state ==
nullptr) {
357 state =
new PState(
static_cast<MSPerson*
>(person), stage, journeyId, startingStage, waypoints);
359 state->
setPosition(departurePosition.
x(), departurePosition.
y());
364 state->
reinit(stage, journeyId, startingStage, waypoints);
370 (*myPythonScript) <<
"journey_id = simulation.add_journey(journey)\n"
371 "simulation.add_agent(jps.CollisionFreeSpeedModelAgentParameters(journey_id=journey_id,stage_id="
372 << startingStage <<
",position=(" << departurePosition.
x() <<
"," << departurePosition.
y()
377 if (message !=
nullptr) {
378 WRITE_WARNINGF(
TL(
"Error while switching to a new journey for person '%': %"), person->
getID(), JPS_ErrorMessage_GetMessage(message));
379 JPS_ErrorMessage_Free(message);
390 if (pstate->
getLane() !=
nullptr) {
392 peds.erase(std::find(peds.begin(), peds.end(), pstate));
394 if (pstate->
getStage() !=
nullptr) {
404 JPS_ErrorMessage message =
nullptr;
405 for (
int i = 0; i < nbrIterations; ++i) {
409 WRITE_ERRORF(
TL(
"Error during iteration %: %"), i, JPS_ErrorMessage_GetMessage(message));
417 PState*
const state = *stateIt;
431 if (stage ==
nullptr) {
442 const JPS_Point position = JPS_Agent_GetPosition(agent);
446 const JPS_Point orientation = JPS_Agent_GetOrientation(agent);
447 state->
setAngle(atan2(orientation.y, orientation.x));
450 Position newPosition(position.x, position.y);
454 double bestDistance = std::numeric_limits<double>::max();
455 MSLane* candidateLane =
nullptr;
456 double candidateLaneLongitudinalPosition = 0.0;
459 forwardRoute, 0, person->
getVClass(),
true, bestDistance, &candidateLane, candidateLaneLongitudinalPosition, routeOffset);
462 if (candidateLane != state->
getLane()) {
463 if (state->
getLane() !=
nullptr) {
466 peds.erase(std::find(peds.begin(), peds.end(), state));
477 const bool arrived = stage->
moveToNextEdge(person, time, 1,
nullptr);
485 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState(agent,
nullptr);
486 if (newMaxSpeed != JPS_CollisionFreeSpeedModelState_GetV0(modelState)) {
487 JPS_CollisionFreeSpeedModelState_SetV0(modelState, newMaxSpeed);
492 JPS_CollisionFreeSpeedModelV2State modelState = JPS_Agent_GetCollisionFreeSpeedModelV2State(agent,
nullptr);
493 if (newMaxSpeed != JPS_CollisionFreeSpeedModelV2State_GetV0(modelState)) {
494 JPS_CollisionFreeSpeedModelV2State_SetV0(modelState, newMaxSpeed);
499 JPS_GeneralizedCentrifugalForceModelState modelState = JPS_Agent_GetGeneralizedCentrifugalForceModelState(agent,
nullptr);
500 if (newMaxSpeed != JPS_GeneralizedCentrifugalForceModelState_GetV0(modelState)) {
501 JPS_GeneralizedCentrifugalForceModelState_SetV0(modelState, newMaxSpeed);
506 JPS_SocialForceModelState modelState = JPS_Agent_GetSocialForceModelState(agent,
nullptr);
507 if (newMaxSpeed != JPS_SocialForceModelState_GetDesiredSpeed(modelState)) {
508 JPS_SocialForceModelState_SetDesiredSpeed(modelState, newMaxSpeed);
514 const double speed = person->
getSpeed();
515 for (
int offset = 0; offset < 2; offset++) {
517 if (waypoint !=
nullptr && std::get<0>(*waypoint) != 0) {
518 const JPS_StageId waitingStage = std::get<0>(*waypoint);
526 const double passingClearanceTime = person->
getFloatParam(
"pedestrian.timegap-crossing");
528 person->
getImpatience(), speed, 0, 0,
nullptr,
false, person);
529 const auto proxy = JPS_Simulation_GetWaitingSetProxy(
myJPSSimulation, waitingStage, &message);
530 JPS_WaitingSetProxy_SetWaitingSetState(proxy, open ? JPS_WaitingSet_Inactive : JPS_WaitingSet_Active);
535 const double slack = person->
getMaxSpeed() *
TS / 2. + POSITION_EPS;
541 const JPS_AgentId agentID = state->
getAgentId();
555 const std::vector<JPS_Point>& areaBoundary = area.areaBoundary;
556 JPS_AgentIdIterator agentsInArea = JPS_Simulation_AgentsInPolygon(
myJPSSimulation, areaBoundary.data(), areaBoundary.size());
557 if (area.areaType ==
"vanishing_area") {
558 const SUMOTime period = area.params.count(
"period") > 0 ?
string2time(area.params.at(
"period")) : 1000;
559 const int nbrPeriodsCoveringTimestep = (int)ceil(
TS /
STEPS2TIME(period));
560 if (time - area.lastRemovalTime >= nbrPeriodsCoveringTimestep * period) {
561 for (
int k = 0; k < nbrPeriodsCoveringTimestep; k++) {
562 const JPS_AgentId agentID = JPS_AgentIdIterator_Next(agentsInArea);
564 auto lambda = [agentID](
const PState *
const p) {
565 return p->getAgentId() == agentID;
569 const PState*
const state = *iterator;
574 WRITE_MESSAGEF(
TL(
"Person '%' in vanishing area '%' was removed from the simulation."), person->
getID(), area.id);
578 area.lastRemovalTime = time;
585 for (JPS_AgentId agentID = JPS_AgentIdIterator_Next(agentsInArea); agentID != 0; agentID = JPS_AgentIdIterator_Next(agentsInArea)) {
586 if (area.params.count(
"speed") > 0) {
587 const JPS_Agent agent = JPS_Simulation_GetAgent(
myJPSSimulation, agentID,
nullptr);
591 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState(agent,
nullptr);
592 if (newMaxSpeed != JPS_CollisionFreeSpeedModelState_GetV0(modelState)) {
593 JPS_CollisionFreeSpeedModelState_SetV0(modelState, newMaxSpeed);
598 JPS_CollisionFreeSpeedModelV2State modelState = JPS_Agent_GetCollisionFreeSpeedModelV2State(agent,
nullptr);
599 if (newMaxSpeed != JPS_CollisionFreeSpeedModelV2State_GetV0(modelState)) {
600 JPS_CollisionFreeSpeedModelV2State_SetV0(modelState, newMaxSpeed);
605 JPS_GeneralizedCentrifugalForceModelState modelState = JPS_Agent_GetGeneralizedCentrifugalForceModelState(agent,
nullptr);
606 if (newMaxSpeed != JPS_GeneralizedCentrifugalForceModelState_GetV0(modelState)) {
607 JPS_GeneralizedCentrifugalForceModelState_SetV0(modelState, newMaxSpeed);
612 JPS_SocialForceModelState modelState = JPS_Agent_GetSocialForceModelState(agent,
nullptr);
613 if (newMaxSpeed != JPS_SocialForceModelState_GetDesiredSpeed(modelState)) {
614 JPS_SocialForceModelState_SetDesiredSpeed(modelState, newMaxSpeed);
622 JPS_AgentIdIterator_Free(agentsInArea);
627 std::vector<SUMOTrafficObject::NumericalID> allStoppedTrainIDs;
628 std::vector<const MSVehicle*> allStoppedTrains;
629 for (
const auto& stop : stoppingPlaces) {
630 std::vector<const SUMOVehicle*> stoppedTrains = stop.second->getStoppedVehicles();
632 allStoppedTrainIDs.push_back(train->getNumericalID());
633 allStoppedTrains.push_back(
dynamic_cast<const MSVehicle*
>(train));
638 if (!allStoppedTrainIDs.empty()) {
639 std::vector<GEOSGeometry*> carriagePolygons;
640 std::vector<GEOSGeometry*> rampPolygons;
641 for (
const MSVehicle* train : allStoppedTrains) {
642 if (train->getLeavingPersonNumber() > 0) {
645 const std::vector<MSTrainHelper::Carriage*>& carriages = trainHelper.
getCarriages();
647 Position dir = carriage->front - carriage->back;
656 carriageShape.push_back(carriage->front + perp * p);
657 carriageShape.push_back(carriage->back + perp * p);
658 carriageShape.push_back(carriage->back - perp * p);
659 carriageShape.push_back(carriage->front - perp * p);
664 for (
const Position& door : carriage->doorPositions) {
666 rampShape.push_back(door - perp * p + dir * d);
667 rampShape.push_back(door - perp * p - dir * d);
668 rampShape.push_back(door + perp * p - dir * d);
669 rampShape.push_back(door + perp * p + dir * d);
675 if (!carriagePolygons.empty()) {
676 GEOSGeometry* carriagesCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, carriagePolygons.data(), (
unsigned int)carriagePolygons.size());
677 GEOSGeometry* rampsCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, rampPolygons.data(), (
unsigned int)rampPolygons.size());
678 GEOSGeometry* carriagesAndRampsUnion = GEOSUnion(carriagesCollection, rampsCollection);
679 if (carriagesAndRampsUnion ==
nullptr) {
683#ifdef DEBUG_GEOMETRY_GENERATION
686 int nbrComponents = 0;
687 double maxArea = 0.0;
688 double totalArea = 0.0;
689 const GEOSGeometry* pedestrianNetworkWithTrainsAndRampsLargestComponent =
getLargestComponent(pedestrianNetworkWithTrainsAndRamps, nbrComponents, maxArea, totalArea);
690 if (nbrComponents > 1) {
691 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
692 nbrComponents, maxArea / totalArea * 100.0,
"%");
694#ifdef DEBUG_GEOMETRY_GENERATION
701 GEOSGeom_destroy(pedestrianNetworkWithTrainsAndRamps);
703 GEOSGeom_destroy(rampsCollection);
704 GEOSGeom_destroy(carriagesCollection);
713 JPS_ErrorMessage_Free(message);
734 GEOSGeometry* lineString = GEOSGeom_createLineString(coordinateSequence);
736 GEOSGeom_destroy(lineString);
737 return dilatedLineString;
744 if (shape.size() == 1) {
745 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is just a point."), shapeID, junctionID);
749 if (shape.back() != shape.front()) {
750 shape.push_back(shape.front());
754 cleanShape.push_back(shape[0]);
756 for (
int i = 1; i < (int)shape.size(); i++) {
757 if (shape[i] != shape[i - 1]) {
758 cleanShape.push_back(shape[i]);
760 duplicates.push_back(shape[i]);
763 if (cleanShape.size() < shape.size()) {
764 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' had some equal consecutive points removed: %"), shapeID, junctionID,
toString(duplicates, 9));
767 GEOSGeometry* linearRing = GEOSGeom_createLinearRing(coordinateSequence);
768 GEOSGeometry* polygon = GEOSGeom_createPolygon(linearRing,
nullptr, 0);
770 if (!GEOSisValid(polygon)) {
771 if (cleanShape.size() == 3) {
772 if (isInternalShape) {
773 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been dilated as it is just a segment."), shapeID, junctionID);
775 WRITE_WARNINGF(
TL(
"Polygon '%' has been dilated as it is just a segment."), shapeID);
777 GEOSGeometry* lineString = GEOSGeom_createLineString(GEOSCoordSeq_clone(coordinateSequence));
778 GEOSGeom_destroy(polygon);
780 GEOSGeom_destroy(lineString);
782 if (isInternalShape) {
783 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been replaced by its convex hull as it is not simple."), shapeID, junctionID);
784 GEOSGeometry* hull = GEOSConvexHull(polygon);
785 GEOSGeom_destroy(polygon);
788 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is not simple."), shapeID, junctionID);
797 if (isInternalShape) {
807 std::vector<GEOSGeometry*> walkableAreas;
809 const MSLane*
const lane = getSidewalk<MSEdge, MSLane>(edge);
810 if (lane !=
nullptr) {
811 GEOSGeometry* dilatedLane =
nullptr;
812 if (edge->isWalkingArea()) {
814 }
else if (edge->isCrossing()) {
816 if (outlineShape !=
nullptr) {
819 if (dilatedLane !=
nullptr) {
820 walkableAreas.push_back(dilatedLane);
830 if (dilatedLane !=
nullptr) {
831 walkableAreas.push_back(dilatedLane);
836 const MSJunction*
const junction = junctionWithID.second;
837 int pedEdgeCount = 0;
838 bool hasWalkingArea =
false;
842 for (
const MSEdge*
const edge : edges) {
843 if (edge->isWalkingArea()) {
844 hasWalkingArea =
true;
847 if (getSidewalk<MSEdge, MSLane>(edge) !=
nullptr) {
851 if (hasWalkingArea) {
855 if (!hasWalkingArea && pedEdgeCount > 1) {
858 if (walkingAreaGeom !=
nullptr) {
859 walkableAreas.push_back(walkingAreaGeom);
865 std::vector<GEOSGeometry*> additionalObstacles;
867 if (polygonWithID.second->getShapeType() ==
"jupedsim.walkable_area" || polygonWithID.second->getShapeType() ==
"taz") {
868 GEOSGeometry* walkableArea =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
869 if (walkableArea !=
nullptr) {
870 walkableAreas.push_back(walkableArea);
873 }
else if (polygonWithID.second->getShapeType() ==
"jupedsim.obstacle") {
874 GEOSGeometry* additionalObstacle =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
875 if (additionalObstacle !=
nullptr) {
876 additionalObstacles.push_back(additionalObstacle);
882 GEOSGeometry* disjointWalkableAreas = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, walkableAreas.data(), (
unsigned int)walkableAreas.size());
883#ifdef DEBUG_GEOMETRY_GENERATION
886 GEOSGeometry* initialWalkableAreas = GEOSUnaryUnion(disjointWalkableAreas);
887#ifdef DEBUG_GEOMETRY_GENERATION
888 dumpGeometry(initialWalkableAreas,
"initialWalkableAreas.wkt");
890 GEOSGeom_destroy(disjointWalkableAreas);
893 GEOSGeometry* disjointAdditionalObstacles = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, additionalObstacles.data(), (
unsigned int)additionalObstacles.size());
894#ifdef DEBUG_GEOMETRY_GENERATION
897 GEOSGeometry* additionalObstaclesUnion = GEOSUnaryUnion(disjointAdditionalObstacles);
898#ifdef DEBUG_GEOMETRY_GENERATION
899 dumpGeometry(additionalObstaclesUnion,
"additionalObstaclesUnion.wkt");
901 GEOSGeometry* finalWalkableAreas = GEOSDifference(initialWalkableAreas, additionalObstaclesUnion);
902#ifdef DEBUG_GEOMETRY_GENERATION
903 dumpGeometry(finalWalkableAreas,
"finalWalkableAreas.wkt");
905 GEOSGeom_destroy(initialWalkableAreas);
906 GEOSGeom_destroy(additionalObstaclesUnion);
907 GEOSGeom_destroy(disjointAdditionalObstacles);
909 if (!GEOSisSimple(finalWalkableAreas)) {
910 throw ProcessError(
TL(
"Union of walkable areas minus union of obstacles is not a simple polygon."));
913 return finalWalkableAreas;
919 GEOSCoordSequence* coordinateSequence = GEOSCoordSeq_create((
unsigned int)shape.size(), 2);
920 for (
int i = 0; i < (int)shape.size(); i++) {
921 GEOSCoordSeq_setXY(coordinateSequence, i, shape[i].x(), shape[i].y());
923 return coordinateSequence;
930 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
931 unsigned int coordinateSequenceSize;
932 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
935 for (
unsigned int i = 0; i < coordinateSequenceSize; i++) {
936 GEOSCoordSeq_getX(coordinateSequence, i, &x);
937 GEOSCoordSeq_getY(coordinateSequence, i, &y);
938 coordinateVector.push_back(
Position(x, y));
940 return coordinateVector;
944std::vector<JPS_Point>
946 std::vector<JPS_Point> pointVector;
947 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
948 unsigned int coordinateSequenceSize;
949 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
953 for (
unsigned int i = 0; i < coordinateSequenceSize - 1; i++) {
954 GEOSCoordSeq_getX(coordinateSequence, i, &x);
955 GEOSCoordSeq_getY(coordinateSequence, i, &y);
956 pointVector.push_back({x, y});
965 GEOSGeometry* linearRingAsPolygon = GEOSGeom_createPolygon(GEOSGeom_clone(linearRing),
nullptr, 0);
966 GEOSArea(linearRingAsPolygon, &area);
967 GEOSGeom_destroy(linearRingAsPolygon);
980 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
984 std::vector<PositionVector> holes;
985 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
986 if (nbrInteriorRings != -1) {
987 for (
int k = 0; k < nbrInteriorRings; k++) {
988 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1002 nbrComponents = GEOSGetNumGeometries(polygon);
1003 const GEOSGeometry* largestComponent =
nullptr;
1006 for (
int i = 0; i < nbrComponents; i++) {
1007 const GEOSGeometry* componentPolygon = GEOSGetGeometryN(polygon, i);
1009 GEOSArea(componentPolygon, &area);
1011 if (area > maxArea) {
1013 largestComponent = componentPolygon;
1016 return largestComponent;
1022 JPS_GeometryBuilder geometryBuilder = JPS_GeometryBuilder_Create();
1025 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1027 JPS_GeometryBuilder_AddAccessibleArea(geometryBuilder, exteriorCoordinates.data(), exteriorCoordinates.size());
1030 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1031 if (nbrInteriorRings != -1) {
1032 for (
int k = 0; k < nbrInteriorRings; k++) {
1033 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1037 JPS_GeometryBuilder_ExcludeFromAccessibleArea(geometryBuilder, holeCoordinates.data(), holeCoordinates.size());
1042 JPS_ErrorMessage message =
nullptr;
1043 JPS_Geometry geometry = JPS_GeometryBuilder_Build(geometryBuilder, &message);
1044 if (geometry ==
nullptr) {
1045 const std::string error =
TLF(
"Error while generating geometry: %", JPS_ErrorMessage_GetMessage(message));
1046 JPS_ErrorMessage_Free(message);
1049 JPS_GeometryBuilder_Free(geometryBuilder);
1056 GEOSGeometry* polygonGeoCoordinates =
nullptr;
1057 if (useGeoCoordinates) {
1058 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1060 for (
Position& position : exteriorPoints) {
1063 const int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1064 std::vector<GEOSGeometry*> holeRings;
1065 if (nbrInteriorRings != -1) {
1066 for (
int k = 0; k < nbrInteriorRings; k++) {
1067 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1069 for (
Position& position : holePoints) {
1073 GEOSGeometry* holeRing = GEOSGeom_createLinearRing(holeRingCoords);
1074 holeRings.push_back(holeRing);
1078 GEOSGeometry* exteriorRing = GEOSGeom_createLinearRing(exteriorRingCoords);
1079 polygonGeoCoordinates = GEOSGeom_createPolygon(exteriorRing, holeRings.data(), nbrInteriorRings);
1081 std::ofstream dumpFile;
1082 dumpFile.open(filename);
1083 GEOSWKTWriter* writer = GEOSWKTWriter_create();
1085 char* wkt = GEOSWKTWriter_write(writer, polygonGeoCoordinates ==
nullptr ? polygon : polygonGeoCoordinates);
1086 dumpFile << wkt << std::endl;
1089 GEOSWKTWriter_destroy(writer);
1090 GEOSGeom_destroy(polygonGeoCoordinates);
1102 JPS_ErrorMessage message =
nullptr;
1103 JPS_StageId waitingStage = 0;
1107 const double offset = 2 * radius + POSITION_EPS;
1108 const double lonOffset = entry ? NUMERICAL_EPS : shape.
length() - NUMERICAL_EPS;
1111 for (
double latOff = offset; latOff < crossing->
getWidth() / 2. - offset; latOff += offset) {
1121 pv.push_back(crossing->
getIncomingLanes().front().lane->getShape().getCentroid());
1123 if (!entry && crossing->
getLinkCont().size() == 1 && crossing->
getLinkCont().front()->getLane()->isWalkingArea()) {
1124 pv.push_back(crossing->
getLinkCont().front()->getLane()->getShape().getCentroid());
1126 std::vector<JPS_Point> points;
1128 GEOSGeometry* point = GEOSGeom_createPointFromXY(p.x(), p.y());
1130 points.push_back({p.x(), p.y()});
1132 GEOSGeom_destroy(point);
1134 waitingStage = JPS_Simulation_AddStageWaitingSet(
myJPSSimulation, points.data(), points.size(), &message);
1135 if (message !=
nullptr) {
1136 const std::string error =
TLF(
"Error while adding waiting set for % on '%': %",
1137 entry ?
"entry" :
"exit", crossing->
getID(), JPS_ErrorMessage_GetMessage(message));
1138 JPS_ErrorMessage_Free(message);
1141 const auto proxy = JPS_Simulation_GetWaitingSetProxy(
myJPSSimulation, waitingStage, &message);
1142 JPS_WaitingSetProxy_SetWaitingSetState(proxy, JPS_WaitingSet_Inactive);
1145 (*myPythonScript) <<
"ws = simulation.add_waiting_set_stage([";
1146 for (
const JPS_Point& p : points) {
1147 (*myPythonScript) <<
"(" << p.x <<
"," << p.y <<
"),";
1149 (*myPythonScript) <<
"])\nsimulation.get_stage(ws).state = jps.stages.WaitingSetState.INACTIVE\n";
1151 return waitingStage;
1157 initGEOS(
nullptr,
nullptr);
1160 int nbrComponents = 0;
1161 double maxArea = 0.0;
1162 double totalArea = 0.0;
1164 if (nbrComponents > 1) {
1165 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
1166 nbrComponents, maxArea / totalArea * 100.0,
"%");
1168#ifdef DEBUG_GEOMETRY_GENERATION
1171 const std::string filename = oc.
getString(
"pedestrian.jupedsim.wkt");
1172 if (!filename.empty()) {
1180 JPS_ErrorMessage message =
nullptr;
1182 double strengthGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.strength-geometry-repulsion");
1183 double rangeGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.range-geometry-repulsion");
1185 if (oc.
isDefault(
"pedestrian.jupedsim.strength-geometry-repulsion") && oc.
isDefault(
"pedestrian.jupedsim.range-geometry-repulsion")) {
1186 WRITE_MESSAGE(
TL(
"Adapting geometry repulsion default values for jupedsim timestep of 0.02."));
1187 strengthGeometryRepulsion = 35.;
1188 rangeGeometryRepulsion = 0.019;
1194 JPS_CollisionFreeSpeedModelBuilder modelBuilder = JPS_CollisionFreeSpeedModelBuilder_Create(
1195 oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"),
1196 oc.
getFloat(
"pedestrian.jupedsim.range-neighbor-repulsion"),
1197 strengthGeometryRepulsion,
1198 rangeGeometryRepulsion);
1200 JPS_CollisionFreeSpeedModelBuilder_Free(modelBuilder);
1204 JPS_CollisionFreeSpeedModelV2Builder modelBuilder = JPS_CollisionFreeSpeedModelV2Builder_Create();
1206 JPS_CollisionFreeSpeedModelV2Builder_Free(modelBuilder);
1210 JPS_GeneralizedCentrifugalForceModelBuilder modelBuilder = JPS_GeneralizedCentrifugalForceModelBuilder_Create(
1211 oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"),
1212 strengthGeometryRepulsion,
1220 JPS_GeneralizedCentrifugalForceModelBuilder_Free(modelBuilder);
1224 JPS_SocialForceModelBuilder modelBuilder = JPS_SocialForceModelBuilder_Create(120000.0, 240000.0);
1226 JPS_SocialForceModelBuilder_Free(modelBuilder);
1232 const std::string error =
TLF(
"Error creating the pedestrian model: %", JPS_ErrorMessage_GetMessage(message));
1233 JPS_ErrorMessage_Free(message);
1238 const std::string error =
TLF(
"Error creating the simulation: %", JPS_ErrorMessage_GetMessage(message));
1239 JPS_ErrorMessage_Free(message);
1244 const SUMOPolygon*
const poly = polygonWithID.second;
1246 std::vector<JPS_Point> areaBoundary;
1248 areaBoundary.push_back({p.x(), p.y()});
1251 if (areaBoundary.back().x == areaBoundary.front().x && areaBoundary.back().y == areaBoundary.front().y) {
1252 areaBoundary.pop_back();
1261 (*myPythonScript) <<
"import jupedsim as jps\nimport shapely\n\n"
1262 "with open('" << filename <<
"') as f: geom = shapely.from_wkt(f.read())\n"
1263 "simulation = jps.Simulation(dt=" <<
STEPS2TIME(
myJPSDeltaT) <<
", model=jps.CollisionFreeSpeedModel(), geometry=geom,\n"
1264 "trajectory_writer=jps.SqliteTrajectoryWriter(output_file='out.sql'))\n";
1268 crossing.second.first =
addWaitingSet(crossing.first,
true);
1269 crossing.second.second =
addWaitingSet(crossing.first,
false);
1278 JPS_JourneyId journeyId, JPS_StageId stageId,
1279 const std::vector<WaypointDesc>& waypoints) :
1281 myJourneyId(journeyId), myStageId(stageId), myWaypoints(waypoints), myAgentId(0) {
1288 const std::vector<WaypointDesc>& waypoints) {
1289 if (myStage !=
nullptr) {
1290 myStage->setPState(
nullptr);
1293 myJourneyId = journeyId;
1294 myStageId = stageId;
1295 myWaypoints = waypoints;
1309 myRemoteXYPos.set(x, y);
1320 return offset < (int)myWaypoints.size() ? &myWaypoints[offset] :
nullptr;
std::vector< const MSEdge * > ConstMSEdgeVector
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
#define WRITE_ERRORF(...)
#define WRITE_MESSAGE(msg)
#define WRITE_WARNING(msg)
#define PROGRESS_DONE_MESSAGE()
#define PROGRESS_BEGIN_MESSAGE(msg)
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
const std::string DEFAULT_PEDTYPE_ID
@ RANDOM_LOCATION
The position may be chosen freely in a polygon defined by a taz.
@ SUMO_TAG_BUS_STOP
A bus stop.
const double SUMO_const_laneWidth
#define UNUSED_PARAMETER(x)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A class that stores a 2D geometrical boundary.
double ymin() const
Returns minimum y-coordinate.
double xmin() const
Returns minimum x-coordinate.
double ymax() const
Returns maximum y-coordinate.
double xmax() const
Returns maximum x-coordinate.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
const MSEdgeVector & getEdges() const
Returns loaded edges.
A road/street connecting two junctions.
bool isNormal() const
return whether this edge is an internal edge
const MSJunction * getToJunction() const
const MSJunction * getFromJunction() const
bool isTazConnector() const
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
The base class for an intersection.
const ConstMSEdgeVector & getOutgoing() const
const PositionVector & getShape() const
Returns this junction's shape.
const ConstMSEdgeVector & getIncoming() const
Representation of a lane in the micro simulation.
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
virtual const PositionVector & getShape(bool) const
MSEdge & getEdge() const
Returns the lane's edge.
const PositionVector * getOutlineShape() const
double getWidth() const
Returns the lane's width.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
bool opened(SUMOTime arrivalTime, double arrivalSpeed, double leaveSpeed, double vehicleLength, double impatience, double decel, SUMOTime waitingTime, double posLat=0, BlockingFoes *collectFoes=nullptr, bool ignoreRed=false, const SUMOTrafficObject *ego=nullptr, double dist=-1) const
Returns the information whether the link may be passed.
const MSTrafficLightLogic * getTLLogic() const
Returns the TLS index.
The simulated network and simulation perfomer.
MSPedestrianRouter & getPedestrianRouter(const int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector()) const
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
MSJunctionControl & getJunctionControl()
Returns the junctions control.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
ShapeContainer & getShapeContainer()
Returns the shapes container.
MSEdgeControl & getEdgeControl()
Returns the edge control.
const NamedObjectCont< MSStoppingPlace * > & getStoppingPlaces(SumoXMLTag category) const
ActiveLanes myActiveLanes
store of all lanes which have pedestrians on them
int myNumActivePedestrians
the total number of active pedestrians
Container for pedestrian state and individual position update function.
MSStageMoving * getStage() const
return the current stage
int myDir
the walking direction on the current lane (1 forward, -1 backward)
virtual double getAngle(const MSStageMoving &, SUMOTime) const
return the current orientation in degrees
MSPerson * getPerson() const
return the represented person
bool isWaitingToEnter() const
whether the person still waits to entere the network
const MSLane * getLane() const
the current lane of the transportable
Holds pedestrian state and performs updates.
JPS_StageId getStageId() const
first stage of the journey
void setPosition(double x, double y)
void setAngle(double angle)
void setLane(MSLane *lane)
JPS_AgentId getAgentId() const
void setStage(MSStageMoving *const stage)
void setAgentId(JPS_AgentId id)
const MSPModel_JuPedSim::WaypointDesc * getNextWaypoint(const int offset=0) const
bool advanceNextWaypoint()
void setLanePosition(double lanePosition)
const MSEdge * getNextEdge(const MSStageMoving &stage) const override
return the list of internal edges if the transportable is on an intersection
JPS_JourneyId getJourneyId() const
PState(MSPerson *person, MSStageMoving *stage, JPS_JourneyId journeyId, JPS_StageId stageId, const std::vector< WaypointDesc > &waypoints)
void reinit(MSStageMoving *stage, JPS_JourneyId journeyId, JPS_StageId stageId, const std::vector< WaypointDesc > &waypoints)
Position getPosition(const MSStageMoving &, SUMOTime) const override
return the network coordinate of the transportable
JPS_StageId addWaitingSet(const MSLane *const crossing, const bool entry)
OutputDevice * myPythonScript
MSTransportableStateAdapter * add(MSTransportable *person, MSStageMoving *stage, SUMOTime now) override
register the given person as a pedestrian
void removePolygonFromDrawing(const std::string &polygonId)
const GEOSGeometry * myGEOSPedestrianNetworkLargestComponent
The GEOS polygon representing the largest (by area) connected component of the pedestrian network.
void preparePolygonForDrawing(const GEOSGeometry *polygon, const std::string &polygonId, const RGBColor &color)
static const RGBColor PEDESTRIAN_NETWORK_CARRIAGES_AND_RAMPS_COLOR
MSPModel_JuPedSim(const OptionsCont &oc, MSNet *net)
static const double GEOS_MITRE_LIMIT
@ GeneralizedCentrifugalForce
const double myExitTolerance
Threshold to decide if a pedestrian has ended its journey or not.
std::vector< SUMOTrafficObject::NumericalID > myAllStoppedTrainIDs
Array of stopped trains, used to detect whether to add carriages and ramps to the geometry.
bool addStage(JPS_JourneyDescription journey, JPS_StageId &predecessor, const std::string &agentID, const JPS_StageId stage)
void registerArrived(const JPS_AgentId agentID)
static GEOSGeometry * createGeometryFromCenterLine(PositionVector centerLine, double width, int capStyle)
static PositionVector convertToSUMOPoints(const GEOSGeometry *geometry)
static const std::string PEDESTRIAN_NETWORK_CARRIAGES_AND_RAMPS_ID
static const RGBColor PEDESTRIAN_NETWORK_COLOR
JPS_Geometry myJPSGeometry
The JPS polygon representing the largest connected component of the pedestrian network.
static const std::string PEDESTRIAN_NETWORK_ID
bool addWaypoint(JPS_JourneyDescription journey, JPS_StageId &predecessor, const std::string &agentID, const WaypointDesc &waypoint)
static GEOSGeometry * createGeometryFromShape(PositionVector shape, std::string junctionID=std::string(""), std::string shapeID=std::string(""), bool isInternalShape=false)
static GEOSCoordSequence * convertToGEOSPoints(PositionVector shape)
JPS_Simulation myJPSSimulation
GEOSGeometry * myGEOSPedestrianNetwork
The GEOS polygon containing all computed connected components of the pedestrian network.
static void dumpGeometry(const GEOSGeometry *polygon, const std::string &filename, bool useGeoCoordinates=false)
std::vector< AreaData > myAreas
Array of special areas.
bool myHaveAdditionalWalkableAreas
static std::vector< JPS_Point > convertToJPSPoints(const GEOSGeometry *geometry)
static JPS_Geometry buildJPSGeometryFromGEOSGeometry(const GEOSGeometry *polygon)
const SUMOTime myJPSDeltaT
Timestep used in the JuPedSim simulator.
MSNet *const myNetwork
The network on which the simulation runs.
std::map< JPS_StageId, const MSLane * > myCrossings
JPS_Geometry myJPSGeometryWithTrainsAndRamps
The JPS polygon representing the largest connected component plus carriages and ramps.
static const double CARRIAGE_RAMP_LENGTH
static const double GEOS_MIN_AREA
std::tuple< JPS_StageId, Position, double > WaypointDesc
void initialize(const OptionsCont &oc)
GEOSGeometry * buildPedestrianNetwork(MSNet *network)
void remove(MSTransportableStateAdapter *state) override
remove the specified person from the pedestrian simulation
static double getLinearRingArea(const GEOSGeometry *linearRing)
std::map< const MSLane *, std::pair< JPS_StageId, JPS_StageId > > myCrossingWaits
void clearState() override
Resets pedestrians when quick-loading state.
ShapeContainer & myShapeContainer
The shape container used to add polygons to the rendering pipeline.
std::vector< PState * > myPedestrianStates
JPS_OperationalModel myJPSOperationalModel
static const int GEOS_QUADRANT_SEGMENTS
static const std::vector< MSPModel_JuPedSim::PState * > noPedestrians
static const GEOSGeometry * getLargestComponent(const GEOSGeometry *polygon, int &nbrComponents, double &maxArea, double &totalArea)
static double getRadius(const MSVehicleType &vehType)
void tryPedestrianInsertion(PState *state, const Position &p)
SUMOTime execute(SUMOTime time)
static const double GEOS_BUFFERED_SEGMENT_WIDTH
static const int BACKWARD
static const double RANDOM_POS_LAT
magic value to encode randomized lateral offset for persons when starting a walk
static const int UNDEFINED_DIRECTION
static const double UNSPECIFIED_POS_LAT
the default lateral offset for persons when starting a walk
double getImpatience() const
const MSEdge * getDestination() const
returns the destination edge
virtual double getArrivalPos() const
virtual const MSEdge * getEdge() const
Returns the current edge.
virtual const MSEdge * getNextRouteEdge() const =0
ConstMSEdgeVector getEdges() const
the edges of the current stage
const std::vector< const MSEdge * > & getRoute() const
void setPState(MSTransportableStateAdapter *pstate)
double getDepartPosLat() const
const MSEdge * getEdge() const
Returns the current edge.
double getDepartPos() const
const std::vector< constMSEdge * >::iterator getRouteStep() const
virtual bool moveToNextEdge(MSTransportable *transportable, SUMOTime currentTime, int prevDir, MSEdge *nextInternal=nullptr, const bool isReplay=false)=0
move forward and return whether the transportable arrived
virtual double getMaxSpeed(const MSTransportable *const transportable=nullptr) const =0
the maximum speed of the transportable
bool moveToNextEdge(MSTransportable *person, SUMOTime currentTime, int prevDir, MSEdge *nextInternal=nullptr, const bool isReplay=false)
move forward and return whether the person arrived
void activateEntryReminders(MSTransportable *person, const bool isDepart=false)
add the move reminders for the current lane on entry
A class that helps computing positions of a train's carriages and additional structures.
void computeDoorPositions()
compute door positions on demand and fills the carriage structures
const std::vector< Carriage * > & getCarriages() const
static const double CARRIAGE_DOOR_WIDTH
average door width used to compute doors positions
double getHalfWidth() const
SUMOVehicleClass getVClass() const
Returns the object's access class.
MSStage * getNextStage(int offset) const
Return the next (or previous) stage denoted by the offset.
int getNumRemainingStages() const
Return the number of remaining stages (including the current)
virtual double getSpeed() const
the current speed of the transportable
MSStage * getCurrentStage() const
Return the current stage.
const MSVehicleType & getVehicleType() const
Returns the object's "vehicle" type.
int getCurrentStageIndex() const
Return the index of the current stage.
MSStageType getCurrentStageType() const
the current stage type of the transportable
const MSEdge * getEdge() const
Returns the current edge.
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
double getMaxSpeed() const
Returns the maximum speed (the minimum of desired and physical maximum speed)
abstract base class for managing callbacks to retrieve various state information from the model
Representation of a vehicle in the micro simulation.
The car-following model and parameter.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
double getLength() const
Get vehicle's length [m].
const std::string & getID() const
Returns the id.
T get(const std::string &id) const
Retrieves an item.
A storage for options typed value containers)
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
static bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="")
Creates the device using the output definition stored in the named option.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
void setPrecision(int precision=gPrecision)
Sets the precision or resets it to default.
double getDouble(const std::string &key, const double defaultValue) const
Returns the value for a given key converted to a double.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
double compute(const E *from, const E *to, double departPos, double arrivalPos, double speed, SUMOTime msTime, const N *onlyNode, std::vector< const E * > &into, bool allEdges=false)
Builds the route between the given edges using the minimum effort at the given time The definition of...
A point in 2D or 3D with translation and scaling methods.
void setx(double x)
set position x
static const Position INVALID
used to indicate that a position is valid
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
void norm2D()
Normalizes the given vector.
double x() const
Returns the x-position.
double length2D() const
Computes the length of the given vector neglecting the z coordinate.
void sety(double y)
set position y
double y() const
Returns the y-position.
double length() const
Returns the length.
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void extrapolate2D(const double val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
bool around(const Position &p, double offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
const PositionVector & getShape() const
Returns the shape of the polygon.
virtual void setHoles(const std::vector< PositionVector > &holes)
Sets the holes of the polygon.
double getFloatParam(const std::string ¶mName, const bool required=false, const double deflt=INVALID_DOUBLE) const
Retrieve a floating point parameter for the traffic object.
Representation of a vehicle.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
virtual bool removePolygon(const std::string &id, bool useLock=true)
Removes a polygon from the container.
const Polygons & getPolygons() const
Returns all polygons.
virtual bool addPolygon(const std::string &id, const std::string &type, const RGBColor &color, double layer, double angle, const std::string &imgFile, bool relativePath, const PositionVector &shape, bool geo, bool fill, double lineWidth, bool ignorePruning=false, const std::string &name=Shape::DEFAULT_NAME)
Builds a polygon using the given values and adds it to the container.
const std::string & getShapeType() const
Returns the (abstract) type of the Shape.
std::vector< std::string > getVector()
return vector of strings
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool moveToXYMap_matchingRoutePosition(const Position &pos, const std::string &origID, const ConstMSEdgeVector ¤tRoute, int routeIndex, SUMOVehicleClass vClass, bool setLateralPos, double &bestDistance, MSLane **lane, double &lanePos, int &routeOffset)
Structure that keeps data related to vanishing areas (and other types of areas).