Eclipse SUMO - Simulation of Urban MObility
GUISUMOAbstractView.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2001-2022 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
62
63#include "GUISUMOAbstractView.h"
64#include "GUIMainWindow.h"
65#include "GUIGlChildWindow.h"
68
69#ifdef HAVE_GDAL
70#ifdef _MSC_VER
71#pragma warning(push)
72#pragma warning(disable: 4435 5219 5220)
73#endif
74#if __GNUC__ > 3
75#pragma GCC diagnostic push
76#pragma GCC diagnostic ignored "-Wpedantic"
77#endif
78#include <gdal_priv.h>
79#if __GNUC__ > 3
80#pragma GCC diagnostic pop
81#endif
82#ifdef _MSC_VER
83#pragma warning(pop)
84#endif
85#endif
86
87
88// ===========================================================================
89// debug constants
90// ===========================================================================
91//#define DEBUG_SNAPSHOT
92
93// ===========================================================================
94// static members
95// ===========================================================================
96
97const double GUISUMOAbstractView::SENSITIVITY = 0.1; // meters
98
99
100// ===========================================================================
101// member method definitions
102// ===========================================================================
103/* -------------------------------------------------------------------------
104 * GUISUMOAbstractView - FOX callback mapping
105 * ----------------------------------------------------------------------- */
106FXDEFMAP(GUISUMOAbstractView) GUISUMOAbstractViewMap[] = {
107 FXMAPFUNC(SEL_CONFIGURE, 0, GUISUMOAbstractView::onConfigure),
108 FXMAPFUNC(SEL_PAINT, 0, GUISUMOAbstractView::onPaint),
109 FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, GUISUMOAbstractView::onLeftBtnPress),
110 FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, GUISUMOAbstractView::onLeftBtnRelease),
111 FXMAPFUNC(SEL_MIDDLEBUTTONPRESS, 0, GUISUMOAbstractView::onMiddleBtnPress),
112 FXMAPFUNC(SEL_MIDDLEBUTTONRELEASE, 0, GUISUMOAbstractView::onMiddleBtnRelease),
113 FXMAPFUNC(SEL_RIGHTBUTTONPRESS, 0, GUISUMOAbstractView::onRightBtnPress),
114 FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, 0, GUISUMOAbstractView::onRightBtnRelease),
115 FXMAPFUNC(SEL_DOUBLECLICKED, 0, GUISUMOAbstractView::onDoubleClicked),
116 FXMAPFUNC(SEL_MOUSEWHEEL, 0, GUISUMOAbstractView::onMouseWheel),
117 FXMAPFUNC(SEL_MOTION, 0, GUISUMOAbstractView::onMouseMove),
118 FXMAPFUNC(SEL_LEAVE, 0, GUISUMOAbstractView::onMouseLeft),
119 FXMAPFUNC(SEL_KEYPRESS, 0, GUISUMOAbstractView::onKeyPress),
120 FXMAPFUNC(SEL_KEYRELEASE, 0, GUISUMOAbstractView::onKeyRelease),
127};
128
129
130FXIMPLEMENT_ABSTRACT(GUISUMOAbstractView, FXGLCanvas, GUISUMOAbstractViewMap, ARRAYNUMBER(GUISUMOAbstractViewMap))
131
132
133/* -------------------------------------------------------------------------
134 * GUISUMOAbstractView - methods
135 * ----------------------------------------------------------------------- */
136GUISUMOAbstractView::GUISUMOAbstractView(FXComposite* p, GUIMainWindow& app, GUIGlChildWindow* parent, const SUMORTree& grid, FXGLVisual* glVis, FXGLCanvas* share) :
137 FXGLCanvas(p, glVis, share, p, MID_GLCANVAS, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0),
138 myApp(&app),
139 myParent(parent),
140 myGrid(&grid),
141 myChanger(nullptr),
142 myMouseHotspotX(app.getDefaultCursor()->getHotX()),
143 myMouseHotspotY(app.getDefaultCursor()->getHotY()),
144 myAmInitialised(false),
145 myViewportChooser(nullptr),
146 myWindowCursorPositionX(getWidth() / 2),
147 myWindowCursorPositionY(getHeight() / 2),
148 myVisualizationChanger(nullptr),
149 myFrameDrawTime(0) {
150 setTarget(this);
151 enable();
152 flags |= FLAG_ENABLED;
153 myChanger = new GUIDanielPerspectiveChanger(*this, *myGrid);
154 myVisualizationSettings = &gSchemeStorage.getDefault();
155 myVisualizationSettings->gaming = myApp->isGaming();
157 myDecals = gSchemeStorage.getDecals();
158}
159
160
165 delete myPopup;
166 delete myChanger;
167 delete myViewportChooser;
169 // cleanup decals
170 for (std::vector<GUISUMOAbstractView::Decal>::iterator it = myDecals.begin(); it != myDecals.end(); ++it) {
171 delete it->image;
172 }
173 for (auto i : myAdditionallyDrawn) {
174 i.first->removeActiveAddVisualisation(this, ~0); // remove all
175 }
176}
177
178
179bool
181 return myInEditMode;
182}
183
184
187 return *myChanger;
188}
189
190
191void
194 update();
195 }
196}
197
198
202}
203
204
206GUISUMOAbstractView::snapToActiveGrid(const Position& pos, bool snapXY) const {
207 Position result = pos;
209 if (snapXY) {
210 const double xRest = std::fmod(pos.x(), myVisualizationSettings->gridXSize) + (pos.x() < 0 ? myVisualizationSettings->gridXSize : 0);
211 const double yRest = std::fmod(pos.y(), myVisualizationSettings->gridYSize) + (pos.y() < 0 ? myVisualizationSettings->gridYSize : 0);
212 result.setx(pos.x() - xRest + (xRest < myVisualizationSettings->gridXSize * 0.5 ? 0 : myVisualizationSettings->gridXSize));
213 result.sety(pos.y() - yRest + (yRest < myVisualizationSettings->gridYSize * 0.5 ? 0 : myVisualizationSettings->gridYSize));
214 } else {
215 // snapZToActiveGrid uses grid Y Size
216 const double zRest = std::fmod(pos.z(), myVisualizationSettings->gridYSize) + (pos.z() < 0 ? myVisualizationSettings->gridYSize : 0);
217 result.setz(pos.z() - zRest + (zRest < myVisualizationSettings->gridYSize * 0.5 ? 0 : myVisualizationSettings->gridYSize));
218 }
219 }
220 return result;
221}
222
223
226 Boundary bound = myChanger->getViewport();
227 double xNet = bound.xmin() + bound.getWidth() * x / getWidth();
228 // cursor origin is in the top-left corner
229 double yNet = bound.ymin() + bound.getHeight() * (getHeight() - y) / getHeight();
230 // rotate around the viewport center
231 if (myChanger->getRotation() != 0) {
232 return Position(xNet, yNet).rotateAround2D(-DEG2RAD(myChanger->getRotation()), bound.getCenter());
233 } else {
234 return Position(xNet, yNet);
235 }
236}
237
238
239void
240GUISUMOAbstractView::addDecals(const std::vector<Decal>& decals) {
241 myDecals.insert(myDecals.end(), decals.begin(), decals.end());
242}
243
244
245void
248 // set cartesian position
249 myApp->getCartesianLabel()->setText(("x:" + toString(pos.x()) + ", y:" + toString(pos.y())).c_str());
250 // set geo position
252 if (GeoConvHelper::getFinal().usingGeoProjection()) {
253 myApp->getGeoLabel()->setText(("lat:" + toString(pos.y(), gPrecisionGeo) + ", lon:" + toString(pos.x(), gPrecisionGeo)).c_str());
254 } else {
255 myApp->getGeoLabel()->setText(("x:" + toString(pos.x()) + ", y:" + toString(pos.y()) + " (No projection defined)").c_str());
256 }
257 // if enabled, set test position
258 if (myApp->getTestLabel()) {
259 // adjust cursor position (24,25) to show exactly the same position as in function netedit.leftClick(match, X, Y)
260 myApp->getTestLabel()->setText(("Test: x:" + toString(getWindowCursorPosition().x() - 24.0) + " y:" + toString(getWindowCursorPosition().y() - 25.0)).c_str());
261 }
262}
263
264
265int
266GUISUMOAbstractView::doPaintGL(int /*mode*/, const Boundary& /*boundary*/) {
267 return 0;
268}
269
270
271void
273}
274
275
278 return myChanger->getViewport();
279}
280
281
282bool
284 return false;
285}
286
287
288void GUISUMOAbstractView::zoom2Pos(Position& /* camera */, Position& /* lookAt */, double /* zoom */) {
289}
290
291
292void
294 // reset debug counters
297 if (getWidth() == 0 || getHeight() == 0) {
298 return;
299 }
300 const long start = SysUtils::getCurrentMillis();
301
303 centerTo(getTrackedID(), false);
304 }
305 // get id tooltip
306 const GUIGlID idToolTip = getObjectUnderCursor();
307 // draw
308 glClearColor(
313 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
314 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
315
317 glEnable(GL_DITHER);
318 } else {
319 glDisable(GL_DITHER);
320 }
321 glEnable(GL_BLEND);
322 glDisable(GL_LINE_SMOOTH);
323
324 Boundary bound = applyGLTransform();
325 doPaintGL(GL_RENDER, bound);
329 const long end = SysUtils::getCurrentMillis();
330 myFrameDrawTime = end - start;
332 drawFPS();
333 }
334 // check if show tooltip
336 showToolTipFor(idToolTip);
337 } else {
339 }
340 swapBuffers();
341}
342
343
344long
345GUISUMOAbstractView::onCmdCloseLane(FXObject*, FXSelector, void*) {
346 return 1;
347}
348
349
350long
351GUISUMOAbstractView::onCmdCloseEdge(FXObject*, FXSelector, void*) {
352 return 1;
353}
354
355
356long
357GUISUMOAbstractView::onCmdAddRerouter(FXObject*, FXSelector, void*) {
358 return 1;
359}
360
361
362long
363GUISUMOAbstractView::onCmdShowReachability(FXObject*, FXSelector, void*) {
364 return 1;
365}
366
367
368long
369GUISUMOAbstractView::onVisualizationChange(FXObject*, FXSelector, void*) {
370 return 1;
371}
372
373
374GUILane*
376 return nullptr;
377}
378
379
383}
384
385
386std::vector<GUIGlID>
389}
390
391
392std::vector<GUIGlObject*>
395}
396
397
398std::vector<GUIGlObject*>
401}
402
403
406 // calculate a boundary for the given position
407 Boundary positionBoundary;
408 positionBoundary.add(pos);
409 positionBoundary.grow(SENSITIVITY);
410 const std::vector<GUIGlID> ids = getObjectsInBoundary(positionBoundary, true);
411 // Interpret results
412 int idMax = 0;
413 double maxLayer = -std::numeric_limits<double>::max();
414 // iterate over obtained GUIGlIDs
415 for (const auto& i : ids) {
416 // obtain GUIGlObject
418 // check that GUIGlObject exist
419 if (o == nullptr) {
420 continue;
421 }
422 // check that GUIGlObject isn't the network
423 if (o->getGlID() == 0) {
424 continue;
425 }
426 //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
427 double layer = o->getClickPriority();
428 // check whether the current object is above a previous one
429 if (layer > maxLayer) {
430 idMax = i;
431 maxLayer = layer;
432 }
433 // unblock object
435 }
436 return idMax;
437}
438
439
440std::vector<GUIGlID>
442 // declare result vector
443 std::vector<GUIGlID> result;
444 // calculate boundary
445 Boundary selection;
446 selection.add(pos);
447 selection.grow(radius);
448 // obtain GUIGlID of objects in boundary
449 const std::vector<GUIGlID> ids = getObjectsInBoundary(selection, true);
450 // iterate over obtained GUIGlIDs
451 for (const auto& i : ids) {
452 // obtain GUIGlObject
454 // check that GUIGlObject exist
455 if (o == nullptr) {
456 continue;
457 }
458 // check that GUIGlObject isn't the network
459 if (o->getGlID() == 0) {
460 continue;
461 }
462 //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
463 GUIGlObjectType type = o->getType();
464 // avoid network
465 if (type != GLO_NETWORK) {
466 result.push_back(i);
467 }
468 // unblock object
470 }
471 return result;
472}
473
474
475std::vector<GUIGlObject*>
477 // declare result vector
478 std::vector<GUIGlObject*> result;
479 // calculate boundary
480 Boundary selection;
481 selection.add(pos);
482 selection.grow(radius);
483 // obtain GUIGlID of objects in boundary
484 const std::vector<GUIGlID> ids = getObjectsInBoundary(selection, true);
485 // iterate over obtained GUIGlIDs
486 for (const auto& i : ids) {
487 // obtain GUIGlObject
489 // check that GUIGlObject exist
490 if (o == nullptr) {
491 continue;
492 }
493 // check that GUIGlObject isn't the network
494 if (o->getGlID() == 0) {
495 continue;
496 }
497 result.push_back(o);
498 // unblock object
500 }
501 return result;
502}
503
504
505std::vector<GUIGlID>
507 const int NB_HITS_MAX = 1024 * 1024;
508 // Prepare the selection mode
509 static GUIGlID hits[NB_HITS_MAX];
510 static GLint nb_hits = 0;
511 glSelectBuffer(NB_HITS_MAX, hits);
512 glInitNames();
513
515 Boundary oldViewPort = myChanger->getViewport(false); // backup the actual viewPort
516 myChanger->setViewport(bound);
517 bound = applyGLTransform(false);
518 // enable draw for selecting (to draw objects with less details)
519 if (singlePosition) {
521 } else {
523 }
524 int hits2 = doPaintGL(GL_SELECT, bound);
525 // reset flags
528 // Get the results
529 nb_hits = glRenderMode(GL_RENDER);
530 if (nb_hits == -1) {
531 myApp->setStatusBarText("Selection in boundary failed. Try to select fewer than " + toString(hits2) + " items");
532 }
533 std::vector<GUIGlID> result;
534 GLuint numNames;
535 GLuint* ptr = hits;
536 for (int i = 0; i < nb_hits; ++i) {
537 numNames = *ptr;
538 ptr += 3;
539 for (int j = 0; j < (int)numNames; j++) {
540 result.push_back(*ptr);
541 ptr++;
542 }
543 }
544 // switch viewport back to normal
545 myChanger->setViewport(oldViewPort);
546 return result;
547}
548
549
550std::vector<GUIGlObject*>
551GUISUMOAbstractView::filterInernalLanes(const std::vector<GUIGlObject*>& objects) const {
552 // if no draw junction shape, nothing to filter
554 return objects;
555 }
556 // check if there is junctions in list
557 bool junction = false;
558 for (const auto& object : objects) {
559 if (object->getType() == GLO_JUNCTION) {
560 junction = true;
561 }
562 }
563 if (!junction) {
564 return objects;
565 }
566 // filter internal lanes
567 std::vector<GUIGlObject*> filteredObjects;
568 for (const auto& object : objects) {
569 if ((object->getType() == GLO_LANE) && (object->getMicrosimID().find(':') != std::string::npos)) {
570 continue;
571 }
572 filteredObjects.push_back(object);
573 }
574 return filteredObjects;
575}
576
577
578bool
580 if (idToolTip != GUIGlObject::INVALID_ID) {
582 if (object != nullptr) {
583 myParent->getParent()->getStaticTooltipView()->showStaticToolTip(object->getFullName().c_str());
584 return true;
585 }
586 }
587 // nothing to show
589 return false;
590}
591
592
593void
595 // obtain minimum grid
597 // Check if the distance is enough to draw grid
599 glEnable(GL_DEPTH_TEST);
600 glLineWidth(1);
601 // get multiplication values (2 is the margin)
602 const int multXmin = (int)(myChanger->getViewport().xmin() / myVisualizationSettings->gridXSize) - 2;
603 const int multYmin = (int)(myChanger->getViewport().ymin() / myVisualizationSettings->gridYSize) - 2;
604 const int multXmax = (int)(myChanger->getViewport().xmax() / myVisualizationSettings->gridXSize) + 2;
605 const int multYmax = (int)(myChanger->getViewport().ymax() / myVisualizationSettings->gridYSize) + 2;
606 // obtain references
607 const double xmin = myVisualizationSettings->gridXSize * multXmin;
608 const double ymin = myVisualizationSettings->gridYSize * multYmin;
609 const double xmax = myVisualizationSettings->gridXSize * multXmax;
610 const double ymax = myVisualizationSettings->gridYSize * multYmax;
611 double xp = xmin;
612 double yp = ymin;
613 // move drawing matrix
614 glTranslated(0, 0, .55);
615 glColor3d(0.5, 0.5, 0.5);
616 // draw horizontal lines
617 glBegin(GL_LINES);
618 while (yp <= ymax) {
619 glVertex2d(xmin, yp);
620 glVertex2d(xmax, yp);
622 }
623 // draw vertical lines
624 while (xp <= xmax) {
625 glVertex2d(xp, ymin);
626 glVertex2d(xp, ymax);
628 }
629 glEnd();
630 glTranslated(0, 0, -.55);
631 }
632}
633
634
635void
637 // compute the scale bar length
638 int length = 1;
639 const std::string text("10000000000");
640 int noDigits = 1;
641 int pixelSize = (int) m2p((double) length);
642 while (pixelSize <= 20) {
643 length *= 10;
644 noDigits++;
645 if (noDigits > (int)text.length()) {
646 return;
647 }
648 pixelSize = (int) m2p((double) length);
649 }
650 glLineWidth(1.0);
651
652 glMatrixMode(GL_PROJECTION);
654 glLoadIdentity();
655 glMatrixMode(GL_MODELVIEW);
657 glLoadIdentity();
658
659 // draw the scale bar
660 const double z = -1;
661 glDisable(GL_TEXTURE_2D);
662 glDisable(GL_ALPHA_TEST);
663 glDisable(GL_BLEND);
664 glEnable(GL_DEPTH_TEST);
666 glTranslated(0, 0, z);
667
668 double len = (double) pixelSize / (double)(getWidth() - 1) * (double) 2.0;
669 glColor3d(0, 0, 0);
670 double o = double(15) / double(getHeight());
671 double o2 = o + o;
672 double oo = double(5) / double(getHeight());
673 glBegin(GL_LINES);
674 // vertical
675 glVertex2d(-.98, -1. + o);
676 glVertex2d(-.98 + len, -1. + o);
677 // tick at begin
678 glVertex2d(-.98, -1. + o);
679 glVertex2d(-.98, -1. + o2);
680 // tick at end
681 glVertex2d(-.98 + len, -1. + o);
682 glVertex2d(-.98 + len, -1. + o2);
683 glEnd();
685
686 const double fontHeight = 0.1 * 300. / getHeight();
687 const double fontWidth = 0.1 * 300. / getWidth();
688 // draw 0
689 GLHelper::drawText("0", Position(-.99, -0.99 + o2 + oo), z, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT, fontWidth);
690
691 // draw current scale
692 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);
693
694 // restore matrices
695 glMatrixMode(GL_PROJECTION);
697 glMatrixMode(GL_MODELVIEW);
699}
700
701void
705 }
708 }
711 }
712}
713
714void
716 // compute the scale bar length
717 glLineWidth(1.0);
718 glMatrixMode(GL_PROJECTION);
720 glLoadIdentity();
721 glMatrixMode(GL_MODELVIEW);
723 glLoadIdentity();
724
725 const double z = -1;
726 glEnable(GL_DEPTH_TEST);
727 glEnable(GL_BLEND);
729 glTranslated(0, 0, z);
730
731 const bool fixed = scheme.isFixed();
732 const int numColors = (int)scheme.getColors().size();
733
734 // vertical
735 double right = 0.98;
736 double left = 0.95;
737 double textX = left - 0.01;
738 double textDir = 1;
739 FONSalign textAlign = FONS_ALIGN_RIGHT;
740 const double top = -0.8;
741 const double bot = 0.8;
742 const double dy = (top - bot) / numColors;
743 const double bot2 = fixed ? bot : bot + dy / 2;
744 // legend placement
745 if (leftSide) {
746 right = -right;
747 left = -left;
748 std::swap(right, left);
749 textX = right + 0.01;
750 textDir *= -1;
751 textAlign = FONS_ALIGN_LEFT;
752 }
753 // draw black boundary around legend colors
754 glColor3d(0, 0, 0);
755 glBegin(GL_LINES);
756 glVertex2d(right, top);
757 glVertex2d(right, bot2);
758 glVertex2d(left, bot2);
759 glVertex2d(left, top);
760 glVertex2d(right, top);
761 glVertex2d(left, top);
762 glVertex2d(right, bot2);
763 glVertex2d(left, bot2);
764 glEnd();
765
766 const double fontHeight = 0.20 * 300. / getHeight();
767 const double fontWidth = 0.20 * 300. / getWidth();
768
769 const int fadeSteps = fixed ? 1 : 10;
770 double colorStep = dy / fadeSteps;
771 for (int i = 0; i < numColors; i++) {
772 RGBColor col = scheme.getColors()[i];
773 const double topi = top - i * dy;
774 //const double boti = top - (i + 1) * dy;
775 //std::cout << " col=" << scheme.getColors()[i] << " i=" << i << " topi=" << topi << " boti=" << boti << "\n";
776 if (i + 1 < numColors) {
777 // fade
778 RGBColor col2 = scheme.getColors()[i + 1];
779 double thresh2 = scheme.getThresholds()[i + 1];
780 if (!fixed && thresh2 == GUIVisualizationSettings::MISSING_DATA) {
781 // draw scale end before missing data
783 glBegin(GL_QUADS);
784 glVertex2d(left, topi);
785 glVertex2d(right, topi);
786 glVertex2d(right, topi - 5 * colorStep);
787 glVertex2d(left, topi - 5 * colorStep);
788 glEnd();
789 glColor3d(0, 0, 0);
790 glBegin(GL_LINES);
791 glVertex2d(right, topi - 10 * colorStep);
792 glVertex2d(left, topi - 10 * colorStep);
793 glEnd();
794 glBegin(GL_LINES);
795 glVertex2d(right, topi - 5 * colorStep);
796 glVertex2d(left, topi - 5 * colorStep);
797 glEnd();
798 } else {
799 // fade colors
800 for (double j = 0.0; j < fadeSteps; j++) {
801 GLHelper::setColor(RGBColor::interpolate(col, col2, j / fadeSteps));
802 glBegin(GL_QUADS);
803 glVertex2d(left, topi - j * colorStep);
804 glVertex2d(right, topi - j * colorStep);
805 glVertex2d(right, topi - (j + 1) * colorStep);
806 glVertex2d(left, topi - (j + 1) * colorStep);
807 glEnd();
808 }
809 }
810 } else {
812 glBegin(GL_QUADS);
813 glVertex2d(left, topi);
814 glVertex2d(right, topi);
815 glVertex2d(right, bot2);
816 glVertex2d(left, bot2);
817 glEnd();
818 }
819
820 const double threshold = scheme.getThresholds()[i];
821 std::string name = scheme.getNames()[i];
822 std::string text = fixed || threshold == GUIVisualizationSettings::MISSING_DATA ? name : toString(threshold);
823
824 const double bgShift = 0.0;
825 const double textShift = 0.01;
826 const double textXShift = -0.005;
827
829 glTranslated(0, 0, 0.1);
830 glBegin(GL_QUADS);
831 glVertex2d(textX, topi + fontHeight * bgShift);
832 glVertex2d(textX - textDir * fontWidth * (double)text.size() / 2., topi + fontHeight * bgShift);
833 glVertex2d(textX - textDir * fontWidth * (double)text.size() / 2., topi + fontHeight * (1. + bgShift));
834 glVertex2d(textX, topi + fontHeight * (1. + bgShift));
835 glEnd();
836 glTranslated(0, 0, -0.1);
837 GLHelper::drawText(text, Position(textX + textDir * textXShift, topi + textShift), 0, fontHeight, RGBColor::BLACK, 0, textAlign, fontWidth);
838 }
840 // restore matrices
841 glMatrixMode(GL_PROJECTION);
843 glMatrixMode(GL_MODELVIEW);
845}
846
847
848double
850 return 1000.0 / MAX2((long)1, myFrameDrawTime);
851}
852
853void
855 glMatrixMode(GL_PROJECTION);
857 glLoadIdentity();
858 glMatrixMode(GL_MODELVIEW);
860 glLoadIdentity();
861 const double fontHeight = 0.2 * 300. / getHeight();
862 const double fontWidth = 0.2 * 300. / getWidth();
863 GLHelper::drawText(toString((int)getFPS()) + " FPS", Position(0.82, 0.88), -1, fontHeight, RGBColor::RED, 0, FONS_ALIGN_LEFT, fontWidth);
864#ifdef CHECK_ELEMENTCOUNTER
865 GLHelper::drawText(toString(GLHelper::getMatrixCounter()) + " matrix", Position(0.82, 0.79), -1, fontHeight, RGBColor::RED, 0, FONS_ALIGN_LEFT, fontWidth);
866 GLHelper::drawText(toString(GLHelper::getVertexCounter()) + " vertex", Position(0.82, 0.71), -1, fontHeight, RGBColor::RED, 0, FONS_ALIGN_LEFT, fontWidth);
867#endif
868 // restore matrices
869 glMatrixMode(GL_PROJECTION);
871 glMatrixMode(GL_MODELVIEW);
873}
874
875
876double
877GUISUMOAbstractView::m2p(double meter) const {
878 return meter * getWidth() / myChanger->getViewport().getWidth();
879}
880
881
882double
883GUISUMOAbstractView::p2m(double pixel) const {
884 return pixel * myChanger->getViewport().getWidth() / getWidth();
885}
886
887
888void
891}
892
893
894void
895GUISUMOAbstractView::centerTo(GUIGlID id, bool applyZoom, double zoomDist) {
897 if (o != nullptr && dynamic_cast<GUIGlObject*>(o) != nullptr) {
898 if (applyZoom && zoomDist < 0) {
900 update(); // only update when centering onto an object once
901 } else {
902 // called during tracking. update is triggered somewhere else
903 myChanger->centerTo(o->getCenteringBoundary().getCenter(), zoomDist, applyZoom);
905 }
906 }
908}
909
910
911void
912GUISUMOAbstractView::centerTo(const Position& pos, bool applyZoom, double zoomDist) {
913 // called during tracking. update is triggered somewhere else
914 myChanger->centerTo(pos, zoomDist, applyZoom);
916}
917
918
919void
921 myChanger->setViewport(bound);
922 update();
923}
924
925
928 return myApp;
929}
930
931
935}
936
937
938void
942}
943
944
945FXbool
947 FXbool ret = FXGLCanvas::makeCurrent();
948 return ret;
949}
950
951
952long
953GUISUMOAbstractView::onConfigure(FXObject*, FXSelector, void*) {
954 if (makeCurrent()) {
955 glViewport(0, 0, getWidth() - 1, getHeight() - 1);
956 glClearColor(
961 doInit();
962 myAmInitialised = true;
963 makeNonCurrent();
965 }
966 return 1;
967}
968
969
970long
971GUISUMOAbstractView::onPaint(FXObject*, FXSelector, void*) {
972 if (!isEnabled() || !myAmInitialised) {
973 return 1;
974 }
975 if (makeCurrent()) {
976 paintGL();
977 makeNonCurrent();
978 }
979 return 1;
980}
981
982
983const Position&
985 return myPopupPosition;
986}
987
988
989void
991 if (myPopup != nullptr) {
992 delete myPopup;
993 myPopupPosition.set(0, 0);
994 myPopup = nullptr;
996 }
997}
998
999
1000void
1002 // use the same position of old popUp
1003 popUp->move(myPopup->getX(), myPopup->getY());
1004 // delete and replace popup
1005 delete myPopup;
1006 myPopup = popUp;
1007 // create and show popUp
1008 myPopup->create();
1009 myPopup->show();
1010 myChanger->onRightBtnRelease(nullptr);
1011 setFocus();
1012}
1013
1014
1015long
1016GUISUMOAbstractView::onLeftBtnPress(FXObject*, FXSelector, void* ptr) {
1017 destroyPopup();
1018 setFocus();
1019 FXEvent* e = (FXEvent*) ptr;
1020 // check whether the selection-mode is activated
1021 if ((e->state & CONTROLMASK) != 0) {
1022 // toggle selection of object under cursor
1023 if (makeCurrent()) {
1024 int id = getObjectUnderCursor();
1025 if (id != 0) {
1027 }
1028 makeNonCurrent();
1029 if (id != 0) {
1030 // possibly, the selection-colouring is used,
1031 // so we should update the screen again...
1032 update();
1033 }
1034 }
1035 }
1036 if ((e->state & SHIFTMASK) != 0) {
1037 // track vehicle or person under cursor
1038 if (makeCurrent()) {
1039 int id = getObjectUnderCursor();
1040 if (id != 0) {
1042 if (o != nullptr) {
1043 if (o->getType() == GLO_VEHICLE || o->getType() == GLO_PERSON) {
1044 startTrack(id);
1045 } else if (o->getType() == GLO_REROUTER_EDGE) {
1046 o->onLeftBtnPress(ptr);
1047 update();
1048 }
1049 }
1050 }
1051 makeNonCurrent();
1052 }
1053 }
1055 grab();
1056 // Check there are double click
1057 if (e->click_count == 2) {
1058 handle(this, FXSEL(SEL_DOUBLECLICKED, 0), ptr);
1059 }
1060 return 1;
1061}
1062
1063
1064long
1065GUISUMOAbstractView::onLeftBtnRelease(FXObject*, FXSelector, void* ptr) {
1066 destroyPopup();
1068 if (myApp->isGaming()) {
1070 }
1071 ungrab();
1072 return 1;
1073}
1074
1075
1076long
1077GUISUMOAbstractView::onMiddleBtnPress(FXObject*, FXSelector, void* ptr) {
1078 destroyPopup();
1079 setFocus();
1081 grab();
1082 // enable panning
1083 myPanning = true;
1084 // set cursors
1087 return 1;
1088}
1089
1090
1091long
1092GUISUMOAbstractView::onMiddleBtnRelease(FXObject*, FXSelector, void* ptr) {
1093 destroyPopup();
1095 ungrab();
1096 // disable panning
1097 myPanning = false;
1098 // restore cursors
1101 return 1;
1102}
1103
1104
1105long
1106GUISUMOAbstractView::onRightBtnPress(FXObject*, FXSelector, void* ptr) {
1107 destroyPopup();
1109 grab();
1110 return 1;
1111}
1112
1113
1114long
1115GUISUMOAbstractView::onRightBtnRelease(FXObject* o, FXSelector sel, void* ptr) {
1116 destroyPopup();
1117 onMouseMove(o, sel, ptr);
1118 if (!myChanger->onRightBtnRelease(ptr) && !myApp->isGaming()) {
1119 openObjectDialogAtCursor((FXEvent*)ptr);
1120 }
1121 if (myApp->isGaming()) {
1123 }
1124 ungrab();
1125 return 1;
1126}
1127
1128
1129long
1130GUISUMOAbstractView::onDoubleClicked(FXObject*, FXSelector, void*) {
1131 return 1;
1132}
1133
1134
1135long
1136GUISUMOAbstractView::onMouseWheel(FXObject*, FXSelector, void* ptr) {
1137 if (!myApp->isGaming()) {
1138 myChanger->onMouseWheel(ptr);
1139 // upddate viewport
1140 if (myViewportChooser != nullptr) {
1144 }
1146 }
1147 return 1;
1148}
1149
1150
1151long
1152GUISUMOAbstractView::onMouseMove(FXObject*, FXSelector, void* ptr) {
1153 // check if popup exist
1154 if (myPopup) {
1155 // check if handle front element
1158 myPopup->handle(this, FXSEL(SEL_COMMAND, MID_CURSORDIALOG_FRONT), nullptr);
1159 destroyPopup();
1160 } else if (myPopup->shown() == false) {
1161 destroyPopup();
1162 }
1163 }
1164 if (myPopup == nullptr) {
1165 if (myViewportChooser == nullptr || !myViewportChooser->haveGrabbed()) {
1166 myChanger->onMouseMove(ptr);
1167 }
1168 if (myViewportChooser != nullptr) {
1172 }
1174 }
1175 return 1;
1176}
1177
1178
1179long
1180GUISUMOAbstractView::onMouseLeft(FXObject*, FXSelector, void* /*data*/) {
1181 return 1;
1182}
1183
1184
1185void
1187 // release the mouse grab
1188 ungrab();
1189 // check if alt key is pressed
1190 const bool altKeyPressed = ((ev->state & ALTMASK) != 0);
1191 // check if SUMO is enabled, initialised and Make OpenGL context current
1192 if (isEnabled() && myAmInitialised && makeCurrent()) {
1193 // get all objects under cusor
1194 const auto objectsUnderCursor = getGUIGlObjectsUnderCursor();
1195 // filter elements
1196 std::vector<GUIGlObject*> filteredObjectsUnderCursor;
1197 std::vector<GUIGlObject*> filteredVehiclesUnderCursor;
1198 std::vector<GUIGlObject*> filteredTLSUnderCursor;
1199 for (const auto& GLObject : objectsUnderCursor) {
1200 if (GLObject->getType() == GLO_EDGE) {
1201 // avoid edges
1202 continue;
1203 }
1204 if (std::find(filteredObjectsUnderCursor.begin(), filteredObjectsUnderCursor.end(), GLObject) != filteredObjectsUnderCursor.end()) {
1205 // avoid duplicated lanes
1206 continue;
1207 }
1208 if ((GLObject->getType() == GLO_VEHICLE) || (GLObject->getType() == GLO_TRIP) ||
1209 (GLObject->getType() == GLO_FLOW) || (GLObject->getType() == GLO_ROUTEFLOW) ||
1210 (GLObject->getType() == GLO_CONTAINER) || (GLObject->getType() == GLO_CONTAINERFLOW) ||
1211 (GLObject->getType() == GLO_PERSON) || (GLObject->getType() == GLO_PERSONFLOW)) {
1212 // filter vehicles, person and containers
1213 filteredVehiclesUnderCursor.push_back(GLObject);
1214 }
1215 if (GLObject->getType() == GLO_TLLOGIC) {
1216 // filter TLSs
1217 filteredTLSUnderCursor.push_back(GLObject);
1218 }
1219 filteredObjectsUnderCursor.push_back(GLObject);
1220 }
1221 // filter internal lanes
1222 filteredObjectsUnderCursor = filterInernalLanes(filteredObjectsUnderCursor);
1223 // continue depending of number of objects
1224 if (filteredObjectsUnderCursor.empty()) {
1225 // if filteredObjectsUnderCursor, inspect net
1227 } else if (altKeyPressed) {
1228 // inspect all objects under cusror
1229 openObjectDialog(filteredObjectsUnderCursor);
1230 } else if (filteredVehiclesUnderCursor.size() > 0) {
1231 // inspect only vehicles
1232 openObjectDialog(filteredVehiclesUnderCursor);
1233 } else if (filteredTLSUnderCursor.size() > 0) {
1234 // inspect only TLSs
1235 openObjectDialog(filteredTLSUnderCursor);
1236 } else {
1237 // inspect objects under cursor
1238 openObjectDialog(filteredObjectsUnderCursor);
1239 }
1240 // Make OpenGL context non current
1241 makeNonCurrent();
1242 }
1243}
1244
1245
1246void
1247GUISUMOAbstractView::openObjectDialog(const std::vector<GUIGlObject*>& objects) {
1248 if (objects.size() > 0) {
1249 // create cursor popup dialog
1250 if (objects.size() == 1) {
1251 myCurrentObjectsDialog = objects;
1252 } else {
1253 // declare filtered objects
1254 std::vector<GUIGlObject*> filteredGLObjects;
1255 // fill filtered objects
1256 for (const auto& glObject : objects) {
1257 // compare type with first eleement type
1258 if (glObject->getType() == objects.front()->getType()) {
1259 filteredGLObjects.push_back(glObject);
1260 }
1261 }
1262 myCurrentObjectsDialog = filteredGLObjects;
1263 }
1264 if (myCurrentObjectsDialog.size() > 1) {
1266 } else {
1267 myPopup = myCurrentObjectsDialog.front()->getPopUpMenu(*myApp, *this);
1268 }
1269 // open popup dialog
1271 }
1272}
1273
1274
1275long
1276GUISUMOAbstractView::onKeyPress(FXObject* o, FXSelector sel, void* ptr) {
1277 if (myPopup != nullptr) {
1278 return myPopup->onKeyPress(o, sel, ptr);
1279 } else {
1280 FXEvent* e = (FXEvent*) ptr;
1281 if (e->state & CONTROLMASK) {
1282 if (e->code == FX::KEY_Page_Up) {
1285 update();
1286 return 1;
1287 } else if (e->code == FX::KEY_Page_Down) {
1290 update();
1291 return 1;
1292 }
1293 }
1294 FXGLCanvas::onKeyPress(o, sel, ptr);
1295 return myChanger->onKeyPress(ptr);
1296 }
1297}
1298
1299
1300long
1301GUISUMOAbstractView::onKeyRelease(FXObject* o, FXSelector sel, void* ptr) {
1302 if (myPopup != nullptr) {
1303 return myPopup->onKeyRelease(o, sel, ptr);
1304 } else {
1305 FXGLCanvas::onKeyRelease(o, sel, ptr);
1306 return myChanger->onKeyRelease(ptr);
1307 }
1308}
1309
1310
1311// ------------ Dealing with snapshots
1312void
1313GUISUMOAbstractView::addSnapshot(SUMOTime time, const std::string& file, const int w, const int h) {
1314#ifdef DEBUG_SNAPSHOT
1315 std::cout << "add snapshot time=" << time << " file=" << file << "\n";
1316#endif
1317 FXMutexLock lock(mySnapshotsMutex);
1318 mySnapshots[time].push_back(std::make_tuple(file, w, h));
1319}
1320
1321
1322std::string
1323GUISUMOAbstractView::makeSnapshot(const std::string& destFile, const int w, const int h) {
1324 if (w >= 0) {
1325 resize(w, h);
1326 repaint();
1327 }
1328 std::string errorMessage;
1329 FXString ext = FXPath::extension(destFile.c_str());
1330 const bool useGL2PS = ext == "ps" || ext == "eps" || ext == "pdf" || ext == "svg" || ext == "tex" || ext == "pgf";
1331#ifdef HAVE_FFMPEG
1332 const bool useVideo = destFile == "" || ext == "h264" || ext == "hevc" || ext == "mp4";
1333#endif
1334 for (int i = 0; i < 10 && !makeCurrent(); ++i) {
1336 }
1337 // draw
1338 glClearColor(
1343 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
1344 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1345
1347 glEnable(GL_DITHER);
1348 } else {
1349 glDisable(GL_DITHER);
1350 }
1351 glEnable(GL_BLEND);
1352 glDisable(GL_LINE_SMOOTH);
1353
1355
1356 if (useGL2PS) {
1357#ifdef HAVE_GL2PS
1358 GLint format = GL2PS_PS;
1359 if (ext == "ps") {
1360 format = GL2PS_PS;
1361 } else if (ext == "eps") {
1362 format = GL2PS_EPS;
1363 } else if (ext == "pdf") {
1364 format = GL2PS_PDF;
1365 } else if (ext == "tex") {
1366 format = GL2PS_TEX;
1367 } else if (ext == "svg") {
1368 format = GL2PS_SVG;
1369 } else if (ext == "pgf") {
1370 format = GL2PS_PGF;
1371 } else {
1372 return "Could not save '" + destFile + "'.\n Unrecognized format '" + std::string(ext.text()) + "'.";
1373 }
1374 FILE* fp = fopen(destFile.c_str(), "wb");
1375 if (fp == 0) {
1376 return "Could not save '" + destFile + "'.\n Could not open file for writing";
1377 }
1379 GLint buffsize = 0, state = GL2PS_OVERFLOW;
1380 GLint viewport[4];
1381 glGetIntegerv(GL_VIEWPORT, viewport);
1382 while (state == GL2PS_OVERFLOW) {
1383 buffsize += 1024 * 1024;
1384 gl2psBeginPage(destFile.c_str(), "sumo-gui; https://sumo.dlr.de", viewport, format, GL2PS_SIMPLE_SORT,
1385 GL2PS_DRAW_BACKGROUND | GL2PS_USE_CURRENT_VIEWPORT,
1386 GL_RGBA, 0, NULL, 0, 0, 0, buffsize, fp, "out.eps");
1387 glMatrixMode(GL_MODELVIEW);
1389 glDisable(GL_TEXTURE_2D);
1390 glDisable(GL_ALPHA_TEST);
1391 glDisable(GL_BLEND);
1392 glEnable(GL_DEPTH_TEST);
1393 // draw decals (if not in grabbing mode)
1394
1395 drawDecals();
1397 paintGLGrid();
1398 }
1399
1400 glLineWidth(1);
1401 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1402 Boundary viewPort = myChanger->getViewport();
1403 const float minB[2] = { (float)viewPort.xmin(), (float)viewPort.ymin() };
1404 const float maxB[2] = { (float)viewPort.xmax(), (float)viewPort.ymax() };
1406 glEnable(GL_POLYGON_OFFSET_FILL);
1407 glEnable(GL_POLYGON_OFFSET_LINE);
1408 myGrid->Search(minB, maxB, *myVisualizationSettings);
1409
1411 state = gl2psEndPage();
1412 glFinish();
1413 }
1414 GLHelper::setGL2PS(false);
1415 fclose(fp);
1416#else
1417 return "Could not save '" + destFile + "', gl2ps was not enabled at compile time.";
1418#endif
1419 } else {
1420 doPaintGL(GL_RENDER, myChanger->getViewport());
1422 swapBuffers();
1423 glFinish();
1424 FXColor* buf;
1425 FXMALLOC(&buf, FXColor, getWidth()*getHeight());
1426 // read from the back buffer
1427 glReadBuffer(GL_BACK);
1428 // Read the pixels
1429 glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)buf);
1430 makeNonCurrent();
1431 update();
1432 // mirror
1433 int mwidth = getWidth();
1434 int mheight = getHeight();
1435 FXColor* paa = buf;
1436 FXColor* pbb = buf + mwidth * (mheight - 1);
1437 do {
1438 FXColor* pa = paa;
1439 paa += mwidth;
1440 FXColor* pb = pbb;
1441 pbb -= mwidth;
1442 do {
1443 FXColor t = *pa;
1444 *pa++ = *pb;
1445 *pb++ = t;
1446 } while (pa < paa);
1447 } while (paa < pbb);
1448 try {
1449#ifdef HAVE_FFMPEG
1450 if (useVideo) {
1451 try {
1452 saveFrame(destFile, buf);
1453 errorMessage = "video";
1454 } catch (std::runtime_error& err) {
1455 errorMessage = err.what();
1456 }
1457 } else
1458#endif
1459 if (!MFXImageHelper::saveImage(destFile, getWidth(), getHeight(), buf)) {
1460 errorMessage = "Could not save '" + destFile + "'.";
1461 }
1462 } catch (InvalidArgument& e) {
1463 errorMessage = "Could not save '" + destFile + "'.\n" + e.what();
1464 }
1465 FXFREE(&buf);
1466 }
1467 return errorMessage;
1468}
1469
1470
1471void
1472GUISUMOAbstractView::saveFrame(const std::string& destFile, FXColor* buf) {
1473 UNUSED_PARAMETER(destFile);
1474 UNUSED_PARAMETER(buf);
1475}
1476
1477
1478void
1480 const SUMOTime time = getCurrentTimeStep() - DELTA_T;
1481#ifdef DEBUG_SNAPSHOT
1482 std::cout << "check snapshots time=" << time << " registeredTimes=" << mySnapshots.size() << "\n";
1483#endif
1484 FXMutexLock lock(mySnapshotsMutex);
1485 const auto snapIt = mySnapshots.find(time);
1486 if (snapIt == mySnapshots.end()) {
1487 return;
1488 }
1489 std::vector<std::tuple<std::string, int, int> > files = snapIt->second;
1490 lock.unlock();
1491 // decouple map access and painting to avoid deadlock
1492 for (const auto& entry : files) {
1493#ifdef DEBUG_SNAPSHOT
1494 std::cout << "make snapshot time=" << time << " file=" << file << "\n";
1495#endif
1496 const std::string& error = makeSnapshot(std::get<0>(entry), std::get<1>(entry), std::get<2>(entry));
1497 if (error != "" && error != "video") {
1498 WRITE_WARNING(error);
1499 }
1500 }
1501 // synchronization with a waiting run thread
1502 lock.lock();
1503 mySnapshots.erase(time);
1504 mySnapshotCondition.signal();
1505#ifdef DEBUG_SNAPSHOT
1506 std::cout << " files=" << toString(files) << " myApplicationSnapshots=" << joinToString(*myApplicationSnapshots, ",") << "\n";
1507#endif
1508}
1509
1510
1511void
1513 FXMutexLock lock(mySnapshotsMutex);
1514 if (mySnapshots.count(snapshotTime) > 0) {
1516 }
1517}
1518
1519
1522 return 0;
1523}
1524
1525
1526void
1528 if (myVisualizationChanger == nullptr) {
1533 myVisualizationChanger->create();
1534 } else {
1536 }
1537 setFocus();
1539}
1540
1541
1544 if (myViewportChooser == nullptr) {
1545 const FXint minSize = 100;
1546 const FXint minTitlebarHeight = 20;
1547 int x = MAX2(0, MIN2(getApp()->reg().readIntEntry(
1548 "VIEWPORT_DIALOG_SETTINGS", "x", 150),
1549 getApp()->getRootWindow()->getWidth() - minSize));
1550 int y = MAX2(minTitlebarHeight, MIN2(getApp()->reg().readIntEntry(
1551 "VIEWPORT_DIALOG_SETTINGS", "y", 150),
1552 getApp()->getRootWindow()->getHeight() - minSize));
1553 myViewportChooser = new GUIDialog_EditViewport(this, "Edit Viewport", x, y);
1554 myViewportChooser->create();
1555 }
1557 return myViewportChooser;
1558}
1559
1560
1565}
1566
1567
1568void
1570 getViewportEditor(); // make sure it exists;
1574}
1575
1576
1577void
1578GUISUMOAbstractView::setViewportFromToRot(const Position& lookFrom, const Position& /* lookAt */, double rotation) {
1579 myChanger->setViewportFrom(lookFrom.x(), lookFrom.y(), lookFrom.z());
1580 myChanger->setRotation(rotation);
1581 update();
1582}
1583
1584
1585void
1587 // look straight down
1591}
1592
1593
1594bool
1596 return true;
1597}
1598
1599
1603}
1604
1605
1609}
1610
1611
1612void
1614 myViewportChooser = nullptr;
1615}
1616
1617
1618void
1620 myVisualizationChanger = nullptr;
1621}
1622
1623
1624double
1626 return myGrid->getWidth();
1627}
1628
1629
1630double
1632 return myGrid->getHeight();
1633}
1634
1635
1636void
1638}
1639
1640
1641void
1643}
1644
1645
1646GUIGlID
1649}
1650
1651
1652void
1654}
1655
1656void
1658}
1659
1660
1661FXComboBox*
1664}
1665
1666
1667FXImage*
1669#ifdef HAVE_GDAL
1670 GDALAllRegister();
1671 GDALDataset* poDataset = (GDALDataset*)GDALOpen(d.filename.c_str(), GA_ReadOnly);
1672 if (poDataset == 0) {
1673 return 0;
1674 }
1675 const int xSize = poDataset->GetRasterXSize();
1676 const int ySize = poDataset->GetRasterYSize();
1677 // checking for geodata in the picture and try to adapt position and scale
1678 if (d.width <= 0.) {
1679 double adfGeoTransform[6];
1680 if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) {
1681 Position topLeft(adfGeoTransform[0], adfGeoTransform[3]);
1682 const double horizontalSize = xSize * adfGeoTransform[1];
1683 const double verticalSize = ySize * adfGeoTransform[5];
1684 Position bottomRight(topLeft.x() + horizontalSize, topLeft.y() + verticalSize);
1685 if (GeoConvHelper::getProcessing().x2cartesian(topLeft) && GeoConvHelper::getProcessing().x2cartesian(bottomRight)) {
1686 d.width = bottomRight.x() - topLeft.x();
1687 d.height = topLeft.y() - bottomRight.y();
1688 d.centerX = (topLeft.x() + bottomRight.x()) / 2;
1689 d.centerY = (topLeft.y() + bottomRight.y()) / 2;
1690 //WRITE_MESSAGE("proj: " + toString(poDataset->GetProjectionRef()) + " dim: " + toString(d.width) + "," + toString(d.height) + " center: " + toString(d.centerX) + "," + toString(d.centerY));
1691 } else {
1692 WRITE_WARNING("Could not convert coordinates in " + d.filename + ".");
1693 }
1694 }
1695 }
1696#endif
1697 if (d.width <= 0.) {
1698 d.width = getGridWidth();
1699 d.height = getGridHeight();
1700 }
1701
1702 // trying to read the picture
1703#ifdef HAVE_GDAL
1704 const int picSize = xSize * ySize;
1705 FXColor* result;
1706 if (!FXMALLOC(&result, FXColor, picSize)) {
1707 WRITE_WARNING("Could not allocate memory for " + d.filename + ".");
1708 return 0;
1709 }
1710 for (int j = 0; j < picSize; j++) {
1711 result[j] = FXRGB(0, 0, 0);
1712 }
1713 bool valid = true;
1714 for (int i = 1; i <= poDataset->GetRasterCount(); i++) {
1715 GDALRasterBand* poBand = poDataset->GetRasterBand(i);
1716 int shift = -1;
1717 if (poBand->GetColorInterpretation() == GCI_RedBand) {
1718 shift = 0;
1719 } else if (poBand->GetColorInterpretation() == GCI_GreenBand) {
1720 shift = 1;
1721 } else if (poBand->GetColorInterpretation() == GCI_BlueBand) {
1722 shift = 2;
1723 } else if (poBand->GetColorInterpretation() == GCI_AlphaBand) {
1724 shift = 3;
1725 } else {
1726 valid = false;
1727 break;
1728 }
1729 assert(xSize == poBand->GetXSize() && ySize == poBand->GetYSize());
1730 if (poBand->RasterIO(GF_Read, 0, 0, xSize, ySize, ((unsigned char*)result) + shift, xSize, ySize, GDT_Byte, 4, 4 * xSize) == CE_Failure) {
1731 valid = false;
1732 break;
1733 }
1734 }
1735 GDALClose(poDataset);
1736 if (valid) {
1737 return new FXImage(getApp(), result, IMAGE_OWNED | IMAGE_KEEP | IMAGE_SHMI | IMAGE_SHMP, xSize, ySize);
1738 }
1739 FXFREE(&result);
1740#endif
1741 return nullptr;
1742}
1743
1744
1745void
1748 myDecalsLock.lock();
1750 if (d.skip2D) {
1751 continue;
1752 }
1753 if (!d.initialised) {
1754 try {
1755 FXImage* img = checkGDALImage(d);
1756 if (img == nullptr) {
1757 img = MFXImageHelper::loadImage(getApp(), d.filename);
1758 }
1760 d.glID = GUITexturesHelper::add(img);
1761 d.initialised = true;
1762 d.image = img;
1763 } catch (InvalidArgument& e) {
1764 WRITE_ERROR("Could not load '" + d.filename + "'.\n" + e.what());
1765 d.skip2D = true;
1766 }
1767 }
1769 if (d.screenRelative) {
1770 Position center = screenPos2NetPos((int)d.centerX, (int)d.centerY);
1771 glTranslated(center.x(), center.y(), d.layer);
1772 } else {
1773 glTranslated(d.centerX, d.centerY, d.layer);
1774 }
1775 glRotated(d.rot, 0, 0, 1);
1776 glColor3d(1, 1, 1);
1777 double halfWidth = d.width / 2.;
1778 double halfHeight = d.height / 2.;
1779 if (d.screenRelative) {
1780 halfWidth = p2m(halfWidth);
1781 halfHeight = p2m(halfHeight);
1782 }
1783 GUITexturesHelper::drawTexturedBox(d.glID, -halfWidth, -halfHeight, halfWidth, halfHeight);
1785 }
1786 myDecalsLock.unlock();
1788}
1789
1790
1791void
1793 int x, y;
1794 FXuint b;
1795 myApp->getCursorPosition(x, y, b);
1796 int popX = x + myApp->getX();
1797 int popY = y + myApp->getY();
1798 myPopup->setX(popX);
1799 myPopup->setY(popY);
1800 myPopup->create();
1801 myPopup->show();
1802 // try to stay on screen unless click appears to come from a multi-screen setup
1803 const int rootWidth = getApp()->getRootWindow()->getWidth();
1804 const int rootHeight = getApp()->getRootWindow()->getHeight();
1805 if (popX <= rootWidth) {
1806 popX = MAX2(0, MIN2(popX, rootWidth - myPopup->getWidth() - 10));
1807 }
1808 if (popY <= rootHeight) {
1809 popY = MAX2(0, MIN2(popY, rootHeight - myPopup->getHeight() - 50));
1810 }
1811 myPopup->move(popX, popY);
1813 myChanger->onRightBtnRelease(nullptr);
1814 setFocus();
1815}
1816
1817// ------------ Additional visualisations
1818
1819bool
1821 if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1822 myAdditionallyDrawn[which] = 1;
1823 } else {
1824 myAdditionallyDrawn[which] = myAdditionallyDrawn[which] + 1;
1825 }
1826 update();
1827 return true;
1828}
1829
1830
1831bool
1833 if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1834 return false;
1835 }
1836 int cnt = myAdditionallyDrawn[which];
1837 if (cnt == 1) {
1838 myAdditionallyDrawn.erase(which);
1839 } else {
1840 myAdditionallyDrawn[which] = myAdditionallyDrawn[which] - 1;
1841 }
1842 update();
1843 return true;
1844}
1845
1846
1847bool
1849 if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1850 return false;
1851 } else {
1852 return true;
1853 }
1854}
1855
1856
1859 Boundary bound = myChanger->getViewport(fixRatio);
1860 glMatrixMode(GL_PROJECTION);
1861 glLoadIdentity();
1862 // as a rough rule, each GLObject is drawn at z = -GUIGlObjectType
1863 // thus, objects with a higher value will be closer (drawn on top)
1864 // // @todo last param should be 0 after modifying all glDraw methods
1865 glOrtho(0, getWidth(), 0, getHeight(), -GLO_MAX - 1, GLO_MAX + 1);
1866 glMatrixMode(GL_MODELVIEW);
1867 glLoadIdentity();
1868 double scaleX = (double)getWidth() / bound.getWidth();
1869 double scaleY = (double)getHeight() / bound.getHeight();
1870 glScaled(scaleX, scaleY, 1);
1871 glTranslated(-bound.xmin(), -bound.ymin(), 0);
1872 // rotate around the center of the screen
1873 //double angle = -90;
1874 if (myChanger->getRotation() != 0) {
1875 glTranslated(bound.getCenter().x(), bound.getCenter().y(), 0);
1876 glRotated(myChanger->getRotation(), 0, 0, 1);
1877 glTranslated(-bound.getCenter().x(), -bound.getCenter().y(), 0);
1878 Boundary rotBound;
1879 double rad = -DEG2RAD(myChanger->getRotation());
1880 rotBound.add(Position(bound.xmin(), bound.ymin()).rotateAround2D(rad, bound.getCenter()));
1881 rotBound.add(Position(bound.xmin(), bound.ymax()).rotateAround2D(rad, bound.getCenter()));
1882 rotBound.add(Position(bound.xmax(), bound.ymin()).rotateAround2D(rad, bound.getCenter()));
1883 rotBound.add(Position(bound.xmax(), bound.ymax()).rotateAround2D(rad, bound.getCenter()));
1884 bound = rotBound;
1885 }
1887 return bound;
1888}
1889
1890
1891double
1893 return myApp->getDelay();
1894}
1895
1896
1897void
1899 myApp->setDelay(delay);
1900}
1901
1902
1903void
1904GUISUMOAbstractView::setBreakpoints(const std::vector<SUMOTime>& breakpoints) {
1905 myApp->setBreakpoints(breakpoints);
1906}
1907
1908
1910 filename(),
1911 centerX(0),
1912 centerY(0),
1913 centerZ(0),
1914 width(0),
1915 height(0),
1916 altitude(0),
1917 rot(0),
1918 tilt(0),
1919 roll(0),
1920 layer(0),
1921 initialised(false),
1922 skip2D(false),
1923 screenRelative(false),
1924 glID(-1),
1925 image(nullptr) {
1926}
1927
1928
1929/****************************************************************************/
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:522
@ MID_CLOSE_LANE
close lane
Definition: GUIAppEnum.h:653
@ MID_CURSORDIALOG_FRONT
remove/select/mark front element
Definition: GUIAppEnum.h:437
@ MID_CLOSE_EDGE
close edge
Definition: GUIAppEnum.h:655
@ MID_SIMPLE_VIEW_COLORCHANGE
Informs the dialog about a value's change.
Definition: GUIAppEnum.h:618
@ MID_ADD_REROUTER
add rerouter
Definition: GUIAppEnum.h:657
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_JUNCTION
a junction
@ 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_CONTAINERFLOW
a person flow
@ 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_ERROR(msg)
Definition: MsgHandler.h:274
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
int gPrecisionGeo
Definition: StdDefs.cpp:26
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:71
T MAX2(T a, T b)
Definition: StdDefs.h:77
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:282
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 * getParent()
Returns the main window.
static const GUIGlID INVALID_ID
Definition: GUIGlObject.h:71
virtual double getClickPriority() const
Returns the priority of receiving mouse clicks.
Definition: GUIGlObject.h:159
virtual Boundary getCenteringBoundary() const =0
virtual void onLeftBtnPress(void *)
notify object about left click
Definition: GUIGlObject.h:213
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
Definition: GUIGlObject.h:154
GUIGlID getGlID() const
Returns the numerical id of the object.
Definition: GUIGlObject.h:102
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
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::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 *)
FXMutex myDecalsLock
The mutex to use before accessing the decals list in order to avoid thread conflicts.
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 openObjectDialog(const std::vector< GUIGlObject * > &objects)
open object dialog for the given object
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.
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
GUIDialog_ViewSettings * myVisualizationChanger
Visualization changer.
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 *)
GUIDialog_EditViewport * myViewportChooser
viewport chooser
bool myPanning
Panning flag.
bool isAdditionalGLVisualisationEnabled(GUIGlObject *const which) const
Check if an object is added in the additional GL visualitation.
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
bool removeAdditionalGLVisualisation(GUIGlObject *const which)
Removes an object from the list of objects that show additional things.
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
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
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)
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 *)
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
GUIGlChildWindow * myParent
The parent window.
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
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
Definition: GeoConvHelper.h:84
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
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:298
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
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition: SysUtils.cpp:47
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.
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values