Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/frames/GNEPlanCreator.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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
/****************************************************************************/
14
/// @file GNEPlanCreator.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Mar 2022
17
///
18
// Frame for create paths
19
/****************************************************************************/
20
21
#include <netedit/GNEApplicationWindow.h>
22
#include <netedit/GNENet.h>
23
#include <netedit/GNEViewNet.h>
24
#include <netedit/GNEViewParent.h>
25
#include <netedit/elements/additional/GNETAZ.h>
26
#include <netedit/elements/demand/GNEDemandElementPlan.h>
27
#include <netedit/elements/demand/GNEPlanParents.h>
28
#include <netedit/frames/common/GNEInspectorFrame.h>
29
#include <utils/gui/div/GLHelper.h>
30
#include <utils/gui/div/GUIDesigns.h>
31
#include <utils/gui/windows/GUIAppEnum.h>
32
33
#include "GNEPlanCreator.h"
34
35
// ===========================================================================
36
// FOX callback mapping
37
// ===========================================================================
38
39
FXDEFMAP(GNEPlanCreator) PathCreatorMap[] = {
40
FXMAPFUNC(SEL_COMMAND, MID_GNE_PATHCREATOR_ABORT, GNEPlanCreator::onCmdAbortPathCreation),
41
FXMAPFUNC(SEL_COMMAND, MID_GNE_PATHCREATOR_FINISH, GNEPlanCreator::onCmdCreatePath),
42
FXMAPFUNC(SEL_COMMAND, MID_GNE_PATHCREATOR_USELASTROUTE, GNEPlanCreator::onCmdUseLastRoute),
43
FXMAPFUNC(SEL_UPDATE, MID_GNE_PATHCREATOR_USELASTROUTE, GNEPlanCreator::onUpdUseLastRoute),
44
FXMAPFUNC(SEL_COMMAND, MID_GNE_PATHCREATOR_REMOVELAST, GNEPlanCreator::onCmdRemoveLastElement)
45
};
46
47
// Object implementation
48
FXIMPLEMENT(GNEPlanCreator, MFXGroupBoxModule, PathCreatorMap, ARRAYNUMBER(PathCreatorMap))
49
50
// ===========================================================================
51
// method definitions
52
// ===========================================================================
53
54
GNEPlanCreator::PlanPath::PlanPath(GNEPathManager* pathManager, const SUMOVehicleClass vClass, GNEEdge* fromEdge, GNEEdge* toEdge) :
55
myConflictVClass(false),
56
myConflictDisconnected(false) {
57
// calculate subpath using given vClass
58
mySubPath = pathManager->getPathCalculator()->calculateDijkstraPath(vClass, fromEdge, toEdge);
59
// if subPath is empty, try it with pedestrian (i.e. ignoring vCass)
60
if (mySubPath.empty()) {
61
mySubPath = pathManager->getPathCalculator()->calculateDijkstraPath(SVC_PEDESTRIAN, fromEdge, toEdge);
62
if (mySubPath.empty()) {
63
mySubPath = {fromEdge, toEdge};
64
myConflictDisconnected = true;
65
} else {
66
myConflictVClass = true;
67
}
68
}
69
}
70
71
72
GNEPlanCreator::PlanPath::PlanPath(GNEPathManager* pathManager, const SUMOVehicleClass vClass, GNEEdge* fromEdge, GNEJunction* toJunction) :
73
myConflictVClass(false),
74
myConflictDisconnected(false) {
75
// calculate subpath using given vClass
76
mySubPath = pathManager->getPathCalculator()->calculateDijkstraPath(vClass, fromEdge, toJunction);
77
// if subPath is empty, try it with pedestrian (i.e. ignoring vCass)
78
if (mySubPath.empty()) {
79
mySubPath = pathManager->getPathCalculator()->calculateDijkstraPath(SVC_PEDESTRIAN, fromEdge, toJunction);
80
if (mySubPath.empty()) {
81
mySubPath = {fromEdge};
82
myConflictDisconnected = true;
83
} else {
84
myConflictVClass = true;
85
}
86
}
87
88
}
89
90
91
GNEPlanCreator::PlanPath::PlanPath(GNEPathManager* pathManager, const SUMOVehicleClass vClass, GNEJunction* fromJunction, GNEEdge* toEdge) :
92
myConflictVClass(false),
93
myConflictDisconnected(false) {
94
// calculate subpath using given vClass
95
mySubPath = pathManager->getPathCalculator()->calculateDijkstraPath(vClass, fromJunction, toEdge);
96
// if subPath is empty, try it with pedestrian (i.e. ignoring vCass)
97
if (mySubPath.empty()) {
98
mySubPath = pathManager->getPathCalculator()->calculateDijkstraPath(SVC_PEDESTRIAN, fromJunction, toEdge);
99
if (mySubPath.empty()) {
100
mySubPath = {toEdge};
101
myConflictDisconnected = true;
102
} else {
103
myConflictVClass = true;
104
}
105
}
106
107
}
108
109
110
GNEPlanCreator::PlanPath::PlanPath(GNEPathManager* pathManager, const SUMOVehicleClass vClass, GNEJunction* fromJunction, GNEJunction* toJunction) :
111
myConflictVClass(false),
112
myConflictDisconnected(false) {
113
// calculate subpath using the given vClass
114
mySubPath = pathManager->getPathCalculator()->calculateDijkstraPath(vClass, fromJunction, toJunction);
115
// if subPath is empty, try it with pedestrian (i.e. ignoring vCass)
116
if (mySubPath.empty()) {
117
if (mySubPath.empty()) {
118
myConflictDisconnected = true;
119
} else {
120
myConflictVClass = true;
121
}
122
}
123
124
}
125
126
127
const std::vector<GNEEdge*>&
128
GNEPlanCreator::PlanPath::getSubPath() const {
129
return mySubPath;
130
}
131
132
133
bool
134
GNEPlanCreator::PlanPath::isConflictVClass() const {
135
return myConflictVClass;
136
}
137
138
139
bool
140
GNEPlanCreator::PlanPath::isConflictDisconnected() const {
141
return myConflictDisconnected;
142
}
143
144
145
GNEPlanCreator::PlanPath::PlanPath() :
146
myConflictVClass(false),
147
myConflictDisconnected(false) {
148
}
149
150
151
GNEPlanCreator::GNEPlanCreator(GNEFrame* frameParent, GNEPathManager* pathManager) :
152
MFXGroupBoxModule(frameParent, TL("Route creator")),
153
myFrameParent(frameParent),
154
myPathManager(pathManager),
155
myVClass(SVC_PASSENGER),
156
myPlanParents(0) {
157
// create button for use last route
158
myUseLastRoute = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Use last route"), "", "", GUIIconSubSys::getIcon(GUIIcon::ROUTE), this, MID_GNE_PATHCREATOR_USELASTROUTE, GUIDesignButton);
159
myUseLastRoute->disable();
160
// create button for finish route creation
161
myFinishCreationButton = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Finish route creation"), "", "", nullptr, this, MID_GNE_PATHCREATOR_FINISH, GUIDesignButton);
162
myFinishCreationButton->disable();
163
// create button for abort route creation
164
myAbortCreationButton = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Abort route creation"), "", "", nullptr, this, MID_GNE_PATHCREATOR_ABORT, GUIDesignButton);
165
myAbortCreationButton->disable();
166
// create button for remove last inserted edge
167
myRemoveLastInsertedElement = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Remove last element"), "", "", nullptr, this, MID_GNE_PATHCREATOR_REMOVELAST, GUIDesignButton);
168
myRemoveLastInsertedElement->disable();
169
// create info label
170
myInfoLabel = new FXLabel(this, "", 0, GUIDesignLabelFrameInformation);
171
}
172
173
174
GNEPlanCreator::~GNEPlanCreator() {}
175
176
177
bool
178
GNEPlanCreator::planCanBeCreated(const GNEDemandElement* planTemplate) const {
179
if (planTemplate == nullptr) {
180
return false;
181
} else if (planTemplate->getTagProperty()->isPlanPersonTrip()) {
182
return myPlanParameteres.getPersonTripTag() != SUMO_TAG_NOTHING;
183
} else if (planTemplate->getTagProperty()->isPlanWalk()) {
184
return myPlanParameteres.getWalkTag() != SUMO_TAG_NOTHING;
185
} else if (planTemplate->getTagProperty()->isPlanRide()) {
186
return myPlanParameteres.getRideTag() != SUMO_TAG_NOTHING;
187
} else if (planTemplate->getTagProperty()->isPlanTransport()) {
188
return myPlanParameteres.getTransportTag() != SUMO_TAG_NOTHING;
189
} else if (planTemplate->getTagProperty()->isPlanTranship()) {
190
return myPlanParameteres.getTranshipTag() != SUMO_TAG_NOTHING;
191
} else if (planTemplate->getTagProperty()->isPlanStopPerson()) {
192
return myPlanParameteres.getPersonStopTag() != SUMO_TAG_NOTHING;
193
} else if (planTemplate->getTagProperty()->isPlanStopContainer()) {
194
return myPlanParameteres.getContainerStopTag() != SUMO_TAG_NOTHING;
195
} else {
196
return false;
197
}
198
}
199
200
201
void
202
GNEPlanCreator::showPlanCreatorModule(const GNEPlanSelector* planSelector, const GNEDemandElement* previousPlan) {
203
// first abort creation
204
abortPathCreation();
205
// hide creation buttons
206
hideCreationButtons();
207
// reset plan parents
208
myPlanParents = 0;
209
// set previous plan element
210
myPreviousPlanElement = previousPlan;
211
// get current plan template
212
const auto& planTagProperty = planSelector->getCurrentPlanTagProperties();
213
// continue depending of plan selector template
214
if (planTagProperty->planRoute()) {
215
myPlanParents |= ROUTE;
216
// show use last inserted route
217
myUseLastRoute->show();
218
} else {
219
// hide use last inserted route
220
myUseLastRoute->hide();
221
}
222
if (planTagProperty->planEdge()) {
223
myPlanParents |= EDGE;
224
}
225
if (planTagProperty->planStoppingPlace()) {
226
myPlanParents |= STOPPINGPLACE;
227
}
228
if (planTagProperty->planConsecutiveEdges()) {
229
myPlanParents |= CONSECUTIVE_EDGES;
230
// show creation buttons
231
showCreationButtons();
232
}
233
if (planTagProperty->planFromEdge() || planTagProperty->planToEdge()) {
234
myPlanParents |= START_EDGE;
235
myPlanParents |= END_EDGE;
236
// show creation buttons
237
showCreationButtons();
238
}
239
if (planTagProperty->planFromJunction() || planTagProperty->planToJunction()) {
240
myPlanParents |= START_JUNCTION;
241
myPlanParents |= END_JUNCTION;
242
// show creation buttons
243
showCreationButtons();
244
}
245
if (planTagProperty->planFromTAZ() || planTagProperty->planToTAZ()) {
246
myPlanParents |= START_TAZ;
247
myPlanParents |= END_TAZ;
248
// show creation buttons
249
showCreationButtons();
250
}
251
if (planTagProperty->planFromStoppingPlace() || planTagProperty->planToStoppingPlace()) {
252
myPlanParents |= START_STOPPINGPLACE;
253
myPlanParents |= END_STOPPINGPLACE;
254
// show creation buttons
255
showCreationButtons();
256
}
257
// update info label (after setting myPlanParents)
258
updateInfoLabel();
259
// check if add first element
260
if (myPreviousPlanElement && planTagProperty->planFromTo()) {
261
const auto previousTagProperty = myPreviousPlanElement->getTagProperty();
262
// add last element of previous plan
263
if (previousTagProperty->planToEdge() || previousTagProperty->planEdge()) {
264
addFromToEdge(myPreviousPlanElement->getParentEdges().back());
265
} else if (previousTagProperty->planToJunction()) {
266
addFromToJunction(myPreviousPlanElement->getParentJunctions().back());
267
} else if (previousTagProperty->planToTAZ()) {
268
addFromToTAZ(myPreviousPlanElement->getParentTAZs().back());
269
} else if (previousTagProperty->planToStoppingPlace() || previousTagProperty->planStoppingPlace()) {
270
addFromToStoppingPlace(myPreviousPlanElement->getParentStoppingPlaces().back());
271
}
272
}
273
// set vClass
274
if (planTagProperty->isPlanRide() || planTagProperty->isPlanContainer()) {
275
myVClass = SVC_PASSENGER;
276
} else {
277
myVClass = SVC_PEDESTRIAN;
278
}
279
// recalc before show (to avoid graphic problems)
280
recalc();
281
// show modul
282
show();
283
}
284
285
286
void
287
GNEPlanCreator::hidePathCreatorModule() {
288
// clear path
289
clearPath();
290
// hide modul
291
hide();
292
}
293
294
295
bool
296
GNEPlanCreator::addRoute(GNEDemandElement* route) {
297
// check if routes are allowed
298
if ((myPlanParents & ROUTE) == 0) {
299
return false;
300
}
301
// add edge
302
myPlanParameteres.toRoute = route->getID();
303
// create path
304
return myFrameParent->createPath(false);
305
}
306
307
308
bool
309
GNEPlanCreator::addEdge(GNELane* lane) {
310
// continue depending of plan parent
311
if (myPlanParents & CONSECUTIVE_EDGES) {
312
return addConsecutiveEdge(lane->getParentEdge());
313
} else if (myPlanParents & EDGE) {
314
return addSingleEdge(lane);
315
} else if ((myPlanParents & START_EDGE) || (myPlanParents & END_EDGE)) {
316
return addFromToEdge(lane->getParentEdge());
317
} else {
318
return false;
319
}
320
}
321
322
323
bool
324
GNEPlanCreator::addJunction(GNEJunction* junction) {
325
if ((myPlanParents & START_JUNCTION) || (myPlanParents & END_JUNCTION)) {
326
return addFromToJunction(junction);
327
} else {
328
return false;
329
}
330
}
331
332
333
bool
334
GNEPlanCreator::addTAZ(GNEAdditional* taz) {
335
if ((myPlanParents & START_TAZ) || (myPlanParents & END_TAZ)) {
336
return addFromToTAZ(taz);
337
} else {
338
return false;
339
}
340
}
341
342
343
bool
344
GNEPlanCreator::addStoppingPlace(GNEAdditional* stoppingPlace) {
345
if (myPlanParents & STOPPINGPLACE) {
346
return addSingleStoppingPlace(stoppingPlace);
347
} else if ((myPlanParents & START_STOPPINGPLACE) || (myPlanParents & END_STOPPINGPLACE)) {
348
return addFromToStoppingPlace(stoppingPlace);
349
} else {
350
return false;
351
}
352
}
353
354
355
const CommonXMLStructure::PlanParameters&
356
GNEPlanCreator::getPlanParameteres() const {
357
return myPlanParameteres;
358
}
359
360
361
double
362
GNEPlanCreator::getClickedPositionOverLane() const {
363
return myClickedPositionOverLane;
364
}
365
366
367
const std::vector<GNEPlanCreator::PlanPath>&
368
GNEPlanCreator::getPath() const {
369
return myPath;
370
}
371
372
373
void
374
GNEPlanCreator::drawTemporalRoute(const GUIVisualizationSettings& s) const {
375
const auto& ACs = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();
376
const double lineWidth = 0.35;
377
const double lineWidthin = 0.25;
378
// Add a draw matrix
379
GLHelper::pushMatrix();
380
// Start with the drawing of the area traslating matrix to origin
381
glTranslated(0, 0, GLO_MAX - 0.1);
382
// check if draw bewteen junction or edges
383
if (myPath.size() > 0) {
384
// set first color
385
GLHelper::setColor(RGBColor::GREY);
386
// iterate over path
387
for (int i = 0; i < (int)myPath.size(); i++) {
388
// get path
389
const GNEPlanCreator::PlanPath& path = myPath.at(i);
390
// draw line over
391
for (int j = 0; j < (int)path.getSubPath().size(); j++) {
392
const GNELane* lane = path.getSubPath().at(j)->getChildLanes().back();
393
if (((i == 0) && (j == 0)) || (j > 0)) {
394
GLHelper::drawBoxLines(lane->getLaneShape(), lineWidth);
395
}
396
// draw connection between lanes
397
if ((j + 1) < (int)path.getSubPath().size()) {
398
const GNELane* nextLane = path.getSubPath().at(j + 1)->getChildLanes().back();
399
if (lane->getLane2laneConnections().exist(nextLane)) {
400
GLHelper::drawBoxLines(lane->getLane2laneConnections().getLane2laneGeometry(nextLane).getShape(), lineWidth);
401
} else {
402
GLHelper::drawBoxLines({lane->getLaneShape().back(), nextLane->getLaneShape().front()}, lineWidth);
403
}
404
}
405
}
406
}
407
glTranslated(0, 0, 0.1);
408
// iterate over path again
409
for (int i = 0; i < (int)myPath.size(); i++) {
410
// get path
411
const GNEPlanCreator::PlanPath& path = myPath.at(i);
412
// set path color color
413
if (path.isConflictDisconnected()) {
414
GLHelper::setColor(s.candidateColorSettings.conflict);
415
} else if (path.isConflictVClass()) {
416
GLHelper::setColor(s.candidateColorSettings.special);
417
} else {
418
GLHelper::setColor(RGBColor::ORANGE);
419
}
420
// draw line over
421
for (int j = 0; j < (int)path.getSubPath().size(); j++) {
422
const GNELane* lane = path.getSubPath().at(j)->getChildLanes().back();
423
if (((i == 0) && (j == 0)) || (j > 0)) {
424
GLHelper::drawBoxLines(lane->getLaneShape(), lineWidthin);
425
}
426
// draw connection between lanes
427
if ((j + 1) < (int)path.getSubPath().size()) {
428
const GNELane* nextLane = path.getSubPath().at(j + 1)->getChildLanes().back();
429
if (lane->getLane2laneConnections().exist(nextLane)) {
430
GLHelper::drawBoxLines(lane->getLane2laneConnections().getLane2laneGeometry(nextLane).getShape(), lineWidthin);
431
} else {
432
GLHelper::drawBoxLines({ lane->getLaneShape().back(), nextLane->getLaneShape().front() }, lineWidthin);
433
}
434
}
435
}
436
}
437
} else if (!myPlanParameteres.fromJunction.empty() && !myPlanParameteres.toJunction.empty()) {
438
// set color
439
GLHelper::setColor(RGBColor::ORANGE);
440
// get two points
441
const Position posA = ACs->getJunctions().at(myPlanParameteres.fromJunction)->getPositionInView();
442
const Position posB = ACs->getJunctions().at(myPlanParameteres.toJunction)->getPositionInView();
443
const double rot = ((double)atan2((posB.x() - posA.x()), (posA.y() - posB.y())) * (double) 180.0 / (double)M_PI);
444
const double len = posA.distanceTo2D(posB);
445
// draw line
446
GLHelper::drawBoxLine(posA, rot, len, 0.25);
447
} else if (!myPlanParameteres.fromTAZ.empty() && !myPlanParameteres.toTAZ.empty()) {
448
// set color
449
GLHelper::setColor(RGBColor::ORANGE);
450
// get two points
451
const Position posA = ACs->retrieveAdditional(SUMO_TAG_TAZ, myPlanParameteres.fromTAZ)->getPositionInView();
452
const Position posB = ACs->retrieveAdditional(SUMO_TAG_TAZ, myPlanParameteres.toTAZ)->getPositionInView();
453
const double rot = ((double)atan2((posB.x() - posA.x()), (posA.y() - posB.y())) * (double) 180.0 / (double)M_PI);
454
const double len = posA.distanceTo2D(posB);
455
// draw line
456
GLHelper::drawBoxLine(posA, rot, len, 0.25);
457
}
458
// Pop last matrix
459
GLHelper::popMatrix();
460
}
461
462
463
void
464
GNEPlanCreator::abortPathCreation() {
465
// first check that there is elements
466
if (getNumberOfSelectedElements() > 0) {
467
// unblock undo/redo
468
myFrameParent->getViewNet()->getViewParent()->getGNEAppWindows()->enableUndoRedoTemporally();
469
// clear edges
470
clearPath();
471
// disable buttons
472
myFinishCreationButton->disable();
473
myAbortCreationButton->disable();
474
myRemoveLastInsertedElement->disable();
475
// update view (to see the new route)
476
myFrameParent->getViewNet()->updateViewNet();
477
}
478
}
479
480
481
void
482
GNEPlanCreator::removeLastElement() {
483
if (myRemoveLastInsertedElement->isEnabled()) {
484
if (myPlanParameteres.consecutiveEdges.size() > 0) {
485
myPlanParameteres.consecutiveEdges.pop_back();
486
} else if (!myPlanParameteres.toEdge.empty()) {
487
myPlanParameteres.toEdge.clear();
488
} else if (!myPlanParameteres.toJunction.empty()) {
489
myPlanParameteres.toJunction.clear();
490
} else if (!myPlanParameteres.toTAZ.empty()) {
491
myPlanParameteres.toTAZ.clear();
492
} else if (!myPlanParameteres.toBusStop.empty()) {
493
myPlanParameteres.toBusStop.clear();
494
} else if (!myPlanParameteres.toTrainStop.empty()) {
495
myPlanParameteres.toBusStop.clear();
496
} else if (!myPlanParameteres.toContainerStop.empty()) {
497
myPlanParameteres.toBusStop.clear();
498
} else if (!myPlanParameteres.toChargingStation.empty()) {
499
myPlanParameteres.toBusStop.clear();
500
} else if (!myPlanParameteres.toParkingArea.empty()) {
501
myPlanParameteres.toBusStop.clear();
502
} else if (!myPlanParameteres.fromEdge.empty()) {
503
myPlanParameteres.fromEdge.clear();
504
} else if (!myPlanParameteres.fromJunction.empty()) {
505
myPlanParameteres.fromJunction.clear();
506
} else if (!myPlanParameteres.fromTAZ.empty()) {
507
myPlanParameteres.fromTAZ.clear();
508
} else if (!myPlanParameteres.fromBusStop.empty()) {
509
myPlanParameteres.fromBusStop.clear();
510
} else if (!myPlanParameteres.fromTrainStop.empty()) {
511
myPlanParameteres.fromBusStop.clear();
512
} else if (!myPlanParameteres.fromContainerStop.empty()) {
513
myPlanParameteres.fromBusStop.clear();
514
} else if (!myPlanParameteres.fromChargingStation.empty()) {
515
myPlanParameteres.fromBusStop.clear();
516
} else if (!myPlanParameteres.fromParkingArea.empty()) {
517
myPlanParameteres.fromBusStop.clear();
518
}
519
// update remove last item button
520
updateRemoveLastItemButton();
521
// recalculate path
522
recalculatePath();
523
}
524
}
525
526
527
long
528
GNEPlanCreator::onCmdCreatePath(FXObject*, FXSelector, void*) {
529
// call create path
530
return myFrameParent->createPath(false);
531
}
532
533
534
long
535
GNEPlanCreator::onCmdUseLastRoute(FXObject*, FXSelector, void*) {
536
// call create path using last route
537
return myFrameParent->createPath(true);
538
}
539
540
541
long
542
GNEPlanCreator::onUpdUseLastRoute(FXObject* sender, FXSelector, void*) {
543
if ((myPlanParents & ROUTE) && myFrameParent->getViewNet()->getLastCreatedRoute()) {
544
return sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), nullptr);
545
} else {
546
return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
547
}
548
}
549
550
long
551
GNEPlanCreator::onCmdAbortPathCreation(FXObject*, FXSelector, void*) {
552
// just call abort path creation
553
abortPathCreation();
554
return 1;
555
}
556
557
558
long
559
GNEPlanCreator::onCmdRemoveLastElement(FXObject*, FXSelector, void*) {
560
// just call remove last element
561
removeLastElement();
562
return 1;
563
}
564
565
566
void
567
GNEPlanCreator::clearPath() {
568
// clear all elements
569
myPlanParameteres.clear();
570
myClickedPositionOverLane = 0;
571
// clear path
572
myPath.clear();
573
}
574
575
576
void
577
GNEPlanCreator::recalculatePath() {
578
const auto& ACs = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();
579
// first clear path
580
myPath.clear();
581
// continue depending of elements
582
if (myPlanParameteres.consecutiveEdges.size() > 0) {
583
// add every segment
584
for (int i = 1; i < (int)myPlanParameteres.consecutiveEdges.size(); i++) {
585
myPath.push_back(PlanPath(myPathManager, myVClass,
586
ACs->retrieveEdge(myPlanParameteres.consecutiveEdges.at(i - 1)),
587
ACs->retrieveEdge(myPlanParameteres.consecutiveEdges.at(i))));
588
}
589
} else {
590
// get from edge
591
GNEEdge* fromEdge = nullptr;
592
if (!myPlanParameteres.fromEdge.empty()) {
593
fromEdge = ACs->retrieveEdge(myPlanParameteres.fromEdge);
594
} else if (!myPlanParameteres.fromBusStop.empty()) {
595
fromEdge = ACs->retrieveAdditional(SUMO_TAG_BUS_STOP, myPlanParameteres.fromBusStop)->getParentLanes().front()->getParentEdge();
596
} else if (!myPlanParameteres.fromTrainStop.empty()) {
597
fromEdge = ACs->retrieveAdditional(SUMO_TAG_TRAIN_STOP, myPlanParameteres.fromTrainStop)->getParentLanes().front()->getParentEdge();
598
} else if (!myPlanParameteres.fromContainerStop.empty()) {
599
fromEdge = ACs->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, myPlanParameteres.fromContainerStop)->getParentLanes().front()->getParentEdge();
600
} else if (!myPlanParameteres.fromChargingStation.empty()) {
601
fromEdge = ACs->retrieveAdditional(SUMO_TAG_CHARGING_STATION, myPlanParameteres.fromChargingStation)->getParentLanes().front()->getParentEdge();
602
} else if (!myPlanParameteres.fromParkingArea.empty()) {
603
fromEdge = ACs->retrieveAdditional(SUMO_TAG_PARKING_AREA, myPlanParameteres.fromParkingArea)->getParentLanes().front()->getParentEdge();
604
}
605
// get to edge
606
GNEEdge* toEdge = nullptr;
607
if (!myPlanParameteres.toEdge.empty()) {
608
toEdge = ACs->retrieveEdge(myPlanParameteres.toEdge);
609
} else if (!myPlanParameteres.toBusStop.empty()) {
610
toEdge = ACs->retrieveAdditional(SUMO_TAG_BUS_STOP, myPlanParameteres.toBusStop)->getParentLanes().front()->getParentEdge();
611
} else if (!myPlanParameteres.toTrainStop.empty()) {
612
toEdge = ACs->retrieveAdditional(SUMO_TAG_TRAIN_STOP, myPlanParameteres.toTrainStop)->getParentLanes().front()->getParentEdge();
613
} else if (!myPlanParameteres.toContainerStop.empty()) {
614
toEdge = ACs->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, myPlanParameteres.toContainerStop)->getParentLanes().front()->getParentEdge();
615
} else if (!myPlanParameteres.toChargingStation.empty()) {
616
toEdge = ACs->retrieveAdditional(SUMO_TAG_CHARGING_STATION, myPlanParameteres.toChargingStation)->getParentLanes().front()->getParentEdge();
617
} else if (!myPlanParameteres.toParkingArea.empty()) {
618
toEdge = ACs->retrieveAdditional(SUMO_TAG_PARKING_AREA, myPlanParameteres.toParkingArea)->getParentLanes().front()->getParentEdge();
619
}
620
// continue depending of edges and junctions
621
if (fromEdge && toEdge) {
622
myPath.push_back(PlanPath(myPathManager, myVClass, fromEdge, toEdge));
623
} else if (fromEdge && !myPlanParameteres.toJunction.empty()) {
624
myPath.push_back(PlanPath(myPathManager, myVClass, fromEdge, ACs->getJunctions().at(myPlanParameteres.toJunction)));
625
} else if (!myPlanParameteres.fromJunction.empty() && toEdge) {
626
myPath.push_back(PlanPath(myPathManager, myVClass, ACs->getJunctions().at(myPlanParameteres.fromJunction), toEdge));
627
} else if (!myPlanParameteres.fromJunction.empty() && !myPlanParameteres.toJunction.empty()) {
628
myPath.push_back(PlanPath(myPathManager, myVClass,
629
ACs->getJunctions().at(myPlanParameteres.fromJunction),
630
ACs->getJunctions().at(myPlanParameteres.toJunction)));
631
}
632
}
633
}
634
635
636
int
637
GNEPlanCreator::getNumberOfSelectedElements() const {
638
return myPlanParameteres.getNumberOfDefinedParameters();
639
}
640
641
642
void
643
GNEPlanCreator::updateRemoveLastItemButton() const {
644
if (myPreviousPlanElement) {
645
if (getNumberOfSelectedElements() == 2) {
646
myRemoveLastInsertedElement->enable();
647
} else {
648
myRemoveLastInsertedElement->disable();
649
}
650
} else {
651
if (getNumberOfSelectedElements() > 0) {
652
myRemoveLastInsertedElement->enable();
653
} else {
654
myRemoveLastInsertedElement->disable();
655
}
656
}
657
}
658
659
660
void
661
GNEPlanCreator::showCreationButtons() {
662
myFinishCreationButton->show();
663
myAbortCreationButton->show();
664
myRemoveLastInsertedElement->show();
665
}
666
667
668
void
669
GNEPlanCreator::hideCreationButtons() {
670
myFinishCreationButton->hide();
671
myAbortCreationButton->hide();
672
myRemoveLastInsertedElement->hide();
673
}
674
675
676
void
677
GNEPlanCreator::updateInfoLabel() {
678
// declare booleans
679
const bool consecutiveEdges = (myPlanParents & CONSECUTIVE_EDGES);
680
const bool route = (myPlanParents & ROUTE);
681
const bool edges = (myPlanParents & EDGE) ||
682
(myPlanParents & START_EDGE) ||
683
(myPlanParents & END_EDGE);
684
const bool TAZs = (myPlanParents & START_TAZ) ||
685
(myPlanParents & END_TAZ);
686
const bool junctions = (myPlanParents & START_JUNCTION) ||
687
(myPlanParents & END_JUNCTION);
688
const bool stoppingPlace = (myPlanParents & STOPPINGPLACE) ||
689
(myPlanParents & START_STOPPINGPLACE) ||
690
(myPlanParents & END_STOPPINGPLACE);
691
692
// declare ostringstream for label and fill it
693
std::ostringstream information;
694
information
695
<< TL("Click over:") << "\n"
696
<< (consecutiveEdges ? "- Consecutive edges\n" : "")
697
<< (route ? "- Routes\n" : "")
698
<< (edges ? "- Edges\n" : "")
699
<< (TAZs ? "- TAZs\n" : "")
700
<< (junctions ? "- Junctions\n" : "")
701
<< (stoppingPlace ? "- StoppingPlaces\n" : "");
702
// remove last \n
703
std::string informationStr = information.str();
704
informationStr.pop_back();
705
// set label text
706
myInfoLabel->setText(informationStr.c_str());
707
}
708
709
710
bool
711
GNEPlanCreator::addSingleEdge(GNELane* lane) {
712
// add edge
713
myPlanParameteres.toEdge = lane->getParentEdge()->getID();
714
// set position over lane
715
const auto clickedPos = myFrameParent->getViewNet()->getPositionInformation();
716
myClickedPositionOverLane = lane->getLaneShape().nearest_offset_to_point2D(clickedPos);
717
// create path
718
return myFrameParent->createPath(false);
719
}
720
721
722
bool
723
GNEPlanCreator::addSingleStoppingPlace(GNEAdditional* stoppingPlace) {
724
// continue depending of stoppingPlace tag
725
switch (stoppingPlace->getTagProperty()->getTag()) {
726
case SUMO_TAG_BUS_STOP:
727
myPlanParameteres.toBusStop = stoppingPlace->getID();
728
break;
729
case SUMO_TAG_TRAIN_STOP:
730
myPlanParameteres.toTrainStop = stoppingPlace->getID();
731
break;
732
case SUMO_TAG_CONTAINER_STOP:
733
myPlanParameteres.toContainerStop = stoppingPlace->getID();
734
break;
735
case SUMO_TAG_CHARGING_STATION:
736
myPlanParameteres.toChargingStation = stoppingPlace->getID();
737
break;
738
case SUMO_TAG_PARKING_AREA:
739
myPlanParameteres.toParkingArea = stoppingPlace->getID();
740
break;
741
default:
742
// abort creation
743
return false;
744
}
745
// create path
746
return myFrameParent->createPath(false);
747
}
748
749
750
bool
751
GNEPlanCreator::addConsecutiveEdge(GNEEdge* edge) {
752
// check double edges
753
if ((myPlanParameteres.consecutiveEdges.size() > 0) && (myPlanParameteres.consecutiveEdges.back() == edge->getID())) {
754
// Write warning
755
WRITE_WARNING(TL("Double edges aren't allowed"));
756
// abort add edge
757
return false;
758
}
759
// All checks ok, then add it in selected elements
760
myPlanParameteres.consecutiveEdges.push_back(edge->getID());
761
// enable abort route button
762
myAbortCreationButton->enable();
763
// enable finish button
764
myFinishCreationButton->enable();
765
// update remove last item button
766
updateRemoveLastItemButton();
767
// recalculate path
768
recalculatePath();
769
// edge added, then return true
770
return true;
771
}
772
773
774
bool
775
GNEPlanCreator::addFromToJunction(GNEJunction* junction) {
776
// avoid double junctions
777
if (myPlanParameteres.fromJunction == junction->getID()) {
778
// Write warning
779
WRITE_WARNING(TL("Double junctions aren't allowed"));
780
// abort add junction
781
return false;
782
}
783
// check number of selected items
784
if (getNumberOfSelectedElements() == 2) {
785
// Write warning
786
WRITE_WARNING(TL("Only two from-to elements are allowed"));
787
// abort add function
788
return false;
789
}
790
// set junction
791
if (getNumberOfSelectedElements() == 0) {
792
myPlanParameteres.fromJunction = junction->getID();
793
} else {
794
myPlanParameteres.toJunction = junction->getID();
795
}
796
// enable abort route button
797
myAbortCreationButton->enable();
798
// enable finish button
799
myFinishCreationButton->enable();
800
// update remove last item button
801
updateRemoveLastItemButton();
802
// recalculate path
803
recalculatePath();
804
return true;
805
}
806
807
808
bool
809
GNEPlanCreator::addFromToTAZ(GNEAdditional* TAZ) {
810
// avoid double TAZs
811
if (myPlanParameteres.fromTAZ == TAZ->getID()) {
812
// Write warning
813
WRITE_WARNING(TL("Double TAZs aren't allowed"));
814
// abort add TAZ
815
return false;
816
}
817
// check number of selected items
818
if (getNumberOfSelectedElements() == 2) {
819
// Write warning
820
WRITE_WARNING(TL("Only two from-to elements are allowed"));
821
// abort add function
822
return false;
823
}
824
// set TAZ
825
if (getNumberOfSelectedElements() == 0) {
826
myPlanParameteres.fromTAZ = TAZ->getID();
827
} else {
828
myPlanParameteres.toTAZ = TAZ->getID();
829
}
830
// enable abort route button
831
myAbortCreationButton->enable();
832
// enable finish button
833
myFinishCreationButton->enable();
834
// update remove last item button
835
updateRemoveLastItemButton();
836
// recalculate path
837
recalculatePath();
838
return true;
839
}
840
841
842
bool
843
GNEPlanCreator::addFromToEdge(GNEEdge* edge) {
844
// check double edges
845
if (myPlanParameteres.fromEdge == edge->getID()) {
846
// Write warning
847
WRITE_WARNING(TL("Double edges aren't allowed"));
848
// abort add edge
849
return false;
850
}
851
// check number of selected items
852
if (getNumberOfSelectedElements() == 2) {
853
// Write warning
854
WRITE_WARNING(TL("Only two from-to elements are allowed"));
855
// abort add function
856
return false;
857
}
858
// set edge
859
if (getNumberOfSelectedElements() == 0) {
860
myPlanParameteres.fromEdge = edge->getID();
861
} else {
862
myPlanParameteres.toEdge = edge->getID();
863
}
864
// enable abort route button
865
myAbortCreationButton->enable();
866
// enable finish button
867
myFinishCreationButton->enable();
868
// update remove last item button
869
updateRemoveLastItemButton();
870
// recalculate path
871
recalculatePath();
872
// edge added, then return true
873
return true;
874
}
875
876
877
bool
878
GNEPlanCreator::addFromToStoppingPlace(GNEAdditional* stoppingPlace) {
879
// check double stoppingPlaces
880
const auto stoppingPlaceID = stoppingPlace->getID();
881
if ((myPlanParameteres.toBusStop == stoppingPlaceID) ||
882
(myPlanParameteres.toTrainStop == stoppingPlaceID) ||
883
(myPlanParameteres.toContainerStop == stoppingPlaceID) ||
884
(myPlanParameteres.toChargingStation == stoppingPlaceID) ||
885
(myPlanParameteres.toParkingArea == stoppingPlaceID)) {
886
// Write warning
887
WRITE_WARNING(TL("Double stoppingPlaces aren't allowed"));
888
// abort add stopping place
889
return false;
890
}
891
// check number of selected items
892
if (getNumberOfSelectedElements() == 2) {
893
// Write warning
894
WRITE_WARNING(TL("Only two from-to elements are allowed"));
895
// abort add function
896
return false;
897
}
898
// add stoppingPlace
899
if (getNumberOfSelectedElements() == 0) {
900
// continue depending of stoppingPlace tag
901
switch (stoppingPlace->getTagProperty()->getTag()) {
902
case SUMO_TAG_BUS_STOP:
903
myPlanParameteres.fromBusStop = stoppingPlaceID;
904
break;
905
case SUMO_TAG_TRAIN_STOP:
906
myPlanParameteres.fromTrainStop = stoppingPlaceID;
907
break;
908
case SUMO_TAG_CONTAINER_STOP:
909
myPlanParameteres.fromContainerStop = stoppingPlaceID;
910
break;
911
case SUMO_TAG_CHARGING_STATION:
912
myPlanParameteres.fromChargingStation = stoppingPlaceID;
913
break;
914
case SUMO_TAG_PARKING_AREA:
915
myPlanParameteres.fromParkingArea = stoppingPlaceID;
916
break;
917
default:
918
return false;
919
}
920
} else {
921
// continue depending of stoppingPlace tag
922
switch (stoppingPlace->getTagProperty()->getTag()) {
923
case SUMO_TAG_BUS_STOP:
924
myPlanParameteres.toBusStop = stoppingPlaceID;
925
break;
926
case SUMO_TAG_TRAIN_STOP:
927
myPlanParameteres.toTrainStop = stoppingPlaceID;
928
break;
929
case SUMO_TAG_CONTAINER_STOP:
930
myPlanParameteres.toContainerStop = stoppingPlaceID;
931
break;
932
case SUMO_TAG_CHARGING_STATION:
933
myPlanParameteres.toChargingStation = stoppingPlaceID;
934
break;
935
case SUMO_TAG_PARKING_AREA:
936
myPlanParameteres.toParkingArea = stoppingPlaceID;
937
break;
938
default:
939
return false;
940
}
941
}
942
// enable abort route button
943
myAbortCreationButton->enable();
944
// enable finish button
945
myFinishCreationButton->enable();
946
// disable undo/redo
947
myFrameParent->getViewNet()->getViewParent()->getGNEAppWindows()->disableUndoRedoTemporally("creation of stoppingPlace path");
948
// enable or disable remove last item button
949
updateRemoveLastItemButton();
950
// recalculate path
951
recalculatePath();
952
// stopping place added, then return true
953
return true;
954
}
955
956
/****************************************************************************/
957
958