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 // ===========================================================================
87 // member method definitions
88 // ===========================================================================
89 /* -------------------------------------------------------------------------
90  * GUISUMOAbstractView - FOX callback mapping
91  * ----------------------------------------------------------------------- */
92 FXDEFMAP(GUISUMOAbstractView) GUISUMOAbstractViewMap[] = {
93  FXMAPFUNC(SEL_CONFIGURE, 0, GUISUMOAbstractView::onConfigure),
94  FXMAPFUNC(SEL_PAINT, 0, GUISUMOAbstractView::onPaint),
95  FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, GUISUMOAbstractView::onLeftBtnPress),
96  FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, GUISUMOAbstractView::onLeftBtnRelease),
97  FXMAPFUNC(SEL_MIDDLEBUTTONPRESS, 0, GUISUMOAbstractView::onMiddleBtnPress),
98  FXMAPFUNC(SEL_MIDDLEBUTTONRELEASE, 0, GUISUMOAbstractView::onMiddleBtnRelease),
99  FXMAPFUNC(SEL_RIGHTBUTTONPRESS, 0, GUISUMOAbstractView::onRightBtnPress),
100  FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, 0, GUISUMOAbstractView::onRightBtnRelease),
101  FXMAPFUNC(SEL_DOUBLECLICKED, 0, GUISUMOAbstractView::onDoubleClicked),
102  FXMAPFUNC(SEL_MOUSEWHEEL, 0, GUISUMOAbstractView::onMouseWheel),
103  FXMAPFUNC(SEL_MOTION, 0, GUISUMOAbstractView::onMouseMove),
104  FXMAPFUNC(SEL_LEAVE, 0, GUISUMOAbstractView::onMouseLeft),
105  FXMAPFUNC(SEL_KEYPRESS, 0, GUISUMOAbstractView::onKeyPress),
106  FXMAPFUNC(SEL_KEYRELEASE, 0, GUISUMOAbstractView::onKeyRelease),
107 
108 };
109 
110 
111 FXIMPLEMENT_ABSTRACT(GUISUMOAbstractView, FXGLCanvas, GUISUMOAbstractViewMap, ARRAYNUMBER(GUISUMOAbstractViewMap))
112 
113 
114 /* -------------------------------------------------------------------------
115  * GUISUMOAbstractView - methods
116  * ----------------------------------------------------------------------- */
117 GUISUMOAbstractView::GUISUMOAbstractView(FXComposite* p, GUIMainWindow& app, GUIGlChildWindow* parent, const SUMORTree& grid, FXGLVisual* glVis, FXGLCanvas* share) :
118  FXGLCanvas(p, glVis, share, p, MID_GLCANVAS, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0),
119  myApp(&app),
120  myParent(parent),
121  myGrid(&((SUMORTree&)grid)),
122  myChanger(0),
123  myMouseHotspotX(app.getDefaultCursor()->getHotX()),
124  myMouseHotspotY(app.getDefaultCursor()->getHotY()),
125  myPopup(0),
126  myPopupPosition(Position(0, 0)),
127  myUseToolTips(false),
128  myAmInitialised(false),
129  myViewportChooser(0),
130  myWindowCursorPositionX(getWidth() / 2),
131  myWindowCursorPositionY(getHeight() / 2),
132  myVisualizationChanger(0),
133  myApplicationSnapshots(0),
134  myApplicationSnapshotsLock(0) {
135  setTarget(this);
136  enable();
137  flags |= FLAG_ENABLED;
138  myInEditMode = false;
139  // show the middle at the beginning
140  myChanger = new GUIDanielPerspectiveChanger(*this, *myGrid);
141  myVisualizationSettings = &gSchemeStorage.getDefault();
142  myVisualizationSettings->gaming = myApp->isGaming();
144 }
145 
146 
150  delete myPopup;
151  delete myChanger;
152  delete myViewportChooser;
153  delete myVisualizationChanger;
154  // cleanup decals
155  for (std::vector<GUISUMOAbstractView::Decal>::iterator it = myDecals.begin(); it != myDecals.end(); ++it) {
156  delete it->image;
157  }
158 }
159 
160 
161 bool
163  return myInEditMode;
164 }
165 
166 
169  return *myChanger;
170 }
171 
172 
173 void
175  if (!myUseToolTips) {
176  return;
177  }
178  update();
179 }
180 
181 
182 Position
185 }
186 
187 
188 Position
190  Position result = pos;
192  const double xRest = std::fmod(pos.x(), myVisualizationSettings->gridXSize) + (pos.x() < 0 ? myVisualizationSettings->gridXSize : 0);
193  const double yRest = std::fmod(pos.y(), myVisualizationSettings->gridYSize) + (pos.y() < 0 ? myVisualizationSettings->gridYSize : 0);
194  result.setx(pos.x() - xRest + (xRest < myVisualizationSettings->gridXSize * 0.5 ? 0 : myVisualizationSettings->gridXSize));
195  result.sety(pos.y() - yRest + (yRest < myVisualizationSettings->gridYSize * 0.5 ? 0 : myVisualizationSettings->gridYSize));
196  }
197  return result;
198 }
199 
200 
201 Position
203  Boundary bound = myChanger->getViewport();
204  double xNet = bound.xmin() + bound.getWidth() * x / getWidth();
205  // cursor origin is in the top-left corner
206  double yNet = bound.ymin() + bound.getHeight() * (getHeight() - y) / getHeight();
207  // rotate around the viewport center
208  if (myChanger->getRotation() != 0) {
209  return Position(xNet, yNet).rotateAround2D(-DEG2RAD(myChanger->getRotation()), bound.getCenter());
210  } else {
211  return Position(xNet, yNet);
212  }
213 }
214 
215 
216 void
217 GUISUMOAbstractView::addDecals(const std::vector<Decal>& decals) {
218  myDecals.insert(myDecals.end(), decals.begin(), decals.end());
219 }
220 
221 
225 }
226 
227 
228 void
231  std::string text = "x:" + toString(pos.x()) + ", y:" + toString(pos.y());
232  myApp->getCartesianLabel().setText(text.c_str());
234  if (GeoConvHelper::getFinal().usingGeoProjection()) {
235  text = "lat:" + toString(pos.y(), gPrecisionGeo) + ", lon:" + toString(pos.x(), gPrecisionGeo);
236  } else {
237  text = "x:" + toString(pos.x()) + ", y:" + toString(pos.y());
238  }
239  myApp->getGeoLabel().setText(text.c_str());
240 }
241 
242 
243 int
244 GUISUMOAbstractView::doPaintGL(int /*mode*/, const Boundary& /*boundary*/) {
245  return 0;
246 }
247 
248 
249 void
251 }
252 
253 
254 Boundary
256  return myChanger->getViewport();
257 }
258 
259 
260 void
262  if (getWidth() == 0 || getHeight() == 0) {
263  return;
264  }
265 
267  centerTo(getTrackedID(), false);
268  }
269 
271  if (myUseToolTips) {
272  id = getObjectUnderCursor();
273  }
274 
275  // draw
276  glClearColor(
281  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
282  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
283 
285  glEnable(GL_DITHER);
286  } else {
287  glDisable(GL_DITHER);
288  }
289  glEnable(GL_BLEND);
290  glDisable(GL_LINE_SMOOTH);
291 
292  Boundary bound = applyGLTransform();
293  doPaintGL(GL_RENDER, bound);
295  displayLegend();
296  }
297  // check whether the select mode /tooltips)
298  // shall be computed, too
299  if (myUseToolTips && id != GUIGlObject::INVALID_ID) {
300  showToolTipFor(id);
301  }
302  swapBuffers();
303 }
304 
305 
306 GUIGlID
309 }
310 
311 
312 GUIGlID
314  const double SENSITIVITY = 0.1; // meters
315  Boundary selection;
316  selection.add(pos);
317  selection.grow(SENSITIVITY);
318  const std::vector<GUIGlID> ids = getObjectsInBoundary(selection);
319  // Interpret results
320  int idMax = 0;
321  double maxLayer = -std::numeric_limits<double>::max();
322  for (std::vector<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
323  GUIGlID id = *it;
325  if (o == 0) {
326  continue;
327  }
328  if (o->getGlID() == 0) {
329  continue;
330  }
331  //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
332  GUIGlObjectType type = o->getType();
333  if (type != 0) {
334  double layer = (double)type;
335  // determine an "abstract" layer for shapes
336  // this "layer" resembles the layer of the shape
337  // taking into account the stac of other objects
338  if (type == GLO_POI || type == GLO_POLYGON) {
339  layer = dynamic_cast<Shape*>(o)->getShapeLayer();
340  }
342  // do not select lanes in meso mode
343  continue;
344  }
345  // check whether the current object is above a previous one
346  if (layer > maxLayer) {
347  idMax = id;
348  maxLayer = layer;
349  }
350  }
352  }
353  return idMax;
354 }
355 
356 
357 std::vector<GUIGlID>
359  Boundary selection;
360  selection.add(pos);
361  selection.grow(radius);
362  const std::vector<GUIGlID> ids = getObjectsInBoundary(selection);
363  std::vector<GUIGlID> result;
364  // Interpret results
365  for (std::vector<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
366  GUIGlID id = *it;
368  if (o == 0) {
369  continue;
370  }
371  if (o->getGlID() == 0) {
372  continue;
373  }
374  //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
375  GUIGlObjectType type = o->getType();
376  if (type != 0) {
377  result.push_back(id);
378  }
380  }
381  return result;
382 }
383 
384 
385 std::vector<GUIGlID>
387  const int NB_HITS_MAX = 1024 * 1024;
388  // Prepare the selection mode
389  static GUIGlID hits[NB_HITS_MAX];
390  static GLint nb_hits = 0;
391  glSelectBuffer(NB_HITS_MAX, hits);
392  glInitNames();
393 
394  Boundary oldViewPort = myChanger->getViewport(false); // backup the actual viewPort
395  myChanger->setViewport(bound);
396  bound = applyGLTransform(false);
397 
398  // paint in select mode
400  int hits2 = doPaintGL(GL_SELECT, bound);
402  // Get the results
403  nb_hits = glRenderMode(GL_RENDER);
404  if (nb_hits == -1) {
405  myApp->setStatusBarText("Selection in boundary failed. Try to select fewer than " + toString(hits2) + " items");
406  }
407  std::vector<GUIGlID> result;
408  GLuint numNames;
409  GLuint* ptr = hits;
410  for (int i = 0; i < nb_hits; ++i) {
411  numNames = *ptr;
412  ptr += 3;
413  for (int j = 0; j < (int)numNames; j++) {
414  result.push_back(*ptr);
415  ptr++;
416  }
417  }
418  // switch viewport back to normal
419  myChanger->setViewport(oldViewPort);
420  return result;
421 }
422 
423 
424 void
426  if (id != 0) {
428  if (object != 0) {
430  pos.add(0, p2m(15));
431  GLHelper::drawTextBox(object->getFullName(), pos, GLO_MAX - 1, p2m(20), RGBColor::BLACK, RGBColor(255, 179, 0, 255));
433  }
434  }
435 }
436 
437 
438 void
440  // obtain minimum grid
442  // Check if the distance is enought to draw grid
444  glEnable(GL_DEPTH_TEST);
445  glLineWidth(1);
446  // get multiplication values (2 is the marging)
447  int multXmin = (int)(myChanger->getViewport().xmin() / myVisualizationSettings->gridXSize) - 2;
448  int multYmin = (int)(myChanger->getViewport().ymin() / myVisualizationSettings->gridYSize) - 2;
449  int multXmax = (int)(myChanger->getViewport().xmax() / myVisualizationSettings->gridXSize) + 2;
450  int multYmax = (int)(myChanger->getViewport().ymax() / myVisualizationSettings->gridYSize) + 2;
451  // obtain references
452  double xmin = myVisualizationSettings->gridXSize * multXmin;
453  double ymin = myVisualizationSettings->gridYSize * multYmin;
454  double xmax = myVisualizationSettings->gridXSize * multXmax;
455  double ymax = myVisualizationSettings->gridYSize * multYmax;
456  double xpos = xmin;
457  double ypos = ymin;
458  // move drawing matrix
459  glTranslated(0, 0, .55);
460  glColor3d(0.5, 0.5, 0.5);
461  // draw horizontal lines
462  glBegin(GL_LINES);
463  while (ypos <= ymax) {
464  glVertex2d(xmin, ypos);
465  glVertex2d(xmax, ypos);
467  }
468  // draw vertical lines
469  while (xpos <= xmax) {
470  glVertex2d(xpos, ymin);
471  glVertex2d(xpos, ymax);
473  }
474  glEnd();
475  glTranslated(0, 0, -.55);
476  }
477 }
478 
479 
480 void
482  // compute the scale bar length
483  int length = 1;
484  const std::string text("10000000000");
485  int noDigits = 1;
486  int pixelSize = (int) m2p((double) length);
487  while (pixelSize <= 20) {
488  length *= 10;
489  noDigits++;
490  if (noDigits > (int)text.length()) {
491  return;
492  }
493  pixelSize = (int) m2p((double) length);
494  }
495  glLineWidth(1.0);
496 
497  glMatrixMode(GL_PROJECTION);
498  glPushMatrix();
499  glLoadIdentity();
500  glMatrixMode(GL_MODELVIEW);
501  glPushMatrix();
502  glLoadIdentity();
503 
504  // draw the scale bar
505  const double z = -1;
506  glDisable(GL_TEXTURE_2D);
507  glDisable(GL_ALPHA_TEST);
508  glDisable(GL_BLEND);
509  glEnable(GL_DEPTH_TEST);
510  glPushMatrix();
511  glTranslated(0, 0, z);
512 
513  double len = (double) pixelSize / (double)(getWidth() - 1) * (double) 2.0;
514  glColor3d(0, 0, 0);
515  double o = double(15) / double(getHeight());
516  double o2 = o + o;
517  double oo = double(5) / double(getHeight());
518  glBegin(GL_LINES);
519  // vertical
520  glVertex2d(-.98, -1. + o);
521  glVertex2d(-.98 + len, -1. + o);
522  // tick at begin
523  glVertex2d(-.98, -1. + o);
524  glVertex2d(-.98, -1. + o2);
525  // tick at end
526  glVertex2d(-.98 + len, -1. + o);
527  glVertex2d(-.98 + len, -1. + o2);
528  glEnd();
529  glPopMatrix();
530 
531  const double fontHeight = 0.1 * 300. / getHeight();
532  const double fontWidth = 0.1 * 300. / getWidth();
533  // draw 0
534  GLHelper::drawText("0", Position(-.99, -0.99 + o2 + oo), z, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT, fontWidth);
535 
536  // draw current scale
537  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);
538 
539  // restore matrices
540  glMatrixMode(GL_PROJECTION);
541  glPopMatrix();
542  glMatrixMode(GL_MODELVIEW);
543  glPopMatrix();
544 }
545 
546 
547 double
548 GUISUMOAbstractView::m2p(double meter) const {
549  return meter * getWidth() / myChanger->getViewport().getWidth();
550 }
551 
552 
553 double
554 GUISUMOAbstractView::p2m(double pixel) const {
555  return pixel * myChanger->getViewport().getWidth() / getWidth();
556 }
557 
558 
559 void
562 }
563 
564 
565 void
566 GUISUMOAbstractView::centerTo(GUIGlID id, bool applyZoom, double zoomDist) {
568  if (o != 0 && dynamic_cast<GUIGlObject*>(o) != 0) {
569  if (applyZoom && zoomDist < 0) {
571  update(); // only update when centering onto an object once
572  } else {
573  // called during tracking. update is triggered somewhere else
574  myChanger->centerTo(o->getCenteringBoundary().getCenter(), zoomDist, applyZoom);
576  }
577  }
579 }
580 
581 
582 void
584  myChanger->setViewport(bound);
585  update();
586 }
587 
588 /*
589 bool
590 GUISUMOAbstractView::allowRotation() const
591 {
592  return myParent->allowRotation();
593 }
594 */
595 
596 void
600 }
601 
602 
603 FXbool
605  FXbool ret = FXGLCanvas::makeCurrent();
606  return ret;
607 }
608 
609 
610 long
611 GUISUMOAbstractView::onConfigure(FXObject*, FXSelector, void*) {
612  if (makeCurrent()) {
613  glViewport(0, 0, getWidth() - 1, getHeight() - 1);
614  glClearColor(
619  doInit();
620  myAmInitialised = true;
621  makeNonCurrent();
622  checkSnapshots();
623  }
624  return 1;
625 }
626 
627 
628 long
629 GUISUMOAbstractView::onPaint(FXObject*, FXSelector, void*) {
630  if (!isEnabled() || !myAmInitialised) {
631  return 1;
632  }
633  if (makeCurrent()) {
634  paintGL();
635  makeNonCurrent();
636  }
637  return 1;
638 }
639 
640 
641 const Position&
643  return myPopupPosition;
644 }
645 
646 void
648  if (myPopup != NULL) {
649  delete myPopup;
650  myPopupPosition.set(0, 0);
651  myPopup = NULL;
652  }
653 }
654 
655 
656 long
657 GUISUMOAbstractView::onLeftBtnPress(FXObject*, FXSelector , void* data) {
658  destroyPopup();
659  setFocus();
660  FXEvent* e = (FXEvent*) data;
661  // check whether the selection-mode is activated
662  if ((e->state & CONTROLMASK) != 0) {
663  // try to get the object-id if so
664  if (makeCurrent()) {
665  int id = getObjectUnderCursor();
666  if (id != 0) {
668  }
669  makeNonCurrent();
670  if (id != 0) {
671  // possibly, the selection-colouring is used,
672  // so we should update the screen again...
673  update();
674  }
675  }
676  }
677  myChanger->onLeftBtnPress(data);
678  grab();
679  // Check there are double click
680  if (e->click_count == 2) {
681  handle(this, FXSEL(SEL_DOUBLECLICKED, 0), data);
682  }
683  return 1;
684 }
685 
686 
687 long
688 GUISUMOAbstractView::onLeftBtnRelease(FXObject*, FXSelector , void* data) {
689  destroyPopup();
691  if (myApp->isGaming()) {
693  }
694  ungrab();
695  return 1;
696 }
697 
698 
699 long
700 GUISUMOAbstractView::onMiddleBtnPress(FXObject*, FXSelector, void*) {
701  return 1;
702 }
703 
704 
705 long
706 GUISUMOAbstractView::onMiddleBtnRelease(FXObject*, FXSelector, void*) {
707  return 1;
708 }
709 
710 
711 long
712 GUISUMOAbstractView::onRightBtnPress(FXObject*, FXSelector , void* data) {
713  destroyPopup();
714  myChanger->onRightBtnPress(data);
715  grab();
716  return 1;
717 }
718 
719 
720 long
721 GUISUMOAbstractView::onRightBtnRelease(FXObject* o, FXSelector sel, void* data) {
722  destroyPopup();
723  onMouseMove(o, sel, data);
724  if (!myChanger->onRightBtnRelease(data) && !myApp->isGaming()) {
726  }
727  ungrab();
728  return 1;
729 }
730 
731 
732 long
733 GUISUMOAbstractView::onDoubleClicked(FXObject*, FXSelector, void*) {
734  return 1;
735 }
736 
737 
738 long
739 GUISUMOAbstractView::onMouseWheel(FXObject*, FXSelector , void* data) {
740  if (!myApp->isGaming()) {
741  myChanger->onMouseWheel(data);
742  // upddate viewport
743  if (myViewportChooser != 0) {
747  }
749  }
750  return 1;
751 }
752 
753 
754 long
755 GUISUMOAbstractView::onMouseMove(FXObject*, FXSelector , void* data) {
756  // if popup exist but isn't shown, destroy it first
757  if (myPopup && (myPopup->shown() == false)) {
758  destroyPopup();
759  }
760  if (myPopup == NULL) {
762  myChanger->onMouseMove(data);
763  }
764  if (myViewportChooser != 0) {
768  }
770  }
771  return 1;
772 }
773 
774 
775 long
776 GUISUMOAbstractView::onMouseLeft(FXObject*, FXSelector , void* /*data*/) {
777  return 1;
778 }
779 
780 
781 void
783  ungrab();
784  if (!isEnabled() || !myAmInitialised) {
785  return;
786  }
787  if (makeCurrent()) {
788  // initialise the select mode
789  int id = getObjectUnderCursor();
790  GUIGlObject* o = 0;
791  if (id != 0) {
793  } else {
795  }
796  if (o != 0) {
797  myPopup = o->getPopUpMenu(*myApp, *this);
798  int x, y;
799  FXuint b;
800  myApp->getCursorPosition(x, y, b);
801  myPopup->setX(x + myApp->getX());
802  myPopup->setY(y + myApp->getY());
803  myPopup->create();
804  myPopup->show();
808  setFocus();
809  }
810  makeNonCurrent();
811  }
812 }
813 
814 
815 long
816 GUISUMOAbstractView::onKeyPress(FXObject* o, FXSelector sel, void* data) {
817  if (myPopup != NULL) {
818  return myPopup->onKeyPress(o, sel, data);
819  } else {
820  FXGLCanvas::onKeyPress(o, sel, data);
821  return myChanger->onKeyPress(data);
822  }
823 }
824 
825 
826 long
827 GUISUMOAbstractView::onKeyRelease(FXObject* o, FXSelector sel, void* data) {
828  if (myPopup != NULL) {
829  return myPopup->onKeyRelease(o, sel, data);
830  } else {
831  FXGLCanvas::onKeyRelease(o, sel, data);
832  return myChanger->onKeyRelease(data);
833  }
834 }
835 
836 
837 // ------------ Dealing with snapshots
838 void
839 GUISUMOAbstractView::addSnapshot(SUMOTime time, const std::string& file, const int width, const int height) {
840 #ifdef DEBUG_SNAPSHOT
841  std::cout << "add snappshot time=" << time << " file=" << file << "\n";
842 #endif
844  mySnapshots[time].push_back(std::make_tuple(file, width, height));
846  if (myApplicationSnapshots != 0) {
848  myApplicationSnapshots->insert(time);
849  myApplicationSnapshotsLock->unlock();
850  }
851 }
852 
853 std::string
854 GUISUMOAbstractView::makeSnapshot(const std::string& destFile, const int width, const int height) {
855  if (width >= 0) {
856  resize(width, height);
857  repaint();
858  }
859  std::string errorMessage;
860  FXString ext = FXPath::extension(destFile.c_str());
861  const bool useGL2PS = ext == "ps" || ext == "eps" || ext == "pdf" || ext == "svg" || ext == "tex" || ext == "pgf";
862 #ifdef HAVE_FFMPEG
863  const bool useVideo = destFile == "" || ext == "h264" || ext == "hevc";
864 #endif
865  for (int i = 0; i < 10 && !makeCurrent(); ++i) {
867  }
868  // draw
869  glClearColor(
874  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
875  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
876 
878  glEnable(GL_DITHER);
879  } else {
880  glDisable(GL_DITHER);
881  }
882  glEnable(GL_BLEND);
883  glDisable(GL_LINE_SMOOTH);
884 
886 
887  if (useGL2PS) {
888 #ifdef HAVE_GL2PS
889  GLint format = GL2PS_PS;
890  if (ext == "ps") {
891  format = GL2PS_PS;
892  } else if (ext == "eps") {
893  format = GL2PS_EPS;
894  } else if (ext == "pdf") {
895  format = GL2PS_PDF;
896  } else if (ext == "tex") {
897  format = GL2PS_TEX;
898  } else if (ext == "svg") {
899  format = GL2PS_SVG;
900  } else if (ext == "pgf") {
901  format = GL2PS_PGF;
902  } else {
903  return "Could not save '" + destFile + "'.\n Unrecognized format '" + std::string(ext.text()) + "'.";
904  }
905  FILE* fp = fopen(destFile.c_str(), "wb");
906  if (fp == 0) {
907  return "Could not save '" + destFile + "'.\n Could not open file for writing";
908  }
909  GLint buffsize = 0, state = GL2PS_OVERFLOW;
910  GLint viewport[4];
911  glGetIntegerv(GL_VIEWPORT, viewport);
912  while (state == GL2PS_OVERFLOW) {
913  buffsize += 1024 * 1024;
914  gl2psBeginPage(destFile.c_str(), "sumo-gui; http://sumo.dlr.de", viewport, format, GL2PS_SIMPLE_SORT,
915  GL2PS_DRAW_BACKGROUND | GL2PS_USE_CURRENT_VIEWPORT,
916  GL_RGBA, 0, NULL, 0, 0, 0, buffsize, fp, "out.eps");
917  glMatrixMode(GL_MODELVIEW);
918  glPushMatrix();
919  glDisable(GL_TEXTURE_2D);
920  glDisable(GL_ALPHA_TEST);
921  glDisable(GL_BLEND);
922  glEnable(GL_DEPTH_TEST);
923  // draw decals (if not in grabbing mode)
924  if (!myUseToolTips) {
925  drawDecals();
927  paintGLGrid();
928  }
929  }
930  glLineWidth(1);
931  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
932  Boundary viewPort = myChanger->getViewport();
933  const float minB[2] = { (float)viewPort.xmin(), (float)viewPort.ymin() };
934  const float maxB[2] = { (float)viewPort.xmax(), (float)viewPort.ymax() };
936  glEnable(GL_POLYGON_OFFSET_FILL);
937  glEnable(GL_POLYGON_OFFSET_LINE);
938  myGrid->Search(minB, maxB, *myVisualizationSettings);
939 
941  displayLegend();
942  }
943  state = gl2psEndPage();
944  glFinish();
945  }
946  fclose(fp);
947 #else
948  return "Could not save '" + destFile + "', gl2ps was not enabled at compile time.";
949 #endif
950  } else {
951  doPaintGL(GL_RENDER, myChanger->getViewport());
953  displayLegend();
954  }
955  swapBuffers();
956  glFinish();
957  FXColor* buf;
958  FXMALLOC(&buf, FXColor, getWidth()*getHeight());
959  // read from the back buffer
960  glReadBuffer(GL_BACK);
961  // Read the pixels
962  glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)buf);
963  makeNonCurrent();
964  update();
965  // mirror
966  int mwidth = getWidth();
967  int mheight = getHeight();
968  FXColor* paa = buf;
969  FXColor* pbb = buf + mwidth * (mheight - 1);
970  do {
971  FXColor* pa = paa;
972  paa += mwidth;
973  FXColor* pb = pbb;
974  pbb -= mwidth;
975  do {
976  FXColor t = *pa;
977  *pa++ = *pb;
978  *pb++ = t;
979  } while (pa < paa);
980  } while (paa < pbb);
981  try {
982 #ifdef HAVE_FFMPEG
983  if (useVideo) {
984  try {
985  saveFrame(destFile, buf);
986  errorMessage = "video";
987  } catch (std::runtime_error& err) {
988  errorMessage = err.what();
989  }
990  } else
991 #endif
992  if (!MFXImageHelper::saveImage(destFile, getWidth(), getHeight(), buf)) {
993  errorMessage = "Could not save '" + destFile + "'.";
994  }
995  } catch (InvalidArgument& e) {
996  errorMessage = "Could not save '" + destFile + "'.\n" + e.what();
997  }
998  FXFREE(&buf);
999  }
1000  return errorMessage;
1001 }
1002 
1003 
1004 void
1005 GUISUMOAbstractView::saveFrame(const std::string& destFile, FXColor* buf) {
1006  UNUSED_PARAMETER(destFile);
1007  UNUSED_PARAMETER(buf);
1008 }
1009 
1010 
1011 void
1013  SUMOTime time = getCurrentTimeStep() - DELTA_T;
1014 #ifdef DEBUG_SNAPSHOT
1015  std::cout << "check snappshots time=" << time << " registeredTimes=" << mySnapshots.size() << "\n";
1016 #endif
1018  auto snapIt = mySnapshots.find(time);
1019  std::vector<std::tuple<std::string, int, int> > files;
1020  if (snapIt != mySnapshots.end()) {
1021  files = snapIt->second;
1022  mySnapshots.erase(snapIt);
1023  }
1025  // decouple map access and painting to avoid deadlock
1026  for (const auto& entry : files) {
1027 #ifdef DEBUG_SNAPSHOT
1028  std::cout << "make snappshot time=" << time << " file=" << file << "\n";
1029 #endif
1030  std::string error = makeSnapshot(std::get<0>(entry), std::get<1>(entry), std::get<2>(entry));
1031  if (error != "") {
1032  WRITE_WARNING(error);
1033  }
1034  }
1035  // synchronization with a waiting run thread
1036  if (!files.empty()) {
1037  assert(myApplicationSnapshots != 0);
1038  assert(myApplicationSnapshotsLock != 0);
1040  myApplicationSnapshots->erase(time);
1041  myApplicationSnapshotsLock->unlock();
1042  }
1043 #ifdef DEBUG_SNAPSHOT
1044  std::cout << " files=" << toString(files) << " myApplicationSnapshots=" << joinToString(*myApplicationSnapshots, ",") << "\n";
1045 #endif
1046 }
1047 
1048 
1049 SUMOTime
1051  return 0;
1052 }
1053 
1054 
1055 void
1057  if (myVisualizationChanger == 0) {
1061  &myDecals, &myDecalsLock);
1062  myVisualizationChanger->create();
1063  } else {
1065  }
1067 }
1068 
1069 
1072  if (myViewportChooser == 0) {
1073  const FXint minSize = 100;
1074  const FXint minTitlebarHeight = 20;
1075  int x = MAX2(0, MIN2(getApp()->reg().readIntEntry(
1076  "VIEWPORT_DIALOG_SETTINGS", "x", 150),
1077  getApp()->getRootWindow()->getWidth() - minSize));
1078  int y = MAX2(minTitlebarHeight, MIN2(getApp()->reg().readIntEntry(
1079  "VIEWPORT_DIALOG_SETTINGS", "y", 150),
1080  getApp()->getRootWindow()->getHeight() - minSize));
1081  myViewportChooser = new GUIDialog_EditViewport(this, "Edit Viewport", x, y);
1082  myViewportChooser->create();
1083  }
1086  myChanger->getRotation());
1087  return myViewportChooser;
1088 }
1089 
1090 
1091 void
1093  getViewportEditor(); // make sure it exists;
1097 }
1098 
1099 
1100 void
1101 GUISUMOAbstractView::setViewportFromToRot(const Position& lookFrom, const Position& /* lookAt */, double rotation) {
1102  myChanger->setViewportFrom(lookFrom.x(), lookFrom.y(), lookFrom.z());
1103  myChanger->setRotation(rotation);
1104  update();
1105 }
1106 
1107 
1108 void
1110  // look straight down
1113  myChanger->getRotation());
1114 }
1115 
1116 
1117 void
1119  myUseToolTips = val;
1120 }
1121 
1122 
1123 bool
1125  return true;
1126 }
1127 
1128 
1131  return myVisualizationSettings;
1132 }
1133 
1134 
1135 void
1137  myViewportChooser = 0;
1138 }
1139 
1140 
1141 void
1144 }
1145 
1146 
1147 double
1149  return myGrid->getWidth();
1150 }
1151 
1152 
1153 double
1155  return myGrid->getHeight();
1156 }
1157 
1158 
1159 void
1161 }
1162 
1163 
1164 void
1166 }
1167 
1168 
1169 GUIGlID
1171  return GUIGlObject::INVALID_ID;
1172 }
1173 
1174 
1175 void
1177 }
1178 
1179 
1180 FXComboBox&
1183 }
1184 
1185 
1186 FXImage*
1188 #ifdef HAVE_GDAL
1189  GDALAllRegister();
1190  GDALDataset* poDataset = (GDALDataset*)GDALOpen(d.filename.c_str(), GA_ReadOnly);
1191  if (poDataset == 0) {
1192  return 0;
1193  }
1194  const int xSize = poDataset->GetRasterXSize();
1195  const int ySize = poDataset->GetRasterYSize();
1196  // checking for geodata in the picture and try to adapt position and scale
1197  if (d.width <= 0.) {
1198  double adfGeoTransform[6];
1199  if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) {
1200  Position topLeft(adfGeoTransform[0], adfGeoTransform[3]);
1201  const double horizontalSize = xSize * adfGeoTransform[1];
1202  const double verticalSize = ySize * adfGeoTransform[5];
1203  Position bottomRight(topLeft.x() + horizontalSize, topLeft.y() + verticalSize);
1205  d.width = bottomRight.x() - topLeft.x();
1206  d.height = topLeft.y() - bottomRight.y();
1207  d.centerX = (topLeft.x() + bottomRight.x()) / 2;
1208  d.centerY = (topLeft.y() + bottomRight.y()) / 2;
1209  //WRITE_MESSAGE("proj: " + toString(poDataset->GetProjectionRef()) + " dim: " + toString(d.width) + "," + toString(d.height) + " center: " + toString(d.centerX) + "," + toString(d.centerY));
1210  } else {
1211  WRITE_WARNING("Could not convert coordinates in " + d.filename + ".");
1212  }
1213  }
1214  }
1215 #endif
1216  if (d.width <= 0.) {
1217  d.width = getGridWidth();
1218  d.height = getGridHeight();
1219  }
1220 
1221  // trying to read the picture
1222 #ifdef HAVE_GDAL
1223  const int picSize = xSize * ySize;
1224  FXColor* result;
1225  if (!FXMALLOC(&result, FXColor, picSize)) {
1226  WRITE_WARNING("Could not allocate memory for " + d.filename + ".");
1227  return 0;
1228  }
1229  for (int j = 0; j < picSize; j++) {
1230  result[j] = FXRGB(0, 0, 0);
1231  }
1232  bool valid = true;
1233  for (int i = 1; i <= poDataset->GetRasterCount(); i++) {
1234  GDALRasterBand* poBand = poDataset->GetRasterBand(i);
1235  int shift = -1;
1236  if (poBand->GetColorInterpretation() == GCI_RedBand) {
1237  shift = 0;
1238  } else if (poBand->GetColorInterpretation() == GCI_GreenBand) {
1239  shift = 1;
1240  } else if (poBand->GetColorInterpretation() == GCI_BlueBand) {
1241  shift = 2;
1242  } else if (poBand->GetColorInterpretation() == GCI_AlphaBand) {
1243  shift = 3;
1244  } else {
1245  WRITE_MESSAGE("Unknown color band in " + d.filename + ", maybe fox can parse it.");
1246  valid = false;
1247  break;
1248  }
1249  assert(xSize == poBand->GetXSize() && ySize == poBand->GetYSize());
1250  if (poBand->RasterIO(GF_Read, 0, 0, xSize, ySize, ((unsigned char*)result) + shift, xSize, ySize, GDT_Byte, 4, 4 * xSize) == CE_Failure) {
1251  valid = false;
1252  break;
1253  }
1254  }
1255  GDALClose(poDataset);
1256  if (valid) {
1257  return new FXImage(getApp(), result, IMAGE_OWNED | IMAGE_KEEP | IMAGE_SHMI | IMAGE_SHMP, xSize, ySize);
1258  }
1259  FXFREE(&result);
1260 #endif
1261  return 0;
1262 }
1263 
1264 
1265 void
1267  glPushName(0);
1268  myDecalsLock.lock();
1269  for (std::vector<GUISUMOAbstractView::Decal>::iterator l = myDecals.begin(); l != myDecals.end(); ++l) {
1271  if (d.skip2D) {
1272  continue;
1273  }
1274  if (!d.initialised) {
1275  try {
1276  FXImage* img = checkGDALImage(d);
1277  if (img == 0) {
1278  img = MFXImageHelper::loadImage(getApp(), d.filename);
1279  }
1281  d.glID = GUITexturesHelper::add(img);
1282  d.initialised = true;
1283  d.image = img;
1284  } catch (InvalidArgument& e) {
1285  WRITE_ERROR("Could not load '" + d.filename + "'.\n" + e.what());
1286  d.skip2D = true;
1287  }
1288  }
1289  glPushMatrix();
1290  if (d.screenRelative) {
1291  Position center = screenPos2NetPos((int)d.centerX, (int)d.centerY);
1292  glTranslated(center.x(), center.y(), d.layer);
1293  } else {
1294  glTranslated(d.centerX, d.centerY, d.layer);
1295  }
1296  glRotated(d.rot, 0, 0, 1);
1297  glColor3d(1, 1, 1);
1298  double halfWidth = d.width / 2.;
1299  double halfHeight = d.height / 2.;
1300  if (d.screenRelative) {
1301  halfWidth = p2m(halfWidth);
1302  halfHeight = p2m(halfHeight);
1303  }
1304  GUITexturesHelper::drawTexturedBox(d.glID, -halfWidth, -halfHeight, halfWidth, halfHeight);
1305  glPopMatrix();
1306  }
1307  myDecalsLock.unlock();
1308  glPopName();
1309 }
1310 
1311 
1312 // ------------ Additional visualisations
1313 bool
1315  if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1316  myAdditionallyDrawn[which] = 1;
1317  } else {
1318  myAdditionallyDrawn[which] = myAdditionallyDrawn[which] + 1;
1319  }
1320  update();
1321  return true;
1322 }
1323 
1324 
1325 bool
1327  if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1328  return false;
1329  }
1330  int cnt = myAdditionallyDrawn[which];
1331  if (cnt == 1) {
1332  myAdditionallyDrawn.erase(which);
1333  } else {
1334  myAdditionallyDrawn[which] = myAdditionallyDrawn[which] - 1;
1335  }
1336  update();
1337  return true;
1338 }
1339 
1340 
1341 bool
1343  if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1344  return false;
1345  } else {
1346  return true;
1347  }
1348 }
1349 
1350 
1351 Boundary
1353  Boundary bound = myChanger->getViewport(fixRatio);
1354  glMatrixMode(GL_PROJECTION);
1355  glLoadIdentity();
1356  // as a rough rule, each GLObject is drawn at z = -GUIGlObjectType
1357  // thus, objects with a higher value will be closer (drawn on top)
1358  // // @todo last param should be 0 after modifying all glDraw methods
1359  glOrtho(0, getWidth(), 0, getHeight(), -GLO_MAX - 1, GLO_MAX + 1);
1360  glMatrixMode(GL_MODELVIEW);
1361  glLoadIdentity();
1362  double scaleX = (double)getWidth() / bound.getWidth();
1363  double scaleY = (double)getHeight() / bound.getHeight();
1364  glScaled(scaleX, scaleY, 1);
1365  glTranslated(-bound.xmin(), -bound.ymin(), 0);
1366  // rotate around the center of the screen
1367  //double angle = -90;
1368  if (myChanger->getRotation() != 0) {
1369  glTranslated(bound.getCenter().x(), bound.getCenter().y(), 0);
1370  glRotated(myChanger->getRotation(), 0, 0, 1);
1371  glTranslated(-bound.getCenter().x(), -bound.getCenter().y(), 0);
1372  Boundary rotBound;
1373  double rad = -DEG2RAD(myChanger->getRotation());
1374  rotBound.add(Position(bound.xmin(), bound.ymin()).rotateAround2D(rad, bound.getCenter()));
1375  rotBound.add(Position(bound.xmin(), bound.ymax()).rotateAround2D(rad, bound.getCenter()));
1376  rotBound.add(Position(bound.xmax(), bound.ymin()).rotateAround2D(rad, bound.getCenter()));
1377  rotBound.add(Position(bound.xmax(), bound.ymax()).rotateAround2D(rad, bound.getCenter()));
1378  bound = rotBound;
1380  }
1381  return bound;
1382 }
1383 
1384 
1385 double
1387  return myApp->getDelay();
1388 }
1389 
1390 
1391 void
1393  myApp->setDelay(delay);
1394 }
1395 
1396 
1398  filename(),
1399  centerX(0),
1400  centerY(0),
1401  centerZ(0),
1402  width(0),
1403  height(0),
1404  altitude(0),
1405  rot(0),
1406  tilt(0),
1407  roll(0),
1408  layer(0),
1409  initialised(false),
1410  skip2D(false),
1411  screenRelative(false),
1412  glID(-1),
1413  image(0) {
1414 }
1415 
1416 
1417 /****************************************************************************/
1418 
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:66
GUIGlObjectType
bool myAmInitialised
Internal information whether doInit() was called.
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:126
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:83
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:43
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:61
void remove(GUIDialog_EditViewport *)
remove viewport
GUIVisualizationSettings * getVisualisationSettings() const
get visualitation settings
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.
double x() const
Returns the x-position.
Definition: Position.h:56
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:68
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:76
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:180
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:86
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)
#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:242
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()
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))
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:74
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:71
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:80
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:62
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.
FXMutex * myApplicationSnapshotsLock
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:248
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
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)
draw Text box with given parameters
Definition: GLHelper.cpp:635
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:69
void paintGL()
performs the painting of the simulation
virtual long onKeyPress(void *data)
called when user press a key
void sety(double y)
set position y
Definition: Position.h:76
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
static FXImage * loadImage(FXApp *a, const std::string &file)
MFXMutex mySnapshotsLock
The mutex to use before accessing the decals list in order to avoid thread conflicts.
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.
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
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:62
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 *)
const std::string & getFullName() const
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 *)
GUIGlID getObjectUnderCursor()
returns the id of the 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:243
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:230
GUIGlChildWindow * myParent
The parent window.
virtual long onRightBtnRelease(FXObject *, FXSelector, void *)
std::set< SUMOTime > * myApplicationSnapshots
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:274
const Position & getPopupPosition() const
get position of current popup