Eclipse SUMO - Simulation of Urban MObility
GNEFrameModuls.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // Auxiliar class for GNEFrame Moduls
19 /****************************************************************************/
20 #include <config.h>
21 
23 #include <netedit/GNENet.h>
24 #include <netedit/GNEUndoList.h>
25 #include <netedit/GNEViewNet.h>
26 #include <netedit/GNEViewParent.h>
33 #include <utils/gui/div/GLHelper.h>
37 
38 #include "GNEFrameModuls.h"
39 
40 
41 // ===========================================================================
42 // FOX callback mapping
43 // ===========================================================================
44 
48 };
49 
50 FXDEFMAP(GNEFrameModuls::DemandElementSelector) DemandElementSelectorMap[] = {
52 };
53 
54 FXDEFMAP(GNEFrameModuls::HierarchicalElementTree) HierarchicalElementTreeMap[] = {
61 };
62 
63 FXDEFMAP(GNEFrameModuls::DrawingShape) DrawingShapeMap[] = {
67 };
68 
69 FXDEFMAP(GNEFrameModuls::OverlappedInspection) OverlappedInspectionMap[] = {
75 };
76 
82 };
83 
84 
85 // Object implementation
86 FXIMPLEMENT(GNEFrameModuls::TagSelector, FXGroupBox, TagSelectorMap, ARRAYNUMBER(TagSelectorMap))
87 FXIMPLEMENT(GNEFrameModuls::DemandElementSelector, FXGroupBox, DemandElementSelectorMap, ARRAYNUMBER(DemandElementSelectorMap))
88 FXIMPLEMENT(GNEFrameModuls::HierarchicalElementTree, FXGroupBox, HierarchicalElementTreeMap, ARRAYNUMBER(HierarchicalElementTreeMap))
89 FXIMPLEMENT(GNEFrameModuls::DrawingShape, FXGroupBox, DrawingShapeMap, ARRAYNUMBER(DrawingShapeMap))
90 FXIMPLEMENT(GNEFrameModuls::OverlappedInspection, FXGroupBox, OverlappedInspectionMap, ARRAYNUMBER(OverlappedInspectionMap))
91 FXIMPLEMENT(GNEFrameModuls::PathCreator, FXGroupBox, PathCreatorMap, ARRAYNUMBER(PathCreatorMap))
92 
93 
94 // ===========================================================================
95 // method definitions
96 // ===========================================================================
97 
98 // ---------------------------------------------------------------------------
99 // GNEFrameModuls::TagSelector - methods
100 // ---------------------------------------------------------------------------
101 
102 GNEFrameModuls::TagSelector::TagSelector(GNEFrame* frameParent, GNETagProperties::TagType type, bool onlyDrawables) :
103  FXGroupBox(frameParent->myContentFrame, "Element", GUIDesignGroupBoxFrame),
104  myFrameParent(frameParent) {
105  // first check that property is valid
106  switch (type) {
107  case GNETagProperties::TagType::NETWORKELEMENT:
108  setText("network elements");
109  break;
110  case GNETagProperties::TagType::ADDITIONALELEMENT:
111  setText("Additional elements");
112  break;
113  case GNETagProperties::TagType::SHAPE:
114  setText("Shape elements");
115  break;
116  case GNETagProperties::TagType::TAZELEMENT:
117  setText("TAZ elements");
118  break;
119  case GNETagProperties::TagType::VEHICLE:
120  setText("Vehicles");
121  break;
122  case GNETagProperties::TagType::STOP:
123  setText("Stops");
124  break;
125  case GNETagProperties::TagType::PERSON:
126  setText("Persons");
127  break;
128  case GNETagProperties::TagType::PERSONPLAN:
129  setText("Person plans");
130  // person plan type has four sub-groups
131  myListOfTagTypes.push_back(std::make_pair("person trips", GNETagProperties::TagType::PERSONTRIP));
132  myListOfTagTypes.push_back(std::make_pair("walks", GNETagProperties::TagType::WALK));
133  myListOfTagTypes.push_back(std::make_pair("rides", GNETagProperties::TagType::RIDE));
134  myListOfTagTypes.push_back(std::make_pair("stops", GNETagProperties::TagType::PERSONSTOP));
135  break;
136  case GNETagProperties::TagType::PERSONTRIP:
137  setText("Person trips");
138  break;
139  case GNETagProperties::TagType::WALK:
140  setText("Walks");
141  break;
142  case GNETagProperties::TagType::RIDE:
143  setText("Rides");
144  break;
145  case GNETagProperties::TagType::PERSONSTOP:
146  setText("Person stops");
147  break;
148  default:
149  throw ProcessError("invalid tag property");
150  }
151 
152  // Create FXComboBox
153  myTagTypesMatchBox = new FXComboBox(this, GUIDesignComboBoxNCol, this, MID_GNE_TAGTYPE_SELECTED, GUIDesignComboBox);
154  // Create FXComboBox
155  myTagsMatchBox = new FXComboBox(this, GUIDesignComboBoxNCol, this, MID_GNE_TAG_SELECTED, GUIDesignComboBox);
156  // Fill comboBox depending of TagTypes
157  if (myListOfTagTypes.size() > 0) {
158  // fill myTypeMatchBox with list of tags
159  for (const auto& i : myListOfTagTypes) {
160  myTagTypesMatchBox->appendItem(i.first.c_str());
161  }
162  // Set visible items
163  myTagTypesMatchBox->setNumVisible((int)myTagTypesMatchBox->getNumItems());
164  // fill myListOfTags with personTrips (the first Tag Type)
165  myListOfTags = GNEAttributeCarrier::getAllowedTagsByCategory(GNETagProperties::TagType::PERSONTRIP, onlyDrawables);
166  } else {
167  myTagTypesMatchBox->hide();
168  // fill myListOfTags
169  myListOfTags = GNEAttributeCarrier::getAllowedTagsByCategory(type, onlyDrawables);
170  }
171  // fill myTypeMatchBox with list of tags
172  for (const auto& tag : myListOfTags) {
173  myTagsMatchBox->appendItem(tag.second.c_str());
174  }
175  // Set visible items
176  myTagsMatchBox->setNumVisible((int)myTagsMatchBox->getNumItems());
177  // TagSelector is always shown
178  show();
179 }
180 
181 
183 
184 
185 void
187  show();
188 }
189 
190 
191 void
193  hide();
194 }
195 
196 
197 const GNETagProperties&
199  return myCurrentTagProperties;
200 }
201 
202 
203 void
205  // set empty tag properties
206  myCurrentTagProperties = GNETagProperties();
207  // make sure that tag is in myTypeMatchBox
208  for (int i = 0; i < (int)myTagsMatchBox->getNumItems(); i++) {
209  if (myTagsMatchBox->getItem(i).text() == toString(tagType)) {
210  myTagsMatchBox->setCurrentItem(i);
211  // fill myListOfTags with personTrips (the first Tag Type)
212  myListOfTags = GNEAttributeCarrier::getAllowedTagsByCategory(GNETagProperties::TagType::PERSONTRIP, true);
213  // clear myTagsMatchBox
214  myTagsMatchBox->clearItems();
215  // fill myTypeMatchBox with list of tags
216  for (const auto& tag : myListOfTags) {
217  myTagsMatchBox->appendItem(tag.second.c_str());
218  }
219  // Set visible items
220  myTagsMatchBox->setNumVisible((int)myTagsMatchBox->getNumItems());
221  }
222  }
223  // call tag selected function
224  myFrameParent->tagSelected();
225 }
226 
227 
228 void
230  // set empty tag properties
231  myCurrentTagProperties = GNETagProperties();
232  // make sure that tag is in myTypeMatchBox
233  for (int i = 0; i < (int)myTagsMatchBox->getNumItems(); i++) {
234  if (myTagsMatchBox->getItem(i).text() == toString(newTag)) {
235  myTagsMatchBox->setCurrentItem(i);
236  // Set new current type
237  myCurrentTagProperties = GNEAttributeCarrier::getTagProperties(newTag);
238  }
239  }
240  // call tag selected function
241  myFrameParent->tagSelected();
242 }
243 
244 
245 void
247  // simply call onCmdSelectItem (to avoid duplicated code)
248  onCmdSelectTag(0, 0, 0);
249 }
250 
251 
252 long GNEFrameModuls::TagSelector::onCmdSelectTagType(FXObject*, FXSelector, void*) {
253  // Check if value of myTypeMatchBox correspond of an allowed additional tags
254  for (const auto& i : myListOfTagTypes) {
255  if (i.first == myTagTypesMatchBox->getText().text()) {
256  // set color of myTagTypesMatchBox to black (valid)
257  myTagTypesMatchBox->setTextColor(FXRGB(0, 0, 0));
258  // fill myListOfTags with personTrips (the first Tag Type)
259  myListOfTags = GNEAttributeCarrier::getAllowedTagsByCategory(i.second, true);
260  // show and clear myTagsMatchBox
261  myTagsMatchBox->show();
262  myTagsMatchBox->clearItems();
263  // fill myTypeMatchBox with list of tags
264  for (const auto& tag : myListOfTags) {
265  myTagsMatchBox->appendItem(tag.second.c_str());
266  }
267  // Set visible items
268  myTagsMatchBox->setNumVisible((int)myTagsMatchBox->getNumItems());
269  // Write Warning in console if we're in testing mode
270  WRITE_DEBUG(("Selected item '" + myTagsMatchBox->getText() + "' in TagTypeSelector").text());
271  // call onCmdSelectTag
272  return onCmdSelectTag(nullptr, 0, nullptr);
273  }
274  }
275  // if TagType isn't valid, hide myTagsMatchBox
276  myTagsMatchBox->hide();
277  // if additional name isn't correct, set SUMO_TAG_NOTHING as current type
278  myCurrentTagProperties = myInvalidTagProperty;
279  // call tag selected function
280  myFrameParent->tagSelected();
281  // set color of myTagTypesMatchBox to red (invalid)
282  myTagTypesMatchBox->setTextColor(FXRGB(255, 0, 0));
283  // Write Warning in console if we're in testing mode
284  WRITE_DEBUG("Selected invalid item in TagTypeSelector");
285  return 1;
286 }
287 
288 
289 long
290 GNEFrameModuls::TagSelector::onCmdSelectTag(FXObject*, FXSelector, void*) {
291  // Check if value of myTypeMatchBox correspond of an allowed additional tags
292  for (const auto& tag : myListOfTags) {
293  if (tag.second == myTagsMatchBox->getText().text()) {
294  // set color of myTypeMatchBox to black (valid)
295  myTagsMatchBox->setTextColor(FXRGB(0, 0, 0));
296  // Set new current type
297  myCurrentTagProperties = GNEAttributeCarrier::getTagProperties(tag.first);
298  // call tag selected function
299  myFrameParent->tagSelected();
300  // Write Warning in console if we're in testing mode
301  WRITE_DEBUG(("Selected item '" + myTagsMatchBox->getText() + "' in TagSelector").text());
302  return 1;
303  }
304  }
305  // if additional name isn't correct, set SUMO_TAG_NOTHING as current type
306  myCurrentTagProperties = myInvalidTagProperty;
307  // call tag selected function
308  myFrameParent->tagSelected();
309  // set color of myTypeMatchBox to red (invalid)
310  myTagsMatchBox->setTextColor(FXRGB(255, 0, 0));
311  // Write Warning in console if we're in testing mode
312  WRITE_DEBUG("Selected invalid item in TagSelector");
313  return 1;
314 }
315 
316 // ---------------------------------------------------------------------------
317 // GNEFrameModuls::DemandElementSelector - methods
318 // ---------------------------------------------------------------------------
319 
321  FXGroupBox(frameParent->myContentFrame, ("Parent " + toString(demandElementTag)).c_str(), GUIDesignGroupBoxFrame),
322  myFrameParent(frameParent),
323  myCurrentDemandElement(nullptr),
324  myDemandElementTags({demandElementTag}) {
325  // Create FXComboBox
326  myDemandElementsMatchBox = new FXComboBox(this, GUIDesignComboBoxNCol, this, MID_GNE_SET_TYPE, GUIDesignComboBox);
327  // refresh demand element MatchBox
328  refreshDemandElementSelector();
329  // shown after creation
330  show();
331 }
332 
333 
334 GNEFrameModuls::DemandElementSelector::DemandElementSelector(GNEFrame* frameParent, const std::vector<GNETagProperties::TagType>& tagTypes) :
335  FXGroupBox(frameParent->myContentFrame, "Parent element", GUIDesignGroupBoxFrame),
336  myFrameParent(frameParent),
337  myCurrentDemandElement(nullptr) {
338  // fill myDemandElementTags
339  for (const auto& tagType : tagTypes) {
340  const auto tagsByCategory = GNEAttributeCarrier::getAllowedTagsByCategory(tagType, false);
341  for (const auto& tagByCategory : tagsByCategory) {
342  myDemandElementTags.push_back(tagByCategory.first);
343  }
344  }
345  // Create FXComboBox
347  // refresh demand element MatchBox
349  // shown after creation
350  show();
351 }
352 
353 
355 
356 
359  return myCurrentDemandElement;
360 }
361 
362 
363 const std::vector<SumoXMLTag>&
365  return myDemandElementTags;
366 }
367 
368 
369 void
371  // first check that demandElement tag correspond to a tag of myDemandElementTags
372  if (std::find(myDemandElementTags.begin(), myDemandElementTags.end(), demandElement->getTagProperty().getTag()) != myDemandElementTags.end()) {
373  // update text of myDemandElementsMatchBox
374  myDemandElementsMatchBox->setText(demandElement->getID().c_str());
375  // Set new current demand element
376  myCurrentDemandElement = demandElement;
377  // call demandElementSelected function
378  myFrameParent->demandElementSelected();
379  }
380 }
381 
382 
383 void
385  // first refresh modul
386  refreshDemandElementSelector();
387  // if current selected item isn't valid, set DEFAULT_VTYPE_ID or DEFAULT_PEDTYPE_ID
388  if (myCurrentDemandElement) {
389  myDemandElementsMatchBox->setText(myCurrentDemandElement->getID().c_str());
390  } else if (myDemandElementTags.size() == 1) {
391  if (myDemandElementTags.at(0) == SUMO_TAG_VTYPE) {
392  myDemandElementsMatchBox->setText(DEFAULT_VTYPE_ID.c_str());
393  } else if (myDemandElementTags.at(0) == SUMO_TAG_PTYPE) {
394  myDemandElementsMatchBox->setText(DEFAULT_PEDTYPE_ID.c_str());
395  }
396  }
397  onCmdSelectDemandElement(nullptr, 0, nullptr);
398  show();
399 }
400 
401 
402 void
404  hide();
405 }
406 
407 
408 bool
410  return shown();
411 }
412 
413 
414 void
416  // clear demand elements comboBox
417  myDemandElementsMatchBox->clearItems();
418  // fill myTypeMatchBox with list of demand elements
419  for (const auto& i : myDemandElementTags) {
420  // special case for VTypes and PTypes
421  if (i == SUMO_TAG_VTYPE) {
422  // add default Vehicle an Bike types in the first and second positions
423  myDemandElementsMatchBox->appendItem(DEFAULT_VTYPE_ID.c_str());
424  myDemandElementsMatchBox->appendItem(DEFAULT_BIKETYPE_ID.c_str());
425  // add rest of vTypes
426  for (const auto& j : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(i)) {
427  // avoid insert duplicated default vType
428  if ((j.first != DEFAULT_VTYPE_ID) && (j.first != DEFAULT_BIKETYPE_ID)) {
429  myDemandElementsMatchBox->appendItem(j.first.c_str());
430  }
431  }
432  } else if (i == SUMO_TAG_PTYPE) {
433  // add default Person type in the firs
434  myDemandElementsMatchBox->appendItem(DEFAULT_PEDTYPE_ID.c_str());
435  // add rest of pTypes
436  for (const auto& j : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(i)) {
437  // avoid insert duplicated default pType
438  if (j.first != DEFAULT_PEDTYPE_ID) {
439  myDemandElementsMatchBox->appendItem(j.first.c_str());
440  }
441  }
442  } else {
443  // insert all Ids
444  for (const auto& j : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(i)) {
445  myDemandElementsMatchBox->appendItem(j.first.c_str());
446  }
447  }
448  }
449  // Set number of items (maximum 10)
450  if (myDemandElementsMatchBox->getNumItems() < 10) {
451  myDemandElementsMatchBox->setNumVisible((int)myDemandElementsMatchBox->getNumItems());
452  } else {
453  myDemandElementsMatchBox->setNumVisible(10);
454  }
455  // update myCurrentDemandElement
456  if (myDemandElementsMatchBox->getNumItems() == 0) {
457  myCurrentDemandElement = nullptr;
458  } else if (myCurrentDemandElement) {
459  for (int i = 0; i < myDemandElementsMatchBox->getNumItems(); i++) {
460  if (myDemandElementsMatchBox->getItem(i).text() == myCurrentDemandElement->getID()) {
461  myDemandElementsMatchBox->setCurrentItem(i, FALSE);
462  }
463  }
464  } else {
465  // set first element in the list as myCurrentDemandElement (Special case for default person and vehicle type)
466  if (myDemandElementsMatchBox->getItem(0).text() == DEFAULT_VTYPE_ID) {
467  myCurrentDemandElement = myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(SUMO_TAG_VTYPE).at(DEFAULT_VTYPE_ID);
468  } else if (myDemandElementsMatchBox->getItem(0).text() == DEFAULT_PEDTYPE_ID) {
469  myCurrentDemandElement = myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(SUMO_TAG_PTYPE).at(DEFAULT_PEDTYPE_ID);
470  } else {
471  // disable myCurrentDemandElement
472  myCurrentDemandElement = nullptr;
473  // update myCurrentDemandElement with the first allowed element
474  for (auto i = myDemandElementTags.begin(); (i != myDemandElementTags.end()) && (myCurrentDemandElement == nullptr); i++) {
475  if (myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(*i).size() > 0) {
476  myCurrentDemandElement = myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(*i).begin()->second;
477  }
478  }
479  }
480  }
481 }
482 
483 
484 GNEEdge*
486  if (myCurrentDemandElement == nullptr) {
487  return nullptr;
488  }
489  if (!myCurrentDemandElement->getTagProperty().isPerson()) {
490  return nullptr;
491  }
492  if (myCurrentDemandElement->getChildDemandElements().empty()) {
493  return nullptr;
494  }
495  // get last person plan
496  const GNEDemandElement* lastPersonPlan = myCurrentDemandElement->getChildDemandElements().back();
497  // check tag
498  switch (lastPersonPlan->getTagProperty().getTag()) {
500  case GNE_TAG_WALK_EDGES:
504  return lastPersonPlan->getParentEdges().back();
509  return lastPersonPlan->getParentAdditionals().back()->getParentLanes().front()->getParentEdge();
510  case GNE_TAG_WALK_ROUTE:
511  return lastPersonPlan->getParentDemandElements().back()->getParentEdges().back();
512  default:
513  return nullptr;
514  }
515 }
516 
517 
518 long
520  // Check if value of myTypeMatchBox correspond to a demand element
521  for (const auto& i : myDemandElementTags) {
522  for (const auto& j : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(i)) {
523  if (j.first == myDemandElementsMatchBox->getText().text()) {
524  // set color of myTypeMatchBox to black (valid)
525  myDemandElementsMatchBox->setTextColor(FXRGB(0, 0, 0));
526  // Set new current demand element
527  myCurrentDemandElement = j.second;
528  // call demandElementSelected function
529  myFrameParent->demandElementSelected();
530  // Write Warning in console if we're in testing mode
531  WRITE_DEBUG(("Selected item '" + myDemandElementsMatchBox->getText() + "' in DemandElementSelector").text());
532  return 1;
533  }
534  }
535  }
536  // if demand element selected is invalid, set demand element as null
537  myCurrentDemandElement = nullptr;
538  // call demandElementSelected function
539  myFrameParent->demandElementSelected();
540  // change color of myDemandElementsMatchBox to red (invalid)
541  myDemandElementsMatchBox->setTextColor(FXRGB(255, 0, 0));
542  // Write Warning in console if we're in testing mode
543  WRITE_DEBUG("Selected invalid item in DemandElementSelector");
544  return 1;
545 }
546 
547 // ---------------------------------------------------------------------------
548 // GNEFrameModuls::HierarchicalElementTree - methods
549 // ---------------------------------------------------------------------------
550 
552  FXGroupBox(frameParent->myContentFrame, "Hierarchy", GUIDesignGroupBoxFrame),
553  myFrameParent(frameParent),
554  myHE(nullptr),
555  myClickedAC(nullptr),
556  myClickedJunction(nullptr),
557  myClickedEdge(nullptr),
558  myClickedLane(nullptr),
559  myClickedCrossing(nullptr),
560  myClickedConnection(nullptr),
561  myClickedShape(nullptr),
562  myClickedTAZElement(nullptr),
563  myClickedAdditional(nullptr),
564  myClickedDemandElement(nullptr),
565  myClickedDataSet(nullptr),
566  myClickedDataInterval(nullptr),
567  myClickedGenericData(nullptr) {
568  // Create three list
570  hide();
571 }
572 
573 
575 
576 
577 void
579  myHE = dynamic_cast<GNEHierarchicalElement*>(AC);
580  // show HierarchicalElementTree and refresh HierarchicalElementTree
581  if (myHE) {
582  show();
583  refreshHierarchicalElementTree();
584  }
585 }
586 
587 
588 void
590  // set all pointers null
591  myHE = nullptr;
592  myClickedAC = nullptr;
593  myClickedJunction = nullptr;
594  myClickedEdge = nullptr;
595  myClickedLane = nullptr;
596  myClickedCrossing = nullptr;
597  myClickedConnection = nullptr;
598  myClickedShape = nullptr;
599  myClickedTAZElement = nullptr;
600  myClickedAdditional = nullptr;
601  myClickedDemandElement = nullptr;
602  myClickedDataSet = nullptr;
603  myClickedDataInterval = nullptr;
604  myClickedGenericData = nullptr;
605  // hide modul
606  hide();
607 }
608 
609 
610 void
612  // clear items
613  myTreelist->clearItems();
614  myTreeItemToACMap.clear();
615  myTreeItemsConnections.clear();
616  // show children of myHE
617  if (myHE) {
618  showHierarchicalElementChildren(myHE, showAttributeCarrierParents());
619  }
620 }
621 
622 
623 void
625  // simply check if AC is the same of myHE
626  if (AC == myHE) {
627  myHE = nullptr;
628  }
629 }
630 
631 
632 long
633 GNEFrameModuls::HierarchicalElementTree::onCmdShowChildMenu(FXObject*, FXSelector, void* eventData) {
634  // Obtain event
635  FXEvent* e = (FXEvent*)eventData;
636  // obtain FXTreeItem in the given position
637  FXTreeItem* item = myTreelist->getItemAt(e->win_x, e->win_y);
638  // open Pop-up if FXTreeItem has a Attribute Carrier vinculated
639  if (item && (myTreeItemsConnections.find(item) == myTreeItemsConnections.end())) {
640  createPopUpMenu(e->root_x, e->root_y, myTreeItemToACMap[item]);
641  }
642  return 1;
643 }
644 
645 
646 long
648  // Center item
649  if (myClickedJunction) {
650  myFrameParent->myViewNet->centerTo(myClickedJunction->getGlID(), true, -1);
651  } else if (myClickedEdge) {
652  myFrameParent->myViewNet->centerTo(myClickedEdge->getGlID(), true, -1);
653  } else if (myClickedLane) {
654  myFrameParent->myViewNet->centerTo(myClickedLane->getGlID(), true, -1);
655  } else if (myClickedCrossing) {
656  myFrameParent->myViewNet->centerTo(myClickedCrossing->getGlID(), true, -1);
657  } else if (myClickedConnection) {
658  myFrameParent->myViewNet->centerTo(myClickedConnection->getGlID(), true, -1);
659  } else if (myClickedAdditional) {
660  myFrameParent->myViewNet->centerTo(myClickedAdditional->getGlID(), true, -1);
661  } else if (myClickedShape) {
662  myFrameParent->myViewNet->centerTo(myClickedShape->getGlID(), true, -1);
663  } else if (myClickedTAZElement) {
664  myFrameParent->myViewNet->centerTo(myClickedTAZElement->getGlID(), true, -1);
665  } else if (myClickedDemandElement) {
666  myFrameParent->myViewNet->centerTo(myClickedDemandElement->getGlID(), true, -1);
667  } else if (myClickedGenericData) {
668  myFrameParent->myViewNet->centerTo(myClickedGenericData->getGlID(), true, -1);
669  }
670  // update view after centering
671  myFrameParent->myViewNet->updateViewNet();
672  return 1;
673 }
674 
675 
676 long
678  if ((myHE != nullptr) && (myClickedAC != nullptr)) {
679  myFrameParent->myViewNet->getViewParent()->getInspectorFrame()->inspectChild(myClickedAC, myHE);
680  }
681  return 1;
682 }
683 
684 
685 long
687  // Remove Attribute Carrier
688  if (myClickedJunction) {
689  myFrameParent->myViewNet->getNet()->deleteJunction(myClickedJunction, myFrameParent->myViewNet->getUndoList());
690  } else if (myClickedEdge) {
691  myFrameParent->myViewNet->getNet()->deleteEdge(myClickedEdge, myFrameParent->myViewNet->getUndoList(), false);
692  } else if (myClickedLane) {
693  myFrameParent->myViewNet->getNet()->deleteLane(myClickedLane, myFrameParent->myViewNet->getUndoList(), false);
694  } else if (myClickedCrossing) {
695  myFrameParent->myViewNet->getNet()->deleteCrossing(myClickedCrossing, myFrameParent->myViewNet->getUndoList());
696  } else if (myClickedConnection) {
697  myFrameParent->myViewNet->getNet()->deleteConnection(myClickedConnection, myFrameParent->myViewNet->getUndoList());
698  } else if (myClickedAdditional) {
699  myFrameParent->myViewNet->getNet()->deleteAdditional(myClickedAdditional, myFrameParent->myViewNet->getUndoList());
700  } else if (myClickedShape) {
701  myFrameParent->myViewNet->getNet()->deleteShape(myClickedShape, myFrameParent->myViewNet->getUndoList());
702  } else if (myClickedTAZElement) {
703  myFrameParent->myViewNet->getNet()->deleteTAZElement(myClickedTAZElement, myFrameParent->myViewNet->getUndoList());
704  } else if (myClickedDemandElement) {
705  // check that default VTypes aren't removed
706  if ((myClickedDemandElement->getTagProperty().getTag() == SUMO_TAG_VTYPE) && (GNEAttributeCarrier::parse<bool>(myClickedDemandElement->getAttribute(GNE_ATTR_DEFAULT_VTYPE)))) {
707  WRITE_WARNING("Default Vehicle Type '" + myClickedDemandElement->getAttribute(SUMO_ATTR_ID) + "' cannot be removed");
708  return 1;
709  } else if (myClickedDemandElement->getTagProperty().isPersonPlan() && (myClickedDemandElement->getParentDemandElements().front()->getChildDemandElements().size() == 1)) {
710  // we need to check if we're removing the last person plan of a person.
711  myFrameParent->myViewNet->getNet()->deleteDemandElement(myClickedDemandElement->getParentDemandElements().front(), myFrameParent->myViewNet->getUndoList());
712  } else {
713  myFrameParent->myViewNet->getNet()->deleteDemandElement(myClickedDemandElement, myFrameParent->myViewNet->getUndoList());
714  }
715  } else if (myClickedDataSet) {
716  myFrameParent->myViewNet->getNet()->deleteDataSet(myClickedDataSet, myFrameParent->myViewNet->getUndoList());
717  } else if (myClickedDataInterval) {
718  // check if we have to remove data Set
719  if (myClickedDataInterval->getDataSetParent()->getDataIntervalChildren().size() == 1) {
720  myFrameParent->myViewNet->getNet()->deleteDataSet(myClickedDataInterval->getDataSetParent(), myFrameParent->myViewNet->getUndoList());
721  } else {
722  myFrameParent->myViewNet->getNet()->deleteDataInterval(myClickedDataInterval, myFrameParent->myViewNet->getUndoList());
723  }
724  } else if (myClickedGenericData) {
725  // check if we have to remove interval
726  if (myClickedGenericData->getDataIntervalParent()->getGenericDataChildren().size() == 1) {
727  // check if we have to remove data Set
728  if (myClickedGenericData->getDataIntervalParent()->getDataSetParent()->getDataIntervalChildren().size() == 1) {
729  myFrameParent->myViewNet->getNet()->deleteDataSet(myClickedGenericData->getDataIntervalParent()->getDataSetParent(), myFrameParent->myViewNet->getUndoList());
730  } else {
731  myFrameParent->myViewNet->getNet()->deleteDataInterval(myClickedGenericData->getDataIntervalParent(), myFrameParent->myViewNet->getUndoList());
732  }
733  } else {
734  myFrameParent->myViewNet->getNet()->deleteGenericData(myClickedGenericData, myFrameParent->myViewNet->getUndoList());
735  }
736  }
737  // update net
738  myFrameParent->myViewNet->updateViewNet();
739  // refresh AC Hierarchy
740  refreshHierarchicalElementTree();
741  // check if inspector frame has to be shown again
742  if (myFrameParent->myViewNet->getInspectedAttributeCarriers().size() == 1) {
743  if (myFrameParent->myViewNet->getInspectedAttributeCarriers().front() != myClickedAC) {
744  myFrameParent->myViewNet->getViewParent()->getInspectorFrame()->inspectSingleElement(myFrameParent->myViewNet->getInspectedAttributeCarriers().front());
745  } else {
746  // inspect a nullprt element to reset inspector frame
747  myFrameParent->myViewNet->getViewParent()->getInspectorFrame()->inspectSingleElement(nullptr);
748  }
749  }
750  return 1;
751 }
752 
753 
754 long
756  // currently only children of demand elements can be moved
757  if (myClickedDemandElement) {
758  myFrameParent->myViewNet->getUndoList()->p_begin(("moving up " + myClickedDemandElement->getTagStr()).c_str());
759  // move element one position back
760  myFrameParent->myViewNet->getUndoList()->add(new GNEChange_Children(myClickedDemandElement->getParentDemandElements().at(0), myClickedDemandElement,
761  GNEChange_Children::Operation::MOVE_BACK), true);
762  myFrameParent->myViewNet->getUndoList()->p_end();
763  }
764  // refresh after moving child
765  refreshHierarchicalElementTree();
766  return 1;
767 }
768 
769 
770 long
772  // currently only children of demand elements can be moved
773  if (myClickedDemandElement) {
774  myFrameParent->myViewNet->getUndoList()->p_begin(("moving down " + myClickedDemandElement->getTagStr()).c_str());
775  // move element one position front
776  myFrameParent->myViewNet->getUndoList()->add(new GNEChange_Children(myClickedDemandElement->getParentDemandElements().at(0), myClickedDemandElement,
777  GNEChange_Children::Operation::MOVE_FRONT), true);
778  myFrameParent->myViewNet->getUndoList()->p_end();
779  }
780  // refresh after moving child
781  refreshHierarchicalElementTree();
782  return 1;
783 }
784 
785 
786 void
788  // first check that AC exist
789  if (clickedAC) {
790  // set current clicked AC
791  myClickedAC = clickedAC;
792  // cast all elements
793  myClickedJunction = dynamic_cast<GNEJunction*>(clickedAC);
794  myClickedEdge = dynamic_cast<GNEEdge*>(clickedAC);
795  myClickedLane = dynamic_cast<GNELane*>(clickedAC);
796  myClickedCrossing = dynamic_cast<GNECrossing*>(clickedAC);
797  myClickedConnection = dynamic_cast<GNEConnection*>(clickedAC);
798  myClickedShape = dynamic_cast<GNEShape*>(clickedAC);
799  myClickedTAZElement = dynamic_cast<GNETAZElement*>(clickedAC);
800  myClickedAdditional = dynamic_cast<GNEAdditional*>(clickedAC);
801  myClickedDemandElement = dynamic_cast<GNEDemandElement*>(clickedAC);
802  myClickedDataSet = dynamic_cast<GNEDataSet*>(clickedAC);
803  myClickedDataInterval = dynamic_cast<GNEDataInterval*>(clickedAC);
804  myClickedGenericData = dynamic_cast<GNEGenericData*>(clickedAC);
805  // create FXMenuPane
806  FXMenuPane* pane = new FXMenuPane(myTreelist);
807  // set item name and icon
808  new MFXMenuHeader(pane, myFrameParent->myViewNet->getViewParent()->getGUIMainWindow()->getBoldFont(), myClickedAC->getPopUpID().c_str(), myClickedAC->getIcon());
809  // insert separator
810  new FXMenuSeparator(pane);
811  // create center menu command
812  FXMenuCommand* centerMenuCommand = GUIDesigns::buildFXMenuCommand(pane, "Center", GUIIconSubSys::getIcon(GUIIcon::RECENTERVIEW), this, MID_GNE_CENTER);
813  // disable Centering for Vehicle Types, data sets and data intervals
814  if (myClickedAC->getTagProperty().isVehicleType() || (myClickedAC->getTagProperty().getTag() == SUMO_TAG_DATASET) ||
815  (myClickedAC->getTagProperty().getTag() == SUMO_TAG_DATAINTERVAL)) {
816  centerMenuCommand->disable();
817  }
818  // create inspect and delete menu commands
819  FXMenuCommand* inspectMenuCommand = GUIDesigns::buildFXMenuCommand(pane, "Inspect", GUIIconSubSys::getIcon(GUIIcon::MODEINSPECT), this, MID_GNE_INSPECT);
820  FXMenuCommand* deleteMenuCommand = GUIDesigns::buildFXMenuCommand(pane, "Delete", GUIIconSubSys::getIcon(GUIIcon::MODEDELETE), this, MID_GNE_DELETE);
821  // check if inspect and delete menu commands has to be disabled
822  if (GNEFrameAttributesModuls::isSupermodeValid(myFrameParent->myViewNet, myClickedAC) == false) {
823  inspectMenuCommand->disable();
824  deleteMenuCommand->disable();
825  }
826  // now chec if given AC support manually moving of their item up and down (Currently only for certain demand elements)
827  /* if (myClickedDemandElement && myClickedAC->getTagProperty().canBeSortedManually()) {
828  // insert separator
829  new FXMenuSeparator(pane);
830  // create both moving menu commands
831  FXMenuCommand* moveUpMenuCommand = GUIDesigns::buildFXMenuCommand(pane, "Move up", GUIIconSubSys::getIcon(GUIIcon::ARROW_UP), this, MID_GNE_ACHIERARCHY_MOVEUP);
832  FXMenuCommand* moveDownMenuCommand = GUIDesigns::buildFXMenuCommand(pane, "Move down", GUIIconSubSys::getIcon(GUIIcon::ARROW_DOWN), this, MID_GNE_ACHIERARCHY_MOVEDOWN);
833  // check if both commands has to be disabled
834  if (myClickedDemandElement->getTagProperty().isPersonStop()) {
835  moveUpMenuCommand->setText("Move up (Stops cannot be moved)");
836  moveDownMenuCommand->setText("Move down (Stops cannot be moved)");
837  moveUpMenuCommand->disable();
838  moveDownMenuCommand->disable();
839  } else {
840  // check if moveUpMenuCommand has to be disabled
841  if (myClickedDemandElement->getParentDemandElements().front()->getChildDemandElements().front() == myClickedDemandElement) {
842  moveUpMenuCommand->setText("Move up (It's already the first element)");
843  moveUpMenuCommand->disable();
844  } else if (myClickedDemandElement->getParentDemandElements().front()->getPreviousChildDemandElement(myClickedDemandElement)->getTagProperty().isPersonStop()) {
845  moveUpMenuCommand->setText("Move up (Previous element is a Stop)");
846  moveUpMenuCommand->disable();
847  }
848  // check if moveDownMenuCommand has to be disabled
849  if (myClickedDemandElement->getParentDemandElements().front()->getChildDemandElements().back() == myClickedDemandElement) {
850  moveDownMenuCommand->setText("Move down (It's already the last element)");
851  moveDownMenuCommand->disable();
852  } else if (myClickedDemandElement->getParentDemandElements().front()->getNextChildDemandElement(myClickedDemandElement)->getTagProperty().isPersonStop()) {
853  moveDownMenuCommand->setText("Move down (Next element is a Stop)");
854  moveDownMenuCommand->disable();
855  }
856  }
857  } */
858  // Center in the mouse position and create pane
859  pane->setX(X);
860  pane->setY(Y);
861  pane->create();
862  pane->show();
863  } else {
864  // set all clicked elements to null
865  myClickedAC = nullptr;
866  myClickedJunction = nullptr;
867  myClickedEdge = nullptr;
868  myClickedLane = nullptr;
869  myClickedCrossing = nullptr;
870  myClickedConnection = nullptr;
871  myClickedShape = nullptr;
872  myClickedTAZElement = nullptr;
873  myClickedAdditional = nullptr;
874  myClickedDemandElement = nullptr;
875  myClickedDataSet = nullptr;
876  myClickedDataInterval = nullptr;
877  myClickedGenericData = nullptr;
878  }
879 }
880 
881 
882 FXTreeItem*
884  if (myHE->getTagProperty().isNetworkElement()) {
885  // check demand element type
886  switch (myHE->getTagProperty().getTag()) {
887  case SUMO_TAG_EDGE: {
888  // obtain Edge
889  GNEEdge* edge = myFrameParent->myViewNet->getNet()->retrieveEdge(myHE->getID(), false);
890  if (edge) {
891  // insert Junctions of edge in tree (Pararell because a edge has always two Junctions)
892  FXTreeItem* junctionSourceItem = myTreelist->insertItem(nullptr, nullptr, (edge->getParentJunctions().front()->getHierarchyName() + " origin").c_str(), edge->getParentJunctions().front()->getIcon(), edge->getParentJunctions().front()->getIcon());
893  FXTreeItem* junctionDestinyItem = myTreelist->insertItem(nullptr, nullptr, (edge->getParentJunctions().front()->getHierarchyName() + " destiny").c_str(), edge->getParentJunctions().front()->getIcon(), edge->getParentJunctions().front()->getIcon());
894  junctionDestinyItem->setExpanded(true);
895  // Save items in myTreeItemToACMap
896  myTreeItemToACMap[junctionSourceItem] = edge->getParentJunctions().front();
897  myTreeItemToACMap[junctionDestinyItem] = edge->getParentJunctions().back();
898  // return junction destiny Item
899  return junctionDestinyItem;
900  } else {
901  return nullptr;
902  }
903  }
904  case SUMO_TAG_LANE: {
905  // obtain lane
906  GNELane* lane = myFrameParent->myViewNet->getNet()->retrieveLane(myHE->getID(), false);
907  if (lane) {
908  // obtain parent edge
909  GNEEdge* edge = myFrameParent->myViewNet->getNet()->retrieveEdge(lane->getParentEdge()->getID());
910  //inser Junctions of lane of edge in tree (Pararell because a edge has always two Junctions)
911  FXTreeItem* junctionSourceItem = myTreelist->insertItem(nullptr, nullptr, (edge->getParentJunctions().front()->getHierarchyName() + " origin").c_str(), edge->getParentJunctions().front()->getIcon(), edge->getParentJunctions().front()->getIcon());
912  FXTreeItem* junctionDestinyItem = myTreelist->insertItem(nullptr, nullptr, (edge->getParentJunctions().front()->getHierarchyName() + " destiny").c_str(), edge->getParentJunctions().front()->getIcon(), edge->getParentJunctions().front()->getIcon());
913  junctionDestinyItem->setExpanded(true);
914  // Create edge item
915  FXTreeItem* edgeItem = myTreelist->insertItem(nullptr, junctionDestinyItem, edge->getHierarchyName().c_str(), edge->getIcon(), edge->getIcon());
916  edgeItem->setExpanded(true);
917  // Save items in myTreeItemToACMap
918  myTreeItemToACMap[junctionSourceItem] = edge->getParentJunctions().front();
919  myTreeItemToACMap[junctionDestinyItem] = edge->getParentJunctions().back();
920  myTreeItemToACMap[edgeItem] = edge;
921  // return edge item
922  return edgeItem;
923  } else {
924  return nullptr;
925  }
926  }
927  case SUMO_TAG_CROSSING: {
928  // obtain Crossing
929  GNECrossing* crossing = myFrameParent->myViewNet->getNet()->retrieveCrossing(myHE->getID(), false);
930  if (crossing) {
931  // obtain junction
932  GNEJunction* junction = crossing->getParentJunction();
933  // create junction item
934  FXTreeItem* junctionItem = myTreelist->insertItem(nullptr, nullptr, junction->getHierarchyName().c_str(), junction->getIcon(), junction->getIcon());
935  junctionItem->setExpanded(true);
936  // Save items in myTreeItemToACMap
937  myTreeItemToACMap[junctionItem] = junction;
938  // return junction Item
939  return junctionItem;
940  } else {
941  return nullptr;
942  }
943  }
944  case SUMO_TAG_CONNECTION: {
945  // obtain Connection
946  GNEConnection* connection = myFrameParent->myViewNet->getNet()->retrieveConnection(myHE->getID(), false);
947  if (connection) {
948  // create edge from item
949  FXTreeItem* edgeFromItem = myTreelist->insertItem(nullptr, nullptr, connection->getEdgeFrom()->getHierarchyName().c_str(), connection->getEdgeFrom()->getIcon(), connection->getEdgeFrom()->getIcon());
950  edgeFromItem->setExpanded(true);
951  // create edge to item
952  FXTreeItem* edgeToItem = myTreelist->insertItem(nullptr, nullptr, connection->getEdgeTo()->getHierarchyName().c_str(), connection->getEdgeTo()->getIcon(), connection->getEdgeTo()->getIcon());
953  edgeToItem->setExpanded(true);
954  // create connection item
955  FXTreeItem* connectionItem = myTreelist->insertItem(nullptr, edgeToItem, connection->getHierarchyName().c_str(), connection->getIcon(), connection->getIcon());
956  connectionItem->setExpanded(true);
957  // Save items in myTreeItemToACMap
958  myTreeItemToACMap[edgeFromItem] = connection->getEdgeFrom();
959  myTreeItemToACMap[edgeToItem] = connection->getEdgeTo();
960  myTreeItemToACMap[connectionItem] = connection;
961  // return connection item
962  return connectionItem;
963  } else {
964  return nullptr;
965  }
966  }
967  default:
968  break;
969  }
970  } else if (myHE->getTagProperty().getTag() == SUMO_TAG_POILANE) {
971  // Obtain POILane
972  GNEShape* POILane = myFrameParent->myViewNet->getNet()->retrieveShape(SUMO_TAG_POILANE, myHE->getID(), false);
973  if (POILane) {
974  // obtain parent lane
975  GNELane* lane = myFrameParent->myViewNet->getNet()->retrieveLane(POILane->getParentLanes().at(0)->getID());
976  // obtain parent edge
977  GNEEdge* edge = myFrameParent->myViewNet->getNet()->retrieveEdge(lane->getParentEdge()->getID());
978  //inser Junctions of lane of edge in tree (Pararell because a edge has always two Junctions)
979  FXTreeItem* junctionSourceItem = myTreelist->insertItem(nullptr, nullptr, (edge->getParentJunctions().front()->getHierarchyName() + " origin").c_str(), edge->getParentJunctions().front()->getIcon(), edge->getParentJunctions().front()->getIcon());
980  FXTreeItem* junctionDestinyItem = myTreelist->insertItem(nullptr, nullptr, (edge->getParentJunctions().front()->getHierarchyName() + " destiny").c_str(), edge->getParentJunctions().front()->getIcon(), edge->getParentJunctions().front()->getIcon());
981  junctionDestinyItem->setExpanded(true);
982  // Create edge item
983  FXTreeItem* edgeItem = myTreelist->insertItem(nullptr, junctionDestinyItem, edge->getHierarchyName().c_str(), edge->getIcon(), edge->getIcon());
984  edgeItem->setExpanded(true);
985  // Create lane item
986  FXTreeItem* laneItem = myTreelist->insertItem(nullptr, edgeItem, lane->getHierarchyName().c_str(), lane->getIcon(), lane->getIcon());
987  laneItem->setExpanded(true);
988  // Save items in myTreeItemToACMap
989  myTreeItemToACMap[junctionSourceItem] = edge->getParentJunctions().front();
990  myTreeItemToACMap[junctionDestinyItem] = edge->getParentJunctions().back();
991  myTreeItemToACMap[edgeItem] = edge;
992  myTreeItemToACMap[laneItem] = lane;
993  // return Lane item
994  return laneItem;
995  } else {
996  return nullptr;
997  }
998  } else if (myHE->getTagProperty().isAdditionalElement()) {
999  // Obtain Additional
1000  GNEAdditional* additional = myFrameParent->myViewNet->getNet()->retrieveAdditional(myHE->getTagProperty().getTag(), myHE->getID(), false);
1001  if (additional) {
1002  // declare auxiliar FXTreeItem, due a demand element can have multiple "roots"
1003  FXTreeItem* root = nullptr;
1004  // check if there is demand elements parents
1005  if (additional->getParentAdditionals().size() > 0) {
1006  // check if we have more than one edge
1007  if (additional->getParentAdditionals().size() > 1) {
1008  // insert first item
1009  addListItem(additional->getParentAdditionals().front());
1010  // insert "spacer"
1011  if (additional->getParentAdditionals().size() > 2) {
1012  addListItem(nullptr, ("..." + toString((int)additional->getParentAdditionals().size() - 2) + " additionals...").c_str(), 0, false);
1013  }
1014  }
1015  // return last inserted item
1016  root = addListItem(additional->getParentAdditionals().back());
1017  }
1018  // check if there is parent demand elements
1019  if (additional->getParentDemandElements().size() > 0) {
1020  // check if we have more than one demand element
1021  if (additional->getParentDemandElements().size() > 1) {
1022  // insert first item
1023  addListItem(additional->getParentDemandElements().front());
1024  // insert "spacer"
1025  if (additional->getParentDemandElements().size() > 2) {
1026  addListItem(nullptr, ("..." + toString((int)additional->getParentDemandElements().size() - 2) + " demand elements...").c_str(), 0, false);
1027  }
1028  }
1029  // return last inserted item
1030  root = addListItem(additional->getParentDemandElements().back());
1031  }
1032  // check if there is parent edges
1033  if (additional->getParentEdges().size() > 0) {
1034  // check if we have more than one edge
1035  if (additional->getParentEdges().size() > 1) {
1036  // insert first item
1037  addListItem(additional->getParentEdges().front());
1038  // insert "spacer"
1039  if (additional->getParentEdges().size() > 2) {
1040  addListItem(nullptr, ("..." + toString((int)additional->getParentEdges().size() - 2) + " edges...").c_str(), 0, false);
1041  }
1042  }
1043  // return last inserted item
1044  root = addListItem(additional->getParentEdges().back());
1045  }
1046  // check if there is parent lanes
1047  if (additional->getParentLanes().size() > 0) {
1048  // check if we have more than one parent lane
1049  if (additional->getParentLanes().size() > 1) {
1050  // insert first item
1051  addListItem(additional->getParentLanes().front());
1052  // insert "spacer"
1053  if (additional->getParentLanes().size() > 2) {
1054  addListItem(nullptr, ("..." + toString((int)additional->getParentLanes().size() - 2) + " lanes...").c_str(), 0, false);
1055  }
1056  }
1057  // return last inserted item
1058  root = addListItem(additional->getParentLanes().back());
1059  }
1060  // return last inserted list item
1061  return root;
1062  }
1063  } else if (myHE->getTagProperty().isTAZElement()) {
1064  // Obtain TAZElement
1065  GNETAZElement* TAZElement = myFrameParent->myViewNet->getNet()->retrieveTAZElement(myHE->getTagProperty().getTag(), myHE->getID(), false);
1066  if (TAZElement) {
1067  // declare auxiliar FXTreeItem, due a demand element can have multiple "roots"
1068  FXTreeItem* root = nullptr;
1069  // check if there is demand elements parents
1070  if (TAZElement->getParentTAZElements().size() > 0) {
1071  // check if we have more than one edge
1072  if (TAZElement->getParentTAZElements().size() > 1) {
1073  // insert first item
1074  addListItem(TAZElement->getParentTAZElements().front());
1075  // insert "spacer"
1076  if (TAZElement->getParentTAZElements().size() > 2) {
1077  addListItem(nullptr, ("..." + toString((int)TAZElement->getParentTAZElements().size() - 2) + " TAZElements...").c_str(), 0, false);
1078  }
1079  }
1080  // return last inserted item
1081  root = addListItem(TAZElement->getParentTAZElements().back());
1082  }
1083  // check if there is parent demand elements
1084  if (TAZElement->getParentDemandElements().size() > 0) {
1085  // check if we have more than one demand element
1086  if (TAZElement->getParentDemandElements().size() > 1) {
1087  // insert first item
1088  addListItem(TAZElement->getParentDemandElements().front());
1089  // insert "spacer"
1090  if (TAZElement->getParentDemandElements().size() > 2) {
1091  addListItem(nullptr, ("..." + toString((int)TAZElement->getParentDemandElements().size() - 2) + " demand elements...").c_str(), 0, false);
1092  }
1093  }
1094  // return last inserted item
1095  root = addListItem(TAZElement->getParentDemandElements().back());
1096  }
1097  // check if there is parent edges
1098  if (TAZElement->getParentEdges().size() > 0) {
1099  // check if we have more than one edge
1100  if (TAZElement->getParentEdges().size() > 1) {
1101  // insert first item
1102  addListItem(TAZElement->getParentEdges().front());
1103  // insert "spacer"
1104  if (TAZElement->getParentEdges().size() > 2) {
1105  addListItem(nullptr, ("..." + toString((int)TAZElement->getParentEdges().size() - 2) + " edges...").c_str(), 0, false);
1106  }
1107  }
1108  // return last inserted item
1109  root = addListItem(TAZElement->getParentEdges().back());
1110  }
1111  // check if there is parent lanes
1112  if (TAZElement->getParentLanes().size() > 0) {
1113  // check if we have more than one parent lane
1114  if (TAZElement->getParentLanes().size() > 1) {
1115  // insert first item
1116  addListItem(TAZElement->getParentLanes().front());
1117  // insert "spacer"
1118  if (TAZElement->getParentLanes().size() > 2) {
1119  addListItem(nullptr, ("..." + toString((int)TAZElement->getParentLanes().size() - 2) + " lanes...").c_str(), 0, false);
1120  }
1121  }
1122  // return last inserted item
1123  root = addListItem(TAZElement->getParentLanes().back());
1124  }
1125  // return last inserted list item
1126  return root;
1127  }
1128  } else if (myHE->getTagProperty().isDemandElement()) {
1129  // Obtain DemandElement
1130  GNEDemandElement* demandElement = myFrameParent->myViewNet->getNet()->retrieveDemandElement(myHE->getTagProperty().getTag(), myHE->getID(), false);
1131  if (demandElement) {
1132  // declare auxiliar FXTreeItem, due a demand element can have multiple "roots"
1133  FXTreeItem* root = nullptr;
1134  // check if there is demand elements parents
1135  if (demandElement->getParentAdditionals().size() > 0) {
1136  // check if we have more than one edge
1137  if (demandElement->getParentAdditionals().size() > 1) {
1138  // insert first item
1139  addListItem(demandElement->getParentAdditionals().front());
1140  // insert "spacer"
1141  if (demandElement->getParentAdditionals().size() > 2) {
1142  addListItem(nullptr, ("..." + toString((int)demandElement->getParentAdditionals().size() - 2) + " additionals...").c_str(), 0, false);
1143  }
1144  }
1145  // return last inserted item
1146  root = addListItem(demandElement->getParentAdditionals().back());
1147  }
1148  // check if there is parent demand elements
1149  if (demandElement->getParentDemandElements().size() > 0) {
1150  // check if we have more than one demand element
1151  if (demandElement->getParentDemandElements().size() > 1) {
1152  // insert first item
1153  addListItem(demandElement->getParentDemandElements().front());
1154  // insert "spacer"
1155  if (demandElement->getParentDemandElements().size() > 2) {
1156  addListItem(nullptr, ("..." + toString((int)demandElement->getParentDemandElements().size() - 2) + " demand elements...").c_str(), 0, false);
1157  }
1158  }
1159  // return last inserted item
1160  root = addListItem(demandElement->getParentDemandElements().back());
1161  }
1162  // check if there is parent edges
1163  if (demandElement->getParentEdges().size() > 0) {
1164  // check if we have more than one edge
1165  if (demandElement->getParentEdges().size() > 1) {
1166  // insert first item
1167  addListItem(demandElement->getParentEdges().front());
1168  // insert "spacer"
1169  if (demandElement->getParentEdges().size() > 2) {
1170  addListItem(nullptr, ("..." + toString((int)demandElement->getParentEdges().size() - 2) + " edges...").c_str(), 0, false);
1171  }
1172  }
1173  // return last inserted item
1174  root = addListItem(demandElement->getParentEdges().back());
1175  }
1176  // check if there is parent lanes
1177  if (demandElement->getParentLanes().size() > 0) {
1178  // check if we have more than one parent lane
1179  if (demandElement->getParentLanes().size() > 1) {
1180  // insert first item
1181  addListItem(demandElement->getParentLanes().front());
1182  // insert "spacer"
1183  if (demandElement->getParentLanes().size() > 2) {
1184  addListItem(nullptr, ("..." + toString((int)demandElement->getParentLanes().size() - 2) + " lanes...").c_str(), 0, false);
1185  }
1186  }
1187  // return last inserted item
1188  root = addListItem(demandElement->getParentLanes().back());
1189  }
1190  // return last inserted list item
1191  return root;
1192  }
1193 
1194  } else if (myHE->getTagProperty().isDataElement()) {
1195  // check if is a GNEDataInterval or a GNEGenericData
1196  if (myHE->getTagProperty().getTag() == SUMO_TAG_DATASET) {
1197  return nullptr;
1198  } else if (myHE->getTagProperty().getTag() == SUMO_TAG_DATAINTERVAL) {
1199  return addListItem(myFrameParent->myViewNet->getNet()->retrieveDataSet(myHE->getID()));
1200  } else {
1201  // Obtain DataElement
1202  GNEGenericData* dataElement = dynamic_cast<GNEGenericData*>(myHE);
1203  if (dataElement) {
1204  // declare auxiliar FXTreeItem, due a data element can have multiple "roots"
1205  FXTreeItem* root = nullptr;
1206  // set dataset
1207  addListItem(dataElement->getDataIntervalParent()->getDataSetParent());
1208  // set data interval
1209  addListItem(dataElement->getDataIntervalParent());
1210  // check if there is data elements parents
1211  if (dataElement->getParentAdditionals().size() > 0) {
1212  // check if we have more than one edge
1213  if (dataElement->getParentAdditionals().size() > 1) {
1214  // insert first item
1215  addListItem(dataElement->getParentAdditionals().front());
1216  // insert "spacer"
1217  if (dataElement->getParentAdditionals().size() > 2) {
1218  addListItem(nullptr, ("..." + toString((int)dataElement->getParentAdditionals().size() - 2) + " additionals...").c_str(), 0, false);
1219  }
1220  }
1221  // return last inserted item
1222  root = addListItem(dataElement->getParentAdditionals().back());
1223  }
1224  // check if there is parent demand elements
1225  if (dataElement->getParentDemandElements().size() > 0) {
1226  // check if we have more than one demand element
1227  if (dataElement->getParentDemandElements().size() > 1) {
1228  // insert first item
1229  addListItem(dataElement->getParentDemandElements().front());
1230  // insert "spacer"
1231  if (dataElement->getParentDemandElements().size() > 2) {
1232  addListItem(nullptr, ("..." + toString((int)dataElement->getParentDemandElements().size() - 2) + " demand elements...").c_str(), 0, false);
1233  }
1234  }
1235  // return last inserted item
1236  root = addListItem(dataElement->getParentDemandElements().back());
1237  }
1238  // check if there is parent edges
1239  if (dataElement->getParentEdges().size() > 0) {
1240  // check if we have more than one edge
1241  if (dataElement->getParentEdges().size() > 1) {
1242  // insert first ege
1243  if (dataElement->getTagProperty().getTag() == SUMO_TAG_EDGEREL) {
1244  addListItem(dataElement->getParentEdges().front(), nullptr, "from ");
1245  } else {
1246  addListItem(dataElement->getParentEdges().front());
1247  }
1248  // insert "spacer"
1249  if (dataElement->getParentEdges().size() > 2) {
1250  addListItem(nullptr, ("..." + toString((int)dataElement->getParentEdges().size() - 2) + " edges...").c_str(), 0, false);
1251  }
1252  }
1253  // insert last ege
1254  if (dataElement->getTagProperty().getTag() == SUMO_TAG_EDGEREL) {
1255  addListItem(dataElement->getParentEdges().back(), nullptr, "to ");
1256  } else {
1257  addListItem(dataElement->getParentEdges().back());
1258  }
1259  }
1260  // check if there is parent lanes
1261  if (dataElement->getParentLanes().size() > 0) {
1262  // check if we have more than one parent lane
1263  if (dataElement->getParentLanes().size() > 1) {
1264  // insert first item
1265  addListItem(dataElement->getParentLanes().front());
1266  // insert "spacer"
1267  if (dataElement->getParentLanes().size() > 2) {
1268  addListItem(nullptr, ("..." + toString((int)dataElement->getParentLanes().size() - 2) + " lanes...").c_str(), 0, false);
1269  }
1270  }
1271  // return last inserted item
1272  root = addListItem(dataElement->getParentLanes().back());
1273  }
1274  // return last inserted list item
1275  return root;
1276  }
1277  }
1278  }
1279  // there aren't parents
1280  return nullptr;
1281 }
1282 
1283 
1284 void
1286  if (HE->getTagProperty().isNetworkElement()) {
1287  // Switch gl type of ac
1288  switch (HE->getTagProperty().getTag()) {
1289  case SUMO_TAG_JUNCTION: {
1290  // retrieve junction
1291  GNEJunction* junction = myFrameParent->myViewNet->getNet()->retrieveJunction(HE->getID(), false);
1292  if (junction) {
1293  // insert junction item
1294  FXTreeItem* junctionItem = addListItem(HE, itemParent);
1295  // insert edges
1296  for (auto i : junction->getChildEdges()) {
1297  showHierarchicalElementChildren(i, junctionItem);
1298  }
1299  // insert crossings
1300  for (auto i : junction->getGNECrossings()) {
1301  showHierarchicalElementChildren(i, junctionItem);
1302  }
1303  }
1304  break;
1305  }
1306  case SUMO_TAG_EDGE: {
1307  // retrieve edge
1308  GNEEdge* edge = myFrameParent->myViewNet->getNet()->retrieveEdge(HE->getID(), false);
1309  if (edge) {
1310  // insert edge item
1311  FXTreeItem* edgeItem = addListItem(HE, itemParent);
1312  // insert lanes
1313  for (const auto& i : edge->getLanes()) {
1314  showHierarchicalElementChildren(i, edgeItem);
1315  }
1316  // insert child additional
1317  for (const auto& i : edge->getChildAdditionals()) {
1318  showHierarchicalElementChildren(i, edgeItem);
1319  }
1320  // insert child shapes
1321  for (const auto& i : edge->getChildShapes()) {
1322  showHierarchicalElementChildren(i, edgeItem);
1323  }
1324  // insert child TAZElements
1325  for (const auto& i : edge->getChildTAZElements()) {
1326  showHierarchicalElementChildren(i, edgeItem);
1327  }
1328  // insert child demand elements
1329  for (const auto& i : edge->getChildDemandElements()) {
1330  showHierarchicalElementChildren(i, edgeItem);
1331  }
1332  /*
1333 
1334  CHECK THIS
1335 
1336  // insert demand elements children (note: use getChildDemandElementsSortedByType to avoid duplicated elements)
1337  for (const auto& i : edge->getChildDemandElementsByType(SUMO_TAG_ROUTE)) {
1338  showHierarchicalElementChildren(i, edgeItem);
1339  }
1340  for (const auto& i : edge->getChildDemandElementsByType(SUMO_TAG_TRIP)) {
1341  showHierarchicalElementChildren(i, edgeItem);
1342  }
1343  for (const auto& i : edge->getChildDemandElementsByType(SUMO_TAG_FLOW)) {
1344  showHierarchicalElementChildren(i, edgeItem);
1345  }
1346  */
1347  // show data elements
1348  for (const auto& i : edge->getChildGenericDatas()) {
1349  showHierarchicalElementChildren(i, edgeItem);
1350  }
1351  }
1352  break;
1353  }
1354  case SUMO_TAG_LANE: {
1355  // retrieve lane
1356  GNELane* lane = myFrameParent->myViewNet->getNet()->retrieveLane(HE->getID(), false);
1357  if (lane) {
1358  // insert lane item
1359  FXTreeItem* laneItem = addListItem(HE, itemParent);
1360  // insert child additional
1361  for (const auto& i : lane->getChildAdditionals()) {
1362  showHierarchicalElementChildren(i, laneItem);
1363  }
1364  // insert child shapes
1365  for (const auto& i : lane->getChildShapes()) {
1366  showHierarchicalElementChildren(i, laneItem);
1367  }
1368  // insert child TAZElements
1369  for (const auto& i : lane->getChildTAZElements()) {
1370  showHierarchicalElementChildren(i, laneItem);
1371  }
1372  // insert demand elements children
1373  for (const auto& i : lane->getChildDemandElements()) {
1374  showHierarchicalElementChildren(i, laneItem);
1375  }
1376  // insert incoming connections of lanes (by default isn't expanded)
1377  if (lane->getGNEIncomingConnections().size() > 0) {
1378  std::vector<GNEConnection*> incomingLaneConnections = lane->getGNEIncomingConnections();
1379  // insert intermediate list item
1380  FXTreeItem* incomingConnections = addListItem(laneItem, "Incomings", incomingLaneConnections.front()->getIcon(), false);
1381  // insert incoming connections
1382  for (auto i : incomingLaneConnections) {
1383  showHierarchicalElementChildren(i, incomingConnections);
1384  }
1385  }
1386  // insert outcoming connections of lanes (by default isn't expanded)
1387  if (lane->getGNEOutcomingConnections().size() > 0) {
1388  std::vector<GNEConnection*> outcomingLaneConnections = lane->getGNEOutcomingConnections();
1389  // insert intermediate list item
1390  FXTreeItem* outgoingConnections = addListItem(laneItem, "Outgoing", outcomingLaneConnections.front()->getIcon(), false);
1391  // insert outcoming connections
1392  for (auto i : outcomingLaneConnections) {
1393  showHierarchicalElementChildren(i, outgoingConnections);
1394  }
1395  }
1396  }
1397  break;
1398  }
1399  case SUMO_TAG_CROSSING:
1400  case SUMO_TAG_CONNECTION: {
1401  // insert connection item
1402  addListItem(HE, itemParent);
1403  break;
1404  }
1405  default:
1406  break;
1407  }
1409  // insert additional item
1410  FXTreeItem* treeItem = addListItem(HE, itemParent);
1411  // insert child edges
1412  for (const auto& i : HE->getChildEdges()) {
1413  showHierarchicalElementChildren(i, treeItem);
1414  }
1415  // insert child lanes
1416  for (const auto& i : HE->getChildLanes()) {
1417  showHierarchicalElementChildren(i, treeItem);
1418  }
1419  // insert additional children
1420  for (const auto& i : HE->getChildAdditionals()) {
1421  showHierarchicalElementChildren(i, treeItem);
1422  }
1423  // insert child shapes
1424  for (const auto& i : HE->getChildShapes()) {
1425  showHierarchicalElementChildren(i, treeItem);
1426  }
1427  // insert TAZElements children
1428  for (const auto& i : HE->getChildTAZElements()) {
1429  showHierarchicalElementChildren(i, treeItem);
1430  }
1431  // insert child demand elements
1432  for (const auto& i : HE->getChildDemandElements()) {
1433  showHierarchicalElementChildren(i, treeItem);
1434  }
1435  } else if (HE->getTagProperty().isDataElement()) {
1436  // insert data item
1437  FXTreeItem* dataElementItem = addListItem(HE, itemParent);
1438  // insert intervals
1439  if (HE->getTagProperty().getTag() == SUMO_TAG_DATASET) {
1440  GNEDataSet* dataSet = myFrameParent->myViewNet->getNet()->retrieveDataSet(HE->getID());
1441  // iterate over intevals
1442  for (const auto& interval : dataSet->getDataIntervalChildren()) {
1443  showHierarchicalElementChildren(interval.second, dataElementItem);
1444  }
1445  } else if (HE->getTagProperty().getTag() == SUMO_TAG_DATAINTERVAL) {
1446  GNEDataInterval* dataInterval = dynamic_cast<GNEDataInterval*>(HE);
1447  // iterate over generic datas
1448  for (const auto& genericData : dataInterval->getGenericDataChildren()) {
1449  showHierarchicalElementChildren(genericData, dataElementItem);
1450  }
1451  }
1452  }
1453 }
1454 
1455 
1456 FXTreeItem*
1457 GNEFrameModuls::HierarchicalElementTree::addListItem(GNEAttributeCarrier* AC, FXTreeItem* itemParent, std::string prefix, std::string sufix) {
1458  // insert item in Tree list
1459  FXTreeItem* item = myTreelist->insertItem(nullptr, itemParent, (prefix + AC->getHierarchyName() + sufix).c_str(), AC->getIcon(), AC->getIcon());
1460  // insert item in map
1461  myTreeItemToACMap[item] = AC;
1462  // by default item is expanded
1463  item->setExpanded(true);
1464  // return created FXTreeItem
1465  return item;
1466 }
1467 
1468 
1469 FXTreeItem*
1470 GNEFrameModuls::HierarchicalElementTree::addListItem(FXTreeItem* itemParent, const std::string& text, FXIcon* icon, bool expanded) {
1471  // insert item in Tree list
1472  FXTreeItem* item = myTreelist->insertItem(nullptr, itemParent, text.c_str(), icon, icon);
1473  // expand item depending of flag expanded
1474  item->setExpanded(expanded);
1475  // return created FXTreeItem
1476  return item;
1477 }
1478 
1479 // ---------------------------------------------------------------------------
1480 // GNEFrameModuls::DrawingShape - methods
1481 // ---------------------------------------------------------------------------
1482 
1484  FXGroupBox(frameParent->myContentFrame, "Drawing", GUIDesignGroupBoxFrame),
1485  myFrameParent(frameParent),
1486  myDeleteLastCreatedPoint(false) {
1487  // create start and stop buttons
1488  myStartDrawingButton = new FXButton(this, "Start drawing", 0, this, MID_GNE_STARTDRAWING, GUIDesignButton);
1489  myStopDrawingButton = new FXButton(this, "Stop drawing", 0, this, MID_GNE_STOPDRAWING, GUIDesignButton);
1490  myAbortDrawingButton = new FXButton(this, "Abort drawing", 0, this, MID_GNE_ABORTDRAWING, GUIDesignButton);
1491  // create information label
1492  std::ostringstream information;
1493  information
1494  << "- 'Start drawing' or ENTER\n"
1495  << " to create shape.\n"
1496  << "- 'Stop drawing' or ESC to\n"
1497  << " abort shape creation.\n"
1498  << "- 'Shift + Click' to remove\n"
1499  << " last inserted point.";
1500  myInformationLabel = new FXLabel(this, information.str().c_str(), 0, GUIDesignLabelFrameInformation);
1501  // disable stop and abort functions as init
1502  myStopDrawingButton->disable();
1503  myAbortDrawingButton->disable();
1504 }
1505 
1506 
1508 
1509 
1511  // abort current drawing before show
1512  abortDrawing();
1513  // show FXGroupBox
1514  FXGroupBox::show();
1515 }
1516 
1517 
1519  // abort current drawing before hide
1520  abortDrawing();
1521  // show FXGroupBox
1522  FXGroupBox::hide();
1523 }
1524 
1525 
1526 void
1528  // Only start drawing if DrawingShape modul is shown
1529  if (shown()) {
1530  // change buttons
1531  myStartDrawingButton->disable();
1532  myStopDrawingButton->enable();
1533  myAbortDrawingButton->enable();
1534  }
1535 }
1536 
1537 
1538 void
1540  // try to build shape
1541  if (myFrameParent->shapeDrawed()) {
1542  // clear created points
1543  myTemporalShape.clear();
1544  // change buttons
1545  myStartDrawingButton->enable();
1546  myStopDrawingButton->disable();
1547  myAbortDrawingButton->disable();
1548  } else {
1549  // abort drawing if shape cannot be created
1550  abortDrawing();
1551  }
1552 }
1553 
1554 
1555 void
1557  // clear created points
1558  myTemporalShape.clear();
1559  // change buttons
1560  myStartDrawingButton->enable();
1561  myStopDrawingButton->disable();
1562  myAbortDrawingButton->disable();
1563 }
1564 
1565 
1566 void
1568  if (myStopDrawingButton->isEnabled()) {
1569  myTemporalShape.push_back(P);
1570  } else {
1571  throw ProcessError("A new point cannot be added if drawing wasn't started");
1572  }
1573 }
1574 
1575 
1576 void
1578  if (myTemporalShape.size() > 1) {
1579  myTemporalShape.pop_back();
1580  }
1581 }
1582 
1583 
1584 const PositionVector&
1586  return myTemporalShape;
1587 }
1588 
1589 
1590 bool
1592  return myStopDrawingButton->isEnabled();
1593 }
1594 
1595 
1596 void
1598  myDeleteLastCreatedPoint = value;
1599 }
1600 
1601 
1602 bool
1604  return myDeleteLastCreatedPoint;
1605 }
1606 
1607 
1608 long
1610  startDrawing();
1611  return 0;
1612 }
1613 
1614 
1615 long
1616 GNEFrameModuls::DrawingShape::onCmdStopDrawing(FXObject*, FXSelector, void*) {
1617  stopDrawing();
1618  return 0;
1619 }
1620 
1621 
1622 long
1624  abortDrawing();
1625  return 0;
1626 }
1627 
1628 // ---------------------------------------------------------------------------
1629 // GNEFrameModuls::SelectorParent - methods
1630 // ---------------------------------------------------------------------------
1631 
1633  FXGroupBox(frameParent->myContentFrame, "Parent selector", GUIDesignGroupBoxFrame),
1634  myFrameParent(frameParent),
1635  myParentTag(SUMO_TAG_NOTHING) {
1636  // Create label with the type of SelectorParent
1637  myParentsLabel = new FXLabel(this, "No additional selected", nullptr, GUIDesignLabelLeftThick);
1638  // Create list
1640  // Hide List
1642 }
1643 
1644 
1646 
1647 
1648 std::string
1650  for (int i = 0; i < myParentsList->getNumItems(); i++) {
1651  if (myParentsList->isItemSelected(i)) {
1652  return myParentsList->getItem(i)->getText().text();
1653  }
1654  }
1655  return "";
1656 }
1657 
1658 
1659 void
1661  // first unselect all
1662  for (int i = 0; i < myParentsList->getNumItems(); i++) {
1663  myParentsList->getItem(i)->setSelected(false);
1664  }
1665  // select element if correspond to given ID
1666  for (int i = 0; i < myParentsList->getNumItems(); i++) {
1667  if (myParentsList->getItem(i)->getText().text() == id) {
1668  myParentsList->getItem(i)->setSelected(true);
1669  }
1670  }
1671  // recalc myFirstParentsList
1672  myParentsList->recalc();
1673 }
1674 
1675 
1676 bool
1678  // make sure that we're editing an additional tag
1679  const auto listOfTags = GNEAttributeCarrier::getAllowedTagsByCategory(GNETagProperties::TagType::ADDITIONALELEMENT, false);
1680  for (const auto& tag : listOfTags) {
1681  if (tag.first == additionalType) {
1682  myParentTag = additionalType;
1683  myParentsLabel->setText(("Parent type: " + tag.second).c_str());
1684  refreshSelectorParentModul();
1685  show();
1686  return true;
1687  }
1688  }
1689  return false;
1690 }
1691 
1692 
1693 void
1695  myParentTag = SUMO_TAG_NOTHING;
1696  hide();
1697 }
1698 
1699 
1700 void
1702  myParentsList->clearItems();
1703  if (myParentTag != SUMO_TAG_NOTHING) {
1704  // fill list with IDs of additionals
1705  for (const auto& i : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getAdditionals().at(myParentTag)) {
1706  myParentsList->appendItem(i.first.c_str());
1707  }
1708  }
1709 }
1710 
1711 // ---------------------------------------------------------------------------
1712 // GNEFrameModuls::OverlappedInspection - methods
1713 // ---------------------------------------------------------------------------
1714 
1716  FXGroupBox(frameParent->myContentFrame, "Overlapped elements", GUIDesignGroupBoxFrame),
1717  myFrameParent(frameParent),
1718  myFilteredTag(SUMO_TAG_NOTHING),
1719  myItemIndex(0) {
1720  // build elements
1721  buildFXElements();
1722 }
1723 
1724 
1726  FXGroupBox(frameParent->myContentFrame, ("Overlapped " + toString(filteredTag) + "s").c_str(), GUIDesignGroupBoxFrame),
1727  myFrameParent(frameParent),
1728  myFilteredTag(filteredTag),
1729  myItemIndex(0) {
1730  // build elements
1731  buildFXElements();
1732 }
1733 
1734 
1736 
1737 
1738 void
1740  // first clear myOverlappedACs
1741  myOverlappedACs.clear();
1742  // reserve
1743  myOverlappedACs.reserve(objectsUnderCursor.getClickedAttributeCarriers().size());
1744  // iterate over objects under cursor
1745  for (const auto& AC : objectsUnderCursor.getClickedAttributeCarriers()) {
1746  bool insert = true;
1747  // special case for supermode data
1748  if (myFrameParent->getViewNet()->getEditModes().isCurrentSupermodeData() &&
1749  !AC->getTagProperty().isGenericData()) {
1750  insert = false;
1751  }
1752  // check filter
1753  if ((myFilteredTag != SUMO_TAG_NOTHING) && (AC->getTagProperty().getTag() != myFilteredTag)) {
1754  insert = false;
1755  }
1756  if (insert) {
1757  myOverlappedACs.push_back(AC);
1758  }
1759  }
1760  mySavedClickedPosition = clickedPosition;
1761  // by default we inspect first element
1762  myItemIndex = 0;
1763  // update text of current index button
1764  myCurrentIndexButton->setText(("1 / " + toString(myOverlappedACs.size())).c_str());
1765  // clear and fill list again
1766  myOverlappedElementList->clearItems();
1767  for (int i = 0; i < (int)myOverlappedACs.size(); i++) {
1768  myOverlappedElementList->insertItem(i, myOverlappedACs.at(i)->getID().c_str(), myOverlappedACs.at(i)->getIcon());
1769  }
1770  // set first element as selected element
1771  myOverlappedElementList->getItem(0)->setSelected(TRUE);
1772  // by default list hidden
1773  myOverlappedElementList->hide();
1774  // show template editor
1775  show();
1776 }
1777 
1778 
1779 void
1781  // hide modul
1782  hide();
1783 }
1784 
1785 
1786 bool
1788  return shown();
1789 }
1790 
1791 
1792 int
1794  return (int)myOverlappedACs.size();
1795 }
1796 
1797 
1798 bool
1800  return (mySavedClickedPosition.distanceSquaredTo2D(clickedPosition) < 0.25);
1801 }
1802 
1803 
1804 bool
1806  // first check if OverlappedInspection is shown
1807  if (shown()) {
1808  // check if given position is near saved position
1809  if (checkSavedPosition(clickedPosition)) {
1810  // inspect next element
1811  onCmdNextElement(0, 0, 0);
1812  return true;
1813  } else {
1814  return false;
1815  }
1816  } else {
1817  return false;
1818  }
1819 }
1820 
1821 
1822 bool
1824  // first check if OverlappedInspection is shown
1825  if (shown()) {
1826  // check if given position is near saved position
1827  if (checkSavedPosition(clickedPosition)) {
1828  // inspect previousElement
1829  onCmdPreviousElement(0, 0, 0);
1830  return true;
1831  } else {
1832  return false;
1833  }
1834  } else {
1835  return false;
1836  }
1837 }
1838 
1839 
1840 long
1842  // check if there is items
1843  if (myOverlappedElementList->getNumItems() > 0) {
1844  // unselect current list element
1845  myOverlappedElementList->getItem((int)myItemIndex)->setSelected(FALSE);
1846  // set index (it works as a ring)
1847  if (myItemIndex > 0) {
1848  myItemIndex--;
1849  } else {
1850  myItemIndex = (myOverlappedACs.size() - 1);
1851  }
1852  // selected current list element
1853  myOverlappedElementList->getItem((int)myItemIndex)->setSelected(TRUE);
1854  myOverlappedElementList->update();
1855  // update current index button
1856  myCurrentIndexButton->setText((toString(myItemIndex + 1) + " / " + toString(myOverlappedACs.size())).c_str());
1857  // inspect overlapped attribute carrier
1858  myFrameParent->selectedOverlappedElement(myOverlappedACs.at(myItemIndex));
1859  // show OverlappedInspection again (because it's hidden in inspectSingleElement)
1860  show();
1861  }
1862  return 1;
1863 }
1864 
1865 
1866 long
1868  // check if there is items
1869  if (myOverlappedElementList->getNumItems() > 0) {
1870  // unselect current list element
1871  myOverlappedElementList->getItem((int)myItemIndex)->setSelected(FALSE);
1872  // set index (it works as a ring)
1873  myItemIndex = (myItemIndex + 1) % myOverlappedACs.size();
1874  // selected current list element
1875  myOverlappedElementList->getItem((int)myItemIndex)->setSelected(TRUE);
1876  myOverlappedElementList->update();
1877  // update current index button
1878  myCurrentIndexButton->setText((toString(myItemIndex + 1) + " / " + toString(myOverlappedACs.size())).c_str());
1879  // inspect overlapped attribute carrier
1880  myFrameParent->selectedOverlappedElement(myOverlappedACs.at(myItemIndex));
1881  // show OverlappedInspection again (because it's hidden in inspectSingleElement)
1882  show();
1883  }
1884  return 1;
1885 }
1886 
1887 
1888 long
1890  // show or hidde element list
1891  if (myOverlappedElementList->shown()) {
1892  myOverlappedElementList->hide();
1893  } else {
1894  myOverlappedElementList->show();
1895  }
1896  if (myOverlappedElementList->getNumItems() <= 10) {
1897  myOverlappedElementList->setHeight(23 * myOverlappedElementList->getNumItems());
1898  } else {
1899  myOverlappedElementList->setHeight(230);
1900  }
1901  myOverlappedElementList->recalc();
1902  // recalc and update frame
1903  recalc();
1904  return 1;
1905 }
1906 
1907 long
1909  for (int i = 0; i < myOverlappedElementList->getNumItems(); i++) {
1910  if (myOverlappedElementList->getItem(i)->isSelected()) {
1911  myItemIndex = i;
1912  // update current index button
1913  myCurrentIndexButton->setText((toString(myItemIndex + 1) + " / " + toString(myOverlappedACs.size())).c_str());
1914  // inspect overlapped attribute carrier
1915  myFrameParent->selectedOverlappedElement(myOverlappedACs.at(myItemIndex));
1916  // show OverlappedInspection again (because it's hidden in inspectSingleElement)
1917  show();
1918  return 1;
1919  }
1920  }
1921  return 0;
1922 }
1923 
1924 
1925 long
1927  FXDialogBox* helpDialog = new FXDialogBox(this, "GEO attributes Help", GUIDesignDialogBox);
1928  std::ostringstream help;
1929  help
1930  << " - Click in the same position\n"
1931  << " for inspect next element\n"
1932  << " - Shift + Click in the same\n"
1933  << " position for inspect\n"
1934  << " previous element";
1935  new FXLabel(helpDialog, help.str().c_str(), nullptr, GUIDesignLabelFrameInformation);
1936  // "OK"
1937  new FXButton(helpDialog, "OK\t\tclose", GUIIconSubSys::getIcon(GUIIcon::ACCEPT), helpDialog, FXDialogBox::ID_ACCEPT, GUIDesignButtonOK);
1938  helpDialog->create();
1939  helpDialog->show();
1940  return 1;
1941 }
1942 
1943 
1945  myFrameParent(nullptr),
1946  myPreviousElement(nullptr),
1947  myCurrentIndexButton(nullptr),
1948  myNextElement(nullptr),
1949  myOverlappedElementList(nullptr),
1950  myHelpButton(nullptr),
1951  myFilteredTag(SUMO_TAG_NOTHING),
1952  myItemIndex(0) {
1953 }
1954 
1955 
1956 void
1958  FXHorizontalFrame* frameButtons = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
1959  // Create previous Item Button
1960  myPreviousElement = new FXButton(frameButtons, "", GUIIconSubSys::getIcon(GUIIcon::BIGARROWLEFT), this, MID_GNE_OVERLAPPED_PREVIOUS, GUIDesignButtonIconRectangular);
1961  // create current index button
1962  myCurrentIndexButton = new FXButton(frameButtons, "", nullptr, this, MID_GNE_OVERLAPPED_SHOWLIST, GUIDesignButton);
1963  // Create next Item Button
1964  myNextElement = new FXButton(frameButtons, "", GUIIconSubSys::getIcon(GUIIcon::BIGARROWRIGHT), this, MID_GNE_OVERLAPPED_NEXT, GUIDesignButtonIconRectangular);
1965  // Create list of overlapped elements (by default hidden)
1966  myOverlappedElementList = new FXList(this, this, MID_GNE_OVERLAPPED_ITEMSELECTED, GUIDesignListFixedHeight);
1967  // by default list of overlapped elements is hidden)
1968  myOverlappedElementList->hide();
1969  // Create help button
1970  myHelpButton = new FXButton(this, "Help", nullptr, this, MID_HELP, GUIDesignButtonRectangular);
1971 }
1972 
1973 // ---------------------------------------------------------------------------
1974 // GNEFrameModuls::PathCreator - methods
1975 // ---------------------------------------------------------------------------
1976 
1978  mySubPath({edge}),
1979  myFromBusStop(nullptr),
1980  myToBusStop(nullptr),
1981  myConflictVClass(false),
1982 myConflictDisconnected(false) {
1983  // check if we have to change vClass flag
1984  if (edge->getNBEdge()->getNumLanesThatAllow(vClass) == 0) {
1985  myConflictVClass = true;
1986  }
1987 }
1988 
1989 
1991  myFromBusStop(nullptr),
1992  myToBusStop(nullptr),
1993  myConflictVClass(false),
1994  myConflictDisconnected(false) {
1995  // calculate subpath
1996  mySubPath = viewNet->getNet()->getPathCalculator()->calculatePath(vClass, {edgeFrom, edgeTo});
1997  // if subPath is empty, try it with pedestrian (i.e. ignoring vCass)
1998  if (mySubPath.empty()) {
1999  mySubPath = viewNet->getNet()->getPathCalculator()->calculatePath(SVC_PEDESTRIAN, {edgeFrom, edgeTo});
2000  if (mySubPath.empty()) {
2001  mySubPath = { edgeFrom, edgeTo };
2002  myConflictDisconnected = true;
2003  } else {
2004  myConflictVClass = true;
2005  }
2006  }
2007 }
2008 
2009 
2010 const std::vector<GNEEdge*>&
2012  return mySubPath;
2013 }
2014 
2015 
2017  return myFromBusStop;
2018 }
2019 
2020 
2022  return myToBusStop;
2023 }
2024 
2025 
2026 bool
2028  return myConflictVClass;
2029 }
2030 
2031 
2032 bool
2034  return myConflictDisconnected;
2035 }
2036 
2037 
2039  myFromBusStop(nullptr),
2040  myToBusStop(nullptr),
2041  myConflictVClass(false),
2042  myConflictDisconnected(false) {
2043 }
2044 
2045 
2047  FXGroupBox(frameParent->myContentFrame, "Route creator", GUIDesignGroupBoxFrame),
2048  myFrameParent(frameParent),
2050  myCreationMode(0),
2051  myFromStoppingPlace(nullptr),
2052  myToStoppingPlace(nullptr),
2053  myRoute(nullptr) {
2054  // create label for route info
2055  myInfoRouteLabel = new FXLabel(this, "No edges selected", 0, GUIDesignLabelFrameThicked);
2056  // create button for finish route creation
2057  myFinishCreationButton = new FXButton(this, "Finish route creation", nullptr, this, MID_GNE_EDGEPATH_FINISH, GUIDesignButton);
2058  myFinishCreationButton->disable();
2059  // create button for abort route creation
2060  myAbortCreationButton = new FXButton(this, "Abort route creation", nullptr, this, MID_GNE_EDGEPATH_ABORT, GUIDesignButton);
2061  myAbortCreationButton->disable();
2062  // create button for remove last inserted edge
2063  myRemoveLastInsertedElement = new FXButton(this, "Remove last inserted edge", nullptr, this, MID_GNE_EDGEPATH_REMOVELAST, GUIDesignButton);
2064  myRemoveLastInsertedElement->disable();
2065  // create check button
2066  myShowCandidateEdges = new FXCheckButton(this, "Show candidate edges", this, MID_GNE_EDGEPATH_SHOWCANDIDATES, GUIDesignCheckButton);
2067  myShowCandidateEdges->setCheck(TRUE);
2068  // create shift label
2069  myShiftLabel = new FXLabel(this,
2070  "SHIFT-click: ignore vClass",
2072  // create control label
2073  myControlLabel = new FXLabel(this,
2074  "CTRL-click: add disconnected",
2076  // create backspace label (always shown)
2077  new FXLabel(this,
2078  "BACKSPACE: undo click",
2080 }
2081 
2082 
2084 
2085 
2086 void
2087 GNEFrameModuls::PathCreator::showPathCreatorModul(SumoXMLTag tag, const bool firstElement, const bool consecutives) {
2088  // declare flag
2089  bool showPathCreator = true;
2090  // first abort creation
2091  abortPathCreation();
2092  // disable buttons
2093  myFinishCreationButton->disable();
2094  myAbortCreationButton->disable();
2095  myRemoveLastInsertedElement->disable();
2096  // reset creation mode
2097  myCreationMode = 0;
2098  // set first element
2099  if (firstElement) {
2100  myCreationMode |= REQUIERE_FIRSTELEMENT;
2101  }
2102  // set consecutive or non consecuives
2103  if (consecutives) {
2104  myCreationMode |= CONSECUTIVE_EDGES;
2105  } else {
2106  myCreationMode |= NONCONSECUTIVE_EDGES;
2107  }
2108  // set specific mode depending of tag
2109  switch (tag) {
2110  // routes
2111  case SUMO_TAG_ROUTE:
2113  myCreationMode |= SHOW_CANDIDATE_EDGES;
2114  myCreationMode |= START_EDGE;
2115  myCreationMode |= END_EDGE;
2116  break;
2117  // vehicles
2118  case SUMO_TAG_VEHICLE:
2119  case GNE_TAG_FLOW_ROUTE:
2120  case GNE_TAG_WALK_ROUTE:
2121  myCreationMode |= SINGLE_ELEMENT;
2122  myCreationMode |= ROUTE;
2123  break;
2124  case SUMO_TAG_TRIP:
2125  case SUMO_TAG_FLOW:
2128  myCreationMode |= SHOW_CANDIDATE_EDGES;
2129  myCreationMode |= START_EDGE;
2130  myCreationMode |= END_EDGE;
2131  break;
2132  // edges
2133  case GNE_TAG_WALK_EDGES:
2134  myCreationMode |= SHOW_CANDIDATE_EDGES;
2135  myCreationMode |= START_EDGE;
2136  myCreationMode |= END_EDGE;
2137  break;
2138  // edge->edge
2142  myCreationMode |= SHOW_CANDIDATE_EDGES;
2143  myCreationMode |= ONLY_FROMTO;
2144  myCreationMode |= START_EDGE;
2145  myCreationMode |= END_EDGE;
2146  break;
2147  // edge->busStop
2151  myCreationMode |= SHOW_CANDIDATE_EDGES;
2152  myCreationMode |= ONLY_FROMTO;
2153  myCreationMode |= START_BUSSTOP;
2154  myCreationMode |= END_BUSSTOP;
2155  break;
2156  // busStop->edge
2160  myCreationMode |= SHOW_CANDIDATE_EDGES;
2161  myCreationMode |= ONLY_FROMTO;
2162  myCreationMode |= START_BUSSTOP;
2163  myCreationMode |= END_EDGE;
2164  break;
2165  // busStop->busStop
2169  myCreationMode |= ONLY_FROMTO;
2170  myCreationMode |= START_BUSSTOP;
2171  myCreationMode |= END_BUSSTOP;
2172  break;
2173  // stops
2175  myCreationMode |= SINGLE_ELEMENT;
2176  myCreationMode |= START_BUSSTOP;
2177  break;
2179  myCreationMode |= SINGLE_ELEMENT;
2180  myCreationMode |= START_EDGE;
2181  break;
2182  // generic datas
2183  case SUMO_TAG_EDGEREL:
2184  myCreationMode |= ONLY_FROMTO;
2185  myCreationMode |= START_EDGE;
2186  myCreationMode |= END_EDGE;
2187  break;
2188  default:
2189  showPathCreator = false;
2190  break;
2191  }
2192  // check if show path creator
2193  if (showPathCreator) {
2194  // update edge colors
2195  updateEdgeColors();
2196  // recalc before show (to avoid graphic problems)
2197  recalc();
2198  // show modul
2199  show();
2200  } else {
2201  // hide modul
2202  hide();
2203  }
2204 }
2205 
2206 
2207 void
2209  // clear path
2210  clearPath();
2211  // hide modul
2212  hide();
2213 }
2214 
2215 
2218  return myVClass;
2219 }
2220 
2221 
2222 void
2224  myVClass = vClass;
2225  // update edge colors
2226  updateEdgeColors();
2227 }
2228 
2229 
2230 bool
2231 GNEFrameModuls::PathCreator::addEdge(GNEEdge* edge, const bool shiftKeyPressed, const bool controlKeyPressed) {
2232  // check if edges are allowed
2233  if (((myCreationMode & CONSECUTIVE_EDGES) + (myCreationMode & NONCONSECUTIVE_EDGES) +
2234  (myCreationMode & START_EDGE) + (myCreationMode & END_EDGE)) == 0) {
2235  return false;
2236  }
2237  // check if only an edge is allowed
2238  if ((myCreationMode & SINGLE_ELEMENT) && (mySelectedEdges.size() == 1)) {
2239  return false;
2240  }
2241  // continue depending of number of selected eges
2242  if (mySelectedEdges.size() > 0) {
2243  // check double edges
2244  if (mySelectedEdges.back() == edge) {
2245  // Write warning
2246  WRITE_WARNING("Double edges aren't allowed");
2247  // abort add edge
2248  return false;
2249  }
2250  // check consecutive edges
2251  if (myCreationMode & Mode::CONSECUTIVE_EDGES) {
2252  // check that new edge is consecutive
2253  const auto& outgoingEdges = mySelectedEdges.back()->getParentJunctions().back()->getGNEOutgoingEdges();
2254  if (std::find(outgoingEdges.begin(), outgoingEdges.end(), edge) == outgoingEdges.end()) {
2255  // Write warning
2256  WRITE_WARNING("Only consecutives edges are allowed");
2257  // abort add edge
2258  return false;
2259  }
2260  }
2261  }
2262  // check number of edges
2263  if (mySelectedEdges.size() == 2 && (myCreationMode & Mode::ONLY_FROMTO)) {
2264  // Write warning
2265  WRITE_WARNING("Only two edges are allowed");
2266  // abort add edge
2267  return false;
2268  }
2269  // check candidate edge
2270  if ((myShowCandidateEdges->getCheck() == TRUE) && !edge->isPossibleCandidate()) {
2271  if (edge->isSpecialCandidate()) {
2272  if (!shiftKeyPressed) {
2273  // Write warning
2274  WRITE_WARNING("Invalid edge (SHIFT + click to add an invalid vClass edge)");
2275  // abort add edge
2276  return false;
2277  }
2278  } else if (edge->isConflictedCandidate()) {
2279  if (!controlKeyPressed) {
2280  // Write warning
2281  WRITE_WARNING("Invalid edge (CONTROL + click to add a disconnected edge)");
2282  // abort add edge
2283  return false;
2284  }
2285  }
2286  }
2287  // All checks ok, then add it in selected elements
2288  mySelectedEdges.push_back(edge);
2289  // enable abort route button
2290  myAbortCreationButton->enable();
2291  // enable finish button
2292  myFinishCreationButton->enable();
2293  // disable undo/redo
2294  myFrameParent->myViewNet->getViewParent()->getGNEAppWindows()->disableUndoRedo("route creation");
2295  // enable or disable remove last edge button
2296  if (mySelectedEdges.size() > 1) {
2297  myRemoveLastInsertedElement->enable();
2298  } else {
2299  myRemoveLastInsertedElement->disable();
2300  }
2301  // recalculate path
2302  recalculatePath();
2303  // update info route label
2304  updateInfoRouteLabel();
2305  // update edge colors
2306  updateEdgeColors();
2307  return true;
2308 }
2309 
2310 
2311 std::vector<GNEEdge*>
2313  return mySelectedEdges;
2314 }
2315 
2316 
2317 bool
2318 GNEFrameModuls::PathCreator::addStoppingPlace(GNEAdditional* stoppingPlace, const bool /*shiftKeyPressed*/, const bool /*controlKeyPressed*/) {
2319  // check if stoppingPlaces aren allowed
2320  if (((myCreationMode & START_BUSSTOP) + (myCreationMode & END_BUSSTOP)) == 0) {
2321  return false;
2322  }
2323  // check if only a busStop is allowed
2324  if ((myCreationMode & SINGLE_ELEMENT) && myFromStoppingPlace) {
2325  return false;
2326  }
2327  // first add startBusStop
2328  if (myCreationMode & START_BUSSTOP) {
2329  // check if previously stopping place from was set
2330  if (myFromStoppingPlace) {
2331  // check if previously stopping place to was set
2332  if ((myCreationMode & END_BUSSTOP) && myToStoppingPlace) {
2333  return false;
2334  } else {
2335  myToStoppingPlace = stoppingPlace;
2336  }
2337  } else {
2338  myFromStoppingPlace = stoppingPlace;
2339  }
2340  } else if (myCreationMode & END_BUSSTOP) {
2341  // check if previously stopping place from was set
2342  if (myToStoppingPlace) {
2343  return false;
2344  } else {
2345  myToStoppingPlace = stoppingPlace;
2346  }
2347  }
2348  // enable abort route button
2349  myAbortCreationButton->enable();
2350  // enable finish button
2351  myFinishCreationButton->enable();
2352  // disable undo/redo
2353  myFrameParent->myViewNet->getViewParent()->getGNEAppWindows()->disableUndoRedo("route creation");
2354  // enable or disable remove last stoppingPlace button
2355  if (myFromStoppingPlace || myToStoppingPlace) {
2356  myRemoveLastInsertedElement->enable();
2357  } else {
2358  myRemoveLastInsertedElement->disable();
2359  }
2360  // recalculate path
2361  recalculatePath();
2362  // update info route label
2363  updateInfoRouteLabel();
2364  // update stoppingPlace colors
2365  updateEdgeColors();
2366  return true;
2367 }
2368 
2369 
2372  if (myFromStoppingPlace && (myFromStoppingPlace->getTagProperty().getTag() == expectedTag)) {
2373  return myFromStoppingPlace;
2374  } else {
2375  return nullptr;
2376  }
2377 }
2378 
2379 
2382  if (myToStoppingPlace && (myToStoppingPlace->getTagProperty().getTag() == expectedTag)) {
2383  return myToStoppingPlace;
2384  } else {
2385  return nullptr;
2386  }
2387 }
2388 
2389 
2390 bool
2391 GNEFrameModuls::PathCreator::addRoute(GNEDemandElement* route, const bool /*shiftKeyPressed*/, const bool /*controlKeyPressed*/) {
2392  // check if routes aren allowed
2393  if ((myCreationMode & ROUTE) == 0) {
2394  return false;
2395  }
2396  // check if previously a route was added
2397  if (myRoute) {
2398  return false;
2399  }
2400  // set route
2401  myRoute = route;
2402  // recalculate path
2403  recalculatePath();
2404  updateInfoRouteLabel();
2405  updateEdgeColors();
2406  return true;
2407 }
2408 
2409 
2412  return myRoute;
2413 }
2414 
2415 
2416 const std::vector<GNEFrameModuls::PathCreator::Path>&
2418  return myPath;
2419 }
2420 
2421 
2422 bool
2424  return (myShowCandidateEdges->getCheck() == TRUE);
2425 }
2426 
2427 
2428 void
2430  // reset all flags
2431  for (const auto& edge : myFrameParent->myViewNet->getNet()->getAttributeCarriers()->getEdges()) {
2432  edge.second->resetCandidateFlags();
2433  }
2434  // set reachability
2435  if (mySelectedEdges.size() > 0) {
2436  // only coloring edges if checkbox "show candidate edges" is enabled
2437  if ((myShowCandidateEdges->getCheck() == TRUE) && (myCreationMode & SHOW_CANDIDATE_EDGES)) {
2438  // mark all edges as conflicted (to mark special candidates)
2439  for (const auto& edge : myFrameParent->myViewNet->getNet()->getAttributeCarriers()->getEdges()) {
2440  edge.second->setConflictedCandidate(true);
2441  }
2442  // set special candidates (Edges that are connected but aren't compatibles with current vClass
2443  setSpecialCandidates(mySelectedEdges.back());
2444  // mark again all edges as conflicted (to mark possible candidates)
2445  for (const auto& edge : myFrameParent->myViewNet->getNet()->getAttributeCarriers()->getEdges()) {
2446  edge.second->setConflictedCandidate(true);
2447  }
2448  // set possible candidates (Edges that are connected AND are compatibles with current vClass
2449  setPossibleCandidates(mySelectedEdges.back(), myVClass);
2450  }
2451  // now mark selected eges
2452  for (const auto& edge : mySelectedEdges) {
2453  edge->resetCandidateFlags();
2454  edge->setSourceCandidate(true);
2455  }
2456  // finally mark last selected element as target
2457  mySelectedEdges.back()->resetCandidateFlags();
2458  mySelectedEdges.back()->setTargetCandidate(true);
2459  } else if (myShowCandidateEdges->getCheck() == TRUE && (myCreationMode & SHOW_CANDIDATE_EDGES)) {
2460  // mark all edges that have at least one lane that allow given vClass
2461  for (const auto& edge : myFrameParent->myViewNet->getNet()->getAttributeCarriers()->getEdges()) {
2462  if (edge.second->getNBEdge()->getNumLanesThatAllow(myVClass) > 0) {
2463  edge.second->setPossibleCandidate(true);
2464  } else {
2465  edge.second->setSpecialCandidate(true);
2466  }
2467  }
2468  }
2469  // update view net
2470  myFrameParent->myViewNet->updateViewNet();
2471 }
2472 
2473 
2474 #if defined(_MSC_VER) && _MSC_VER == 1800
2475 #pragma warning(push)
2476 #pragma warning(disable: 4100) // do not warn about "unused" parameters which get optimized away
2477 #endif
2478 void
2480  if (myPath.size() > 0) {
2481  const double lineWidth = 0.35;
2482  const double lineWidthin = 0.25;
2483  // Add a draw matrix
2484  glPushMatrix();
2485  // Start with the drawing of the area traslating matrix to origin
2486  glTranslated(0, 0, GLO_MAX - 0.1);
2487  // set first color
2489  // iterate over path
2490  for (int i = 0; i < (int)myPath.size(); i++) {
2491  // get path
2492  const GNEFrameModuls::PathCreator::Path& path = myPath.at(i);
2493  // draw line over
2494  for (int j = 0; j < (int)path.getSubPath().size(); j++) {
2495  const GNELane* lane = path.getSubPath().at(j)->getLanes().back();
2496  if (((i == 0) && (j == 0)) || (j > 0)) {
2497  GLHelper::drawBoxLines(lane->getLaneShape(), lineWidth);
2498  }
2499  // draw connection between lanes
2500  if ((j + 1) < (int)path.getSubPath().size()) {
2501  const GNELane* nextLane = path.getSubPath().at(j + 1)->getLanes().back();
2502  if (lane->getLane2laneConnections().exist(nextLane)) {
2504  } else {
2505  GLHelper::drawBoxLines({lane->getLaneShape().back(), nextLane->getLaneShape().front()}, lineWidth);
2506  }
2507  }
2508  }
2509  }
2510  glTranslated(0, 0, 0.1);
2511  // iterate over path again
2512  for (int i = 0; i < (int)myPath.size(); i++) {
2513  // get path
2514  const GNEFrameModuls::PathCreator::Path& path = myPath.at(i);
2515  // set path color color
2516  if ((myCreationMode & SHOW_CANDIDATE_EDGES) == 0) {
2518  } else if (path.isConflictDisconnected()) {
2520  } else if (path.isConflictVClass()) {
2522  } else {
2524  }
2525  // draw line over
2526  for (int j = 0; j < (int)path.getSubPath().size(); j++) {
2527  const GNELane* lane = path.getSubPath().at(j)->getLanes().back();
2528  if (((i == 0) && (j == 0)) || (j > 0)) {
2529  GLHelper::drawBoxLines(lane->getLaneShape(), lineWidthin);
2530  }
2531  // draw connection between lanes
2532  if ((j + 1) < (int)path.getSubPath().size()) {
2533  const GNELane* nextLane = path.getSubPath().at(j + 1)->getLanes().back();
2534  if (lane->getLane2laneConnections().exist(nextLane)) {
2536  } else {
2537  GLHelper::drawBoxLines({ lane->getLaneShape().back(), nextLane->getLaneShape().front() }, lineWidthin);
2538  }
2539  }
2540  }
2541  }
2542  // Pop last matrix
2543  glPopMatrix();
2544  }
2545 }
2546 #if defined(_MSC_VER) && _MSC_VER == 1800
2547 #pragma warning(pop)
2548 #endif
2549 
2550 
2551 void
2553  // call create path implemented in frame parent
2554  myFrameParent->createPath();
2555 }
2556 
2557 
2558 void
2560  // first check that there is elements
2561  if ((mySelectedEdges.size() > 0) || myFromStoppingPlace || myToStoppingPlace || myRoute) {
2562  // unblock undo/redo
2563  myFrameParent->myViewNet->getViewParent()->getGNEAppWindows()->enableUndoRedo();
2564  // clear edges
2565  clearPath();
2566  // disable buttons
2567  myFinishCreationButton->disable();
2568  myAbortCreationButton->disable();
2569  myRemoveLastInsertedElement->disable();
2570  // update info route label
2571  updateInfoRouteLabel();
2572  // update reachability
2573  updateEdgeColors();
2574  // update view (to see the new route)
2575  myFrameParent->getViewNet()->updateViewNet();
2576  }
2577 }
2578 
2579 
2580 void
2582  if (mySelectedEdges.size() > 1) {
2583  // remove special color of last selected edge
2584  mySelectedEdges.back()->resetCandidateFlags();
2585  // remove last edge
2586  mySelectedEdges.pop_back();
2587  // change last edge flag
2588  if ((mySelectedEdges.size() > 0) && mySelectedEdges.back()->isSourceCandidate()) {
2589  mySelectedEdges.back()->setSourceCandidate(false);
2590  mySelectedEdges.back()->setTargetCandidate(true);
2591  }
2592  // enable or disable remove last edge button
2593  if (mySelectedEdges.size() > 1) {
2594  myRemoveLastInsertedElement->enable();
2595  } else {
2596  myRemoveLastInsertedElement->disable();
2597  }
2598  // recalculate path
2599  recalculatePath();
2600  // update info route label
2601  updateInfoRouteLabel();
2602  // update reachability
2603  updateEdgeColors();
2604  // update view
2605  myFrameParent->myViewNet->updateViewNet();
2606  }
2607 }
2608 
2609 
2610 long
2611 GNEFrameModuls::PathCreator::onCmdCreatePath(FXObject*, FXSelector, void*) {
2612  // just call create path
2613  createPath();
2614  return 1;
2615 }
2616 
2617 
2618 long
2620  // just call abort path creation
2621  abortPathCreation();
2622  return 1;
2623 }
2624 
2625 
2626 long
2628  // just call remove last element
2629  removeLastElement();
2630  return 1;
2631 }
2632 
2633 
2634 long
2636  // update labels
2637  if (myShowCandidateEdges->getCheck() == TRUE) {
2638  myShiftLabel->show();
2639  myControlLabel->show();
2640  } else {
2641  myShiftLabel->hide();
2642  myControlLabel->hide();
2643  }
2644  // recalc frame
2645  recalc();
2646  // update edge colors (view will be updated within function)
2647  updateEdgeColors();
2648  return 1;
2649 }
2650 
2651 
2652 void
2654  if (myPath.size() > 0) {
2655  // declare variables for route info
2656  double length = 0;
2657  double speed = 0;
2658  int pathSize = 0;
2659  for (const auto& path : myPath) {
2660  for (const auto& edge : path.getSubPath()) {
2661  length += edge->getNBEdge()->getLength();
2662  speed += edge->getNBEdge()->getSpeed();
2663  }
2664  pathSize += (int)path.getSubPath().size();
2665  }
2666  // declare ostringstream for label and fill it
2667  std::ostringstream information;
2668  information
2669  << "- Selected edges: " << toString(mySelectedEdges.size()) << "\n"
2670  << "- Path edges: " << toString(pathSize) << "\n"
2671  << "- Length: " << toString(length) << "\n"
2672  << "- Average speed: " << toString(speed / pathSize);
2673  // set new label
2674  myInfoRouteLabel->setText(information.str().c_str());
2675  } else {
2676  myInfoRouteLabel->setText("No edges selected");
2677  }
2678 }
2679 
2680 
2681 void
2683  // reset all flags
2684  for (const auto& edge : myFrameParent->myViewNet->getNet()->getAttributeCarriers()->getEdges()) {
2685  edge.second->resetCandidateFlags();
2686  }
2687  // clear edges, additionals and route
2688  mySelectedEdges.clear();
2689  myFromStoppingPlace = nullptr;
2690  myToStoppingPlace = nullptr;
2691  myRoute = nullptr;
2692  // clear path
2693  myPath.clear();
2694  // update info route label
2695  updateInfoRouteLabel();
2696 }
2697 
2698 
2699 void
2701  // first clear path
2702  myPath.clear();
2703  // set edges
2704  std::vector<GNEEdge*> edges;
2705  // add route edges
2706  if (myRoute) {
2707  edges = myRoute->getParentEdges();
2708  } else {
2709  // add from stopping place edge
2710  if (myFromStoppingPlace) {
2711  edges.push_back(myFromStoppingPlace->getParentLanes().front()->getParentEdge());
2712  }
2713  // add selected edges
2714  for (const auto& edge : mySelectedEdges) {
2715  edges.push_back(edge);
2716  }
2717  // add to stopping place edge
2718  if (myToStoppingPlace) {
2719  edges.push_back(myToStoppingPlace->getParentLanes().front()->getParentEdge());
2720  }
2721  }
2722  // fill paths
2723  if (edges.size() == 1) {
2724  myPath.push_back(Path(myVClass, edges.front()));
2725  } else {
2726  // add every segment
2727  for (int i = 1; i < (int)edges.size(); i++) {
2728  myPath.push_back(Path(myFrameParent->getViewNet(), myVClass, edges.at(i - 1), edges.at(i)));
2729  }
2730  }
2731 }
2732 
2733 
2734 void
2736  // first calculate reachability for pedestrians (we use it, because pedestran can walk in almost all edges)
2737  myFrameParent->getViewNet()->getNet()->getPathCalculator()->calculateReachability(SVC_PEDESTRIAN, originEdge);
2738  // change flags
2739  for (const auto& edge : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getEdges()) {
2740  for (const auto& lane : edge.second->getLanes()) {
2741  if (lane->getReachability() > 0) {
2742  lane->getParentEdge()->resetCandidateFlags();
2743  lane->getParentEdge()->setSpecialCandidate(true);
2744  }
2745  }
2746  }
2747 }
2748 
2749 void
2751  // first calculate reachability for pedestrians
2752  myFrameParent->getViewNet()->getNet()->getPathCalculator()->calculateReachability(vClass, originEdge);
2753  // change flags
2754  for (const auto& edge : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getEdges()) {
2755  for (const auto& lane : edge.second->getLanes()) {
2756  if (lane->getReachability() > 0) {
2757  lane->getParentEdge()->resetCandidateFlags();
2758  lane->getParentEdge()->setPossibleCandidate(true);
2759  }
2760  }
2761  }
2762 }
2763 
2764 // ---------------------------------------------------------------------------
2765 // GNERouteFrame::Legend - methods
2766 // ---------------------------------------------------------------------------
2767 
2769  FXGroupBox(frameParent->myContentFrame, "Legend", GUIDesignGroupBoxFrame) {
2770  // declare label
2771  FXLabel* legendLabel = nullptr;
2772  // edge candidate
2773  legendLabel = new FXLabel(this, " edge candidate", 0, GUIDesignLabelLeft);
2774  legendLabel->setBackColor(MFXUtils::getFXColor(frameParent->getViewNet()->getVisualisationSettings().candidateColorSettings.possible));
2775  legendLabel->setTextColor(MFXUtils::getFXColor(RGBColor::WHITE));
2776  // last edge selected
2777  legendLabel = new FXLabel(this, " last edge selected", 0, GUIDesignLabelLeft);
2778  legendLabel->setBackColor(MFXUtils::getFXColor(frameParent->getViewNet()->getVisualisationSettings().candidateColorSettings.target));
2779  // edge selected
2780  legendLabel = new FXLabel(this, " edge selected", 0, GUIDesignLabelLeft);
2781  legendLabel->setBackColor(MFXUtils::getFXColor(frameParent->getViewNet()->getVisualisationSettings().candidateColorSettings.source));
2782  // edge conflict (vClass)
2783  legendLabel = new FXLabel(this, " edge conflic (vClass)", 0, GUIDesignLabelLeft);
2784  legendLabel->setBackColor(MFXUtils::getFXColor(frameParent->getViewNet()->getVisualisationSettings().candidateColorSettings.special));
2785  // edge disconnected
2786  legendLabel = new FXLabel(this, " edge disconnected", 0, GUIDesignLabelLeft);
2787  legendLabel->setBackColor(MFXUtils::getFXColor(frameParent->getViewNet()->getVisualisationSettings().candidateColorSettings.conflict));
2788 }
2789 
2790 
2792 
2793 
2794 void
2796  show();
2797 }
2798 
2799 void
2801  hide();
2802 }
2803 
2804 // ---------------------------------------------------------------------------
2805 // GNEFrameModuls - methods
2806 // ---------------------------------------------------------------------------
2807 
2808 FXLabel*
2809 GNEFrameModuls::buildRainbow(FXComposite* parent) {
2810  // create label for color information
2811  FXLabel* label = new FXLabel(parent, "Scale: Min -> Max", nullptr, GUIDesignLabelCenterThick);
2812  // create frame for color scale
2813  FXHorizontalFrame* horizontalFrameColors = new FXHorizontalFrame(parent, GUIDesignAuxiliarHorizontalFrame);
2814  for (const auto& color : GNEViewNetHelper::getRainbowScaledColors()) {
2815  FXLabel* colorLabel = new FXLabel(horizontalFrameColors, "", nullptr, GUIDesignLabelLeft);
2816  colorLabel->setBackColor(MFXUtils::getFXColor(color));
2817  }
2818  // return label
2819  return label;
2820 }
2821 
2822 /****************************************************************************/
FXDEFMAP(GNEFrameModuls::TagSelector) TagSelectorMap[]
@ MID_GNE_TAGTYPE_SELECTED
tag type selected in ComboBox
Definition: GUIAppEnum.h:735
@ MID_GNE_DELETE
delete element
Definition: GUIAppEnum.h:721
@ MID_GNE_OVERLAPPED_PREVIOUS
inspect previous element in overlapped modul
Definition: GUIAppEnum.h:785
@ MID_GNE_TAG_SELECTED
tag selected in ComboBox
Definition: GUIAppEnum.h:737
@ MID_GNE_OVERLAPPED_ITEMSELECTED
list item selected in overlapped modul
Definition: GUIAppEnum.h:789
@ MID_GNE_CENTER
center element
Definition: GUIAppEnum.h:727
@ MID_GNE_EDGEPATH_FINISH
finish edge path creation
Definition: GUIAppEnum.h:757
@ MID_GNE_ACHIERARCHY_SHOWCHILDMENU
In HierarchicalElementTree list, show child menu.
Definition: GUIAppEnum.h:771
@ MID_GNE_STARTDRAWING
start drawing polygon
Definition: GUIAppEnum.h:777
@ MID_GNE_ACHIERARCHY_MOVEUP
In HierarchicalElementTree list, move element to up.
Definition: GUIAppEnum.h:773
@ MID_HELP
help button
Definition: GUIAppEnum.h:578
@ MID_GNE_OVERLAPPED_SHOWLIST
show list of overlapped elements
Definition: GUIAppEnum.h:787
@ MID_GNE_EDGEPATH_REMOVELAST
remove last inserted element in path
Definition: GUIAppEnum.h:759
@ MID_GNE_INSPECT
inspect element
Definition: GUIAppEnum.h:723
@ MID_GNE_OVERLAPPED_NEXT
inspect next element in overlapped modul
Definition: GUIAppEnum.h:783
@ MID_GNE_ABORTDRAWING
abort drawing polygon
Definition: GUIAppEnum.h:781
@ MID_GNE_ACHIERARCHY_MOVEDOWN
In HierarchicalElementTree list, move element to down.
Definition: GUIAppEnum.h:775
@ MID_GNE_EDGEPATH_SHOWCANDIDATES
enable or disable show path candidates
Definition: GUIAppEnum.h:761
@ MID_GNE_STOPDRAWING
stop drawing polygon
Definition: GUIAppEnum.h:779
@ MID_GNE_EDGEPATH_ABORT
abort edge path creation
Definition: GUIAppEnum.h:755
@ MID_GNE_SET_TYPE
used to select a type of element in a combo box
Definition: GUIAppEnum.h:733
#define GUIDesignLabelLeft
Definition: GUIDesigns.h:175
#define GUIDesignButton
Definition: GUIDesigns.h:62
#define GUIDesignComboBox
Definition: GUIDesigns.h:237
#define GUIDesignListFixedHeight
design for FXLists with height fixed
Definition: GUIDesigns.h:570
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:255
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition: GUIDesigns.h:313
#define GUIDesignDialogBox
Definition: GUIDesigns.h:494
#define GUIDesignButtonRectangular
little button rectangula used in frames (For example, in "help" buttons)
Definition: GUIDesigns.h:68
#define GUIDesignLabelLeftThick
label extended over frame with thick and with text justify to left
Definition: GUIDesigns.h:187
#define GUIDesignButtonIconRectangular
button only with icon
Definition: GUIDesigns.h:74
#define GUIDesignLabelFrameThicked
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition: GUIDesigns.h:226
#define GUIDesignListSingleElementFixedHeight
design for FXLists that only allow a single selected elements selected and height fixed
Definition: GUIDesigns.h:573
#define GUIDesignGroupBoxFrame
Group box design extended over frame.
Definition: GUIDesigns.h:278
#define GUIDesignButtonOK
Definition: GUIDesigns.h:115
#define GUIDesignLabelCenterThick
label extended over frame with thick and with text justify to center
Definition: GUIDesigns.h:193
#define GUIDesignTreeListFrame
Tree list used in frames to represent elements children.
Definition: GUIDesigns.h:564
#define GUIDesignCheckButton
checkButton placed in left position
Definition: GUIDesigns.h:133
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition: GUIDesigns.h:223
@ GLO_MAX
empty max
@ BIGARROWLEFT
@ RECENTERVIEW
@ BIGARROWRIGHT
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:286
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_PEDESTRIAN
pedestrian
const std::string DEFAULT_PEDTYPE_ID
const std::string DEFAULT_VTYPE_ID
const std::string DEFAULT_BIKETYPE_ID
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ GNE_TAG_WALK_BUSSTOP_BUSSTOP
@ GNE_TAG_PERSONTRIP_EDGE_EDGE
@ GNE_TAG_PERSONSTOP_BUSSTOP
@ GNE_TAG_RIDE_BUSSTOP_BUSSTOP
@ SUMO_TAG_EDGEREL
a relation between two edges
@ SUMO_TAG_DATAINTERVAL
@ GNE_TAG_PERSONTRIP_BUSSTOP_EDGE
@ SUMO_TAG_VTYPE
description of a vehicle type
@ SUMO_TAG_NOTHING
invalid tag
@ GNE_TAG_WALK_EDGES
@ SUMO_TAG_VEHICLE
description of a vehicle
@ GNE_TAG_FLOW_ROUTE
a flow definition using a route instead of a from-to edges route (used in NETEDIT)
@ GNE_TAG_FLOW_WITHROUTE
description of a vehicle with an embedded route (used in NETEDIT)
@ SUMO_TAG_FLOW
a flow definitio nusing a from-to edges instead of a route (used by router)
@ GNE_TAG_RIDE_BUSSTOP_EDGE
@ SUMO_TAG_CONNECTION
connectio between two lanes
@ GNE_TAG_RIDE_EDGE_EDGE
@ GNE_TAG_PERSONSTOP_EDGE
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_CROSSING
crossing between edges for pedestrians
@ GNE_TAG_WALK_EDGE_EDGE
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ GNE_TAG_PERSONTRIP_EDGE_BUSSTOP
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ GNE_TAG_WALK_BUSSTOP_EDGE
@ GNE_TAG_VEHICLE_WITHROUTE
@ GNE_TAG_RIDE_EDGE_BUSSTOP
@ SUMO_TAG_POILANE
begin/end of the description of a Point of interest over Lane (used by Netedit)
@ SUMO_TAG_DATASET
@ GNE_TAG_PERSONTRIP_BUSSTOP_BUSSTOP
@ GNE_TAG_WALK_EDGE_BUSSTOP
@ SUMO_TAG_PTYPE
description of a person type (used in NETEDIT)
@ GNE_TAG_ROUTE_EMBEDDED
embedded route (used in NETEDIT)
@ GNE_TAG_WALK_ROUTE
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ GNE_ATTR_DEFAULT_VTYPE
Flag to check if VType is a default VType.
@ SUMO_ATTR_ID
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:446
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition: GLHelper.cpp:181
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:47
virtual const std::string & getID() const =0
return ID of object
static const GNETagProperties & getTagProperties(SumoXMLTag tag)
get Tag Properties
const GNETagProperties & getTagProperty() const
get Tag Property assigned to this object
FXIcon * getIcon() const
get FXIcon associated to this AC
static std::vector< std::pair< SumoXMLTag, const std::string > > getAllowedTagsByCategory(const int tagPropertyCategory, const bool onlyDrawables)
get tags of all editable element types using TagProperty Type (NetworkEditMode::NETWORKELEMENT,...
virtual std::string getHierarchyName() const =0
get Hierarchy Name (Used in AC Hierarchy)
GNENet * getNet() const
get pointer to net
bool isSpecialCandidate() const
check if this element is a special candidate
bool isPossibleCandidate() const
check if this element is a possible candidate
bool isConflictedCandidate() const
check if this element is a conflicted candidate
GNEEdge * getEdgeFrom() const
get the name of the edge the vehicles leave
GNEEdge * getEdgeTo() const
get the name of the edge the vehicles may reach when leaving "from"
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
Definition: GNECrossing.h:41
GNEJunction * getParentJunction() const
get parent Junction
An Element which don't belongs to GNENet but has influency in the simulation.
GNEDataSet * getDataSetParent() const
Returns a pointer to GNEDataSet parent.
const std::vector< GNEGenericData * > & getGenericDataChildren() const
get generic data children
const std::map< const double, GNEDataInterval * > & getDataIntervalChildren() const
get data interval children
Definition: GNEDataSet.cpp:293
An Element which don't belongs to GNENet but has influency in the simulation.
const std::string & getID() const
get ID
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:49
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:723
static bool isSupermodeValid(const GNEViewNet *viewNet, const GNEAttributeCarrier *AC)
return true if AC can be edited in the current supermode
GNEViewNet * getViewNet() const
get view net
Definition: GNEFrame.cpp:133
GNEDemandElement * getCurrentDemandElement() const
get current demand element
void setDemandElement(GNEDemandElement *demandElement)
set current demand element
GNEEdge * getPersonPlanPreviousEdge() const
get previous edge for the current selected demand elemnt
long onCmdSelectDemandElement(FXObject *, FXSelector, void *)
const std::vector< SumoXMLTag > & getAllowedTags() const
std::vector< SumoXMLTag > myDemandElementTags
demand element tags
DemandElementSelector(GNEFrame *frameParent, SumoXMLTag demandElementTag)
FOX-declaration.
void showDemandElementSelector()
show demand element selector
FXComboBox * myDemandElementsMatchBox
comboBox with the list of elements type
bool isDemandElementSelectorShown() const
check if demand element selector is shown
void hideDemandElementSelector()
hide demand element selector
void refreshDemandElementSelector()
refresh demand element selector
long onCmdAbortDrawing(FXObject *, FXSelector, void *)
Called when the user press abort drawing button.
void showDrawingShape()
show Drawing mode
FXLabel * myInformationLabel
Label with information.
void startDrawing()
start drawing
DrawingShape(GNEFrame *frameParent)
FOX-declaration.
bool getDeleteLastCreatedPoint()
get flag delete last created point
long onCmdStartDrawing(FXObject *, FXSelector, void *)
void hideDrawingShape()
hide Drawing mode
long onCmdStopDrawing(FXObject *, FXSelector, void *)
Called when the user press stop drawing button.
void stopDrawing()
stop drawing and check if shape can be created
FXButton * myAbortDrawingButton
button for abort drawing
void setDeleteLastCreatedPoint(bool value)
enable or disable delete last created point
const PositionVector & getTemporalShape() const
get Temporal shape
void addNewPoint(const Position &P)
add new point to temporal shape
void abortDrawing()
abort drawing
void removeLastPoint()
remove last added point
bool isDrawing() const
return true if currently a shape is drawed
FXButton * myStopDrawingButton
button for stop drawing
FXButton * myStartDrawingButton
button for start drawing
void showHierarchicalElementChildren(GNEHierarchicalElement *HE, FXTreeItem *itemParent)
show children of given hierarchical element
long onCmdDeleteItem(FXObject *, FXSelector, void *)
called when user click over option "delete" of child menu
void removeCurrentEditedAttributeCarrier(const GNEAttributeCarrier *HE)
if given AttributeCarrier is the same of myHE, set it as nullptr
FXTreeItem * showAttributeCarrierParents()
show child of current attributeCarrier
long onCmdMoveItemUp(FXObject *, FXSelector, void *)
called when user click over option "Move up" of child menu
void refreshHierarchicalElementTree()
refresh HierarchicalElementTree
long onCmdInspectItem(FXObject *, FXSelector, void *)
called when user click over option "inspect" of child menu
long onCmdCenterItem(FXObject *, FXSelector, void *)
called when user click over option "center" of child Menu
long onCmdMoveItemDown(FXObject *, FXSelector, void *)
called when user click over option "Move down" of child menu
long onCmdShowChildMenu(FXObject *, FXSelector, void *data)
void createPopUpMenu(int X, int Y, GNEAttributeCarrier *clickedAC)
FXTreeList * myTreelist
tree list to show the children of the element to erase
HierarchicalElementTree(GNEFrame *frameParent)
FOX-declaration.
void showHierarchicalElementTree(GNEAttributeCarrier *AC)
show HierarchicalElementTree
void hideHierarchicalElementTree()
hide HierarchicalElementTree
FXTreeItem * addListItem(GNEAttributeCarrier *AC, FXTreeItem *itemParent=nullptr, std::string prefix="", std::string sufix="")
add item into list
long onCmdOverlappingHelp(FXObject *, FXSelector, void *)
Called when user press the help button.
void showOverlappedInspection(const GNEViewNetHelper::ObjectsUnderCursor &objectsUnderCursor, const Position &clickedPosition)
show template editor
bool nextElement(const Position &clickedPosition)
try to go to next element if clicked position is near to saved position
bool checkSavedPosition(const Position &clickedPosition) const
check if given position is near to saved position
bool previousElement(const Position &clickedPosition)
try to go to previous element if clicked position is near to saved position
void buildFXElements()
build Fox Toolkit elemements
long onCmdShowList(FXObject *, FXSelector, void *)
show list of overlapped elements
long onCmdPreviousElement(FXObject *, FXSelector, void *)
Inspect previous element (from top to bot)
long onCmdListItemSelected(FXObject *, FXSelector, void *)
called when a list item is selected
int getNumberOfOverlappedACs() const
get number of overlapped ACSs
long onCmdNextElement(FXObject *, FXSelector, void *)
Inspect next Element (from top to bot)
void hideOverlappedInspection()
hide template editor
bool overlappedInspectionShown() const
check if overlappedInspection modul is shown
bool myConflictDisconnected
flag to mark this path as disconnected
const std::vector< GNEEdge * > & getSubPath() const
get sub path
GNEAdditional * getFromBusStop() const
get from additional
bool myConflictVClass
flag to mark this path as conflicted
std::vector< GNEEdge * > mySubPath
sub path
GNEAdditional * getToBusStop() const
to additional
bool isConflictVClass() const
check if current path is conflict due vClass
bool isConflictDisconnected() const
check if current path is conflict due is disconnected
GNEDemandElement * myRoute
route (usually a busStop)
bool addRoute(GNEDemandElement *route, const bool shiftKeyPressed, const bool controlKeyPressed)
add route
std::vector< GNEEdge * > getSelectedEdges() const
get current selected additionals
int myCreationMode
current creation mode
void updateInfoRouteLabel()
update InfoRouteLabel
const std::vector< Path > & getPath() const
get path route
bool drawCandidateEdgesWithSpecialColor() const
draw candidate edges with special color (Only for candidates, special and conflicted)
SUMOVehicleClass getVClass() const
get vClass
GNEAdditional * myToStoppingPlace
to additional (usually a busStop)
GNEDemandElement * getRoute() const
get route
void drawTemporalRoute(const GUIVisualizationSettings &s) const
draw temporal route
void removeLastElement()
remove path element
void abortPathCreation()
abort path creation
FXLabel * myControlLabel
label for control information
long onCmdCreatePath(FXObject *, FXSelector, void *)
FXButton * myAbortCreationButton
button for abort route creation
void recalculatePath()
recalculate path
void showPathCreatorModul(SumoXMLTag tag, const bool firstElement, const bool consecutives)
show PathCreator for the given tag
GNEFrame * myFrameParent
current frame parent
void clearPath()
clear edges (and restore colors)
GNEAdditional * getToStoppingPlace(SumoXMLTag expectedTag) const
get to stoppingPlace
bool addEdge(GNEEdge *edge, const bool shiftKeyPressed, const bool controlKeyPressed)
add edge
long onCmdRemoveLastElement(FXObject *, FXSelector, void *)
Called when the user click over button "Remove las inserted edge".
void setPossibleCandidates(GNEEdge *originEdge, const SUMOVehicleClass vClass)
set edgereachability (This function will be called recursively)
void setVClass(SUMOVehicleClass vClass)
set vClass
bool addStoppingPlace(GNEAdditional *stoppingPlace, const bool shiftKeyPressed, const bool controlKeyPressed)
add stoppingPlace
GNEAdditional * myFromStoppingPlace
from additional (usually a busStop)
long onCmdShowCandidateEdges(FXObject *, FXSelector, void *)
Called when the user click over check button "show candidate edges".
SUMOVehicleClass myVClass
current vClass
void setSpecialCandidates(GNEEdge *originEdge)
set special candidates (This function will be called recursively)
FXLabel * myShiftLabel
label for shift information
FXLabel * myInfoRouteLabel
label with route info
long onCmdAbortPathCreation(FXObject *, FXSelector, void *)
Called when the user click over button "Abort route creation".
FXButton * myRemoveLastInsertedElement
button for removing last inserted element
FXCheckButton * myShowCandidateEdges
CheckBox for show candidate edges.
PathCreator(GNEFrame *frameParent)
default constructor
void hidePathCreatorModul()
show PathCreator
FXButton * myFinishCreationButton
button for finish route creation
void updateEdgeColors()
update edge colors
GNEAdditional * getFromStoppingPlace(SumoXMLTag expectedTag) const
get from stoppingPlace
PathLegend(GNEFrame *frameParent)
constructor
void hidePathLegendModul()
hide Legend modul
void showPathLegendModul()
show Legend modul
void refreshSelectorParentModul()
Refresh list of Additional Parents Modul.
std::string getIdSelected() const
get currently parent additional selected
FXLabel * myParentsLabel
Label with parent name.
SelectorParent(GNEFrame *frameParent)
constructor
void hideSelectorParentModul()
hide SelectorParent Modul
bool showSelectorParentModul(SumoXMLTag additionalTypeParent)
Show list of SelectorParent Modul.
FXList * myParentsList
List of parents.
void setIDSelected(const std::string &id)
select manually a element of the list
void hideTagSelector()
hide item selector
void setCurrentTagType(GNETagProperties::TagType tagType)
set current type manually
void refreshTagProperties()
due myCurrentTagProperties is a Reference, we need to refresh it when frameParent is show
long onCmdSelectTag(FXObject *, FXSelector, void *)
Called when the user select an elementin ComboBox.
const GNETagProperties & getCurrentTagProperties() const
get current type tag
long onCmdSelectTagType(FXObject *, FXSelector, void *)
void showTagSelector()
show item selector
void setCurrentTag(SumoXMLTag newTag)
set current type manually
static FXLabel * buildRainbow(FXComposite *parent)
build rainbow in frame modul
An Element which don't belongs to GNENet but has influency in the simulation.
GNEDataInterval * getDataIntervalParent() const
get data interval parent
const PositionVector & getShape() const
The shape of the additional element.
bool exist(const GNELane *toLane) const
check if exist a lane2lane geometry for the given tolane
const GNEGeometry::Geometry & getLane2laneGeometry(const GNELane *toLane) const
get lane2lane geometry
const std::vector< GNEJunction * > & getParentJunctions() const
get parent junctions
const std::vector< GNETAZElement * > & getChildTAZElements() const
get child TAZElements
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNELane * > & getChildLanes() const
get child lanes
const std::vector< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
const std::vector< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const std::vector< GNEEdge * > & getChildEdges() const
get child edges
const std::vector< GNEEdge * > & getParentEdges() const
get parent edges
const std::vector< GNELane * > & getParentLanes() const
get parent lanes
const std::vector< GNEShape * > & getChildShapes() const
get child shapes
const std::vector< GNETAZElement * > & getParentTAZElements() const
get parent TAZElements
const std::vector< GNEAdditional * > & getChildAdditionals() const
return child additionals
const std::vector< GNEGenericData * > & getChildGenericDatas() const
return child generic data elements
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:45
const PositionVector & getLaneShape() const
Definition: GNELane.cpp:117
const GNEGeometry::Lane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition: GNELane.cpp:774
std::vector< GNEConnection * > getGNEOutcomingConnections()
returns a vector with the outgoing GNEConnections of this lane
Definition: GNELane.cpp:1585
std::vector< GNEConnection * > getGNEIncomingConnections()
returns a vector with the incoming GNEConnections of this lane
Definition: GNELane.cpp:1564
GNEEdge * getParentEdge() const
get arent edge
Definition: GNELane.cpp:111
std::vector< GNEEdge * > calculatePath(const SUMOVehicleClass vClass, const std::vector< GNEEdge * > &partialEdges) const
calculate Dijkstra path between a list of partial edges
GNECrossing * retrieveCrossing(const std::string &id, bool failHard=true) const
get Crossing by id
Definition: GNENet.cpp:1213
GNELane * retrieveLane(const std::string &id, bool failHard=true, bool checkVolatileChange=false)
get lane by id
Definition: GNENet.cpp:1337
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true) const
get edge by id
Definition: GNENet.cpp:1141
GNEDataSet * retrieveDataSet(const std::string &id, bool hardFail=true) const
Returns the named data set.
Definition: GNENet.cpp:2590
GNETAZElement * retrieveTAZElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named TAZElement.
Definition: GNENet.cpp:3001
GNENetHelper::PathCalculator * getPathCalculator()
obtain instance of PathCalculator
Definition: GNENet.cpp:136
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
Definition: GNENet.cpp:2316
GNEShape * retrieveShape(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named shape.
Definition: GNENet.cpp:2944
GNEDemandElement * retrieveDemandElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named demand element.
Definition: GNENet.cpp:2435
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true) const
get junction by id
Definition: GNENet.cpp:1113
GNEConnection * retrieveConnection(const std::string &id, bool failHard=true) const
get Connection by id
Definition: GNENet.cpp:1177
std::string getHierarchyName() const
get Hierarchy Name (Used in AC Hierarchy)
const std::string & getID() const
get ID
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNETAZElement.h:45
bool isShape() const
return true if tag correspond to a shape
bool isTAZElement() const
return true if tag correspond to a TAZ element
bool isNetworkElement() const
return true if tag correspond to a network element
bool isDataElement() const
return true if tag correspond to a data element
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool isDemandElement() const
return true if tag correspond to a demand element
bool isAdditionalElement() const
return true if tag correspond to an additional element
class used to group all variables related with objects under cursor after a click over view
const std::vector< GNEAttributeCarrier * > & getClickedAttributeCarriers() const
get vector with clicked ACs
GNENet * getNet() const
get the net object
static FXMenuCommand * buildFXMenuCommand(FXComposite *p, const std::string &text, FXIcon *icon, FXObject *tgt, FXSelector sel)
build menu command
Definition: GUIDesigns.cpp:40
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings
Stores the information about how to visualize structures.
GUIVisualizationCandidateColorSettings candidateColorSettings
candidate color settings
static FXColor getFXColor(const RGBColor &col)
converts FXColor to RGBColor
Definition: MFXUtils.cpp:112
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
A list of positions.
static const RGBColor WHITE
Definition: RGBColor.h:187
static const RGBColor GREY
Definition: RGBColor.h:189
static const RGBColor ORANGE
Definition: RGBColor.h:186
static const std::vector< RGBColor > & getRainbowScaledColors()
get scaled rainbow colors
static const RGBColor special
color for selected special candidate element (Usually selected using shift+click)
static const RGBColor conflict
color for selected conflict candidate element (Usually selected using ctrl+click)
static const RGBColor target
color for selected candidate target
static const RGBColor possible
color for possible candidate element
static const RGBColor source
color for selected candidate source