Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GUISUMOAbstractView.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2023 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/****************************************************************************/
22// The base class for a view
23/****************************************************************************/
24#include <config.h>
25
26#include <iostream>
27#include <utility>
28#include <cmath>
29#include <cassert>
30#include <limits>
31#include <fxkeys.h>
32#ifdef HAVE_GL2PS
33#include <gl2ps.h>
34#endif
63
64#include <unordered_set>
65
66#include "GUISUMOAbstractView.h"
67#include "GUIMainWindow.h"
68#include "GUIGlChildWindow.h"
71
72#ifdef HAVE_GDAL
73#ifdef _MSC_VER
74#pragma warning(push)
75#pragma warning(disable: 4435 5219 5220)
76#endif
77#if __GNUC__ > 3
78#pragma GCC diagnostic push
79#pragma GCC diagnostic ignored "-Wpedantic"
80#endif
81#include <gdal_priv.h>
82#if __GNUC__ > 3
83#pragma GCC diagnostic pop
84#endif
85#ifdef _MSC_VER
86#pragma warning(pop)
87#endif
88#endif
89
90
91// ===========================================================================
92// debug constants
93// ===========================================================================
94//#define DEBUG_SNAPSHOT
95
96// ===========================================================================
97// static members
98// ===========================================================================
99
100const double GUISUMOAbstractView::SENSITIVITY = 0.1; // meters
101
102
103// ===========================================================================
104// member method definitions
105// ===========================================================================
106/* -------------------------------------------------------------------------
107 * GUISUMOAbstractView - FOX callback mapping
108 * ----------------------------------------------------------------------- */
109FXDEFMAP(GUISUMOAbstractView) GUISUMOAbstractViewMap[] = {
110 FXMAPFUNC(SEL_CONFIGURE, 0, GUISUMOAbstractView::onConfigure),
111 FXMAPFUNC(SEL_PAINT, 0, GUISUMOAbstractView::onPaint),
112 FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, GUISUMOAbstractView::onLeftBtnPress),
113 FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, GUISUMOAbstractView::onLeftBtnRelease),
114 FXMAPFUNC(SEL_MIDDLEBUTTONPRESS, 0, GUISUMOAbstractView::onMiddleBtnPress),
115 FXMAPFUNC(SEL_MIDDLEBUTTONRELEASE, 0, GUISUMOAbstractView::onMiddleBtnRelease),
116 FXMAPFUNC(SEL_RIGHTBUTTONPRESS, 0, GUISUMOAbstractView::onRightBtnPress),
117 FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, 0, GUISUMOAbstractView::onRightBtnRelease),
118 FXMAPFUNC(SEL_DOUBLECLICKED, 0, GUISUMOAbstractView::onDoubleClicked),
119 FXMAPFUNC(SEL_MOUSEWHEEL, 0, GUISUMOAbstractView::onMouseWheel),
120 FXMAPFUNC(SEL_MOTION, 0, GUISUMOAbstractView::onMouseMove),
121 FXMAPFUNC(SEL_LEAVE, 0, GUISUMOAbstractView::onMouseLeft),
122 FXMAPFUNC(SEL_KEYPRESS, 0, GUISUMOAbstractView::onKeyPress),
123 FXMAPFUNC(SEL_KEYRELEASE, 0, GUISUMOAbstractView::onKeyRelease),
130};
131
132
133FXIMPLEMENT_ABSTRACT(GUISUMOAbstractView, FXGLCanvas, GUISUMOAbstractViewMap, ARRAYNUMBER(GUISUMOAbstractViewMap))
134
135
136/* -------------------------------------------------------------------------
137 * GUISUMOAbstractView - methods
138 * ----------------------------------------------------------------------- */
139GUISUMOAbstractView::GUISUMOAbstractView(FXComposite* p, GUIMainWindow& app, GUIGlChildWindow* parent, const SUMORTree& grid, FXGLVisual* glVis, FXGLCanvas* share) :
140 FXGLCanvas(p, glVis, share, p, MID_GLCANVAS, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0),
141 myApp(&app),
142 myGlChildWindowParent(parent),
143 myGrid(&grid),
144 myMouseHotspotX(app.getDefaultCursor()->getHotX()),
145 myMouseHotspotY(app.getDefaultCursor()->getHotY()),
146 myWindowCursorPositionX(getWidth() / 2),
147 myWindowCursorPositionY(getHeight() / 2) {
148 setTarget(this);
149 enable();
150 flags |= FLAG_ENABLED;
151 myChanger = new GUIDanielPerspectiveChanger(*this, *myGrid);
152 myVisualizationSettings = &gSchemeStorage.getDefault();
153 myVisualizationSettings->gaming = myApp->isGaming();
155 myDecals = gSchemeStorage.getDecals();
156}
157
158
163 delete myPopup;
164 delete myChanger;
167 // cleanup decals
168 for (auto& decal : myDecals) {
169 delete decal.image;
170 }
171 // remove all elements
172 for (auto& additional : myAdditionallyDrawn) {
173 additional.first->removeActiveAddVisualisation(this, ~0);
174 }
175}
176
177
178bool
182
183
186 return *myChanger;
187}
188
189
190void
196
197
202
203
205GUISUMOAbstractView::snapToActiveGrid(const Position& pos, bool snapXY) const {
206 Position result = pos;
208 if (snapXY) {
209 const double xRest = std::fmod(pos.x(), myVisualizationSettings->gridXSize) + (pos.x() < 0 ? myVisualizationSettings->gridXSize : 0);
210 const double yRest = std::fmod(pos.y(), myVisualizationSettings->gridYSize) + (pos.y() < 0 ? myVisualizationSettings->gridYSize : 0);
211 result.setx(pos.x() - xRest + (xRest < myVisualizationSettings->gridXSize * 0.5 ? 0 : myVisualizationSettings->gridXSize));
212 result.sety(pos.y() - yRest + (yRest < myVisualizationSettings->gridYSize * 0.5 ? 0 : myVisualizationSettings->gridYSize));
213 } else {
214 // snapZToActiveGrid uses grid Y Size
215 const double zRest = std::fmod(pos.z(), myVisualizationSettings->gridYSize) + (pos.z() < 0 ? myVisualizationSettings->gridYSize : 0);
216 result.setz(pos.z() - zRest + (zRest < myVisualizationSettings->gridYSize * 0.5 ? 0 : myVisualizationSettings->gridYSize));
217 }
218 }
219 return result;
220}
221
222
225 Boundary bound = myChanger->getViewport();
226 double xNet = bound.xmin() + bound.getWidth() * x / getWidth();
227 // cursor origin is in the top-left corner
228 double yNet = bound.ymin() + bound.getHeight() * (getHeight() - y) / getHeight();
229 // rotate around the viewport center
230 if (myChanger->getRotation() != 0) {
231 return Position(xNet, yNet).rotateAround2D(-DEG2RAD(myChanger->getRotation()), bound.getCenter());
232 } else {
233 return Position(xNet, yNet);
234 }
235}
236
237
238void
239GUISUMOAbstractView::addDecals(const std::vector<Decal>& decals) {
240 myDecals.insert(myDecals.end(), decals.begin(), decals.end());
241}
242
243
244void
247 // set cartesian position
248 myApp->getCartesianLabel()->setText(("x:" + toString(pos.x()) + ", y:" + toString(pos.y())).c_str());
249 // set geo position
251 if (GeoConvHelper::getFinal().usingGeoProjection()) {
252 myApp->getGeoLabel()->setText(("lat:" + toString(pos.y(), gPrecisionGeo) + ", lon:" + toString(pos.x(), gPrecisionGeo)).c_str());
253 } else {
254 myApp->getGeoLabel()->setText(("x:" + toString(pos.x()) + ", y:" + toString(pos.y()) + TL(" (No projection defined)")).c_str());
255 }
256 // if enabled, set test position
257 if (myApp->getTestFrame()) {
258 if (OptionsCont::getOptions().getBool("gui-testing")) {
259 myApp->getTestFrame()->show();
260 // adjust cursor position (24,25) to show exactly the same position as in function netedit.leftClick(match, X, Y)
261 myApp->getTestLabel()->setText(("Test: x:" + toString(getWindowCursorPosition().x() - 24.0) + " y:" + toString(getWindowCursorPosition().y() - 25.0)).c_str());
262 } else {
263 myApp->getTestFrame()->hide();
264 }
265 }
266}
267
268
269int
270GUISUMOAbstractView::doPaintGL(int /*mode*/, const Boundary& /*boundary*/) {
271 return 0;
272}
273
274
275void
278
279
284
285
286bool
288 return false;
289}
290
291
292void GUISUMOAbstractView::zoom2Pos(Position& /* camera */, Position& /* lookAt */, double /* zoom */) {
293}
294
295
296void
298 // reset debug counters
301 if (getWidth() == 0 || getHeight() == 0) {
302 return;
303 }
304 const long start = SysUtils::getCurrentMillis();
305
307 centerTo(getTrackedID(), false);
308 }
309 // get id tooltip
310 const GUIGlID idToolTip = getObjectUnderCursor();
311 // draw
312 glClearColor(
317 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
318 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
319
321 glEnable(GL_DITHER);
322 } else {
323 glDisable(GL_DITHER);
324 }
325 glEnable(GL_BLEND);
326 glDisable(GL_LINE_SMOOTH);
327
328 Boundary bound = applyGLTransform();
329 doPaintGL(GL_RENDER, bound);
333 const long end = SysUtils::getCurrentMillis();
334 myFrameDrawTime = end - start;
336 drawFPS();
337 }
338 // check if show tooltip
340 showToolTipFor(idToolTip);
341 } else {
343 }
344 swapBuffers();
345}
346
347
348long
349GUISUMOAbstractView::onCmdCloseLane(FXObject*, FXSelector, void*) {
350 return 1;
351}
352
353
354long
355GUISUMOAbstractView::onCmdCloseEdge(FXObject*, FXSelector, void*) {
356 return 1;
357}
358
359
360long
361GUISUMOAbstractView::onCmdAddRerouter(FXObject*, FXSelector, void*) {
362 return 1;
363}
364
365
366long
367GUISUMOAbstractView::onCmdShowReachability(FXObject*, FXSelector, void*) {
368 return 1;
369}
370
371
372long
373GUISUMOAbstractView::onVisualizationChange(FXObject*, FXSelector, void*) {
374 return 1;
375}
376
377
378GUILane*
380 return nullptr;
381}
382
383
388
389
390std::vector<GUIGlID>
394
395
396std::vector<GUIGlObject*>
400
401
402std::vector<GUIGlObject*>
406
407
410 // calculate a boundary for the given position
411 Boundary positionBoundary;
412 positionBoundary.add(pos);
413 positionBoundary.grow(SENSITIVITY);
414 const std::vector<GUIGlID> ids = getObjectsInBoundary(positionBoundary, true);
415 // Interpret results
416 int idMax = 0;
417 double maxLayer = -std::numeric_limits<double>::max();
418 // iterate over obtained GUIGlIDs
419 for (const auto& i : ids) {
420 // obtain GUIGlObject
422 // check that GUIGlObject exist
423 if (o == nullptr) {
424 continue;
425 }
426 // check that GUIGlObject isn't the network
427 if (o->getGlID() == 0) {
428 continue;
429 }
430 //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
431 double layer = o->getClickPriority();
432 // check whether the current object is above a previous one
433 if (layer > maxLayer) {
434 idMax = i;
435 maxLayer = layer;
436 }
437 // unblock object
439 }
440 return idMax;
441}
442
443
444std::vector<GUIGlID>
446 // declare result vector
447 std::vector<GUIGlID> result;
448 // calculate boundary
449 Boundary selection;
450 selection.add(pos);
451 selection.grow(radius);
452 // obtain GUIGlID of objects in boundary
453 const std::vector<GUIGlID> ids = getObjectsInBoundary(selection, true);
454 // iterate over obtained GUIGlIDs
455 for (const auto& i : ids) {
456 // obtain GUIGlObject
458 // check that GUIGlObject exist
459 if (o == nullptr) {
460 continue;
461 }
462 // check that GUIGlObject isn't the network
463 if (o->getGlID() == 0) {
464 continue;
465 }
466 //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
467 GUIGlObjectType type = o->getType();
468 // avoid network
469 if (type != GLO_NETWORK) {
470 result.push_back(i);
471 }
472 // unblock object
474 }
475 return result;
476}
477
478
479std::vector<GUIGlObject*>
481 // declare result vector
482 std::vector<GUIGlObject*> result;
483 // calculate boundary
484 Boundary selection;
485 selection.add(pos);
486 selection.grow(radius);
487 // obtain GUIGlID of objects in boundary
488 const std::vector<GUIGlID> ids = getObjectsInBoundary(selection, true);
489 // iterate over obtained GUIGlIDs
490 for (const auto& i : ids) {
491 // obtain GUIGlObject
493 // check that GUIGlObject exist
494 if (o == nullptr) {
495 continue;
496 }
497 // check that GUIGlObject isn't the network
498 if (o->getGlID() == 0) {
499 continue;
500 }
501 result.push_back(o);
502 // unblock object
504 }
505 return result;
506}
507
508
509std::vector<GUIGlID>
511 const int NB_HITS_MAX = 1024 * 1024;
512 // Prepare the selection mode
513 static GUIGlID hits[NB_HITS_MAX];
514 static GLint nb_hits = 0;
515 glSelectBuffer(NB_HITS_MAX, hits);
516 glInitNames();
517
519 Boundary oldViewPort = myChanger->getViewport(false); // backup the actual viewPort
520 myChanger->setViewport(bound);
521 bound = applyGLTransform(false);
522 // enable draw for selecting (to draw objects with less details)
523 if (singlePosition) {
525 } else {
527 }
528 int hits2 = doPaintGL(GL_SELECT, bound);
529 // reset flags
532 // Get the results
533 nb_hits = glRenderMode(GL_RENDER);
534 if (nb_hits == -1) {
535 myApp->setStatusBarText("Selection in boundary failed. Try to select fewer than " + toString(hits2) + " items");
536 }
537 std::vector<GUIGlID> result;
538 GLuint numNames;
539 GLuint* ptr = hits;
540 for (int i = 0; i < nb_hits; ++i) {
541 numNames = *ptr;
542 ptr += 3;
543 for (int j = 0; j < (int)numNames; j++) {
544 result.push_back(*ptr);
545 ptr++;
546 }
547 }
548 // switch viewport back to normal
549 myChanger->setViewport(oldViewPort);
550 return result;
551}
552
553
554std::vector<GUIGlObject*>
555GUISUMOAbstractView::filterInernalLanes(const std::vector<GUIGlObject*>& objects) const {
556 // count number of internal lanes
557 size_t internalLanes = 0;
558 for (const auto& object : objects) {
559 if ((object->getType() == GLO_LANE) && (object->getMicrosimID().find(':') != std::string::npos)) {
560 internalLanes++;
561 }
562 }
563 // if all objects are internal lanes, return it all
564 if (objects.size() == internalLanes || !myVisualizationSettings->drawJunctionShape) {
565 return objects;
566 }
567 // in other case filter internal lanes
568 std::vector<GUIGlObject*> filteredObjects;
569 for (const auto& object : objects) {
570 if ((object->getType() == GLO_LANE) && (object->getMicrosimID().find(':') != std::string::npos)) {
571 continue;
572 }
573 filteredObjects.push_back(object);
574 }
575 return filteredObjects;
576}
577
578
579bool
581 if (idToolTip != GUIGlObject::INVALID_ID) {
583 if (object != nullptr) {
585 return true;
586 }
587 }
588 // nothing to show
590 return false;
591}
592
593
594void
596 // obtain minimum grid
598 // Check if the distance is enough to draw grid
600 glEnable(GL_DEPTH_TEST);
601 glLineWidth(1);
602 // get multiplication values (2 is the margin)
603 const int multXmin = (int)(myChanger->getViewport().xmin() / myVisualizationSettings->gridXSize) - 2;
604 const int multYmin = (int)(myChanger->getViewport().ymin() / myVisualizationSettings->gridYSize) - 2;
605 const int multXmax = (int)(myChanger->getViewport().xmax() / myVisualizationSettings->gridXSize) + 2;
606 const int multYmax = (int)(myChanger->getViewport().ymax() / myVisualizationSettings->gridYSize) + 2;
607 // obtain references
608 const double xmin = myVisualizationSettings->gridXSize * multXmin;
609 const double ymin = myVisualizationSettings->gridYSize * multYmin;
610 const double xmax = myVisualizationSettings->gridXSize * multXmax;
611 const double ymax = myVisualizationSettings->gridYSize * multYmax;
612 double xp = xmin;
613 double yp = ymin;
614 // move drawing matrix
615 glTranslated(0, 0, .55);
616 glColor3d(0.5, 0.5, 0.5);
617 // draw horizontal lines
618 glBegin(GL_LINES);
619 while (yp <= ymax) {
620 glVertex2d(xmin, yp);
621 glVertex2d(xmax, yp);
623 }
624 // draw vertical lines
625 while (xp <= xmax) {
626 glVertex2d(xp, ymin);
627 glVertex2d(xp, ymax);
629 }
630 glEnd();
631 glTranslated(0, 0, -.55);
632 }
633}
634
635
636void
638 // compute the scale bar length
639 int length = 1;
640 const std::string text("10000000000");
641 int noDigits = 1;
642 int pixelSize = (int) m2p((double) length);
643 while (pixelSize <= 20) {
644 length *= 10;
645 noDigits++;
646 if (noDigits > (int)text.length()) {
647 return;
648 }
649 pixelSize = (int) m2p((double) length);
650 }
651 glLineWidth(1.0);
652
653 glMatrixMode(GL_PROJECTION);
655 glLoadIdentity();
656 glMatrixMode(GL_MODELVIEW);
658 glLoadIdentity();
659
660 // draw the scale bar
661 const double z = -1;
662 glDisable(GL_TEXTURE_2D);
663 glDisable(GL_ALPHA_TEST);
664 glDisable(GL_BLEND);
665 glEnable(GL_DEPTH_TEST);
667 glTranslated(0, 0, z);
668
669 double len = (double) pixelSize / (double)(getWidth() - 1) * (double) 2.0;
670 glColor3d(0, 0, 0);
671 double o = double(15) / double(getHeight());
672 double o2 = o + o;
673 double oo = double(5) / double(getHeight());
674 glBegin(GL_LINES);
675 // vertical
676 glVertex2d(-.98, -1. + o);
677 glVertex2d(-.98 + len, -1. + o);
678 // tick at begin
679 glVertex2d(-.98, -1. + o);
680 glVertex2d(-.98, -1. + o2);
681 // tick at end
682 glVertex2d(-.98 + len, -1. + o);
683 glVertex2d(-.98 + len, -1. + o2);
684 glEnd();
686
687 const double fontHeight = 0.1 * 300. / getHeight();
688 const double fontWidth = 0.1 * 300. / getWidth();
689 // draw 0
690 GLHelper::drawText("0", Position(-.99, -0.99 + o2 + oo), z, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT, fontWidth);
691
692 // draw current scale
693 GLHelper::drawText((text.substr(0, noDigits) + "m").c_str(), Position(-.99 + len, -0.99 + o2 + oo), z, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT, fontWidth);
694
695 // restore matrices
696 glMatrixMode(GL_PROJECTION);
698 glMatrixMode(GL_MODELVIEW);
700}
701
702void
714
715void
717 // compute the scale bar length
718 glLineWidth(1.0);
719 glMatrixMode(GL_PROJECTION);
721 glLoadIdentity();
722 glMatrixMode(GL_MODELVIEW);
724 glLoadIdentity();
725
726 const double z = -1;
727 glEnable(GL_DEPTH_TEST);
728 glEnable(GL_BLEND);
730 glTranslated(0, 0, z);
731
732 const bool fixed = scheme.isFixed();
733 const int numColors = (int)scheme.getColors().size();
734
735 // vertical
736 double right = 0.98;
737 double left = 0.95;
738 double textX = left - 0.01;
739 double textDir = 1;
740 FONSalign textAlign = FONS_ALIGN_RIGHT;
741 const double top = -0.7;
742 const double bot = 0.9;
743 const double dy = (top - bot) / numColors;
744 const double bot2 = fixed ? bot : bot + dy / 2;
745 // legend placement
746 if (leftSide) {
747 right = -right;
748 left = -left;
749 std::swap(right, left);
750 textX = right + 0.01;
751 textDir *= -1;
752 textAlign = FONS_ALIGN_LEFT;
753 }
754 // draw black boundary around legend colors
755 glColor3d(0, 0, 0);
756 glBegin(GL_LINES);
757 glVertex2d(right, top);
758 glVertex2d(right, bot2);
759 glVertex2d(left, bot2);
760 glVertex2d(left, top);
761 glVertex2d(right, top);
762 glVertex2d(left, top);
763 glVertex2d(right, bot2);
764 glVertex2d(left, bot2);
765 glEnd();
766
767 const double fontHeight = 0.20 * 300. / getHeight();
768 const double fontWidth = 0.20 * 300. / getWidth();
769
770 const int fadeSteps = fixed ? 1 : 10;
771 double colorStep = dy / fadeSteps;
772 for (int i = 0; i < numColors; i++) {
773 RGBColor col = scheme.getColors()[i];
774 const double topi = top - i * dy;
775 //const double boti = top - (i + 1) * dy;
776 //std::cout << " col=" << scheme.getColors()[i] << " i=" << i << " topi=" << topi << " boti=" << boti << "\n";
777 if (i + 1 < numColors) {
778 // fade
779 RGBColor col2 = scheme.getColors()[i + 1];
780 double thresh2 = scheme.getThresholds()[i + 1];
781 if (!fixed && thresh2 == GUIVisualizationSettings::MISSING_DATA) {
782 // draw scale end before missing data
784 glBegin(GL_QUADS);
785 glVertex2d(left, topi);
786 glVertex2d(right, topi);
787 glVertex2d(right, topi - 5 * colorStep);
788 glVertex2d(left, topi - 5 * colorStep);
789 glEnd();
790 glColor3d(0, 0, 0);
791 glBegin(GL_LINES);
792 glVertex2d(right, topi - 10 * colorStep);
793 glVertex2d(left, topi - 10 * colorStep);
794 glEnd();
795 glBegin(GL_LINES);
796 glVertex2d(right, topi - 5 * colorStep);
797 glVertex2d(left, topi - 5 * colorStep);
798 glEnd();
799 } else {
800 // fade colors
801 for (double j = 0.0; j < fadeSteps; j++) {
802 GLHelper::setColor(RGBColor::interpolate(col, col2, j / fadeSteps));
803 glBegin(GL_QUADS);
804 glVertex2d(left, topi - j * colorStep);
805 glVertex2d(right, topi - j * colorStep);
806 glVertex2d(right, topi - (j + 1) * colorStep);
807 glVertex2d(left, topi - (j + 1) * colorStep);
808 glEnd();
809 }
810 }
811 } else {
813 glBegin(GL_QUADS);
814 glVertex2d(left, topi);
815 glVertex2d(right, topi);
816 glVertex2d(right, bot2);
817 glVertex2d(left, bot2);
818 glEnd();
819 }
820
821 const double threshold = scheme.getThresholds()[i];
822 std::string name = scheme.getNames()[i];
823 std::string text = fixed || threshold == GUIVisualizationSettings::MISSING_DATA ? name : toString(threshold);
824
825 const double bgShift = 0.0;
826 const double textShift = 0.01;
827 const double textXShift = -0.005;
828
830 glTranslated(0, 0, 0.1);
831 glBegin(GL_QUADS);
832 glVertex2d(textX, topi + fontHeight * bgShift);
833 glVertex2d(textX - textDir * fontWidth * (double)text.size() / 2., topi + fontHeight * bgShift);
834 glVertex2d(textX - textDir * fontWidth * (double)text.size() / 2., topi + fontHeight * (1. + bgShift));
835 glVertex2d(textX, topi + fontHeight * (1. + bgShift));
836 glEnd();
837 glTranslated(0, 0, -0.1);
838 GLHelper::drawText(text, Position(textX + textDir * textXShift, topi + textShift), 0, fontHeight, RGBColor::BLACK, 0, textAlign, fontWidth);
839 }
840 // draw scheme name
841 std::string name = scheme.getName();
842 if (StringUtils::startsWith(name, "by ")) {
843 name = name.substr(3);
844 }
845 GLHelper::drawText(name, Position(textX + textDir * 0.04, -0.8), 0, fontHeight, RGBColor::BLACK, 0, textAlign, fontWidth);
846
848 // restore matrices
849 glMatrixMode(GL_PROJECTION);
851 glMatrixMode(GL_MODELVIEW);
853}
854
855
856double
858 return 1000.0 / MAX2((long)1, myFrameDrawTime);
859}
860
861
866
867
868void
870 glMatrixMode(GL_PROJECTION);
872 glLoadIdentity();
873 glMatrixMode(GL_MODELVIEW);
875 glLoadIdentity();
876 const double fontHeight = 0.2 * 300. / getHeight();
877 const double fontWidth = 0.2 * 300. / getWidth();
878 GLHelper::drawText(toString((int)getFPS()) + " FPS", Position(0.82, 0.88), -1, fontHeight, RGBColor::RED, 0, FONS_ALIGN_LEFT, fontWidth);
879#ifdef CHECK_ELEMENTCOUNTER
880 GLHelper::drawText(toString(GLHelper::getMatrixCounter()) + " matrix", Position(0.82, 0.79), -1, fontHeight, RGBColor::RED, 0, FONS_ALIGN_LEFT, fontWidth);
881 GLHelper::drawText(toString(GLHelper::getVertexCounter()) + " vertex", Position(0.82, 0.71), -1, fontHeight, RGBColor::RED, 0, FONS_ALIGN_LEFT, fontWidth);
882#endif
883 // restore matrices
884 glMatrixMode(GL_PROJECTION);
886 glMatrixMode(GL_MODELVIEW);
888}
889
890
891double
892GUISUMOAbstractView::m2p(double meter) const {
893 return meter * getWidth() / myChanger->getViewport().getWidth();
894}
895
896
897double
898GUISUMOAbstractView::p2m(double pixel) const {
899 return pixel * myChanger->getViewport().getWidth() / getWidth();
900}
901
902
903void
907
908
909void
910GUISUMOAbstractView::centerTo(GUIGlID id, bool applyZoom, double zoomDist) {
912 if (o != nullptr && dynamic_cast<GUIGlObject*>(o) != nullptr) {
913 const Boundary& b = o->getCenteringBoundary();
914 if (b.getCenter() != Position::INVALID) {
915 if (applyZoom && zoomDist < 0) {
917 update(); // only update when centering onto an object once
918 } else {
919 // called during tracking. update is triggered somewhere else
920 myChanger->centerTo(b.getCenter(), zoomDist, applyZoom);
922 }
923 }
924 }
926}
927
928
929void
930GUISUMOAbstractView::centerTo(const Position& pos, bool applyZoom, double zoomDist) {
931 // called during tracking. update is triggered somewhere else
932 myChanger->centerTo(pos, zoomDist, applyZoom);
934}
935
936
937void
939 myChanger->setViewport(bound);
940 update();
941}
942
943
946 return myApp;
947}
948
949
954
955
956void
961
962
963FXbool
965 FXbool ret = FXGLCanvas::makeCurrent();
966 return ret;
967}
968
969
970long
971GUISUMOAbstractView::onConfigure(FXObject*, FXSelector, void*) {
972 if (makeCurrent()) {
973 glViewport(0, 0, getWidth() - 1, getHeight() - 1);
974 glClearColor(
979 doInit();
980 myAmInitialised = true;
981 makeNonCurrent();
983 }
984 return 1;
985}
986
987
988long
989GUISUMOAbstractView::onPaint(FXObject*, FXSelector, void*) {
990 if (!isEnabled() || !myAmInitialised) {
991 return 1;
992 }
993 if (makeCurrent()) {
994 paintGL();
995 makeNonCurrent();
996 }
997 return 1;
998}
999
1000
1001const Position&
1005
1006
1007void
1009 if (myPopup != nullptr) {
1011 delete myPopup;
1012 myPopupPosition.set(0, 0);
1013 myPopup = nullptr;
1014 myCurrentObjectsDialog.clear();
1015 }
1016}
1017
1018
1019void
1021 // use the same position of old popUp
1022 popUp->move(myPopup->getX(), myPopup->getY());
1023 // delete and replace popup
1025 delete myPopup;
1026 myPopup = popUp;
1027 // create and show popUp
1028 myPopup->create();
1029 myPopup->show();
1030 myChanger->onRightBtnRelease(nullptr);
1031 setFocus();
1032}
1033
1034
1035long
1036GUISUMOAbstractView::onLeftBtnPress(FXObject*, FXSelector, void* ptr) {
1037 destroyPopup();
1038 setFocus();
1039 FXEvent* e = (FXEvent*) ptr;
1040 // check whether the selection-mode is activated
1041 if ((e->state & CONTROLMASK) != 0) {
1042 // toggle selection of object under cursor
1043 if (makeCurrent()) {
1044 int id = getObjectUnderCursor();
1045 if (id != 0) {
1047 }
1048 makeNonCurrent();
1049 if (id != 0) {
1050 // possibly, the selection-colouring is used,
1051 // so we should update the screen again...
1052 update();
1053 }
1054 }
1055 }
1056 if ((e->state & SHIFTMASK) != 0) {
1057 // track vehicle or person under cursor
1058 if (makeCurrent()) {
1059 int id = getObjectUnderCursor();
1060 if (id != 0) {
1062 if (o != nullptr) {
1063 if (o->getType() == GLO_VEHICLE || o->getType() == GLO_PERSON) {
1064 startTrack(id);
1065 } else if (o->getType() == GLO_REROUTER_EDGE) {
1066 o->onLeftBtnPress(ptr);
1067 update();
1068 }
1069 }
1070 }
1071 makeNonCurrent();
1072 }
1073 }
1075 grab();
1076 // Check there are double click
1077 if (e->click_count == 2) {
1078 handle(this, FXSEL(SEL_DOUBLECLICKED, 0), ptr);
1079 }
1080 return 1;
1081}
1082
1083
1084long
1085GUISUMOAbstractView::onLeftBtnRelease(FXObject*, FXSelector, void* ptr) {
1086 destroyPopup();
1088 if (myApp->isGaming()) {
1090 }
1091 ungrab();
1092 return 1;
1093}
1094
1095
1096long
1097GUISUMOAbstractView::onMiddleBtnPress(FXObject*, FXSelector, void* ptr) {
1098 destroyPopup();
1099 setFocus();
1100 if (!myApp->isGaming()) {
1102 }
1103 grab();
1104 // enable panning
1105 myPanning = true;
1106 // set cursors
1109 return 1;
1110}
1111
1112
1113long
1114GUISUMOAbstractView::onMiddleBtnRelease(FXObject*, FXSelector, void* ptr) {
1115 destroyPopup();
1116 if (!myApp->isGaming()) {
1118 }
1119 ungrab();
1120 // disable panning
1121 myPanning = false;
1122 // restore cursors
1125 return 1;
1126}
1127
1128
1129long
1130GUISUMOAbstractView::onRightBtnPress(FXObject*, FXSelector, void* ptr) {
1131 destroyPopup();
1132 if (!myApp->isGaming()) {
1134 }
1135 grab();
1136 return 1;
1137}
1138
1139
1140long
1141GUISUMOAbstractView::onRightBtnRelease(FXObject* o, FXSelector sel, void* ptr) {
1142 destroyPopup();
1143 onMouseMove(o, sel, ptr);
1144 if (!myChanger->onRightBtnRelease(ptr) && !myApp->isGaming()) {
1145 openObjectDialogAtCursor((FXEvent*)ptr);
1146 }
1147 if (myApp->isGaming()) {
1149 }
1150 ungrab();
1151 return 1;
1152}
1153
1154
1155long
1156GUISUMOAbstractView::onDoubleClicked(FXObject*, FXSelector, void*) {
1157 return 1;
1158}
1159
1160
1161long
1162GUISUMOAbstractView::onMouseWheel(FXObject*, FXSelector, void* ptr) {
1163 if (!myApp->isGaming()) {
1164 myChanger->onMouseWheel(ptr);
1165 // upddate viewport
1166 if (myGUIDialogEditViewport != nullptr) {
1170 }
1172 }
1173 return 1;
1174}
1175
1176
1177long
1178GUISUMOAbstractView::onMouseMove(FXObject*, FXSelector, void* ptr) {
1179 // check if popup exist
1180 if (myPopup) {
1181 // check if handle front element
1184 myPopup->handle(this, FXSEL(SEL_COMMAND, MID_CURSORDIALOG_FRONT), nullptr);
1185 destroyPopup();
1186 } else if (myPopup->shown() == false) {
1187 destroyPopup();
1188 }
1189 }
1190 if (myPopup == nullptr) {
1192 myChanger->onMouseMove(ptr);
1193 }
1194 if (myGUIDialogEditViewport != nullptr) {
1198 }
1200 }
1201 return 1;
1202}
1203
1204
1205long
1206GUISUMOAbstractView::onMouseLeft(FXObject*, FXSelector, void* /*data*/) {
1207 return 1;
1208}
1209
1210
1211void
1213 // release the mouse grab
1214 ungrab();
1215 // check if alt key is pressed
1216 const bool altKeyPressed = ((ev->state & ALTMASK) != 0);
1217 // check if SUMO is enabled, initialised and Make OpenGL context current
1218 if (isEnabled() && myAmInitialised && makeCurrent()) {
1219 // get all objects under cusor
1220 auto objectsUnderCursor = getGUIGlObjectsUnderCursor();
1221 // filter elements by layer
1222 objectsUnderCursor = filterGUIGLObjectsByLayer(objectsUnderCursor);
1223 // filter elements
1224 std::vector<GUIGlObject*> filteredObjectsUnderCursor;
1225 std::vector<GUIGlObject*> filteredVehiclesUnderCursor;
1226 std::vector<GUIGlObject*> filteredTLSUnderCursor;
1227 for (const auto& GLObject : objectsUnderCursor) {
1228 if (GLObject->getType() == GLO_EDGE) {
1229 // avoid edges
1230 continue;
1231 }
1232 if (std::find(filteredObjectsUnderCursor.begin(), filteredObjectsUnderCursor.end(), GLObject) != filteredObjectsUnderCursor.end()) {
1233 // avoid duplicated lanes
1234 continue;
1235 }
1236 if ((GLObject->getType() == GLO_VEHICLE) || (GLObject->getType() == GLO_TRIP) ||
1237 (GLObject->getType() == GLO_FLOW) || (GLObject->getType() == GLO_ROUTEFLOW) ||
1238 (GLObject->getType() == GLO_CONTAINER) || (GLObject->getType() == GLO_CONTAINERFLOW) ||
1239 (GLObject->getType() == GLO_PERSON) || (GLObject->getType() == GLO_PERSONFLOW)) {
1240 // filter vehicles, person and containers
1241 filteredVehiclesUnderCursor.push_back(GLObject);
1242 }
1243 if (GLObject->getType() == GLO_TLLOGIC) {
1244 // filter TLSs
1245 filteredTLSUnderCursor.push_back(GLObject);
1246 }
1247 filteredObjectsUnderCursor.push_back(GLObject);
1248 }
1249 // filter internal lanes
1250 filteredObjectsUnderCursor = filterInernalLanes(filteredObjectsUnderCursor);
1251 // remove duplicated elements using an unordered set
1252 auto itDuplicated = filteredObjectsUnderCursor.begin();
1253 std::unordered_set<GUIGlObject*> unorderedSet;
1254 for (auto itElement = filteredObjectsUnderCursor.begin(); itElement != filteredObjectsUnderCursor.end(); itElement++) {
1255 if (unorderedSet.insert(*itElement).second) {
1256 *itDuplicated++ = *itElement;
1257 }
1258 }
1259 filteredObjectsUnderCursor.erase(itDuplicated, filteredObjectsUnderCursor.end());
1260 // continue depending of number of objects
1261 if (filteredObjectsUnderCursor.empty()) {
1262 // if filteredObjectsUnderCursor, inspect net
1264 } else if (altKeyPressed) {
1265 // inspect all objects under cusror
1266 openObjectDialog(filteredObjectsUnderCursor, false);
1267 } else if (filteredVehiclesUnderCursor.size() > 0) {
1268 // inspect only vehicles
1269 openObjectDialog(filteredVehiclesUnderCursor, true);
1270 } else if (filteredTLSUnderCursor.size() > 0) {
1271 // inspect only TLSs
1272 openObjectDialog(filteredTLSUnderCursor, true);
1273 } else {
1274 // inspect objects under cursor
1275 openObjectDialog(filteredObjectsUnderCursor, true);
1276 }
1277 // Make OpenGL context non current
1278 makeNonCurrent();
1279 }
1280}
1281
1282
1283void
1284GUISUMOAbstractView::openObjectDialog(const std::vector<GUIGlObject*>& objects, const bool filter) {
1285 if (objects.size() > 0) {
1286 // create cursor popup dialog
1287 if (objects.size() == 1) {
1288 myCurrentObjectsDialog = objects;
1289 } else if (filter) {
1290 // declare filtered objects
1291 std::vector<GUIGlObject*> filteredGLObjects;
1292 // fill filtered objects
1293 for (const auto& glObject : objects) {
1294 // compare type with first eleement type
1295 if (glObject->getType() == objects.front()->getType()) {
1296 filteredGLObjects.push_back(glObject);
1297 }
1298 }
1299 myCurrentObjectsDialog = filteredGLObjects;
1300 } else {
1301 myCurrentObjectsDialog = objects;
1302 }
1303 if (myCurrentObjectsDialog.size() > 1) {
1305 } else {
1306 myPopup = myCurrentObjectsDialog.front()->getPopUpMenu(*myApp, *this);
1307 }
1308 // open popup dialog
1310 }
1311}
1312
1313
1314long
1315GUISUMOAbstractView::onKeyPress(FXObject* o, FXSelector sel, void* ptr) {
1316 const FXEvent* e = (FXEvent*) ptr;
1317 if (e->state & ALTMASK) {
1319 // update view (for polygon layers)
1320 update();
1321 } else {
1323 }
1324 // check if process canvas or popup
1325 if (myPopup != nullptr) {
1326 return myPopup->onKeyPress(o, sel, ptr);
1327 } else {
1328 if (e->state & CONTROLMASK) {
1329 if (e->code == FX::KEY_Page_Up) {
1332 update();
1333 return 1;
1334 } else if (e->code == FX::KEY_Page_Down) {
1337 update();
1338 return 1;
1339 }
1340 }
1341 FXGLCanvas::onKeyPress(o, sel, ptr);
1342 return myChanger->onKeyPress(ptr);
1343 }
1344}
1345
1346
1347long
1348GUISUMOAbstractView::onKeyRelease(FXObject* o, FXSelector sel, void* ptr) {
1349 const FXEvent* e = (FXEvent*) ptr;
1350 if ((e->state & ALTMASK) == 0) {
1352 // update view (for polygon layers)
1353 update();
1354 }
1355 // check if process canvas or popup
1356 if (myPopup != nullptr) {
1357 return myPopup->onKeyRelease(o, sel, ptr);
1358 } else {
1359 FXGLCanvas::onKeyRelease(o, sel, ptr);
1360 return myChanger->onKeyRelease(ptr);
1361 }
1362}
1363
1364// ------------ Dealing with snapshots
1365
1366void
1367GUISUMOAbstractView::addSnapshot(SUMOTime time, const std::string& file, const int w, const int h) {
1368#ifdef DEBUG_SNAPSHOT
1369 std::cout << "add snapshot time=" << time << " file=" << file << "\n";
1370#endif
1371 FXMutexLock lock(mySnapshotsMutex);
1372 mySnapshots[time].push_back(std::make_tuple(file, w, h));
1373}
1374
1375
1376std::string
1377GUISUMOAbstractView::makeSnapshot(const std::string& destFile, const int w, const int h) {
1378 if (w >= 0) {
1379 resize(w, h);
1380 repaint();
1381 }
1382 std::string errorMessage;
1383 FXString ext = FXPath::extension(destFile.c_str());
1384 const bool useGL2PS = ext == "ps" || ext == "eps" || ext == "pdf" || ext == "svg" || ext == "tex" || ext == "pgf";
1385#ifdef HAVE_FFMPEG
1386 const bool useVideo = destFile == "" || ext == "h264" || ext == "hevc" || ext == "mp4";
1387#endif
1388 for (int i = 0; i < 10 && !makeCurrent(); ++i) {
1390 }
1391 // draw
1392 glClearColor(
1397 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
1398 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1399
1401 glEnable(GL_DITHER);
1402 } else {
1403 glDisable(GL_DITHER);
1404 }
1405 glEnable(GL_BLEND);
1406 glDisable(GL_LINE_SMOOTH);
1407
1409
1410 if (useGL2PS) {
1411#ifdef HAVE_GL2PS
1412 GLint format = GL2PS_PS;
1413 if (ext == "ps") {
1414 format = GL2PS_PS;
1415 } else if (ext == "eps") {
1416 format = GL2PS_EPS;
1417 } else if (ext == "pdf") {
1418 format = GL2PS_PDF;
1419 } else if (ext == "tex") {
1420 format = GL2PS_TEX;
1421 } else if (ext == "svg") {
1422 format = GL2PS_SVG;
1423 } else if (ext == "pgf") {
1424 format = GL2PS_PGF;
1425 } else {
1426 return "Could not save '" + destFile + "'.\n Unrecognized format '" + std::string(ext.text()) + "'.";
1427 }
1428 FILE* fp = fopen(destFile.c_str(), "wb");
1429 if (fp == 0) {
1430 return "Could not save '" + destFile + "'.\n Could not open file for writing";
1431 }
1433 GLint buffsize = 0, state = GL2PS_OVERFLOW;
1434 GLint viewport[4];
1435 glGetIntegerv(GL_VIEWPORT, viewport);
1436 while (state == GL2PS_OVERFLOW) {
1437 buffsize += 1024 * 1024;
1438 gl2psBeginPage(destFile.c_str(), "sumo-gui; https://sumo.dlr.de", viewport, format, GL2PS_SIMPLE_SORT,
1439 GL2PS_DRAW_BACKGROUND | GL2PS_USE_CURRENT_VIEWPORT,
1440 GL_RGBA, 0, NULL, 0, 0, 0, buffsize, fp, "out.eps");
1441 glMatrixMode(GL_MODELVIEW);
1443 glDisable(GL_TEXTURE_2D);
1444 glDisable(GL_ALPHA_TEST);
1445 glDisable(GL_BLEND);
1446 glEnable(GL_DEPTH_TEST);
1447 // draw decals (if not in grabbing mode)
1448
1449 drawDecals();
1451 paintGLGrid();
1452 }
1453
1454 glLineWidth(1);
1455 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1456 Boundary viewPort = myChanger->getViewport();
1457 const float minB[2] = { (float)viewPort.xmin(), (float)viewPort.ymin() };
1458 const float maxB[2] = { (float)viewPort.xmax(), (float)viewPort.ymax() };
1460 glEnable(GL_POLYGON_OFFSET_FILL);
1461 glEnable(GL_POLYGON_OFFSET_LINE);
1462 myGrid->Search(minB, maxB, *myVisualizationSettings);
1463
1465 state = gl2psEndPage();
1466 glFinish();
1467 }
1468 GLHelper::setGL2PS(false);
1469 fclose(fp);
1470#else
1471 return "Could not save '" + destFile + "', gl2ps was not enabled at compile time.";
1472#endif
1473 } else {
1474 doPaintGL(GL_RENDER, myChanger->getViewport());
1476 swapBuffers();
1477 glFinish();
1478 FXColor* buf;
1479 FXMALLOC(&buf, FXColor, getWidth()*getHeight());
1480 // read from the back buffer
1481 glReadBuffer(GL_BACK);
1482 // Read the pixels
1483 glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)buf);
1484 makeNonCurrent();
1485 update();
1486 // mirror
1487 int mwidth = getWidth();
1488 int mheight = getHeight();
1489 FXColor* paa = buf;
1490 FXColor* pbb = buf + mwidth * (mheight - 1);
1491 do {
1492 FXColor* pa = paa;
1493 paa += mwidth;
1494 FXColor* pb = pbb;
1495 pbb -= mwidth;
1496 do {
1497 FXColor t = *pa;
1498 *pa++ = *pb;
1499 *pb++ = t;
1500 } while (pa < paa);
1501 } while (paa < pbb);
1502 try {
1503#ifdef HAVE_FFMPEG
1504 if (useVideo) {
1505 try {
1506 saveFrame(destFile, buf);
1507 errorMessage = "video";
1508 } catch (std::runtime_error& err) {
1509 errorMessage = err.what();
1510 }
1511 } else
1512#endif
1513 if (!MFXImageHelper::saveImage(destFile, getWidth(), getHeight(), buf)) {
1514 errorMessage = "Could not save '" + destFile + "'.";
1515 }
1516 } catch (InvalidArgument& e) {
1517 errorMessage = "Could not save '" + destFile + "'.\n" + e.what();
1518 }
1519 FXFREE(&buf);
1520 }
1521 return errorMessage;
1522}
1523
1524
1525void
1526GUISUMOAbstractView::saveFrame(const std::string& destFile, FXColor* buf) {
1527 UNUSED_PARAMETER(destFile);
1528 UNUSED_PARAMETER(buf);
1529}
1530
1531
1532void
1534 const SUMOTime time = getCurrentTimeStep() - DELTA_T;
1535#ifdef DEBUG_SNAPSHOT
1536 std::cout << "check snapshots time=" << time << " registeredTimes=" << mySnapshots.size() << "\n";
1537#endif
1538 FXMutexLock lock(mySnapshotsMutex);
1539 const auto snapIt = mySnapshots.find(time);
1540 if (snapIt == mySnapshots.end()) {
1541 return;
1542 }
1543 std::vector<std::tuple<std::string, int, int> > files = snapIt->second;
1544 lock.unlock();
1545 // decouple map access and painting to avoid deadlock
1546 for (const auto& entry : files) {
1547#ifdef DEBUG_SNAPSHOT
1548 std::cout << "make snapshot time=" << time << " file=" << file << "\n";
1549#endif
1550 const std::string& error = makeSnapshot(std::get<0>(entry), std::get<1>(entry), std::get<2>(entry));
1551 if (error != "" && error != "video") {
1552 WRITE_WARNING(error);
1553 }
1554 }
1555 // synchronization with a waiting run thread
1556 lock.lock();
1557 mySnapshots.erase(time);
1558 mySnapshotCondition.signal();
1559#ifdef DEBUG_SNAPSHOT
1560 std::cout << " files=" << toString(files) << " myApplicationSnapshots=" << joinToString(*myApplicationSnapshots, ",") << "\n";
1561#endif
1562}
1563
1564
1565void
1567 FXMutexLock lock(mySnapshotsMutex);
1568 if (mySnapshots.count(snapshotTime) > 0) {
1570 }
1571}
1572
1573
1576 return 0;
1577}
1578
1579
1580void
1591
1592
1595 if (myGUIDialogEditViewport == nullptr) {
1596 myGUIDialogEditViewport = new GUIDialog_EditViewport(this, TL("Edit Viewport"));
1597 myGUIDialogEditViewport->create();
1598 }
1601}
1602
1603
1609
1610
1611void
1618
1619
1620void
1621GUISUMOAbstractView::setViewportFromToRot(const Position& lookFrom, const Position& /* lookAt */, double rotation) {
1622 myChanger->setViewportFrom(lookFrom.x(), lookFrom.y(), lookFrom.z());
1623 myChanger->setRotation(rotation);
1624 update();
1625}
1626
1627
1628void
1635
1636
1637bool
1639 return true;
1640}
1641
1642
1647
1648
1653
1654
1655void
1659
1660
1661void
1665
1666
1667double
1669 return myGrid->getWidth();
1670}
1671
1672
1673double
1677
1678
1679void
1682
1683
1684void
1687
1688
1689GUIGlID
1693
1694
1695void
1698
1699void
1702
1703
1704std::vector<GUISUMOAbstractView::Decal>&
1708
1709
1710FXMutex&
1714
1715
1716FXComboBox*
1720
1721
1722FXImage*
1724#ifdef HAVE_GDAL
1725 GDALAllRegister();
1726 GDALDataset* poDataset = (GDALDataset*)GDALOpen(d.filename.c_str(), GA_ReadOnly);
1727 if (poDataset == 0) {
1728 return 0;
1729 }
1730 const int xSize = poDataset->GetRasterXSize();
1731 const int ySize = poDataset->GetRasterYSize();
1732 // checking for geodata in the picture and try to adapt position and scale
1733 if (d.width <= 0.) {
1734 double adfGeoTransform[6];
1735 if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) {
1736 Position topLeft(adfGeoTransform[0], adfGeoTransform[3]);
1737 const double horizontalSize = xSize * adfGeoTransform[1];
1738 const double verticalSize = ySize * adfGeoTransform[5];
1739 Position bottomRight(topLeft.x() + horizontalSize, topLeft.y() + verticalSize);
1740 if (GeoConvHelper::getProcessing().x2cartesian(topLeft) && GeoConvHelper::getProcessing().x2cartesian(bottomRight)) {
1741 d.width = bottomRight.x() - topLeft.x();
1742 d.height = topLeft.y() - bottomRight.y();
1743 d.centerX = (topLeft.x() + bottomRight.x()) / 2;
1744 d.centerY = (topLeft.y() + bottomRight.y()) / 2;
1745 //WRITE_MESSAGE("proj: " + toString(poDataset->GetProjectionRef()) + " dim: " + toString(d.width) + "," + toString(d.height) + " center: " + toString(d.centerX) + "," + toString(d.centerY));
1746 } else {
1747 WRITE_WARNINGF(TL("Could not convert coordinates in %."), d.filename);
1748 }
1749 }
1750 }
1751#endif
1752 if (d.width <= 0.) {
1753 d.width = getGridWidth();
1754 d.height = getGridHeight();
1755 }
1756
1757 // trying to read the picture
1758#ifdef HAVE_GDAL
1759 const int picSize = xSize * ySize;
1760 FXColor* result;
1761 if (!FXMALLOC(&result, FXColor, picSize)) {
1762 WRITE_WARNINGF("Could not allocate memory for %.", d.filename);
1763 return 0;
1764 }
1765 for (int j = 0; j < picSize; j++) {
1766 result[j] = FXRGB(0, 0, 0);
1767 }
1768 bool valid = true;
1769 for (int i = 1; i <= poDataset->GetRasterCount(); i++) {
1770 GDALRasterBand* poBand = poDataset->GetRasterBand(i);
1771 int shift = -1;
1772 if (poBand->GetColorInterpretation() == GCI_RedBand) {
1773 shift = 0;
1774 } else if (poBand->GetColorInterpretation() == GCI_GreenBand) {
1775 shift = 1;
1776 } else if (poBand->GetColorInterpretation() == GCI_BlueBand) {
1777 shift = 2;
1778 } else if (poBand->GetColorInterpretation() == GCI_AlphaBand) {
1779 shift = 3;
1780 } else {
1781 valid = false;
1782 break;
1783 }
1784 assert(xSize == poBand->GetXSize() && ySize == poBand->GetYSize());
1785 if (poBand->RasterIO(GF_Read, 0, 0, xSize, ySize, ((unsigned char*)result) + shift, xSize, ySize, GDT_Byte, 4, 4 * xSize) == CE_Failure) {
1786 valid = false;
1787 break;
1788 }
1789 }
1790 GDALClose(poDataset);
1791 if (valid) {
1792 return new FXImage(getApp(), result, IMAGE_OWNED | IMAGE_KEEP | IMAGE_SHMI | IMAGE_SHMP, xSize, ySize);
1793 }
1794 FXFREE(&result);
1795#endif
1796 return nullptr;
1797}
1798
1799
1800void
1803 myDecalsLockMutex.lock();
1804 for (auto& decal : myDecals) {
1805 if (decal.skip2D || decal.filename.empty()) {
1806 continue;
1807 }
1808 if (!decal.initialised) {
1809 try {
1810 FXImage* img = checkGDALImage(decal);
1811 if (img == nullptr) {
1812 img = MFXImageHelper::loadImage(getApp(), decal.filename);
1813 }
1815 decal.glID = GUITexturesHelper::add(img);
1816 decal.initialised = true;
1817 decal.image = img;
1818 } catch (InvalidArgument& e) {
1819 WRITE_ERROR("Could not load '" + decal.filename + "'.\n" + e.what());
1820 decal.skip2D = true;
1821 }
1822 }
1824 if (decal.screenRelative) {
1825 Position center = screenPos2NetPos((int)decal.centerX, (int)decal.centerY);
1826 glTranslated(center.x(), center.y(), decal.layer);
1827 } else {
1828 glTranslated(decal.centerX, decal.centerY, decal.layer);
1829 }
1830 glRotated(decal.rot, 0, 0, 1);
1831 glColor3d(1, 1, 1);
1832 double halfWidth = decal.width / 2.;
1833 double halfHeight = decal.height / 2.;
1834 if (decal.screenRelative) {
1835 halfWidth = p2m(halfWidth);
1836 halfHeight = p2m(halfHeight);
1837 }
1838 GUITexturesHelper::drawTexturedBox(decal.glID, -halfWidth, -halfHeight, halfWidth, halfHeight);
1840 }
1841 myDecalsLockMutex.unlock();
1843}
1844
1845
1846void
1848 int x, y;
1849 FXuint b;
1850 myApp->getCursorPosition(x, y, b);
1851 int popX = x + myApp->getX();
1852 int popY = y + myApp->getY();
1853 myPopup->setX(popX);
1854 myPopup->setY(popY);
1855 myPopup->create();
1856 myPopup->show();
1857 // try to stay on screen unless click appears to come from a multi-screen setup
1858 const int rootWidth = getApp()->getRootWindow()->getWidth();
1859 const int rootHeight = getApp()->getRootWindow()->getHeight();
1860 if (popX <= rootWidth) {
1861 popX = MAX2(0, MIN2(popX, rootWidth - myPopup->getWidth() - 10));
1862 }
1863 if (popY <= rootHeight) {
1864 popY = MAX2(0, MIN2(popY, rootHeight - myPopup->getHeight() - 50));
1865 }
1866 myPopup->move(popX, popY);
1868 myChanger->onRightBtnRelease(nullptr);
1869 setFocus();
1870}
1871
1872// ------------ Additional visualisations
1873
1874bool
1876 if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1877 myAdditionallyDrawn[which] = 1;
1878 } else {
1879 myAdditionallyDrawn[which] = myAdditionallyDrawn[which] + 1;
1880 }
1881 update();
1882 return true;
1883}
1884
1885
1886bool
1888 if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1889 return false;
1890 }
1891 int cnt = myAdditionallyDrawn[which];
1892 if (cnt == 1) {
1893 myAdditionallyDrawn.erase(which);
1894 } else {
1895 myAdditionallyDrawn[which] = myAdditionallyDrawn[which] - 1;
1896 }
1897 update();
1898 return true;
1899}
1900
1901
1902bool
1904 if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1905 return false;
1906 } else {
1907 return true;
1908 }
1909}
1910
1911
1914 Boundary bound = myChanger->getViewport(fixRatio);
1915 glMatrixMode(GL_PROJECTION);
1916 glLoadIdentity();
1917 // as a rough rule, each GLObject is drawn at z = -GUIGlObjectType
1918 // thus, objects with a higher value will be closer (drawn on top)
1919 // // @todo last param should be 0 after modifying all glDraw methods
1920 glOrtho(0, getWidth(), 0, getHeight(), -GLO_MAX - 1, GLO_MAX + 1);
1921 glMatrixMode(GL_MODELVIEW);
1922 glLoadIdentity();
1923 double scaleX = (double)getWidth() / bound.getWidth();
1924 double scaleY = (double)getHeight() / bound.getHeight();
1925 glScaled(scaleX, scaleY, 1);
1926 glTranslated(-bound.xmin(), -bound.ymin(), 0);
1927 // rotate around the center of the screen
1928 //double angle = -90;
1929 if (myChanger->getRotation() != 0) {
1930 glTranslated(bound.getCenter().x(), bound.getCenter().y(), 0);
1931 glRotated(myChanger->getRotation(), 0, 0, 1);
1932 glTranslated(-bound.getCenter().x(), -bound.getCenter().y(), 0);
1933 Boundary rotBound;
1934 double rad = -DEG2RAD(myChanger->getRotation());
1935 rotBound.add(Position(bound.xmin(), bound.ymin()).rotateAround2D(rad, bound.getCenter()));
1936 rotBound.add(Position(bound.xmin(), bound.ymax()).rotateAround2D(rad, bound.getCenter()));
1937 rotBound.add(Position(bound.xmax(), bound.ymin()).rotateAround2D(rad, bound.getCenter()));
1938 rotBound.add(Position(bound.xmax(), bound.ymax()).rotateAround2D(rad, bound.getCenter()));
1939 bound = rotBound;
1940 }
1942 return bound;
1943}
1944
1945
1946double
1948 return myApp->getDelay();
1949}
1950
1951
1952void
1954 myApp->setDelay(delay);
1955}
1956
1957
1958void
1959GUISUMOAbstractView::setBreakpoints(const std::vector<SUMOTime>& breakpoints) {
1960 myApp->setBreakpoints(breakpoints);
1961}
1962
1963
1965 myGLObject(object) {
1966 first = layer;
1967 second.first = object->getType();
1968 second.second = object->getMicrosimID();
1969}
1970
1971
1973 myGLObject(object) {
1974 first = object->getType();
1975 second.first = object->getType();
1976 second.second = object->getMicrosimID();
1977}
1978
1979
1982 return myGLObject;
1983}
1984
1985
1986std::vector<GUIGlObject*>
1987GUISUMOAbstractView::filterGUIGLObjectsByLayer(const std::vector<GUIGlObject*>& objects) const {
1988 // declare map for saving shapes sorted by layer and ID
1989 std::set<LayerObject> layerObjects;
1990 for (const auto& object : objects) {
1991 if ((object->getType() == GLO_POLYGON) || (object->getType() == GLO_POI)) {
1992 layerObjects.insert(LayerObject(dynamic_cast<Shape*>(object)->getShapeLayer(), object));
1993 } else {
1994 layerObjects.insert(LayerObject(object));
1995 }
1996 }
1997 // declare vector for saving object filtered by layer
1998 std::vector<GUIGlObject*> objectsFiltered;
1999 // insert in objects filtered sorted from bot to top
2000 for (const auto& object : layerObjects) {
2001 objectsFiltered.push_back(object.getGLObject());
2002 }
2003 // reverse objets filtered to top from bot
2004 std::reverse(objectsFiltered.begin(), objectsFiltered.end());
2005 return objectsFiltered;
2006}
2007
2008/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ MID_GLCANVAS
GLCanvas - ID.
Definition GUIAppEnum.h:406
@ MID_REACHABILITY
show reachability from a given lane
Definition GUIAppEnum.h:524
@ MID_CLOSE_LANE
close lane
Definition GUIAppEnum.h:659
@ MID_CURSORDIALOG_FRONT
remove/select/mark front element
Definition GUIAppEnum.h:437
@ MID_CLOSE_EDGE
close edge
Definition GUIAppEnum.h:661
@ MID_SIMPLE_VIEW_COLORCHANGE
Informs the dialog about a value's change.
Definition GUIAppEnum.h:620
@ MID_ADD_REROUTER
add rerouter
Definition GUIAppEnum.h:663
GUICompleteSchemeStorage gSchemeStorage
@ MOVEVIEW
move view cursor
@ DEFAULT
default cursor
unsigned int GUIGlID
Definition GUIGlObject.h:43
GUIGlObjectType
@ GLO_REROUTER_EDGE
a Rerouter over edge
@ GLO_TRIP
a trip
@ GLO_ROUTEFLOW
a routeFlow
@ GLO_MAX
empty max
@ GLO_LANE
a lane
@ GLO_FLOW
a flow
@ GLO_CONTAINER
a container
@ GLO_EDGE
an edge
@ GLO_VEHICLE
a vehicle
@ GLO_PERSON
a person
@ GLO_NETWORK
The network - empty.
@ GLO_POI
a poi
@ GLO_CONTAINERFLOW
a person flow
@ GLO_POLYGON
a polygon
@ GLO_TLLOGIC
a tl-logic
@ GLO_PERSONFLOW
a person flow
GUISelectedStorage gSelected
A global holder of selected objects.
FXDEFMAP(GUISUMOAbstractView) GUISUMOAbstractViewMap[]
#define DEG2RAD(x)
Definition GeomHelper.h:35
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:271
#define WRITE_ERROR(msg)
Definition MsgHandler.h:279
#define WRITE_WARNING(msg)
Definition MsgHandler.h:270
#define TL(string)
Definition MsgHandler.h:287
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
int gPrecisionGeo
Definition StdDefs.cpp:27
const double SUMO_const_laneWidth
Definition StdDefs.h:48
#define UNUSED_PARAMETER(x)
Definition StdDefs.h:30
T MIN2(T a, T b)
Definition StdDefs.h:76
T MAX2(T a, T b)
Definition StdDefs.h:82
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition ToString.h:283
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
Position getCenter() const
Returns the center of the boundary.
Definition Boundary.cpp:112
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition Boundary.cpp:78
double ymin() const
Returns minimum y-coordinate.
Definition Boundary.cpp:130
double xmin() const
Returns minimum x-coordinate.
Definition Boundary.cpp:118
Boundary & grow(double by)
extends the boundary by the given amount
Definition Boundary.cpp:300
double getHeight() const
Returns the height of the boundary (y-axis)
Definition Boundary.cpp:160
double getWidth() const
Returns the width of the boudary (x-axis)
Definition Boundary.cpp:154
double ymax() const
Returns maximum y-coordinate.
Definition Boundary.cpp:136
double xmax() const
Returns maximum x-coordinate.
Definition Boundary.cpp:124
static void resetVertexCounter()
reset vertex counter
Definition GLHelper.cpp:175
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:583
static void pushName(unsigned int name)
push Name
Definition GLHelper.cpp:139
static void checkCounterMatrix()
check counter matrix (for debug purposes)
Definition GLHelper.cpp:181
static void popMatrix()
pop matrix
Definition GLHelper.cpp:130
static int getMatrixCounter()
get matrix counter
Definition GLHelper.cpp:157
static void checkCounterName()
check counter name (for debug purposes)
Definition GLHelper.cpp:192
static void popName()
pop Name
Definition GLHelper.cpp:148
static void pushMatrix()
push matrix
Definition GLHelper.cpp:117
static void setGL2PS(bool active=true)
set GL2PS
Definition GLHelper.cpp:607
static int getVertexCounter()
get vertex counter
Definition GLHelper.cpp:169
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, const int align=0, double width=-1)
Definition GLHelper.cpp:685
static void resetMatrixCounter()
reset matrix counter
Definition GLHelper.cpp:163
GUIVisualizationSettings & getDefault()
Returns the default scheme.
void saveViewport(const double x, const double y, const double z, const double rot)
Makes the given viewport the default.
const std::vector< GUISUMOAbstractView::Decal > & getDecals()
Returns the default decals.
void setDefault(const std::string &name)
Makes the scheme with the given name the default.
void saveDecals(const std::vector< GUISUMOAbstractView::Decal > &decals)
Makes the given decals the default.
void setViewport(GUISUMOAbstractView *view)
Sets the default viewport.
Dialog for edit rerouter intervals.
static FXCursor * getCursor(GUICursor which)
returns a cursor previously defined in the enum GUICursor
A dialog to change the viewport.
void setOldValues(const Position &lookFrom, const Position &lookAt, double rotation)
Resets old values.
bool haveGrabbed() const
Returns the information whether one of the spin dialers is grabbed.
void setValues(double zoom, double xoff, double yoff, double rotation)
Sets the given values into the dialog.
void show()
overload show function to focus always in OK Button
The dialog to change the view (gui) settings.
void show()
show view settings dialog
void setCurrent(GUIVisualizationSettings *settings)
Sets current settings (called if reopened)
The popup menu of a globject.
FXComboBox * getColoringSchemesCombo()
return combobox with the current coloring schemes (standard, fastest standard, real world....
GUIMainWindow * getGUIMainWindowParent()
Returns the GUIMainWindow parent.
static const GUIGlID INVALID_ID
Definition GUIGlObject.h:71
virtual double getClickPriority() const
Returns the priority of receiving mouse clicks.
virtual Boundary getCenteringBoundary() const =0
virtual void onLeftBtnPress(void *)
notify object about left click
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
GUIGlID getGlID() const
Returns the numerical id of the object.
void unblockObject(GUIGlID id)
Marks an object as unblocked.
GUIGlObject * getNetObject() const
Returns the network object.
GUIGlObject * getObjectBlocking(GUIGlID id) const
Returns the object from the container locking it.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
Representation of a lane in the micro simulation (gui-version)
Definition GUILane.h:60
MFXStaticToolTip * getStaticTooltipView() const
get static toolTip for view
virtual double getDelay() const
Returns the delay (should be overwritten by subclasses if applicable)
FXLabel * getGeoLabel()
get geo label
bool isGaming() const
return whether the gui is in gaming mode
virtual void setBreakpoints(const std::vector< SUMOTime > &)
Sets the breakpoints of the parent application.
FXLabel * getTestLabel()
get test label
virtual void setStatusBarText(const std::string &)
get status bar text (can be implemented in children)
virtual void setDelay(double)
Sets the delay of the parent application.
FXLabel * getCartesianLabel()
get cartesian label
FXHorizontalFrame * getTestFrame()
get test frame
virtual void setViewportFrom(double xPos, double yPos, double zPos)=0
Alternative method for setting the viewport.
virtual long onKeyPress(void *data)
called when user press a key
virtual void setRotation(double rotation)=0
Sets the rotation.
virtual void onRightBtnPress(void *data)
called when user press right button
virtual void centerTo(const Position &pos, double radius, bool applyZoom=true)=0
Centers the view to the given position, setting it to a size that covers the radius....
virtual double getRotation() const =0
Returns the rotation of the canvas stored in this changer.
virtual bool onLeftBtnRelease(void *data)
called when user releases left button
virtual double getZoom() const =0
Returns the zoom factor computed stored in this changer.
virtual void onLeftBtnPress(void *data)
mouse functions
virtual bool onMiddleBtnRelease(void *data)
called when user releases middle button
virtual double getXPos() const =0
Returns the x-offset of the field to show stored in this changer.
virtual double getYPos() const =0
Returns the y-offset of the field to show stored in this changer.
virtual void onMiddleBtnPress(void *data)
called when user press middle button
virtual long onKeyRelease(void *data)
called when user releases a key
virtual void onMouseMove(void *data)
called when user moves mouse
virtual double getZPos() const =0
Returns the camera height corresponding to the current zoom factor.
virtual void onMouseWheel(void *data)
called when user changes mouse wheel
virtual bool onRightBtnRelease(void *data)
called when user releases right button
Boundary getViewport(bool fixRatio=true)
get viewport
virtual void setViewport(double zoom, double xPos, double yPos)=0
Sets the viewport Used for: Adapting a new viewport.
const std::vector< double > & getThresholds() const
const std::vector< std::string > & getNames() const
const std::string & getName() const
const std::vector< T > & getColors() const
void paintGLGrid()
paints a grid
bool myAmInitialised
Internal information whether doInit() was called.
Position snapToActiveGrid(const Position &pos, bool snapXY=true) const
Returns a position that is mapped to the closest grid point if the grid is active.
std::vector< GUIGlObject * > myCurrentObjectsDialog
vector with current objects dialog
std::string makeSnapshot(const std::string &destFile, const int w=-1, const int h=-1)
Takes a snapshots and writes it into the given file.
void updateToolTip()
A method that updates the tooltip.
void addDecals(const std::vector< Decal > &decals)
add decals
virtual void checkSnapshots()
Checks whether it is time for a snapshot.
void showViewschemeEditor()
show viewsscheme editor
static const double SENSITIVITY
virtual long onLeftBtnRelease(FXObject *, FXSelector, void *)
void displayLegend()
Draws a line with ticks, and the length information.
virtual long onVisualizationChange(FXObject *, FXSelector, void *)
hook to react on change in visualization settings
std::vector< GUIGlObject * > getGUIGlObjectsUnderCursor()
returns the GUIGlObject under the cursor using GL_SELECT (including overlapped objects)
long myFrameDrawTime
counter for measuring rendering time
void replacePopup(GUIGLObjectPopupMenu *popUp)
replace PopUp
std::vector< GUIGlID > getObjectsAtPosition(Position pos, double radius)
returns the ids of the object at position within the given (rectangular) radius using GL_SELECT
const SUMORTree * myGrid
The visualization speed-up.
void openObjectDialog(const std::vector< GUIGlObject * > &objects, const bool filter=true)
open object dialog for the given object
virtual void saveFrame(const std::string &destFile, FXColor *buf)
Adds a frame to a video snapshot which will be initialized if necessary.
virtual void recenterView()
recenters the view
virtual SUMOTime getCurrentTimeStep() const
get the current simulation time
std::vector< GUIGlID > getObjectsInBoundary(Boundary bound, bool singlePosition)
returns the ids of all objects in the given boundary
FXbool makeCurrent()
A reimplementation due to some internal reasons.
int myMouseHotspotX
Offset to the mouse-hotspot from the mouse position.
std::vector< GUIGlObject * > filterInernalLanes(const std::vector< GUIGlObject * > &objects) const
filter internal lanes in Objects under cursor
GUIMainWindow * getMainWindow() const
get main window
bool isInEditMode()
returns true, if the edit button was pressed
virtual long onMiddleBtnRelease(FXObject *, FXSelector, void *)
virtual long onMouseMove(FXObject *, FXSelector, void *)
bool myPanning
Panning flag.
bool isAdditionalGLVisualisationEnabled(GUIGlObject *const which) const
Check if an object is added in the additional GL visualitation.
FXMutex myDecalsLockMutex
The mutex to use before accessing the decals list in order to avoid thread conflicts.
FXCondition mySnapshotCondition
the semaphore when waiting for snapshots to finish
Position myPopupPosition
The current popup-menu position.
virtual void doInit()
doInit
virtual long onCmdCloseEdge(FXObject *, FXSelector, void *)
virtual int doPaintGL(int, const Boundary &)
paint GL
virtual void showViewportEditor()
show viewport editor
const GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings (read only)
void setDelay(double delay)
Sets the delay of the parent application.
Boundary getVisibleBoundary() const
get visible boundary
Position screenPos2NetPos(int x, int y) const
Translate screen position to network position.
void addSnapshot(SUMOTime time, const std::string &file, const int w=-1, const int h=-1)
Sets the snapshot time to file map.
GUIGlID getObjectUnderCursor()
returns the id of the front object under the cursor using GL_SELECT
GUIPerspectiveChanger & getChanger() const
get changer
virtual void centerTo(GUIGlID id, bool applyZoom, double zoomDist=20)
centers to the chosen artifact
GUIMainWindow * myApp
The application.
GUIDialog_EditViewport * getViewportEditor()
get the viewport and create it on first access
virtual void zoom2Pos(Position &camera, Position &lookAt, double zoom)
zoom interface for 3D view
virtual long onCmdCloseLane(FXObject *, FXSelector, void *)
interaction with the simulation
void drawFPS()
Draws frames-per-second indicator.
virtual long onMouseWheel(FXObject *, FXSelector, void *)
double getGridWidth() const
get grid width
std::vector< Decal > & getDecals()
The list of decals to show.
std::vector< GUIGlObject * > filterGUIGLObjectsByLayer(const std::vector< GUIGlObject * > &objects) const
@fbrief filter elements by layer
bool removeAdditionalGLVisualisation(GUIGlObject *const which)
Removes an object from the list of objects that show additional things.
GUIGlChildWindow * myGlChildWindowParent
The parent window.
GUIGlChildWindow * getGUIGlChildWindow()
get GUIGlChildWindow
double getDelay() const
Returns the delay of the parent application.
virtual void updatePositionInformationLabel() const
update position information labels
std::vector< GUIGlObject * > getGUIGlObjectsAtPosition(Position pos, double radius)
returns the GUIGlObjects at position within the given (rectangular) radius using GL_SELECT
virtual long onLeftBtnPress(FXObject *, FXSelector, void *)
virtual void setViewportFromToRot(const Position &lookFrom, const Position &lookAt, double rotation)
applies the given viewport settings
double p2m(double pixel) const
pixels-to-meters conversion method
std::vector< Decal > myDecals
The list of decals to show.
const Position & getPopupPosition() const
get position of current popup
double m2p(double meter) const
meter-to-pixels conversion method
virtual GUILane * getLaneUnderCursor()
returns the GUILane at cursor position (implementation depends on view)
virtual void openObjectDialogAtCursor(const FXEvent *ev)
open object dialog at the cursor position
virtual void onGamingClick(Position)
on gaming click
bool myInEditMode
Information whether too-tip informations shall be generated.
GUIVisualizationSettings * editVisualisationSettings() const
edit visualization settings (allow modify VisualizationSetings, use carefully)
GUIVisualizationSettings * myVisualizationSettings
visualization settings
void destroyPopup()
destroys the popup
Position getWindowCursorPosition() const
return windows cursor position
virtual long onKeyPress(FXObject *o, FXSelector sel, void *data)
keyboard functions
GUIDialog_EditViewport * myGUIDialogEditViewport
viewport chooser
virtual long onMiddleBtnPress(FXObject *, FXSelector, void *)
void paintGL()
FOX needs this.
virtual void stopTrack()
stop track
virtual Position getPositionInformation() const
Returns the cursor's x/y position within the network.
GUIGlID getObjectAtPosition(Position pos)
returns the id of the object at position using GL_SELECT
std::vector< GUIGlObject * > getGUIGlObjectsUnderSnappedCursor()
returns the GUIGlObject under the gripped cursor using GL_SELECT (including overlapped objects)
bool showToolTipFor(const GUIGlID idToolTip)
invokes the tooltip for the given object
virtual long onKeyRelease(FXObject *o, FXSelector sel, void *data)
GUIDialog_ViewSettings * myGUIDialogViewSettings
Visualization changer.
virtual void onGamingRightClick(Position)
void setWindowCursorPosition(FXint x, FXint y)
Returns the gl-id of the object under the given coordinates.
double getFPS() const
retrieve FPS
virtual long onCmdShowReachability(FXObject *, FXSelector, void *)
highlight edges according to reachability
std::map< GUIGlObject *, int > myAdditionallyDrawn
List of objects for which GUIGlObject::drawGLAdditional is called.
void drawDecals()
Draws the stored decals.
std::vector< GUIGlID > getObjectsUnderCursor()
returns the id of the objects under the cursor using GL_SELECT (including overlapped objects)
Boundary applyGLTransform(bool fixRatio=true)
applies gl-transformations to fit the Boundary given by myChanger onto the canvas....
virtual void updateViewportValues()
update the viewport chooser with the current view values
FXImage * checkGDALImage(Decal &d)
check whether we can read image data or position with gdal
double getGridHeight() const
get grid height
virtual void startTrack(int)
star track
virtual long onDoubleClicked(FXObject *, FXSelector, void *)
FXMutex & getDecalsLockMutex()
The mutex to use before accessing the decals list in order to avoid thread conflicts.
virtual bool is3DView() const
return whether this is a 3D view
void displayLegends()
Draws the configured legends.
void displayColorLegend(const GUIColorScheme &scheme, bool leftSide)
Draws a legend for the given scheme.
FXMutex mySnapshotsMutex
The mutex to use before accessing the decals list in order to avoid thread conflicts.
virtual long onMouseLeft(FXObject *, FXSelector, void *)
virtual long onRightBtnRelease(FXObject *, FXSelector, void *)
FXint myWindowCursorPositionX
Position of the cursor relative to the window.
GUIPerspectiveChanger * myChanger
The perspective changer.
GUIGLObjectPopupMenu * myPopup
The current popup-menu.
virtual void copyViewportTo(GUISUMOAbstractView *view)
copy the viewport to the given view
void setBreakpoints(const std::vector< SUMOTime > &breakpoints)
Sets the breakpoints of the parent application.
FXComboBox * getColoringSchemesCombo()
get coloring schemes combo
void waitForSnapshots(const SUMOTime snapshotTime)
bool addAdditionalGLVisualisation(GUIGlObject *const which)
Adds an object to call its additional visualisation method.
virtual bool setColorScheme(const std::string &)
set color scheme
virtual long onCmdAddRerouter(FXObject *, FXSelector, void *)
virtual long onPaint(FXObject *, FXSelector, void *)
virtual long onRightBtnPress(FXObject *, FXSelector, void *)
virtual ~GUISUMOAbstractView()
destructor
virtual long onConfigure(FXObject *, FXSelector, void *)
mouse functions
std::map< SUMOTime, std::vector< std::tuple< std::string, int, int > > > mySnapshots
Snapshots.
void remove(GUIDialog_EditViewport *)
remove viewport
virtual GUIGlID getTrackedID() const
get tracked id
void openPopupDialog()
open popup dialog
void toggleSelection(GUIGlID id)
Toggles selection of an object.
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
static GUIGlID add(FXImage *i)
Adds a texture to use.
static int getMaxTextureSize()
return maximum number of pixels in x and y direction
Stores the information about how to visualize structures.
RGBColor backgroundColor
The background color to use.
bool dither
Information whether dithering shall be enabled.
GUIColorer vehicleColorer
The vehicle colorer.
bool drawForRectangleSelection
whether drawing is performed for the purpose of selecting objects using a rectangle
GUIVisualizationSizeSettings addSize
bool altKeyPressed
alt key pressed (only used for draw polygons under other elements in SUMO-GUI, store is not needed)
std::string name
The name of this setting.
bool drawJunctionShape
whether the shape of the junction should be drawn
bool drawForPositionSelection
whether drawing is performed for the purpose of selecting objects with a single click
bool gaming
whether the application is in gaming mode or not
bool fps
Information whether frames-per-second should be drawn.
bool showGrid
Information whether a grid shall be shown.
bool showVehicleColorLegend
Information whether the vehicle color legend shall be drawn.
double scale
information about a lane's width (temporary, used for a single view)
GUIColorScheme & getLaneEdgeScheme()
Returns the current lane (edge) coloring schme.
bool showSizeLegend
Information whether the size legend shall be drawn.
double gridXSize
Information about the grid spacings.
bool showColorLegend
Information whether the edge color legend shall be drawn.
double angle
The current view rotation angle.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
static FXImage * loadImage(FXApp *a, const std::string &file)
static FXbool scalePower2(FXImage *image, int maxSize=(2<< 29))
static FXbool saveImage(const std::string &file, int width, int height, FXColor *data)
static void sleep(long ms)
void showStaticToolTip(const FXString &toolTipText)
show static toolTip
void hideStaticToolTip()
hide static toolTip
bool isStaticToolTipEnabled() const
check staticToolTip is enabled
static OptionsCont & getOptions()
Retrieves the options.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
void setx(double x)
set position x
Definition Position.h:70
void set(double x, double y)
set positions x and y
Definition Position.h:85
static const Position INVALID
used to indicate that a position is valid
Definition Position.h:300
double x() const
Returns the x-position.
Definition Position.h:55
void setz(double z)
set position z
Definition Position.h:80
Position rotateAround2D(double rad, const Position &origin)
rotate this position by rad around origin and return the result
Definition Position.cpp:41
double z() const
Returns the z-position.
Definition Position.h:65
void sety(double y)
set position y
Definition Position.h:75
double y() const
Returns the y-position.
Definition Position.h:60
static RGBColor interpolate(const RGBColor &minColor, const RGBColor &maxColor, double weight)
Interpolates between two colors.
Definition RGBColor.cpp:355
static const RGBColor WHITE
Definition RGBColor.h:192
unsigned char red() const
Returns the red-amount of the color.
Definition RGBColor.cpp:74
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:92
unsigned char green() const
Returns the green-amount of the color.
Definition RGBColor.cpp:80
unsigned char blue() const
Returns the blue-amount of the color.
Definition RGBColor.cpp:86
static const RGBColor BLACK
Definition RGBColor.h:193
static const RGBColor RED
named colors
Definition RGBColor.h:185
A RT-tree for efficient storing of SUMO's GL-objects.
Definition SUMORTree.h:66
virtual int Search(const float a_min[2], const float a_max[2], const GUIVisualizationSettings &c) const
Find all within search rectangle.
Definition SUMORTree.h:116
A 2D- or 3D-Shape.
Definition Shape.h:38
double getShapeLayer() const
Returns the layer of the Shape.
Definition Shape.h:91
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition SysUtils.cpp:43
FONSalign
Definition fontstash.h:40
@ FONS_ALIGN_LEFT
Definition fontstash.h:42
@ FONS_ALIGN_RIGHT
Definition fontstash.h:44
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition json.hpp:21884
A decal (an image) that can be shown.
double centerX
The center of the image in x-direction (net coordinates, in m)
double height
The height of the image (net coordinates in y-direction, in m)
double width
The width of the image (net coordinates in x-direction, in m)
double centerY
The center of the image in y-direction (net coordinates, in m)
std::string filename
The path to the file the image is located at.
struct used for sorting objects by layer
GUIGlObject * getGLObject() const
get GLObject
LayerObject(double layer, GUIGlObject *object)
constructor for shapes
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values