Eclipse SUMO - Simulation of Urban MObility
GNEPerson.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // Representation of persons in NETEDIT
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 
22 #include <cmath>
25 #include <netedit/GNENet.h>
26 #include <netedit/GNEUndoList.h>
27 #include <netedit/GNEViewNet.h>
28 #include <netedit/GNEViewParent.h>
36 #include <utils/gui/div/GLHelper.h>
41 
42 #include "GNEPerson.h"
43 #include "GNERouteHandler.h"
44 
45 
46 // ===========================================================================
47 // FOX callback mapping
48 // ===========================================================================
49 FXDEFMAP(GNEPerson::GNEPersonPopupMenu) personPopupMenuMap[] = {
51 };
52 
53 FXDEFMAP(GNEPerson::GNESelectedPersonsPopupMenu) selectedPersonsPopupMenuMap[] = {
55 };
56 
57 // Object implementation
58 FXIMPLEMENT(GNEPerson::GNEPersonPopupMenu, GUIGLObjectPopupMenu, personPopupMenuMap, ARRAYNUMBER(personPopupMenuMap))
59 FXIMPLEMENT(GNEPerson::GNESelectedPersonsPopupMenu, GUIGLObjectPopupMenu, selectedPersonsPopupMenuMap, ARRAYNUMBER(selectedPersonsPopupMenuMap))
60 
61 // ===========================================================================
62 // GNEPerson::GNEPersonPopupMenu
63 // ===========================================================================
64 
66  GUIGLObjectPopupMenu(app, parent, *person),
67  myPerson(person),
68  myTransformToPerson(nullptr),
69  myTransformToPersonFlow(nullptr) {
70  // build header
71  myPerson->buildPopupHeader(this, app);
72  // build menu command for center button and copy cursor position to clipboard
73  myPerson->buildCenterPopupEntry(this);
74  myPerson->buildPositionCopyEntry(this, false);
75  // buld menu commands for names
76  new FXMenuCommand(this, ("Copy " + myPerson->getTagStr() + " name to clipboard").c_str(), nullptr, this, MID_COPY_NAME);
77  new FXMenuCommand(this, ("Copy " + myPerson->getTagStr() + " typed name to clipboard").c_str(), nullptr, this, MID_COPY_TYPED_NAME);
78  new FXMenuSeparator(this);
79  // build selection and show parameters menu
80  myPerson->getViewNet()->buildSelectionACPopupEntry(this, myPerson);
81  myPerson->buildShowParamsPopupEntry(this);
82  // add transform functions only in demand mode
83  if (myPerson->getViewNet()->getEditModes().currentSupermode == GNE_SUPERMODE_DEMAND) {
84  // create menu pane for transform operations
85  FXMenuPane* transformOperation = new FXMenuPane(this);
86  this->insertMenuPaneChild(transformOperation);
87  new FXMenuCascade(this, "transform to", nullptr, transformOperation);
88  // Create menu comands for all transformations
89  myTransformToPerson = new FXMenuCommand(transformOperation, "Person", GUIIconSubSys::getIcon(ICON_PERSON), this, MID_GNE_PERSON_TRANSFORM);
90  myTransformToPersonFlow = new FXMenuCommand(transformOperation, "Person (embedded route)", GUIIconSubSys::getIcon(ICON_PERSONFLOW), this, MID_GNE_PERSON_TRANSFORM);
91  // check what menu command has to be disabled
92  if (myPerson->getTagProperty().getTag() == SUMO_TAG_PERSON) {
93  myTransformToPerson->disable();
94  } else if (myPerson->getTagProperty().getTag() == SUMO_TAG_PERSONFLOW) {
95  myTransformToPersonFlow->disable();
96  }
97  }
98 }
99 
100 
102 
103 
104 long
105 GNEPerson::GNEPersonPopupMenu::onCmdTransform(FXObject* obj, FXSelector, void*) {
106  if (obj == myTransformToPerson) {
108  } else if (obj == myTransformToPersonFlow) {
110  }
111  return 1;
112 }
113 
114 
115 // ===========================================================================
116 // GNEPerson::GNESelectedPersonsPopupMenu
117 // ===========================================================================
118 
119 GNEPerson::GNESelectedPersonsPopupMenu::GNESelectedPersonsPopupMenu(GNEPerson* person, const std::vector<GNEPerson*>& selectedPerson, GUIMainWindow& app, GUISUMOAbstractView& parent) :
120  GUIGLObjectPopupMenu(app, parent, *person),
121  myPersonTag(person->getTagProperty().getTag()),
122  mySelectedPersons(selectedPerson),
123  myTransformToPerson(nullptr),
124  myTransformToPersonFlow(nullptr) {
125  // build header
126  person->buildPopupHeader(this, app);
127  // build menu command for center button and copy cursor position to clipboard
128  person->buildCenterPopupEntry(this);
129  person->buildPositionCopyEntry(this, false);
130  // buld menu commands for names
131  new FXMenuCommand(this, ("Copy " + person->getTagStr() + " name to clipboard").c_str(), nullptr, this, MID_COPY_NAME);
132  new FXMenuCommand(this, ("Copy " + person->getTagStr() + " typed name to clipboard").c_str(), nullptr, this, MID_COPY_TYPED_NAME);
133  new FXMenuSeparator(this);
134  // build selection and show parameters menu
135  person->getViewNet()->buildSelectionACPopupEntry(this, person);
136  person->buildShowParamsPopupEntry(this);
137  // add transform functions only in demand mode
139  // create menu pane for transform operations
140  FXMenuPane* transformOperation = new FXMenuPane(this);
141  this->insertMenuPaneChild(transformOperation);
142  new FXMenuCascade(this, "transform to", nullptr, transformOperation);
143  // Create menu comands for all transformations
144  myTransformToPerson = new FXMenuCommand(transformOperation, "Person", GUIIconSubSys::getIcon(ICON_PERSON), this, MID_GNE_PERSON_TRANSFORM);
145  myTransformToPersonFlow = new FXMenuCommand(transformOperation, "PersonFlow", GUIIconSubSys::getIcon(ICON_PERSONFLOW), this, MID_GNE_PERSON_TRANSFORM);
146  }
147 }
148 
149 
151 
152 
153 long
155  // iterate over all selected persons
156  for (const auto& i : mySelectedPersons) {
157  if ((obj == myTransformToPerson) &&
158  (i->getTagProperty().getTag() == myPersonTag)) {
160  } else if ((obj == myTransformToPersonFlow) &&
161  (i->getTagProperty().getTag() == myPersonTag)) {
163  }
164  }
165  return 1;
166 }
167 
168 // ===========================================================================
169 // member method definitions
170 // ===========================================================================
171 
173  GNEDemandElement(personparameters.id, viewNet, (tag == SUMO_TAG_PERSONFLOW) ? GLO_PERSONFLOW : GLO_PERSON, tag,
174 {}, {}, {}, {}, {pType}, {}, {}, {}, {}, {}),
175 SUMOVehicleParameter(personparameters) {
176  // set manually vtypeID (needed for saving)
177  vtypeid = pType->getID();
178 }
179 
180 
182 
183 
184 std::string
186  // obtain depart depending if is a Person, trip or routeFlow
187  std::string departStr;
189  departStr = toString(depart);
190  } else {
191  departStr = getDepart();
192  }
193  // we need to handle depart as a tuple of 20 numbers (format: 000000...00<departTime>)
194  departStr.reserve(20 - departStr.size());
195  // add 0s at the beginning of departStr until we have 20 numbers
196  for (int i = (int)departStr.size(); i < 20; i++) {
197  departStr.insert(departStr.begin(), '0');
198  }
199  return departStr;
200 }
201 
202 
203 void
205  // obtain tag depending if tagProperty has a synonym
207  // attribute VType musn't be written if is DEFAULT_PEDTYPE_ID
209  // unset VType parameter
211  // write person attributes (VType will not be written)
212  write(device, OptionsCont::getOptions(), synonymTag);
213  // set VType parameter again
215  } else {
216  // write person attributes, including VType
217  write(device, OptionsCont::getOptions(), synonymTag, getDemandElementParents().at(0)->getID());
218  }
219  // write specific flow attributes
221  // write routeFlow values depending if it was set
224  }
227  }
230  }
233  }
236  }
237  }
238  // write demand element children associated to this person (Rides, Walks...)
239  for (const auto& i : getDemandElementChildren()) {
240  i->writeDemandElement(device);
241  }
242  // close person tag
243  device.closeTag();
244 }
245 
246 
247 bool
249  // a single person is always valid
250  return true;
251 }
252 
253 
254 std::string
256  // A single person cannot habe problem (but their children)
257  return "";
258 }
259 
260 
261 void
263  // nothing to fix
264 }
265 
266 
267 GNEEdge*
269  return getDemandElementChildren().front()->getFromEdge();
270 }
271 
272 
273 GNEEdge*
275  return getDemandElementChildren().front()->getToEdge();
276 }
277 
278 
281  return getDemandElementParents().front()->getVClass();
282 }
283 
284 
285 const RGBColor&
287  return color;
288 }
289 
290 
291 void
293  // Nothing to compute
294 }
295 
296 
297 void
299  // Persons cannot be moved
300 }
301 
302 
303 void
305  // Persons cannot be moved
306 }
307 
308 
309 void
311  // Persons cannot be moved
312 }
313 
314 
315 void
317  // Persons cannot be moved
318 }
319 
320 
321 void
323  // first check if geometry is deprecated
325  // first clear geometry
327  // only calculate new shape if there is demand element childrens
328  if (getDemandElementChildren().size() > 0) {
329  std::vector<personPlanSegment> personPlanSegments;
330  // iterate over all demand element childrens
331  for (const auto& personPlan : getDemandElementChildren()) {
332  GNEAdditional* busStop = (personPlan->getAdditionalParents().size() > 0) ? personPlan->getAdditionalParents().front() : nullptr;
333  // special case for person stops
334  if (personPlan->getTagProperty().isPersonStop()) {
335  // declare a segment
336  personPlanSegment segment(personPlan);
337  // set stop in segment
338  segment.stops.push_back(personPlan);
339  // set edge depending of stop type
340  if (personPlan->getTagProperty().getTag() == SUMO_TAG_PERSONSTOP_LANE) {
341  segment.edge = &personPlan->getLaneParents().front()->getParentEdge();
342  } else {
343  segment.edge = &personPlan->getAdditionalParents().front()->getLaneParents().front()->getParentEdge();
344  }
345  // add segment to personPlanSegments
346  personPlanSegments.push_back(segment);
347  } else if (personPlan->getTagProperty().getTag() == SUMO_TAG_WALK_ROUTE) {
348  // iterate over all demand element's route edges
349  for (const auto& j : personPlan->getDemandElementParents().at(1)->getEdgeParents()) {
350  // declare a segment
351  personPlanSegment segment(personPlan);
352  // set edge in segment
353  segment.edge = j;
354  // check if busStop can be set
355  if (busStop && (&busStop->getLaneParents().front()->getParentEdge() == segment.edge)) {
356  segment.busStops.push_back(busStop);
357  }
358  // check if arrivalPos has to be set
359  if (personPlan->getTagProperty().hasAttribute(SUMO_ATTR_ARRIVALPOS) && (personPlan->getDemandElementParents().at(1)->getEdgeParents().back() == j)) {
360  segment.arrivalPos = personPlan->getAttributeDouble(SUMO_ATTR_ARRIVALPOS);
361  }
362  // add segment to personPlanSegments
363  personPlanSegments.push_back(segment);
364  }
365  } else {
366  // iterate over all demand element's edges
367  for (const auto& j : personPlan->getEdgeParents()) {
368  // declare a segment
369  personPlanSegment segment(personPlan);
370  // set edge in segment
371  segment.edge = j;
372  // check if busStop can be set
373  if (busStop && (&busStop->getLaneParents().front()->getParentEdge() == segment.edge)) {
374  segment.busStops.push_back(busStop);
375  }
376  // check if arrivalPos has to be set
377  if (personPlan->getTagProperty().hasAttribute(SUMO_ATTR_ARRIVALPOS) && (personPlan->getEdgeParents().back() == j)) {
378  segment.arrivalPos = personPlan->getAttributeDouble(SUMO_ATTR_ARRIVALPOS);
379  }
380  // add segment to personPlanSegments
381  personPlanSegments.push_back(segment);
382  }
383  }
384  }
385  // now filter personPlanSegments
386  auto it = personPlanSegments.begin();
387  // iterate over segment plan
388  while ((it != personPlanSegments.end()) && (it != (personPlanSegments.end() - 1))) {
389  // check if this element and next element shares the same edge
390  if (it->edge == (it + 1)->edge) {
391  // copy all busStops from next segment to previous segment
392  it->busStops.insert(it->busStops.end(), (it + 1)->busStops.begin(), (it + 1)->busStops.end());
393  // copy all stops from next segment to previous segment
394  it->stops.insert(it->stops.end(), (it + 1)->stops.begin(), (it + 1)->stops.end());
395  // erase next segment (note: don't copy arrival position)
396  personPlanSegments.erase(it + 1);
397  // start again
398  it = personPlanSegments.begin();
399  } else {
400  it++;
401  }
402  }
403  // now set shape
404  for (auto personPlanSegmentsIT = personPlanSegments.begin(); personPlanSegmentsIT != personPlanSegments.end(); personPlanSegmentsIT++) {
405  // obtain first lane (special case for rides)
406  SUMOVehicleClass vClassOfPersonPlanSegmentsIT = personPlanSegmentsIT->personPlan->getTagProperty().isRide() ? SVC_PASSENGER : SVC_PEDESTRIAN;
407  GNELane* firstLane = personPlanSegmentsIT->edge->getLaneByVClass(vClassOfPersonPlanSegmentsIT);
408  // obtain next lane (special case for rides)
409  GNELane* nextLane = nullptr;
410  // check that next person plan segment isn't the last
411  if ((personPlanSegmentsIT + 1) != personPlanSegments.end()) {
412  SUMOVehicleClass vClassOfNextPersonPlanSegmentsIT = (personPlanSegmentsIT + 1)->personPlan->getTagProperty().isRide() ? SVC_PASSENGER : SVC_PEDESTRIAN;
413  nextLane = personPlanSegmentsIT->edge->getLaneByVClass(vClassOfNextPersonPlanSegmentsIT);
414  }
415  if (personPlanSegmentsIT->stops.size() > 0) {
416  // iterate over all stops
417  for (const auto& stop : personPlanSegmentsIT->stops) {
418  // obtain stop shapes
419  auto shapesStop = calculatePersonPlanConnectionStop(firstLane, stop, nextLane);
420  // add first shape
421  for (const auto& shapesStopPos : shapesStop.first) {
422  // last segment must be invisible
423  if (shapesStopPos == shapesStop.first.back()) {
424  myDemandElementSegmentGeometry.insertEdgeSegment(personPlanSegmentsIT->personPlan, personPlanSegmentsIT->edge, shapesStopPos, false, true);
425  } else {
426  myDemandElementSegmentGeometry.insertEdgeSegment(personPlanSegmentsIT->personPlan, personPlanSegmentsIT->edge, shapesStopPos, true, true);
427  }
428  }
429  // check that next person plan segment isn't the last
430  if ((personPlanSegmentsIT + 1) != personPlanSegments.end()) {
431  // add second shape
432  for (const auto& shapesStopPos : shapesStop.second) {
433  myDemandElementSegmentGeometry.insertEdgeSegment((personPlanSegmentsIT + 1)->personPlan, personPlanSegmentsIT->edge, shapesStopPos, true, true);
434  }
435  }
436  }
437  } else if (personPlanSegmentsIT->busStops.size() > 0) {
438  // iterate over all busStops
439  for (const auto& busStop : personPlanSegmentsIT->busStops) {
440  // obtain busStop shapes
441  auto shapesBusStop = calculatePersonPlanConnectionBusStop(firstLane, busStop, nextLane);
442  // add first shape
443  for (const auto& shapeBusStopPos : shapesBusStop.first) {
444  // last segment must be invisible
445  if (shapeBusStopPos == shapesBusStop.first.back()) {
446  myDemandElementSegmentGeometry.insertEdgeSegment(personPlanSegmentsIT->personPlan, personPlanSegmentsIT->edge, shapeBusStopPos, false, true);
447  } else {
448  myDemandElementSegmentGeometry.insertEdgeSegment(personPlanSegmentsIT->personPlan, personPlanSegmentsIT->edge, shapeBusStopPos, true, true);
449  }
450  }
451  // check that next person plan segment isn't the last
452  if ((personPlanSegmentsIT + 1) != personPlanSegments.end()) {
453  // add second shape
454  for (const auto& shapeBusStopPos : shapesBusStop.second) {
455  myDemandElementSegmentGeometry.insertEdgeSegment((personPlanSegmentsIT + 1)->personPlan, personPlanSegmentsIT->edge, shapeBusStopPos, true, true);
456  }
457  }
458  }
459  } else if (personPlanSegmentsIT->arrivalPos != -1) {
460  // obtain busStop shapes
461  auto shapeArrival = calculatePersonPlanConnectionArrivalPos(firstLane, personPlanSegmentsIT->arrivalPos, nextLane);
462  // add first shape
463  for (const auto& shapeArrivalPos : shapeArrival.first) {
464  // special case for the last segment
465  if ((shapeArrivalPos == shapeArrival.first.back()) && (shapeArrival.first.size() > 0) && (shapeArrival.second.size() > 0)) {
466  myDemandElementSegmentGeometry.insertEdgeSegment((personPlanSegmentsIT + 1)->personPlan, personPlanSegmentsIT->edge, shapeArrivalPos, true, true);
467  } else {
468  myDemandElementSegmentGeometry.insertEdgeSegment(personPlanSegmentsIT->personPlan, personPlanSegmentsIT->edge, shapeArrivalPos, true, true);
469  }
470  }
471  // add second shape
472  for (const auto& shapeArrivalPos : shapeArrival.second) {
473  myDemandElementSegmentGeometry.insertEdgeSegment((personPlanSegmentsIT + 1)->personPlan, personPlanSegmentsIT->edge, shapeArrivalPos, true, true);
474  }
475  } else {
476  // obtain lane (special case due rides)
477  GNELane* lane = personPlanSegmentsIT->edge->getLaneByVClass(vClassOfPersonPlanSegmentsIT);
478  // add lane shape over personPlan shape
479  for (int i = 0; i < (int)lane->getGeometry().shape.size(); i++) {
480  // insert segment
481  if (i < (int)lane->getGeometry().shape.size() - 1) {
482  myDemandElementSegmentGeometry.insertEdgeLengthRotSegment(personPlanSegmentsIT->personPlan, personPlanSegmentsIT->edge,
483  lane->getGeometry().shape[i],
484  lane->getGeometry().shapeLengths[i],
485  lane->getGeometry().shapeRotations[i],
486  true, true);
487  } else {
488  myDemandElementSegmentGeometry.insertEdgeSegment(personPlanSegmentsIT->personPlan, personPlanSegmentsIT->edge,
489  lane->getGeometry().shape[i], true, true);
490  }
491  }
492  }
493  // if this isn't the last person plan segment, calculate a smooth shape connection
494  if ((personPlanSegmentsIT + 1) != personPlanSegments.end()) {
495  calculateSmoothPersonPlanConnection((personPlanSegmentsIT + 1)->personPlan, personPlanSegmentsIT->edge, (personPlanSegmentsIT + 1)->edge);
496  }
497  }
498  // calculate entire shape, rotations and lengths
500  }
501  // mark demand element geometry as non-deprecated
503  }
504 }
505 
506 
507 Position
509  // Position in view depend of first child element
510  if (getDemandElementChildren().size() > 0) {
511  if (getDemandElementChildren().at(0)->getTagProperty().isPersonStop()) {
512  return getDemandElementChildren().at(0)->getDemandElementGeometry().shape.getLineCenter();
513  } else {
514  // obtain lane (special case for rides)
515  SUMOVehicleClass vClassEdgeFrom = getDemandElementChildren().front()->getTagProperty().isRide() ? SVC_PASSENGER : SVC_PEDESTRIAN;
516  GNELane* lane = getDemandElementChildren().at(0)->getEdgeParents().at(0)->getLaneByVClass(vClassEdgeFrom);
517  // return position in view depending of lane
518  if (lane->getGeometry().shape.length() < 2.5) {
519  return lane->getGeometry().shape.front();
520  } else {
521  Position A = lane->getGeometry().shape.positionAtOffset(2.5);
522  Position B = lane->getGeometry().shape.positionAtOffset(2.5);
523  // return Middle point
524  return Position((A.x() + B.x()) / 2, (A.y() + B.y()) / 2);
525  }
526  }
527  } else {
528  return Position(0, 0);
529  }
530 }
531 
532 
535  // return a GNEPersonPopupMenu
536  return new GNEPersonPopupMenu(this, app, parent);
537 }
538 
539 
540 std::string
542  return myViewNet->getNet()->getMicrosimID();
543 }
544 
545 
546 Boundary
548  Boundary personBoundary;
549  if (getDemandElementChildren().size() > 0) {
550  personBoundary.add(getDemandElementChildren().at(1)->getEdgeParents().at(0)->getLanes().front()->getGeometry().shape.front());
551  } else {
552  personBoundary = Boundary(-0.1, -0.1, 0.1, 0.1);
553  }
554  personBoundary.grow(20);
555  return personBoundary;
556 }
557 
558 
559 void
561  // only drawn in super mode demand
563  // obtain exaggeration (and add the special personExaggeration)
564  const double exaggeration = s.personSize.getExaggeration(s, this, 80) + s.detailSettings.personExaggeration;
565  // obtain width and length
566  const double length = getDemandElementParents().at(0)->getAttributeDouble(SUMO_ATTR_LENGTH);
567  const double width = getDemandElementParents().at(0)->getAttributeDouble(SUMO_ATTR_WIDTH);
568  const std::string file = getDemandElementParents().at(0)->getAttribute(SUMO_ATTR_IMGFILE);
569  // push GL ID
570  glPushName(getGlID());
571  // push draw matrix
572  glPushMatrix();
573  Position personPosition;
574  // obtain position depending of first PersonPlan child
575  if (getDemandElementChildren().front()->getTagProperty().isPersonStop()) {
576  // obtain position of stop center
577  personPosition = getDemandElementChildren().front()->getPositionInView();
578  } else if (getDemandElementChildren().front()->getTagProperty().getTag() == SUMO_TAG_WALK_ROUTE) {
579  // obtain position of first route's edge
580  personPosition = getDemandElementChildren().front()->getDemandElementParents().at(1)->getEdgeParents().front()->getLanes().front()->getGeometry().shape.front();
581  } else {
582  // obtain position of first edge
583  personPosition = getDemandElementChildren().front()->getEdgeParents().front()->getLanes().front()->getGeometry().shape.front();
584  }
585  glTranslated(personPosition.x(), personPosition.y(), getType());
586  glRotated(90, 0, 0, 1);
587  // set person color
588  setColor(s);
589  // set scale
590  glScaled(exaggeration, exaggeration, 1);
591  // draw person depending of detail level
592  if (s.drawDetail(s.detailSettings.personShapes, exaggeration)) {
593  GUIBasePersonHelper::drawAction_drawAsImage(0, length, width, file, SVS_PEDESTRIAN, exaggeration);
594  } else if (s.drawDetail(s.detailSettings.personCircles, exaggeration)) {
596  } else if (s.drawDetail(s.detailSettings.personTriangles, exaggeration)) {
598  }
599  // pop matrix
600  glPopMatrix();
601  drawName(personPosition, s.scale, s.personName, s.angle);
602  if (s.personValue.show) {
603  Position personValuePosition = personPosition + Position(0, 0.6 * s.personName.scaledSize(s.scale));
604  const double value = getColorValue(s, s.personColorer.getActive());
605  GLHelper::drawTextSettings(s.personValue, toString(value), personValuePosition, s.scale, s.angle, GLO_MAX - getType());
606  }
607  // check if dotted contour has to be drawn
608  if (myViewNet->getDottedAC() == this) {
609  GLHelper::drawShapeDottedContourRectangle(s, getType(), personPosition, exaggeration, exaggeration);
610  }
611  // pop name
612  glPopName();
613  }
614 }
615 
616 
617 void
619  if (!myViewNet) {
620  throw ProcessError("ViewNet cannot be nullptr");
621  } else {
623  // add object of list into selected objects
625  if (changeFlag) {
626  mySelected = true;
627  }
628  }
629 }
630 
631 
632 void
634  if (!myViewNet) {
635  throw ProcessError("ViewNet cannot be nullptr");
636  } else {
638  // remove object of list of selected objects
640  if (changeFlag) {
641  mySelected = false;
642 
643  }
644  }
645 }
646 
647 
648 std::string
650  // declare string error
651  std::string error;
652  switch (key) {
653  case SUMO_ATTR_ID:
654  return getDemandElementID();
655  case SUMO_ATTR_TYPE:
656  return getDemandElementParents().at(0)->getID();
657  case SUMO_ATTR_COLOR:
658  if (wasSet(VEHPARS_COLOR_SET)) {
659  return toString(color);
660  } else {
662  }
663  case SUMO_ATTR_DEPARTPOS:
665  return getDepartPos();
666  } else {
668  }
669  // Specific of persons
670  case SUMO_ATTR_DEPART:
671  return toString(depart);
672  // Specific of personFlows
673  case SUMO_ATTR_BEGIN:
674  return time2string(depart);
675  case SUMO_ATTR_END:
676  return time2string(repetitionEnd);
678  return toString(3600 / STEPS2TIME(repetitionOffset));
679  case SUMO_ATTR_PERIOD:
681  case SUMO_ATTR_PROB:
683  case SUMO_ATTR_NUMBER:
684  return toString(repetitionNumber);
685  //
686  case GNE_ATTR_SELECTED:
688  case GNE_ATTR_GENERIC:
689  return getGenericParametersStr();
690  default:
691  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
692  }
693 }
694 
695 
696 double
698  return 0;
699 }
700 
701 
702 void
703 GNEPerson::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
704  if (value == getAttribute(key)) {
705  return; //avoid needless changes, later logic relies on the fact that attributes have changed
706  }
707  switch (key) {
708  case SUMO_ATTR_ID:
709  case SUMO_ATTR_TYPE:
710  case SUMO_ATTR_COLOR:
711  case SUMO_ATTR_DEPARTPOS:
712  // Specific of persons
713  case SUMO_ATTR_DEPART:
714  // Specific of personFlows
715  case SUMO_ATTR_BEGIN:
716  case SUMO_ATTR_END:
717  case SUMO_ATTR_NUMBER:
719  case SUMO_ATTR_PERIOD:
720  case SUMO_ATTR_PROB:
721  //
722  case GNE_ATTR_GENERIC:
723  case GNE_ATTR_SELECTED:
724  undoList->p_add(new GNEChange_Attribute(this, myViewNet->getNet(), key, value));
725  break;
726  default:
727  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
728  }
729 }
730 
731 
732 bool
733 GNEPerson::isValid(SumoXMLAttr key, const std::string& value) {
734  // declare string error
735  std::string error;
736  switch (key) {
737  case SUMO_ATTR_ID:
738  // Persons and personflows share namespace
740  (myViewNet->getNet()->retrieveDemandElement(SUMO_TAG_PERSON, value, false) == nullptr) &&
741  (myViewNet->getNet()->retrieveDemandElement(SUMO_TAG_PERSONFLOW, value, false) == nullptr)) {
742  return true;
743  } else {
744  return false;
745  }
746  case SUMO_ATTR_TYPE:
747  return SUMOXMLDefinitions::isValidTypeID(value) && (myViewNet->getNet()->retrieveDemandElement(SUMO_TAG_VTYPE, value, false) != nullptr);
748  case SUMO_ATTR_COLOR:
749  return canParse<RGBColor>(value);
750  case SUMO_ATTR_DEPARTPOS: {
751  double dummyDepartPos;
752  DepartPosDefinition dummyDepartPosProcedure;
753  parseDepartPos(value, toString(SUMO_TAG_VEHICLE), id, dummyDepartPos, dummyDepartPosProcedure, error);
754  // if error is empty, given value is valid
755  return error.empty();
756  }
757  // Specific of persons
758  case SUMO_ATTR_DEPART: {
759  if (canParse<double>(value)) {
760  return (parse<double>(value) >= 0);
761  } else {
762  return false;
763  }
764  }
765  // Specific of personflows
766  case SUMO_ATTR_BEGIN:
767  if (canParse<double>(value)) {
768  return (parse<double>(value) >= 0);
769  } else {
770  return false;
771  }
772  case SUMO_ATTR_END:
773  if (value.empty()) {
774  return true;
775  } else if (canParse<double>(value)) {
776  return (parse<double>(value) >= 0);
777  } else {
778  return false;
779  }
781  if (value.empty()) {
782  return true;
783  } else if (canParse<double>(value)) {
784  return (parse<double>(value) > 0);
785  } else {
786  return false;
787  }
788  case SUMO_ATTR_PERIOD:
789  if (value.empty()) {
790  return true;
791  } else if (canParse<double>(value)) {
792  return (parse<double>(value) > 0);
793  } else {
794  return false;
795  }
796  case SUMO_ATTR_PROB:
797  if (value.empty()) {
798  return true;
799  } else if (canParse<double>(value)) {
800  return (parse<double>(value) >= 0);
801  } else {
802  return false;
803  }
804  case SUMO_ATTR_NUMBER:
805  if (canParse<int>(value)) {
806  return (parse<int>(value) >= 0);
807  } else {
808  return false;
809  }
810  //
811  case GNE_ATTR_SELECTED:
812  return canParse<bool>(value);
813  case GNE_ATTR_GENERIC:
814  return isGenericParametersValid(value);
815  default:
816  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
817  }
818 }
819 
820 
821 void
823  // obtain a copy of parameter sets
824  int newParametersSet = parametersSet;
825  // modify parametersSetCopy depending of attr
826  switch (key) {
827  case SUMO_ATTR_END: {
828  // give more priority to end
829  newParametersSet = VEHPARS_END_SET | VEHPARS_NUMBER_SET;
830  break;
831  }
832  case SUMO_ATTR_NUMBER:
833  newParametersSet ^= VEHPARS_END_SET;
834  newParametersSet |= VEHPARS_NUMBER_SET;
835  break;
836  case SUMO_ATTR_VEHSPERHOUR: {
837  // give more priority to end
838  if ((newParametersSet & VEHPARS_END_SET) && (newParametersSet & VEHPARS_NUMBER_SET)) {
839  newParametersSet = VEHPARS_END_SET;
840  } else if (newParametersSet & VEHPARS_END_SET) {
841  newParametersSet = VEHPARS_END_SET;
842  } else if (newParametersSet & VEHPARS_NUMBER_SET) {
843  newParametersSet = VEHPARS_NUMBER_SET;
844  }
845  // set VehsPerHour
846  newParametersSet |= VEHPARS_VPH_SET;
847  break;
848  }
849  case SUMO_ATTR_PERIOD: {
850  // give more priority to end
851  if ((newParametersSet & VEHPARS_END_SET) && (newParametersSet & VEHPARS_NUMBER_SET)) {
852  newParametersSet = VEHPARS_END_SET;
853  } else if (newParametersSet & VEHPARS_END_SET) {
854  newParametersSet = VEHPARS_END_SET;
855  } else if (newParametersSet & VEHPARS_NUMBER_SET) {
856  newParametersSet = VEHPARS_NUMBER_SET;
857  }
858  // set period
859  newParametersSet |= VEHPARS_PERIOD_SET;
860  break;
861  }
862  case SUMO_ATTR_PROB: {
863  // give more priority to end
864  if ((newParametersSet & VEHPARS_END_SET) && (newParametersSet & VEHPARS_NUMBER_SET)) {
865  newParametersSet = VEHPARS_END_SET;
866  } else if (newParametersSet & VEHPARS_END_SET) {
867  newParametersSet = VEHPARS_END_SET;
868  } else if (newParametersSet & VEHPARS_NUMBER_SET) {
869  newParametersSet = VEHPARS_NUMBER_SET;
870  }
871  // set probability
872  newParametersSet |= VEHPARS_PROB_SET;
873  break;
874  }
875  default:
876  break;
877  }
878  // add GNEChange_EnableAttribute
879  undoList->add(new GNEChange_EnableAttribute(this, myViewNet->getNet(), parametersSet, newParametersSet), true);
880 }
881 
882 
883 bool
885  switch (key) {
886  case SUMO_ATTR_END:
887  return (parametersSet & VEHPARS_END_SET) != 0;
888  case SUMO_ATTR_NUMBER:
889  return (parametersSet & VEHPARS_NUMBER_SET) != 0;
891  return (parametersSet & VEHPARS_VPH_SET) != 0;
892  case SUMO_ATTR_PERIOD:
893  return (parametersSet & VEHPARS_PERIOD_SET) != 0;
894  case SUMO_ATTR_PROB:
895  return (parametersSet & VEHPARS_PROB_SET) != 0;
896  default:
897  return true;
898  };
899 }
900 
901 
902 std::string
904  return getTagStr();
905 }
906 
907 
908 std::string
910  // special case for Trips and flow
912  // check if we're inspecting a Edge
913  if (myViewNet->getNet()->getViewNet()->getDottedAC() &&
915  // check if edge correspond to a "from", "to" or "via" edge
916  if (getEdgeParents().front() == myViewNet->getNet()->getViewNet()->getDottedAC()) {
917  return getTagStr() + ": " + getAttribute(SUMO_ATTR_ID) + " (from)";
918  } else if (getEdgeParents().front() == myViewNet->getNet()->getViewNet()->getDottedAC()) {
919  return getTagStr() + ": " + getAttribute(SUMO_ATTR_ID) + " (to)";
920  } else {
921  // iterate over via
922  for (const auto& i : via) {
923  if (i == myViewNet->getNet()->getViewNet()->getDottedAC()->getID()) {
924  return getTagStr() + ": " + getAttribute(SUMO_ATTR_ID) + " (via)";
925  }
926  }
927  }
928  }
929  }
930  return getTagStr() + ": " + getAttribute(SUMO_ATTR_ID);
931 }
932 
933 // ===========================================================================
934 // protected
935 // ===========================================================================
936 
937 void
939  const GUIColorer& c = s.personColorer;
940  if (!setFunctionalColor(c.getActive())) {
942  }
943 }
944 
945 
946 bool
947 GNEPerson::setFunctionalColor(int /* activeScheme */) const {
948  /*
949  switch (activeScheme) {
950  case 0: {
951  if (getParameter().wasSet(VEHPARS_COLOR_SET)) {
952  GLHelper::setColor(getParameter().color);
953  return true;
954  }
955  if (getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
956  GLHelper::setColor(getVehicleType().getColor());
957  return true;
958  }
959  return false;
960  }
961  case 2: {
962  if (getParameter().wasSet(VEHPARS_COLOR_SET)) {
963  GLHelper::setColor(getParameter().color);
964  return true;
965  }
966  return false;
967  }
968  case 3: {
969  if (getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
970  GLHelper::setColor(getVehicleType().getColor());
971  return true;
972  }
973  return false;
974  }
975  case 8: { // color by angle
976  double hue = GeomHelper::naviDegree(getAngle());
977  GLHelper::setColor(RGBColor::fromHSV(hue, 1., 1.));
978  return true;
979  }
980  case 9: { // color randomly (by pointer)
981  const double hue = (long)this % 360; // [0-360]
982  const double sat = (((long)this / 360) % 67) / 100.0 + 0.33; // [0.33-1]
983  GLHelper::setColor(RGBColor::fromHSV(hue, sat, 1.));
984  return true;
985  }
986  default:
987  return false;
988  }
989  */
990  return false;
991 }
992 
993 
994 std::string
996  std::string result;
997  // Generate an string using the following structure: "key1=value1|key2=value2|...
998  for (auto i : getParametersMap()) {
999  result += i.first + "=" + i.second + "|";
1000  }
1001  // remove the last "|"
1002  if (!result.empty()) {
1003  result.pop_back();
1004  }
1005  return result;
1006 }
1007 
1008 
1009 std::vector<std::pair<std::string, std::string> >
1011  std::vector<std::pair<std::string, std::string> > result;
1012  // iterate over parameters map and fill result
1013  for (auto i : getParametersMap()) {
1014  result.push_back(std::make_pair(i.first, i.second));
1015  }
1016  return result;
1017 }
1018 
1019 
1020 void
1021 GNEPerson::setGenericParametersStr(const std::string& value) {
1022  // clear parameters
1023  clearParameter();
1024  // separate value in a vector of string using | as separator
1025  std::vector<std::string> parsedValues;
1026  StringTokenizer stValues(value, "|", true);
1027  while (stValues.hasNext()) {
1028  parsedValues.push_back(stValues.next());
1029  }
1030  // check that parsed values (A=B)can be parsed in generic parameters
1031  for (auto i : parsedValues) {
1032  std::vector<std::string> parsedParameters;
1033  StringTokenizer stParam(i, "=", true);
1034  while (stParam.hasNext()) {
1035  parsedParameters.push_back(stParam.next());
1036  }
1037  // Check that parsed parameters are exactly two and contains valid chracters
1038  if (parsedParameters.size() == 2 && SUMOXMLDefinitions::isValidGenericParameterKey(parsedParameters.front()) && SUMOXMLDefinitions::isValidGenericParameterValue(parsedParameters.back())) {
1039  setParameter(parsedParameters.front(), parsedParameters.back());
1040  }
1041  }
1042 }
1043 
1044 // ===========================================================================
1045 // private
1046 // ===========================================================================
1047 
1049  personPlan(_personPlan),
1050  edge(nullptr),
1051  arrivalPos(-1) {
1052 }
1053 
1054 
1056  personPlan(nullptr),
1057  edge(nullptr),
1058  arrivalPos(-1) {
1059 }
1060 
1061 
1062 void
1063 GNEPerson::setAttribute(SumoXMLAttr key, const std::string& value) {
1064  // declare string error
1065  std::string error;
1066  switch (key) {
1067  case SUMO_ATTR_ID:
1068  changeDemandElementID(value);
1069  break;
1070  case SUMO_ATTR_TYPE:
1071  changeDemandElementParent(this, value, 0);
1072  // set manually vtypeID (needed for saving)
1073  vtypeid = value;
1074  break;
1075  case SUMO_ATTR_COLOR:
1076  if (!value.empty() && (value != myTagProperty.getDefaultValue(key))) {
1077  color = parse<RGBColor>(value);
1078  // mark parameter as set
1080  } else {
1081  // set default value
1082  color = parse<RGBColor>(myTagProperty.getDefaultValue(key));
1083  // unset parameter
1085  }
1086  break;
1087  case SUMO_ATTR_DEPARTPOS:
1088  if (!value.empty() && (value != myTagProperty.getDefaultValue(key))) {
1090  // mark parameter as set
1092  } else {
1093  // set default value
1095  // unset parameter
1097  }
1098  break;
1099  // Specific of persons
1100  case SUMO_ATTR_DEPART: {
1101  std::string oldDepart = getBegin();
1103  myViewNet->getNet()->updateDemandElementBegin(oldDepart, this);
1104  break;
1105  }
1106  // Specific of personFlows
1107  case SUMO_ATTR_BEGIN: {
1108  std::string oldBegin = getBegin();
1109  depart = string2time(value);
1110  myViewNet->getNet()->updateDemandElementBegin(oldBegin, this);
1111  break;
1112  }
1113  case SUMO_ATTR_END:
1114  repetitionEnd = string2time(value);
1115  break;
1116  case SUMO_ATTR_VEHSPERHOUR:
1117  repetitionOffset = TIME2STEPS(3600 / parse<double>(value));
1118  break;
1119  case SUMO_ATTR_PERIOD:
1120  repetitionOffset = string2time(value);
1121  break;
1122  case SUMO_ATTR_PROB:
1123  repetitionProbability = parse<double>(value);
1124  break;
1125  case SUMO_ATTR_NUMBER:
1126  repetitionNumber = parse<int>(value);
1127  break;
1128  //
1129  case GNE_ATTR_SELECTED:
1130  if (parse<bool>(value)) {
1132  } else {
1134  }
1135  break;
1136  case GNE_ATTR_GENERIC:
1137  setGenericParametersStr(value);
1138  break;
1139  default:
1140  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1141  }
1142 }
1143 
1144 
1145 void
1146 GNEPerson::setEnabledAttribute(const int enabledAttributes) {
1147  parametersSet = enabledAttributes;
1148 }
1149 
1150 
1151 void
1152 GNEPerson::calculateSmoothPersonPlanConnection(const GNEDemandElement* personPlanElement, const GNEEdge* edgeFrom, const GNEEdge* edgeTo) {
1153  // obtain lane from (special case due rides)
1154  SUMOVehicleClass vClassEdgeFrom = personPlanElement->getTagProperty().isRide() ? SVC_PASSENGER : SVC_PEDESTRIAN;
1155  GNELane* laneFrom = edgeFrom->getLaneByVClass(vClassEdgeFrom);
1156  // obtain lane to (special case due rides)
1157  SUMOVehicleClass vClassEdgeTo = personPlanElement->getTagProperty().isRide() ? SVC_PASSENGER : SVC_PEDESTRIAN;
1158  GNELane* laneTo = edgeTo->getLaneByVClass(vClassEdgeTo);
1159  // calculate smooth shape
1160  PositionVector smoothShape = edgeFrom->getNBEdge()->getToNode()->computeSmoothShape(
1161  laneFrom->getGeometry().shape, laneTo->getGeometry().shape,
1162  5, false,
1163  (double) 5. * (double) edgeFrom->getNBEdge()->getNumLanes(),
1164  (double) 5. * (double) edgeTo->getNBEdge()->getNumLanes());
1165  // add smootshape in personPlan shape
1166  for (const auto& i : smoothShape) {
1167  myDemandElementSegmentGeometry.insertJunctionSegment(personPlanElement, edgeTo->getGNEJunctionSource(), i, true, true);
1168  }
1169 }
1170 
1171 
1172 std::pair<PositionVector, PositionVector>
1174  // declare a pair of PositionVectors to save result
1175  std::pair<PositionVector, PositionVector> result;
1176  if (previousLane) {
1177  // obtain first position values of busStop shape
1178  const Position& firstBusStopShapePosition = busStop->getAdditionalGeometry().shape.front();
1179  double offsetFirstPosition = previousLane->getGeometry().shape.nearest_offset_to_point2D(firstBusStopShapePosition, false);
1180  // split laneShape
1181  auto splittedFirstLaneShape = previousLane->getGeometry().shape.splitAt(offsetFirstPosition, true);
1182  // fill result position vector
1183  for (const auto& i : splittedFirstLaneShape.first) {
1184  result.first.push_back(i);
1185  }
1186  // finally add first BusStop shape position
1187  result.first.push_back(firstBusStopShapePosition);
1188  }
1189  if (nextLane) {
1190  // obtain second position of busStops
1191  const Position& lastBusStopShapePosition = busStop->getAdditionalGeometry().shape.back();
1192  double offsetLastPosition = nextLane->getGeometry().shape.nearest_offset_to_point2D(lastBusStopShapePosition, false);
1193  // split laneShape
1194  auto splittedLastLaneShape = nextLane->getGeometry().shape.splitAt(offsetLastPosition, true);
1195  // first add last BusStop shape position
1196  result.second.push_back(lastBusStopShapePosition);
1197  // fill result position vector
1198  for (const auto& i : splittedLastLaneShape.second) {
1199  result.second.push_back(i);
1200  }
1201  }
1202  return result;
1203 }
1204 
1205 
1206 std::pair<PositionVector, PositionVector>
1208  // reuse calculatePersonPlanConnectionBusStop(...) if stop is placed over a busStop
1210  return calculatePersonPlanConnectionBusStop(previousLane, stop->getAdditionalParents().front(), nextLane);
1211  } else {
1212  // declare a pair of PositionVectors to save result
1213  std::pair<PositionVector, PositionVector> result;
1214  if (previousLane) {
1215  // split laneShape in start position
1216  auto splittedFirstLaneShape = previousLane->getGeometry().shape.splitAt(stop->getAttributeDouble(SUMO_ATTR_STARTPOS), true);
1217  // fill result position vector
1218  for (const auto& i : splittedFirstLaneShape.first) {
1219  result.first.push_back(i);
1220  }
1221  // finally add first Stop shape position
1222  result.first.push_back(stop->getDemandElementGeometry().shape.front());
1223  }
1224  if (nextLane) {
1225  // split laneShape in end position
1226  auto splittedLastLaneShape = nextLane->getGeometry().shape.splitAt(stop->getAttributeDouble(SUMO_ATTR_ENDPOS), true);
1227  // first add last Stop shape position
1228  result.second.push_back(stop->getDemandElementGeometry().shape.back());
1229  // fill result position vector
1230  for (const auto& i : splittedLastLaneShape.second) {
1231  result.second.push_back(i);
1232  }
1233  }
1234  return result;
1235  }
1236 }
1237 
1238 
1239 std::pair<PositionVector, PositionVector>
1240 GNEPerson::calculatePersonPlanConnectionArrivalPos(GNELane* previousLane, double arrivalPosPersonPlan, GNELane* nextLane) {
1241  // check if both lanes are similar)
1242  if ((previousLane == nextLane) && (previousLane != nullptr)) {
1243  // split laneShape in arrivalPos
1244  return previousLane->getGeometry().shape.splitAt(arrivalPosPersonPlan, true);
1245  } else {
1246  // declare pair of position vectors
1247  std::pair<PositionVector, PositionVector> solution;
1248  // split previousLane in arrivalPos
1249  if (previousLane) {
1250  solution.first = previousLane->getGeometry().shape.splitAt(arrivalPosPersonPlan, true).first;
1251  }
1252  // split nextLane in arrivalPos
1253  if (nextLane) {
1254  solution.second = nextLane ->getGeometry().shape.splitAt(arrivalPosPersonPlan, true).second;
1255  }
1256  // return solution
1257  return solution;
1258  }
1259 }
1260 
1261 /****************************************************************************/
bool mySelected
boolean to check if this AC is selected (instead of GUIGlObjectStorage)
static const double personCircles
details for draw person as circles
std::pair< PositionVector, PositionVector > calculatePersonPlanConnectionArrivalPos(GNELane *previousLane, double arrivalPosPersonPlan, GNELane *nextLane)
return two shapes used for calculate person plan conections between arrival position ...
Definition: GNEPerson.cpp:1240
void unselectAttributeCarrier(bool changeFlag=true)
unselect attribute carrier using GUIGlobalSelection
Definition: GNEPerson.cpp:633
const TagProperties & myTagProperty
the xml tag to which this attribute carrier corresponds
bool hasTagSynonym() const
return true if tag correspond to an element that will be written in XML with another tag ...
Copy object name - popup entry.
Definition: GUIAppEnum.h:369
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
bool setFunctionalColor(int activeScheme) const
sets the color according to the current scheme index and some vehicle function
Definition: GNEPerson.cpp:947
SumoXMLTag
Numbers representing SUMO-XML - element names.
a person flow
RGBColor color
The vehicle&#39;s color, TraCI may change this.
std::pair< PositionVector, PositionVector > calculatePersonPlanConnectionStop(GNELane *previousLane, GNEDemandElement *stop, GNELane *nextLane)
return two shapes used for calculate person plan conections between stops
Definition: GNEPerson.cpp:1207
SumoXMLTag getTagSynonym() const
get tag synonym
double scale
information about a lane&#39;s width (temporary, used for a single view)
description of a vehicle type
void addedLockedObject(const GUIGlObjectType type)
set object selected
PositionVector shape
The shape of the netElement element.
Definition: GNENetElement.h:57
std::vector< GNEAdditional * > busStops
busStops placed in this segment
Definition: GNEPerson.h:295
static const double personShapes
details for draw person as person shapes
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
void setGenericParametersStr(const std::string &value)
set generic parameters in string format
Definition: GNEPerson.cpp:1021
std::string vtypeid
The vehicle&#39;s type id.
GUIVisualizationTextSettings personValue
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
GUIVisualizationTextSettings personName
std::vector< std::pair< std::string, std::string > > getGenericParameters() const
return generic parameters as vector of pairs format
Definition: GNEPerson.cpp:1010
a flow definitio nusing a from-to edges instead of a route (used by router)
static const double personExaggeration
Exaggeration for persons (only used in NETEDIT)
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNEPerson.cpp:560
FXMenuCommand * myTransformToPersonFlow
menu command for transform to personFlow
Definition: GNEPerson.h:107
const int VEHPARS_PROB_SET
Stores the information about how to visualize structures.
std::pair< PositionVector, PositionVector > splitAt(double where, bool use2D=false) const
Returns the two lists made when this list vector is splitted at the given point.
void endGeometryMoving()
end geometry movement
Definition: GNEPerson.cpp:304
void select(GUIGlID id, bool update=true)
Adds the object with the given id.
GNEViewParent * getViewParent() const
get the net object
Definition: GNEViewNet.cpp:921
double y() const
Returns the y-position.
Definition: Position.h:62
const std::string & getDefaultValue(SumoXMLAttr attr) const
return the default value of the attribute of an element
bool geometryDeprecated
mark geometry as deprecated (used to avoid multiple updates)
double repetitionProbability
The probability for emitting a vehicle per second.
static void drawTextSettings(const GUIVisualizationTextSettings &settings, const std::string &text, const Position &pos, const double scale, const double angle=0, const double layer=2048)
Definition: GLHelper.cpp:701
int parametersSet
Information for the router which parameter were set, TraCI may modify this (whe changing color) ...
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
double x() const
Returns the x-position.
Definition: Position.h:57
static void drawAction_drawAsImage(const double angle, const double lenght, const double width, const std::string &file, const SUMOVehicleShape guiShape, const double exaggeration)
~GNEPerson()
destructor
Definition: GNEPerson.cpp:181
static void drawAction_drawAsTriangle(const double angle, const double lenght, const double width)
FXMenuCommand * myTransformToPersonFlow
menu command for transform to personFlow
Definition: GNEPerson.h:70
void insertEdgeLengthRotSegment(const GNEDemandElement *element, const GNEEdge *edge, const Position pos, double length, double rotation, const bool visible, const bool valid)
insert edge segment with length and rotation (used to avoid unnecessary calculation in calculateParti...
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
weights: time range begin
bool drawDetail(const double detail, const double exaggeration) const
check if details can be drawn for the given GUIVisualizationDetailSettings and current scale and exxa...
GNESelectedPersonsPopupMenu()
default constructor needed by FOX
Definition: GNEPerson.h:94
std::vector< GNEPerson * > mySelectedPersons
current selected persons
Definition: GNEPerson.h:101
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
static void transformToPerson(GNEPerson *originalPerson)
transform person functions
virtual double getAttributeDouble(SumoXMLAttr key) const =0
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
void changeDemandElementID(const std::string &newID)
change ID of demand element
#define TIME2STEPS(x)
Definition: SUMOTime.h:59
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
bool hasNext()
returns the information whether further substrings exist
PositionVector shape
The shape of the additional element.
const int VEHPARS_NUMBER_SET
static bool isValidGenericParameterKey(const std::string &value)
whether the given string is a valid key for a generic parameter
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used, also builds an entry for copying the geo-position.
const AdditionalGeometry & getAdditionalGeometry() const
obtain AdditionalGeometry
generic attribute
class used in GUIGLObjectPopupMenu for single person transformations
Definition: GNEPerson.h:74
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
static void drawAction_drawAsCircle(const double lenght, const double width)
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNEPerson.cpp:534
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
const std::vector< GNEEdge * > & getEdgeParents() const
get edge parents
friend class GNEChange_EnableAttribute
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
bool isRide() const
return true if tag correspond to a ride element
const std::vector< GNEDemandElement * > & getDemandElementChildren() const
return vector of demand elements that have as Parent this edge (For example, Calibrators) ...
double getAttributeDouble(SumoXMLAttr key) const
Definition: GNEPerson.cpp:697
const DemandElementGeometry & getDemandElementGeometry() const
get demand element geometry
void selectAttributeCarrier(bool changeFlag=true)
inherited from GNEAttributeCarrier
Definition: GNEPerson.cpp:618
std::string getGenericParametersStr() const
return generic parameters in string format
Definition: GNEPerson.cpp:995
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition: GNEEdge.cpp:625
std::string getPopUpID() const
get PopPup ID (Used in AC Hierarchy)
Definition: GNEPerson.cpp:903
SUMOVehicleParameter()
Constructor.
std::vector< double > shapeRotations
The rotations of the single shape parts.
Definition: GNENetElement.h:60
LockGLObjectTypes * getLockGLObjectTypes() const
get selected items Modul
static bool isValidGenericParameterValue(const std::string &value)
whether the given string is a valid value for a generic parameter
class used in GUIGLObjectPopupMenu for person transformations
Definition: GNEPerson.h:41
const RGBColor & getColor() const
get color
Definition: GNEPerson.cpp:286
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void setColor(const GUIVisualizationSettings &s) const
sets the color according to the currente settings
Definition: GNEPerson.cpp:938
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:616
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
Definition: GNEPerson.cpp:733
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
GNEDemandElement * retrieveDemandElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named demand element.
Definition: GNENet.cpp:2266
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:465
std::string getDepartPos() const
obtain depart pos parameter in string format
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
PositionVector shape
The shape of the additional element.
Definition: GNEAdditional.h:68
DemandElementSegmentGeometry myDemandElementSegmentGeometry
demand element segment geometry
GNEEdge * getToEdge() const
obtain to edge of this demand element
Definition: GNEPerson.cpp:274
A list of positions.
Supermode currentSupermode
the current supermode
double scaledSize(double scale, double constFactor=0.1) const
get scale size
static bool isGenericParametersValid(const std::string &value)
check if given string can be parsed to a map/list of generic parameters
void removeLockedObject(const GUIGlObjectType type)
set object unselected
friend class GNEChange_Attribute
declare friend class
long onCmdTransform(FXObject *obj, FXSelector, void *)
Called to transform the current person to another person type.
Definition: GNEPerson.cpp:154
std::string getAttribute(SumoXMLAttr key) const
Definition: GNEPerson.cpp:649
void changeDemandElementParent(GNEShape *shapeTobeChanged, const std::string &newDemandElementParentID, int demandElementParentIndex)
change first demand element parent of a shape
const std::vector< GNELane * > & getLaneParents() const
get lanes of VSS
#define STEPS2TIME(x)
Definition: SUMOTime.h:57
void calculatePartialShapeRotationsAndLengths()
calculate partial shape, rotations and lengths
void startGeometryMoving()
Definition: GNEPerson.cpp:298
void enableAttribute(SumoXMLAttr key, GNEUndoList *undoList)
Definition: GNEPerson.cpp:822
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
const std::vector< GNEAdditional * > & getAdditionalParents() const
return vector of additionals that have as Parent this edge (For example, Calibrators) ...
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:42
void write(OutputDevice &dev, const OptionsCont &oc, const SumoXMLTag tag=SUMO_TAG_VEHICLE, const std::string &typeID="") const
Writes the parameters as a beginning element.
const std::string & getDemandElementID() const
returns DemandElement ID
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
GUIColorer personColorer
The person colorer.
void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
GNESelectorFrame * getSelectorFrame() const
get frame for GNE_NMODE_SELECT
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void insertEdgeSegment(const GNEDemandElement *element, const GNEEdge *edge, const Position pos, const bool visible, const bool valid)
insert edge segment
void updateGeometry()
update pre-computed geometry information
Definition: GNEPerson.cpp:322
const std::string getID() const
function to support debugging
static const double personTriangles
details for draw person as triangles
double angle
The current view rotation angle.
void clearDemandElementSegmentGeometry()
clear demand element geometry
const NetElementGeometry & getGeometry() const
const T getColor(const double value) const
std::string getDemandElementProblem() const
return a string with the current demand element problem (by default empty, can be reimplemented in ch...
Definition: GNEPerson.cpp:255
const int VEHPARS_PERIOD_SET
void setEnabledAttribute(const int enabledAttributes)
method for enabling the attribute and nothing else (used in GNEChange_EnableAttribute) ...
Definition: GNEPerson.cpp:1146
GNEJunction * getGNEJunctionSource() const
returns the source-junction
Definition: GNEEdge.cpp:499
const int VEHPARS_COLOR_SET
FXDEFMAP(GNEPerson::GNEPersonPopupMenu) personPopupMenuMap[]
vehicle is a passenger car (a "normal" car)
long onCmdTransform(FXObject *obj, FXSelector, void *)
Called to transform the current person to another person type.
Definition: GNEPerson.cpp:105
std::vector< double > shapeLengths
The lengths of the single shape parts.
Definition: GNENetElement.h:63
const int VEHPARS_END_SET
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
Definition: GNEViewNet.cpp:411
begin/end of the description of an edge
double arrivalPos
(optional) The position the vehicle shall arrive on
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
std::vector< std::string > via
List of the via-edges the vehicle must visit.
static void drawShapeDottedContourRectangle(const GUIVisualizationSettings &s, const int type, const Position &center, const double width, const double height, const double rotation=0, const double offsetX=0, const double offsetY=0)
draw a dotted contour around the given Position with certain width and height
Definition: GLHelper.cpp:555
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:50
GUIVisualizationDetailSettings detailSettings
detail settings
Position getPositionInView() const
Returns position of demand element in view.
Definition: GNEPerson.cpp:508
const std::vector< GNEDemandElement * > & getDemandElementParents() const
return vector of demand elements that have as Parent this edge (For example, Calibrators) ...
bool showNonInspectedDemandElements(const GNEDemandElement *demandElement) const
check if non inspected element has to be hidden
static void transformToPersonFlow(GNEPerson *originalPerson)
transform routeFlow over an existent route
render as a pedestrian
double departPos
(optional) The position the vehicle shall depart from
void updateDemandElementBegin(const std::string &oldBegin, GNEDemandElement *demandElement)
update demand element begin in container
Definition: GNENet.cpp:2328
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNEPerson.cpp:547
bool showDemandElements() const
check if show demand elements checkbox is enabled
Structure representing possible vehicle parameter.
void deselect(GUIGlID id)
Deselects the object with the given id.
void buildSelectionACPopupEntry(GUIGLObjectPopupMenu *ret, GNEAttributeCarrier *AC)
Builds an entry which allows to (de)select the object.
Definition: GNEViewNet.cpp:331
double length() const
Returns the length.
bool isDemandElementValid() const
check if current demand element is valid to be writed into XML (by default true, can be reimplemented...
Definition: GNEPerson.cpp:248
bool isAttributeEnabled(SumoXMLAttr key) const
Definition: GNEPerson.cpp:884
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
method for setting the attribute and letting the object perform demand element changes ...
Definition: GNEPerson.cpp:703
std::vector< GNEDemandElement * > stops
stops placed in this segment
Definition: GNEPerson.h:298
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:47
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
Definition: GNEViewNet.cpp:417
const std::string DEFAULT_PEDTYPE_ID
static bool parseDepartPos(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosDefinition &dpd, std::string &error)
Validates a given departPos value.
const GNEAttributeCarrier * getDottedAC() const
get AttributeCarrier under cursor
Definition: GNEViewNet.cpp:939
virtual double getColorValue(const GUIVisualizationSettings &, int) const
Definition: GUIGlObject.h:148
std::string getHierarchyName() const
get Hierarchy Name (Used in AC Hierarchy)
Definition: GNEPerson.cpp:909
const std::string & getTagStr() const
get tag assigned to this object in string format
weights: time range end
SumoXMLTag myPersonTag
tag of clicked person
Definition: GNEPerson.h:98
Demanding mode (Routes, Vehicles etc..)
element is selected
double arrivalPos
arrival position
Definition: GNEPerson.h:301
SumoXMLTag tag
The vehicle tag.
The popup menu of a globject.
void fixDemandElementProblem()
fix demand element problem (by default throw an exception, has to be reimplemented in children) ...
Definition: GNEPerson.cpp:262
GUIVisualizationSizeSettings personSize
GNENet * getNet() const
get the net object
Definition: GNEViewNet.cpp:927
~GNEPersonPopupMenu()
Destructor.
Definition: GNEPerson.cpp:101
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
bool wasSet(int what) const
Returns whether the given parameter was set.
GUIGlID getGlID() const
Returns the numerical id of the object.
const int VEHPARS_VTYPE_SET
description of a vehicle
void insertMenuPaneChild(FXMenuPane *child)
Insert a sub-menu pane in this GUIGLObjectPopupMenu.
GNEPerson(SumoXMLTag tag, GNEViewNet *viewNet, GNEDemandElement *pType, const SUMOVehicleParameter &personparameters)
constructor for persons
Definition: GNEPerson.cpp:172
GNEViewNet * myViewNet
The GNEViewNet this demand element element belongs.
GNEViewNet * getViewNet() const
Returns a pointer to GNEViewNet in which demand element element is located.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
const TagProperties & getTagProperty() const
get Tag Property assigned to this object
GNEEdge * getFromEdge() const
Definition: GNEPerson.cpp:268
void writeDemandElement(OutputDevice &device) const
writte demand element element into a xml file
Definition: GNEPerson.cpp:204
const int VEHPARS_VPH_SET
a single trip definition (used by router)
SUMOVehicleClass getVClass() const
obtain VClass related with this demand element
Definition: GNEPerson.cpp:280
empty max
std::string getDepart() const
obtain depart parameter in string format
static bool isValidTypeID(const std::string &value)
whether the given string is a valid id for an edge or vehicle type
const int VEHPARS_DEPARTPOS_SET
void compute()
compute demand element
Definition: GNEPerson.cpp:292
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
void calculateSmoothPersonPlanConnection(const GNEDemandElement *personPlanElement, const GNEEdge *edgeFrom, const GNEEdge *edgeTo)
calculate smooth shape between personPlans
Definition: GNEPerson.cpp:1152
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
Definition: GNEViewNet.cpp:399
FXMenuCommand * myTransformToPerson
menu command for transform to person
Definition: GNEPerson.h:67
void commitGeometryMoving(GNEUndoList *undoList)
commit geometry changes in the attributes of an element after use of moveGeometry(...)
Definition: GNEPerson.cpp:316
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
transform person to another person type (ej: person to personflow)
Definition: GUIAppEnum.h:937
DepartPosDefinition
Possible ways to choose the departure position.
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
PositionVector computeSmoothShape(const PositionVector &begShape, const PositionVector &endShape, int numPoints, bool isTurnaround, double extrapolateBeg, double extrapolateEnd, NBNode *recordError=0, int shapeFlag=0) const
Compute a smooth curve between the given geometries.
Definition: NBNode.cpp:504
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
GUISelectedStorage gSelected
A global holder of selected objects.
Copy typed object name - popup entry.
Definition: GUIAppEnum.h:371
A color information.
GNELane * getLaneByVClass(const SUMOVehicleClass vClass) const
return the first lane that allow a vehicle of type vClass (or the first lane, if none was found) ...
Definition: GNEEdge.cpp:1189
std::string getParentName() const
Returns the name of the parent object.
Definition: GNEPerson.cpp:541
static FXIcon * getIcon(GUIIcon which)
returns a icon previously defined in the enum GUIIcon
FXMenuCommand * myTransformToPerson
menu command for transform to person
Definition: GNEPerson.h:104
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:486
const GNEDemandElement * personPlan
person plan
Definition: GNEPerson.h:289
void insertJunctionSegment(const GNEDemandElement *element, const GNEJunction *junction, const Position pos, const bool visible, const bool valid)
insert junction segment
static bool isValidVehicleID(const std::string &value)
whether the given string is a valid id for a vehicle or flow
static bool parseDepart(const std::string &val, const std::string &element, const std::string &id, SUMOTime &depart, DepartDefinition &dd, std::string &error)
Validates a given depart value.
void moveGeometry(const Position &offset)
change the position of the element geometry without saving in undoList
Definition: GNEPerson.cpp:310
GNEPerson * myPerson
current person
Definition: GNEPerson.h:64
std::string id
The vehicle&#39;s id.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2067
std::pair< PositionVector, PositionVector > calculatePersonPlanConnectionBusStop(GNELane *previousLane, GNEAdditional *busStop, GNELane *nextLane)
return two shapes used for calculate person plan conections between busStops
Definition: GNEPerson.cpp:1173
void clearParameter()
Clears the parameter map.
std::string getBegin() const
get begin time of demand element
Definition: GNEPerson.cpp:185