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-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/****************************************************************************/
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// debug constants
92// ===========================================================================
93//#define DEBUG_SNAPSHOT
94
95// ===========================================================================
96// static members
97// ===========================================================================
98
99const double GUISUMOAbstractView::SENSITIVITY = 0.1; // meters
100
101// ===========================================================================
102// FOX callback mapping
103// ===========================================================================
104
105FXDEFMAP(GUISUMOAbstractView) GUISUMOAbstractViewMap[] = {
106 FXMAPFUNC(SEL_CONFIGURE, 0, GUISUMOAbstractView::onConfigure),
107 FXMAPFUNC(SEL_PAINT, 0, GUISUMOAbstractView::onPaint),
108 FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, GUISUMOAbstractView::onLeftBtnPress),
109 FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, GUISUMOAbstractView::onLeftBtnRelease),
110 FXMAPFUNC(SEL_MIDDLEBUTTONPRESS, 0, GUISUMOAbstractView::onMiddleBtnPress),
111 FXMAPFUNC(SEL_MIDDLEBUTTONRELEASE, 0, GUISUMOAbstractView::onMiddleBtnRelease),
112 FXMAPFUNC(SEL_RIGHTBUTTONPRESS, 0, GUISUMOAbstractView::onRightBtnPress),
113 FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, 0, GUISUMOAbstractView::onRightBtnRelease),
114 FXMAPFUNC(SEL_DOUBLECLICKED, 0, GUISUMOAbstractView::onDoubleClicked),
115 FXMAPFUNC(SEL_MOUSEWHEEL, 0, GUISUMOAbstractView::onMouseWheel),
116 FXMAPFUNC(SEL_MOTION, 0, GUISUMOAbstractView::onMouseMove),
117 FXMAPFUNC(SEL_LEAVE, 0, GUISUMOAbstractView::onMouseLeft),
118 FXMAPFUNC(SEL_KEYPRESS, 0, GUISUMOAbstractView::onKeyPress),
119 FXMAPFUNC(SEL_KEYRELEASE, 0, GUISUMOAbstractView::onKeyRelease),
126};
127
128FXIMPLEMENT_ABSTRACT(GUISUMOAbstractView, FXGLCanvas, GUISUMOAbstractViewMap, ARRAYNUMBER(GUISUMOAbstractViewMap))
129
130// ===========================================================================
131// member method definitions
132// ===========================================================================
133
134GUISUMOAbstractView::GUISUMOAbstractView(FXComposite* p, GUIMainWindow& app, GUIGlChildWindow* parent, const SUMORTree& grid, FXGLVisual* glVis, FXGLCanvas* share) :
135 FXGLCanvas(p, glVis, share, p, MID_GLCANVAS, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0),
136 myApp(&app),
137 myGlChildWindowParent(parent),
138 myGrid(&grid),
139 myMouseHotspotX(app.getDefaultCursor()->getHotX()),
140 myMouseHotspotY(app.getDefaultCursor()->getHotY()),
141 myWindowCursorPositionX(getWidth() / 2),
142 myWindowCursorPositionY(getHeight() / 2) {
143 setTarget(this);
144 enable();
145 flags |= FLAG_ENABLED;
146 myChanger = new GUIDanielPerspectiveChanger(*this, *myGrid);
147 myVisualizationSettings = &gSchemeStorage.getDefault();
148 myVisualizationSettings->gaming = myApp->isGaming();
150 myDecals = gSchemeStorage.getDecals();
151}
152
153
158 delete myPopup;
159 delete myChanger;
162 // cleanup decals
163 for (auto& decal : myDecals) {
164 delete decal.image;
165 }
166 // remove all elements
167 for (auto& additional : myAdditionallyDrawn) {
168 additional.first->removeActiveAddVisualisation(this, ~0);
169 }
170}
171
172
173bool
177
178
181 return *myChanger;
182}
183
184
185void
191
192
197
198
200GUISUMOAbstractView::snapToActiveGrid(const Position& pos, bool snapXY) const {
201 Position result = pos;
203 if (snapXY) {
204 const double xRest = std::fmod(pos.x(), myVisualizationSettings->gridXSize) + (pos.x() < 0 ? myVisualizationSettings->gridXSize : 0);
205 const double yRest = std::fmod(pos.y(), myVisualizationSettings->gridYSize) + (pos.y() < 0 ? myVisualizationSettings->gridYSize : 0);
206 result.setx(pos.x() - xRest + (xRest < myVisualizationSettings->gridXSize * 0.5 ? 0 : myVisualizationSettings->gridXSize));
207 result.sety(pos.y() - yRest + (yRest < myVisualizationSettings->gridYSize * 0.5 ? 0 : myVisualizationSettings->gridYSize));
208 } else {
209 // snapZToActiveGrid uses grid Y Size
210 const double zRest = std::fmod(pos.z(), myVisualizationSettings->gridYSize) + (pos.z() < 0 ? myVisualizationSettings->gridYSize : 0);
211 result.setz(pos.z() - zRest + (zRest < myVisualizationSettings->gridYSize * 0.5 ? 0 : myVisualizationSettings->gridYSize));
212 }
213 }
214 return result;
215}
216
217
220 Boundary bound = myChanger->getViewport();
221 double xNet = bound.xmin() + bound.getWidth() * x / getWidth();
222 // cursor origin is in the top-left corner
223 double yNet = bound.ymin() + bound.getHeight() * (getHeight() - y) / getHeight();
224 // rotate around the viewport center
225 if (myChanger->getRotation() != 0) {
226 return Position(xNet, yNet).rotateAround2D(-DEG2RAD(myChanger->getRotation()), bound.getCenter());
227 } else {
228 return Position(xNet, yNet);
229 }
230}
231
232
233void
234GUISUMOAbstractView::addDecals(const std::vector<Decal>& decals) {
235 myDecals.insert(myDecals.end(), decals.begin(), decals.end());
236}
237
238
239void
242 // set cartesian position
243 myApp->getCartesianLabel()->setText(("x:" + toString(pos.x()) + ", y:" + toString(pos.y())).c_str());
244 // set geo position
246 if (GeoConvHelper::getFinal().usingGeoProjection()) {
247 myApp->getGeoLabel()->setText(("lat:" + toString(pos.y(), gPrecisionGeo) + ", lon:" + toString(pos.x(), gPrecisionGeo)).c_str());
248 } else {
249 myApp->getGeoLabel()->setText(TL("(No projection defined)"));
250 }
251 // if enabled, set test position
252 if (myApp->getTestFrame()) {
253 if (OptionsCont::getOptions().getBool("gui-testing")) {
254 myApp->getTestFrame()->show();
255 // adjust cursor position (24,25) to show exactly the same position as in function netedit.leftClick(match, X, Y)
256 myApp->getTestLabel()->setText(("Test: x:" + toString(getWindowCursorPosition().x() - 24.0) + " y:" + toString(getWindowCursorPosition().y() - 25.0)).c_str());
257 } else {
258 myApp->getTestFrame()->hide();
259 }
260 }
261}
262
263
264int
265GUISUMOAbstractView::doPaintGL(int /*mode*/, const Boundary& /*boundary*/) {
266 return 0;
267}
268
269
270void
273
274
279
280
281bool
283 return false;
284}
285
286
287void GUISUMOAbstractView::zoom2Pos(Position& /* camera */, Position& /* lookAt */, double /* zoom */) {
288}
289
290
291void
293 // reset debug counters
296 if (getWidth() == 0 || getHeight() == 0) {
297 return;
298 }
299 const long start = SysUtils::getCurrentMillis();
300
302 centerTo(getTrackedID(), false);
303 }
304 // draw
305 glClearColor(
310 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
311 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
312
314 glEnable(GL_DITHER);
315 } else {
316 glDisable(GL_DITHER);
317 }
318 glEnable(GL_BLEND);
319 glDisable(GL_LINE_SMOOTH);
320
321 Boundary bound = applyGLTransform();
322 doPaintGL(GL_RENDER, bound);
326 const long end = SysUtils::getCurrentMillis();
327 myFrameDrawTime = end - start;
329 drawFPS();
330 }
331 // check if show tooltip
334 } else {
336 }
337 swapBuffers();
338}
339
340
341long
342GUISUMOAbstractView::onCmdCloseLane(FXObject*, FXSelector, void*) {
343 return 1;
344}
345
346
347long
348GUISUMOAbstractView::onCmdCloseEdge(FXObject*, FXSelector, void*) {
349 return 1;
350}
351
352
353long
354GUISUMOAbstractView::onCmdAddRerouter(FXObject*, FXSelector, void*) {
355 return 1;
356}
357
358
359long
360GUISUMOAbstractView::onCmdShowReachability(FXObject*, FXSelector, void*) {
361 return 1;
362}
363
364
365long
366GUISUMOAbstractView::onVisualizationChange(FXObject*, FXSelector, void*) {
367 return 1;
368}
369
370
371GUILane*
373 return nullptr;
374}
375
376
381
382
385 return getObjectAtPosition(getPositionInformation(), sensitivity);
386}
387
388
389std::vector<GUIGlID>
393
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);
415 // Interpret results
416 int idMax = 0;
417 double maxLayer = -std::numeric_limits<double>::max();
418 double minDist = std::numeric_limits<double>::max();
419 // iterate over obtained GUIGlIDs
420 for (const auto& i : ids) {
421 // obtain GUIGlObject
423 // check that GUIGlObject exist
424 if (o == nullptr) {
425 continue;
426 }
427 // check that GUIGlObject isn't the network
428 if (o->getGlID() == 0) {
429 continue;
430 }
431 //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
432 double layer = o->getClickPriority();
433 double dist = o->getCenter().distanceTo2D(pos);
434 // check whether the current object is above a previous one
435 if (layer > maxLayer) {
436 idMax = i;
437 maxLayer = layer;
438 minDist = dist;
439 } else if (layer == maxLayer && dist < minDist) {
440 idMax = i;
441 minDist = dist;
442 }
443 // unblock object
445 }
446 return idMax;
447}
448
449
450std::vector<GUIGlID>
452 // declare result vector
453 std::vector<GUIGlID> result;
454 // calculate boundary
455 Boundary selection;
456 selection.add(pos);
457 selection.grow(radius);
458 // obtain GUIGlID of objects in boundary
459 const std::vector<GUIGlID> ids = getObjectsInBoundary(selection);
460 // iterate over obtained GUIGlIDs
461 for (const auto& i : ids) {
462 // obtain GUIGlObject
464 // check that GUIGlObject exist
465 if (o == nullptr) {
466 continue;
467 }
468 // check that GUIGlObject isn't the network
469 if (o->getGlID() == 0) {
470 continue;
471 }
472 //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
473 GUIGlObjectType type = o->getType();
474 // avoid network
475 if (type != GLO_NETWORK) {
476 result.push_back(i);
477 }
478 // unblock object
480 }
481 return result;
482}
483
484
485std::vector<GUIGlObject*>
487 // declare result vector
488 std::vector<GUIGlObject*> result;
489 // calculate boundary
490 Boundary selection;
491 selection.add(pos);
492 selection.grow(radius);
493 // obtain GUIGlID of objects in boundary
494 const std::vector<GUIGlID> ids = getObjectsInBoundary(selection);
495 // iterate over obtained GUIGlIDs
496 for (const auto& i : ids) {
497 // obtain GUIGlObject
499 // check that GUIGlObject exist
500 if (o == nullptr) {
501 continue;
502 }
503 // check that GUIGlObject isn't the network
504 if (o->getGlID() == 0) {
505 continue;
506 }
507 result.push_back(o);
508 // unblock object
510 }
511 return result;
512}
513
514
515std::vector<GUIGlID>
517 const int NB_HITS_MAX = 1024 * 1024;
518 // Prepare the selection mode
519 static GUIGlID hits[NB_HITS_MAX];
520 static GLint nb_hits = 0;
521 glSelectBuffer(NB_HITS_MAX, hits);
522 glInitNames();
523
525 Boundary oldViewPort = myChanger->getViewport(false); // backup the actual viewPort
526 myChanger->setViewport(bound);
527 bound = applyGLTransform(false);
528 // enable draw for selecting (to draw objects with less details)
530 int hits2 = doPaintGL(GL_SELECT, bound);
531 // reset flags
533 // Get the results
534 nb_hits = glRenderMode(GL_RENDER);
535 if (nb_hits == -1) {
536 myApp->setStatusBarText("Selection in boundary failed. Try to select fewer than " + toString(hits2) + " items");
537 }
538 std::vector<GUIGlID> result;
539 GLuint numNames;
540 GLuint* ptr = hits;
541 for (int i = 0; i < nb_hits; ++i) {
542 numNames = *ptr;
543 ptr += 3;
544 for (int j = 0; j < (int)numNames; j++) {
545 result.push_back(*ptr);
546 ptr++;
547 }
548 }
549 // switch viewport back to normal
550 myChanger->setViewport(oldViewPort);
551 return result;
552}
553
554
555std::vector<GUIGlObject*>
556GUISUMOAbstractView::filterInternalLanes(const std::vector<GUIGlObject*>& objects) const {
557 // count number of internal lanes
558 size_t internalLanes = 0;
559 for (const auto& object : objects) {
560 if ((object->getType() == GLO_LANE) && (object->getMicrosimID().find(':') != std::string::npos)) {
561 internalLanes++;
562 }
563 }
564 // if all objects are internal lanes, return it all
565 if (objects.size() == internalLanes || !myVisualizationSettings->drawJunctionShape) {
566 return objects;
567 }
568 // in other case filter internal lanes
569 std::vector<GUIGlObject*> filteredObjects;
570 for (const auto& object : objects) {
571 if ((object->getType() == GLO_LANE) && (object->getMicrosimID().find(':') != std::string::npos)) {
572 continue;
573 }
574 filteredObjects.push_back(object);
575 }
576 return filteredObjects;
577}
578
579
580bool
582 if (idToolTip != GUIGlObject::INVALID_ID) {
584 if (object != nullptr) {
586 return true;
587 }
588 }
589 // nothing to show
591 return false;
592}
593
594
595void
597 // obtain minimum grid
599 // Check if the distance is enough to draw grid
601 glEnable(GL_DEPTH_TEST);
602 glLineWidth(1);
603 // get multiplication values (2 is the margin)
604 const int multXmin = (int)(myChanger->getViewport().xmin() / myVisualizationSettings->gridXSize) - 2;
605 const int multYmin = (int)(myChanger->getViewport().ymin() / myVisualizationSettings->gridYSize) - 2;
606 const int multXmax = (int)(myChanger->getViewport().xmax() / myVisualizationSettings->gridXSize) + 2;
607 const int multYmax = (int)(myChanger->getViewport().ymax() / myVisualizationSettings->gridYSize) + 2;
608 // obtain references
609 const double xmin = myVisualizationSettings->gridXSize * multXmin;
610 const double ymin = myVisualizationSettings->gridYSize * multYmin;
611 const double xmax = myVisualizationSettings->gridXSize * multXmax;
612 const double ymax = myVisualizationSettings->gridYSize * multYmax;
613 double xp = xmin;
614 double yp = ymin;
615 // move drawing matrix
616 glTranslated(0, 0, .55);
617 glColor3d(0.5, 0.5, 0.5);
618 // draw horizontal lines
619 glBegin(GL_LINES);
620 while (yp <= ymax) {
621 glVertex2d(xmin, yp);
622 glVertex2d(xmax, yp);
624 }
625 // draw vertical lines
626 while (xp <= xmax) {
627 glVertex2d(xp, ymin);
628 glVertex2d(xp, ymax);
630 }
631 glEnd();
632 glTranslated(0, 0, -.55);
633 }
634}
635
636
637void
639 // compute the scale bar length
640 int length = 1;
641 const std::string text("10000000000");
642 int noDigits = 1;
643 int pixelSize = (int) m2p((double) length);
644 while (pixelSize <= 20) {
645 length *= 10;
646 noDigits++;
647 if (noDigits > (int)text.length()) {
648 return;
649 }
650 pixelSize = (int) m2p((double) length);
651 }
652 glLineWidth(1.0);
653
654 glMatrixMode(GL_PROJECTION);
656 glLoadIdentity();
657 glMatrixMode(GL_MODELVIEW);
659 glLoadIdentity();
660
661 // draw the scale bar
662 const double z = -1;
663 glDisable(GL_TEXTURE_2D);
664 glDisable(GL_ALPHA_TEST);
665 glDisable(GL_BLEND);
666 glEnable(GL_DEPTH_TEST);
668 glTranslated(0, 0, z);
669
670 double len = (double) pixelSize / (double)(getWidth() - 1) * (double) 2.0;
671 glColor3d(0, 0, 0);
672 double o = double(15) / double(getHeight());
673 double o2 = o + o;
674 double oo = double(5) / double(getHeight());
675 glBegin(GL_LINES);
676 // vertical
677 glVertex2d(-.98, -1. + o);
678 glVertex2d(-.98 + len, -1. + o);
679 // tick at begin
680 glVertex2d(-.98, -1. + o);
681 glVertex2d(-.98, -1. + o2);
682 // tick at end
683 glVertex2d(-.98 + len, -1. + o);
684 glVertex2d(-.98 + len, -1. + o2);
685 glEnd();
687
688 const double fontHeight = 0.1 * 300. / getHeight();
689 const double fontWidth = 0.1 * 300. / getWidth();
690 // draw 0
691 GLHelper::drawText("0", Position(-.99, -0.99 + o2 + oo), z, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT, fontWidth);
692
693 // draw current scale
694 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);
695
696 // restore matrices
697 glMatrixMode(GL_PROJECTION);
699 glMatrixMode(GL_MODELVIEW);
701}
702
703void
728
729void
730GUISUMOAbstractView::displayColorLegend(const GUIColorScheme& scheme, bool leftSide, const std::string& key) {
731 // compute the scale bar length
732 glLineWidth(1.0);
733 glMatrixMode(GL_PROJECTION);
735 glLoadIdentity();
736 glMatrixMode(GL_MODELVIEW);
738 glLoadIdentity();
739
740 const double z = -1;
741 glEnable(GL_DEPTH_TEST);
742 glEnable(GL_BLEND);
744 glTranslated(0, 0, z);
745
746 const bool fixed = scheme.isFixed();
747 const int numColors = (int)scheme.getColors().size();
748
749 // vertical
750 double right = 0.98;
751 double left = 0.95;
752 double textX = left - 0.01;
753 double textDir = 1;
754 FONSalign textAlign = FONS_ALIGN_RIGHT;
755 const double top = -0.7;
756 const double bot = 0.9;
757 const double dy = (top - bot) / numColors;
758 const double bot2 = fixed ? bot : bot + dy / 2;
759 // legend placement
760 if (leftSide) {
761 right = -right;
762 left = -left;
763 std::swap(right, left);
764 textX = right + 0.01;
765 textDir *= -1;
766 textAlign = FONS_ALIGN_LEFT;
767 }
768 // draw black boundary around legend colors
769 glColor3d(0, 0, 0);
770 glBegin(GL_LINES);
771 glVertex2d(right, top);
772 glVertex2d(right, bot2);
773 glVertex2d(left, bot2);
774 glVertex2d(left, top);
775 glVertex2d(right, top);
776 glVertex2d(left, top);
777 glVertex2d(right, bot2);
778 glVertex2d(left, bot2);
779 glEnd();
780
781 const double fontHeight = 0.20 * 300. / getHeight();
782 const double fontWidth = 0.20 * 300. / getWidth();
783
784 const int fadeSteps = fixed ? 1 : 10;
785 double colorStep = dy / fadeSteps;
786 for (int i = 0; i < numColors; i++) {
787 RGBColor col = scheme.getColors()[i];
788 const double topi = top - i * dy;
789 //const double boti = top - (i + 1) * dy;
790 //std::cout << " col=" << scheme.getColors()[i] << " i=" << i << " topi=" << topi << " boti=" << boti << "\n";
791 if (i + 1 < numColors) {
792 // fade
793 RGBColor col2 = scheme.getColors()[i + 1];
794 double thresh2 = scheme.getThresholds()[i + 1];
795 if (!fixed && thresh2 == GUIVisualizationSettings::MISSING_DATA) {
796 // draw scale end before missing data
798 glBegin(GL_QUADS);
799 glVertex2d(left, topi);
800 glVertex2d(right, topi);
801 glVertex2d(right, topi - 5 * colorStep);
802 glVertex2d(left, topi - 5 * colorStep);
803 glEnd();
804 glColor3d(0, 0, 0);
805 glBegin(GL_LINES);
806 glVertex2d(right, topi - 10 * colorStep);
807 glVertex2d(left, topi - 10 * colorStep);
808 glEnd();
809 glBegin(GL_LINES);
810 glVertex2d(right, topi - 5 * colorStep);
811 glVertex2d(left, topi - 5 * colorStep);
812 glEnd();
813 } else {
814 // fade colors
815 for (double j = 0.0; j < fadeSteps; j++) {
816 GLHelper::setColor(RGBColor::interpolate(col, col2, j / fadeSteps));
817 glBegin(GL_QUADS);
818 glVertex2d(left, topi - j * colorStep);
819 glVertex2d(right, topi - j * colorStep);
820 glVertex2d(right, topi - (j + 1) * colorStep);
821 glVertex2d(left, topi - (j + 1) * colorStep);
822 glEnd();
823 }
824 }
825 } else {
827 glBegin(GL_QUADS);
828 glVertex2d(left, topi);
829 glVertex2d(right, topi);
830 glVertex2d(right, bot2);
831 glVertex2d(left, bot2);
832 glEnd();
833 }
834
835 const double threshold = scheme.getThresholds()[i];
836 std::string name = scheme.getNames()[i];
837 std::string text = fixed || threshold == GUIVisualizationSettings::MISSING_DATA ? name : toString(threshold);
838
839 const double bgShift = 0.0;
840 const double textShift = 0.01;
841 const double textXShift = -0.005;
842
844 glTranslated(0, 0, 0.1);
845 glBegin(GL_QUADS);
846 glVertex2d(textX, topi + fontHeight * bgShift);
847 glVertex2d(textX - textDir * fontWidth * (double)text.size() / 2.1, topi + fontHeight * bgShift);
848 glVertex2d(textX - textDir * fontWidth * (double)text.size() / 2.1, topi + fontHeight * (0.8 + bgShift));
849 glVertex2d(textX, topi + fontHeight * (0.8 + bgShift));
850 glEnd();
851 glTranslated(0, 0, -0.1);
852 GLHelper::drawText(text, Position(textX + textDir * textXShift, topi + textShift), 0, fontHeight, RGBColor::BLACK, 0, textAlign, fontWidth);
853 }
854 // draw scheme name
855 std::string name = scheme.getName();
857 name = "edgeData (" + key + ")";
859 name = "edgeParam (" + key + ")";
861 name = "laneParam (" + key + ")";
863 name = "param (" + key + ")";
865 name = "attribute (" + key + ")";
866 } else if (StringUtils::startsWith(name, "by ")) {
867 name = name.substr(3);
868 }
869 const double topN = -0.8;
870 const double bgShift = 0.0;
872 glTranslated(0, 0, 0.1);
873 glBegin(GL_QUADS);
874 glVertex2d(textX + textDir * 0.04, topN + fontHeight * bgShift - 0.01);
875 glVertex2d(textX + textDir * 0.04 - textDir * fontWidth * (double)name.size() / 2.3, topN + fontHeight * bgShift - 0.01);
876 glVertex2d(textX + textDir * 0.04 - textDir * fontWidth * (double)name.size() / 2.3, topN + fontHeight * (0.8 + bgShift));
877 glVertex2d(textX + textDir * 0.04, topN + fontHeight * (0.8 + bgShift));
878 glEnd();
879 glTranslated(0, 0, -0.1);
880 GLHelper::drawText(name, Position(textX + textDir * 0.04, topN), 0, fontHeight, RGBColor::BLACK, 0, textAlign, fontWidth);
881
883 // restore matrices
884 glMatrixMode(GL_PROJECTION);
886 glMatrixMode(GL_MODELVIEW);
888}
889
890
891double
893 return 1000.0 / MAX2((long)1, myFrameDrawTime);
894}
895
896
901
902
903void
905 glMatrixMode(GL_PROJECTION);
907 glLoadIdentity();
908 glMatrixMode(GL_MODELVIEW);
910 glLoadIdentity();
911 const double fontHeight = 0.2 * 300. / getHeight();
912 const double fontWidth = 0.2 * 300. / getWidth();
913 GLHelper::drawText(toString((int)getFPS()) + " FPS", Position(0.82, 0.88), -1, fontHeight, RGBColor::RED, 0, FONS_ALIGN_LEFT, fontWidth);
914#ifdef CHECK_ELEMENTCOUNTER
915 GLHelper::drawText(toString(GLHelper::getMatrixCounter()) + " matrix", Position(0.82, 0.79), -1, fontHeight, RGBColor::RED, 0, FONS_ALIGN_LEFT, fontWidth);
916 GLHelper::drawText(toString(GLHelper::getVertexCounter()) + " vertex", Position(0.82, 0.71), -1, fontHeight, RGBColor::RED, 0, FONS_ALIGN_LEFT, fontWidth);
917#endif
918 // restore matrices
919 glMatrixMode(GL_PROJECTION);
921 glMatrixMode(GL_MODELVIEW);
923}
924
925
926double
927GUISUMOAbstractView::m2p(double meter) const {
928 return meter * getWidth() / myChanger->getViewport().getWidth();
929}
930
931
932double
933GUISUMOAbstractView::p2m(double pixel) const {
934 return pixel * myChanger->getViewport().getWidth() / getWidth();
935}
936
937
938void
942
943
944void
945GUISUMOAbstractView::centerTo(GUIGlID id, bool applyZoom, double zoomDist) {
947 if (o != nullptr && dynamic_cast<GUIGlObject*>(o) != nullptr) {
948 const Boundary& b = o->getCenteringBoundary();
949 if (b.getCenter() != Position::INVALID) {
950 if (applyZoom && zoomDist < 0) {
952 update(); // only update when centering onto an object once
953 } else {
954 // called during tracking. update is triggered somewhere else
955 myChanger->centerTo(b.getCenter(), zoomDist, applyZoom);
957 }
958 }
959 }
961}
962
963
964void
965GUISUMOAbstractView::centerTo(const Position& pos, bool applyZoom, double zoomDist) {
966 // called during tracking. update is triggered somewhere else
967 myChanger->centerTo(pos, zoomDist, applyZoom);
969}
970
971
972void
974 myChanger->setViewport(bound);
975 update();
976}
977
978
981 return myApp;
982}
983
984
989
990
991void
996
997
998FXbool
1000 FXbool ret = FXGLCanvas::makeCurrent();
1001 return ret;
1002}
1003
1004
1005long
1006GUISUMOAbstractView::onConfigure(FXObject*, FXSelector, void*) {
1007 if (makeCurrent()) {
1008 glViewport(0, 0, getWidth() - 1, getHeight() - 1);
1009 glClearColor(
1014 doInit();
1015 myAmInitialised = true;
1016 makeNonCurrent();
1018 }
1019 return 1;
1020}
1021
1022
1023long
1024GUISUMOAbstractView::onPaint(FXObject*, FXSelector, void*) {
1025 if (!isEnabled() || !myAmInitialised) {
1026 return 1;
1027 }
1028 if (makeCurrent()) {
1029 paintGL();
1030 makeNonCurrent();
1031 }
1032 // run tests
1033 myApp->handle(this, FXSEL(SEL_COMMAND, MID_RUNTESTS), nullptr);
1034 return 1;
1035}
1036
1037
1040 return myPopup;
1041}
1042
1043
1044const Position&
1048
1049
1050void
1052 if (myPopup != nullptr) {
1054 delete myPopup;
1055 myPopupPosition.set(0, 0);
1056 myPopup = nullptr;
1057 myCurrentObjectsDialog.clear();
1058 }
1059}
1060
1061
1062void
1064 // use the same position of old popUp
1065 popUp->move(myPopup->getX(), myPopup->getY());
1066 // delete and replace popup
1068 delete myPopup;
1069 myPopup = popUp;
1070 // create and show popUp
1071 myPopup->create();
1072 myPopup->show();
1073 myChanger->onRightBtnRelease(nullptr);
1074 setFocus();
1075}
1076
1077
1078long
1079GUISUMOAbstractView::onLeftBtnPress(FXObject*, FXSelector, void* ptr) {
1080 destroyPopup();
1081 setFocus();
1082 FXEvent* e = (FXEvent*) ptr;
1083 // check whether the selection-mode is activated
1084 if ((e->state & CONTROLMASK) != 0) {
1085 // toggle selection of object under cursor
1086 if (makeCurrent()) {
1087 int id = getObjectUnderCursor();
1088 if (id != 0) {
1090 }
1091 makeNonCurrent();
1092 if (id != 0) {
1093 // possibly, the selection-coloring is used,
1094 // so we should update the screen again...
1095 update();
1096 }
1097 }
1098 }
1099 if ((e->state & SHIFTMASK) != 0) {
1100 // track vehicle or person under cursor
1101 if (makeCurrent()) {
1102 int id = getObjectUnderCursor();
1103 if (id != 0) {
1105 if (o != nullptr) {
1106 if (!myApp->isGaming() && (o->getType() == GLO_VEHICLE || o->getType() == GLO_PERSON)) {
1107 startTrack(id);
1108 }
1109 }
1110 }
1111 makeNonCurrent();
1112 }
1113 }
1115 grab();
1116 // Check there are double click
1117 if (e->click_count == 2) {
1118 handle(this, FXSEL(SEL_DOUBLECLICKED, 0), ptr);
1119 }
1120 return 1;
1121}
1122
1123
1124long
1125GUISUMOAbstractView::onLeftBtnRelease(FXObject*, FXSelector, void* ptr) {
1126 destroyPopup();
1128 if (myApp->isGaming()) {
1130 }
1131 ungrab();
1132 return 1;
1133}
1134
1135
1136long
1137GUISUMOAbstractView::onMiddleBtnPress(FXObject*, FXSelector, void* ptr) {
1138 destroyPopup();
1139 setFocus();
1140 if (!myApp->isGaming()) {
1142 }
1143 grab();
1144 // enable panning
1145 myPanning = true;
1146 // set cursors
1149 return 1;
1150}
1151
1152
1153long
1154GUISUMOAbstractView::onMiddleBtnRelease(FXObject*, FXSelector, void* ptr) {
1155 destroyPopup();
1156 if (!myApp->isGaming()) {
1158 }
1159 ungrab();
1160 // disable panning
1161 myPanning = false;
1162 // restore cursors
1165 return 1;
1166}
1167
1168
1169long
1170GUISUMOAbstractView::onRightBtnPress(FXObject*, FXSelector, void* ptr) {
1171 destroyPopup();
1172 if (!myApp->isGaming()) {
1174 }
1175 grab();
1176 return 1;
1177}
1178
1179
1180long
1181GUISUMOAbstractView::onRightBtnRelease(FXObject* o, FXSelector sel, void* ptr) {
1182 destroyPopup();
1183 onMouseMove(o, sel, ptr);
1184 if (!myChanger->onRightBtnRelease(ptr) && !myApp->isGaming()) {
1185 openObjectDialogAtCursor((FXEvent*)ptr);
1186 }
1187 if (myApp->isGaming()) {
1189 }
1190 ungrab();
1191 return 1;
1192}
1193
1194
1195long
1196GUISUMOAbstractView::onDoubleClicked(FXObject*, FXSelector, void*) {
1197 return 1;
1198}
1199
1200
1201long
1202GUISUMOAbstractView::onMouseWheel(FXObject*, FXSelector, void* ptr) {
1203 if (!myApp->isGaming()) {
1204 myChanger->onMouseWheel(ptr);
1205 // upddate viewport
1206 if (myGUIDialogEditViewport != nullptr) {
1210 }
1212 }
1213 return 1;
1214}
1215
1216
1217long
1218GUISUMOAbstractView::onMouseMove(FXObject*, FXSelector, void* ptr) {
1219 // check if popup exist
1220 if (myPopup) {
1221 // check if handle front element
1224 myPopup->handle(this, FXSEL(SEL_COMMAND, MID_CURSORDIALOG_FRONT), nullptr);
1225 destroyPopup();
1226 } else if (!myPopup->shown()) {
1227 destroyPopup();
1228 }
1229 }
1230 if (myPopup == nullptr) {
1232 myChanger->onMouseMove(ptr);
1233 }
1234 if (myGUIDialogEditViewport != nullptr) {
1238 }
1240 }
1241 return 1;
1242}
1243
1244
1245long
1246GUISUMOAbstractView::onMouseLeft(FXObject*, FXSelector, void* /*data*/) {
1247 return 1;
1248}
1249
1250std::vector<GUIGlObject*>
1251GUISUMOAbstractView::filterContextObjects(const std::vector<GUIGlObject*>& objects) {
1252 // assume input is sorted with ComparatorClickPriority
1253 std::vector<GUIGlObject*> result;
1254 for (GUIGlObject* o : objects) {
1255 if (o->getClickPriority() != GUIGlObject::INVALID_PRIORITY && (result.empty() || result.back() != o)) {
1256 result.push_back(o);
1257 }
1258 }
1259 return result;
1260}
1261
1262
1263void
1265 // release the mouse grab
1266 ungrab();
1267 // check if alt key is pressed
1268 const bool altKeyPressed = ((ev->state & ALTMASK) != 0);
1269 // check if SUMO is enabled, initialised and Make OpenGL context current
1270 if (isEnabled() && myAmInitialised && makeCurrent()) {
1271 auto objectsUnderCursor = getGUIGlObjectsUnderCursor();
1272 if (objectsUnderCursor.empty()) {
1274 } else {
1275 std::sort(objectsUnderCursor.begin(), objectsUnderCursor.end(), ComparatorClickPriority());
1276 std::vector<GUIGlObject*> filtered = filterContextObjects(objectsUnderCursor);
1277 if (filtered.size() > 1 && (altKeyPressed
1278 || filtered[0]->getClickPriority() == filtered[1]->getClickPriority())) {
1279 // open dialog for picking among objects (without duplicates)
1281 } else {
1282 myPopup = objectsUnderCursor.front()->getPopUpMenu(*myApp, *this);
1283 }
1284 }
1286 makeNonCurrent();
1287 }
1288}
1289
1290
1291void
1292GUISUMOAbstractView::openObjectDialog(const std::vector<GUIGlObject*>& objects, const bool filter) {
1293 if (objects.size() > 0) {
1294 // create cursor popup dialog
1295 if (objects.size() == 1) {
1296 myCurrentObjectsDialog = objects;
1297 } else if (filter) {
1298 // declare filtered objects
1299 std::vector<GUIGlObject*> filteredGLObjects;
1300 // fill filtered objects
1301 for (const auto& glObject : objects) {
1302 // compare type with first element type
1303 if (glObject->getType() == objects.front()->getType()) {
1304 filteredGLObjects.push_back(glObject);
1305 }
1306 }
1307 myCurrentObjectsDialog = filteredGLObjects;
1308 } else {
1309 myCurrentObjectsDialog = objects;
1310 }
1311 if (myCurrentObjectsDialog.size() > 1) {
1313 } else {
1314 myPopup = myCurrentObjectsDialog.front()->getPopUpMenu(*myApp, *this);
1315 }
1316 // open popup dialog
1318 }
1319}
1320
1321
1322long
1323GUISUMOAbstractView::onKeyPress(FXObject* o, FXSelector sel, void* ptr) {
1324 const FXEvent* e = (FXEvent*) ptr;
1325 // check if process canvas or popup
1326 if (myPopup != nullptr) {
1327 return myPopup->onKeyPress(o, sel, ptr);
1328 } else {
1329 if (e->state & CONTROLMASK) {
1330 if (e->code == FX::KEY_Page_Up) {
1333 update();
1334 return 1;
1335 } else if (e->code == FX::KEY_Page_Down) {
1338 update();
1339 return 1;
1340 }
1341 }
1342 FXGLCanvas::onKeyPress(o, sel, ptr);
1343 return myChanger->onKeyPress(ptr);
1344 }
1345}
1346
1347
1348long
1349GUISUMOAbstractView::onKeyRelease(FXObject* o, FXSelector sel, void* ptr) {
1350 // check if process canvas or popup
1351 if (myPopup != nullptr) {
1352 return myPopup->onKeyRelease(o, sel, ptr);
1353 } else {
1354 FXGLCanvas::onKeyRelease(o, sel, ptr);
1355 return myChanger->onKeyRelease(ptr);
1356 }
1357}
1358
1359// ------------ Dealing with snapshots
1360
1361void
1362GUISUMOAbstractView::addSnapshot(SUMOTime time, const std::string& file, const int w, const int h) {
1363#ifdef DEBUG_SNAPSHOT
1364 std::cout << "add snapshot time=" << time << " file=" << file << "\n";
1365#endif
1366 FXMutexLock lock(mySnapshotsMutex);
1367 mySnapshots[time].push_back(std::make_tuple(file, w, h));
1368}
1369
1370
1371std::string
1372GUISUMOAbstractView::makeSnapshot(const std::string& destFile, const int w, const int h) {
1373 if (w >= 0) {
1374 resize(w, h);
1375 repaint();
1376 }
1377 std::string errorMessage;
1378 FXString ext = FXPath::extension(destFile.c_str());
1379 const bool useGL2PS = ext == "ps" || ext == "eps" || ext == "pdf" || ext == "svg" || ext == "tex" || ext == "pgf";
1380#ifdef HAVE_FFMPEG
1381 const bool useVideo = destFile == "" || ext == "h264" || ext == "hevc" || ext == "mp4";
1382#endif
1383 for (int i = 0; i < 10 && !makeCurrent(); ++i) {
1385 }
1386 // draw
1387 glClearColor(
1392 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
1393 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1394
1396 glEnable(GL_DITHER);
1397 } else {
1398 glDisable(GL_DITHER);
1399 }
1400 glEnable(GL_BLEND);
1401 glDisable(GL_LINE_SMOOTH);
1402
1404
1405 if (useGL2PS) {
1406#ifdef HAVE_GL2PS
1407 GLint format = GL2PS_PS;
1408 if (ext == "ps") {
1409 format = GL2PS_PS;
1410 } else if (ext == "eps") {
1411 format = GL2PS_EPS;
1412 } else if (ext == "pdf") {
1413 format = GL2PS_PDF;
1414 } else if (ext == "tex") {
1415 format = GL2PS_TEX;
1416 } else if (ext == "svg") {
1417 format = GL2PS_SVG;
1418 } else if (ext == "pgf") {
1419 format = GL2PS_PGF;
1420 } else {
1421 return "Could not save '" + destFile + "'.\n Unrecognized format '" + std::string(ext.text()) + "'.";
1422 }
1423 FILE* fp = fopen(destFile.c_str(), "wb");
1424 if (fp == 0) {
1425 return "Could not save '" + destFile + "'.\n Could not open file for writing";
1426 }
1428 GLint buffsize = 0, state = GL2PS_OVERFLOW;
1429 GLint viewport[4];
1430 glGetIntegerv(GL_VIEWPORT, viewport);
1431 while (state == GL2PS_OVERFLOW) {
1432 buffsize += 1024 * 1024;
1433 gl2psBeginPage(destFile.c_str(), "sumo-gui; https://sumo.dlr.de", viewport, format, GL2PS_SIMPLE_SORT,
1434 GL2PS_DRAW_BACKGROUND | GL2PS_USE_CURRENT_VIEWPORT,
1435 GL_RGBA, 0, NULL, 0, 0, 0, buffsize, fp, "out.eps");
1436 glMatrixMode(GL_MODELVIEW);
1438 glDisable(GL_TEXTURE_2D);
1439 glDisable(GL_ALPHA_TEST);
1440 glDisable(GL_BLEND);
1441 glEnable(GL_DEPTH_TEST);
1442 // draw decals (if not in grabbing mode)
1443
1444 drawDecals();
1446 paintGLGrid();
1447 }
1448
1449 glLineWidth(1);
1450 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1451 Boundary viewPort = myChanger->getViewport();
1452 const float minB[2] = { (float)viewPort.xmin(), (float)viewPort.ymin() };
1453 const float maxB[2] = { (float)viewPort.xmax(), (float)viewPort.ymax() };
1455 glEnable(GL_POLYGON_OFFSET_FILL);
1456 glEnable(GL_POLYGON_OFFSET_LINE);
1457 myGrid->Search(minB, maxB, *myVisualizationSettings);
1458
1460 state = gl2psEndPage();
1461 glFinish();
1462 }
1463 GLHelper::setGL2PS(false);
1464 fclose(fp);
1465#else
1466 return "Could not save '" + destFile + "', gl2ps was not enabled at compile time.";
1467#endif
1468 } else {
1469 doPaintGL(GL_RENDER, myChanger->getViewport());
1471 swapBuffers();
1472 glFinish();
1473 FXColor* buf;
1474 FXMALLOC(&buf, FXColor, getWidth()*getHeight());
1475 // read from the back buffer
1476 glReadBuffer(GL_BACK);
1477 // Read the pixels
1478 glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)buf);
1479 makeNonCurrent();
1480 update();
1481 // mirror
1482 int mwidth = getWidth();
1483 int mheight = getHeight();
1484 FXColor* paa = buf;
1485 FXColor* pbb = buf + mwidth * (mheight - 1);
1486 do {
1487 FXColor* pa = paa;
1488 paa += mwidth;
1489 FXColor* pb = pbb;
1490 pbb -= mwidth;
1491 do {
1492 FXColor t = *pa;
1493 *pa++ = *pb;
1494 *pb++ = t;
1495 } while (pa < paa);
1496 } while (paa < pbb);
1497 try {
1498#ifdef HAVE_FFMPEG
1499 if (useVideo) {
1500 try {
1501 saveFrame(destFile, buf);
1502 errorMessage = "video";
1503 } catch (std::runtime_error& err) {
1504 errorMessage = err.what();
1505 }
1506 } else
1507#endif
1508 if (!MFXImageHelper::saveImage(destFile, getWidth(), getHeight(), buf)) {
1509 errorMessage = "Could not save '" + destFile + "'.";
1510 }
1511 } catch (InvalidArgument& e) {
1512 errorMessage = "Could not save '" + destFile + "'.\n" + e.what();
1513 }
1514 FXFREE(&buf);
1515 }
1516 return errorMessage;
1517}
1518
1519
1520void
1521GUISUMOAbstractView::saveFrame(const std::string& destFile, FXColor* buf) {
1522 UNUSED_PARAMETER(destFile);
1523 UNUSED_PARAMETER(buf);
1524}
1525
1526
1527void
1529 const SUMOTime time = getCurrentTimeStep() - DELTA_T;
1530#ifdef DEBUG_SNAPSHOT
1531 std::cout << "check snapshots time=" << time << " registeredTimes=" << mySnapshots.size() << "\n";
1532#endif
1533 FXMutexLock lock(mySnapshotsMutex);
1534 const auto snapIt = mySnapshots.find(time);
1535 if (snapIt == mySnapshots.end()) {
1536 return;
1537 }
1538 std::vector<std::tuple<std::string, int, int> > files = snapIt->second;
1539 lock.unlock();
1540 // decouple map access and painting to avoid deadlock
1541 for (const auto& entry : files) {
1542#ifdef DEBUG_SNAPSHOT
1543 std::cout << "make snapshot time=" << time << " file=" << file << "\n";
1544#endif
1545 const std::string& error = makeSnapshot(std::get<0>(entry), std::get<1>(entry), std::get<2>(entry));
1546 if (error != "" && error != "video") {
1547 WRITE_WARNING(error);
1548 }
1549 }
1550 // synchronization with a waiting run thread
1551 lock.lock();
1552 mySnapshots.erase(time);
1553 mySnapshotCondition.signal();
1554#ifdef DEBUG_SNAPSHOT
1555 std::cout << " files=" << toString(files) << " myApplicationSnapshots=" << joinToString(*myApplicationSnapshots, ",") << "\n";
1556#endif
1557}
1558
1559
1560void
1562 FXMutexLock lock(mySnapshotsMutex);
1563 if (mySnapshots.count(snapshotTime) > 0) {
1565 }
1566}
1567
1568
1571 return 0;
1572}
1573
1574
1575void
1586
1587
1590 if (myGUIDialogEditViewport == nullptr) {
1591 myGUIDialogEditViewport = new GUIDialog_EditViewport(this, TLC("Labels", "Edit Viewport"));
1592 myGUIDialogEditViewport->create();
1593 }
1596}
1597
1598
1604
1605
1606void
1613
1614
1615void
1616GUISUMOAbstractView::setViewportFromToRot(const Position& lookFrom, const Position& /* lookAt */, double rotation) {
1617 myChanger->setViewportFrom(lookFrom.x(), lookFrom.y(), lookFrom.z());
1618 myChanger->setRotation(rotation);
1619 update();
1620}
1621
1622
1623void
1630
1631
1632bool
1634 return true;
1635}
1636
1637
1642
1643
1648
1649
1650void
1654
1655
1656void
1660
1661
1662double
1664 return myGrid->getWidth();
1665}
1666
1667
1668double
1672
1673
1674void
1677
1678
1679void
1682
1683
1684GUIGlID
1688
1689
1690void
1693
1694void
1697
1698
1699std::vector<GUISUMOAbstractView::Decal>&
1703
1704
1705FXMutex&
1709
1710
1715
1716
1717FXImage*
1719#ifdef HAVE_GDAL
1720 GDALAllRegister();
1721 GDALDataset* poDataset = (GDALDataset*)GDALOpen(d.filename.c_str(), GA_ReadOnly);
1722 if (poDataset == 0) {
1723 return 0;
1724 }
1725 const int xSize = poDataset->GetRasterXSize();
1726 const int ySize = poDataset->GetRasterYSize();
1727 // checking for geodata in the picture and try to adapt position and scale
1728 if (d.width <= 0.) {
1729 double adfGeoTransform[6];
1730 if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) {
1731 Position topLeft(adfGeoTransform[0], adfGeoTransform[3]);
1732 const double horizontalSize = xSize * adfGeoTransform[1];
1733 const double verticalSize = ySize * adfGeoTransform[5];
1734 Position bottomRight(topLeft.x() + horizontalSize, topLeft.y() + verticalSize);
1735 if (GeoConvHelper::getFinal().x2cartesian_const(topLeft) && GeoConvHelper::getFinal().x2cartesian_const(bottomRight)) {
1736 //WRITE_MESSAGE("proj: " + toString(poDataset->GetProjectionRef()) + " dim: " + toString(d.width) + "," + toString(d.height) + " center: " + toString(d.centerX) + "," + toString(d.centerY));
1737 } else {
1738 WRITE_WARNINGF(TL("Could not transform coordinates from WGS84 in decal %, assuming UTM."), d.filename);
1739 topLeft = topLeft + GeoConvHelper::getFinal().getOffset();
1740 bottomRight = bottomRight + GeoConvHelper::getFinal().getOffset();
1741 }
1742 d.width = bottomRight.x() - topLeft.x();
1743 d.height = topLeft.y() - bottomRight.y();
1744 d.centerX = (topLeft.x() + bottomRight.x()) / 2;
1745 d.centerY = (topLeft.y() + bottomRight.y()) / 2;
1746 }
1747 }
1748#endif
1749 if (d.width <= 0.) {
1750 d.width = getGridWidth();
1751 d.height = getGridHeight();
1752 }
1753
1754 // trying to read the picture
1755#ifdef HAVE_GDAL
1756 const int picSize = xSize * ySize;
1757 FXColor* result;
1758 if (!FXMALLOC(&result, FXColor, picSize)) {
1759 WRITE_WARNINGF("Could not allocate memory for %.", d.filename);
1760 return 0;
1761 }
1762 for (int j = 0; j < picSize; j++) {
1763 result[j] = FXRGB(0, 0, 0);
1764 }
1765 bool valid = true;
1766 for (int i = 1; i <= poDataset->GetRasterCount(); i++) {
1767 GDALRasterBand* poBand = poDataset->GetRasterBand(i);
1768 int shift = -1;
1769 if (poBand->GetColorInterpretation() == GCI_RedBand) {
1770 shift = 0;
1771 } else if (poBand->GetColorInterpretation() == GCI_GreenBand) {
1772 shift = 1;
1773 } else if (poBand->GetColorInterpretation() == GCI_BlueBand) {
1774 shift = 2;
1775 } else if (poBand->GetColorInterpretation() == GCI_AlphaBand) {
1776 shift = 3;
1777 } else {
1778 valid = false;
1779 break;
1780 }
1781 assert(xSize == poBand->GetXSize() && ySize == poBand->GetYSize());
1782 if (poBand->RasterIO(GF_Read, 0, 0, xSize, ySize, ((unsigned char*)result) + shift, xSize, ySize, GDT_Byte, 4, 4 * xSize) == CE_Failure) {
1783 valid = false;
1784 break;
1785 }
1786 }
1787 GDALClose(poDataset);
1788 if (valid) {
1789 return new FXImage(getApp(), result, IMAGE_OWNED | IMAGE_KEEP | IMAGE_SHMI | IMAGE_SHMP, xSize, ySize);
1790 }
1791 FXFREE(&result);
1792#endif
1793 return nullptr;
1794}
1795
1796
1797void
1800 myDecalsLockMutex.lock();
1801 for (auto& decal : myDecals) {
1802 if (decal.skip2D || decal.filename.empty()) {
1803 continue;
1804 }
1805 if (!decal.initialised) {
1806 try {
1807 FXImage* img = checkGDALImage(decal);
1808 if (img == nullptr) {
1809 img = MFXImageHelper::loadImage(getApp(), decal.filename);
1810 }
1812 decal.glID = GUITexturesHelper::add(img);
1813 decal.initialised = true;
1814 decal.image = img;
1815 } catch (InvalidArgument& e) {
1816 WRITE_ERROR("Could not load '" + decal.filename + "'.\n" + e.what());
1817 decal.skip2D = true;
1818 }
1819 }
1821 if (decal.screenRelative) {
1822 Position center = screenPos2NetPos((int)decal.centerX, (int)decal.centerY);
1823 glTranslated(center.x(), center.y(), decal.layer);
1824 } else {
1825 glTranslated(decal.centerX, decal.centerY, decal.layer);
1826 }
1827 glRotated(decal.rot, 0, 0, 1);
1828 glColor3d(1, 1, 1);
1829 double halfWidth = decal.width / 2.;
1830 double halfHeight = decal.height / 2.;
1831 if (decal.screenRelative) {
1832 halfWidth = p2m(halfWidth);
1833 halfHeight = p2m(halfHeight);
1834 }
1835 GUITexturesHelper::drawTexturedBox(decal.glID, -halfWidth, -halfHeight, halfWidth, halfHeight);
1837 }
1838 myDecalsLockMutex.unlock();
1840}
1841
1842
1843void
1845 int x, y;
1846 FXuint b;
1847 myApp->getCursorPosition(x, y, b);
1848 int appX = myApp->getX();
1849 int popX = x + appX;
1850 int popY = y + myApp->getY();
1851 myPopup->setX(popX);
1852 myPopup->setY(popY);
1853 myPopup->create();
1854 myPopup->show();
1855 // TODO: try to stay on screen even on a right secondary screen in multi-monitor setup
1856 const int rootWidth = getApp()->getRootWindow()->getWidth();
1857 const int rootHeight = getApp()->getRootWindow()->getHeight();
1858 if (popX <= rootWidth) {
1859 const int maxX = (appX < 0) ? 0 : rootWidth;
1860 popX = MIN2(popX, maxX - myPopup->getWidth() - 10);
1861 }
1862 popY = MIN2(popY, rootHeight - myPopup->getHeight() - 50);
1863 myPopup->move(popX, popY);
1865 myChanger->onRightBtnRelease(nullptr);
1866 setFocus();
1867}
1868
1869// ------------ Additional visualisations
1870
1871bool
1873 if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1874 myAdditionallyDrawn[which] = 1;
1875 } else {
1876 myAdditionallyDrawn[which] = myAdditionallyDrawn[which] + 1;
1877 }
1878 update();
1879 return true;
1880}
1881
1882
1883bool
1885 if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1886 return false;
1887 }
1888 int cnt = myAdditionallyDrawn[which];
1889 if (cnt == 1) {
1890 myAdditionallyDrawn.erase(which);
1891 } else {
1892 myAdditionallyDrawn[which] = myAdditionallyDrawn[which] - 1;
1893 }
1894 update();
1895 return true;
1896}
1897
1898
1899bool
1901 if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1902 return false;
1903 } else {
1904 return true;
1905 }
1906}
1907
1908
1911 Boundary bound = myChanger->getViewport(fixRatio);
1912 glMatrixMode(GL_PROJECTION);
1913 glLoadIdentity();
1914 // as a rough rule, each GLObject is drawn at z = -GUIGlObjectType
1915 // thus, objects with a higher value will be closer (drawn on top)
1916 // // @todo last param should be 0 after modifying all glDraw methods
1917 glOrtho(0, getWidth(), 0, getHeight(), -GLO_MAX - 1, GLO_MAX + 1);
1918 glMatrixMode(GL_MODELVIEW);
1919 glLoadIdentity();
1920 double scaleX = (double)getWidth() / bound.getWidth();
1921 double scaleY = (double)getHeight() / bound.getHeight();
1922 glScaled(scaleX, scaleY, 1);
1923 glTranslated(-bound.xmin(), -bound.ymin(), 0);
1924 // rotate around the center of the screen
1925 //double angle = -90;
1926 if (myChanger->getRotation() != 0) {
1927 glTranslated(bound.getCenter().x(), bound.getCenter().y(), 0);
1928 glRotated(myChanger->getRotation(), 0, 0, 1);
1929 glTranslated(-bound.getCenter().x(), -bound.getCenter().y(), 0);
1930 Boundary rotBound;
1931 double rad = -DEG2RAD(myChanger->getRotation());
1932 rotBound.add(Position(bound.xmin(), bound.ymin()).rotateAround2D(rad, bound.getCenter()));
1933 rotBound.add(Position(bound.xmin(), bound.ymax()).rotateAround2D(rad, bound.getCenter()));
1934 rotBound.add(Position(bound.xmax(), bound.ymin()).rotateAround2D(rad, bound.getCenter()));
1935 rotBound.add(Position(bound.xmax(), bound.ymax()).rotateAround2D(rad, bound.getCenter()));
1936 bound = rotBound;
1937 }
1939 return bound;
1940}
1941
1942
1943double
1945 return myApp->getDelay();
1946}
1947
1948
1949void
1951 myApp->setDelay(delay);
1952}
1953
1954
1955void
1956GUISUMOAbstractView::setBreakpoints(const std::vector<SUMOTime>& breakpoints) {
1957 myApp->setBreakpoints(breakpoints);
1958}
1959
1960
1961void
1963 const GUIVisualizationRainbowSettings& rs, double minValue, double maxValue, bool hasMissingData) {
1964 if (rs.hideMin && rs.hideMax && minValue == std::numeric_limits<double>::infinity()) {
1965 minValue = rs.minThreshold;
1966 maxValue = rs.maxThreshold;
1967 }
1968 if (rs.fixRange) {
1969 if (rs.hideMin) {
1970 minValue = rs.minThreshold;
1971 }
1972 if (rs.hideMax) {
1973 maxValue = rs.maxThreshold;
1974 }
1975 }
1976 if (minValue != std::numeric_limits<double>::infinity()) {
1977 scheme.clear();
1978 // add new thresholds
1984 || hasMissingData) {
1985 scheme.addColor(s.COL_MISSING_DATA, s.MISSING_DATA, "missing data");
1986 }
1987 if (rs.hideMin && !rs.fixRange) {
1988 const double rawRange = maxValue - minValue;
1989 minValue = MAX2(rs.minThreshold + MIN2(1.0, rawRange / 100.0), minValue);
1990 scheme.addColor(RGBColor(204, 204, 204), rs.minThreshold);
1991 }
1992 if (rs.hideMax && !rs.fixRange) {
1993 const double rawRange = maxValue - minValue;
1994 maxValue = MIN2(rs.maxThreshold - MIN2(1.0, rawRange / 100.0), maxValue);
1995 scheme.addColor(RGBColor(204, 204, 204), rs.maxThreshold);
1996 }
1997 const double range = maxValue - minValue;
1998 scheme.addColor(rs.colors.front(), minValue);
1999 const int steps = (int)rs.colors.size() - 1;
2000 if (rs.setNeutral) {
2001 const int steps1 = steps / 2;
2002 const int steps2 = steps - steps1;
2003 const double range1 = rs.neutralThreshold - minValue;
2004 const double range2 = maxValue - rs.neutralThreshold;
2005 for (int i = 1; i < steps1; i++) {
2006 scheme.addColor(rs.colors[i], (minValue + range1 * i / steps1));
2007 }
2008 scheme.addColor(rs.colors[steps1], rs.neutralThreshold);
2009 for (int i = 1; i < steps2; i++) {
2010 scheme.addColor(rs.colors[steps1 + i], (rs.neutralThreshold + range2 * i / steps2));
2011 }
2012 } else {
2013 for (int i = 1; i < steps; i++) {
2014 scheme.addColor(rs.colors[i], (minValue + range * i / steps));
2015 }
2016 }
2017 scheme.addColor(rs.colors.back(), maxValue);
2018 }
2019}
2020
2021
2023 myGLObject(object) {
2024 first = layer;
2025 second.first = object->getType();
2026 second.second = object->getMicrosimID();
2027}
2028
2029
2031 myGLObject(object) {
2032 first = object->getType();
2033 second.first = object->getType();
2034 second.second = object->getMicrosimID();
2035}
2036
2037
2040 return myGLObject;
2041}
2042
2043/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ MID_GLCANVAS
GLCanvas - ID.
Definition GUIAppEnum.h:411
@ MID_REACHABILITY
show reachability from a given lane
Definition GUIAppEnum.h:531
@ MID_CLOSE_LANE
close lane
Definition GUIAppEnum.h:667
@ MID_CURSORDIALOG_FRONT
remove/select/mark front element
Definition GUIAppEnum.h:442
@ MID_CLOSE_EDGE
close edge
Definition GUIAppEnum.h:669
@ MID_RUNTESTS
run tests
@ MID_SIMPLE_VIEW_COLORCHANGE
Informs the dialog about a value's change.
Definition GUIAppEnum.h:627
@ MID_ADD_REROUTER
add rerouter
Definition GUIAppEnum.h:671
GUICompleteSchemeStorage gSchemeStorage
@ MOVEVIEW
move view cursor
@ DEFAULT
default cursor
unsigned int GUIGlID
Definition GUIGlObject.h:44
GUIGlObjectType
@ GLO_MAX
empty max
@ GLO_LANE
a lane
@ GLO_VEHICLE
a vehicle
@ GLO_PERSON
a person
@ GLO_NETWORK
The network - empty.
GUISelectedStorage gSelected
A global holder of selected objects.
FXDEFMAP(GUISUMOAbstractView) GUISUMOAbstractViewMap[]
#define DEG2RAD(x)
Definition GeomHelper.h:35
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:288
#define WRITE_ERROR(msg)
Definition MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:305
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
int gPrecisionGeo
Definition StdDefs.cpp:28
const double SUMO_const_laneWidth
Definition StdDefs.h:48
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
#define TLC(context, string)
Definition Translation.h:47
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
Position getCenter() const
Returns the center of the boundary.
Definition Boundary.cpp:109
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition Boundary.cpp:75
double ymin() const
Returns minimum y-coordinate.
Definition Boundary.cpp:127
double xmin() const
Returns minimum x-coordinate.
Definition Boundary.cpp:115
Boundary & grow(double by)
extends the boundary by the given amount
Definition Boundary.cpp:340
double getHeight() const
Returns the height of the boundary (y-axis)
Definition Boundary.cpp:157
double getWidth() const
Returns the width of the boudary (x-axis)
Definition Boundary.cpp:151
double ymax() const
Returns maximum y-coordinate.
Definition Boundary.cpp:133
double xmax() const
Returns maximum x-coordinate.
Definition Boundary.cpp:121
static void resetVertexCounter()
reset vertex counter
Definition GLHelper.cpp:180
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:653
static void pushName(unsigned int name)
push Name
Definition GLHelper.cpp:144
static void checkCounterMatrix()
check counter matrix (for debug purposes)
Definition GLHelper.cpp:186
static void popMatrix()
pop matrix
Definition GLHelper.cpp:135
static int getMatrixCounter()
get matrix counter
Definition GLHelper.cpp:162
static void checkCounterName()
check counter name (for debug purposes)
Definition GLHelper.cpp:197
static void popName()
pop Name
Definition GLHelper.cpp:153
static void pushMatrix()
push matrix
Definition GLHelper.cpp:122
static void setGL2PS(bool active=true)
set GL2PS
Definition GLHelper.cpp:677
static int getVertexCounter()
get vertex counter
Definition GLHelper.cpp:174
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:747
static void resetMatrixCounter()
reset matrix counter
Definition GLHelper.cpp:168
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.
MFXComboBoxIcon * getColoringSchemesCombo()
return combobox with the current coloring schemes (standard, fastest standard, real world....
GUIMainWindow * getGUIMainWindowParent()
Returns the GUIMainWindow parent.
static const double INVALID_PRIORITY
Definition GUIGlObject.h:74
static const GUIGlID INVALID_ID
Definition GUIGlObject.h:73
virtual double getClickPriority() const
Returns the priority of receiving mouse clicks.
virtual Boundary getCenteringBoundary() const =0
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
virtual Position getCenter() const
GUIGlID getGlID() const
Returns the numerical id of the object.
virtual GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)=0
Returns an own popup-menu.
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
int addColor(const T &color, const double threshold, const std::string &name="")
MFXComboBoxIcon * getColoringSchemesCombo()
get coloring schemes combo
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
void paintGLGrid() const
paints a grid
FXbool makeCurrent()
A reimplementation due to some internal reasons.
int myMouseHotspotX
Offset to the mouse-hotspot from the mouse position.
GUIMainWindow * getMainWindow() const
get main window
bool isInEditMode()
returns true, if the edit button was pressed
void buildMinMaxRainbow(const GUIVisualizationSettings &s, GUIColorScheme &scheme, const GUIVisualizationRainbowSettings &rs, double minValue, double maxValue, bool hasMissingData)
helper function for buildColorRainbow
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
virtual GUIGlID getToolTipID()
returns the id of object under cursor to show their tooltip
Position myPopupPosition
The current popup-menu position.
virtual void doInit()
doInit
std::vector< GUIGlObject * > filterContextObjects(const std::vector< GUIGlObject * > &objects)
filter out duplicate and forbidden objects
GUIGlID getObjectUnderCursor(double sensitivity=SENSITIVITY)
returns the id of the front object under the cursor using GL_SELECT
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.
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
GUIGlID getObjectAtPosition(Position pos, double sensitivity=SENSITIVITY)
returns the id of the object at position using GL_SELECT
std::vector< GUIGlID > getObjectsInBoundary(Boundary bound)
returns the ids of all objects in the given boundary
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.
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
void displayColorLegend(const GUIColorScheme &scheme, bool leftSide, const std::string &key)
Draws a legend for the given scheme.
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.
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.
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.
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
GUIGLObjectPopupMenu * getPopup() const
ge the current popup-menu
virtual long onCmdAddRerouter(FXObject *, FXSelector, void *)
std::vector< GUIGlObject * > filterInternalLanes(const std::vector< GUIGlObject * > &objects) const
filter internal lanes in Objects under cursor
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.
static const std::string SCHEME_NAME_DATA_ATTRIBUTE_NUMERICAL
static const std::string SCHEME_NAME_EDGEDATA_NUMERICAL
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
std::string name
The name of this setting.
bool drawJunctionShape
whether the shape of the junction should be drawn
std::string edgeData
key for coloring by edgeData
bool gaming
whether the application is in gaming mode or not
static const std::string SCHEME_NAME_LANE_PARAM_NUMERICAL
bool fps
Information whether frames-per-second should be drawn.
std::string vehicleParam
key for coloring by vehicle parameter
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.
static const std::string SCHEME_NAME_EDGE_PARAM_NUMERICAL
scheme names
static const std::string SCHEME_NAME_PARAM_NUMERICAL
std::string edgeParam
key for coloring by edge parameter
double angle
The current view rotation angle.
const Position getOffset() const
Returns the network offset.
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 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:67
void set(double x, double y)
set positions x and y
Definition Position.h:82
static const Position INVALID
used to indicate that a position is valid
Definition Position.h:319
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition Position.h:273
double x() const
Returns the x-position.
Definition Position.h:52
void setz(double z)
set position z
Definition Position.h:77
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:62
void sety(double y)
set position y
Definition Position.h:72
double y() const
Returns the y-position.
Definition Position.h:57
static RGBColor interpolate(const RGBColor &minColor, const RGBColor &maxColor, double weight)
Interpolates between two colors.
Definition RGBColor.cpp:387
static const RGBColor WHITE
Definition RGBColor.h:195
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:196
static const RGBColor RED
named colors
Definition RGBColor.h:188
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:114
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:44
#define UNUSED_PARAMETER(x)
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
comparator for resolving clicks
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.
GUIGlObject * getGLObject() const
get GLObject
LayerObject(double layer, GUIGlObject *object)
constructor for shapes
bool hideMax
whether data above threshold should not be colored
bool setNeutral
whether the scale should be centered at a specific value
bool fixRange
whether the color scale should be fixed to the given min/max values
double minThreshold
threshold below which value should not be colored
std::vector< RGBColor > colors
color steps for the rainbow;
bool hideMin
whether data below threshold should not be colored
double neutralThreshold
neutral point of scale
double maxThreshold
threshold above which value should not be colored
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values