Eclipse SUMO - Simulation of Urban MObility
GNEPersonStop.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-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // Representation of person stops in NETEDIT
19 /****************************************************************************/
20 #include <cmath>
21 #include <netedit/GNENet.h>
22 #include <netedit/GNEUndoList.h>
23 #include <netedit/GNEViewNet.h>
26 #include <utils/gui/div/GLHelper.h>
29 
30 #include "GNEPersonStop.h"
31 
32 
33 // ===========================================================================
34 // member method definitions
35 // ===========================================================================
36 
37 GNEPersonStop::GNEPersonStop(GNENet* net, GNEDemandElement* personParent, GNEAdditional* stoppingPlace, const SUMOVehicleParameter::Stop& stopParameter) :
39 {}, {}, {}, {stoppingPlace}, {}, {}, {personParent}, {}),
40 SUMOVehicleParameter::Stop(stopParameter) {
41 }
42 
43 
44 GNEPersonStop::GNEPersonStop(GNENet* net, GNEDemandElement* personParent, GNEEdge* edge, const SUMOVehicleParameter::Stop& stopParameter) :
46 {}, {edge}, {}, {}, {}, {}, {personParent}, {}),
47 SUMOVehicleParameter::Stop(stopParameter) {
48 }
49 
50 
52 
53 
54 std::string
56  return "";
57 }
58 
59 
60 void
62  write(device);
63 }
64 
65 
66 bool
68  // only Stops placed over lanes can be invalid
70  return true;
71  } else if (friendlyPos) {
72  // with friendly position enabled position are "always fixed"
73  return true;
74  } else {
75  // obtain lane length
76  double laneLength = getParentEdges().front()->getNBEdge()->getFinalLength() * getParentLanes().front()->getLengthGeometryFactor();
77  // declare a copy of start and end positions
78  double startPosCopy = startPos;
79  double endPosCopy = endPos;
80  // check if position has to be fixed
81  if (startPosCopy < 0) {
82  startPosCopy += laneLength;
83  }
84  if (endPosCopy < 0) {
85  endPosCopy += laneLength;
86  }
87  // check values
89  return true;
90  } else if (!(parametersSet & STOP_START_SET)) {
91  return (endPosCopy <= getParentEdges().front()->getNBEdge()->getFinalLength());
92  } else if (!(parametersSet & STOP_END_SET)) {
93  return (startPosCopy >= 0);
94  } else {
95  return ((startPosCopy >= 0) && (endPosCopy <= getParentEdges().front()->getNBEdge()->getFinalLength()) && ((endPosCopy - startPosCopy) >= POSITION_EPS));
96  }
97  }
98 }
99 
100 
101 std::string
103  // declare a copy of start and end positions
104  double startPosCopy = startPos;
105  double endPosCopy = endPos;
106  // obtain lane length
107  double laneLength = getParentEdges().front()->getNBEdge()->getFinalLength();
108  // check if position has to be fixed
109  if (startPosCopy < 0) {
110  startPosCopy += laneLength;
111  }
112  if (endPosCopy < 0) {
113  endPosCopy += laneLength;
114  }
115  // declare variables
116  std::string errorStart, separator, errorEnd;
117  // check positions over lane
118  if (startPosCopy < 0) {
119  errorStart = (toString(SUMO_ATTR_STARTPOS) + " < 0");
120  } else if (startPosCopy > getParentEdges().front()->getNBEdge()->getFinalLength()) {
121  errorStart = (toString(SUMO_ATTR_STARTPOS) + " > lanes's length");
122  }
123  if (endPosCopy < 0) {
124  errorEnd = (toString(SUMO_ATTR_ENDPOS) + " < 0");
125  } else if (endPosCopy > getParentEdges().front()->getNBEdge()->getFinalLength()) {
126  errorEnd = (toString(SUMO_ATTR_ENDPOS) + " > lanes's length");
127  }
128  // check separator
129  if ((errorStart.size() > 0) && (errorEnd.size() > 0)) {
130  separator = " and ";
131  }
132  return errorStart + separator + errorEnd;
133 }
134 
135 
136 void
138  //
139 }
140 
141 
144  return getParentDemandElements().front()->getVClass();
145 }
146 
147 
148 const RGBColor&
151 }
152 
153 
154 void
156  // only start geometry moving if stop is placed over a lane
157  if (getParentLanes().size() > 0) {
158  // always save original position over view
160  // save start and end position
163  // save current centering boundary
165  }
166 }
167 
168 
169 void
171  // check that stop is placed over a lane and endGeometryMoving was called only once
173  // reset myMovingGeometryBoundary
175  }
176 }
177 
178 
179 void
181  // only move if at leats start or end positions is defined
182  if ((getParentLanes().size() > 0) && ((parametersSet & STOP_START_SET) || (parametersSet & STOP_END_SET))) {
183  // Calculate new position using old position
185  newPosition.add(offset);
186  // filtern position using snap to active grid
187  newPosition = myNet->getViewNet()->snapToActiveGrid(newPosition);
188  double offsetLane = getParentLanes().front()->getLaneShape().nearest_offset_to_point2D(newPosition, false) - getParentLanes().front()->getLaneShape().nearest_offset_to_point2D(myStopMove.originalViewPosition, false);
189  // check if both position has to be moved
191  // calculate stoppingPlace length and lane length (After apply geometry factor)
192  double stoppingPlaceLength = fabs(parse<double>(myStopMove.secondOriginalPosition) - parse<double>(myStopMove.firstOriginalLanePosition));
193  double laneLengt = getParentEdges().front()->getNBEdge()->getFinalLength() * getParentLanes().front()->getLengthGeometryFactor();
194  // avoid changing stopping place's length
195  if ((parse<double>(myStopMove.firstOriginalLanePosition) + offsetLane) < 0) {
196  startPos = 0;
197  endPos = stoppingPlaceLength;
198  } else if ((parse<double>(myStopMove.secondOriginalPosition) + offsetLane) > laneLengt) {
199  startPos = laneLengt - stoppingPlaceLength;
200  endPos = laneLengt;
201  } else {
202  startPos = parse<double>(myStopMove.firstOriginalLanePosition) + offsetLane;
203  endPos = parse<double>(myStopMove.secondOriginalPosition) + offsetLane;
204  }
205  } else {
206  // check if start position must be moved
207  if ((parametersSet & STOP_START_SET)) {
208  startPos = parse<double>(myStopMove.firstOriginalLanePosition) + offsetLane;
209  }
210  // check if start position must be moved
211  if ((parametersSet & STOP_END_SET)) {
212  endPos = parse<double>(myStopMove.secondOriginalPosition) + offsetLane;
213  }
214  }
215  // update geometry
216  updateGeometry();
217  }
218 }
219 
220 
221 void
223  // only commit geometry moving if at leats start or end positions is defined
224  if ((getParentLanes().size() > 0) && ((parametersSet & STOP_START_SET) || (parametersSet & STOP_END_SET))) {
225  undoList->p_begin("position of " + getTagStr());
228  }
229  if (parametersSet & STOP_END_SET) {
231  }
232  undoList->p_end();
233  }
234 }
235 
236 
237 void
239  // only update Stops over lanes, because other uses the geometry of stopping place parent
240  if (getParentEdges().size() > 0) {
241  /*
242  // Cut shape using as delimitators fixed start position and fixed end position
243  myDemandElementGeometry.updateGeometry(getParentLanes().front()->getLaneShape(), getStartGeometryPositionOverLane(), getEndGeometryPositionOverLane());
244  */
245  } else if (getParentAdditionals().size() > 0) {
246  // use geometry of additional (busStop)
248  }
249  // compute previous and next person plan
250  GNEDemandElement* previousDemandElement = getParentDemandElements().front()->getPreviousChildDemandElement(this);
251  if (previousDemandElement) {
252  previousDemandElement->updateGeometry();
253  }
254  GNEDemandElement* nextDemandElement = getParentDemandElements().front()->getNextChildDemandElement(this);
255  if (nextDemandElement) {
256  nextDemandElement->updateGeometry();
257  }
258 }
259 
260 
261 void
263  // nothing to compute
264 }
265 
266 
267 void
269  // nothing to invalidate
270 }
271 
272 
273 Position
275  if (getParentLanes().size() > 0) {
276  // calculate start and end positions as absolute values
277  double start = fabs(parametersSet & STOP_START_SET ? startPos : 0);
278  double end = fabs(parametersSet & STOP_END_SET ? endPos : getParentEdges().front()->getNBEdge()->getFinalLength());
279  // obtain position in view depending if both positions are defined
281  return getParentLanes().front()->getLaneShape().positionAtOffset(getParentLanes().front()->getLaneShape().length() / 2);
282  } else if (!(parametersSet & STOP_START_SET)) {
283  return getParentLanes().front()->getLaneShape().positionAtOffset(end);
284  } else if (!(parametersSet & STOP_END_SET)) {
285  return getParentLanes().front()->getLaneShape().positionAtOffset(start);
286  } else {
287  return getParentLanes().front()->getLaneShape().positionAtOffset((start + end) / 2.0);
288  }
289  } else if (getParentDemandElements().size() > 0) {
290  return getParentDemandElements().front()->getPositionInView();
291  } else {
292  throw ProcessError("Invalid Stop parent");
293  }
294 }
295 
296 
297 std::string
299  if (getParentDemandElements().size() > 0) {
300  return getParentDemandElements().front()->getID();
301  } else if (getParentAdditionals().size() > 0) {
302  return getParentAdditionals().front()->getID();
303  } else if (getParentLanes().size() > 0) {
304  return getParentLanes().front()->getID();
305  } else {
306  throw ProcessError("Invalid parent");
307  }
308 }
309 
310 
311 Boundary
313  // Return Boundary depending if myMovingGeometryBoundary is initialised (important for move geometry)
314  if (getParentAdditionals().size() > 0) {
315  return getParentAdditionals().at(0)->getCenteringBoundary();
318  } else if (myDemandElementGeometry.getShape().size() > 0) {
320  b.grow(20);
321  return b;
322  } else {
323  return Boundary(-0.1, -0.1, 0.1, 0.1);
324  }
325 }
326 
327 
328 void
329 GNEPersonStop::splitEdgeGeometry(const double /*splitPosition*/, const GNENetworkElement* /*originalElement*/, const GNENetworkElement* /*newElement*/, GNEUndoList* /*undoList*/) {
330  // geometry of this element cannot be splitted
331 }
332 
333 
334 void
336  // declare flag to enable or disable draw person plan
337  bool drawPersonPlan = false;
338  if (myTagProperty.isPersonStop()) {
341  drawPersonPlan = true;
342  }
344  drawPersonPlan = true;
346  drawPersonPlan = true;
348  drawPersonPlan = true;
349  } else if (!myNet->getViewNet()->getInspectedAttributeCarriers().empty() && myNet->getViewNet()->getInspectedAttributeCarriers().front()->getTagProperty().isPersonPlan() &&
351  drawPersonPlan = true;
352  }
353  // check if stop can be drawn
354  if (drawPersonPlan) {
355  // Obtain exaggeration of the draw
356  const double exaggeration = s.addSize.getExaggeration(s, this);
357  // declare value to save stop color
358  RGBColor stopColor;
359  // Set color
360  if (drawUsingSelectColor()) {
362  } else {
363  stopColor = s.colorSettings.stops;
364  }
365  // Start drawing adding an gl identificator
366  glPushName(getGlID());
367  // Add a draw matrix
368  glPushMatrix();
369  // set Color
370  GLHelper::setColor(stopColor);
371  // Start with the drawing of the area traslating matrix to origin
373  // draw depending of details
374  if (s.drawDetail(s.detailSettings.stopsDetails, exaggeration) && getParentLanes().size() > 0) {
375  // Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration
377  getParentEdges().front()->getNBEdge()->getLaneWidth(getParentLanes().front()->getIndex()) * 0.5);
379  getParentEdges().front()->getNBEdge()->getLaneWidth(getParentLanes().front()->getIndex()) * -0.5);
380  // pop draw matrix
381  glPopMatrix();
382  // Add a draw matrix
383  glPushMatrix();
384  // Start with the drawing of the area traslating matrix to origin
386  // move to geometry front
387  glTranslated(myDemandElementGeometry.getShape().back().x(), myDemandElementGeometry.getShape().back().y(), 0);
388  glRotated(myDemandElementGeometry.getShapeRotations().back(), 0, 0, 1);
389  // draw front of Stop depending if it's placed over a lane or over a stoppingPlace
390  if (getParentLanes().size() > 0) {
391  // draw front of Stop
392  GLHelper::drawBoxLine(Position(0, 0), 0, exaggeration * 0.5,
393  getParentEdges().front()->getNBEdge()->getLaneWidth(getParentLanes().front()->getIndex()) * 0.5);
394  } else {
395  // draw front of Stop
396  GLHelper::drawBoxLine(Position(0, 0), 0, exaggeration * 0.5, exaggeration);
397  }
398  // move to "S" position
399  glTranslated(0, 1, 0);
400  // only draw text if isn't being drawn for selecting
402  GLHelper::setColor(stopColor);
403  GLHelper::drawBoxLine(Position(0, 1), 0, 2, 1);
404  } else if (s.drawDetail(s.detailSettings.stopsText, exaggeration)) {
405  // draw "S" symbol
406  GLHelper::drawText("S", Position(), .1, 2.8, stopColor);
407  // move to subtitle positin
408  glTranslated(0, 1.4, 0);
409  // draw subtitle depending of tag
410  GLHelper::drawText("lane", Position(), .1, 1, stopColor, 180);
411  }
412  // pop draw matrix
413  glPopMatrix();
414  // Draw name if isn't being drawn for selecting
415  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
416  // check if dotted contour has to be drawn
418  // draw dooted contour depending if it's placed over a lane or over a stoppingPlace
419  if (getParentLanes().size() > 0) {
420  // GLHelper::drawShapeDottedContourAroundShape(s, getType(), myDemandElementGeometry.getShape(),
421  // getParentEdges().front()->getNBEdge()->getLaneWidth(getParentLanes().front()->getIndex()) * 0.5);
422  } else {
423  // GLHelper::drawShapeDottedContourAroundShape(s, getType(), myDemandElementGeometry.getShape(), exaggeration);
424  }
425  }
426  } else {
427  // Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration
429  // pop draw matrix
430  glPopMatrix();
431  }
432  // Pop name
433  glPopName();
434  // draw person parent if this stop if their first person plan child
435  if ((getParentDemandElements().size() == 1) && getParentDemandElements().front()->getChildDemandElements().front() == this) {
436  getParentDemandElements().front()->drawGL(s);
437  }
438  }
439 }
440 
441 
442 void
443 GNEPersonStop::drawPartialGL(const GUIVisualizationSettings& /*s*/, const GNELane* /*lane*/, const double /*offsetFront*/) const {
444  // personStops don't use drawPartialGL
445 }
446 
447 
448 void
449 GNEPersonStop::drawPartialGL(const GUIVisualizationSettings& /*s*/, const GNELane* /*fromLane*/, const GNELane* /*toLane*/, const double /*offsetFront*/) const {
450  // personStops don't use drawPartialGL
451 }
452 
453 
454 std::string
456  switch (key) {
457  case SUMO_ATTR_ID:
458  return getParentDemandElements().front()->getID();
459  case SUMO_ATTR_DURATION:
461  return time2string(duration);
462  } else {
463  return "";
464  }
465  case SUMO_ATTR_UNTIL:
467  return time2string(until);
468  } else {
469  return "";
470  }
471  case SUMO_ATTR_EXTENSION:
473  return time2string(extension);
474  } else {
475  return "";
476  }
477  case SUMO_ATTR_INDEX:
478  if (index == STOP_INDEX_END) {
479  return "end";
480  } else if (index == STOP_INDEX_FIT) {
481  return "fit";
482  } else {
483  return toString(index);
484  }
485  case SUMO_ATTR_TRIGGERED:
486  // this is an special case
488  return "1";
489  } else {
490  return "0";
491  }
493  // this is an special case
495  return "1";
496  } else {
497  return "0";
498  }
499  case SUMO_ATTR_EXPECTED:
501  return toString(awaitedPersons);
502  } else {
503  return "";
504  }
507  return toString(awaitedContainers);
508  } else {
509  return "";
510  }
511  case SUMO_ATTR_PARKING:
512  return toString(parking);
513  case SUMO_ATTR_ACTTYPE:
514  return actType;
515  case SUMO_ATTR_TRIP_ID:
517  return tripId;
518  } else {
519  return "";
520  }
521  // specific of Stops over stoppingPlaces
522  case SUMO_ATTR_BUS_STOP:
526  return getParentAdditionals().front()->getID();
527  // specific of stops over lanes
528  case SUMO_ATTR_LANE:
529  return getParentLanes().front()->getID();
530  case SUMO_ATTR_STARTPOS:
532  return toString(startPos);
533  } else {
534  return "";
535  }
536  case SUMO_ATTR_ENDPOS:
537  if (parametersSet & STOP_END_SET) {
538  return toString(endPos);
539  } else {
540  return "";
541  }
543  return toString(friendlyPos);
544  //
545  case GNE_ATTR_SELECTED:
547  case GNE_ATTR_PARENT:
548  return getParentDemandElements().front()->getID();
549  default:
550  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
551  }
552 }
553 
554 
555 double
557  switch (key) {
558  case SUMO_ATTR_STARTPOS:
560  return startPos;
561  } else {
562  return 0;
563  }
564  case SUMO_ATTR_ENDPOS:
565  if (parametersSet & STOP_END_SET) {
566  return endPos;
567  } else {
568  return getParentEdges().front()->getNBEdge()->getFinalLength();
569  }
570  default:
571  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
572  }
573 }
574 
575 
576 void
577 GNEPersonStop::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
578  if (value == getAttribute(key)) {
579  return; //avoid needless changes, later logic relies on the fact that attributes have changed
580  }
581  switch (key) {
582  case SUMO_ATTR_DURATION:
583  case SUMO_ATTR_UNTIL:
584  case SUMO_ATTR_EXTENSION:
585  case SUMO_ATTR_INDEX:
586  case SUMO_ATTR_TRIGGERED:
588  case SUMO_ATTR_EXPECTED:
590  case SUMO_ATTR_PARKING:
591  case SUMO_ATTR_ACTTYPE:
592  case SUMO_ATTR_TRIP_ID:
593  // specific of Stops over stoppingPlaces
594  case SUMO_ATTR_BUS_STOP:
598  // specific of stops over lanes
599  case SUMO_ATTR_LANE:
600  case SUMO_ATTR_STARTPOS:
601  case SUMO_ATTR_ENDPOS:
603  //
604  case GNE_ATTR_SELECTED:
605  undoList->p_add(new GNEChange_Attribute(this, key, value));
606  break;
607  default:
608  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
609  }
610 }
611 
612 
613 bool
614 GNEPersonStop::isValid(SumoXMLAttr key, const std::string& value) {
615  // declare string error
616  std::string error;
617  switch (key) {
618  case SUMO_ATTR_DURATION:
619  case SUMO_ATTR_UNTIL:
620  case SUMO_ATTR_EXTENSION:
621  if (canParse<SUMOTime>(value)) {
622  return parse<SUMOTime>(value) >= 0;
623  } else {
624  return false;
625  }
626  case SUMO_ATTR_INDEX:
627  if ((value == "fit") || (value == "end")) {
628  return true;
629  } else if (canParse<int>(value)) {
630  return (parse<int>(value) >= 0);
631  } else {
632  return false;
633  }
634  case SUMO_ATTR_TRIGGERED:
635  return canParse<bool>(value);
637  return canParse<bool>(value);
638  case SUMO_ATTR_EXPECTED:
640  if (value.empty()) {
641  return true;
642  } else {
643  std::vector<std::string> IDs = parse<std::vector<std::string>>(value);
644  for (const auto& i : IDs) {
645  if (SUMOXMLDefinitions::isValidVehicleID(i) == false) {
646  return false;
647  }
648  }
649  return true;
650  }
651  case SUMO_ATTR_PARKING:
652  return canParse<bool>(value);
653  case SUMO_ATTR_ACTTYPE:
654  return true;
655  case SUMO_ATTR_TRIP_ID:
657  // specific of Stops over stoppingPlaces
658  case SUMO_ATTR_BUS_STOP:
659  return (myNet->retrieveAdditional(SUMO_TAG_BUS_STOP, value, false) != nullptr);
661  return (myNet->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, value, false) != nullptr);
663  return (myNet->retrieveAdditional(SUMO_TAG_CHARGING_STATION, value, false) != nullptr);
665  return (myNet->retrieveAdditional(SUMO_TAG_PARKING_AREA, value, false) != nullptr);
666  // specific of stops over lanes
667  case SUMO_ATTR_LANE:
668  if (myNet->retrieveLane(value, false) != nullptr) {
669  return true;
670  } else {
671  return false;
672  }
673  case SUMO_ATTR_STARTPOS:
674  if (value.empty()) {
675  return true;
676  } else if (canParse<double>(value)) {
677  return SUMORouteHandler::isStopPosValid(parse<double>(value), endPos, getParentEdges().front()->getNBEdge()->getFinalLength(), POSITION_EPS, friendlyPos);
678  } else {
679  return false;
680  }
681  case SUMO_ATTR_ENDPOS:
682  if (value.empty()) {
683  return true;
684  } else if (canParse<double>(value)) {
685  return SUMORouteHandler::isStopPosValid(startPos, parse<double>(value), getParentEdges().front()->getNBEdge()->getFinalLength(), POSITION_EPS, friendlyPos);
686  } else {
687  return false;
688  }
690  return canParse<bool>(value);
691  //
692  case GNE_ATTR_SELECTED:
693  return canParse<bool>(value);
694  default:
695  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
696  }
697 }
698 
699 
700 void
702  // obtain a copy of parameter sets
703  int newParametersSet = parametersSet;
704  // modify parametersSetCopy depending of attr
705  switch (key) {
706  case SUMO_ATTR_STARTPOS:
707  newParametersSet |= STOP_START_SET;
708  break;
709  case SUMO_ATTR_ENDPOS:
710  newParametersSet |= STOP_END_SET;
711  break;
712  case SUMO_ATTR_DURATION:
713  newParametersSet |= STOP_DURATION_SET;
714  break;
715  case SUMO_ATTR_UNTIL:
716  newParametersSet |= STOP_UNTIL_SET;
717  break;
718  case SUMO_ATTR_EXTENSION:
719  newParametersSet |= STOP_EXTENSION_SET;
720  break;
721  case SUMO_ATTR_EXPECTED:
722  newParametersSet |= STOP_TRIGGER_SET;
723  break;
725  newParametersSet |= STOP_CONTAINER_TRIGGER_SET;
726  break;
727  case SUMO_ATTR_PARKING:
728  newParametersSet |= STOP_PARKING_SET;
729  break;
730  default:
731  break;
732  }
733  // add GNEChange_EnableAttribute
734  undoList->add(new GNEChange_EnableAttribute(this, parametersSet, newParametersSet), true);
735  // modify parametersSetCopy depending of attr
736  switch (key) {
737  case SUMO_ATTR_STARTPOS:
738  if (parametersSet & STOP_END_SET) {
739  undoList->p_add(new GNEChange_Attribute(this, key, toString(endPos - MIN_STOP_LENGTH)));
740  } else {
741  undoList->p_add(new GNEChange_Attribute(this, key, toString(getParentEdges().front()->getNBEdge()->getFinalLength() - MIN_STOP_LENGTH)));
742  }
743  break;
744  case SUMO_ATTR_ENDPOS:
745  undoList->p_add(new GNEChange_Attribute(this, key, toString(getParentEdges().front()->getNBEdge()->getFinalLength())));
746  break;
747  case SUMO_ATTR_DURATION:
749  break;
750  case SUMO_ATTR_UNTIL:
751  case SUMO_ATTR_EXTENSION:
753  break;
754  default:
755  break;
756  }
757 }
758 
759 
760 void
762  // obtain a copy of parameter sets
763  int newParametersSet = parametersSet;
764  // modify parametersSetCopy depending of attr
765  switch (key) {
766  case SUMO_ATTR_STARTPOS:
767  newParametersSet &= ~STOP_START_SET;
768  break;
769  case SUMO_ATTR_ENDPOS:
770  newParametersSet &= ~STOP_END_SET;
771  break;
772  case SUMO_ATTR_DURATION:
773  newParametersSet &= ~STOP_DURATION_SET;
774  break;
775  case SUMO_ATTR_UNTIL:
776  newParametersSet &= ~STOP_UNTIL_SET;
777  break;
778  case SUMO_ATTR_EXTENSION:
779  newParametersSet &= ~STOP_EXTENSION_SET;
780  break;
781  case SUMO_ATTR_EXPECTED:
782  newParametersSet &= ~STOP_TRIGGER_SET;
783  break;
785  newParametersSet &= ~STOP_CONTAINER_TRIGGER_SET;
786  break;
787  case SUMO_ATTR_PARKING:
788  newParametersSet &= ~STOP_PARKING_SET;
789  break;
790  default:
791  break;
792  }
793  // add GNEChange_EnableAttribute
794  undoList->add(new GNEChange_EnableAttribute(this, parametersSet, newParametersSet), true);
795 }
796 
797 
798 bool
800  switch (key) {
801  // Currently stops parents cannot be edited
802  case SUMO_ATTR_BUS_STOP:
806  return false;
807  case SUMO_ATTR_STARTPOS:
808  return (parametersSet & STOP_START_SET) != 0;
809  case SUMO_ATTR_ENDPOS:
810  return (parametersSet & STOP_END_SET) != 0;
811  case SUMO_ATTR_DURATION:
812  return (parametersSet & STOP_DURATION_SET) != 0;
813  case SUMO_ATTR_UNTIL:
814  return (parametersSet & STOP_UNTIL_SET) != 0;
815  case SUMO_ATTR_EXTENSION:
816  return (parametersSet & STOP_EXTENSION_SET) != 0;
817  case SUMO_ATTR_EXPECTED:
818  return (parametersSet & STOP_TRIGGER_SET) != 0;
821  case SUMO_ATTR_PARKING:
822  return (parametersSet & STOP_PARKING_SET) != 0;
823  default:
824  return true;
825  }
826 }
827 
828 
829 std::string
831  return getTagStr();
832 }
833 
834 
835 std::string
837  if (getParentAdditionals().size() > 0) {
838  return "person stop: " + getParentAdditionals().front()->getTagStr();
839  } else {
840  return "person stop: lane";
841  }
842 }
843 
844 
845 const std::map<std::string, std::string>&
847  return getParametersMap();
848 }
849 
850 
851 double
853  double fixedPos = 0;
855  fixedPos = startPos;
856  } else if (parametersSet & STOP_END_SET) {
857  fixedPos = endPos - MIN_STOP_LENGTH;
858  } else {
859  fixedPos = getParentEdges().front()->getNBEdge()->getFinalLength() - MIN_STOP_LENGTH;
860  }
861  const double len = getParentEdges().front()->getNBEdge()->getFinalLength();
862  if (fixedPos < 0) {
863  fixedPos += len;
864  }
865  return fixedPos * getParentLanes().front()->getLengthGeometryFactor();
866 }
867 
868 
869 double
871  double fixedPos = 0;
872  if (parametersSet & STOP_END_SET) {
873  fixedPos = endPos;
874  } else {
875  fixedPos = getParentEdges().front()->getNBEdge()->getFinalLength();
876  }
877  const double len = getParentEdges().front()->getNBEdge()->getFinalLength();
878  if (fixedPos < 0) {
879  fixedPos += len;
880  }
881  return fixedPos * getParentLanes().front()->getLengthGeometryFactor();
882 }
883 
884 // ===========================================================================
885 // private
886 // ===========================================================================
887 
888 void
889 GNEPersonStop::setAttribute(SumoXMLAttr key, const std::string& value) {
890  switch (key) {
891  case SUMO_ATTR_DURATION:
892  if (value.empty()) {
894  } else {
895  duration = string2time(value);
897  }
898  break;
899  case SUMO_ATTR_UNTIL:
900  if (value.empty()) {
902  } else {
903  until = string2time(value);
905  }
906  break;
907  case SUMO_ATTR_EXTENSION:
908  if (value.empty()) {
910  } else {
911  extension = string2time(value);
913  }
914  break;
915  case SUMO_ATTR_INDEX:
916  if (value == "fit") {
918  } else if (value == "end") {
920  } else {
921  index = parse<int>(value);
922  }
923  break;
924  case SUMO_ATTR_TRIGGERED:
925  triggered = parse<bool>(value);
926  // this is an special case: only if SUMO_ATTR_TRIGGERED is true, it will be written in XML
927  if (triggered) {
929  } else {
931  }
932  break;
934  containerTriggered = parse<bool>(value);
935  // this is an special case: only if SUMO_ATTR_CONTAINER_TRIGGERED is true, it will be written in XML
936  if (containerTriggered) {
938  } else {
940  }
941  break;
942  case SUMO_ATTR_EXPECTED:
943  if (value.empty()) {
945  } else {
946  awaitedPersons = parse<std::set<std::string> >(value);
948  }
949  break;
951  if (value.empty()) {
953  } else {
954  awaitedContainers = parse<std::set<std::string> >(value);
956  }
957  break;
958  case SUMO_ATTR_PARKING:
959  parking = parse<bool>(value);
960  break;
961  case SUMO_ATTR_ACTTYPE:
962  actType = value;
963  break;
964  case SUMO_ATTR_TRIP_ID:
965  if (value.empty()) {
967  } else {
968  tripId = value;
970  }
971  break;
972  // specific of Stops over stoppingPlaces
973  case SUMO_ATTR_BUS_STOP:
978  updateGeometry();
979  break;
980  // specific of Stops over lanes
981  case SUMO_ATTR_LANE:
983  updateGeometry();
984  break;
985  case SUMO_ATTR_STARTPOS:
986  if (value.empty()) {
988  } else {
989  startPos = parse<double>(value);
991  }
992  updateGeometry();
993  break;
994  case SUMO_ATTR_ENDPOS:
995  if (value.empty()) {
997  } else {
998  endPos = parse<double>(value);
1000  }
1001  updateGeometry();
1002  break;
1004  friendlyPos = parse<bool>(value);
1005  break;
1006  //
1007  case GNE_ATTR_SELECTED:
1008  if (parse<bool>(value)) {
1010  } else {
1012  }
1013  break;
1014  default:
1015  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1016  }
1017 }
1018 
1019 
1020 void
1021 GNEPersonStop::setEnabledAttribute(const int enabledAttributes) {
1022  parametersSet = enabledAttributes;
1023 }
1024 
1025 
1026 /****************************************************************************/
@ GLO_PERSONSTOP
a person stop
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
const int STOP_DURATION_SET
const int STOP_INDEX_END
const int STOP_EXPECTED_SET
const int STOP_UNTIL_SET
const int STOP_PARKING_SET
const int STOP_TRIP_ID_SET
const int STOP_START_SET
const int STOP_CONTAINER_TRIGGER_SET
const int STOP_EXTENSION_SET
const int STOP_INDEX_FIT
const int STOP_TRIGGER_SET
const int STOP_END_SET
const double MIN_STOP_LENGTH
const int STOP_EXPECTED_CONTAINERS_SET
@ GNE_TAG_PERSONSTOP_BUSSTOP
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_STOP_LANE
stop placed over a lane (used in netedit)
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_PARKING_AREA
A parking area.
@ GNE_TAG_PERSONSTOP_EDGE
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_CONTAINER_TRIGGERED
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_PARKING
@ SUMO_ATTR_EXTENSION
@ SUMO_ATTR_LANE
@ SUMO_ATTR_CONTAINER_STOP
@ SUMO_ATTR_PARKING_AREA
@ SUMO_ATTR_BUS_STOP
@ SUMO_ATTR_ENDPOS
@ GNE_ATTR_PARENT
parent of an additional element
@ SUMO_ATTR_ACTTYPE
@ GNE_ATTR_SELECTED
element is selected
@ SUMO_ATTR_EXPECTED
@ SUMO_ATTR_CHARGING_STATION
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_TRIP_ID
@ SUMO_ATTR_FRIENDLY_POS
@ SUMO_ATTR_EXPECTED_CONTAINERS
@ SUMO_ATTR_ID
@ SUMO_ATTR_UNTIL
@ SUMO_ATTR_TRIGGERED
@ SUMO_ATTR_DURATION
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
bool isInitialised() const
check if Boundary is Initialised
Definition: Boundary.cpp:215
void reset()
Resets the boundary.
Definition: Boundary.cpp:65
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:299
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:446
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:181
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:135
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, const int align=0, double width=-1)
Definition: GLHelper.cpp:498
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:47
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
friend class GNEChange_EnableAttribute
friend class GNEChange_Attribute
declare friend class
const std::string & getTagStr() const
get tag assigned to this object in string format
void unselectAttributeCarrier(const bool changeFlag=true)
unselect attribute carrier using GUIGlobalSelection
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
GNENet * myNet
pointer to net
void selectAttributeCarrier(const bool changeFlag=true)
select attribute carrier using GUIGlobalSelection
const GNETagProperties & myTagProperty
the xml tag to which this attribute carrier corresponds
const std::string & getDefaultValue() const
get default value
An Element which don't belongs to GNENet but has influency in the simulation.
virtual void updateGeometry()=0
update pre-computed geometry information
void replaceDemandParentLanes(const std::string &value)
replace demand parent lanes
GNEGeometry::Geometry myDemandElementGeometry
demand element geometry (also called "stacked geometry")
void replaceAdditionalParent(SumoXMLTag tag, const std::string &value, const int parentIndex)
replace additional parent
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:49
const std::vector< double > & getShapeRotations() const
The rotations of the single shape parts.
const PositionVector & getShape() const
The shape of the additional element.
void updateGeometry(const PositionVector &shape, double startPos=-1, double endPos=-1, const Position &extraFirstPosition=Position::INVALID, const Position &extraLastPosition=Position::INVALID)
update geometry shape
Definition: GNEGeometry.cpp:81
const std::vector< double > & getShapeLengths() const
The lengths of the single shape parts.
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
const std::vector< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const std::vector< GNEEdge * > & getParentEdges() const
get parent edges
const std::vector< GNELane * > & getParentLanes() const
get parent lanes
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:45
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:40
GNELane * retrieveLane(const std::string &id, bool failHard=true, bool checkVolatileChange=false)
get lane by id
Definition: GNENet.cpp:1337
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
Definition: GNENet.cpp:2316
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2245
const std::map< std::string, std::string > & getACParametersMap() const
get parameters map
std::string getDemandElementProblem() const
return a string with the current demand element problem (by default empty, can be reimplemented in ch...
double getEndGeometryPositionOverLane() const
get end position over lane that is applicable to the shape
GNEPersonStop(GNENet *net, GNEDemandElement *personParent, GNEAdditional *stoppingPlace, const SUMOVehicleParameter::Stop &stopParameter)
constructor used for stops over busStops
void invalidatePath()
invalidate path
bool isDemandElementValid() const
check if current demand element is valid to be writed into XML (by default true, can be reimplemented...
DemandElementMove myStopMove
variable demand element move
std::string getAttribute(SumoXMLAttr key) const
inherited from GNEAttributeCarrier
const RGBColor & getColor() const
get color
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
method for setting the attribute and letting the object perform demand element changes
std::string getBegin() const
get begin time of demand element
void setEnabledAttribute(const int enabledAttributes)
method for enabling the attribute and nothing else (used in GNEChange_EnableAttribute)
void fixDemandElementProblem()
fix demand element problem (by default throw an exception, has to be reimplemented in children)
bool isAttributeEnabled(SumoXMLAttr key) const
void commitGeometryMoving(GNEUndoList *undoList)
commit geometry changes in the attributes of an element after use of moveGeometry(....
void startGeometryMoving()
~GNEPersonStop()
destructor
void writeDemandElement(OutputDevice &device) const
writte demand element element into a xml file
void endGeometryMoving()
end movement
double getAttributeDouble(SumoXMLAttr key) const
std::string getHierarchyName() const
get Hierarchy Name (Used in AC Hierarchy)
void drawPartialGL(const GUIVisualizationSettings &s, const GNELane *lane, const double offsetFront) const
Draws partial object.
double getStartGeometryPositionOverLane() const
get start position over lane that is applicable to the shape
void moveGeometry(const Position &offset)
change the position of the element geometry without saving in undoList
void splitEdgeGeometry(const double splitPosition, const GNENetworkElement *originalElement, const GNENetworkElement *newElement, GNEUndoList *undoList)
split geometry
SUMOVehicleClass getVClass() const
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
void enableAttribute(SumoXMLAttr key, GNEUndoList *undoList)
std::string getParentName() const
Returns the name of the parent object.
Position getPositionInView() const
Returns position of demand element in view.
void updateGeometry()
update pre-computed geometry information
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
void computePath()
compute path
std::string getPopUpID() const
get PopPup ID (Used in AC Hierarchy)
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
void disableAttribute(SumoXMLAttr key, GNEUndoList *undoList)
bool isPersonStop() const
return true if tag correspond to a person stop element
const GNEAttributeProperties & getAttributeProperties(SumoXMLAttr attr) const
get attribute (throw error if doesn't exist)
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
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:71
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
Definition: GNEUndoList.cpp:78
const GNEViewNetHelper::DataViewOptions & getDataViewOptions() const
get data view options
Definition: GNEViewNet.cpp:491
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
Definition: GNEViewNet.cpp:479
const std::vector< GNEAttributeCarrier * > & getInspectedAttributeCarriers() const
get inspected attribute carriers
bool isAttributeCarrierInspected(const GNEAttributeCarrier *AC) const
check if attribute carrier is being inspected
void drawTranslateFrontAttributeCarrier(const GNEAttributeCarrier *AC, GUIGlObjectType objectType, const double extraOffset=0)
draw front attributeCarrier
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
Definition: GNEViewNet.cpp:485
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
GUIGlID getGlID() const
Returns the numerical id of the object.
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
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.
GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings
Stores the information about how to visualize structures.
GUIVisualizationTextSettings addName
bool drawForRectangleSelection
whether drawing is performed for the purpose of selecting objects using a rectangle
GUIVisualizationDetailSettings detailSettings
detail settings
GUIVisualizationSizeSettings addSize
bool drawDottedContour() const
check if dotted contour can be drawn
GUIVisualizationColorSettings colorSettings
color settings
double scale
information about a lane's width (temporary, used for a single view)
bool drawDetail(const double detail, const double exaggeration) const
check if details can be drawn for the given GUIVisualizationDetailSettings and current scale and exxa...
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:124
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
static bool isStopPosValid(const double startPos, const double endPos, const double laneLength, const double minLength, const bool friendlyPos)
check if start and end position of a stop is valid
Definition of vehicle stop (position and duration)
void write(OutputDevice &dev, bool close=true) const
Writes the stop as XML.
SUMOTime extension
The maximum time extension for boarding / loading.
bool friendlyPos
enable or disable friendly position (used by NETEDIT)
double startPos
The stopping position start.
int parametersSet
Information for the output which parameter were set.
int index
at which position in the stops list
SUMOTime until
The time at which the vehicle may continue its journey.
std::string actType
act Type (only used by Persons) (used by NETEDIT)
bool triggered
whether an arriving person lets the vehicle continue
double endPos
The stopping position end.
bool parking
whether the vehicle is removed from the net while stopping
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
std::string tripId
id of the trip within a cyclical public transport route
bool containerTriggered
whether an arriving container lets the vehicle continue
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
Position originalViewPosition
value for saving first original position over lane before moving
std::string secondOriginalPosition
value for saving second original position over lane before moving
std::string firstOriginalLanePosition
value for saving first original position over lane before moving
Boundary movingGeometryBoundary
boundary used during moving of elements (to avoid insertion in RTREE)
static void drawGeometry(const GNEViewNet *viewNet, const Geometry &geometry, const double width)
draw geometry
bool showDemandElements() const
check if show demand elements checkbox is enabled
bool showAllPersonPlans() const
check all person plans has to be show
const GNEDemandElement * getLockedPerson() const
get locked person
bool showNonInspectedDemandElements(const GNEDemandElement *demandElement) const
check if non inspected element has to be hidden
bool showDemandElements() const
check if show demand elements checkbox is enabled
static const RGBColor personStops
color for personStops
RGBColor selectedPersonPlanColor
person plan selection color (Rides, Walks, personStops...)
static const RGBColor stops
color for Stops
static const double stopsText
details for stop texts
static const double stopsDetails
details for stops
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values