30#include <jupedsim/jupedsim.h>
68 myNetwork(net), myShapeContainer(net->getShapeContainer()), myJPSDeltaT(
string2time(oc.getString(
"pedestrian.jupedsim.step-length"))),
69 myExitTolerance(oc.getFloat(
"pedestrian.jupedsim.exit-tolerance")), myGEOSPedestrianNetworkLargestComponent(nullptr),
70 myHaveAdditionalWalkableAreas(false) {
71 std::string model = oc.
getString(
"pedestrian.jupedsim.model");
72 if (model ==
"CollisionFreeSpeed") {
74 }
else if (model ==
"CollisionFreeSpeedV2") {
76 }
else if (model ==
"GeneralizedCentrifugalForce") {
78 }
else if (model ==
"SocialForce") {
89 (*myPythonScript) <<
"while simulation.agent_count() > 0 and simulation.iteration_count() < 160 * 100: simulation.iterate()\n";
109 JPS_Point orientation;
110 if (fabs(angle -
M_PI / 2) < NUMERICAL_EPS) {
111 orientation = JPS_Point{0., 1.};
112 }
else if (fabs(angle +
M_PI / 2) < NUMERICAL_EPS) {
113 orientation = JPS_Point{0., -1.};
115 orientation = JPS_Point{1., tan(angle)};
118 JPS_AgentId agentId = 0;
119 JPS_ErrorMessage message =
nullptr;
123 JPS_CollisionFreeSpeedModelAgentParameters agentParameters{};
124 agentParameters.position = {p.
x(), p.
y()};
126 agentParameters.stageId = state->
getStageId();
128 agentParameters.radius =
getRadius(type);
129 agentId = JPS_Simulation_AddCollisionFreeSpeedModelAgent(
myJPSSimulation, agentParameters, &message);
133 JPS_CollisionFreeSpeedModelV2AgentParameters agentParameters{};
134 agentParameters.position = {p.
x(), p.
y()};
136 agentParameters.stageId = state->
getStageId();
138 agentParameters.radius =
getRadius(type);
139 agentId = JPS_Simulation_AddCollisionFreeSpeedModelV2Agent(
myJPSSimulation, agentParameters, &message);
143 JPS_GeneralizedCentrifugalForceModelAgentParameters agentParameters{};
144 agentParameters.position = {p.
x(), p.
y()};
145 agentParameters.orientation = orientation;
147 agentParameters.stageId = state->
getStageId();
149 agentId = JPS_Simulation_AddGeneralizedCentrifugalForceModelAgent(
myJPSSimulation, agentParameters, &message);
153 JPS_SocialForceModelAgentParameters agentParameters{};
154 agentParameters.position = {p.
x(), p.
y()};
155 agentParameters.orientation = orientation;
157 agentParameters.stageId = state->
getStageId();
159 agentParameters.radius =
getRadius(type);
160 agentId = JPS_Simulation_AddSocialForceModelAgent(
myJPSSimulation, agentParameters, &message);
164 if (message !=
nullptr) {
166 JPS_ErrorMessage_Free(message);
175 JPS_ErrorMessage message =
nullptr;
176 if (predecessor != 0) {
177 const JPS_Transition transition = JPS_Transition_CreateFixedTransition(stage, &message);
178 if (message !=
nullptr) {
179 WRITE_WARNINGF(
TL(
"Error while creating fixed transition for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
180 JPS_ErrorMessage_Free(message);
183 JPS_JourneyDescription_SetTransitionForStage(journey, predecessor, transition, &message);
184 if (message !=
nullptr) {
185 WRITE_WARNINGF(
TL(
"Error while setting transition for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
186 JPS_ErrorMessage_Free(message);
189 JPS_Transition_Free(transition);
191 JPS_JourneyDescription_AddStage(journey, stage);
199 JPS_ErrorMessage message =
nullptr;
200 const Position& coords = std::get<1>(waypoint);
201 const JPS_StageId waypointId = JPS_Simulation_AddStageWaypoint(
myJPSSimulation, {coords.
x(), coords.
y()},
202 std::get<2>(waypoint), &message);
203 if (message !=
nullptr) {
204 WRITE_WARNINGF(
TL(
"Error while adding waypoint for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
205 JPS_ErrorMessage_Free(message);
208 const JPS_StageId waiting = std::get<0>(waypoint);
211 (*myPythonScript) <<
"journey.add(" << waiting <<
")\n";
212 if (predecessor != 0) {
213 (*myPythonScript) <<
"journey.set_transition_for_stage(" << predecessor <<
", jps.Transition.create_fixed_transition(" << waiting <<
"))\n";
216 if (!
addStage(journey, predecessor, agentID, waiting)) {
221 (*myPythonScript) <<
"ws = simulation.add_waypoint_stage((" << coords.
x() <<
"," << coords.
y() <<
"), " << std::get<2>(waypoint) <<
")\n"
223 if (predecessor != 0) {
224 (*myPythonScript) <<
"journey.set_transition_for_stage(" << predecessor <<
", jps.Transition.create_fixed_transition(ws))\n";
227 if (!
addStage(journey, predecessor, agentID, waypointId)) {
239 const MSLane*
const departureLane = getSidewalk<MSEdge, MSLane>(stage->
getRoute().front());
240 if (departureLane ==
nullptr) {
241 const char* error =
TL(
"Person '%' could not find sidewalk on edge '%', time=%.");
254 if (tazShape ==
nullptr) {
267 const double halfDepartureLaneWidth = departureLane->
getWidth() / 2.0;
270 departureRelativePositionY = 0.0;
273 departureRelativePositionY =
RandHelper::rand(-halfDepartureLaneWidth, halfDepartureLaneWidth);
278 std::vector<WaypointDesc> waypoints;
279 const MSEdge* prev =
nullptr;
281 const MSLane*
const lane = getSidewalk<MSEdge, MSLane>(e);
282 JPS_StageId waitingStage = 0;
283 if (prev !=
nullptr) {
295 const MSEdge* wa =
nullptr;
296 for (
const MSEdge*
const ce : crossingRoute) {
297 if (ce->isCrossing()) {
298 const MSLane*
const crossing = getSidewalk<MSEdge, MSLane>(ce);
300 if (waitingStage != 0 && wa !=
nullptr) {
302 waypoints.push_back({waitingStage, wa->
getLanes()[0]->getShape().getCentroid(), wa->
getWidth() / 2.});
304 const MSLane*
const prevLane = getSidewalk<MSEdge, MSLane>(prev);
307 if (crossing->
getShape().front().distanceSquaredTo(startPos) < crossing->
getShape().back().distanceSquaredTo(startPos)) {
313 throw ProcessError(
TLF(
"No waiting set for crossing at %.", ce->getID()));
316 if (ce->isWalkingArea()) {
322 waypoints.push_back({waitingStage, lane->
getShape().positionAtOffset(e->getLength() / 2.), lane->
getWidth() / 2.});
325 const JPS_StageId finalWait = std::get<0>(waypoints.back());
326 waypoints.pop_back();
327 if (!waypoints.empty()) {
328 waypoints.erase(waypoints.begin());
334 JPS_JourneyDescription journeyDesc = JPS_JourneyDescription_Create();
336 (*myPythonScript) <<
"\njourney = jps.JourneyDescription()\n";
338 JPS_StageId startingStage = 0;
339 JPS_StageId predecessor = 0;
340 for (
const auto& p : waypoints) {
342 JPS_JourneyDescription_Free(journeyDesc);
345 if (startingStage == 0) {
346 startingStage = std::get<0>(waypoints.front()) == 0 ? predecessor : std::get<0>(waypoints.front());
349 JPS_ErrorMessage message =
nullptr;
350 JPS_JourneyId journeyId = JPS_Simulation_AddJourney(
myJPSSimulation, journeyDesc, &message);
351 JPS_JourneyDescription_Free(journeyDesc);
352 if (message !=
nullptr) {
353 WRITE_WARNINGF(
TL(
"Error while adding a journey for person '%': %"), person->
getID(), JPS_ErrorMessage_GetMessage(message));
354 JPS_ErrorMessage_Free(message);
360 if (pstate->getPerson() == person) {
365 if (state ==
nullptr) {
366 state =
new PState(
static_cast<MSPerson*
>(person), stage, journeyId, startingStage, waypoints);
368 state->
setPosition(departurePosition.
x(), departurePosition.
y());
373 state->
reinit(stage, journeyId, startingStage, waypoints);
379 (*myPythonScript) <<
"journey_id = simulation.add_journey(journey)\n"
380 "simulation.add_agent(jps.CollisionFreeSpeedModelAgentParameters(journey_id=journey_id,stage_id="
381 << startingStage <<
",position=(" << departurePosition.
x() <<
"," << departurePosition.
y()
386 if (message !=
nullptr) {
387 WRITE_WARNINGF(
TL(
"Error while switching to a new journey for person '%': %"), person->
getID(), JPS_ErrorMessage_GetMessage(message));
388 JPS_ErrorMessage_Free(message);
399 if (pstate->
getLane() !=
nullptr) {
401 peds.erase(std::find(peds.begin(), peds.end(), pstate));
404 if (pstate->
getStage() !=
nullptr) {
414 JPS_ErrorMessage message =
nullptr;
415 for (
int i = 0; i < nbrIterations; ++i) {
419 WRITE_ERRORF(
TL(
"Error during iteration %: %"), i, JPS_ErrorMessage_GetMessage(message));
427 PState*
const state = *stateIt;
441 if (stage ==
nullptr) {
452 const JPS_Point position = JPS_Agent_GetPosition(agent);
456 const JPS_Point orientation = JPS_Agent_GetOrientation(agent);
457 state->
setAngle(atan2(orientation.y, orientation.x));
460 Position newPosition(position.x, position.y);
463 const double oldLanePos = state->
getEdgePos(time);
465 double bestDistance = std::numeric_limits<double>::max();
466 MSLane* candidateLane =
nullptr;
467 double candidateLaneLongitudinalPosition = 0.0;
470 forwardRoute, 0, person->
getVClass(),
true, bestDistance, &candidateLane, candidateLaneLongitudinalPosition, routeOffset);
473 if (candidateLane != state->
getLane()) {
474 if (state->
getLane() !=
nullptr) {
476 peds.erase(std::find(peds.begin(), peds.end(), state));
486 const bool arrived = stage->
moveToNextEdge(person, time, 1,
nullptr);
494 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState(agent,
nullptr);
495 if (newMaxSpeed != JPS_CollisionFreeSpeedModelState_GetV0(modelState)) {
496 JPS_CollisionFreeSpeedModelState_SetV0(modelState, newMaxSpeed);
501 JPS_CollisionFreeSpeedModelV2State modelState = JPS_Agent_GetCollisionFreeSpeedModelV2State(agent,
nullptr);
502 if (newMaxSpeed != JPS_CollisionFreeSpeedModelV2State_GetV0(modelState)) {
503 JPS_CollisionFreeSpeedModelV2State_SetV0(modelState, newMaxSpeed);
508 JPS_GeneralizedCentrifugalForceModelState modelState = JPS_Agent_GetGeneralizedCentrifugalForceModelState(agent,
nullptr);
509 if (newMaxSpeed != JPS_GeneralizedCentrifugalForceModelState_GetV0(modelState)) {
510 JPS_GeneralizedCentrifugalForceModelState_SetV0(modelState, newMaxSpeed);
515 JPS_SocialForceModelState modelState = JPS_Agent_GetSocialForceModelState(agent,
nullptr);
516 if (newMaxSpeed != JPS_SocialForceModelState_GetDesiredSpeed(modelState)) {
517 JPS_SocialForceModelState_SetDesiredSpeed(modelState, newMaxSpeed);
523 const double speed = person->
getSpeed();
524 for (
int offset = 0; offset < 2; offset++) {
526 if (waypoint !=
nullptr && std::get<0>(*waypoint) != 0) {
527 const JPS_StageId waitingStage = std::get<0>(*waypoint);
538 const double passingClearanceTime = person->
getFloatParam(
"pedestrian.timegap-crossing");
540 person->
getImpatience(), speed, 0, 0,
nullptr,
false, person);
541 const auto proxy = JPS_Simulation_GetWaitingSetProxy(
myJPSSimulation, waitingStage, &message);
542 JPS_WaitingSetProxy_SetWaitingSetState(proxy, open ? JPS_WaitingSet_Inactive : JPS_WaitingSet_Active);
548 const double slack = person->
getMaxSpeed() *
TS / 2. + POSITION_EPS;
554 const JPS_AgentId agentID = state->
getAgentId();
568 const std::vector<JPS_Point>& areaBoundary = area.areaBoundary;
569 JPS_AgentIdIterator agentsInArea = JPS_Simulation_AgentsInPolygon(
myJPSSimulation, areaBoundary.data(), areaBoundary.size());
570 if (area.areaType ==
"vanishing_area") {
571 const SUMOTime period = area.params.count(
"period") > 0 ?
string2time(area.params.at(
"period")) : 1000;
572 const int nbrPeriodsCoveringTimestep = (int)ceil(
TS /
STEPS2TIME(period));
573 if (time - area.lastRemovalTime >= nbrPeriodsCoveringTimestep * period) {
574 for (
int k = 0; k < nbrPeriodsCoveringTimestep; k++) {
575 const JPS_AgentId agentID = JPS_AgentIdIterator_Next(agentsInArea);
577 auto lambda = [agentID](
const PState *
const p) {
578 return p->getAgentId() == agentID;
582 const PState*
const state = *iterator;
587 WRITE_MESSAGEF(
TL(
"Person '%' in vanishing area '%' was removed from the simulation."), person->
getID(), area.id);
591 area.lastRemovalTime = time;
598 for (JPS_AgentId agentID = JPS_AgentIdIterator_Next(agentsInArea); agentID != 0; agentID = JPS_AgentIdIterator_Next(agentsInArea)) {
599 if (area.params.count(
"speed") > 0) {
600 const JPS_Agent agent = JPS_Simulation_GetAgent(
myJPSSimulation, agentID,
nullptr);
604 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState(agent,
nullptr);
605 if (newMaxSpeed != JPS_CollisionFreeSpeedModelState_GetV0(modelState)) {
606 JPS_CollisionFreeSpeedModelState_SetV0(modelState, newMaxSpeed);
611 JPS_CollisionFreeSpeedModelV2State modelState = JPS_Agent_GetCollisionFreeSpeedModelV2State(agent,
nullptr);
612 if (newMaxSpeed != JPS_CollisionFreeSpeedModelV2State_GetV0(modelState)) {
613 JPS_CollisionFreeSpeedModelV2State_SetV0(modelState, newMaxSpeed);
618 JPS_GeneralizedCentrifugalForceModelState modelState = JPS_Agent_GetGeneralizedCentrifugalForceModelState(agent,
nullptr);
619 if (newMaxSpeed != JPS_GeneralizedCentrifugalForceModelState_GetV0(modelState)) {
620 JPS_GeneralizedCentrifugalForceModelState_SetV0(modelState, newMaxSpeed);
625 JPS_SocialForceModelState modelState = JPS_Agent_GetSocialForceModelState(agent,
nullptr);
626 if (newMaxSpeed != JPS_SocialForceModelState_GetDesiredSpeed(modelState)) {
627 JPS_SocialForceModelState_SetDesiredSpeed(modelState, newMaxSpeed);
635 JPS_AgentIdIterator_Free(agentsInArea);
640 std::vector<SUMOTrafficObject::NumericalID> allStoppedTrainIDs;
641 std::vector<const MSVehicle*> allStoppedTrains;
642 for (
const auto& stop : stoppingPlaces) {
643 std::vector<const SUMOVehicle*> stoppedTrains = stop.second->getStoppedVehicles();
645 allStoppedTrainIDs.push_back(train->getNumericalID());
646 allStoppedTrains.push_back(
dynamic_cast<const MSVehicle*
>(train));
651 if (!allStoppedTrainIDs.empty()) {
652 std::vector<GEOSGeometry*> carriagePolygons;
653 std::vector<GEOSGeometry*> rampPolygons;
654 for (
const MSVehicle* train : allStoppedTrains) {
655 if (train->getLeavingPersonNumber() > 0) {
659 const std::vector<MSTrainHelper::Carriage*>& carriages = trainHelper.
getCarriages();
661 Position dir = carriage->front - carriage->back;
670 carriageShape.push_back(carriage->front + perp * p);
671 carriageShape.push_back(carriage->back + perp * p);
672 carriageShape.push_back(carriage->back - perp * p);
673 carriageShape.push_back(carriage->front - perp * p);
678 for (
const Position& door : carriage->doorPositions) {
680 rampShape.push_back(door - perp * p + dir * d);
681 rampShape.push_back(door - perp * p - dir * d);
682 rampShape.push_back(door + perp * p - dir * d);
683 rampShape.push_back(door + perp * p + dir * d);
689 if (!carriagePolygons.empty()) {
690 GEOSGeometry* carriagesCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, carriagePolygons.data(), (
unsigned int)carriagePolygons.size());
691 GEOSGeometry* rampsCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, rampPolygons.data(), (
unsigned int)rampPolygons.size());
692 GEOSGeometry* carriagesAndRampsUnion = GEOSUnion(carriagesCollection, rampsCollection);
693 if (carriagesAndRampsUnion ==
nullptr) {
697#ifdef DEBUG_GEOMETRY_GENERATION
700 int nbrComponents = 0;
701 double maxArea = 0.0;
702 double totalArea = 0.0;
703 const GEOSGeometry* pedestrianNetworkWithTrainsAndRampsLargestComponent =
getLargestComponent(pedestrianNetworkWithTrainsAndRamps, nbrComponents, maxArea, totalArea);
704 if (nbrComponents > 1) {
705 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
706 nbrComponents, maxArea / totalArea * 100.0,
"%");
708#ifdef DEBUG_GEOMETRY_GENERATION
715 GEOSGeom_destroy(pedestrianNetworkWithTrainsAndRamps);
717 GEOSGeom_destroy(rampsCollection);
718 GEOSGeom_destroy(carriagesCollection);
727 JPS_ErrorMessage_Free(message);
748 GEOSGeometry* lineString = GEOSGeom_createLineString(coordinateSequence);
750 GEOSGeom_destroy(lineString);
751 return dilatedLineString;
758 if (shape.size() == 1) {
759 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is just a point."), shapeID, junctionID);
763 if (shape.back() != shape.front()) {
764 shape.push_back(shape.front());
768 cleanShape.push_back(shape[0]);
770 for (
int i = 1; i < (int)shape.size(); i++) {
771 if (shape[i] != shape[i - 1]) {
772 cleanShape.push_back(shape[i]);
774 duplicates.push_back(shape[i]);
777 if (cleanShape.size() < shape.size()) {
778 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' had some equal consecutive points removed: %"), shapeID, junctionID,
toString(duplicates, 9));
781 GEOSGeometry* linearRing = GEOSGeom_createLinearRing(coordinateSequence);
782 GEOSGeometry* polygon = GEOSGeom_createPolygon(linearRing,
nullptr, 0);
784 if (!GEOSisValid(polygon)) {
785 if (cleanShape.size() == 3) {
786 if (isInternalShape) {
787 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been dilated as it is just a segment."), shapeID, junctionID);
789 WRITE_WARNINGF(
TL(
"Polygon '%' has been dilated as it is just a segment."), shapeID);
791 GEOSGeometry* lineString = GEOSGeom_createLineString(GEOSCoordSeq_clone(coordinateSequence));
792 GEOSGeom_destroy(polygon);
794 GEOSGeom_destroy(lineString);
796 if (isInternalShape) {
797 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been replaced by its convex hull as it is not simple."), shapeID, junctionID);
798 GEOSGeometry* hull = GEOSConvexHull(polygon);
799 GEOSGeom_destroy(polygon);
802 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is not simple."), shapeID, junctionID);
811 if (isInternalShape) {
821 std::vector<GEOSGeometry*> walkableAreas;
823 const MSLane*
const lane = getSidewalk<MSEdge, MSLane>(edge);
824 if (lane !=
nullptr) {
825 GEOSGeometry* dilatedLane =
nullptr;
826 if (edge->isWalkingArea()) {
828 }
else if (edge->isCrossing()) {
830 if (outlineShape !=
nullptr) {
833 if (dilatedLane !=
nullptr) {
834 walkableAreas.push_back(dilatedLane);
844 if (dilatedLane !=
nullptr) {
845 walkableAreas.push_back(dilatedLane);
850 const MSJunction*
const junction = junctionWithID.second;
851 int pedEdgeCount = 0;
852 bool hasWalkingArea =
false;
856 for (
const MSEdge*
const edge : edges) {
857 if (edge->isWalkingArea()) {
858 hasWalkingArea =
true;
861 if (getSidewalk<MSEdge, MSLane>(edge) !=
nullptr) {
865 if (hasWalkingArea) {
869 if (!hasWalkingArea && pedEdgeCount > 1) {
872 if (walkingAreaGeom !=
nullptr) {
873 walkableAreas.push_back(walkingAreaGeom);
879 std::vector<GEOSGeometry*> additionalObstacles;
881 if (polygonWithID.second->getShapeType() ==
"jupedsim.walkable_area" || polygonWithID.second->getShapeType() ==
"taz") {
882 GEOSGeometry* walkableArea =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
883 if (walkableArea !=
nullptr) {
884 walkableAreas.push_back(walkableArea);
887 }
else if (polygonWithID.second->getShapeType() ==
"jupedsim.obstacle") {
888 GEOSGeometry* additionalObstacle =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
889 if (additionalObstacle !=
nullptr) {
890 additionalObstacles.push_back(additionalObstacle);
896 GEOSGeometry* disjointWalkableAreas = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, walkableAreas.data(), (
unsigned int)walkableAreas.size());
897#ifdef DEBUG_GEOMETRY_GENERATION
900 GEOSGeometry* initialWalkableAreas = GEOSUnaryUnion(disjointWalkableAreas);
901#ifdef DEBUG_GEOMETRY_GENERATION
902 dumpGeometry(initialWalkableAreas,
"initialWalkableAreas.wkt");
904 GEOSGeom_destroy(disjointWalkableAreas);
907 GEOSGeometry* disjointAdditionalObstacles = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, additionalObstacles.data(), (
unsigned int)additionalObstacles.size());
908#ifdef DEBUG_GEOMETRY_GENERATION
911 GEOSGeometry* additionalObstaclesUnion = GEOSUnaryUnion(disjointAdditionalObstacles);
912#ifdef DEBUG_GEOMETRY_GENERATION
913 dumpGeometry(additionalObstaclesUnion,
"additionalObstaclesUnion.wkt");
915 GEOSGeometry* finalWalkableAreas = GEOSDifference(initialWalkableAreas, additionalObstaclesUnion);
916#ifdef DEBUG_GEOMETRY_GENERATION
917 dumpGeometry(finalWalkableAreas,
"finalWalkableAreas.wkt");
919 GEOSGeom_destroy(initialWalkableAreas);
920 GEOSGeom_destroy(additionalObstaclesUnion);
921 GEOSGeom_destroy(disjointAdditionalObstacles);
923 if (!GEOSisSimple(finalWalkableAreas)) {
924 throw ProcessError(
TL(
"Union of walkable areas minus union of obstacles is not a simple polygon."));
927 return finalWalkableAreas;
933 GEOSCoordSequence* coordinateSequence = GEOSCoordSeq_create((
unsigned int)shape.size(), 2);
934 for (
int i = 0; i < (int)shape.size(); i++) {
935 GEOSCoordSeq_setXY(coordinateSequence, i, shape[i].x(), shape[i].y());
937 return coordinateSequence;
944 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
945 unsigned int coordinateSequenceSize;
946 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
949 for (
unsigned int i = 0; i < coordinateSequenceSize; i++) {
950 GEOSCoordSeq_getX(coordinateSequence, i, &x);
951 GEOSCoordSeq_getY(coordinateSequence, i, &y);
952 coordinateVector.push_back(
Position(x, y));
954 return coordinateVector;
958std::vector<JPS_Point>
960 std::vector<JPS_Point> pointVector;
961 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
962 unsigned int coordinateSequenceSize;
963 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
967 for (
unsigned int i = 0; i < coordinateSequenceSize - 1; i++) {
968 GEOSCoordSeq_getX(coordinateSequence, i, &x);
969 GEOSCoordSeq_getY(coordinateSequence, i, &y);
970 pointVector.push_back({x, y});
979 GEOSGeometry* linearRingAsPolygon = GEOSGeom_createPolygon(GEOSGeom_clone(linearRing),
nullptr, 0);
980 GEOSArea(linearRingAsPolygon, &area);
981 GEOSGeom_destroy(linearRingAsPolygon);
994 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
998 std::vector<PositionVector> holes;
999 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1000 if (nbrInteriorRings != -1) {
1001 for (
int k = 0; k < nbrInteriorRings; k++) {
1002 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1016 nbrComponents = GEOSGetNumGeometries(polygon);
1017 const GEOSGeometry* largestComponent =
nullptr;
1020 for (
int i = 0; i < nbrComponents; i++) {
1021 const GEOSGeometry* componentPolygon = GEOSGetGeometryN(polygon, i);
1023 GEOSArea(componentPolygon, &area);
1025 if (area > maxArea) {
1027 largestComponent = componentPolygon;
1030 return largestComponent;
1036 JPS_GeometryBuilder geometryBuilder = JPS_GeometryBuilder_Create();
1039 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1041 JPS_GeometryBuilder_AddAccessibleArea(geometryBuilder, exteriorCoordinates.data(), exteriorCoordinates.size());
1044 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1045 if (nbrInteriorRings != -1) {
1046 for (
int k = 0; k < nbrInteriorRings; k++) {
1047 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1051 JPS_GeometryBuilder_ExcludeFromAccessibleArea(geometryBuilder, holeCoordinates.data(), holeCoordinates.size());
1056 JPS_ErrorMessage message =
nullptr;
1057 JPS_Geometry geometry = JPS_GeometryBuilder_Build(geometryBuilder, &message);
1058 if (geometry ==
nullptr) {
1059 const std::string error =
TLF(
"Error while generating geometry: %", JPS_ErrorMessage_GetMessage(message));
1060 JPS_ErrorMessage_Free(message);
1063 JPS_GeometryBuilder_Free(geometryBuilder);
1070 GEOSGeometry* polygonGeoCoordinates =
nullptr;
1071 if (useGeoCoordinates) {
1072 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1074 for (
Position& position : exteriorPoints) {
1077 const int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1078 std::vector<GEOSGeometry*> holeRings;
1079 if (nbrInteriorRings != -1) {
1080 for (
int k = 0; k < nbrInteriorRings; k++) {
1081 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1083 for (
Position& position : holePoints) {
1087 GEOSGeometry* holeRing = GEOSGeom_createLinearRing(holeRingCoords);
1088 holeRings.push_back(holeRing);
1092 GEOSGeometry* exteriorRing = GEOSGeom_createLinearRing(exteriorRingCoords);
1093 polygonGeoCoordinates = GEOSGeom_createPolygon(exteriorRing, holeRings.data(), nbrInteriorRings);
1095 std::ofstream dumpFile;
1096 dumpFile.open(filename);
1097 GEOSWKTWriter* writer = GEOSWKTWriter_create();
1099 char* wkt = GEOSWKTWriter_write(writer, polygonGeoCoordinates ==
nullptr ? polygon : polygonGeoCoordinates);
1100 dumpFile << wkt << std::endl;
1103 GEOSWKTWriter_destroy(writer);
1104 GEOSGeom_destroy(polygonGeoCoordinates);
1116 JPS_ErrorMessage message =
nullptr;
1117 JPS_StageId waitingStage = 0;
1121 const double offset = 2 * radius + POSITION_EPS;
1122 const double lonOffset = entry ? NUMERICAL_EPS : shape.
length() - NUMERICAL_EPS;
1125 for (
double latOff = offset; latOff < crossing->
getWidth() / 2. - offset; latOff += offset) {
1133 pv.push_back(crossing->
getIncomingLanes().front().lane->getShape().getCentroid());
1135 if (!entry && crossing->
getLinkCont().size() == 1 && crossing->
getLinkCont().front()->getLane()->isWalkingArea()) {
1136 pv.push_back(crossing->
getLinkCont().front()->getLane()->getShape().getCentroid());
1138 std::vector<JPS_Point> points;
1140 GEOSGeometry* point = GEOSGeom_createPointFromXY(p.x(), p.y());
1142 points.push_back({p.x(), p.y()});
1144 GEOSGeom_destroy(point);
1146 waitingStage = JPS_Simulation_AddStageWaitingSet(
myJPSSimulation, points.data(), points.size(), &message);
1147 if (message !=
nullptr) {
1148 const std::string error =
TLF(
"Error while adding waiting set for % on '%': %",
1149 entry ?
"entry" :
"exit", crossing->
getID(), JPS_ErrorMessage_GetMessage(message));
1150 JPS_ErrorMessage_Free(message);
1153 const auto proxy = JPS_Simulation_GetWaitingSetProxy(
myJPSSimulation, waitingStage, &message);
1154 JPS_WaitingSetProxy_SetWaitingSetState(proxy, JPS_WaitingSet_Inactive);
1157 (*myPythonScript) <<
"ws = simulation.add_waiting_set_stage([";
1158 for (
const JPS_Point& p : points) {
1159 (*myPythonScript) <<
"(" << p.x <<
"," << p.y <<
"),";
1161 (*myPythonScript) <<
"])\nsimulation.get_stage(ws).state = jps.stages.WaitingSetState.INACTIVE\n";
1163 return waitingStage;
1169 initGEOS(
nullptr,
nullptr);
1172 int nbrComponents = 0;
1173 double maxArea = 0.0;
1174 double totalArea = 0.0;
1176 if (nbrComponents > 1) {
1177 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
1178 nbrComponents, maxArea / totalArea * 100.0,
"%");
1180#ifdef DEBUG_GEOMETRY_GENERATION
1183 const std::string filename = oc.
getString(
"pedestrian.jupedsim.wkt");
1184 if (!filename.empty()) {
1192 JPS_ErrorMessage message =
nullptr;
1194 double strengthGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.strength-geometry-repulsion");
1195 double rangeGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.range-geometry-repulsion");
1197 if (oc.
isDefault(
"pedestrian.jupedsim.strength-geometry-repulsion") && oc.
isDefault(
"pedestrian.jupedsim.range-geometry-repulsion")) {
1198 WRITE_MESSAGE(
TL(
"Adapting geometry repulsion default values for jupedsim timestep of 0.02."));
1199 strengthGeometryRepulsion = 35.;
1200 rangeGeometryRepulsion = 0.019;
1206 JPS_CollisionFreeSpeedModelBuilder modelBuilder = JPS_CollisionFreeSpeedModelBuilder_Create(
1207 oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"),
1208 oc.
getFloat(
"pedestrian.jupedsim.range-neighbor-repulsion"),
1209 strengthGeometryRepulsion,
1210 rangeGeometryRepulsion);
1212 JPS_CollisionFreeSpeedModelBuilder_Free(modelBuilder);
1216 JPS_CollisionFreeSpeedModelV2Builder modelBuilder = JPS_CollisionFreeSpeedModelV2Builder_Create();
1218 JPS_CollisionFreeSpeedModelV2Builder_Free(modelBuilder);
1222 JPS_GeneralizedCentrifugalForceModelBuilder modelBuilder = JPS_GeneralizedCentrifugalForceModelBuilder_Create(
1223 oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"),
1224 strengthGeometryRepulsion,
1232 JPS_GeneralizedCentrifugalForceModelBuilder_Free(modelBuilder);
1236 JPS_SocialForceModelBuilder modelBuilder = JPS_SocialForceModelBuilder_Create(120000.0, 240000.0);
1238 JPS_SocialForceModelBuilder_Free(modelBuilder);
1244 const std::string error =
TLF(
"Error creating the pedestrian model: %", JPS_ErrorMessage_GetMessage(message));
1245 JPS_ErrorMessage_Free(message);
1250 const std::string error =
TLF(
"Error creating the simulation: %", JPS_ErrorMessage_GetMessage(message));
1251 JPS_ErrorMessage_Free(message);
1256 const SUMOPolygon*
const poly = polygonWithID.second;
1258 std::vector<JPS_Point> areaBoundary;
1260 areaBoundary.push_back({p.x(), p.y()});
1263 if (areaBoundary.back().x == areaBoundary.front().x && areaBoundary.back().y == areaBoundary.front().y) {
1264 areaBoundary.pop_back();
1273 (*myPythonScript) <<
"import jupedsim as jps\nimport shapely\n\n"
1274 "with open('" << filename <<
"') as f: geom = shapely.from_wkt(f.read())\n"
1275 "simulation = jps.Simulation(dt=" <<
STEPS2TIME(
myJPSDeltaT) <<
", model=jps.CollisionFreeSpeedModel(), geometry=geom,\n"
1276 "trajectory_writer=jps.SqliteTrajectoryWriter(output_file='out.sql'))\n";
1280 crossing.second.first =
addWaitingSet(crossing.first,
true);
1281 crossing.second.second =
addWaitingSet(crossing.first,
false);
1290 JPS_JourneyId journeyId, JPS_StageId stageId,
1291 const std::vector<WaypointDesc>& waypoints) :
1293 myJourneyId(journeyId), myStageId(stageId), myWaypoints(waypoints), myAgentId(0) {
1300 const std::vector<WaypointDesc>& waypoints) {
1301 if (myStage !=
nullptr) {
1302 myStage->setPState(
nullptr);
1305 myJourneyId = journeyId;
1306 myStageId = stageId;
1307 myWaypoints = waypoints;
1321 myRemoteXYPos.set(x, y, z);
1332 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
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.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
bool isNormal() const
return whether this edge is an internal edge
const MSJunction * getToJunction() const
const MSJunction * getFromJunction() const
bool isTazConnector() const
double getWidth() const
Returns the edges's width (sum over all lanes)
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.
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
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.
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.
MSPedestrianRouter & getPedestrianRouter(int rngIndex, const Prohibitions &prohibited={}) const
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
double getEdgePos(SUMOTime) const
abstract methods inherited from MSTransportableStateAdapter
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
double getSpeed(const MSStageMoving &) const
return the current speed of the transportable
Holds pedestrian state and performs updates.
JPS_StageId getStageId() const
first stage of the journey
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
void setPosition(const double x, const double y, const double z=0.)
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 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 activateMoveReminders(MSTransportable *person, double oldPos, double newPos, double newSpeed)
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
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 SUMOVTypeParameter & getVTypeParameter() const
Returns the object's "vehicle" type parameter.
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, const SUMOVTypeParameter &pars, std::vector< const E * > &into, bool allEdges=false) const
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, bool checkDist=true) const
Retrieve a floating point parameter for the traffic object.
Structure representing possible vehicle parameter.
double maxPlatformDistance
the maximum distance between platform and train
double carriageDoorWidth
the width of the carriage doors
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, 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)
#define UNUSED_PARAMETER(x)
Structure that keeps data related to vanishing areas (and other types of areas).