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-2022 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 Stops in NETEDIT
19 /****************************************************************************/
20 #include <cmath>
21 #include <netedit/GNENet.h>
22 #include <netedit/GNEUndoList.h>
23 #include <netedit/GNEViewNet.h>
24 #include <netedit/GNEViewParent.h>
28 #include <utils/gui/div/GLHelper.h>
31 
32 #include "GNEStop.h"
33 
34 // ===========================================================================
35 // member method definitions
36 // ===========================================================================
37 
39  GNEDemandElement("", net, GLO_STOP, tag, GNEPathManager::PathElement::Options::DEMAND_ELEMENT,
40 {}, {}, {}, {}, {}, {}, {}, {}) {
41  // reset default values
42  resetDefaultValues();
43 }
44 
45 
46 GNEStop::GNEStop(SumoXMLTag tag, GNENet* net, GNEDemandElement* stopParent, GNEAdditional* stoppingPlace, const SUMOVehicleParameter::Stop& stopParameter) :
47  GNEDemandElement(stopParent, net, GLO_STOP, tag, GNEPathManager::PathElement::Options::DEMAND_ELEMENT,
48 {}, {}, {}, {stoppingPlace}, {}, {}, {stopParent}, {}),
49 SUMOVehicleParameter::Stop(stopParameter) {
50  // enable parking for stops in parkingAreas
51  if (tag == SUMO_TAG_STOP_PARKINGAREA) {
52  parking = true;
54  } else {
55  // set parking flag
57  }
58 }
59 
60 
61 GNEStop::GNEStop(GNENet* net, GNEDemandElement* stopParent, GNELane* lane, const SUMOVehicleParameter::Stop& stopParameter) :
62  GNEDemandElement(stopParent, net, GLO_STOP, SUMO_TAG_STOP_LANE, GNEPathManager::PathElement::Options::DEMAND_ELEMENT,
63 {}, {}, {lane}, {}, {}, {}, {stopParent}, {}),
64 SUMOVehicleParameter::Stop(stopParameter) {
65  // set parking flag
67 }
68 
69 
70 GNEStop::GNEStop(SumoXMLTag tag, GNENet* net, GNEDemandElement* stopParent, GNEEdge* edge, const SUMOVehicleParameter::Stop& stopParameter) :
71  GNEDemandElement(stopParent, net, GLO_STOP, tag, GNEPathManager::PathElement::Options::DEMAND_ELEMENT,
72 {}, {edge}, {}, {}, {}, {}, {stopParent}, {}),
73 SUMOVehicleParameter::Stop(stopParameter) {
74  // set parking flag
76 }
77 
78 
80 
81 
85  // return move operation for additional placed over shape
86  return new GNEMoveOperation(this, getParentEdges().front()->getLanes().front(), endPos, false);
87  } else if (myTagProperty.getTag() == SUMO_TAG_STOP_LANE) {
88  // get allow change lane
89  const bool allowChangeLane = myNet->getViewNet()->getViewParent()->getMoveFrame()->getCommonModeOptions()->getAllowChangeLane();
90  // fist check if we're moving only extremes
94  // get snap radius
96  // get mouse position
97  const Position mousePosition = myNet->getViewNet()->getPositionInformation();
98  // check if we clicked over start or end position
99  if ((startPos != INVALID_DOUBLE) && (myDemandElementGeometry.getShape().front().distanceSquaredTo2D(mousePosition) <= (snap_radius * snap_radius))) {
100  // move only start position
101  return new GNEMoveOperation(this, getParentLanes().front(), startPos, getParentLanes().front()->getLaneShape().length2D() - POSITION_EPS,
103  } else if ((endPos != INVALID_DOUBLE) && (myDemandElementGeometry.getShape().back().distanceSquaredTo2D(mousePosition) <= (snap_radius * snap_radius))) {
104  // move only end position
105  return new GNEMoveOperation(this, getParentLanes().front(), 0, endPos,
107  } else {
108  return nullptr;
109  }
110  } else if ((startPos != INVALID_DOUBLE) && (endPos != INVALID_DOUBLE)) {
111  // move both start and end positions
112  return new GNEMoveOperation(this, getParentLanes().front(), startPos, endPos,
114  } else if (startPos != INVALID_DOUBLE) {
115  // move only start position
116  return new GNEMoveOperation(this, getParentLanes().front(), startPos, getParentLanes().front()->getLaneShape().length2D() - POSITION_EPS,
118  } else if (startPos != INVALID_DOUBLE) {
119  // move only end position
120  return new GNEMoveOperation(this, getParentLanes().front(), 0, endPos,
122  } else {
123  // start and end positions undefined, then nothing to move
124  return nullptr;
125  }
126  } else {
127  return nullptr;
128  }
129 }
130 
131 
132 std::string
134  return "";
135 }
136 
137 
138 void
140  device.openTag(SUMO_TAG_STOP);
141  if (getParentAdditionals().size() > 0) {
142  if (getParentAdditionals().front()->getTagProperty().getTag() == SUMO_TAG_BUS_STOP) {
144  }
145  if (getParentAdditionals().front()->getTagProperty().getTag() == SUMO_TAG_CONTAINER_STOP) {
147  }
148  if (getParentAdditionals().front()->getTagProperty().getTag() == SUMO_TAG_CHARGING_STATION) {
150  }
151  if (getParentAdditionals().front()->getTagProperty().getTag() == SUMO_TAG_PARKING_AREA) {
153  }
154  } else {
155  if (getParentLanes().size() > 0) {
156  device.writeAttr(SUMO_ATTR_LANE, getParentLanes().front()->getID());
157  } else {
158  device.writeAttr(SUMO_ATTR_EDGE, getParentEdges().front()->getID());
159  }
160  if ((parametersSet & STOP_START_SET) != 0) {
162  }
163  if ((parametersSet & STOP_END_SET) != 0) {
165  }
166  }
167  // write rest of attributes
168  write(device, true, false);
169 }
170 
171 
175  // get lane
176  const GNELane* firstLane = getFirstAllowedLane();
177  // only Stops placed over lanes can be invalid
179  return isPersonPlanValid();
180  } else if (friendlyPos) {
181  // with friendly position enabled position are "always fixed"
182  return isPersonPlanValid();
183  } else if (firstLane != nullptr) {
184  // obtain lane length
185  const double laneLength = getParentEdges().front()->getNBEdge()->getFinalLength() * firstLane->getLengthGeometryFactor();
186  // declare end pos fixed
187  const double endPosFixed = (endPos < 0) ? (endPos + laneLength) : endPos;
188  // check values
189  if ((endPosFixed <= getParentEdges().front()->getNBEdge()->getFinalLength()) && (endPosFixed > 0)) {
190  return isPersonPlanValid();
191  } else {
193  }
194  } else {
196  }
197  } else {
198  // only Stops placed over lanes can be invalid
200  return Problem::OK;
201  } else if (friendlyPos) {
202  // with friendly position enabled position are "always fixed"
203  return Problem::OK;
204  } else {
205  // obtain lane length
206  double laneLength = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength() * getParentLanes().front()->getLengthGeometryFactor();
207  // declare a copy of start and end positions
208  double startPosCopy = startPos;
209  double endPosCopy = endPos;
210  // check if position has to be fixed
211  if (startPosCopy < 0) {
212  startPosCopy += laneLength;
213  }
214  if (endPosCopy < 0) {
215  endPosCopy += laneLength;
216  }
217  // check values
218  if ((startPosCopy >= 0) && (endPosCopy <= getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength()) && ((endPosCopy - startPosCopy) >= POSITION_EPS)) {
219  return Problem::OK;
220  } else {
222  }
223  }
224  }
225 }
226 
227 
228 std::string
231  if (friendlyPos) {
232  return getPersonPlanProblem();
233  } else {
234  // obtain lane length
235  const double laneLength = getParentEdges().front()->getNBEdge()->getFinalLength();
236  // declare end pos fixed
237  const double endPosFixed = (endPos < 0) ? (endPos + laneLength) : endPos;
238  // check positions over lane
239  if (endPosFixed < 0) {
240  return (toString(SUMO_ATTR_ENDPOS) + " < 0");
241  } else if (endPosFixed > getParentEdges().front()->getNBEdge()->getFinalLength()) {
242  return (toString(SUMO_ATTR_ENDPOS) + " > lanes's length");
243  } else {
244  return getPersonPlanProblem();
245  }
246  }
247  } else {
248  // declare a copy of start and end positions
249  double startPosCopy = startPos;
250  double endPosCopy = endPos;
251  // obtain lane length
252  double laneLength = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
253  // check if position has to be fixed
254  if (startPosCopy < 0) {
255  startPosCopy += laneLength;
256  }
257  if (endPosCopy < 0) {
258  endPosCopy += laneLength;
259  }
260  // declare variables
261  std::string errorStart, separator, errorEnd;
262  // check positions over lane
263  if (startPosCopy < 0) {
264  errorStart = (toString(SUMO_ATTR_STARTPOS) + " < 0");
265  } else if (startPosCopy > getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength()) {
266  errorStart = (toString(SUMO_ATTR_STARTPOS) + " > lanes's length");
267  }
268  if (endPosCopy < 0) {
269  errorEnd = (toString(SUMO_ATTR_ENDPOS) + " < 0");
270  } else if (endPosCopy > getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength()) {
271  errorEnd = (toString(SUMO_ATTR_ENDPOS) + " > lanes's length");
272  }
273  // check separator
274  if ((errorStart.size() > 0) && (errorEnd.size() > 0)) {
275  separator = " and ";
276  }
277  return errorStart + separator + errorEnd;
278  }
279 }
280 
281 
282 void
284  //
285 }
286 
287 
290  return getParentDemandElements().front()->getVClass();
291 }
292 
293 
294 const RGBColor&
296  if (getTagProperty().isPersonPlan() || getTagProperty().isContainerPlan()) {
298  } else {
300  }
301 }
302 
303 
304 void
306  // update geometry depending of parent
307  if (getParentLanes().size() > 0) {
308  // Cut shape using as delimitators fixed start position and fixed end position
310  } else if (getParentAdditionals().size() > 0) {
311  if (getTagProperty().isPersonPlan() || getTagProperty().isContainerPlan()) {
312  // get busStop shape
313  const PositionVector& busStopShape = getParentAdditionals().front()->getAdditionalGeometry().getShape();
314  // update demand element geometry using both positions
315  myDemandElementGeometry.updateGeometry(busStopShape, busStopShape.length2D() - 0.6, busStopShape.length2D(), 0);
316  } else {
317  // use geometry of additional (busStop)
318  myDemandElementGeometry = getParentAdditionals().at(0)->getAdditionalGeometry();
319  }
320  } else if (getParentEdges().size() > 0) {
321  // get front and back lane
322  const GNELane* frontLane = getParentEdges().front()->getLanes().front();
323  const GNELane* backLane = getParentEdges().front()->getLanes().back();
324  // get lane drawing constants
325  GNELane::LaneDrawingConstants laneDrawingConstantsFront(myNet->getViewNet()->getVisualisationSettings(), frontLane);
326  GNELane::LaneDrawingConstants laneDrawingConstantBack(myNet->getViewNet()->getVisualisationSettings(), backLane);
327  // calculate front position
328  const Position frontPosition = frontLane->getLaneShape().positionAtOffset2D(getAttributeDouble(SUMO_ATTR_ARRIVALPOS), laneDrawingConstantsFront.halfWidth);
329  // calulate length between both shapes
330  const double length = backLane->getLaneShape().distance2D(frontPosition, true);
331  // calculate back position
332  const Position backPosition = frontLane->getLaneShape().positionAtOffset2D(getAttributeDouble(SUMO_ATTR_ARRIVALPOS), (length + laneDrawingConstantBack.halfWidth - laneDrawingConstantsFront.halfWidth) * -1);
333  // update demand element geometry using both positions
334  myDemandElementGeometry.updateGeometry({frontPosition, backPosition});
335  }
336  /*
337  // recompute geometry of all Demand elements related with this this stop
338  if (getParentDemandElements().front()->getTagProperty().isRoute()) {
339  getParentDemandElements().front()->updateGeometry();
340  }
341  */
342 }
343 
344 
345 Position
348  // check if is placed over a busStop
349  if (getParentAdditionals().size() > 0) {
350  return getParentAdditionals().front()->getPositionInView();
351  } else {
352  // get lane
353  const GNELane* personLane = getParentEdges().front()->getLaneByAllowedVClass(SVC_PEDESTRIAN);
354  // get position over lane shape
355  if (endPos <= 0) {
356  return personLane->getLaneShape().front();
357  } else if (endPos >= personLane->getLaneShape().length2D()) {
358  return personLane->getLaneShape().back();
359  } else {
360  return personLane->getLaneShape().positionAtOffset2D(endPos);
361  }
362  }
363  } else {
364  if (getParentLanes().size() > 0) {
365  return getParentLanes().front()->getLaneShape().positionAtOffset((startPos + endPos) / 2.0);
366  } else if (getParentAdditionals().size() > 0) {
367  return getParentAdditionals().front()->getPositionInView();
368  } else {
369  throw ProcessError("Invalid Stop parent");
370  }
371  }
372 }
373 
374 
375 std::string
377  if (getParentDemandElements().size() > 0) {
378  return getParentDemandElements().front()->getID();
379  } else if (getParentAdditionals().size() > 0) {
380  return getParentAdditionals().front()->getID();
381  } else if (getParentLanes().size() > 0) {
382  return getParentLanes().front()->getID();
383  } else {
384  throw ProcessError("Invalid parent");
385  }
386 }
387 
388 
389 double
391  return s.addSize.getExaggeration(s, this);
392 }
393 
394 
395 Boundary
397  Boundary b;
398  // Return Boundary depending if myMovingGeometryBoundary is initialised (important for move geometry)
399  if (getParentAdditionals().size() > 0) {
400  return getParentAdditionals().at(0)->getCenteringBoundary();
403  } else if (myDemandElementGeometry.getShape().size() > 0) {
405  } else {
406  b.add(getPositionInView());
407  }
408  b.grow(20);
409  return b;
410 }
411 
412 
413 void
414 GNEStop::splitEdgeGeometry(const double /*splitPosition*/, const GNENetworkElement* /*originalElement*/, const GNENetworkElement* /*newElement*/, GNEUndoList* /*undoList*/) {
415  // geometry of this element cannot be splitted
416 }
417 
418 
419 void
422  // check if stop can be drawn
423  if (draw) {
424  // Obtain exaggeration of the draw
425  const double exaggeration = getExaggeration(s);
426  // check if draw an stop for person/containers or for vehicles/routes
427  if (getTagProperty().isStopPerson() || getTagProperty().isStopContainer()) {
428  // check if draw stopPerson over busStop oder over lane
429  if (getParentAdditionals().size() > 0) {
430  drawStopPersonOverBusStop(s, exaggeration);
431  } else {
432  drawStopPersonOverEdge(s, exaggeration);
433  }
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  } else {
439  // draw vehicle over stop
440  drawVehicleStop(s, exaggeration);
441  }
442  // Draw name
443  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
444  }
445 }
446 
447 
448 void
450  // only update geometry
451  updateGeometry();
452 }
453 
454 
455 void
456 GNEStop::drawPartialGL(const GUIVisualizationSettings& /*s*/, const GNELane* /*lane*/, const GNEPathManager::Segment* /*segment*/, const double /*offsetFront*/) const {
457  // Stops don't use drawPartialGL
458 }
459 
460 
461 void
462 GNEStop::drawPartialGL(const GUIVisualizationSettings& /*s*/, const GNELane* /*fromLane*/, const GNELane* /*toLane*/, const GNEPathManager::Segment* /*segment*/, const double /*offsetFront*/) const {
463  // Stops don't use drawPartialGL
464 }
465 
466 
467 GNELane*
469  // check if stop is placed over a busStop
470  if (getParentAdditionals().size() > 0) {
471  return getParentAdditionals().front()->getParentLanes().front();
472  } else if (getParentEdges().size() > 0) {
473  return getParentEdges().front()->getLaneByAllowedVClass(SVC_PEDESTRIAN);
474  } else {
475  return getParentLanes().front();
476  }
477 }
478 
479 
480 GNELane*
482  // first and last path lane are the same
483  return getFirstPathLane();
484 }
485 
486 
487 std::string
489  switch (key) {
490  case SUMO_ATTR_DURATION:
491  if (isAttributeEnabled(key)) {
492  return time2string(duration);
493  } else {
494  return "";
495  }
496  case SUMO_ATTR_UNTIL:
497  if (isAttributeEnabled(key)) {
498  return time2string(until);
499  } else {
500  return "";
501  }
502  case SUMO_ATTR_EXTENSION:
503  if (isAttributeEnabled(key)) {
504  return time2string(extension);
505  } else {
506  return "";
507  }
508  case SUMO_ATTR_TRIGGERED:
509  if (triggered && containerTriggered) {
510  return "join";
511  } else if (triggered) {
512  return "person";
513  } else if (containerTriggered) {
514  return "container";
515  } else {
516  return "false";
517  }
518  case SUMO_ATTR_EXPECTED:
519  if (isAttributeEnabled(key)) {
520  return toString(awaitedPersons);
521  } else {
522  return "";
523  }
524  case SUMO_ATTR_PARKING:
525  return toString(parking);
526  case SUMO_ATTR_ACTTYPE:
527  return actType;
528  case SUMO_ATTR_TRIP_ID:
529  if (isAttributeEnabled(key)) {
530  return tripId;
531  } else {
532  return "";
533  }
534  // specific of Stops over stoppingPlaces
535  case SUMO_ATTR_BUS_STOP:
539  return getParentAdditionals().front()->getID();
540  // specific of stops over edges
541  case SUMO_ATTR_EDGE:
542  return getParentEdges().front()->getID();
543  // specific of stops over lanes
544  case SUMO_ATTR_LANE:
545  return getParentLanes().front()->getID();
546  case SUMO_ATTR_STARTPOS:
547  return toString(startPos);
548  case SUMO_ATTR_ENDPOS:
549  return toString(endPos);
551  return toString(friendlyPos);
553  if (posLat == INVALID_DOUBLE) {
554  return "";
555  } else {
556  return toString(posLat);
557  }
558  //
559  case GNE_ATTR_SELECTED:
561  case GNE_ATTR_PARENT:
562  return getParentDemandElements().front()->getID();
563  default:
564  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
565  }
566 }
567 
568 
569 double
571  switch (key) {
572  case SUMO_ATTR_STARTPOS:
573  if (getParentAdditionals().size() > 0) {
574  return getParentAdditionals().front()->getAttributeDouble(SUMO_ATTR_STARTPOS);
575  } else {
576  return startPos;
577  }
578  case SUMO_ATTR_ENDPOS:
579  case SUMO_ATTR_ARRIVALPOS: // for person plans
580  if (getParentAdditionals().size() > 0) {
581  return getParentAdditionals().front()->getAttributeDouble(SUMO_ATTR_ENDPOS);
582  } else {
583  return endPos;
584  }
585  default:
586  throw InvalidArgument(getTagStr() + " doesn't have a double attribute of type '" + toString(key) + "'");
587  }
588 }
589 
590 
591 Position
593  switch (key) {
594  // we use SUMO_ATTR_ARRIVALPOS instead SUMO_ATTR_ENDPOS due it's a person plan
595  case SUMO_ATTR_ARRIVALPOS: {
596  if (getParentAdditionals().size() > 0) {
597  // return first position of busStop
598  return getParentAdditionals().front()->getAdditionalGeometry().getShape().front();
599  } else {
600  // get lane shape
601  const PositionVector& laneShape = getLastPathLane()->getLaneShape();
602  // continue depending of arrival position
603  if (endPos == 0) {
604  return laneShape.front();
605  } else if ((endPos == -1) || (endPos >= laneShape.length2D())) {
606  return laneShape.back();
607  } else {
608  return laneShape.positionAtOffset2D(endPos);
609  }
610  }
611  }
612  default:
613  throw InvalidArgument(getTagStr() + " doesn't have a position attribute of type '" + toString(key) + "'");
614  }
615 }
616 
617 
618 void
619 GNEStop::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
620  if (value == getAttribute(key)) {
621  return; //avoid needless changes, later logic relies on the fact that attributes have changed
622  }
623  switch (key) {
624  case SUMO_ATTR_DURATION:
625  case SUMO_ATTR_UNTIL:
626  case SUMO_ATTR_EXTENSION:
627  case SUMO_ATTR_TRIGGERED:
628  case SUMO_ATTR_EXPECTED:
629  case SUMO_ATTR_PARKING:
630  case SUMO_ATTR_ACTTYPE:
631  case SUMO_ATTR_TRIP_ID:
632  // specific of Stops over stoppingPlaces
635  // specific of stops over lanes
636  case SUMO_ATTR_LANE:
637  case SUMO_ATTR_STARTPOS:
640  //
641  case GNE_ATTR_SELECTED:
642  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
643  break;
644  // special case for person plans
645  case SUMO_ATTR_EDGE: {
646  // get next personPlan
647  GNEDemandElement* nextPersonPlan = getParentDemandElements().at(0)->getNextChildDemandElement(this);
648  // continue depending of nextPersonPlan
649  if (nextPersonPlan) {
650  undoList->begin(myTagProperty.getGUIIcon(), "Change from attribute of next personPlan");
651  nextPersonPlan->setAttribute(SUMO_ATTR_FROM, value, undoList);
652  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
653  undoList->end();
654  } else {
655  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
656  }
657  break;
658  }
659  case SUMO_ATTR_BUS_STOP:
660  if (myTagProperty.isStopPerson()) {
661  // get next person plan
662  GNEDemandElement* nextPersonPlan = getParentDemandElements().at(0)->getNextChildDemandElement(this);
663  // continue depending of nextPersonPlan
664  if (nextPersonPlan) {
665  // obtain busStop
667  // change from attribute using edge ID
668  undoList->begin(myTagProperty.getGUIIcon(), "Change from attribute of next personPlan");
669  nextPersonPlan->setAttribute(SUMO_ATTR_FROM, busStop->getParentLanes().front()->getParentEdge()->getID(), undoList);
670  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
671  undoList->end();
672  } else {
673  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
674  }
675  } else {
676  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
677  }
678  break;
681  // get next person plan
682  GNEDemandElement* nextPersonPlan = getParentDemandElements().at(0)->getNextChildDemandElement(this);
683  // continue depending of nextPersonPlan
684  if (nextPersonPlan) {
685  // obtain containerStop
687  // change from attribute using edge ID
688  undoList->begin(myTagProperty.getGUIIcon(), "Change from attribute of next personPlan");
689  nextPersonPlan->setAttribute(SUMO_ATTR_FROM, containerStop->getParentLanes().front()->getParentEdge()->getID(), undoList);
690  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
691  undoList->end();
692  } else {
693  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
694  }
695  } else {
696  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
697  }
698  break;
699  case SUMO_ATTR_ENDPOS:
701  // get previous person plan
702  GNEDemandElement* previousPersonPlan = getParentDemandElements().at(0)->getPreviousChildDemandElement(this);
703  // check if leave presonStop connected is enabled
705  previousPersonPlan && previousPersonPlan->getTagProperty().hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
706  // change from attribute using edge ID
707  undoList->begin(myTagProperty.getGUIIcon(), "Change arrivalPos attribute of previous personPlan");
708  previousPersonPlan->setAttribute(SUMO_ATTR_ARRIVALPOS, value, undoList);
709  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
710  undoList->end();
711  } else {
712  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
713  }
714  } else {
715  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
716  }
717  break;
718  default:
719  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
720  }
721 }
722 
723 
724 bool
725 GNEStop::isValid(SumoXMLAttr key, const std::string& value) {
726  // declare string error
727  std::string error;
728  switch (key) {
729  case SUMO_ATTR_DURATION:
730  case SUMO_ATTR_UNTIL:
731  case SUMO_ATTR_EXTENSION:
732  if (canParse<SUMOTime>(value)) {
733  return parse<SUMOTime>(value) >= 0;
734  } else {
735  return false;
736  }
737  case SUMO_ATTR_TRIGGERED:
738  if (value.empty()) {
739  return false;
740  } else {
741  const std::set<std::string> expectedValues = {"true", "false", "person", "container", "join"};
742  const std::vector<std::string> triggeredValues = parse<std::vector<std::string> >(value);
743  for (const auto& triggeredValue : triggeredValues) {
744  if (expectedValues.find(triggeredValue) == expectedValues.end()) {
745  return false;
746  }
747  }
748  return true;
749  }
750  case SUMO_ATTR_EXPECTED:
751  if (value.empty()) {
752  return false;
753  } else {
754  const std::vector<std::string> expectedValues = parse<std::vector<std::string> >(value);
755  for (const auto& expectedValue : expectedValues) {
756  if (!SUMOXMLDefinitions::isValidVehicleID(expectedValue)) {
757  return false;
758  }
759  }
760  return true;
761  }
762  case SUMO_ATTR_PARKING:
763  return canParse<bool>(value);
764  case SUMO_ATTR_ACTTYPE:
765  return true;
766  case SUMO_ATTR_TRIP_ID:
768  // specific of Stops over stoppingPlaces
769  case SUMO_ATTR_BUS_STOP:
770  return (myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, value, false) != nullptr);
772  return (myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, value, false) != nullptr);
774  return (myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CHARGING_STATION, value, false) != nullptr);
776  return (myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_PARKING_AREA, value, false) != nullptr);
777  // specific of stops over edges
778  case SUMO_ATTR_EDGE:
779  if (myNet->getAttributeCarriers()->retrieveEdge(value, false) != nullptr) {
780  return true;
781  } else {
782  return false;
783  }
784  // specific of stops over lanes
785  case SUMO_ATTR_LANE:
786  if (myNet->getAttributeCarriers()->retrieveLane(value, false) != nullptr) {
787  return true;
788  } else {
789  return false;
790  }
791  case SUMO_ATTR_STARTPOS:
792  if (canParse<double>(value)) {
793  return SUMORouteHandler::isStopPosValid(parse<double>(value), endPos, getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength(), POSITION_EPS, friendlyPos);
794  } else {
795  return false;
796  }
797  case SUMO_ATTR_ENDPOS:
799  return canParse<double>(value) && fabs(parse<double>(value)) < getParentEdges().front()->getNBEdge()->getFinalLength();
800  } else if (canParse<double>(value)) {
801  return SUMORouteHandler::isStopPosValid(startPos, parse<double>(value), getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength(), POSITION_EPS, friendlyPos);
802  } else {
803  return false;
804  }
806  return canParse<bool>(value);
808  if (value.empty()) {
809  return true;
810  } else {
811  return canParse<double>(value);
812  }
813  //
814  case GNE_ATTR_SELECTED:
815  return canParse<bool>(value);
816  default:
817  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
818  }
819 }
820 
821 
822 void
824  switch (key) {
825  case SUMO_ATTR_DURATION:
826  case SUMO_ATTR_UNTIL:
827  case SUMO_ATTR_EXTENSION:
828  case SUMO_ATTR_EXPECTED:
830  undoList->add(new GNEChange_EnableAttribute(this, key, true));
831  break;
832  default:
833  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
834  }
835 }
836 
837 
838 void
840  switch (key) {
841  case SUMO_ATTR_DURATION:
842  case SUMO_ATTR_UNTIL:
843  case SUMO_ATTR_EXTENSION:
844  case SUMO_ATTR_EXPECTED:
846  undoList->add(new GNEChange_EnableAttribute(this, key, false));
847  break;
848  default:
849  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
850  }
851 }
852 
853 
854 bool
856  switch (key) {
857  // Currently stops parents cannot be edited
858  case SUMO_ATTR_BUS_STOP:
862  return false;
863  case SUMO_ATTR_DURATION:
864  return (parametersSet & STOP_DURATION_SET) != 0;
865  case SUMO_ATTR_UNTIL:
866  return (parametersSet & STOP_UNTIL_SET) != 0;
867  case SUMO_ATTR_EXTENSION:
868  return (parametersSet & STOP_EXTENSION_SET) != 0;
869  case SUMO_ATTR_EXPECTED:
870  return (parametersSet & STOP_TRIGGER_SET) != 0;
873  case SUMO_ATTR_PARKING:
875  default:
876  return true;
877  }
878 }
879 
880 
881 std::string
883  return getTagStr();
884 }
885 
886 
887 std::string
889  if (getParentAdditionals().size() > 0) {
890  return getTagProperty().getTagStr() + " stop: " + getParentAdditionals().front()->getTagStr();
891  } else if (getParentEdges().size() > 0) {
892  return getTagProperty().getTagStr() + " stop: edge";
893  } else {
894  return getTagProperty().getTagStr() + " stop: lane";
895  }
896 }
897 
898 
899 const std::map<std::string, std::string>&
901  return getParametersMap();
902 }
903 
904 double
906  double fixedPos = startPos;
907  const double len = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
908  if (fixedPos < 0) {
909  fixedPos += len;
910  }
911  return fixedPos * getParentLanes().front()->getLengthGeometryFactor();
912 }
913 
914 
915 double
917  double fixedPos = endPos;
918  const double len = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
919  if (fixedPos < 0) {
920  fixedPos += len;
921  }
922  return fixedPos * getParentLanes().front()->getLengthGeometryFactor();
923 }
924 
925 // ===========================================================================
926 // protected
927 // ===========================================================================
928 
929 const GNELane*
931  if (getParentEdges().empty()) {
932  return nullptr;
933  }
934  for (const auto& pLane : getParentEdges().front()->getLanes()) {
935  if (pLane->allowPedestrians()) {
936  return pLane;
937  }
938  }
939  return getParentEdges().front()->getLanes().front();
940 }
941 
942 
943 bool
946  return true;
947  } else if (myNet->getViewNet()->isAttributeCarrierInspected(this)) {
948  return true;
950  return true;
951  } else if (myNet->getViewNet()->getDemandViewOptions().showAllTrips()) {
952  return true;
953  } else {
954  return false;
955  }
956 }
957 
958 
959 void
960 GNEStop::drawVehicleStop(const GUIVisualizationSettings& s, const double exaggeration) const {
961  // declare value to save stop color
963  // get lane
964  const auto& stopLane = getParentLanes().size() > 0 ? getParentLanes().front() : nullptr;
965  // get lane width
966  const double width = stopLane ? stopLane->getParentEdge()->getNBEdge()->getLaneWidth(stopLane->getIndex()) * 0.5 : exaggeration * 0.8;
967  // Start drawing adding an gl identificator
969  // Add a layer matrix
971  // set Color
972  GLHelper::setColor(stopColor);
973  // Start with the drawing of the area traslating matrix to origin
975  // draw depending of details
976  if (s.drawDetail(s.detailSettings.stopsDetails, exaggeration) && stopLane) {
977  // Draw top and bot lines using shape, shapeRotations, shapeLengths and value of exaggeration
981  exaggeration * 0.1, 0, width);
985  exaggeration * 0.1, 0, width * -1);
986  // Add a detail matrix
988  // move to geometry front
989  glTranslated(myDemandElementGeometry.getShape().back().x(), myDemandElementGeometry.getShape().back().y(), 0.1);
990  // rotate
991  if (myDemandElementGeometry.getShapeRotations().size() > 0) {
992  glRotated(myDemandElementGeometry.getShapeRotations().back(), 0, 0, 1);
993  }
994  // move again
995  glTranslated(0, exaggeration * 0.5, 0);
996  // draw stop front
997  GLHelper::drawBoxLine(Position(0, 0), 0, exaggeration * 0.5, width);
998  // move to "S" position
999  glTranslated(0, 1, 0.1);
1000  // only draw text if isn't being drawn for selecting
1001  if (s.drawForRectangleSelection) {
1002  GLHelper::setColor(stopColor);
1003  GLHelper::drawBoxLine(Position(0, 1), 0, 2, 1);
1004  } else if (s.drawDetail(s.detailSettings.stopsText, exaggeration)) {
1005  // draw "S" symbol
1006  GLHelper::drawText("S", Position(), .1, 2.8, stopColor);
1007  // move to subtitle positin
1008  glTranslated(0, 1.4, 0);
1009  // draw subtitle depending of tag
1010  GLHelper::drawText("lane", Position(), .1, 1, stopColor, 180);
1011  }
1012  // pop detail matrix
1014  // draw geometry points
1015  drawGeometryPoints(s, stopColor);
1016  } else {
1017  // Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration taked from stoppingPlace parent
1019  }
1020  // pop layer matrix
1022  // Pop name
1024  // draw lock icon
1026  // check if dotted contour has to be drawn
1029  width, exaggeration, true, true);
1030  }
1031  if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
1033  width, exaggeration, true, true);
1034  }
1035 }
1036 
1037 
1038 void
1039 GNEStop::drawStopPersonOverEdge(const GUIVisualizationSettings& s, const double exaggeration) const {
1040  // Start drawing adding an gl identificator
1042  // Add layer matrix matrix
1044  // translate to front
1046  // declare stop color
1048  // declare central line color
1049  const RGBColor centralLineColor = drawUsingSelectColor() ? stopColor.changedBrightness(-32) : RGBColor::WHITE;
1050  // set base color
1051  GLHelper::setColor(stopColor);
1052  // Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration
1054  // move to front
1055  glTranslated(0, 0, .1);
1056  // set central color
1057  GLHelper::setColor(centralLineColor);
1058  // Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration
1060  // move to icon position and front
1061  glTranslated(myDemandElementGeometry.getShape().front().x(), myDemandElementGeometry.getShape().front().y(), .1);
1062  // rotate over lane
1064  // move again
1065  glTranslated(0, s.additionalSettings.vaporizerSize * exaggeration, 0);
1066  // Draw icon depending of Route Probe is selected and if isn't being drawn for selecting
1067  if (!s.drawForRectangleSelection && s.drawDetail(s.detailSettings.laneTextures, exaggeration)) {
1068  // set color
1069  glColor3d(1, 1, 1);
1070  // rotate texture
1071  glRotated(180, 0, 0, 1);
1072  // draw texture
1073  if (drawUsingSelectColor()) {
1075  } else {
1077  }
1078  } else {
1079  // rotate
1080  glRotated(22.5, 0, 0, 1);
1081  // set stop color
1082  GLHelper::setColor(stopColor);
1083  // move matrix
1084  glTranslated(0, 0, 0);
1085  // draw filled circle
1087  }
1088  // pop layer matrix
1090  // Pop name
1092  // draw lock icon
1094  // check if dotted contours has to be drawn
1097  exaggeration, 1, 1);
1098  }
1099  if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
1101  exaggeration, 1, 1);
1102  }
1103 }
1104 
1105 
1106 void
1107 GNEStop::drawStopPersonOverBusStop(const GUIVisualizationSettings& s, const double exaggeration) const {
1108  // Start drawing adding an gl identificator
1110  // Add layer matrix matrix
1112  // translate to front
1114  // declare stop color
1116  // set base color
1117  GLHelper::setColor(stopColor);
1118  // Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration
1120  // move to icon position and front
1122  // rotate over lane
1124  // move again
1125  glTranslated(s.stoppingPlaceSettings.busStopWidth * exaggeration * -2, 0, 0);
1126  // Draw icon depending of Route Probe is selected and if isn't being drawn for selecting
1127  if (!s.drawForRectangleSelection && s.drawDetail(s.detailSettings.laneTextures, exaggeration)) {
1128  // set color
1129  glColor3d(1, 1, 1);
1130  // rotate texture
1131  glRotated(-90, 0, 0, 1);
1132  // draw texture
1133  if (drawUsingSelectColor()) {
1135  } else {
1137  }
1138  } else {
1139  // rotate
1140  glRotated(22.5, 0, 0, 1);
1141  // set stop color
1142  GLHelper::setColor(stopColor);
1143  // move matrix
1144  glTranslated(0, 0, 0);
1145  // draw filled circle
1147  }
1148  // pop layer matrix
1150  // Pop name
1152  // draw lock icon
1154  // check if dotted contours has to be drawn
1157  exaggeration, 1, 1);
1158  }
1159  if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
1161  exaggeration, 1, 1);
1162  }
1163 }
1164 
1165 // ===========================================================================
1166 // private
1167 // ===========================================================================
1168 
1169 void
1170 GNEStop::setAttribute(SumoXMLAttr key, const std::string& value) {
1171  switch (key) {
1172  case SUMO_ATTR_DURATION:
1173  if (value.empty()) {
1174  toogleAttribute(key, false, -1);
1175  } else {
1176  toogleAttribute(key, true, -1);
1177  duration = string2time(value);
1178  }
1179  break;
1180  case SUMO_ATTR_UNTIL:
1181  if (value.empty()) {
1182  toogleAttribute(key, false, -1);
1183  } else {
1184  toogleAttribute(key, true, -1);
1185  until = string2time(value);
1186  }
1187  break;
1188  case SUMO_ATTR_EXTENSION:
1189  if (value.empty()) {
1190  toogleAttribute(key, false, -1);
1191  } else {
1192  toogleAttribute(key, true, -1);
1193  extension = string2time(value);
1194  }
1195  break;
1196  case SUMO_ATTR_TRIGGERED:
1197  if (value == "join") {
1198  triggered = true;
1199  containerTriggered = true;
1200  } else if ((value == "person") || (value == "true")) {
1201  triggered = true;
1202  containerTriggered = false;
1203  } else if (value == "container") {
1204  triggered = false;
1205  containerTriggered = true;
1206  } else {
1207  triggered = false;
1208  containerTriggered = false;
1209  }
1212  break;
1213  case SUMO_ATTR_EXPECTED:
1214  awaitedPersons = parse<std::set<std::string> >(value);
1216  break;
1217  case SUMO_ATTR_PARKING:
1218  parking = parse<bool>(value);
1219  toogleAttribute(key, parking, -1);
1220  break;
1221  case SUMO_ATTR_ACTTYPE:
1222  actType = value;
1223  break;
1224  case SUMO_ATTR_TRIP_ID:
1225  if (value.empty()) {
1226  toogleAttribute(key, false, -1);
1227  } else {
1228  toogleAttribute(key, true, -1);
1229  tripId = value;
1230  }
1231  break;
1232  // specific of Stops over stoppingPlaces
1233  case SUMO_ATTR_BUS_STOP:
1235  updateGeometry();
1236  break;
1239  updateGeometry();
1240  break;
1243  updateGeometry();
1244  break;
1247  updateGeometry();
1248  break;
1249  // specific of Stops over edges
1250  case SUMO_ATTR_EDGE:
1251  replaceDemandParentEdges(value);
1252  updateGeometry();
1253  edge = value;
1254  break;
1255  // specific of Stops over lanes
1256  case SUMO_ATTR_LANE:
1257  replaceDemandParentLanes(value);
1258  updateGeometry();
1259  break;
1260  case SUMO_ATTR_STARTPOS:
1261  startPos = parse<double>(value);
1262  updateGeometry();
1263  break;
1264  case SUMO_ATTR_ENDPOS:
1265  endPos = parse<double>(value);
1266  updateGeometry();
1267  break;
1269  friendlyPos = parse<bool>(value);
1270  break;
1272  if (value.empty()) {
1273  toogleAttribute(key, false, -1);
1275  } else {
1276  toogleAttribute(key, true, -1);
1277  posLat = parse<double>(value);
1278  }
1279  break;
1280  //
1281  case GNE_ATTR_SELECTED:
1282  if (parse<bool>(value)) {
1284  } else {
1286  }
1287  break;
1288  default:
1289  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1290  }
1291 }
1292 
1293 
1294 void
1295 GNEStop::toogleAttribute(SumoXMLAttr key, const bool value, const int /*previousParameters*/) {
1296  switch (key) {
1297  case SUMO_ATTR_DURATION:
1298  if (value) {
1300  } else {
1302  }
1303  break;
1304  case SUMO_ATTR_UNTIL:
1305  if (value) {
1307  } else {
1309  }
1310  break;
1311  case SUMO_ATTR_EXTENSION:
1312  if (value) {
1314  } else {
1316  }
1317  break;
1318  case SUMO_ATTR_TRIGGERED:
1319  if (value) {
1321  } else {
1323  }
1324  break;
1325  case SUMO_ATTR_EXPECTED:
1326  if (value) {
1328  } else {
1330  }
1331  break;
1332  case SUMO_ATTR_PARKING:
1333  if (value) {
1335  } else {
1337  }
1338  break;
1340  if (value) {
1342  } else {
1344  }
1345  break;
1346  default:
1347  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1348  }
1349 }
1350 
1351 
1352 void
1355  // change endPos
1356  endPos = moveResult.newFirstPos;
1357  } else {
1359  // change only start position
1360  startPos = moveResult.newFirstPos;
1361  // adjust startPos
1362  if (startPos > (getAttributeDouble(SUMO_ATTR_ENDPOS) - POSITION_EPS)) {
1363  startPos = (getAttributeDouble(SUMO_ATTR_ENDPOS) - POSITION_EPS);
1364  }
1366  // change only end position
1367  endPos = moveResult.newFirstPos;
1368  // adjust endPos
1369  if (endPos < (getAttributeDouble(SUMO_ATTR_STARTPOS) + POSITION_EPS)) {
1370  endPos = (getAttributeDouble(SUMO_ATTR_STARTPOS) + POSITION_EPS);
1371  }
1372  } else {
1373  // change both position
1374  startPos = moveResult.newFirstPos;
1375  endPos = moveResult.newSecondPos;
1376  // set lateral offset
1378  }
1379  }
1380  // update geometry
1381  updateGeometry();
1382 }
1383 
1384 
1385 void
1386 GNEStop::commitMoveShape(const GNEMoveResult& moveResult, GNEUndoList* undoList) {
1387  // begin change attribute
1388  undoList->begin(myTagProperty.getGUIIcon(), "position of " + getTagStr());
1390  // now adjust endPos position
1391  setAttribute(SUMO_ATTR_ENDPOS, toString(moveResult.newFirstPos), undoList);
1392  } else {
1393  // set attributes depending of operation type
1395  // set only start position
1396  undoList->changeAttribute(new GNEChange_Attribute(this, SUMO_ATTR_STARTPOS, toString(moveResult.newFirstPos)));
1398  // set only end position
1399  undoList->changeAttribute(new GNEChange_Attribute(this, SUMO_ATTR_ENDPOS, toString(moveResult.newFirstPos)));
1400  } else {
1401  // set both
1402  undoList->changeAttribute(new GNEChange_Attribute(this, SUMO_ATTR_STARTPOS, toString(moveResult.newFirstPos)));
1403  undoList->changeAttribute(new GNEChange_Attribute(this, SUMO_ATTR_ENDPOS, toString(moveResult.newSecondPos)));
1404  // check if lane has to be changed
1405  if (moveResult.newFirstLane) {
1406  // set new lane
1407  setAttribute(SUMO_ATTR_LANE, moveResult.newFirstLane->getID(), undoList);
1408  }
1409  }
1410  }
1411  // end change attribute
1412  undoList->end();
1413 }
1414 
1415 
1416 void
1418  // first check that we're in move mode and shift key is pressed
1422  // calculate new color
1423  const RGBColor color = baseColor.changedBrightness(-50);
1424  // push matrix
1426  // translated to front
1427  glTranslated(0, 0, 0.1);
1428  // set color
1429  GLHelper::setColor(color);
1430  // draw points
1431  if (startPos != INVALID_DOUBLE) {
1432  // push geometry point matrix
1434  glTranslated(myDemandElementGeometry.getShape().front().x(), myDemandElementGeometry.getShape().front().y(), 0.1);
1435  // draw geometry point
1437  // pop geometry point matrix
1439  }
1440  if (endPos != INVALID_DOUBLE) {
1441  // push geometry point matrix
1443  glTranslated(myDemandElementGeometry.getShape().back().x(), myDemandElementGeometry.getShape().back().y(), 0.1);
1444  // draw geometry point
1446  // pop geometry point matrix
1448  }
1449  // pop draw matrix
1451  }
1452 }
1453 
1454 /****************************************************************************/
@ DEMAND_MOVE
mode for moving demand elements
@ GLO_STOP
a stop
@ STOPPERSON_SELECTED
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.
@ SVC_PEDESTRIAN
pedestrian
const int STOP_DURATION_SET
const int STOP_POSLAT_SET
const int STOP_EXPECTED_SET
const int STOP_UNTIL_SET
const int STOP_PARKING_SET
const int STOP_START_SET
const int STOP_CONTAINER_TRIGGER_SET
const int STOP_EXTENSION_SET
const int STOP_TRIGGER_SET
const int STOP_END_SET
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ 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)
@ GNE_TAG_STOPCONTAINER_EDGE
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_STOP
stop for vehicles
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_STOP_PARKINGAREA
stop placed over a parking area (used in netedit)
@ GNE_TAG_STOPPERSON_EDGE
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_PARKING
@ SUMO_ATTR_EXTENSION
@ SUMO_ATTR_LANE
@ SUMO_ATTR_CONTAINER_STOP
@ SUMO_ATTR_PARKING_AREA
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_BUS_STOP
@ SUMO_ATTR_ENDPOS
@ GNE_ATTR_PARENT
parent of an additional element
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_ACTTYPE
@ GNE_ATTR_SELECTED
element is selected
@ SUMO_ATTR_POSITION_LAT
@ SUMO_ATTR_EXPECTED
@ SUMO_ATTR_CHARGING_STATION
@ SUMO_ATTR_TRIP_ID
@ SUMO_ATTR_FROM
@ SUMO_ATTR_FRIENDLY_POS
@ SUMO_ATTR_EXPECTED_CONTAINERS
@ SUMO_ATTR_UNTIL
@ SUMO_ATTR_TRIGGERED
@ SUMO_ATTR_DURATION
const double INVALID_DOUBLE
Definition: StdDefs.h:63
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:77
bool isInitialised() const
check if Boundary is Initialised
Definition: Boundary.cpp:215
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:507
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:431
static void pushName(unsigned int name)
push Name
Definition: GLHelper.cpp:132
static void popMatrix()
pop matrix
Definition: GLHelper.cpp:123
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:277
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:231
static void popName()
pop Name
Definition: GLHelper.cpp:141
static void pushMatrix()
push matrix
Definition: GLHelper.cpp:114
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:609
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:48
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
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
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
reference to tagProperty associated with this attribute carrier
An Element which don't belongs to GNENet but has influency in the simulation.
void replaceDemandParentEdges(const std::string &value)
replace demand parent edges
Problem isPersonPlanValid() const
check if person plan is valid
GUIGeometry myDemandElementGeometry
demand element geometry (also called "stacked geometry")
std::string getPersonPlanProblem() const
get person plan problem
void replaceDemandParentLanes(const std::string &value)
replace demand parent lanes
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
method for setting the attribute and letting the object perform demand element changes
void replaceAdditionalParent(SumoXMLTag tag, const std::string &value)
replace additional parent
Problem
enum class for demandElement problems
bool drawPersonPlan() const
const std::string & getID() const
get ID
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
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
FOX-declaration.
Definition: GNELane.h:52
const double halfWidth
Draw as a normal lane, and reduce width to make sure that a selected edge can still be seen.
Definition: GNELane.h:68
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
const PositionVector & getLaneShape() const
get elements shape
Definition: GNELane.cpp:131
double getLengthGeometryFactor() const
get length geometry factor
Definition: GNELane.cpp:1713
double myMoveElementLateralOffset
move element lateral offset (used by elements placed over lanes
bool getAllowChangeLane() const
allow change lane
bool getLeaveStopPersonsConnected() const
check if leave stopPersonConnected is enabled
DemandModeOptions * getDemandModeOptions() const
get demand mode options
CommonModeOptions * getCommonModeOptions() const
get common mode options
move operation
move result
const GNELane * newFirstLane
new first Lane
double newFirstPos
new first position
const GNEMoveOperation::OperationType operationType
move operation
double firstLaneOffset
lane offset
double newSecondPos
new second position
GNELane * retrieveLane(const std::string &id, bool hardFail=true, bool checkVolatileChange=false) const
get lane by id
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:42
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:125
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:1964
const std::string & getID() const
get ID
const RGBColor & getColor() const
get color
Definition: GNEStop.cpp:295
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
Definition: GNEStop.cpp:725
void toogleAttribute(SumoXMLAttr key, const bool value, const int previousParameters)
method for enable or disable the attribute and nothing else (used in GNEChange_EnableAttribute)
Definition: GNEStop.cpp:1295
std::string getBegin() const
get begin time of demand element
Definition: GNEStop.cpp:133
SUMOVehicleClass getVClass() const
Definition: GNEStop.cpp:289
void disableAttribute(SumoXMLAttr key, GNEUndoList *undoList)
Definition: GNEStop.cpp:839
~GNEStop()
destructor
Definition: GNEStop.cpp:79
GNEStop(SumoXMLTag tag, GNENet *net)
default constructor
Definition: GNEStop.cpp:38
GNELane * getFirstPathLane() const
get first path lane
Definition: GNEStop.cpp:468
Position getAttributePosition(SumoXMLAttr key) const
Definition: GNEStop.cpp:592
std::string getPopUpID() const
get PopPup ID (Used in AC Hierarchy)
Definition: GNEStop.cpp:882
Position getPositionInView() const
Returns position of demand element in view.
Definition: GNEStop.cpp:346
void splitEdgeGeometry(const double splitPosition, const GNENetworkElement *originalElement, const GNENetworkElement *newElement, GNEUndoList *undoList)
split geometry
Definition: GNEStop.cpp:414
bool isAttributeEnabled(SumoXMLAttr key) const
Definition: GNEStop.cpp:855
void drawPartialGL(const GUIVisualizationSettings &s, const GNELane *lane, const GNEPathManager::Segment *segment, const double offsetFront) const
Draws partial object.
Definition: GNEStop.cpp:456
GNELane * getLastPathLane() const
get last path lane
Definition: GNEStop.cpp:481
void writeDemandElement(OutputDevice &device) const
writte demand element element into a xml file
Definition: GNEStop.cpp:139
GNEMoveOperation * getMoveOperation()
get move operation
Definition: GNEStop.cpp:83
std::string getHierarchyName() const
get Hierarchy Name (Used in AC Hierarchy)
Definition: GNEStop.cpp:888
Boundary myMovingGeometryBoundary
boundary used during moving of elements (to avoid insertion in RTREE)
Definition: GNEStop.h:222
std::string getParentName() const
Returns the name of the parent object.
Definition: GNEStop.cpp:376
void drawStopPersonOverBusStop(const GUIVisualizationSettings &s, const double exaggeration) const
draw stopPerson over busStop
Definition: GNEStop.cpp:1107
void enableAttribute(SumoXMLAttr key, GNEUndoList *undoList)
Definition: GNEStop.cpp:823
double getAttributeDouble(SumoXMLAttr key) const
Definition: GNEStop.cpp:570
std::string getAttribute(SumoXMLAttr key) const
inherited from GNEAttributeCarrier
Definition: GNEStop.cpp:488
void commitMoveShape(const GNEMoveResult &moveResult, GNEUndoList *undoList)
commit move shape
Definition: GNEStop.cpp:1386
void drawGeometryPoints(const GUIVisualizationSettings &s, const RGBColor &baseColor) const
draw geometry points
Definition: GNEStop.cpp:1417
Problem isDemandElementValid() const
check if current demand element is valid to be writed into XML (by default true, can be reimplemented...
Definition: GNEStop.cpp:173
void computePathElement()
compute pathElement
Definition: GNEStop.cpp:449
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNEStop.cpp:396
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNEStop.cpp:420
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:619
void drawStopPersonOverEdge(const GUIVisualizationSettings &s, const double exaggeration) const
draw stopPerson over lane
Definition: GNEStop.cpp:1039
void setMoveShape(const GNEMoveResult &moveResult)
set move shape
Definition: GNEStop.cpp:1353
void fixDemandElementProblem()
fix demand element problem (by default throw an exception, has to be reimplemented in children)
Definition: GNEStop.cpp:283
double getExaggeration(const GUIVisualizationSettings &s) const
return exaggeration asociated with this GLObject
Definition: GNEStop.cpp:390
void drawVehicleStop(const GUIVisualizationSettings &s, const double exaggeration) const
draw vehicle stop
Definition: GNEStop.cpp:960
double getStartGeometryPositionOverLane() const
get start position over lane that is applicable to the shape
Definition: GNEStop.cpp:905
bool canDrawVehicleStop() const
check if vehicle stop can be draw
Definition: GNEStop.cpp:944
const std::map< std::string, std::string > & getACParametersMap() const
get parameters map
Definition: GNEStop.cpp:900
void updateGeometry()
update pre-computed geometry information
Definition: GNEStop.cpp:305
double getEndGeometryPositionOverLane() const
get end position over lane that is applicable to the shape
Definition: GNEStop.cpp:916
std::string getDemandElementProblem() const
return a string with the current demand element problem (by default empty, can be reimplemented in ch...
Definition: GNEStop.cpp:229
const GNELane * getFirstAllowedLane() const
get first valid lane
Definition: GNEStop.cpp:930
const std::string & getTagStr() const
get Tag vinculated with this attribute Property in String Format (used to avoid multiple calls to toS...
GUIIcon getGUIIcon() const
get GUI icon associated to this Tag
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool isStopPerson() const
return true if tag correspond to a person stop element
bool isStopContainer() const
return true if tag correspond to a container stop element
bool hasAttribute(SumoXMLAttr attr) const
check if current TagProperties owns the attribute "attr"
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
void changeAttribute(GNEChange_Attribute *change)
special method for change attributes, avoid empty changes, always execute
const GNEAttributeCarrier * getFrontAttributeCarrier() const
get front attributeCarrier
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
Definition: GNEViewNet.cpp:513
const GNEViewNetHelper::MouseButtonKeyPressed & getMouseButtonKeyPressed() const
get Key Pressed modul
Definition: GNEViewNet.cpp:543
void drawTranslateFrontAttributeCarrier(const GNEAttributeCarrier *AC, double typeOrLayer, const double extraOffset=0)
draw front attributeCarrier
GNEViewParent * getViewParent() const
get the net object
bool isAttributeCarrierInspected(const GNEAttributeCarrier *AC) const
check if attribute carrier is being inspected
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
Definition: GNEViewNet.cpp:531
GNEMoveFrame * getMoveFrame() const
get frame for move elements
static void drawDottedContourShape(const DottedContourType type, const GUIVisualizationSettings &s, const PositionVector &shape, const double width, const double exaggeration, const bool drawFirstExtrem, const bool drawLastExtrem, const double lineWidth=-1)
draw dotted contour for the given shape (used by additionals)
static void rotateOverLane(const double rot)
rotate over lane (used by Lock icons, detector logos, etc.)
const std::vector< double > & getShapeRotations() const
The rotations of the single shape parts.
static void drawGeometry(const GUIVisualizationSettings &s, const Position &mousePos, const GUIGeometry &geometry, const double width, double offset=0)
draw geometry
const PositionVector & getShape() const
The shape of the additional element.
void updateGeometry(const PositionVector &shape)
update entire geometry
Definition: GUIGeometry.cpp:58
const std::vector< double > & getShapeLengths() const
The lengths of the single shape parts.
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, bool forceShow=false) const
draw name of item
GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings
Position getPositionInformation() const
Returns the cursor's x/y position within the network.
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
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
GUIVisualizationColorSettings colorSettings
color settings
double scale
information about a lane's width (temporary, used for a single view)
GUIVisualizationStoppingPlaceSettings stoppingPlaceSettings
StoppingPlace settings.
bool drawDetail(const double detail, const double exaggeration) const
check if details can be drawn for the given GUIVisualizationDetailSettings and current scale and exxa...
GUIVisualizationAdditionalSettings additionalSettings
Additional settings.
int getCircleResolution() const
function to calculate circle resolution for all circles drawn in drawGL(...) functions
GUIVisualizationNeteditSizeSettings neteditSizeSettings
netedit size settings
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:248
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:37
double x() const
Returns the x-position.
Definition: Position.h:55
double y() const
Returns the y-position.
Definition: Position.h:60
A list of positions.
double length2D() const
Returns the length.
double distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector)
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
Position getLineCenter() const
get line center
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
static const RGBColor WHITE
Definition: RGBColor.h:192
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition: RGBColor.cpp:197
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)
std::string edge
The edge to stop at (used only in NETEDIT)
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.
double posLat
the lateral offset when stopping
int parametersSet
Information for the output which parameter were set.
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
void write(OutputDevice &dev, const bool close=true, const bool writeTagAndParents=true) const
Writes the stop as XML.
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::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
bool showAllTrips() const
check if trips has to be drawn
DemandEditMode demandEditMode
the current Demand edit mode
bool isCurrentSupermodeDemand() const
@check if current supermode is Demand
static void drawLockIcon(const GNEAttributeCarrier *AC, GUIGlObjectType type, const Position viewPosition, const double exaggeration, const double size=0.5, const double offsetx=0, const double offsety=0)
draw lock icon
bool shiftKeyPressed() const
check if SHIFT is pressed during current event
static const double vaporizerSize
Vaporizer size.
RGBColor selectedPersonPlanColor
person plan selection color (Rides, Walks, stopPersons...)
RGBColor stopPersonColor
color for stopPersons
RGBColor selectedRouteColor
route selection color (used for routes and vehicle stops)
static const double laneTextures
details for lane textures
static const double stopsText
details for stop texts
static const double stopsDetails
details for stops
static const double additionalGeometryPointRadius
moving additional geometry point radius
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
static const double busStopWidth
busStop width