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) {
293 const MSEdge* wa =
nullptr;
294 for (
const MSEdge*
const ce : crossingRoute) {
295 if (ce->isCrossing()) {
296 const MSLane*
const crossing = getSidewalk<MSEdge, MSLane>(ce);
298 if (waitingStage != 0 && wa !=
nullptr) {
300 waypoints.push_back({waitingStage, wa->
getLanes()[0]->getShape().getCentroid(), wa->
getWidth() / 2.});
302 const MSLane*
const prevLane = getSidewalk<MSEdge, MSLane>(prev);
305 if (crossing->
getShape().front().distanceSquaredTo(startPos) < crossing->
getShape().back().distanceSquaredTo(startPos)) {
311 throw ProcessError(
TLF(
"No waiting set for crossing at %.", ce->getID()));
314 if (ce->isWalkingArea()) {
320 waypoints.push_back({waitingStage, lane->
getShape().positionAtOffset(e->getLength() / 2.), lane->
getWidth() / 2.});
323 const JPS_StageId finalWait = std::get<0>(waypoints.back());
324 waypoints.pop_back();
325 if (!waypoints.empty()) {
326 waypoints.erase(waypoints.begin());
332 JPS_JourneyDescription journeyDesc = JPS_JourneyDescription_Create();
334 (*myPythonScript) <<
"\njourney = jps.JourneyDescription()\n";
336 JPS_StageId startingStage = 0;
337 JPS_StageId predecessor = 0;
338 for (
const auto& p : waypoints) {
340 JPS_JourneyDescription_Free(journeyDesc);
343 if (startingStage == 0) {
344 startingStage = std::get<0>(waypoints.front()) == 0 ? predecessor : std::get<0>(waypoints.front());
347 JPS_ErrorMessage message =
nullptr;
348 JPS_JourneyId journeyId = JPS_Simulation_AddJourney(
myJPSSimulation, journeyDesc, &message);
349 JPS_JourneyDescription_Free(journeyDesc);
350 if (message !=
nullptr) {
351 WRITE_WARNINGF(
TL(
"Error while adding a journey for person '%': %"), person->
getID(), JPS_ErrorMessage_GetMessage(message));
352 JPS_ErrorMessage_Free(message);
358 if (pstate->getPerson() == person) {
363 if (state ==
nullptr) {
364 state =
new PState(
static_cast<MSPerson*
>(person), stage, journeyId, startingStage, waypoints);
366 state->
setPosition(departurePosition.
x(), departurePosition.
y());
371 state->
reinit(stage, journeyId, startingStage, waypoints);
377 (*myPythonScript) <<
"journey_id = simulation.add_journey(journey)\n"
378 "simulation.add_agent(jps.CollisionFreeSpeedModelAgentParameters(journey_id=journey_id,stage_id="
379 << startingStage <<
",position=(" << departurePosition.
x() <<
"," << departurePosition.
y()
384 if (message !=
nullptr) {
385 WRITE_WARNINGF(
TL(
"Error while switching to a new journey for person '%': %"), person->
getID(), JPS_ErrorMessage_GetMessage(message));
386 JPS_ErrorMessage_Free(message);
397 if (pstate->
getLane() !=
nullptr) {
399 peds.erase(std::find(peds.begin(), peds.end(), pstate));
402 if (pstate->
getStage() !=
nullptr) {
412 JPS_ErrorMessage message =
nullptr;
413 for (
int i = 0; i < nbrIterations; ++i) {
417 WRITE_ERRORF(
TL(
"Error during iteration %: %"), i, JPS_ErrorMessage_GetMessage(message));
425 PState*
const state = *stateIt;
439 if (stage ==
nullptr) {
450 const JPS_Point position = JPS_Agent_GetPosition(agent);
454 const JPS_Point orientation = JPS_Agent_GetOrientation(agent);
455 state->
setAngle(atan2(orientation.y, orientation.x));
458 Position newPosition(position.x, position.y);
461 const double oldLanePos = state->
getEdgePos(time);
463 double bestDistance = std::numeric_limits<double>::max();
464 MSLane* candidateLane =
nullptr;
465 double candidateLaneLongitudinalPosition = 0.0;
468 forwardRoute, 0, person->
getVClass(),
true, bestDistance, &candidateLane, candidateLaneLongitudinalPosition, routeOffset);
471 if (candidateLane != state->
getLane()) {
472 if (state->
getLane() !=
nullptr) {
474 peds.erase(std::find(peds.begin(), peds.end(), state));
484 const bool arrived = stage->
moveToNextEdge(person, time, 1,
nullptr);
492 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState(agent,
nullptr);
493 if (newMaxSpeed != JPS_CollisionFreeSpeedModelState_GetV0(modelState)) {
494 JPS_CollisionFreeSpeedModelState_SetV0(modelState, newMaxSpeed);
499 JPS_CollisionFreeSpeedModelV2State modelState = JPS_Agent_GetCollisionFreeSpeedModelV2State(agent,
nullptr);
500 if (newMaxSpeed != JPS_CollisionFreeSpeedModelV2State_GetV0(modelState)) {
501 JPS_CollisionFreeSpeedModelV2State_SetV0(modelState, newMaxSpeed);
506 JPS_GeneralizedCentrifugalForceModelState modelState = JPS_Agent_GetGeneralizedCentrifugalForceModelState(agent,
nullptr);
507 if (newMaxSpeed != JPS_GeneralizedCentrifugalForceModelState_GetV0(modelState)) {
508 JPS_GeneralizedCentrifugalForceModelState_SetV0(modelState, newMaxSpeed);
513 JPS_SocialForceModelState modelState = JPS_Agent_GetSocialForceModelState(agent,
nullptr);
514 if (newMaxSpeed != JPS_SocialForceModelState_GetDesiredSpeed(modelState)) {
515 JPS_SocialForceModelState_SetDesiredSpeed(modelState, newMaxSpeed);
521 const double speed = person->
getSpeed();
522 for (
int offset = 0; offset < 2; offset++) {
524 if (waypoint !=
nullptr && std::get<0>(*waypoint) != 0) {
525 const JPS_StageId waitingStage = std::get<0>(*waypoint);
536 const double passingClearanceTime = person->
getFloatParam(
"pedestrian.timegap-crossing");
538 person->
getImpatience(), speed, 0, 0,
nullptr,
false, person);
539 const auto proxy = JPS_Simulation_GetWaitingSetProxy(
myJPSSimulation, waitingStage, &message);
540 JPS_WaitingSetProxy_SetWaitingSetState(proxy, open ? JPS_WaitingSet_Inactive : JPS_WaitingSet_Active);
546 const double slack = person->
getMaxSpeed() *
TS / 2. + POSITION_EPS;
552 const JPS_AgentId agentID = state->
getAgentId();
566 const std::vector<JPS_Point>& areaBoundary = area.areaBoundary;
567 JPS_AgentIdIterator agentsInArea = JPS_Simulation_AgentsInPolygon(
myJPSSimulation, areaBoundary.data(), areaBoundary.size());
568 if (area.areaType ==
"vanishing_area") {
569 const SUMOTime period = area.params.count(
"period") > 0 ?
string2time(area.params.at(
"period")) : 1000;
570 const int nbrPeriodsCoveringTimestep = (int)ceil(
TS /
STEPS2TIME(period));
571 if (time - area.lastRemovalTime >= nbrPeriodsCoveringTimestep * period) {
572 for (
int k = 0; k < nbrPeriodsCoveringTimestep; k++) {
573 const JPS_AgentId agentID = JPS_AgentIdIterator_Next(agentsInArea);
575 auto lambda = [agentID](
const PState *
const p) {
576 return p->getAgentId() == agentID;
580 const PState*
const state = *iterator;
585 WRITE_MESSAGEF(
TL(
"Person '%' in vanishing area '%' was removed from the simulation."), person->
getID(), area.id);
589 area.lastRemovalTime = time;
596 for (JPS_AgentId agentID = JPS_AgentIdIterator_Next(agentsInArea); agentID != 0; agentID = JPS_AgentIdIterator_Next(agentsInArea)) {
597 if (area.params.count(
"speed") > 0) {
598 const JPS_Agent agent = JPS_Simulation_GetAgent(
myJPSSimulation, agentID,
nullptr);
602 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState(agent,
nullptr);
603 if (newMaxSpeed != JPS_CollisionFreeSpeedModelState_GetV0(modelState)) {
604 JPS_CollisionFreeSpeedModelState_SetV0(modelState, newMaxSpeed);
609 JPS_CollisionFreeSpeedModelV2State modelState = JPS_Agent_GetCollisionFreeSpeedModelV2State(agent,
nullptr);
610 if (newMaxSpeed != JPS_CollisionFreeSpeedModelV2State_GetV0(modelState)) {
611 JPS_CollisionFreeSpeedModelV2State_SetV0(modelState, newMaxSpeed);
616 JPS_GeneralizedCentrifugalForceModelState modelState = JPS_Agent_GetGeneralizedCentrifugalForceModelState(agent,
nullptr);
617 if (newMaxSpeed != JPS_GeneralizedCentrifugalForceModelState_GetV0(modelState)) {
618 JPS_GeneralizedCentrifugalForceModelState_SetV0(modelState, newMaxSpeed);
623 JPS_SocialForceModelState modelState = JPS_Agent_GetSocialForceModelState(agent,
nullptr);
624 if (newMaxSpeed != JPS_SocialForceModelState_GetDesiredSpeed(modelState)) {
625 JPS_SocialForceModelState_SetDesiredSpeed(modelState, newMaxSpeed);
633 JPS_AgentIdIterator_Free(agentsInArea);
638 std::vector<SUMOTrafficObject::NumericalID> allStoppedTrainIDs;
639 std::vector<const MSVehicle*> allStoppedTrains;
640 for (
const auto& stop : stoppingPlaces) {
641 std::vector<const SUMOVehicle*> stoppedTrains = stop.second->getStoppedVehicles();
643 allStoppedTrainIDs.push_back(train->getNumericalID());
644 allStoppedTrains.push_back(
dynamic_cast<const MSVehicle*
>(train));
649 if (!allStoppedTrainIDs.empty()) {
650 std::vector<GEOSGeometry*> carriagePolygons;
651 std::vector<GEOSGeometry*> rampPolygons;
652 for (
const MSVehicle* train : allStoppedTrains) {
653 if (train->getLeavingPersonNumber() > 0) {
657 const std::vector<MSTrainHelper::Carriage*>& carriages = trainHelper.
getCarriages();
659 Position dir = carriage->front - carriage->back;
668 carriageShape.push_back(carriage->front + perp * p);
669 carriageShape.push_back(carriage->back + perp * p);
670 carriageShape.push_back(carriage->back - perp * p);
671 carriageShape.push_back(carriage->front - perp * p);
676 for (
const Position& door : carriage->doorPositions) {
678 rampShape.push_back(door - perp * p + dir * d);
679 rampShape.push_back(door - perp * p - dir * d);
680 rampShape.push_back(door + perp * p - dir * d);
681 rampShape.push_back(door + perp * p + dir * d);
687 if (!carriagePolygons.empty()) {
688 GEOSGeometry* carriagesCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, carriagePolygons.data(), (
unsigned int)carriagePolygons.size());
689 GEOSGeometry* rampsCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, rampPolygons.data(), (
unsigned int)rampPolygons.size());
690 GEOSGeometry* carriagesAndRampsUnion = GEOSUnion(carriagesCollection, rampsCollection);
691 if (carriagesAndRampsUnion ==
nullptr) {
695#ifdef DEBUG_GEOMETRY_GENERATION
698 int nbrComponents = 0;
699 double maxArea = 0.0;
700 double totalArea = 0.0;
701 const GEOSGeometry* pedestrianNetworkWithTrainsAndRampsLargestComponent =
getLargestComponent(pedestrianNetworkWithTrainsAndRamps, nbrComponents, maxArea, totalArea);
702 if (nbrComponents > 1) {
703 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
704 nbrComponents, maxArea / totalArea * 100.0,
"%");
706#ifdef DEBUG_GEOMETRY_GENERATION
713 GEOSGeom_destroy(pedestrianNetworkWithTrainsAndRamps);
715 GEOSGeom_destroy(rampsCollection);
716 GEOSGeom_destroy(carriagesCollection);
725 JPS_ErrorMessage_Free(message);
746 GEOSGeometry* lineString = GEOSGeom_createLineString(coordinateSequence);
748 GEOSGeom_destroy(lineString);
749 return dilatedLineString;
756 if (shape.size() == 1) {
757 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is just a point."), shapeID, junctionID);
761 if (shape.back() != shape.front()) {
762 shape.push_back(shape.front());
766 cleanShape.push_back(shape[0]);
768 for (
int i = 1; i < (int)shape.size(); i++) {
769 if (shape[i] != shape[i - 1]) {
770 cleanShape.push_back(shape[i]);
772 duplicates.push_back(shape[i]);
775 if (cleanShape.size() < shape.size()) {
776 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' had some equal consecutive points removed: %"), shapeID, junctionID,
toString(duplicates, 9));
779 GEOSGeometry* linearRing = GEOSGeom_createLinearRing(coordinateSequence);
780 GEOSGeometry* polygon = GEOSGeom_createPolygon(linearRing,
nullptr, 0);
782 if (!GEOSisValid(polygon)) {
783 if (cleanShape.size() == 3) {
784 if (isInternalShape) {
785 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been dilated as it is just a segment."), shapeID, junctionID);
787 WRITE_WARNINGF(
TL(
"Polygon '%' has been dilated as it is just a segment."), shapeID);
789 GEOSGeometry* lineString = GEOSGeom_createLineString(GEOSCoordSeq_clone(coordinateSequence));
790 GEOSGeom_destroy(polygon);
792 GEOSGeom_destroy(lineString);
794 if (isInternalShape) {
795 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been replaced by its convex hull as it is not simple."), shapeID, junctionID);
796 GEOSGeometry* hull = GEOSConvexHull(polygon);
797 GEOSGeom_destroy(polygon);
800 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is not simple."), shapeID, junctionID);
809 if (isInternalShape) {
819 std::vector<GEOSGeometry*> walkableAreas;
821 const MSLane*
const lane = getSidewalk<MSEdge, MSLane>(edge);
822 if (lane !=
nullptr) {
823 GEOSGeometry* dilatedLane =
nullptr;
824 if (edge->isWalkingArea()) {
826 }
else if (edge->isCrossing()) {
828 if (outlineShape !=
nullptr) {
831 if (dilatedLane !=
nullptr) {
832 walkableAreas.push_back(dilatedLane);
842 if (dilatedLane !=
nullptr) {
843 walkableAreas.push_back(dilatedLane);
848 const MSJunction*
const junction = junctionWithID.second;
849 int pedEdgeCount = 0;
850 bool hasWalkingArea =
false;
854 for (
const MSEdge*
const edge : edges) {
855 if (edge->isWalkingArea()) {
856 hasWalkingArea =
true;
859 if (getSidewalk<MSEdge, MSLane>(edge) !=
nullptr) {
863 if (hasWalkingArea) {
867 if (!hasWalkingArea && pedEdgeCount > 1) {
870 if (walkingAreaGeom !=
nullptr) {
871 walkableAreas.push_back(walkingAreaGeom);
877 std::vector<GEOSGeometry*> additionalObstacles;
879 if (polygonWithID.second->getShapeType() ==
"jupedsim.walkable_area" || polygonWithID.second->getShapeType() ==
"taz") {
880 GEOSGeometry* walkableArea =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
881 if (walkableArea !=
nullptr) {
882 walkableAreas.push_back(walkableArea);
885 }
else if (polygonWithID.second->getShapeType() ==
"jupedsim.obstacle") {
886 GEOSGeometry* additionalObstacle =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
887 if (additionalObstacle !=
nullptr) {
888 additionalObstacles.push_back(additionalObstacle);
894 GEOSGeometry* disjointWalkableAreas = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, walkableAreas.data(), (
unsigned int)walkableAreas.size());
895#ifdef DEBUG_GEOMETRY_GENERATION
898 GEOSGeometry* initialWalkableAreas = GEOSUnaryUnion(disjointWalkableAreas);
899#ifdef DEBUG_GEOMETRY_GENERATION
900 dumpGeometry(initialWalkableAreas,
"initialWalkableAreas.wkt");
902 GEOSGeom_destroy(disjointWalkableAreas);
905 GEOSGeometry* disjointAdditionalObstacles = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, additionalObstacles.data(), (
unsigned int)additionalObstacles.size());
906#ifdef DEBUG_GEOMETRY_GENERATION
909 GEOSGeometry* additionalObstaclesUnion = GEOSUnaryUnion(disjointAdditionalObstacles);
910#ifdef DEBUG_GEOMETRY_GENERATION
911 dumpGeometry(additionalObstaclesUnion,
"additionalObstaclesUnion.wkt");
913 GEOSGeometry* finalWalkableAreas = GEOSDifference(initialWalkableAreas, additionalObstaclesUnion);
914#ifdef DEBUG_GEOMETRY_GENERATION
915 dumpGeometry(finalWalkableAreas,
"finalWalkableAreas.wkt");
917 GEOSGeom_destroy(initialWalkableAreas);
918 GEOSGeom_destroy(additionalObstaclesUnion);
919 GEOSGeom_destroy(disjointAdditionalObstacles);
921 if (!GEOSisSimple(finalWalkableAreas)) {
922 throw ProcessError(
TL(
"Union of walkable areas minus union of obstacles is not a simple polygon."));
925 return finalWalkableAreas;
931 GEOSCoordSequence* coordinateSequence = GEOSCoordSeq_create((
unsigned int)shape.size(), 2);
932 for (
int i = 0; i < (int)shape.size(); i++) {
933 GEOSCoordSeq_setXY(coordinateSequence, i, shape[i].x(), shape[i].y());
935 return coordinateSequence;
942 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
943 unsigned int coordinateSequenceSize;
944 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
947 for (
unsigned int i = 0; i < coordinateSequenceSize; i++) {
948 GEOSCoordSeq_getX(coordinateSequence, i, &x);
949 GEOSCoordSeq_getY(coordinateSequence, i, &y);
950 coordinateVector.push_back(
Position(x, y));
952 return coordinateVector;
956std::vector<JPS_Point>
958 std::vector<JPS_Point> pointVector;
959 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
960 unsigned int coordinateSequenceSize;
961 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
965 for (
unsigned int i = 0; i < coordinateSequenceSize - 1; i++) {
966 GEOSCoordSeq_getX(coordinateSequence, i, &x);
967 GEOSCoordSeq_getY(coordinateSequence, i, &y);
968 pointVector.push_back({x, y});
977 GEOSGeometry* linearRingAsPolygon = GEOSGeom_createPolygon(GEOSGeom_clone(linearRing),
nullptr, 0);
978 GEOSArea(linearRingAsPolygon, &area);
979 GEOSGeom_destroy(linearRingAsPolygon);
992 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
996 std::vector<PositionVector> holes;
997 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
998 if (nbrInteriorRings != -1) {
999 for (
int k = 0; k < nbrInteriorRings; k++) {
1000 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1014 nbrComponents = GEOSGetNumGeometries(polygon);
1015 const GEOSGeometry* largestComponent =
nullptr;
1018 for (
int i = 0; i < nbrComponents; i++) {
1019 const GEOSGeometry* componentPolygon = GEOSGetGeometryN(polygon, i);
1021 GEOSArea(componentPolygon, &area);
1023 if (area > maxArea) {
1025 largestComponent = componentPolygon;
1028 return largestComponent;
1034 JPS_GeometryBuilder geometryBuilder = JPS_GeometryBuilder_Create();
1037 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1039 JPS_GeometryBuilder_AddAccessibleArea(geometryBuilder, exteriorCoordinates.data(), exteriorCoordinates.size());
1042 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1043 if (nbrInteriorRings != -1) {
1044 for (
int k = 0; k < nbrInteriorRings; k++) {
1045 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1049 JPS_GeometryBuilder_ExcludeFromAccessibleArea(geometryBuilder, holeCoordinates.data(), holeCoordinates.size());
1054 JPS_ErrorMessage message =
nullptr;
1055 JPS_Geometry geometry = JPS_GeometryBuilder_Build(geometryBuilder, &message);
1056 if (geometry ==
nullptr) {
1057 const std::string error =
TLF(
"Error while generating geometry: %", JPS_ErrorMessage_GetMessage(message));
1058 JPS_ErrorMessage_Free(message);
1061 JPS_GeometryBuilder_Free(geometryBuilder);
1068 GEOSGeometry* polygonGeoCoordinates =
nullptr;
1069 if (useGeoCoordinates) {
1070 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1072 for (
Position& position : exteriorPoints) {
1075 const int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1076 std::vector<GEOSGeometry*> holeRings;
1077 if (nbrInteriorRings != -1) {
1078 for (
int k = 0; k < nbrInteriorRings; k++) {
1079 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1081 for (
Position& position : holePoints) {
1085 GEOSGeometry* holeRing = GEOSGeom_createLinearRing(holeRingCoords);
1086 holeRings.push_back(holeRing);
1090 GEOSGeometry* exteriorRing = GEOSGeom_createLinearRing(exteriorRingCoords);
1091 polygonGeoCoordinates = GEOSGeom_createPolygon(exteriorRing, holeRings.data(), nbrInteriorRings);
1093 std::ofstream dumpFile;
1094 dumpFile.open(filename);
1095 GEOSWKTWriter* writer = GEOSWKTWriter_create();
1097 char* wkt = GEOSWKTWriter_write(writer, polygonGeoCoordinates ==
nullptr ? polygon : polygonGeoCoordinates);
1098 dumpFile << wkt << std::endl;
1101 GEOSWKTWriter_destroy(writer);
1102 GEOSGeom_destroy(polygonGeoCoordinates);
1114 JPS_ErrorMessage message =
nullptr;
1115 JPS_StageId waitingStage = 0;
1119 const double offset = 2 * radius + POSITION_EPS;
1120 const double lonOffset = entry ? NUMERICAL_EPS : shape.
length() - NUMERICAL_EPS;
1123 for (
double latOff = offset; latOff < crossing->
getWidth() / 2. - offset; latOff += offset) {
1131 pv.push_back(crossing->
getIncomingLanes().front().lane->getShape().getCentroid());
1133 if (!entry && crossing->
getLinkCont().size() == 1 && crossing->
getLinkCont().front()->getLane()->isWalkingArea()) {
1134 pv.push_back(crossing->
getLinkCont().front()->getLane()->getShape().getCentroid());
1136 std::vector<JPS_Point> points;
1138 GEOSGeometry* point = GEOSGeom_createPointFromXY(p.x(), p.y());
1140 points.push_back({p.x(), p.y()});
1142 GEOSGeom_destroy(point);
1144 waitingStage = JPS_Simulation_AddStageWaitingSet(
myJPSSimulation, points.data(), points.size(), &message);
1145 if (message !=
nullptr) {
1146 const std::string error =
TLF(
"Error while adding waiting set for % on '%': %",
1147 entry ?
"entry" :
"exit", crossing->
getID(), JPS_ErrorMessage_GetMessage(message));
1148 JPS_ErrorMessage_Free(message);
1151 const auto proxy = JPS_Simulation_GetWaitingSetProxy(
myJPSSimulation, waitingStage, &message);
1152 JPS_WaitingSetProxy_SetWaitingSetState(proxy, JPS_WaitingSet_Inactive);
1155 (*myPythonScript) <<
"ws = simulation.add_waiting_set_stage([";
1156 for (
const JPS_Point& p : points) {
1157 (*myPythonScript) <<
"(" << p.x <<
"," << p.y <<
"),";
1159 (*myPythonScript) <<
"])\nsimulation.get_stage(ws).state = jps.stages.WaitingSetState.INACTIVE\n";
1161 return waitingStage;
1167 initGEOS(
nullptr,
nullptr);
1170 int nbrComponents = 0;
1171 double maxArea = 0.0;
1172 double totalArea = 0.0;
1174 if (nbrComponents > 1) {
1175 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
1176 nbrComponents, maxArea / totalArea * 100.0,
"%");
1178#ifdef DEBUG_GEOMETRY_GENERATION
1181 const std::string filename = oc.
getString(
"pedestrian.jupedsim.wkt");
1182 if (!filename.empty()) {
1190 JPS_ErrorMessage message =
nullptr;
1192 double strengthGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.strength-geometry-repulsion");
1193 double rangeGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.range-geometry-repulsion");
1195 if (oc.
isDefault(
"pedestrian.jupedsim.strength-geometry-repulsion") && oc.
isDefault(
"pedestrian.jupedsim.range-geometry-repulsion")) {
1196 WRITE_MESSAGE(
TL(
"Adapting geometry repulsion default values for jupedsim timestep of 0.02."));
1197 strengthGeometryRepulsion = 35.;
1198 rangeGeometryRepulsion = 0.019;
1204 JPS_CollisionFreeSpeedModelBuilder modelBuilder = JPS_CollisionFreeSpeedModelBuilder_Create(
1205 oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"),
1206 oc.
getFloat(
"pedestrian.jupedsim.range-neighbor-repulsion"),
1207 strengthGeometryRepulsion,
1208 rangeGeometryRepulsion);
1210 JPS_CollisionFreeSpeedModelBuilder_Free(modelBuilder);
1214 JPS_CollisionFreeSpeedModelV2Builder modelBuilder = JPS_CollisionFreeSpeedModelV2Builder_Create();
1216 JPS_CollisionFreeSpeedModelV2Builder_Free(modelBuilder);
1220 JPS_GeneralizedCentrifugalForceModelBuilder modelBuilder = JPS_GeneralizedCentrifugalForceModelBuilder_Create(
1221 oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"),
1222 strengthGeometryRepulsion,
1230 JPS_GeneralizedCentrifugalForceModelBuilder_Free(modelBuilder);
1234 JPS_SocialForceModelBuilder modelBuilder = JPS_SocialForceModelBuilder_Create(120000.0, 240000.0);
1236 JPS_SocialForceModelBuilder_Free(modelBuilder);
1242 const std::string error =
TLF(
"Error creating the pedestrian model: %", JPS_ErrorMessage_GetMessage(message));
1243 JPS_ErrorMessage_Free(message);
1248 const std::string error =
TLF(
"Error creating the simulation: %", JPS_ErrorMessage_GetMessage(message));
1249 JPS_ErrorMessage_Free(message);
1254 const SUMOPolygon*
const poly = polygonWithID.second;
1256 std::vector<JPS_Point> areaBoundary;
1258 areaBoundary.push_back({p.x(), p.y()});
1261 if (areaBoundary.back().x == areaBoundary.front().x && areaBoundary.back().y == areaBoundary.front().y) {
1262 areaBoundary.pop_back();
1271 (*myPythonScript) <<
"import jupedsim as jps\nimport shapely\n\n"
1272 "with open('" << filename <<
"') as f: geom = shapely.from_wkt(f.read())\n"
1273 "simulation = jps.Simulation(dt=" <<
STEPS2TIME(
myJPSDeltaT) <<
", model=jps.CollisionFreeSpeedModel(), geometry=geom,\n"
1274 "trajectory_writer=jps.SqliteTrajectoryWriter(output_file='out.sql'))\n";
1278 crossing.second.first =
addWaitingSet(crossing.first,
true);
1279 crossing.second.second =
addWaitingSet(crossing.first,
false);
1288 JPS_JourneyId journeyId, JPS_StageId stageId,
1289 const std::vector<WaypointDesc>& waypoints) :
1291 myJourneyId(journeyId), myStageId(stageId), myWaypoints(waypoints), myAgentId(0) {
1298 const std::vector<WaypointDesc>& waypoints) {
1299 if (myStage !=
nullptr) {
1300 myStage->setPState(
nullptr);
1303 myJourneyId = journeyId;
1304 myStageId = stageId;
1305 myWaypoints = waypoints;
1319 myRemoteXYPos.set(x, y, z);
1330 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.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
ShapeContainer & getShapeContainer()
Returns the shapes container.
MSPedestrianRouter & getPedestrianRouter(int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector()) const
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 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) 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).