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-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
19 // The base class for a view
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #include <config.h>
27 
28 #include <iostream>
29 #include <utility>
30 #include <cmath>
31 #include <cassert>
32 #include <limits>
33 #include <fxkeys.h>
34 #ifdef HAVE_GL2PS
35 #include <gl2ps.h>
36 #endif
40 #include <utils/common/RGBColor.h>
41 #include <utils/common/ToString.h>
48 #include <utils/gui/div/GLHelper.h>
56 #include <utils/geom/GeomHelper.h>
61 
62 #include "GUISUMOAbstractView.h"
63 #include "GUIMainWindow.h"
64 #include "GUIGlChildWindow.h"
66 #include "GUIDialog_EditViewport.h"
67 
68 #ifdef HAVE_GDAL
69 #if __GNUC__ > 3
70 #pragma GCC diagnostic push
71 #pragma GCC diagnostic ignored "-Wpedantic"
72 #endif
73 #include <gdal_priv.h>
74 #if __GNUC__ > 3
75 #pragma GCC diagnostic pop
76 #endif
77 #endif
78 
79 
80 // ===========================================================================
81 // debug constants
82 // ===========================================================================
83 //#define DEBUG_SNAPSHOT
84 
85 // ===========================================================================
86 // static members
87 // ===========================================================================
88 
89 const double GUISUMOAbstractView::SENSITIVITY = 0.1; // meters
90 
91 
92 // ===========================================================================
93 // member method definitions
94 // ===========================================================================
95 /* -------------------------------------------------------------------------
96  * GUISUMOAbstractView - FOX callback mapping
97  * ----------------------------------------------------------------------- */
98 FXDEFMAP(GUISUMOAbstractView) GUISUMOAbstractViewMap[] = {
99  FXMAPFUNC(SEL_CONFIGURE, 0, GUISUMOAbstractView::onConfigure),
100  FXMAPFUNC(SEL_PAINT, 0, GUISUMOAbstractView::onPaint),
101  FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, GUISUMOAbstractView::onLeftBtnPress),
102  FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, GUISUMOAbstractView::onLeftBtnRelease),
103  FXMAPFUNC(SEL_MIDDLEBUTTONPRESS, 0, GUISUMOAbstractView::onMiddleBtnPress),
104  FXMAPFUNC(SEL_MIDDLEBUTTONRELEASE, 0, GUISUMOAbstractView::onMiddleBtnRelease),
105  FXMAPFUNC(SEL_RIGHTBUTTONPRESS, 0, GUISUMOAbstractView::onRightBtnPress),
106  FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, 0, GUISUMOAbstractView::onRightBtnRelease),
107  FXMAPFUNC(SEL_DOUBLECLICKED, 0, GUISUMOAbstractView::onDoubleClicked),
108  FXMAPFUNC(SEL_MOUSEWHEEL, 0, GUISUMOAbstractView::onMouseWheel),
109  FXMAPFUNC(SEL_MOTION, 0, GUISUMOAbstractView::onMouseMove),
110  FXMAPFUNC(SEL_LEAVE, 0, GUISUMOAbstractView::onMouseLeft),
111  FXMAPFUNC(SEL_KEYPRESS, 0, GUISUMOAbstractView::onKeyPress),
112  FXMAPFUNC(SEL_KEYRELEASE, 0, GUISUMOAbstractView::onKeyRelease),
113 
114 };
115 
116 
117 FXIMPLEMENT_ABSTRACT(GUISUMOAbstractView, FXGLCanvas, GUISUMOAbstractViewMap, ARRAYNUMBER(GUISUMOAbstractViewMap))
118 
119 
120 /* -------------------------------------------------------------------------
121  * GUISUMOAbstractView - methods
122  * ----------------------------------------------------------------------- */
123 GUISUMOAbstractView::GUISUMOAbstractView(FXComposite* p, GUIMainWindow& app, GUIGlChildWindow* parent, const SUMORTree& grid, FXGLVisual* glVis, FXGLCanvas* share) :
124  FXGLCanvas(p, glVis, share, p, MID_GLCANVAS, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0),
125  myApp(&app),
126  myParent(parent),
127  myGrid(&((SUMORTree&)grid)),
128  myChanger(nullptr),
129  myMouseHotspotX(app.getDefaultCursor()->getHotX()),
130  myMouseHotspotY(app.getDefaultCursor()->getHotY()),
131  myPopup(nullptr),
132  myPopupPosition(Position(0, 0)),
133  myUseToolTips(false),
134  myAmInitialised(false),
135  myViewportChooser(nullptr),
136  myWindowCursorPositionX(getWidth() / 2),
137  myWindowCursorPositionY(getHeight() / 2),
138  myVisualizationChanger(nullptr) {
139  setTarget(this);
140  enable();
141  flags |= FLAG_ENABLED;
142  myInEditMode = false;
143  // show the middle at the beginning
144  myChanger = new GUIDanielPerspectiveChanger(*this, *myGrid);
145  myVisualizationSettings = &gSchemeStorage.getDefault();
146  myVisualizationSettings->gaming = myApp->isGaming();
148 }
149 
150 
154  delete myPopup;
155  delete myChanger;
156  delete myViewportChooser;
157  delete myVisualizationChanger;
158  // cleanup decals
159  for (std::vector<GUISUMOAbstractView::Decal>::iterator it = myDecals.begin(); it != myDecals.end(); ++it) {
160  delete it->image;
161  }
162 }
163 
164 
165 bool
167  return myInEditMode;
168 }
169 
170 
173  return *myChanger;
174 }
175 
176 
177 void
179  if (!myUseToolTips) {
180  return;
181  }
182  update();
183 }
184 
185 
186 Position
189 }
190 
191 
192 Position
194  Position result = pos;
196  if (pos.z() == 0) {
197  const double xRest = std::fmod(pos.x(), myVisualizationSettings->gridXSize) + (pos.x() < 0 ? myVisualizationSettings->gridXSize : 0);
198  const double yRest = std::fmod(pos.y(), myVisualizationSettings->gridYSize) + (pos.y() < 0 ? myVisualizationSettings->gridYSize : 0);
199  result.setx(pos.x() - xRest + (xRest < myVisualizationSettings->gridXSize * 0.5 ? 0 : myVisualizationSettings->gridXSize));
200  result.sety(pos.y() - yRest + (yRest < myVisualizationSettings->gridYSize * 0.5 ? 0 : myVisualizationSettings->gridYSize));
201  } else {
202  // snapZToActiveGrid uses grid Y Size
203  const double zRest = std::fmod(pos.z(), myVisualizationSettings->gridYSize) + (pos.z() < 0 ? myVisualizationSettings->gridYSize : 0);
204  result.setz(pos.z() - zRest + (zRest < myVisualizationSettings->gridYSize * 0.5 ? 0 : myVisualizationSettings->gridYSize));
205  }
206  }
207  return result;
208 }
209 
210 
211 Position
213  Boundary bound = myChanger->getViewport();
214  double xNet = bound.xmin() + bound.getWidth() * x / getWidth();
215  // cursor origin is in the top-left corner
216  double yNet = bound.ymin() + bound.getHeight() * (getHeight() - y) / getHeight();
217  // rotate around the viewport center
218  if (myChanger->getRotation() != 0) {
219  return Position(xNet, yNet).rotateAround2D(-DEG2RAD(myChanger->getRotation()), bound.getCenter());
220  } else {
221  return Position(xNet, yNet);
222  }
223 }
224 
225 
226 void
227 GUISUMOAbstractView::addDecals(const std::vector<Decal>& decals) {
228  myDecals.insert(myDecals.end(), decals.begin(), decals.end());
229 }
230 
231 
235 }
236 
237 
238 void
241  std::string text = "x:" + toString(pos.x()) + ", y:" + toString(pos.y());
242  myApp->getCartesianLabel().setText(text.c_str());
244  if (GeoConvHelper::getFinal().usingGeoProjection()) {
245  text = "lat:" + toString(pos.y(), gPrecisionGeo) + ", lon:" + toString(pos.x(), gPrecisionGeo);
246  } else {
247  text = "x:" + toString(pos.x()) + ", y:" + toString(pos.y());
248  }
249  myApp->getGeoLabel().setText(text.c_str());
250 }
251 
252 
253 int
254 GUISUMOAbstractView::doPaintGL(int /*mode*/, const Boundary& /*boundary*/) {
255  return 0;
256 }
257 
258 
259 void
261 }
262 
263 
264 Boundary
266  return myChanger->getViewport();
267 }
268 
269 
270 void
272  if (getWidth() == 0 || getHeight() == 0) {
273  return;
274  }
275 
277  centerTo(getTrackedID(), false);
278  }
279 
281  if (myUseToolTips) {
282  id = getObjectUnderCursor();
283  }
284 
285  // draw
286  glClearColor(
291  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
292  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
293 
295  glEnable(GL_DITHER);
296  } else {
297  glDisable(GL_DITHER);
298  }
299  glEnable(GL_BLEND);
300  glDisable(GL_LINE_SMOOTH);
301 
302  Boundary bound = applyGLTransform();
303  doPaintGL(GL_RENDER, bound);
305  displayLegend();
306  }
307  // check whether the select mode /tooltips)
308  // shall be computed, too
309  if (myUseToolTips && id != GUIGlObject::INVALID_ID) {
310  showToolTipFor(id);
311  }
312  swapBuffers();
313 }
314 
315 
316 GUIGlID
319 }
320 
321 
322 std::vector<GUIGlID>
324 
326 }
327 
328 
329 std::vector<GUIGlObject*>
332 }
333 
334 
335 GUIGlID
337  Boundary selection;
338  selection.add(pos);
339  selection.grow(SENSITIVITY);
340  const std::vector<GUIGlID> ids = getObjectsInBoundary(selection);
341  // Interpret results
342  int idMax = 0;
343  double maxLayer = -std::numeric_limits<double>::max();
344  // iterate over obtained GUIGlIDs
345  for (const auto &i : ids) {
346  // obtain GUIGlObject
348  // check that GUIGlObject exist
349  if (o == nullptr) {
350  continue;
351  }
352  // check that GUIGlObject isn't the network
353  if (o->getGlID() == 0) {
354  continue;
355  }
356  //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
357  GUIGlObjectType type = o->getType();
358  // avoid network
359  if (type != GLO_NETWORK) {
360  double layer = (double)type;
361  // determine an "abstract" layer for shapes
362  // this "layer" resembles the layer of the shape
363  // taking into account the stac of other objects
364  if (type == GLO_POI || type == GLO_POLYGON) {
365  layer = dynamic_cast<Shape*>(o)->getShapeLayer();
366  }
368  // do not select lanes in meso mode
369  continue;
370  }
371  // check whether the current object is above a previous one
372  if (layer > maxLayer) {
373  idMax = i;
374  maxLayer = layer;
375  }
376  }
377  // unblock object
379  }
380  return idMax;
381 }
382 
383 
384 std::vector<GUIGlID>
386  // declare result vector
387  std::vector<GUIGlID> result;
388  // calculate boundary
389  Boundary selection;
390  selection.add(pos);
391  selection.grow(radius);
392  // obtain GUIGlID of objects in boundary
393  const std::vector<GUIGlID> ids = getObjectsInBoundary(selection);
394  // iterate over obtained GUIGlIDs
395  for (const auto &i : ids) {
396  // obtain GUIGlObject
398  // check that GUIGlObject exist
399  if (o == nullptr) {
400  continue;
401  }
402  // check that GUIGlObject isn't the network
403  if (o->getGlID() == 0) {
404  continue;
405  }
406  //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
407  GUIGlObjectType type = o->getType();
408  // avoid network
409  if (type != GLO_NETWORK) {
410  result.push_back(i);
411  }
412  // unblock object
414  }
415  return result;
416 }
417 
418 
419 std::vector<GUIGlObject*>
421  // declare result vector
422  std::vector<GUIGlObject*> result;
423  // calculate boundary
424  Boundary selection;
425  selection.add(pos);
426  selection.grow(radius);
427  // obtain GUIGlID of objects in boundary
428  const std::vector<GUIGlID> ids = getObjectsInBoundary(selection);
429  // iterate over obtained GUIGlIDs
430  for (const auto &i : ids) {
431  // obtain GUIGlObject
433  // check that GUIGlObject exist
434  if (o == nullptr) {
435  continue;
436  }
437  // check that GUIGlObject isn't the network
438  if (o->getGlID() == 0) {
439  continue;
440  }
441  result.push_back(o);
442  // unblock object
444  }
445  return result;
446 }
447 
448 
449 std::vector<GUIGlID>
451  const int NB_HITS_MAX = 1024 * 1024;
452  // Prepare the selection mode
453  static GUIGlID hits[NB_HITS_MAX];
454  static GLint nb_hits = 0;
455  glSelectBuffer(NB_HITS_MAX, hits);
456  glInitNames();
457 
458  Boundary oldViewPort = myChanger->getViewport(false); // backup the actual viewPort
459  myChanger->setViewport(bound);
460  bound = applyGLTransform(false);
461 
462  // paint in select mode
464  int hits2 = doPaintGL(GL_SELECT, bound);
466  // Get the results
467  nb_hits = glRenderMode(GL_RENDER);
468  if (nb_hits == -1) {
469  myApp->setStatusBarText("Selection in boundary failed. Try to select fewer than " + toString(hits2) + " items");
470  }
471  std::vector<GUIGlID> result;
472  GLuint numNames;
473  GLuint* ptr = hits;
474  for (int i = 0; i < nb_hits; ++i) {
475  numNames = *ptr;
476  ptr += 3;
477  for (int j = 0; j < (int)numNames; j++) {
478  result.push_back(*ptr);
479  ptr++;
480  }
481  }
482  // switch viewport back to normal
483  myChanger->setViewport(oldViewPort);
484  return result;
485 }
486 
487 
488 void
490  if (id != 0) {
492  if (object != nullptr) {
494  pos.add(0, p2m(15));
495  std::string label = object->getFullName();
497  (object->getType() == GLO_EDGE || object->getType() == GLO_LANE)) {
498  const int activeScheme = myVisualizationSettings->getLaneEdgeMode();
499  label += " (" + toString(object->getColorValue(*myVisualizationSettings, activeScheme)) + ")";
500  }
501  GLHelper::drawTextBox(label, pos, GLO_MAX - 1, p2m(20), RGBColor::BLACK, RGBColor(255, 179, 0, 255));
503  }
504  }
505 }
506 
507 
508 void
510  // obtain minimum grid
512  // Check if the distance is enought to draw grid
514  glEnable(GL_DEPTH_TEST);
515  glLineWidth(1);
516  // get multiplication values (2 is the marging)
517  int multXmin = (int)(myChanger->getViewport().xmin() / myVisualizationSettings->gridXSize) - 2;
518  int multYmin = (int)(myChanger->getViewport().ymin() / myVisualizationSettings->gridYSize) - 2;
519  int multXmax = (int)(myChanger->getViewport().xmax() / myVisualizationSettings->gridXSize) + 2;
520  int multYmax = (int)(myChanger->getViewport().ymax() / myVisualizationSettings->gridYSize) + 2;
521  // obtain references
522  double xmin = myVisualizationSettings->gridXSize * multXmin;
523  double ymin = myVisualizationSettings->gridYSize * multYmin;
524  double xmax = myVisualizationSettings->gridXSize * multXmax;
525  double ymax = myVisualizationSettings->gridYSize * multYmax;
526  double xpos = xmin;
527  double ypos = ymin;
528  // move drawing matrix
529  glTranslated(0, 0, .55);
530  glColor3d(0.5, 0.5, 0.5);
531  // draw horizontal lines
532  glBegin(GL_LINES);
533  while (ypos <= ymax) {
534  glVertex2d(xmin, ypos);
535  glVertex2d(xmax, ypos);
537  }
538  // draw vertical lines
539  while (xpos <= xmax) {
540  glVertex2d(xpos, ymin);
541  glVertex2d(xpos, ymax);
543  }
544  glEnd();
545  glTranslated(0, 0, -.55);
546  }
547 }
548 
549 
550 void
552  // compute the scale bar length
553  int length = 1;
554  const std::string text("10000000000");
555  int noDigits = 1;
556  int pixelSize = (int) m2p((double) length);
557  while (pixelSize <= 20) {
558  length *= 10;
559  noDigits++;
560  if (noDigits > (int)text.length()) {
561  return;
562  }
563  pixelSize = (int) m2p((double) length);
564  }
565  glLineWidth(1.0);
566 
567  glMatrixMode(GL_PROJECTION);
568  glPushMatrix();
569  glLoadIdentity();
570  glMatrixMode(GL_MODELVIEW);
571  glPushMatrix();
572  glLoadIdentity();
573 
574  // draw the scale bar
575  const double z = -1;
576  glDisable(GL_TEXTURE_2D);
577  glDisable(GL_ALPHA_TEST);
578  glDisable(GL_BLEND);
579  glEnable(GL_DEPTH_TEST);
580  glPushMatrix();
581  glTranslated(0, 0, z);
582 
583  double len = (double) pixelSize / (double)(getWidth() - 1) * (double) 2.0;
584  glColor3d(0, 0, 0);
585  double o = double(15) / double(getHeight());
586  double o2 = o + o;
587  double oo = double(5) / double(getHeight());
588  glBegin(GL_LINES);
589  // vertical
590  glVertex2d(-.98, -1. + o);
591  glVertex2d(-.98 + len, -1. + o);
592  // tick at begin
593  glVertex2d(-.98, -1. + o);
594  glVertex2d(-.98, -1. + o2);
595  // tick at end
596  glVertex2d(-.98 + len, -1. + o);
597  glVertex2d(-.98 + len, -1. + o2);
598  glEnd();
599  glPopMatrix();
600 
601  const double fontHeight = 0.1 * 300. / getHeight();
602  const double fontWidth = 0.1 * 300. / getWidth();
603  // draw 0
604  GLHelper::drawText("0", Position(-.99, -0.99 + o2 + oo), z, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT, fontWidth);
605 
606  // draw current scale
607  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);
608 
609  // restore matrices
610  glMatrixMode(GL_PROJECTION);
611  glPopMatrix();
612  glMatrixMode(GL_MODELVIEW);
613  glPopMatrix();
614 }
615 
616 
617 double
618 GUISUMOAbstractView::m2p(double meter) const {
619  return meter * getWidth() / myChanger->getViewport().getWidth();
620 }
621 
622 
623 double
624 GUISUMOAbstractView::p2m(double pixel) const {
625  return pixel * myChanger->getViewport().getWidth() / getWidth();
626 }
627 
628 
629 void
632 }
633 
634 
635 void
636 GUISUMOAbstractView::centerTo(GUIGlID id, bool applyZoom, double zoomDist) {
638  if (o != nullptr && dynamic_cast<GUIGlObject*>(o) != nullptr) {
639  if (applyZoom && zoomDist < 0) {
641  update(); // only update when centering onto an object once
642  } else {
643  // called during tracking. update is triggered somewhere else
644  myChanger->centerTo(o->getCenteringBoundary().getCenter(), zoomDist, applyZoom);
646  }
647  }
649 }
650 
651 
652 void
654  myChanger->setViewport(bound);
655  update();
656 }
657 
658 /*
659 bool
660 GUISUMOAbstractView::allowRotation() const
661 {
662  return myParent->allowRotation();
663 }
664 */
665 
666 void
670 }
671 
672 
673 FXbool
675  FXbool ret = FXGLCanvas::makeCurrent();
676  return ret;
677 }
678 
679 
680 long
681 GUISUMOAbstractView::onConfigure(FXObject*, FXSelector, void*) {
682  if (makeCurrent()) {
683  glViewport(0, 0, getWidth() - 1, getHeight() - 1);
684  glClearColor(
689  doInit();
690  myAmInitialised = true;
691  makeNonCurrent();
692  checkSnapshots();
693  }
694  return 1;
695 }
696 
697 
698 long
699 GUISUMOAbstractView::onPaint(FXObject*, FXSelector, void*) {
700  if (!isEnabled() || !myAmInitialised) {
701  return 1;
702  }
703  if (makeCurrent()) {
704  paintGL();
705  makeNonCurrent();
706  }
707  return 1;
708 }
709 
710 
711 const Position&
713  return myPopupPosition;
714 }
715 
716 void
718  if (myPopup != nullptr) {
719  delete myPopup;
720  myPopupPosition.set(0, 0);
721  myPopup = nullptr;
722  }
723 }
724 
725 
726 long
727 GUISUMOAbstractView::onLeftBtnPress(FXObject*, FXSelector , void* data) {
728  destroyPopup();
729  setFocus();
730  FXEvent* e = (FXEvent*) data;
731  // check whether the selection-mode is activated
732  if ((e->state & CONTROLMASK) != 0) {
733  // try to get the object-id if so
734  if (makeCurrent()) {
735  int id = getObjectUnderCursor();
736  if (id != 0) {
738  }
739  makeNonCurrent();
740  if (id != 0) {
741  // possibly, the selection-colouring is used,
742  // so we should update the screen again...
743  update();
744  }
745  }
746  }
747  myChanger->onLeftBtnPress(data);
748  grab();
749  // Check there are double click
750  if (e->click_count == 2) {
751  handle(this, FXSEL(SEL_DOUBLECLICKED, 0), data);
752  }
753  return 1;
754 }
755 
756 
757 long
758 GUISUMOAbstractView::onLeftBtnRelease(FXObject*, FXSelector , void* data) {
759  destroyPopup();
761  if (myApp->isGaming()) {
763  }
764  ungrab();
765  return 1;
766 }
767 
768 
769 long
770 GUISUMOAbstractView::onMiddleBtnPress(FXObject*, FXSelector, void*) {
771  return 1;
772 }
773 
774 
775 long
776 GUISUMOAbstractView::onMiddleBtnRelease(FXObject*, FXSelector, void*) {
777  return 1;
778 }
779 
780 
781 long
782 GUISUMOAbstractView::onRightBtnPress(FXObject*, FXSelector , void* data) {
783  destroyPopup();
784  myChanger->onRightBtnPress(data);
785  grab();
786  return 1;
787 }
788 
789 
790 long
791 GUISUMOAbstractView::onRightBtnRelease(FXObject* o, FXSelector sel, void* data) {
792  destroyPopup();
793  onMouseMove(o, sel, data);
794  if (!myChanger->onRightBtnRelease(data) && !myApp->isGaming()) {
796  }
797  ungrab();
798  return 1;
799 }
800 
801 
802 long
803 GUISUMOAbstractView::onDoubleClicked(FXObject*, FXSelector, void*) {
804  return 1;
805 }
806 
807 
808 long
809 GUISUMOAbstractView::onMouseWheel(FXObject*, FXSelector , void* data) {
810  if (!myApp->isGaming()) {
811  myChanger->onMouseWheel(data);
812  // upddate viewport
813  if (myViewportChooser != nullptr) {
817  }
819  }
820  return 1;
821 }
822 
823 
824 long
825 GUISUMOAbstractView::onMouseMove(FXObject*, FXSelector , void* data) {
826  // if popup exist but isn't shown, destroy it first
827  if (myPopup && (myPopup->shown() == false)) {
828  destroyPopup();
829  }
830  if (myPopup == nullptr) {
831  if (myViewportChooser == nullptr || !myViewportChooser->haveGrabbed()) {
832  myChanger->onMouseMove(data);
833  }
834  if (myViewportChooser != nullptr) {
838  }
840  }
841  return 1;
842 }
843 
844 
845 long
846 GUISUMOAbstractView::onMouseLeft(FXObject*, FXSelector , void* /*data*/) {
847  return 1;
848 }
849 
850 
851 void
853  ungrab();
854  if (!isEnabled() || !myAmInitialised) {
855  return;
856  }
857  if (makeCurrent()) {
858  // initialise the select mode
859  int id = getObjectUnderCursor();
860  GUIGlObject* o = nullptr;
861  if (id != 0) {
863  } else {
865  }
866  if (o != nullptr) {
867  myPopup = o->getPopUpMenu(*myApp, *this);
868  int x, y;
869  FXuint b;
870  myApp->getCursorPosition(x, y, b);
871  myPopup->setX(x + myApp->getX());
872  myPopup->setY(y + myApp->getY());
873  myPopup->create();
874  myPopup->show();
876  myChanger->onRightBtnRelease(nullptr);
878  setFocus();
879  }
880  makeNonCurrent();
881  }
882 }
883 
884 
885 long
886 GUISUMOAbstractView::onKeyPress(FXObject* o, FXSelector sel, void* data) {
887  if (myPopup != nullptr) {
888  return myPopup->onKeyPress(o, sel, data);
889  } else {
890  FXGLCanvas::onKeyPress(o, sel, data);
891  return myChanger->onKeyPress(data);
892  }
893 }
894 
895 
896 long
897 GUISUMOAbstractView::onKeyRelease(FXObject* o, FXSelector sel, void* data) {
898  if (myPopup != nullptr) {
899  return myPopup->onKeyRelease(o, sel, data);
900  } else {
901  FXGLCanvas::onKeyRelease(o, sel, data);
902  return myChanger->onKeyRelease(data);
903  }
904 }
905 
906 
907 // ------------ Dealing with snapshots
908 void
909 GUISUMOAbstractView::addSnapshot(SUMOTime time, const std::string& file, const int width, const int height) {
910 #ifdef DEBUG_SNAPSHOT
911  std::cout << "add snapshot time=" << time << " file=" << file << "\n";
912 #endif
913  FXMutexLock lock(mySnapshotsMutex);
914  mySnapshots[time].push_back(std::make_tuple(file, width, height));
915 }
916 
917 
918 std::string
919 GUISUMOAbstractView::makeSnapshot(const std::string& destFile, const int width, const int height) {
920  if (width >= 0) {
921  resize(width, height);
922  repaint();
923  }
924  std::string errorMessage;
925  FXString ext = FXPath::extension(destFile.c_str());
926  const bool useGL2PS = ext == "ps" || ext == "eps" || ext == "pdf" || ext == "svg" || ext == "tex" || ext == "pgf";
927 #ifdef HAVE_FFMPEG
928  const bool useVideo = destFile == "" || ext == "h264" || ext == "hevc";
929 #endif
930  for (int i = 0; i < 10 && !makeCurrent(); ++i) {
932  }
933  // draw
934  glClearColor(
939  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
940  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
941 
943  glEnable(GL_DITHER);
944  } else {
945  glDisable(GL_DITHER);
946  }
947  glEnable(GL_BLEND);
948  glDisable(GL_LINE_SMOOTH);
949 
951 
952  if (useGL2PS) {
953 #ifdef HAVE_GL2PS
954  GLint format = GL2PS_PS;
955  if (ext == "ps") {
956  format = GL2PS_PS;
957  } else if (ext == "eps") {
958  format = GL2PS_EPS;
959  } else if (ext == "pdf") {
960  format = GL2PS_PDF;
961  } else if (ext == "tex") {
962  format = GL2PS_TEX;
963  } else if (ext == "svg") {
964  format = GL2PS_SVG;
965  } else if (ext == "pgf") {
966  format = GL2PS_PGF;
967  } else {
968  return "Could not save '" + destFile + "'.\n Unrecognized format '" + std::string(ext.text()) + "'.";
969  }
970  FILE* fp = fopen(destFile.c_str(), "wb");
971  if (fp == 0) {
972  return "Could not save '" + destFile + "'.\n Could not open file for writing";
973  }
974  GLint buffsize = 0, state = GL2PS_OVERFLOW;
975  GLint viewport[4];
976  glGetIntegerv(GL_VIEWPORT, viewport);
977  while (state == GL2PS_OVERFLOW) {
978  buffsize += 1024 * 1024;
979  gl2psBeginPage(destFile.c_str(), "sumo-gui; http://sumo.dlr.de", viewport, format, GL2PS_SIMPLE_SORT,
980  GL2PS_DRAW_BACKGROUND | GL2PS_USE_CURRENT_VIEWPORT,
981  GL_RGBA, 0, NULL, 0, 0, 0, buffsize, fp, "out.eps");
982  glMatrixMode(GL_MODELVIEW);
983  glPushMatrix();
984  glDisable(GL_TEXTURE_2D);
985  glDisable(GL_ALPHA_TEST);
986  glDisable(GL_BLEND);
987  glEnable(GL_DEPTH_TEST);
988  // draw decals (if not in grabbing mode)
989  if (!myUseToolTips) {
990  drawDecals();
992  paintGLGrid();
993  }
994  }
995  glLineWidth(1);
996  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
997  Boundary viewPort = myChanger->getViewport();
998  const float minB[2] = { (float)viewPort.xmin(), (float)viewPort.ymin() };
999  const float maxB[2] = { (float)viewPort.xmax(), (float)viewPort.ymax() };
1001  glEnable(GL_POLYGON_OFFSET_FILL);
1002  glEnable(GL_POLYGON_OFFSET_LINE);
1003  myGrid->Search(minB, maxB, *myVisualizationSettings);
1004 
1006  displayLegend();
1007  }
1008  state = gl2psEndPage();
1009  glFinish();
1010  }
1011  fclose(fp);
1012 #else
1013  return "Could not save '" + destFile + "', gl2ps was not enabled at compile time.";
1014 #endif
1015  } else {
1016  doPaintGL(GL_RENDER, myChanger->getViewport());
1018  displayLegend();
1019  }
1020  swapBuffers();
1021  glFinish();
1022  FXColor* buf;
1023  FXMALLOC(&buf, FXColor, getWidth()*getHeight());
1024  // read from the back buffer
1025  glReadBuffer(GL_BACK);
1026  // Read the pixels
1027  glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)buf);
1028  makeNonCurrent();
1029  update();
1030  // mirror
1031  int mwidth = getWidth();
1032  int mheight = getHeight();
1033  FXColor* paa = buf;
1034  FXColor* pbb = buf + mwidth * (mheight - 1);
1035  do {
1036  FXColor* pa = paa;
1037  paa += mwidth;
1038  FXColor* pb = pbb;
1039  pbb -= mwidth;
1040  do {
1041  FXColor t = *pa;
1042  *pa++ = *pb;
1043  *pb++ = t;
1044  } while (pa < paa);
1045  } while (paa < pbb);
1046  try {
1047 #ifdef HAVE_FFMPEG
1048  if (useVideo) {
1049  try {
1050  saveFrame(destFile, buf);
1051  errorMessage = "video";
1052  } catch (std::runtime_error& err) {
1053  errorMessage = err.what();
1054  }
1055  } else
1056 #endif
1057  if (!MFXImageHelper::saveImage(destFile, getWidth(), getHeight(), buf)) {
1058  errorMessage = "Could not save '" + destFile + "'.";
1059  }
1060  } catch (InvalidArgument& e) {
1061  errorMessage = "Could not save '" + destFile + "'.\n" + e.what();
1062  }
1063  FXFREE(&buf);
1064  }
1065  return errorMessage;
1066 }
1067 
1068 
1069 void
1070 GUISUMOAbstractView::saveFrame(const std::string& destFile, FXColor* buf) {
1071  UNUSED_PARAMETER(destFile);
1072  UNUSED_PARAMETER(buf);
1073 }
1074 
1075 
1076 void
1078  const SUMOTime time = getCurrentTimeStep() - DELTA_T;
1079 #ifdef DEBUG_SNAPSHOT
1080  std::cout << "check snapshots time=" << time << " registeredTimes=" << mySnapshots.size() << "\n";
1081 #endif
1082  FXMutexLock lock(mySnapshotsMutex);
1083  const auto snapIt = mySnapshots.find(time);
1084  if (snapIt == mySnapshots.end()) {
1085  return;
1086  }
1087  std::vector<std::tuple<std::string, int, int> > files = snapIt->second;
1088  lock.unlock();
1089  // decouple map access and painting to avoid deadlock
1090  for (const auto& entry : files) {
1091 #ifdef DEBUG_SNAPSHOT
1092  std::cout << "make snapshot time=" << time << " file=" << file << "\n";
1093 #endif
1094  const std::string& error = makeSnapshot(std::get<0>(entry), std::get<1>(entry), std::get<2>(entry));
1095  if (error != "" && error != "video") {
1096  WRITE_WARNING(error);
1097  }
1098  }
1099  // synchronization with a waiting run thread
1100  lock.lock();
1101  mySnapshots.erase(time);
1102  mySnapshotCondition.signal();
1103 #ifdef DEBUG_SNAPSHOT
1104  std::cout << " files=" << toString(files) << " myApplicationSnapshots=" << joinToString(*myApplicationSnapshots, ",") << "\n";
1105 #endif
1106 }
1107 
1108 
1109 void
1111  FXMutexLock lock(mySnapshotsMutex);
1112  if (mySnapshots.count(snapshotTime) > 0) {
1114  }
1115 }
1116 
1117 
1118 SUMOTime
1120  return 0;
1121 }
1122 
1123 
1124 void
1126  if (myVisualizationChanger == nullptr) {
1130  &myDecals, &myDecalsLock);
1131  myVisualizationChanger->create();
1132  } else {
1134  }
1136 }
1137 
1138 
1141  if (myViewportChooser == nullptr) {
1142  const FXint minSize = 100;
1143  const FXint minTitlebarHeight = 20;
1144  int x = MAX2(0, MIN2(getApp()->reg().readIntEntry(
1145  "VIEWPORT_DIALOG_SETTINGS", "x", 150),
1146  getApp()->getRootWindow()->getWidth() - minSize));
1147  int y = MAX2(minTitlebarHeight, MIN2(getApp()->reg().readIntEntry(
1148  "VIEWPORT_DIALOG_SETTINGS", "y", 150),
1149  getApp()->getRootWindow()->getHeight() - minSize));
1150  myViewportChooser = new GUIDialog_EditViewport(this, "Edit Viewport", x, y);
1151  myViewportChooser->create();
1152  }
1155  myChanger->getRotation());
1156  return myViewportChooser;
1157 }
1158 
1159 
1160 void
1162  getViewportEditor(); // make sure it exists;
1166 }
1167 
1168 
1169 void
1170 GUISUMOAbstractView::setViewportFromToRot(const Position& lookFrom, const Position& /* lookAt */, double rotation) {
1171  myChanger->setViewportFrom(lookFrom.x(), lookFrom.y(), lookFrom.z());
1172  myChanger->setRotation(rotation);
1173  update();
1174 }
1175 
1176 
1177 void
1179  // look straight down
1182  myChanger->getRotation());
1183 }
1184 
1185 
1186 void
1188  myUseToolTips = val;
1189 }
1190 
1191 
1192 bool
1194  return true;
1195 }
1196 
1197 
1200  return myVisualizationSettings;
1201 }
1202 
1203 
1204 void
1206  myViewportChooser = nullptr;
1207 }
1208 
1209 
1210 void
1212  myVisualizationChanger = nullptr;
1213 }
1214 
1215 
1216 double
1218  return myGrid->getWidth();
1219 }
1220 
1221 
1222 double
1224  return myGrid->getHeight();
1225 }
1226 
1227 
1228 void
1230 }
1231 
1232 
1233 void
1235 }
1236 
1237 
1238 GUIGlID
1240  return GUIGlObject::INVALID_ID;
1241 }
1242 
1243 
1244 void
1246 }
1247 
1248 
1249 FXComboBox&
1252 }
1253 
1254 
1255 FXImage*
1257 #ifdef HAVE_GDAL
1258  GDALAllRegister();
1259  GDALDataset* poDataset = (GDALDataset*)GDALOpen(d.filename.c_str(), GA_ReadOnly);
1260  if (poDataset == 0) {
1261  return 0;
1262  }
1263  const int xSize = poDataset->GetRasterXSize();
1264  const int ySize = poDataset->GetRasterYSize();
1265  // checking for geodata in the picture and try to adapt position and scale
1266  if (d.width <= 0.) {
1267  double adfGeoTransform[6];
1268  if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) {
1269  Position topLeft(adfGeoTransform[0], adfGeoTransform[3]);
1270  const double horizontalSize = xSize * adfGeoTransform[1];
1271  const double verticalSize = ySize * adfGeoTransform[5];
1272  Position bottomRight(topLeft.x() + horizontalSize, topLeft.y() + verticalSize);
1274  d.width = bottomRight.x() - topLeft.x();
1275  d.height = topLeft.y() - bottomRight.y();
1276  d.centerX = (topLeft.x() + bottomRight.x()) / 2;
1277  d.centerY = (topLeft.y() + bottomRight.y()) / 2;
1278  //WRITE_MESSAGE("proj: " + toString(poDataset->GetProjectionRef()) + " dim: " + toString(d.width) + "," + toString(d.height) + " center: " + toString(d.centerX) + "," + toString(d.centerY));
1279  } else {
1280  WRITE_WARNING("Could not convert coordinates in " + d.filename + ".");
1281  }
1282  }
1283  }
1284 #endif
1285  if (d.width <= 0.) {
1286  d.width = getGridWidth();
1287  d.height = getGridHeight();
1288  }
1289 
1290  // trying to read the picture
1291 #ifdef HAVE_GDAL
1292  const int picSize = xSize * ySize;
1293  FXColor* result;
1294  if (!FXMALLOC(&result, FXColor, picSize)) {
1295  WRITE_WARNING("Could not allocate memory for " + d.filename + ".");
1296  return 0;
1297  }
1298  for (int j = 0; j < picSize; j++) {
1299  result[j] = FXRGB(0, 0, 0);
1300  }
1301  bool valid = true;
1302  for (int i = 1; i <= poDataset->GetRasterCount(); i++) {
1303  GDALRasterBand* poBand = poDataset->GetRasterBand(i);
1304  int shift = -1;
1305  if (poBand->GetColorInterpretation() == GCI_RedBand) {
1306  shift = 0;
1307  } else if (poBand->GetColorInterpretation() == GCI_GreenBand) {
1308  shift = 1;
1309  } else if (poBand->GetColorInterpretation() == GCI_BlueBand) {
1310  shift = 2;
1311  } else if (poBand->GetColorInterpretation() == GCI_AlphaBand) {
1312  shift = 3;
1313  } else {
1314  WRITE_MESSAGE("Unknown color band in " + d.filename + ", maybe fox can parse it.");
1315  valid = false;
1316  break;
1317  }
1318  assert(xSize == poBand->GetXSize() && ySize == poBand->GetYSize());
1319  if (poBand->RasterIO(GF_Read, 0, 0, xSize, ySize, ((unsigned char*)result) + shift, xSize, ySize, GDT_Byte, 4, 4 * xSize) == CE_Failure) {
1320  valid = false;
1321  break;
1322  }
1323  }
1324  GDALClose(poDataset);
1325  if (valid) {
1326  return new FXImage(getApp(), result, IMAGE_OWNED | IMAGE_KEEP | IMAGE_SHMI | IMAGE_SHMP, xSize, ySize);
1327  }
1328  FXFREE(&result);
1329 #endif
1330  return nullptr;
1331 }
1332 
1333 
1334 void
1336  glPushName(0);
1337  myDecalsLock.lock();
1338  for (std::vector<GUISUMOAbstractView::Decal>::iterator l = myDecals.begin(); l != myDecals.end(); ++l) {
1340  if (d.skip2D) {
1341  continue;
1342  }
1343  if (!d.initialised) {
1344  try {
1345  FXImage* img = checkGDALImage(d);
1346  if (img == nullptr) {
1347  img = MFXImageHelper::loadImage(getApp(), d.filename);
1348  }
1350  d.glID = GUITexturesHelper::add(img);
1351  d.initialised = true;
1352  d.image = img;
1353  } catch (InvalidArgument& e) {
1354  WRITE_ERROR("Could not load '" + d.filename + "'.\n" + e.what());
1355  d.skip2D = true;
1356  }
1357  }
1358  glPushMatrix();
1359  if (d.screenRelative) {
1360  Position center = screenPos2NetPos((int)d.centerX, (int)d.centerY);
1361  glTranslated(center.x(), center.y(), d.layer);
1362  } else {
1363  glTranslated(d.centerX, d.centerY, d.layer);
1364  }
1365  glRotated(d.rot, 0, 0, 1);
1366  glColor3d(1, 1, 1);
1367  double halfWidth = d.width / 2.;
1368  double halfHeight = d.height / 2.;
1369  if (d.screenRelative) {
1370  halfWidth = p2m(halfWidth);
1371  halfHeight = p2m(halfHeight);
1372  }
1373  GUITexturesHelper::drawTexturedBox(d.glID, -halfWidth, -halfHeight, halfWidth, halfHeight);
1374  glPopMatrix();
1375  }
1376  myDecalsLock.unlock();
1377  glPopName();
1378 }
1379 
1380 
1381 // ------------ Additional visualisations
1382 bool
1384  if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1385  myAdditionallyDrawn[which] = 1;
1386  } else {
1387  myAdditionallyDrawn[which] = myAdditionallyDrawn[which] + 1;
1388  }
1389  update();
1390  return true;
1391 }
1392 
1393 
1394 bool
1396  if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1397  return false;
1398  }
1399  int cnt = myAdditionallyDrawn[which];
1400  if (cnt == 1) {
1401  myAdditionallyDrawn.erase(which);
1402  } else {
1403  myAdditionallyDrawn[which] = myAdditionallyDrawn[which] - 1;
1404  }
1405  update();
1406  return true;
1407 }
1408 
1409 
1410 bool
1412  if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1413  return false;
1414  } else {
1415  return true;
1416  }
1417 }
1418 
1419 
1420 Boundary
1422  Boundary bound = myChanger->getViewport(fixRatio);
1423  glMatrixMode(GL_PROJECTION);
1424  glLoadIdentity();
1425  // as a rough rule, each GLObject is drawn at z = -GUIGlObjectType
1426  // thus, objects with a higher value will be closer (drawn on top)
1427  // // @todo last param should be 0 after modifying all glDraw methods
1428  glOrtho(0, getWidth(), 0, getHeight(), -GLO_MAX - 1, GLO_MAX + 1);
1429  glMatrixMode(GL_MODELVIEW);
1430  glLoadIdentity();
1431  double scaleX = (double)getWidth() / bound.getWidth();
1432  double scaleY = (double)getHeight() / bound.getHeight();
1433  glScaled(scaleX, scaleY, 1);
1434  glTranslated(-bound.xmin(), -bound.ymin(), 0);
1435  // rotate around the center of the screen
1436  //double angle = -90;
1437  if (myChanger->getRotation() != 0) {
1438  glTranslated(bound.getCenter().x(), bound.getCenter().y(), 0);
1439  glRotated(myChanger->getRotation(), 0, 0, 1);
1440  glTranslated(-bound.getCenter().x(), -bound.getCenter().y(), 0);
1441  Boundary rotBound;
1442  double rad = -DEG2RAD(myChanger->getRotation());
1443  rotBound.add(Position(bound.xmin(), bound.ymin()).rotateAround2D(rad, bound.getCenter()));
1444  rotBound.add(Position(bound.xmin(), bound.ymax()).rotateAround2D(rad, bound.getCenter()));
1445  rotBound.add(Position(bound.xmax(), bound.ymin()).rotateAround2D(rad, bound.getCenter()));
1446  rotBound.add(Position(bound.xmax(), bound.ymax()).rotateAround2D(rad, bound.getCenter()));
1447  bound = rotBound;
1449  }
1450  return bound;
1451 }
1452 
1453 
1454 double
1456  return myApp->getDelay();
1457 }
1458 
1459 
1460 void
1462  myApp->setDelay(delay);
1463 }
1464 
1465 
1467  filename(),
1468  centerX(0),
1469  centerY(0),
1470  centerZ(0),
1471  width(0),
1472  height(0),
1473  altitude(0),
1474  rot(0),
1475  tilt(0),
1476  roll(0),
1477  layer(0),
1478  initialised(false),
1479  skip2D(false),
1480  screenRelative(false),
1481  glID(-1),
1482  image(nullptr) {
1483 }
1484 
1485 
1486 /****************************************************************************/
GUIDialog_EditViewport * getViewportEditor()
get the viewport and create it on first access
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
void paintGLGrid()
paints a grid
A decal (an image) that can be shown.
virtual long onConfigure(FXObject *, FXSelector, void *)
mouse functions
void showToolTips(bool val)
show tool tips
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:131
std::vector< GUIGlID > getObjectsAtPosition(Position pos, double radius)
returns the ids of the object at position within the given (rectangular) radius using GL_SELECT ...
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:125
bool haveGrabbed() const
Returns the information whether one of the spin dialers is grabbed.
GUICompleteSchemeStorage gSchemeStorage
bool showSizeLegend
Information whether the size legend shall be drawn.
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. Used for: Centering of vehicles and junctions */.
long long int SUMOTime
Definition: SUMOTime.h:36
double scale
information about a lane&#39;s width (temporary, used for a single view)
FXImage * checkGDALImage(Decal &d)
check whether we can read image data or position with gdal
FXImage * image
The image pointer for later cleanup.
std::map< SUMOTime, std::vector< std::tuple< std::string, int, int > > > mySnapshots
Snapshots.
a polygon
virtual long onDoubleClicked(FXObject *, FXSelector, void *)
void setDefault(const std::string &name)
Makes the scheme with the given name the default.
double z() const
Returns the z-position.
Definition: Position.h:67
GUIGlObjectType
bool myAmInitialised
Internal information whether doInit() was called.
static void drawTextBox(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &txtColor=RGBColor::BLACK, const RGBColor &bgColor=RGBColor::WHITE, const RGBColor &borderColor=RGBColor::BLACK, const double angle=0, const double relBorder=0.05, const double relMargin=0.5)
draw Text box with given parameters
Definition: GLHelper.cpp:651
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:127
virtual void recenterView()
recenters the view
virtual void setRotation(double rotation)=0
Sets the rotation.
std::vector< GUIGlID > getObjectsInBoundary(Boundary bound)
returns the ids of all objects in the given boundary
SUMORTree * myGrid
The visualization speed-up.
static GUIGlID add(FXImage *i)
Adds a texture to use.
void toggleSelection(GUIGlID id)
Toggles selection of an object.
bool gaming
whether the application is in gaming mode or not
virtual long onMouseMove(FXObject *, FXSelector, void *)
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:84
virtual long onMiddleBtnPress(FXObject *, FXSelector, void *)
Stores the information about how to visualize structures.
The dialog to change the view (gui) settings.
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
Definition: GeoConvHelper.h:84
void setDelay(double delay)
Sets the delay of the parent application.
GLCanvas - ID.
Definition: GUIAppEnum.h:210
const double SUMO_const_laneWidth
Definition: StdDefs.h:51
void displayLegend()
a line with ticks, and the length information.
bool x2cartesian(Position &from, bool includeInBoundary=true)
Converts the given coordinate into a cartesian and optionally update myConvBoundary.
void updatePositionInformation() const
update position information
double y() const
Returns the y-position.
Definition: Position.h:62
void remove(GUIDialog_EditViewport *)
remove viewport
GUIVisualizationSettings * getVisualisationSettings() const
get visualitation settings
GUIVisualizationTextSettings edgeValue
GUIMainWindow * myApp
The application.
Position snapToActiveGrid(const Position &pos) const
Returns a position that is mapped to the closest grid point if the grid is active.
static const double SENSITIVITY
double x() const
Returns the x-position.
Definition: Position.h:57
virtual void saveFrame(const std::string &destFile, FXColor *buf)
Adds a frame to a video snapshot which will be initialized if neccessary.
MFXMutex myDecalsLock
The mutex to use before accessing the decals list in order to avoid thread conflicts.
double centerX
The center of the image in x-direction (net coordinates, in m)
bool screenRelative
Whether this image should be skipped in 2D-views.
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, int align=0, double width=-1)
Definition: GLHelper.cpp:611
virtual long onLeftBtnPress(FXObject *, FXSelector, void *)
T MAX2(T a, T b)
Definition: StdDefs.h:76
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:155
bool myInEditMode
Information whether too-tip informations shall be generated.
virtual void openObjectDialog()
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
virtual Boundary getCenteringBoundary() const =0
virtual double getRotation() const =0
Returns the rotation of the canvas stored in this changer.
void setOldValues(const Position &lookFrom, const Position &lookAt, double rotation)
Resets old values.
virtual long onKeyRelease(FXObject *o, FXSelector sel, void *data)
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:77
void saveViewport(const double x, const double y, const double z)
Makes the given viewport the default.
bool addAdditionalGLVisualisation(const GUIGlObject *const which)
Adds an object to call its additional visualisation method.
int glID
whether the decal shall be drawn in screen coordinates, rather than network coordinates ...
static const RGBColor BLACK
Definition: RGBColor.h:192
virtual void copyViewportTo(GUISUMOAbstractView *view)
copy the viewport to the given view
virtual void onGamingClick(Position)
on gaming click
GUIDialog_ViewSettings * myVisualizationChanger
Visualization changer.
virtual double getZPos() const =0
Returns the camera height corresponding to the current zoom factor.
void set(double x, double y)
set positions x and y
Definition: Position.h:87
virtual void stopTrack()
stop track
GUIDialog_EditViewport * myViewportChooser
viewport chooser
virtual void setDelay(double)
Sets the delay of the parent application.
A RT-tree for efficient storing of SUMO&#39;s GL-objects.
Definition: SUMORTree.h:69
double getGridHeight() const
get grid Height
bool dither
Information whether dithering shall be enabled.
double height
The height of the image (net coordinates in y-direction, in m)
void waitForSnapshots(const SUMOTime snapshotTime)
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:33
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
int myMouseHotspotX
Offset to the mouse-hotspot from the mouse position.
void addDecals(const std::vector< Decal > &decals)
add decals
double getDelay() const
Returns the delay of the parent application.
bool removeAdditionalGLVisualisation(const GUIGlObject *const which)
Removes an object from the list of objects that show additional things.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:241
FXCondition mySnapshotCondition
the semaphore when waiting for snapshots to finish
double layer
The layer of the image.
double p2m(double pixel) const
pixels-to-meters conversion method
std::map< const GUIGlObject *, int > myAdditionallyDrawn
List of objects for which GUIGlObject::drawGLAdditional is called.
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
FXLabel & getCartesianLabel()
FXMutex mySnapshotsMutex
The mutex to use before accessing the decals list in order to avoid thread conflicts.
std::vector< GUIGlID > getObjectstUnderCursor()
returns the id of the objects under the cursor using GL_SELECT (including overlapped objects) ...
GUIVisualizationSizeSettings addSize
Boundary applyGLTransform(bool fixRatio=true)
applies gl-transformations to fit the Boundary given by myChanger onto the canvas. If fixRatio is true, this boundary will be enlarged to prevent anisotropic stretching. (this should be set to false when doing selections)
std::vector< Decal > myDecals
double getGridWidth() const
get grid width
GUIGlID getObjectAtPosition(Position pos)
returns the id of the object at position using GL_SELECT
static FXbool scalePower2(FXImage *image, int maxSize=(2<< 29))
int getLaneEdgeMode() const
Returns the number of the active lane (edge) coloring schme.
virtual GUIGlID getTrackedID() const
get tracked id
virtual void startTrack(int)
star track
virtual long onPaint(FXObject *, FXSelector, void *)
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
std::string name
The name of this setting.
double gridXSize
Information about the grid spacings.
void showToolTipFor(const GUIGlID id)
invokes the tooltip for the given object
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
virtual void setStatusBarText(const std::string &)
Definition: GUIMainWindow.h:78
virtual long onKeyPress(FXObject *o, FXSelector sel, void *data)
keyboard functions
static void sleep(long ms)
virtual void setViewport(double zoom, double xPos, double yPos)=0
Sets the viewport Used for: Adapting a new viewport.
bool isInEditMode()
returns true, if the edit button was pressed
void show()
show view settings dialog
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
void setx(double x)
set position x
Definition: Position.h:72
int gPrecisionGeo
Definition: StdDefs.cpp:28
std::string makeSnapshot(const std::string &destFile, const int width=-1, const int height=-1)
Takes a snapshots and writes it into the given file.
virtual GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)=0
Returns an own popup-menu.
FXComboBox & getColoringSchemesCombo()
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
double rot
The rotation of the image in the ground plane (in degrees)
virtual void centerTo(GUIGlID id, bool applyZoom, double zoomDist=20)
centers to the chosen artifact
bool isGaming() const
return whether the gui is in gaming mode
Definition: GUIMainWindow.h:84
GUIPerspectiveChanger & getChanger() const
get changer
virtual bool onLeftBtnRelease(void *data)
called when user releases left button
FXComboBox & getColoringSchemesCombo()
get coloring schemes combo
bool initialised
Whether this image was initialised (inserted as a texture)
A 2D- or 3D-Shape.
Definition: Shape.h:39
T MIN2(T a, T b)
Definition: StdDefs.h:70
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:119
virtual bool onRightBtnRelease(void *data)
called when user releases right button
virtual void doInit()
doInit
double centerY
The center of the image in y-direction (net coordinates, in m)
FXLabel & getGeoLabel()
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
virtual long onMouseWheel(FXObject *, FXSelector, void *)
virtual void checkSnapshots()
Checks whether it is time for a snapshot.
virtual ~GUISUMOAbstractView()
destructor
std::string filename
The path to the file the image is located at.
virtual double getZoom() const =0
Returns the zoom factor computed stored in this changer.
virtual void setViewportFromToRot(const Position &lookFrom, const Position &lookAt, double rotation)
applies the given viewport settings
double angle
The current view rotation angle.
virtual int doPaintGL(int, const Boundary &)
paint GL
Position screenPos2NetPos(int x, int y) const
Translate screen position to network position.
#define DEG2RAD(x)
Definition: GeomHelper.h:38
static FXbool saveImage(const std::string &file, int width, int height, FXColor *data)
GUIPerspectiveChanger * myChanger
The perspective changer.
bool myUseToolTips
use tool tips
virtual void onLeftBtnPress(void *data)
mouse functions
GUIGLObjectPopupMenu * myPopup
The current popup-menu.
RGBColor backgroundColor
The background color to use.
void destroyPopup()
destoys the popup
void setValues(double zoom, double xoff, double yoff, double rotation)
Sets the given values into the dialog.
FXint myWindowCursorPositionX
Position of the cursor relative to the window.
virtual long onMiddleBtnRelease(FXObject *, FXSelector, void *)
Boundary getViewport(bool fixRatio=true)
get viewport
double width
The width of the image (net coordinates in x-direction, in m)
virtual bool setColorScheme(const std::string &)
set color scheme
unsigned int GUIGlID
Definition: GUIGlObject.h:43
Position rotateAround2D(double rad, const Position &origin)
rotate this position by rad around origin and return the result
Definition: Position.cpp:42
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:247
void unlock()
release mutex lock
Definition: MFXMutex.cpp:87
virtual void showViewportEditor()
show viewport editor
FXbool makeCurrent()
A reimplementation due to some internal reasons.
virtual long onLeftBtnRelease(FXObject *, FXSelector, void *)
GUIVisualizationSettings & getDefault()
Returns the default scheme.
double m2p(double meter) const
meter-to-pixels conversion method
GUIGlObject * getNetObject() const
Returns the network object.
void setViewport(GUISUMOAbstractView *view)
Sets the default viewport.
GUIVisualizationSettings * myVisualizationSettings
visualization settings
Position myPopupPosition
The current popup-menu position.
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:161
virtual void onMouseWheel(void *data)
called when user changes mouse wheel
bool isAdditionalGLVisualisationEnabled(GUIGlObject *const which) const
Check if an object is added in the additional GL visualitation.
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:70
virtual double getColorValue(const GUIVisualizationSettings &, int) const
Definition: GUIGlObject.h:145
void paintGL()
performs the painting of the simulation
virtual long onKeyPress(void *data)
called when user press a key
std::vector< GUIGlObject * > getGUIGlObjectsAtPosition(Position pos, double radius)
returns the GUIGlObjects at position within the given (rectangular) radius using GL_SELECT ...
void sety(double y)
set position y
Definition: Position.h:77
void setWindowCursorPosition(FXint x, FXint y)
Returns the information whether rotation is allowd.
void setCurrent(GUIVisualizationSettings *settings)
Sets current settings (called if reopened)
void show()
overload show function to focus always in OK Button
static const GUIGlID INVALID_ID
Definition: GUIGlObject.h:70
an edge
static FXImage * loadImage(FXApp *a, const std::string &file)
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
void lock()
lock mutex
Definition: MFXMutex.cpp:77
virtual double getDelay() const
Returns the delay (should be overwritten by subclasses if applicable)
bool showGrid
Information whether a grid shall be shown.
void drawDecals()
Draws the stored decals.
The network - empty.
static int getMaxTextureSize()
return maximum number of pixels in x and y direction
virtual double getYPos() const =0
Returns the y-offset of the field to show stored in this changer.
void addSnapshot(SUMOTime time, const std::string &file, const int width=-1, const int height=-1)
Sets the snapshot time to file map.
GUIGlID getGlID() const
Returns the numerical id of the object.
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:113
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:63
bool skip2D
Whether this image should be skipped in 2D-views.
virtual void onMouseMove(void *data)
called when user moves mouse
virtual SUMOTime getCurrentTimeStep() const
get the current simulation time
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
Boundary getVisibleBoundary() const
get visible boundary
void updateToolTip()
A method that updates the tooltip.
A dialog to change the viewport.
virtual void onRightBtnPress(void *data)
called when user press right button
empty max
void unblockObject(GUIGlID id)
Marks an object as unblocked.
static bool UseMesoSim
this should be set at the same time as MSGlobals::gUseMesoSim
virtual void setViewportFrom(double xPos, double yPos, double zPos)=0
Alternative method for setting the viewport.
void showViewschemeEditor()
show viewsscheme editor
virtual long onRightBtnPress(FXObject *, FXSelector, void *)
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
virtual long onMouseLeft(FXObject *, FXSelector, void *)
std::vector< GUIGlObject * > getGUIGlObjectsUnderCursor()
returns the GUIGlObject under the cursor using GL_SELECT (including overlapped objects) ...
GUIGlID getObjectUnderCursor()
returns the id of the front object under the cursor using GL_SELECT
bool drawForSelecting
whether drawing is performed for the purpose of selecting objects
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:137
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:242
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
GUIGlObject * getObjectBlocking(GUIGlID id)
Returns the object from the container locking it.
virtual long onKeyRelease(void *data)
called when user releases a key
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
GUISelectedStorage gSelected
A global holder of selected objects.
virtual double getXPos() const =0
Returns the x-offset of the field to show stored in this changer.
FXDEFMAP(GUISUMOAbstractView) GUISUMOAbstractViewMap[]
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:237
GUIGlChildWindow * myParent
The parent window.
virtual long onRightBtnRelease(FXObject *, FXSelector, void *)
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:285
const Position & getPopupPosition() const
get position of current popup
void setz(double z)
set position z
Definition: Position.h:82