@@ -564,13 +564,13 @@ MSPModel_JuPedSim::execute(SUMOTime time) {
564564 }
565565
566566 // Remove pedestrians that are in a predefined area, at a predefined rate.
567- for (AreaData & area : myAreas) {
568- const std::vector<JPS_Point>& areaBoundary = area. areaBoundary ;
567+ for (const auto & area : myAreas) {
568+ const std::vector<JPS_Point>& areaBoundary = area-> areaBoundary ;
569569 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 ;
570+ if (area-> areaType == " vanishing_area" ) {
571+ const SUMOTime period = area-> params .count (" period" ) > 0 ? string2time (area-> params .at (" period" )) : 1000 ;
572572 const int nbrPeriodsCoveringTimestep = (int )ceil (TS / STEPS2TIME (period));
573- if (time - area. lastRemovalTime >= nbrPeriodsCoveringTimestep * period) {
573+ if (time - area-> lastRemovalTime >= nbrPeriodsCoveringTimestep * period) {
574574 for (int k = 0 ; k < nbrPeriodsCoveringTimestep; k++) {
575575 const JPS_AgentId agentID = JPS_AgentIdIterator_Next (agentsInArea);
576576 if (agentID != 0 ) {
@@ -584,21 +584,21 @@ MSPModel_JuPedSim::execute(SUMOTime time) {
584584 // Code below only works if the removal happens at the last stage.
585585 const bool finalStage = person->getNumRemainingStages () == 1 ;
586586 if (finalStage) {
587- WRITE_MESSAGEF (TL (" Person '%' in vanishing area '%' was removed from the simulation." ), person->getID (), area. id );
587+ WRITE_MESSAGEF (TL (" Person '%' in vanishing area '%' was removed from the simulation." ), person->getID (), area-> id );
588588 while (!state->getStage ()->moveToNextEdge (person, time, 1 , nullptr ));
589589 registerArrived (agentID);
590590 myPedestrianStates.erase (iterator);
591- area. lastRemovalTime = time;
591+ area-> lastRemovalTime = time;
592592 }
593593 }
594594 }
595595 }
596596 }
597597 } else { // areaType == "influencer"
598598 for (JPS_AgentId agentID = JPS_AgentIdIterator_Next (agentsInArea); agentID != 0 ; agentID = JPS_AgentIdIterator_Next (agentsInArea)) {
599- if (area. params .count (" speed" ) > 0 ) {
599+ if (area-> params .count (" speed" ) > 0 ) {
600600 const JPS_Agent agent = JPS_Simulation_GetAgent (myJPSSimulation, agentID, nullptr );
601- const double newMaxSpeed = StringUtils::toDouble (area. params .at (" speed" ));
601+ const double newMaxSpeed = StringUtils::toDouble (area-> params .at (" speed" ));
602602 switch (myJPSModel) {
603603 case JPS_Model::CollisionFreeSpeed: {
604604 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState (agent, nullptr );
@@ -1257,19 +1257,7 @@ MSPModel_JuPedSim::initialize(const OptionsCont& oc) {
12571257 }
12581258 // Polygons that define vanishing areas aren't part of the regular JuPedSim geometry.
12591259 for (const auto & polygonWithID : myNetwork->getShapeContainer ().getPolygons ()) {
1260- const SUMOPolygon* const poly = polygonWithID.second ;
1261- if (poly->getShapeType () == " jupedsim.vanishing_area" || poly->getShapeType () == " jupedsim.influencer" ) {
1262- std::vector<JPS_Point> areaBoundary;
1263- for (const Position& p : poly->getShape ()) {
1264- areaBoundary.push_back ({p.x (), p.y ()});
1265- }
1266- // Make sure the shape is not repeating the first point.
1267- if (areaBoundary.back ().x == areaBoundary.front ().x && areaBoundary.back ().y == areaBoundary.front ().y ) {
1268- areaBoundary.pop_back ();
1269- }
1270- const std::string type = StringTokenizer (poly->getShapeType (), " ." ).getVector ()[1 ];
1271- myAreas.push_back ({poly->getID (), type, areaBoundary, poly->getParametersMap (), 0 });
1272- }
1260+ polygonChanged (polygonWithID.second , true , false );
12731261 }
12741262 if (OutputDevice::createDeviceByOption (" pedestrian.jupedsim.py" )) {
12751263 myPythonScript = &OutputDevice::getDeviceByOption (" pedestrian.jupedsim.py" );
@@ -1284,6 +1272,36 @@ MSPModel_JuPedSim::initialize(const OptionsCont& oc) {
12841272 crossing.second .first = addWaitingSet (crossing.first , true );
12851273 crossing.second .second = addWaitingSet (crossing.first , false );
12861274 }
1275+ myNetwork->getShapeContainer ().addShapeListener (this );
1276+ }
1277+
1278+
1279+ void
1280+ MSPModel_JuPedSim::polygonChanged (const SUMOPolygon* const poly, const bool added, const bool removed) {
1281+ if (poly->getShapeType () == " jupedsim.vanishing_area" || poly->getShapeType () == " jupedsim.influencer" ) {
1282+ SUMOTime lastRemovalTime = 0 ;
1283+ if (!added) {
1284+ for (auto areaIt = myAreas.begin (); areaIt != myAreas.end (); ++areaIt) {
1285+ if (poly->getID () == (*areaIt)->id ) {
1286+ lastRemovalTime = (*areaIt)->lastRemovalTime ;
1287+ myAreas.erase (areaIt);
1288+ break ;
1289+ }
1290+ }
1291+ }
1292+ if (!removed) {
1293+ std::vector<JPS_Point> areaBoundary;
1294+ for (const Position& p : poly->getShape ()) {
1295+ areaBoundary.push_back ({p.x (), p.y ()});
1296+ }
1297+ // Make sure the shape is not repeating the first point.
1298+ if (areaBoundary.back ().x == areaBoundary.front ().x && areaBoundary.back ().y == areaBoundary.front ().y ) {
1299+ areaBoundary.pop_back ();
1300+ }
1301+ const std::string type = StringTokenizer (poly->getShapeType (), " ." ).getVector ()[1 ];
1302+ myAreas.emplace_back (std::unique_ptr<AreaData>(new AreaData{poly->getID (), type, areaBoundary, poly->getParametersMap (), lastRemovalTime}));
1303+ }
1304+ }
12871305}
12881306
12891307
0 commit comments