Eclipse SUMO - Simulation of Urban MObility
GNEStop.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // Representation of Stops in NETEDIT
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 
22 #include <cmath>
24 #include <netedit/GNENet.h>
25 #include <netedit/GNEUndoList.h>
26 #include <netedit/GNEViewNet.h>
27 #include <netedit/GNEViewParent.h>
34 #include <utils/gui/div/GLHelper.h>
37 
38 #include "GNEStop.h"
39 
40 // ===========================================================================
41 // member method definitions
42 // ===========================================================================
43 
44 GNEStop::GNEStop(SumoXMLTag tag, GNEViewNet* viewNet, const SUMOVehicleParameter::Stop& stopParameter, GNEAdditional* stoppingPlace, GNEDemandElement* stopParent) :
45  GNEDemandElement(stopParent, viewNet, stopParent->getTagProperty().isPerson() ? GLO_PERSONSTOP : GLO_STOP, tag,
46 {}, {}, {}, {stoppingPlace}, {stopParent}, {}, {}, {}, {}, {}),
47 SUMOVehicleParameter::Stop(stopParameter),
48 myFriendlyPosition(false) {
49 }
50 
51 
52 GNEStop::GNEStop(GNEViewNet* viewNet, const SUMOVehicleParameter::Stop& stopParameter, GNELane* lane, bool friendlyPosition, GNEDemandElement* stopParent) :
53  GNEDemandElement(stopParent, viewNet,
54  stopParent->getTagProperty().isPerson() ? GLO_PERSONSTOP : GLO_STOP,
55  stopParent->getTagProperty().isPerson() ? SUMO_TAG_PERSONSTOP_LANE : SUMO_TAG_STOP_LANE,
56 {}, {lane}, {}, {}, {stopParent}, {}, {}, {}, {}, {}),
57 SUMOVehicleParameter::Stop(stopParameter),
58 myFriendlyPosition(friendlyPosition) {
59 }
60 
61 
63 
64 
65 std::string
67  return "";
68 }
69 
70 
71 void
73  write(device);
74 }
75 
76 
77 bool
79  // only Stops placed over lanes can be invalid
81  return true;
82  } else if (myFriendlyPosition) {
83  // with friendly position enabled position are "always fixed"
84  return true;
85  } else {
86  // obtain lane length
87  double laneLength = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength() * getLaneParents().front()->getLengthGeometryFactor();
88  // declare a copy of start and end positions
89  double startPosCopy = startPos;
90  double endPosCopy = endPos;
91  // check if position has to be fixed
92  if (startPosCopy < 0) {
93  startPosCopy += laneLength;
94  }
95  if (endPosCopy < 0) {
96  endPosCopy += laneLength;
97  }
98  // check values
100  return true;
101  } else if (!(parametersSet & STOP_START_SET)) {
102  return (endPosCopy <= getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength());
103  } else if (!(parametersSet & STOP_END_SET)) {
104  return (startPosCopy >= 0);
105  } else {
106  return ((startPosCopy >= 0) && (endPosCopy <= getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength()) && ((endPosCopy - startPosCopy) >= POSITION_EPS));
107  }
108  }
109 }
110 
111 
112 std::string
114  // declare a copy of start and end positions
115  double startPosCopy = startPos;
116  double endPosCopy = endPos;
117  // obtain lane length
118  double laneLength = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength();
119  // check if position has to be fixed
120  if (startPosCopy < 0) {
121  startPosCopy += laneLength;
122  }
123  if (endPosCopy < 0) {
124  endPosCopy += laneLength;
125  }
126  // declare variables
127  std::string errorStart, separator, errorEnd;
128  // check positions over lane
129  if (startPosCopy < 0) {
130  errorStart = (toString(SUMO_ATTR_STARTPOS) + " < 0");
131  } else if (startPosCopy > getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength()) {
132  errorStart = (toString(SUMO_ATTR_STARTPOS) + " > lanes's length");
133  }
134  if (endPosCopy < 0) {
135  errorEnd = (toString(SUMO_ATTR_ENDPOS) + " < 0");
136  } else if (endPosCopy > getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength()) {
137  errorEnd = (toString(SUMO_ATTR_ENDPOS) + " > lanes's length");
138  }
139  // check separator
140  if ((errorStart.size() > 0) && (errorEnd.size() > 0)) {
141  separator = " and ";
142  }
143  return errorStart + separator + errorEnd;
144 }
145 
146 
147 void
149  //
150 }
151 
152 
153 GNEEdge*
155  if (getAdditionalParents().size() > 0) {
156  return &getAdditionalParents().front()->getLaneParents().front()->getParentEdge();
157  } else {
158  return &getLaneParents().front()->getParentEdge();
159  }
160 }
161 
162 
163 GNEEdge*
165  if (getAdditionalParents().size() > 0) {
166  return &getAdditionalParents().front()->getLaneParents().front()->getParentEdge();
167  } else {
168  return &getLaneParents().front()->getParentEdge();
169  }
170 }
171 
172 
175  return getDemandElementParents().front()->getVClass();
176 }
177 
178 
179 const RGBColor&
181  if (myTagProperty.isPersonStop()) {
183  } else {
185  }
186 }
187 
188 
189 void
191  // Nothing to compute
192 }
193 
194 
195 void
197  // only start geometry moving if stop is placed over a lane
198  if (getLaneParents().size() > 0) {
199  // always save original position over view
201  // save start and end position
204  // save current centering boundary
206  }
207 }
208 
209 
210 void
212  // check that stop is placed over a lane and endGeometryMoving was called only once
214  // reset myMovingGeometryBoundary
216  }
217 }
218 
219 
220 void
222  // only move if at leats start or end positions is defined
223  if ((getLaneParents().size() > 0) && ((parametersSet & STOP_START_SET) || (parametersSet & STOP_END_SET))) {
224  // Calculate new position using old position
226  newPosition.add(offset);
227  // filtern position using snap to active grid
228  newPosition = myViewNet->snapToActiveGrid(newPosition);
229  double offsetLane = getLaneParents().front()->getGeometry().shape.nearest_offset_to_point2D(newPosition, false) - getLaneParents().front()->getGeometry().shape.nearest_offset_to_point2D(myStopMove.originalViewPosition, false);
230  // check if both position has to be moved
231  if ((parametersSet & STOP_START_SET) && (parametersSet & STOP_END_SET)) {
232  // calculate stoppingPlace length and lane length (After apply geometry factor)
233  double stoppingPlaceLength = fabs(parse<double>(myStopMove.secondOriginalPosition) - parse<double>(myStopMove.firstOriginalLanePosition));
234  double laneLengt = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength() * getLaneParents().front()->getLengthGeometryFactor();
235  // avoid changing stopping place's length
236  if ((parse<double>(myStopMove.firstOriginalLanePosition) + offsetLane) < 0) {
237  startPos = 0;
238  endPos = stoppingPlaceLength;
239  } else if ((parse<double>(myStopMove.secondOriginalPosition) + offsetLane) > laneLengt) {
240  startPos = laneLengt - stoppingPlaceLength;
241  endPos = laneLengt;
242  } else {
243  startPos = parse<double>(myStopMove.firstOriginalLanePosition) + offsetLane;
244  endPos = parse<double>(myStopMove.secondOriginalPosition) + offsetLane;
245  }
246  } else {
247  // check if start position must be moved
248  if ((parametersSet & STOP_START_SET)) {
249  startPos = parse<double>(myStopMove.firstOriginalLanePosition) + offsetLane;
250  }
251  // check if start position must be moved
252  if ((parametersSet & STOP_END_SET)) {
253  endPos = parse<double>(myStopMove.secondOriginalPosition) + offsetLane;
254  }
255  }
256  // update person or vehicle frame
257  getDemandElementParents().front()->markSegmentGeometryDeprecated();
258  getDemandElementParents().front()->updateGeometry();
259  // Update geometry
260  updateGeometry();
261  }
262 }
263 
264 
265 void
267  // only commit geometry moving if at leats start or end positions is defined
268  if ((getLaneParents().size() > 0) && ((parametersSet & STOP_START_SET) || (parametersSet & STOP_END_SET))) {
269  undoList->p_begin("position of " + getTagStr());
270  if (parametersSet & STOP_START_SET) {
272  }
273  if (parametersSet & STOP_END_SET) {
275  }
276  undoList->p_end();
277  // update person or vehicle frame
278  getDemandElementParents().front()->markSegmentGeometryDeprecated();
279  getDemandElementParents().front()->updateGeometry();
280  }
281 }
282 
283 
284 void
286  // Clear all containers
288  //only update Stops over lanes, because other uses the geometry of stopping place parent
289  if (getLaneParents().size() > 0) {
290  // Cut shape using as delimitators fixed start position and fixed end position
292  // Get calculate lengths and rotations
294  } else if (getAdditionalParents().size() > 0) {
295  // copy geometry of additional
296  myDemandElementGeometry.shape = getAdditionalParents().at(0)->getAdditionalGeometry().shape;
297  myDemandElementGeometry.shapeLengths = getAdditionalParents().at(0)->getAdditionalGeometry().shapeLengths;
298  myDemandElementGeometry.shapeRotations = getAdditionalParents().at(0)->getAdditionalGeometry().shapeRotations;
299  }
300 }
301 
302 
303 Position
305  if (getLaneParents().size() > 0) {
306  // calculate start and end positions as absolute values
307  double start = fabs(parametersSet & STOP_START_SET ? startPos : 0);
308  double end = fabs(parametersSet & STOP_END_SET ? endPos : getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength());
309  // obtain position in view depending if both positions are defined
311  return getLaneParents().front()->getGeometry().shape.positionAtOffset(getLaneParents().front()->getGeometry().shape.length() / 2);
312  } else if (!(parametersSet & STOP_START_SET)) {
313  return getLaneParents().front()->getGeometry().shape.positionAtOffset(end);
314  } else if (!(parametersSet & STOP_END_SET)) {
315  return getLaneParents().front()->getGeometry().shape.positionAtOffset(start);
316  } else {
317  return getLaneParents().front()->getGeometry().shape.positionAtOffset((start + end) / 2.0);
318  }
319  } else if (getDemandElementParents().size() > 0) {
320  return getDemandElementParents().front()->getPositionInView();
321  } else {
322  throw ProcessError("Invalid Stop parent");
323  }
324 }
325 
326 
327 std::string
329  if (getDemandElementParents().size() > 0) {
330  return getDemandElementParents().front()->getID();
331  } else if (getAdditionalParents().size() > 0) {
332  return getAdditionalParents().front()->getID();
333  } else if (getLaneParents().size() > 0) {
334  return getLaneParents().front()->getID();
335  } else {
336  throw ProcessError("Invalid parent");
337  }
338 }
339 
340 
341 Boundary
343  // Return Boundary depending if myMovingGeometryBoundary is initialised (important for move geometry)
344  if (getAdditionalParents().size() > 0) {
345  return getAdditionalParents().at(0)->getCenteringBoundary();
348  } else if (myDemandElementGeometry.shape.size() > 0) {
350  b.grow(20);
351  return b;
352  } else {
353  return Boundary(-0.1, -0.1, 0.1, 0.1);
354  }
355 }
356 
357 
358 void
360  // declare flag to enable or disable draw person plan
361  bool drawPersonPlan = false;
364  drawPersonPlan = true;
365  }
367  drawPersonPlan = true;
368  } else if (myViewNet->getDottedAC() == getDemandElementParents().front()) {
369  drawPersonPlan = true;
371  drawPersonPlan = true;
374  drawPersonPlan = true;
375  }
376  // check if stop can be drawn
377  if (drawPersonPlan) {
378  // Obtain exaggeration of the draw
379  const double exaggeration = s.addSize.getExaggeration(s, this);
380  // declare value to save stop color
381  RGBColor stopColor;
382  // Set color
383  if (drawUsingSelectColor()) {
384  if (myTagProperty.isPersonStop()) {
386  } else {
387  stopColor = s.colorSettings.selectedRouteColor;
388  }
389  } else if (myTagProperty.isPersonStop()) {
390  stopColor = s.colorSettings.personStops;
391  } else {
392  stopColor = s.colorSettings.stops;
393  }
394  // Start drawing adding an gl identificator
395  glPushName(getGlID());
396  // Add a draw matrix
397  glPushMatrix();
398  // set Color
399  GLHelper::setColor(stopColor);
400  // Start with the drawing of the area traslating matrix to origin
401  glTranslated(0, 0, getType());
402  // draw depending of details
403  if (s.drawDetail(s.detailSettings.stopsDetails, exaggeration) && getLaneParents().size() > 0) {
404  // Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration
406  getLaneParents().front()->getParentEdge().getNBEdge()->getLaneWidth(getLaneParents().front()->getIndex()) * 0.5);
408  getLaneParents().front()->getParentEdge().getNBEdge()->getLaneWidth(getLaneParents().front()->getIndex()) * -0.5);
409  // pop draw matrix
410  glPopMatrix();
411  // Add a draw matrix
412  glPushMatrix();
413  // move to geometry front
414  glTranslated(myDemandElementGeometry.shape.back().x(), myDemandElementGeometry.shape.back().y(), getType());
415  glRotated(myDemandElementGeometry.shapeRotations.back(), 0, 0, 1);
416  // draw front of Stop depending if it's placed over a lane or over a stoppingPlace
417  if (getLaneParents().size() > 0) {
418  // draw front of Stop
419  GLHelper::drawBoxLine(Position(0, 0), 0, exaggeration * 0.5,
420  getLaneParents().front()->getParentEdge().getNBEdge()->getLaneWidth(getLaneParents().front()->getIndex()) * 0.5);
421  } else {
422  // draw front of Stop
423  GLHelper::drawBoxLine(Position(0, 0), 0, exaggeration * 0.5, exaggeration);
424  }
425  // only draw text if isn't being drawn for selecting
426  if (s.drawDetail(s.detailSettings.stopsText, exaggeration) && !s.drawForSelecting) {
427  // move to "S" position
428  glTranslated(0, 1, 0);
429  // draw "S" symbol
430  GLHelper::drawText("S", Position(), .1, 2.8, stopColor);
431  // move to subtitle positin
432  glTranslated(0, 1.4, 0);
433  // draw subtitle depending of tag
434  GLHelper::drawText("lane", Position(), .1, 1, stopColor, 180);
435  }
436  // pop draw matrix
437  glPopMatrix();
438  // Draw name if isn't being drawn for selecting
439  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
440  // check if dotted contour has to be drawn
441  if (myViewNet->getDottedAC() == this) {
442  // draw dooted contour depending if it's placed over a lane or over a stoppingPlace
443  if (getLaneParents().size() > 0) {
444  GLHelper::drawShapeDottedContourAroundShape(s, getType(), myDemandElementGeometry.shape, getLaneParents().front()->getParentEdge().getNBEdge()->getLaneWidth(getLaneParents().front()->getIndex()) * 0.5);
445  } else {
447  }
448  }
449  } else {
450  // Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration
452  // pop draw matrix
453  glPopMatrix();
454  }
455  // Pop name
456  glPopName();
457  // draw person parent if this stop if their first person plan child
458  if ((getDemandElementParents().size() == 1) && getDemandElementParents().front()->getDemandElementChildren().front() == this) {
459  getDemandElementParents().front()->drawGL(s);
460  }
461  }
462 }
463 
464 
465 void
467  if (!myViewNet) {
468  throw ProcessError("ViewNet cannot be nullptr");
469  } else {
471  // add object of list into selected objects
473  if (changeFlag) {
474  mySelected = true;
475  }
476  }
477 }
478 
479 
480 void
482  if (!myViewNet) {
483  throw ProcessError("ViewNet cannot be nullptr");
484  } else {
486  // remove object of list of selected objects
488  if (changeFlag) {
489  mySelected = false;
490 
491  }
492  }
493 }
494 
495 
496 std::string
498  switch (key) {
499  case SUMO_ATTR_ID:
500  return getDemandElementID();
501  case SUMO_ATTR_DURATION:
502  return time2string(duration);
503  case SUMO_ATTR_UNTIL:
504  return time2string(until);
505  case SUMO_ATTR_INDEX:
506  if (index == STOP_INDEX_END) {
507  return "end";
508  } else if (index == STOP_INDEX_FIT) {
509  return "fit";
510  } else {
511  return toString(index);
512  }
513  case SUMO_ATTR_TRIGGERED:
514  // this is an special case
516  return "1";
517  } else {
518  return "0";
519  }
521  // this is an special case
523  return "1";
524  } else {
525  return "0";
526  }
527  case SUMO_ATTR_EXPECTED:
529  return toString(awaitedPersons);
530  } else {
531  return "";
532  }
535  return toString(awaitedContainers);
536  } else {
537  return "";
538  }
539  case SUMO_ATTR_PARKING:
541  return toString(parking);
542  } else {
543  return "";
544  }
545  case SUMO_ATTR_ACTTYPE:
546  return "waiting";
547  case SUMO_ATTR_TRIP_ID:
549  return tripId;
550  } else {
551  return "";
552  }
553  // specific of Stops over stoppingPlaces
554  case SUMO_ATTR_BUS_STOP:
558  return getAdditionalParents().front()->getID();
559  // specific of stops over lanes
560  case SUMO_ATTR_LANE:
561  return getLaneParents().front()->getID();
562  case SUMO_ATTR_STARTPOS:
564  return toString(startPos);
565  } else {
566  return "";
567  }
568  case SUMO_ATTR_ENDPOS:
569  if (parametersSet & STOP_END_SET) {
570  return toString(endPos);
571  } else {
572  return "";
573  }
576  //
577  case GNE_ATTR_SELECTED:
579  case GNE_ATTR_GENERIC:
580  return getGenericParametersStr();
581  case GNE_ATTR_PARENT:
582  return getDemandElementParents().front()->getID();
583  default:
584  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
585  }
586 }
587 
588 
589 double
591  switch (key) {
592  case SUMO_ATTR_STARTPOS:
594  return startPos;
595  } else {
596  return 0;
597  }
598  case SUMO_ATTR_ENDPOS:
599  if (parametersSet & STOP_END_SET) {
600  return endPos;
601  } else {
602  return getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength();
603  }
604  default:
605  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
606  }
607 }
608 
609 
610 void
611 GNEStop::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
612  if (value == getAttribute(key)) {
613  return; //avoid needless changes, later logic relies on the fact that attributes have changed
614  }
615  switch (key) {
616  case SUMO_ATTR_ID:
617  case SUMO_ATTR_DURATION:
618  case SUMO_ATTR_UNTIL:
619  case SUMO_ATTR_INDEX:
620  case SUMO_ATTR_TRIGGERED:
622  case SUMO_ATTR_EXPECTED:
624  case SUMO_ATTR_PARKING:
625  case SUMO_ATTR_ACTTYPE:
626  case SUMO_ATTR_TRIP_ID:
627  // specific of Stops over stoppingPlaces
628  case SUMO_ATTR_BUS_STOP:
632  // specific of stops over lanes
633  case SUMO_ATTR_LANE:
634  case SUMO_ATTR_STARTPOS:
635  case SUMO_ATTR_ENDPOS:
637  //
638  case GNE_ATTR_GENERIC:
639  case GNE_ATTR_SELECTED:
640  undoList->p_add(new GNEChange_Attribute(this, myViewNet->getNet(), key, value));
641  break;
642  default:
643  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
644  }
645 }
646 
647 
648 bool
649 GNEStop::isValid(SumoXMLAttr key, const std::string& value) {
650  // declare string error
651  std::string error;
652  switch (key) {
653  case SUMO_ATTR_ID:
654  return isValidDemandElementID(value);
655  case SUMO_ATTR_DURATION:
656  case SUMO_ATTR_UNTIL:
657  if (canParse<SUMOTime>(value)) {
658  return parse<SUMOTime>(value) >= 0;
659  } else {
660  return false;
661  }
662  case SUMO_ATTR_INDEX:
663  if ((value == "fit") || (value == "end")) {
664  return true;
665  } else if (canParse<int>(value)) {
666  return (parse<int>(value) >= 0);
667  } else {
668  return false;
669  }
670  case SUMO_ATTR_TRIGGERED:
671  return canParse<bool>(value);
673  return canParse<bool>(value);
674  case SUMO_ATTR_EXPECTED:
676  if (value.empty()) {
677  return true;
678  } else {
679  std::vector<std::string> IDs = parse<std::vector<std::string>>(value);
680  for (const auto &i : IDs) {
681  if (SUMOXMLDefinitions::isValidVehicleID(i) == false) {
682  return false;
683  }
684  }
685  return true;
686  }
687  case SUMO_ATTR_PARKING:
688  return canParse<bool>(value);
689  case SUMO_ATTR_ACTTYPE:
690  return (value == "waiting");
691  case SUMO_ATTR_TRIP_ID:
693  // specific of Stops over stoppingPlaces
694  case SUMO_ATTR_BUS_STOP:
695  return (myViewNet->getNet()->retrieveAdditional(SUMO_TAG_BUS_STOP, value, false) != nullptr);
697  return (myViewNet->getNet()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, value, false) != nullptr);
699  return (myViewNet->getNet()->retrieveAdditional(SUMO_TAG_CHARGING_STATION, value, false) != nullptr);
701  return (myViewNet->getNet()->retrieveAdditional(SUMO_TAG_PARKING_AREA, value, false) != nullptr);
702  // specific of stops over lanes
703  case SUMO_ATTR_LANE:
704  if (myViewNet->getNet()->retrieveLane(value, false) != nullptr) {
705  return true;
706  } else {
707  return false;
708  }
709  case SUMO_ATTR_STARTPOS:
710  if (value.empty()) {
711  return true;
712  } else if (canParse<double>(value)) {
713  return GNEStoppingPlace::checkStoppinPlacePosition(value, toString(endPos), getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength(), myFriendlyPosition);
714  } else {
715  return false;
716  }
717  case SUMO_ATTR_ENDPOS:
718  if (value.empty()) {
719  return true;
720  } else if (canParse<double>(value)) {
721  return GNEStoppingPlace::checkStoppinPlacePosition(toString(startPos), value, getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength(), myFriendlyPosition);
722  } else {
723  return false;
724  }
726  return canParse<bool>(value);
727  //
728  case GNE_ATTR_SELECTED:
729  return canParse<bool>(value);
730  case GNE_ATTR_GENERIC:
731  return isGenericParametersValid(value);
732  default:
733  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
734  }
735 }
736 
737 
738 void
740  // obtain a copy of parameter sets
741  int newParametersSet = parametersSet;
742  // modify parametersSetCopy depending of attr
743  switch (key) {
744  case SUMO_ATTR_EXPECTED:
745  newParametersSet |= STOP_TRIGGER_SET;
746  break;
748  newParametersSet |= STOP_CONTAINER_TRIGGER_SET;
749  break;
750  default:
751  break;
752  }
753  // add GNEChange_EnableAttribute
754  undoList->add(new GNEChange_EnableAttribute(this, myViewNet->getNet(), parametersSet, newParametersSet), true);
755 }
756 
757 
758 bool
760  switch (key) {
761  case SUMO_ATTR_EXPECTED:
762  return (parametersSet & STOP_TRIGGER_SET) != 0;
765  default:
766  return true;
767  };
768 }
769 
770 
771 std::string
773  return getTagStr();
774 }
775 
776 
777 std::string
779  std::string stopType;
780  // first distinguish between person stops and vehicles stops
781  if (getDemandElementParents().front()->getTagProperty().isPerson()) {
782  stopType = "person stop";
783  } else {
784  stopType = "vehicle stop";
785  }
786  if (getAdditionalParents().size() > 0) {
787  return stopType + ": " + getAdditionalParents().front()->getTagStr();
788  } else {
789  return stopType + ": lane";
790  }
791 }
792 
793 
794 double
796  if (parametersSet & STOP_END_SET) {
797  double fixedPos = startPos;
798  const double len = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength();
799  if (fixedPos < 0) {
800  fixedPos += len;
801  }
802  return fixedPos * getLaneParents().front()->getLengthGeometryFactor();
803  } else {
804  return 0;
805  }
806 }
807 
808 
809 double
812  double fixedPos = endPos;
813  const double len = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength();
814  if (fixedPos < 0) {
815  fixedPos += len;
816  }
817  return fixedPos * getLaneParents().front()->getLengthGeometryFactor();
818  } else {
819  return 0;
820  }
821 }
822 
823 
824 std::string
826  std::string result;
827  // Generate an string using the following structure: "key1=value1|key2=value2|...
828  for (auto i : getParametersMap()) {
829  result += i.first + "=" + i.second + "|";
830  }
831  // remove the last "|"
832  if (!result.empty()) {
833  result.pop_back();
834  }
835  return result;
836 }
837 
838 
839 std::vector<std::pair<std::string, std::string> >
841  std::vector<std::pair<std::string, std::string> > result;
842  // iterate over parameters map and fill result
843  for (auto i : getParametersMap()) {
844  result.push_back(std::make_pair(i.first, i.second));
845  }
846  return result;
847 }
848 
849 
850 void
851 GNEStop::setGenericParametersStr(const std::string& value) {
852  // clear parameters
853  clearParameter();
854  // separate value in a vector of string using | as separator
855  std::vector<std::string> parsedValues;
856  StringTokenizer stValues(value, "|", true);
857  while (stValues.hasNext()) {
858  parsedValues.push_back(stValues.next());
859  }
860  // check that parsed values (A=B)can be parsed in generic parameters
861  for (auto i : parsedValues) {
862  std::vector<std::string> parsedParameters;
863  StringTokenizer stParam(i, "=", true);
864  while (stParam.hasNext()) {
865  parsedParameters.push_back(stParam.next());
866  }
867  // Check that parsed parameters are exactly two and contains valid chracters
868  if (parsedParameters.size() == 2 && SUMOXMLDefinitions::isValidGenericParameterKey(parsedParameters.front()) && SUMOXMLDefinitions::isValidGenericParameterValue(parsedParameters.back())) {
869  setParameter(parsedParameters.front(), parsedParameters.back());
870  }
871  }
872 }
873 
874 // ===========================================================================
875 // private
876 // ===========================================================================
877 
878 void
879 GNEStop::setAttribute(SumoXMLAttr key, const std::string& value) {
880  switch (key) {
881  case SUMO_ATTR_ID:
882  changeDemandElementID(value);
883  break;
884  case SUMO_ATTR_DURATION:
885  duration = string2time(value);
886  break;
887  case SUMO_ATTR_UNTIL:
888  until = string2time(value);
889  break;
890  case SUMO_ATTR_INDEX:
891  if (value == "fit") {
893  } else if (value == "end") {
895  } else {
896  index = parse<int>(value);
897  }
898  break;
899  case SUMO_ATTR_TRIGGERED:
900  triggered = parse<bool>(value);
901  // this is an special case: only if SUMO_ATTR_TRIGGERED is true, it will be written in XML
902  if (triggered) {
904  } else {
906  }
907  break;
909  containerTriggered = parse<bool>(value);
910  // this is an special case: only if SUMO_ATTR_CONTAINER_TRIGGERED is true, it will be written in XML
911  if (containerTriggered) {
913  } else {
915  }
916  break;
917  case SUMO_ATTR_EXPECTED:
918  if (value.empty()) {
920  } else {
921  awaitedPersons = parse<std::set<std::string> >(value);
923  }
924  break;
926  if (value.empty()) {
928  } else {
929  awaitedContainers = parse<std::set<std::string> >(value);
931  }
932  break;
933  case SUMO_ATTR_PARKING:
934  if (value.empty()) {
936  } else {
937  parking = parse<bool>(value);
939  }
940  break;
941  case SUMO_ATTR_ACTTYPE:
942  // CHECK
943  break;
944  case SUMO_ATTR_TRIP_ID:
945  if (value.empty()) {
947  } else {
948  tripId = value;
950  }
951  break;
952  // specific of Stops over stoppingPlaces
953  case SUMO_ATTR_BUS_STOP:
957  changeAdditionalParent(this, value, 0);
958  break;
959  // specific of Stops over lanes
960  case SUMO_ATTR_LANE:
961  changeLaneParents(this, value);
962  break;
963  case SUMO_ATTR_STARTPOS:
964  if (value.empty()) {
966  } else {
967  startPos = parse<double>(value);
969  }
970  break;
971  case SUMO_ATTR_ENDPOS:
972  if (value.empty()) {
974  } else {
975  endPos = parse<double>(value);
977  }
978  break;
980  myFriendlyPosition = parse<bool>(value);
981  break;
982  //
983  case GNE_ATTR_SELECTED:
984  if (parse<bool>(value)) {
986  } else {
988  }
989  break;
990  case GNE_ATTR_GENERIC:
992  break;
993  default:
994  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
995  }
996 }
997 
998 
999 void
1000 GNEStop::setEnabledAttribute(const int enabledAttributes) {
1001  parametersSet = enabledAttributes;
1002 }
1003 
1004 /****************************************************************************/
bool mySelected
boolean to check if this AC is selected (instead of GUIGlObjectStorage)
const int STOP_CONTAINER_TRIGGER_SET
const TagProperties & myTagProperty
the xml tag to which this attribute carrier corresponds
void calculateShapeRotationsAndLengths()
calculate shape rotations and lengths
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNEStop.cpp:342
a person stop
bool isPersonStop() const
return true if tag correspond to a person stop element
RGBColor selectedPersonPlanColor
person plan selection color (Rides, Walks, personStops...)
DemandElementGeometry myDemandElementGeometry
demand element geometry
SumoXMLTag
Numbers representing SUMO-XML - element names.
Position snapToActiveGrid(const Position &pos, bool snapXY=true) const
Returns a position that is mapped to the closest grid point if the grid is active.
std::string lane
The lane to stop at.
double scale
information about a lane&#39;s width (temporary, used for a single view)
static const RGBColor personStops
color for personStops
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
void addedLockedObject(const GUIGlObjectType type)
set object selected
void endGeometryMoving()
end movement
Definition: GNEStop.cpp:211
Boundary movingGeometryBoundary
boundary used during moving of elements (to avoid insertion in RTREE)
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition: GLHelper.cpp:182
GUIVisualizationTextSettings addName
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
bool isStop() const
return true if tag correspond to a stop element
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:127
std::vector< std::pair< std::string, std::string > > getGenericParameters() const
return generic parameters as vector of pairs format
Definition: GNEStop.cpp:840
const GNEDemandElement * getLockedPerson() const
get locked person
std::string firstOriginalLanePosition
value for saving first original position over lane before moving
bool isPersonPlan() const
return true if tag correspond to a person plan
Stores the information about how to visualize structures.
DemandElementMove myStopMove
variable demand element move
Definition: GNEStop.h:205
void changeAdditionalParent(GNEShape *shapeTobeChanged, const std::string &newAdditionalParentID, int additionalParentIndex)
change additional parent of a shape
void select(GUIGlID id, bool update=true)
Adds the object with the given id.
GNEViewParent * getViewParent() const
get the net object
Definition: GNEViewNet.cpp:921
GUIVisualizationSettings * getVisualisationSettings() const
get visualitation settings
void setGenericParametersStr(const std::string &value)
set generic parameters in string format
Definition: GNEStop.cpp:851
std::string secondOriginalPosition
value for saving second original position over lane before moving
static bool checkStoppinPlacePosition(const std::string &startPosStr, const std::string &endPosStr, const double laneLength, const bool friendlyPos)
check if the position of an stoppingPlace over a lane is valid (without modifications) ...
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNEStop.cpp:359
void enableAttribute(SumoXMLAttr key, GNEUndoList *undoList)
Definition: GNEStop.cpp:739
Position originalViewPosition
value for saving first original position over lane before moving
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
stop placed over a lane (used in netedit)
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, int align=0, double width=-1)
Definition: GLHelper.cpp:668
bool drawDetail(const double detail, const double exaggeration) const
check if details can be drawn for the given GUIVisualizationDetailSettings and current scale and exxa...
int parametersSet
Information for the output which parameter were set.
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:73
void updateGeometry()
update pre-computed geometry information
Definition: GNEStop.cpp:285
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
const int STOP_INDEX_FIT
void changeDemandElementID(const std::string &newID)
change ID of demand element
bool hasNext()
returns the information whether further substrings exist
static const double stopsDetails
details for stops
PositionVector shape
The shape of the additional element.
virtual std::string getAttribute(SumoXMLAttr key) const =0
double getAttributeDouble(SumoXMLAttr key) const
Definition: GNEStop.cpp:590
static bool isValidGenericParameterKey(const std::string &value)
whether the given string is a valid key for a generic parameter
generic attribute
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
bool triggered
whether an arriving person lets the vehicle continue
bool isAttributeEnabled(SumoXMLAttr key) const
Definition: GNEStop.cpp:759
void writeDemandElement(OutputDevice &device) const
writte demand element element into a xml file
Definition: GNEStop.cpp:72
friend class GNEChange_EnableAttribute
std::string tripId
id of the trip within a cyclical public transport route
const std::vector< GNEDemandElement * > & getDemandElementChildren() const
return vector of demand elements that have as Parent this edge (For example, Calibrators) ...
bool myFriendlyPosition
Flag for friendly position.
Definition: GNEStop.h:208
std::string getBegin() const
get begin time of demand element
Definition: GNEStop.cpp:66
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
Definition: GNENet.cpp:2133
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
GNEEdge * getToEdge() const
obtain to edge of this demand element
Definition: GNEStop.cpp:164
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
GUIVisualizationSizeSettings addSize
const int STOP_START_SET
LockGLObjectTypes * getLockGLObjectTypes() const
get selected items Modul
static bool isValidGenericParameterValue(const std::string &value)
whether the given string is a valid value for a generic parameter
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
void moveGeometry(const Position &offset)
change the position of the element geometry without saving in undoList
Definition: GNEStop.cpp:221
std::string getAttribute(SumoXMLAttr key) const
Definition: GNEStop.cpp:497
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
RGBColor selectedRouteColor
route selection color (used for routes and vehicle stops)
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:616
double getStartGeometryPositionOverLane() const
get start position over lane that is applicable to the shape
Definition: GNEStop.cpp:795
void selectAttributeCarrier(bool changeFlag=true)
inherited from GNEAttributeCarrier
Definition: GNEStop.cpp:466
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:80
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
std::vector< double > shapeLengths
The lengths of the single shape parts.
double getEndGeometryPositionOverLane() const
get end position over lane that is applicable to the shape
Definition: GNEStop.cpp:810
void startGeometryMoving()
Definition: GNEStop.cpp:196
static bool isGenericParametersValid(const std::string &value)
check if given string can be parsed to a map/list of generic parameters
void removeLockedObject(const GUIGlObjectType type)
set object unselected
friend class GNEChange_Attribute
declare friend class
SUMOTime until
The time at which the vehicle may continue its journey.
const int STOP_INDEX_END
bool isValidDemandElementID(const std::string &newID) const
check if a new demand element ID is valid
const std::vector< GNELane * > & getLaneParents() const
get lanes of VSS
const std::vector< GNEAdditional * > & getAdditionalParents() const
return vector of additionals that have as Parent this edge (For example, Calibrators) ...
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:42
const int STOP_TRIP_ID_SET
const std::string & getDemandElementID() const
returns DemandElement ID
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
#define POSITION_EPS
Definition: config.h:169
void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
method for setting the attribute and letting the object perform demand element changes ...
Definition: GNEStop.cpp:611
GNESelectorFrame * getSelectorFrame() const
get frame for GNE_NMODE_SELECT
const int STOP_EXPECTED_SET
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
std::string getPopUpID() const
get PopPup ID (Used in AC Hierarchy)
Definition: GNEStop.cpp:772
const RGBColor & getColor() const
get color
Definition: GNEStop.cpp:180
void write(OutputDevice &dev) const
Writes the stop as XML.
double endPos
The stopping position end.
void commitGeometryMoving(GNEUndoList *undoList)
commit geometry changes in the attributes of an element after use of moveGeometry(...)
Definition: GNEStop.cpp:266
static const RGBColor stops
color for Stops
static void drawShapeDottedContourAroundShape(const GUIVisualizationSettings &s, const int type, const PositionVector &shape, const double width)
draw a dotted contour around the given Non closed shape with certain width
Definition: GLHelper.cpp:461
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
Definition: GNEViewNet.cpp:411
Definition of vehicle stop (position and duration)
void compute()
compute demand element
Definition: GNEStop.cpp:190
int index
at which position in the stops list
const int STOP_END_SET
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:50
GUIVisualizationDetailSettings detailSettings
detail settings
const std::vector< GNEDemandElement * > & getDemandElementParents() const
return vector of demand elements that have as Parent this edge (For example, Calibrators) ...
bool showNonInspectedDemandElements(const GNEDemandElement *demandElement) const
check if non inspected element has to be hidden
~GNEStop()
destructor
Definition: GNEStop.cpp:62
const int STOP_PARKING_SET
GNEStop(SumoXMLTag tag, GNEViewNet *viewNet, const SUMOVehicleParameter::Stop &stopParameter, GNEAdditional *stoppingPlace, GNEDemandElement *stopParent)
constructor used for stops over stoppingPlaces
Definition: GNEStop.cpp:44
void reset()
Resets the boundary.
Definition: Boundary.cpp:67
double startPos
The stopping position start.
void changeLaneParents(GNEShape *elementChild, const std::string &newLaneIDs)
change edge parents of a shape
bool showDemandElements() const
check if show demand elements checkbox is enabled
const int STOP_TRIGGER_SET
void deselect(GUIGlID id)
Deselects the object with the given id.
std::string getDemandElementProblem() const
return a string with the current demand element problem (by default empty, can be reimplemented in ch...
Definition: GNEStop.cpp:113
GNEEdge * getFromEdge() const
Definition: GNEStop.cpp:154
const int STOP_EXPECTED_CONTAINERS_SET
bool containerTriggered
whether an arriving container lets the vehicle continue
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:47
static const double stopsText
details for stop texts
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
Definition: GNEViewNet.cpp:417
const GNEAttributeCarrier * getDottedAC() const
get AttributeCarrier under cursor
Definition: GNEViewNet.cpp:939
const std::string & getTagStr() const
get tag assigned to this object in string format
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
Definition: GNEStop.cpp:649
element is selected
bool isInitialised() const
check if Boundary is Initialised
Definition: Boundary.cpp:217
Position getPositionInView() const
Returns position of demand element in view.
Definition: GNEStop.cpp:304
GNENet * getNet() const
get the net object
Definition: GNEViewNet.cpp:927
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
GUIGlID getGlID() const
Returns the numerical id of the object.
GNEViewNet * myViewNet
The GNEViewNet this demand element element belongs.
std::string getParentName() const
Returns the name of the parent object.
Definition: GNEStop.cpp:328
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
void setEnabledAttribute(const int enabledAttributes)
method for enabling the attribute and nothing else (used in GNEChange_EnableAttribute) ...
Definition: GNEStop.cpp:1000
const TagProperties & getTagProperty() const
get Tag Property assigned to this object
GUIVisualizationColorSettings colorSettings
color settings
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
parent of an additional element
bool showAllPersonPlans() const
check all person plans has to be show
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:136
std::string getHierarchyName() const
get Hierarchy Name (Used in AC Hierarchy)
Definition: GNEStop.cpp:778
void fixDemandElementProblem()
fix demand element problem (by default throw an exception, has to be reimplemented in children) ...
Definition: GNEStop.cpp:148
std::vector< double > shapeRotations
The rotations of the single shape parts.
bool drawForSelecting
whether drawing is performed for the purpose of selecting objects
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
GUISelectedStorage gSelected
A global holder of selected objects.
GNELane * retrieveLane(const std::string &id, bool failHard=true, bool checkVolatileChange=false)
get lane by id
Definition: GNENet.cpp:1179
std::string getGenericParametersStr() const
return generic parameters in string format
Definition: GNEStop.cpp:825
void unselectAttributeCarrier(bool changeFlag=true)
unselect attribute carrier using GUIGlobalSelection
Definition: GNEStop.cpp:481
SUMOVehicleClass getVClass() const
obtain VClass related with this demand element
Definition: GNEStop.cpp:174
SUMOTime duration
The stopping duration.
static bool isValidVehicleID(const std::string &value)
whether the given string is a valid id for a vehicle or flow
bool isDemandElementValid() const
check if current demand element is valid to be writed into XML (by default true, can be reimplemented...
Definition: GNEStop.cpp:78
bool parking
whether the vehicle is removed from the net while stopping
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
void clearParameter()
Clears the parameter map.