SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GUISUMOAbstractView.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // The base class for a view
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
14 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <iostream>
36 #include <utility>
37 #include <cmath>
38 #include <cassert>
39 #include <limits>
40 #include <fxkeys.h>
42 #include <foreign/gl2ps/gl2ps.h>
46 #include <utils/common/RGBColor.h>
47 #include <utils/common/ToString.h>
54 #include <utils/gui/div/GLHelper.h>
64 
65 #include "GUISUMOAbstractView.h"
66 #include "GUIMainWindow.h"
67 #include "GUIGlChildWindow.h"
69 #include "GUIDialog_EditViewport.h"
70 
71 #ifdef HAVE_GDAL
72 #include <gdal_priv.h>
73 #endif
74 
75 #ifdef CHECK_MEMORY_LEAKS
76 #include <foreign/nvwa/debug_new.h>
77 #endif // CHECK_MEMORY_LEAKS
78 
79 
80 // ===========================================================================
81 // member method definitions
82 // ===========================================================================
83 /* -------------------------------------------------------------------------
84  * GUISUMOAbstractView - FOX callback mapping
85  * ----------------------------------------------------------------------- */
86 FXDEFMAP(GUISUMOAbstractView) GUISUMOAbstractViewMap[] = {
87  FXMAPFUNC(SEL_CONFIGURE, 0, GUISUMOAbstractView::onConfigure),
88  FXMAPFUNC(SEL_PAINT, 0, GUISUMOAbstractView::onPaint),
89  FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, GUISUMOAbstractView::onLeftBtnPress),
90  FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, GUISUMOAbstractView::onLeftBtnRelease),
91  FXMAPFUNC(SEL_MIDDLEBUTTONPRESS, 0, GUISUMOAbstractView::onMiddleBtnPress),
92  FXMAPFUNC(SEL_MIDDLEBUTTONRELEASE, 0, GUISUMOAbstractView::onMiddleBtnRelease),
93  FXMAPFUNC(SEL_RIGHTBUTTONPRESS, 0, GUISUMOAbstractView::onRightBtnPress),
94  FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, 0, GUISUMOAbstractView::onRightBtnRelease),
95  FXMAPFUNC(SEL_MOUSEWHEEL, 0, GUISUMOAbstractView::onMouseWheel),
96  FXMAPFUNC(SEL_MOTION, 0, GUISUMOAbstractView::onMouseMove),
97  FXMAPFUNC(SEL_LEAVE, 0, GUISUMOAbstractView::onMouseLeft),
98  FXMAPFUNC(SEL_KEYPRESS, 0, GUISUMOAbstractView::onKeyPress),
99  FXMAPFUNC(SEL_KEYRELEASE, 0, GUISUMOAbstractView::onKeyRelease),
100 
101 };
102 
103 
104 FXIMPLEMENT_ABSTRACT(GUISUMOAbstractView, FXGLCanvas, GUISUMOAbstractViewMap, ARRAYNUMBER(GUISUMOAbstractViewMap))
105 
106 
107 /* -------------------------------------------------------------------------
108  * GUISUMOAbstractView - methods
109  * ----------------------------------------------------------------------- */
111  GUIMainWindow& app,
112  GUIGlChildWindow* parent,
113  const SUMORTree& grid,
114  FXGLVisual* glVis, FXGLCanvas* share)
115  : FXGLCanvas(p, glVis, share, p, MID_GLCANVAS,
116  LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0),
117  myApp(&app),
118  myParent(parent),
119  myGrid(&((SUMORTree&)grid)),
120  myChanger(0),
121  myMouseHotspotX(app.getDefaultCursor()->getHotX()),
122  myMouseHotspotY(app.getDefaultCursor()->getHotY()),
123  myPopup(0),
124  myUseToolTips(false),
125  myAmInitialised(false),
126  myViewportChooser(0),
127  myVisualizationChanger(0) {
128  setTarget(this);
129  enable();
130  flags |= FLAG_ENABLED;
131  myInEditMode = false;
132  // show the middle at the beginning
133  myChanger = new GUIDanielPerspectiveChanger(*this, *myGrid);
134  myVisualizationSettings = &gSchemeStorage.getDefault();
135  myVisualizationSettings->gaming = myApp->isGaming();
137 }
138 
139 
143  delete myPopup;
144  delete myChanger;
145  delete myViewportChooser;
146  delete myVisualizationChanger;
147  // cleanup decals
148  for (std::vector<GUISUMOAbstractView::Decal>::iterator it = myDecals.begin(); it != myDecals.end(); ++it) {
149  delete it->image;
150  }
151 }
152 
153 
154 bool
156  return myInEditMode;
157 }
158 
159 
160 void
162  if (!myUseToolTips) {
163  return;
164  }
165  update();
166 }
167 
168 
169 Position
171  Boundary bound = myChanger->getViewport();
172  SUMOReal x = bound.xmin() + bound.getWidth() * myWindowCursorPositionX / getWidth();
173  // cursor origin is in the top-left corner
174  SUMOReal y = bound.ymin() + bound.getHeight() * (getHeight() - myWindowCursorPositionY) / getHeight();
175  return Position(x, y);
176 }
177 
178 
179 void
182  std::string text = "x:" + toString(pos.x()) + ", y:" + toString(pos.y());
183  myApp->getCartesianLabel().setText(text.c_str());
185  if (GeoConvHelper::getFinal().usingGeoProjection()) {
186  text = "lat:" + toString(pos.y(), GEO_OUTPUT_ACCURACY) + ", lon:" + toString(pos.x(), GEO_OUTPUT_ACCURACY);
187  } else {
188  text = "x:" + toString(pos.x()) + ", y:" + toString(pos.y());
189  }
190  myApp->getGeoLabel().setText(text.c_str());
191 }
192 
193 
194 Boundary
196  return myChanger->getViewport();
197 }
198 
199 void
201  if (getWidth() == 0 || getHeight() == 0) {
202  return;
203  }
204 
205  if (getTrackedID() > 0) {
206  centerTo(getTrackedID(), false);
207  }
208 
209  unsigned int id = 0;
210  if (myUseToolTips) {
211  id = getObjectUnderCursor();
212  }
213 
214  // draw
215  glClearColor(
220  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
221  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
222 
224  glEnable(GL_DITHER);
225  } else {
226  glDisable(GL_DITHER);
227  }
229  glEnable(GL_BLEND);
230  glEnable(GL_POLYGON_SMOOTH);
231  glEnable(GL_LINE_SMOOTH);
232  } else {
233  glDisable(GL_BLEND);
234  glDisable(GL_POLYGON_SMOOTH);
235  glDisable(GL_LINE_SMOOTH);
236  }
237 
239  doPaintGL(GL_RENDER, myChanger->getViewport());
241  displayLegend();
242  }
243  // check whether the select mode /tooltips)
244  // shall be computed, too
245  if (myUseToolTips && id != 0) {
246  showToolTipFor(id);
247  }
248  swapBuffers();
249 }
250 
251 
252 GUIGlID
255 }
256 
257 
258 GUIGlID
260  const SUMOReal SENSITIVITY = 0.1; // meters
261  Boundary selection;
262  selection.add(pos);
263  selection.grow(SENSITIVITY);
264  const std::vector<GUIGlID> ids = getObjectsInBoundary(selection);
265  // Interpret results
266  unsigned int idMax = 0;
268  for (std::vector<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
269  GUIGlID id = *it;
271  if (o == 0) {
272  continue;
273  }
274  if (o->getGlID() == 0) {
275  continue;
276  }
277  //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
278  GUIGlObjectType type = o->getType();
279  if (type != 0) {
280  SUMOReal layer = (SUMOReal)type;
281  // determine an "abstract" layer for shapes
282  // this "layer" resembles the layer of the shape
283  // taking into account the stac of other objects
284  if (type == GLO_POI || type == GLO_POLYGON) {
285  layer = dynamic_cast<Shape*>(o)->getLayer();
286  }
287 #ifdef HAVE_INTERNAL
288  if (type == GLO_LANE && GUIVisualizationSettings::UseMesoSim) {
289  // do not select lanes in meso mode
290  continue;
291  }
292 #endif
293  // check whether the current object is above a previous one
294  if (layer > maxLayer) {
295  idMax = id;
296  maxLayer = layer;
297  }
298  }
300  }
301  return idMax;
302 }
303 
304 
305 std::vector<GUIGlID>
307  Boundary selection;
308  selection.add(pos);
309  selection.grow(radius);
310  const std::vector<GUIGlID> ids = getObjectsInBoundary(selection);
311  std::vector<GUIGlID> result;
312  // Interpret results
313  for (std::vector<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
314  GUIGlID id = *it;
316  if (o == 0) {
317  continue;
318  }
319  if (o->getGlID() == 0) {
320  continue;
321  }
322  //std::cout << "point selection hit " << o->getMicrosimID() << "\n";
323  GUIGlObjectType type = o->getType();
324  if (type != 0) {
325  result.push_back(id);
326  }
328  }
329  return result;
330 }
331 
332 
333 std::vector<GUIGlID>
335  const int NB_HITS_MAX = 1024 * 1024;
336  // Prepare the selection mode
337  static GUIGlID hits[NB_HITS_MAX];
338  static GLint nb_hits = 0;
339  glSelectBuffer(NB_HITS_MAX, hits);
340  glInitNames();
341 
342  Boundary oldViewPort = myChanger->getViewport(false); // backup the actual viewPort
343  myChanger->setViewport(bound);
344  applyGLTransform(false);
345 
346  // paint in select mode
348  int hits2 = doPaintGL(GL_SELECT, bound);
350  // Get the results
351  nb_hits = glRenderMode(GL_RENDER);
352  if (nb_hits == -1) {
353  myApp->setStatusBarText("Selection in boundary failed. Try to select fewer than " + toString(hits2) + " items");
354  }
355  std::vector<GUIGlID> result;
356  GLuint numNames;
357  GLuint* ptr = hits;
358  for (int i = 0; i < nb_hits; ++i) {
359  numNames = *ptr;
360  ptr += 3;
361  for (int j = 0; j < (int)numNames; j++) {
362  result.push_back(*ptr);
363  ptr++;
364  }
365  }
366  // switch viewport back to normal
367  myChanger->setViewport(oldViewPort);
368  return result;
369 }
370 
371 
372 void
374  if (id != 0) {
376  if (object != 0) {
378  pos.add(0, p2m(15));
379  GLHelper::drawTextBox(object->getFullName(), pos, GLO_MAX - 1, p2m(20), RGBColor::BLACK, RGBColor(255, 179, 0, 255));
381  }
382  }
383 }
384 
385 
386 void
388  glEnable(GL_DEPTH_TEST);
389  glLineWidth(1);
390 
391  SUMOReal xmin = myGrid->xmin();
392  SUMOReal ymin = myGrid->ymin();
393  SUMOReal ypos = ymin;
394  SUMOReal xpos = xmin;
395  SUMOReal xend = myGrid->xmax();
396  SUMOReal yend = myGrid->ymax();
397 
398  glTranslated(0, 0, .55);
399  glColor3d(0.5, 0.5, 0.5);
400  // draw horizontal lines
401  glBegin(GL_LINES);
402  for (; ypos < yend;) {
403  glVertex2d(xmin, ypos);
404  glVertex2d(xend, ypos);
406  }
407  // draw vertical lines
408  for (; xpos < xend;) {
409  glVertex2d(xpos, ymin);
410  glVertex2d(xpos, yend);
412  }
413  glEnd();
414  glTranslated(0, 0, -.55);
415 }
416 
417 
418 void
420  // compute the scale bar length
421  size_t length = 1;
422  const std::string text("10000000000");
423  size_t noDigits = 1;
424  size_t pixelSize = (size_t) m2p((SUMOReal) length);
425  while (pixelSize <= 20) {
426  length *= 10;
427  noDigits++;
428  if (noDigits > text.length()) {
429  return;
430  }
431  pixelSize = (size_t) m2p((SUMOReal) length);
432  }
433  SUMOReal lineWidth = 1.0;
434  glLineWidth((SUMOReal) lineWidth);
435 
436  glMatrixMode(GL_PROJECTION);
437  glPushMatrix();
438  glLoadIdentity();
439  glMatrixMode(GL_MODELVIEW);
440  glPushMatrix();
441  glLoadIdentity();
442 
443  // draw the scale bar
444  glDisable(GL_TEXTURE_2D);
445  glDisable(GL_ALPHA_TEST);
446  glDisable(GL_BLEND);
447  glEnable(GL_DEPTH_TEST);
448 
449  SUMOReal len = (SUMOReal) pixelSize / (SUMOReal)(getWidth() - 1) * (SUMOReal) 2.0;
450  glColor3d(0, 0, 0);
451  double o = double(15) / double(getHeight());
452  double o2 = o + o;
453  double oo = double(5) / double(getHeight());
454  glBegin(GL_LINES);
455  // vertical
456  glVertex2d(-.98, -1. + o);
457  glVertex2d(-.98 + len, -1. + o);
458  // tick at begin
459  glVertex2d(-.98, -1. + o);
460  glVertex2d(-.98, -1. + o2);
461  // tick at end
462  glVertex2d(-.98 + len, -1. + o);
463  glVertex2d(-.98 + len, -1. + o2);
464  glEnd();
465 
466  SUMOReal w = SUMOReal(35) / SUMOReal(getWidth());
467  SUMOReal h = SUMOReal(35) / SUMOReal(getHeight());
468  pfSetPosition(SUMOReal(-0.99), SUMOReal(1. - o2 - oo));
469  pfSetScaleXY(w, h);
470  glRotated(180, 1, 0, 0);
471  pfDrawString("0m");
472  glRotated(-180, 1, 0, 0);
473 
474  pfSetPosition(SUMOReal(-.99 + len), SUMOReal(1. - o2 - oo));
475  glRotated(180, 1, 0, 0);
476  pfDrawString((text.substr(0, noDigits) + "m").c_str());
477  glRotated(-180, 1, 0, 0);
478 
479  // restore matrices
480  glMatrixMode(GL_PROJECTION);
481  glPopMatrix();
482  glMatrixMode(GL_MODELVIEW);
483  glPopMatrix();
484 }
485 
486 
487 SUMOReal
489  return meter * getWidth() / myChanger->getViewport().getWidth();
490 }
491 
492 
493 SUMOReal
495  return pixel * myChanger->getViewport().getWidth() / getWidth();
496 }
497 
498 
499 void
502 }
503 
504 
505 void
506 GUISUMOAbstractView::centerTo(GUIGlID id, bool applyZoom, SUMOReal zoomDist) {
508  if (o != 0 && dynamic_cast<GUIGlObject*>(o) != 0) {
509  if (applyZoom && zoomDist < 0) {
511  } else {
512  myChanger->centerTo(o->getCenteringBoundary().getCenter(), zoomDist, applyZoom);
513  }
514  }
516 }
517 
518 
519 void
521  myChanger->setViewport(bound);
522  update();
523 }
524 
525 /*
526 bool
527 GUISUMOAbstractView::allowRotation() const
528 {
529  return myParent->allowRotation();
530 }
531 */
532 
533 void
537 }
538 
539 
540 FXbool
542  FXbool ret = FXGLCanvas::makeCurrent();
543  return ret;
544 }
545 
546 
547 long
549  if (makeCurrent()) {
550  glViewport(0, 0, getWidth() - 1, getHeight() - 1);
551  glClearColor(
556  doInit();
557  myAmInitialised = true;
558  makeNonCurrent();
559  checkSnapshots();
560  }
561  return 1;
562 }
563 
564 
565 long
567  if (!isEnabled() || !myAmInitialised) {
568  return 1;
569  }
570  if (makeCurrent()) {
571  paintGL();
572  makeNonCurrent();
573  }
574  return 1;
575 }
576 
577 
578 void
580  delete myPopup;
581  myPopup = 0;
582 }
583 
584 
585 long
586 GUISUMOAbstractView::onLeftBtnPress(FXObject*, FXSelector , void* data) {
587  destroyPopup();
588  FXEvent* e = (FXEvent*) data;
589  // check whether the selection-mode is activated
590  if (e->state & CONTROLMASK) {
591  // try to get the object-id if so
592  if (makeCurrent()) {
593  unsigned int id = getObjectUnderCursor();
594  if (id != 0) {
596  }
597  makeNonCurrent();
598  if (id != 0) {
599  // possibly, the selection-colouring is used,
600  // so we should update the screen again...
601  update();
602  }
603  }
604  }
605  myChanger->onLeftBtnPress(data);
606  grab();
607  return 1;
608 }
609 
610 
611 long
613  destroyPopup();
615  if (myApp->isGaming()) {
617  }
618  ungrab();
619  return 1;
620 }
621 
622 
623 long
624 GUISUMOAbstractView::onRightBtnPress(FXObject*, FXSelector , void* data) {
625  destroyPopup();
626  myChanger->onRightBtnPress(data);
627  grab();
628  return 1;
629 }
630 
631 
632 long
633 GUISUMOAbstractView::onRightBtnRelease(FXObject* o, FXSelector sel, void* data) {
634  destroyPopup();
635  onMouseMove(o, sel, data);
636  if (!myChanger->onRightBtnRelease(data) && !myApp->isGaming()) {
638  }
639  ungrab();
640  return 1;
641 }
642 
643 
644 long
645 GUISUMOAbstractView::onMouseWheel(FXObject*, FXSelector , void* data) {
646  if (!myApp->isGaming()) {
647  myChanger->onMouseWheel(data);
648  }
649  return 1;
650 }
651 
652 
653 long
654 GUISUMOAbstractView::onMouseMove(FXObject*, FXSelector , void* data) {
656  myChanger->onMouseMove(data);
657  }
658  const SUMOReal xpos = myChanger->getXPos();
659  const SUMOReal ypos = myChanger->getYPos();
660  const SUMOReal zoom = myChanger->getZoom();
661  if (myViewportChooser != 0 &&
662  (xpos != myChanger->getXPos() || ypos != myChanger->getYPos() || zoom != myChanger->getZoom())) {
664  }
666  return 1;
667 }
668 
669 
670 long
671 GUISUMOAbstractView::onMouseLeft(FXObject*, FXSelector , void* /*data*/) {
672  return 1;
673 }
674 
675 
676 void
678  ungrab();
679  if (!isEnabled() || !myAmInitialised) {
680  return;
681  }
682  if (makeCurrent()) {
683  // initialise the select mode
684  unsigned int id = getObjectUnderCursor();
685  GUIGlObject* o = 0;
686  if (id != 0) {
688  } else {
690  }
691  if (o != 0) {
692  myPopup = o->getPopUpMenu(*myApp, *this);
693  int x, y;
694  FXuint b;
695  myApp->getCursorPosition(x, y, b);
696  myPopup->setX(x + myApp->getX());
697  myPopup->setY(y + myApp->getY());
698  myPopup->create();
699  myPopup->show();
702  }
703  makeNonCurrent();
704  }
705 }
706 
707 
708 long
709 GUISUMOAbstractView::onKeyPress(FXObject* o, FXSelector sel, void* data) {
710  FXEvent* e = (FXEvent*) data;
711  if ((e->state & ALTMASK) != 0) {
712  setDefaultCursor(getApp()->getDefaultCursor(DEF_CROSSHAIR_CURSOR));
713  grabKeyboard();
714  }
715  /*
716  switch(e->code) {
717  case KEY_Left:
718  myChanger->move((SUMOReal) -p2m((SUMOReal) getWidth()/10), 0);
719  break;
720  case KEY_Right:
721  myChanger->move((SUMOReal) p2m((SUMOReal) getWidth()/10), 0);
722  break;
723  case KEY_Up:
724  myChanger->move(0, (SUMOReal) -p2m((SUMOReal) getHeight()/10));
725  break;
726  case KEY_Down:
727  myChanger->move(0, (SUMOReal) p2m((SUMOReal) getHeight()/10));
728  break;
729  default:
730  break;
731  }
732  */
733  return FXGLCanvas::onKeyPress(o, sel, data);
734 }
735 
736 
737 long
738 GUISUMOAbstractView::onKeyRelease(FXObject* o, FXSelector sel, void* data) {
739  FXEvent* e = (FXEvent*) data;
740  if ((e->state & ALTMASK) == 0) {
741  ungrabKeyboard();
742  setDefaultCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR));
743  }
744  return FXGLCanvas::onKeyRelease(o, sel, data);
745 }
746 
747 
748 // ------------ Dealing with snapshots
749 void
750 GUISUMOAbstractView::setSnapshots(std::map<SUMOTime, std::string> snaps) {
751  mySnapshots.insert(snaps.begin(), snaps.end());
752 }
753 
754 
755 std::string
756 GUISUMOAbstractView::makeSnapshot(const std::string& destFile) {
757  std::string errorMessage;
758  FXString ext = FXPath::extension(destFile.c_str());
759  bool useGL2PS = ext == "ps" || ext == "eps" || ext == "pdf" || ext == "svg" || ext == "tex" || ext == "pgf";
760 
761  for (int i = 0; i < 10 && !makeCurrent(); ++i) {
763  }
764  // draw
765  glClearColor(
770  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
771  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
772 
774  glEnable(GL_DITHER);
775  } else {
776  glDisable(GL_DITHER);
777  }
779  glEnable(GL_BLEND);
780  glEnable(GL_POLYGON_SMOOTH);
781  glEnable(GL_LINE_SMOOTH);
782  } else {
783  glDisable(GL_BLEND);
784  glDisable(GL_POLYGON_SMOOTH);
785  glDisable(GL_LINE_SMOOTH);
786  }
787 
789 
790  if (useGL2PS) {
791  GLint format = GL2PS_PS;
792  if (ext == "ps") {
793  format = GL2PS_PS;
794  } else if (ext == "eps") {
795  format = GL2PS_EPS;
796  } else if (ext == "pdf") {
797  format = GL2PS_PDF;
798  } else if (ext == "tex") {
799  format = GL2PS_TEX;
800  } else if (ext == "svg") {
801  format = GL2PS_SVG;
802  } else if (ext == "pgf") {
803  format = GL2PS_PGF;
804  } else {
805  return "Could not save '" + destFile + "'.\n Unrecognized format '" + std::string(ext.text()) + "'.";
806  }
807  FILE* fp = fopen(destFile.c_str(), "wb");
808  if (fp == 0) {
809  return "Could not save '" + destFile + "'.\n Could not open file for writing";
810  }
811  GLint buffsize = 0, state = GL2PS_OVERFLOW;
812  GLint viewport[4];
813  glGetIntegerv(GL_VIEWPORT, viewport);
814  while (state == GL2PS_OVERFLOW) {
815  buffsize += 1024 * 1024;
816  gl2psBeginPage(destFile.c_str(), "sumo-gui; http://sumo.dlr.de", viewport, format, GL2PS_SIMPLE_SORT,
818  GL_RGBA, 0, NULL, 0, 0, 0, buffsize, fp, "out.eps");
819  glMatrixMode(GL_MODELVIEW);
820  glPushMatrix();
821  glDisable(GL_TEXTURE_2D);
822  glDisable(GL_ALPHA_TEST);
823  glDisable(GL_BLEND);
824  glEnable(GL_DEPTH_TEST);
825  // compute lane width
826  // draw decals (if not in grabbing mode)
827  if (!myUseToolTips) {
828  drawDecals();
830  paintGLGrid();
831  }
832  }
833  glLineWidth(1);
834  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
835  Boundary viewPort = myChanger->getViewport();
836  float minB[2];
837  float maxB[2];
838  minB[0] = viewPort.xmin();
839  minB[1] = viewPort.ymin();
840  maxB[0] = viewPort.xmax();
841  maxB[1] = viewPort.ymax();
843  glEnable(GL_POLYGON_OFFSET_FILL);
844  glEnable(GL_POLYGON_OFFSET_LINE);
845  myGrid->Search(minB, maxB, *myVisualizationSettings);
846 
848  displayLegend();
849  }
850  state = gl2psEndPage();
851  glFinish();
852  }
853  fclose(fp);
854  } else {
855  doPaintGL(GL_RENDER, myChanger->getViewport());
857  displayLegend();
858  }
859  swapBuffers();
860  glFinish();
861  FXColor* buf;
862  FXMALLOC(&buf, FXColor, getWidth()*getHeight());
863  // read from the back buffer
864  glReadBuffer(GL_BACK);
865  // Read the pixels
866  glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)buf);
867  makeNonCurrent();
868  update();
869  // mirror
870  size_t mwidth = getWidth();
871  size_t mheight = getHeight();
872  FXColor* paa = buf;
873  FXColor* pbb = buf + mwidth * (mheight - 1);
874  do {
875  FXColor* pa = paa;
876  paa += mwidth;
877  FXColor* pb = pbb;
878  pbb -= mwidth;
879  do {
880  FXColor t = *pa;
881  *pa++ = *pb;
882  *pb++ = t;
883  } while (pa < paa);
884  } while (paa < pbb);
885  try {
886  if (!MFXImageHelper::saveImage(destFile, getWidth(), getHeight(), buf)) {
887  errorMessage = "Could not save '" + destFile + "'.";
888  }
889  } catch (InvalidArgument& e) {
890  errorMessage = "Could not save '" + destFile + "'.\n" + e.what();
891  }
892  FXFREE(&buf);
893  }
894  return errorMessage;
895 }
896 
897 
898 void
900  std::map<SUMOTime, std::string>::iterator snapIt = mySnapshots.find(getCurrentTimeStep());
901  if (snapIt != mySnapshots.end()) {
902  std::string error = makeSnapshot(snapIt->second);
903  if (error != "") {
904  WRITE_WARNING(error);
905  }
906  }
907 }
908 
909 
910 void
912  if (myVisualizationChanger == 0) {
917  myVisualizationChanger->create();
918  } else {
920  }
921  myVisualizationChanger->show();
922 }
923 
924 
925 void
927  if (myViewportChooser == 0) {
929  new GUIDialog_EditViewport(this, "Edit Viewport...", 0, 0);
930  myViewportChooser->create();
931  }
934  myViewportChooser->show();
935 }
936 
937 
938 void
939 GUISUMOAbstractView::setViewport(const Position& lookFrom, const Position& /* lookAt */) {
940  myChanger->setViewport(lookFrom.z(), lookFrom.x(), lookFrom.y());
941  update();
942 }
943 
944 
945 void
947  myUseToolTips = val;
948 }
949 
950 
951 
952 SUMOReal
954  return myGrid->getWidth();
955 }
956 
957 
958 SUMOReal
960  return myGrid->getHeight();
961 }
962 
963 
964 FXComboBox&
967 }
968 
969 
970 FXImage*
972 #ifdef HAVE_GDAL
973  GDALAllRegister();
974  GDALDataset* poDataset = (GDALDataset*)GDALOpen(d.filename.c_str(), GA_ReadOnly);
975  if (poDataset == 0) {
976  return 0;
977  }
978  const int xSize = poDataset->GetRasterXSize();
979  const int ySize = poDataset->GetRasterYSize();
980  // checking for geodata in the picture and try to adapt position and scale
981  if (d.width <= 0.) {
982  double adfGeoTransform[6];
983  if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) {
984  Position topLeft(adfGeoTransform[0], adfGeoTransform[3]);
985  const double horizontalSize = xSize * adfGeoTransform[1];
986  const double verticalSize = ySize * adfGeoTransform[5];
987  Position bottomRight(topLeft.x() + horizontalSize, topLeft.y() + verticalSize);
989  d.width = bottomRight.x() - topLeft.x();
990  d.height = topLeft.y() - bottomRight.y();
991  d.centerX = (topLeft.x() + bottomRight.x()) / 2;
992  d.centerY = (topLeft.y() + bottomRight.y()) / 2;
993  //WRITE_MESSAGE("proj: " + toString(poDataset->GetProjectionRef()) + " dim: " + toString(d.width) + "," + toString(d.height) + " center: " + toString(d.centerX) + "," + toString(d.centerY));
994  } else {
995  WRITE_WARNING("Could not convert coordinates in " + d.filename + ".");
996  }
997  }
998  }
999 #endif
1000  if (d.width <= 0.) {
1001  d.width = getGridWidth();
1002  d.height = getGridHeight();
1003  }
1004 
1005  // trying to read the picture
1006 #ifdef HAVE_GDAL
1007  const int picSize = xSize * ySize;
1008  FXColor* result;
1009  if (!FXMALLOC(&result, FXColor, picSize)) {
1010  WRITE_WARNING("Could not allocate memory for " + d.filename + ".");
1011  return 0;
1012  }
1013  for (int j = 0; j < picSize; j++) {
1014  result[j] = FXRGB(0, 0, 0);
1015  }
1016  bool valid = true;
1017  for (int i = 1; i <= poDataset->GetRasterCount(); i++) {
1018  GDALRasterBand* poBand = poDataset->GetRasterBand(i);
1019  int shift = -1;
1020  if (poBand->GetColorInterpretation() == GCI_RedBand) {
1021  shift = 0;
1022  } else if (poBand->GetColorInterpretation() == GCI_GreenBand) {
1023  shift = 1;
1024  } else if (poBand->GetColorInterpretation() == GCI_BlueBand) {
1025  shift = 2;
1026  } else if (poBand->GetColorInterpretation() == GCI_AlphaBand) {
1027  shift = 3;
1028  } else {
1029  WRITE_MESSAGE("Unknown color band in " + d.filename + ", maybe fox can parse it.");
1030  valid = false;
1031  break;
1032  }
1033  assert(xSize == poBand->GetXSize() && ySize == poBand->GetYSize());
1034  if (poBand->RasterIO(GF_Read, 0, 0, xSize, ySize, ((unsigned char*)result) + shift, xSize, ySize, GDT_Byte, 4, 4 * xSize) == CE_Failure) {
1035  valid = false;
1036  break;
1037  }
1038  }
1039  GDALClose(poDataset);
1040  if (valid) {
1041  return new FXImage(getApp(), result, IMAGE_OWNED | IMAGE_KEEP | IMAGE_SHMI | IMAGE_SHMP, xSize, ySize);
1042  }
1043  FXFREE(&result);
1044 #endif
1045  return 0;
1046 }
1047 
1048 
1049 void
1051  glPushName(0);
1052  myDecalsLock.lock();
1053  for (std::vector<GUISUMOAbstractView::Decal>::iterator l = myDecals.begin(); l != myDecals.end(); ++l) {
1055  if (d.skip2D) {
1056  continue;
1057  }
1058  if (!d.initialised) {
1059  try {
1060  FXImage* img = checkGDALImage(d);
1061  if (img == 0) {
1062  img = MFXImageHelper::loadImage(getApp(), d.filename);
1063  }
1065  WRITE_WARNING("Scaling '" + d.filename + "'.");
1066  }
1067  d.glID = GUITexturesHelper::add(img);
1068  d.initialised = true;
1069  d.image = img;
1070  } catch (InvalidArgument& e) {
1071  WRITE_ERROR("Could not load '" + d.filename + "'.\n" + e.what());
1072  d.skip2D = true;
1073  }
1074  }
1075  glPushMatrix();
1076  glTranslated(d.centerX, d.centerY, d.layer);
1077  glRotated(d.rot, 0, 0, 1);
1078  glColor3d(1, 1, 1);
1079  const SUMOReal halfWidth = d.width / 2.;
1080  const SUMOReal halfHeight = d.height / 2.;
1081  GUITexturesHelper::drawTexturedBox(d.glID, -halfWidth, -halfHeight, halfWidth, halfHeight);
1082  glPopMatrix();
1083  }
1084  myDecalsLock.unlock();
1085  glPopName();
1086 }
1087 
1088 
1089 // ------------ Additional visualisations
1090 bool
1092  if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1093  myAdditionallyDrawn[which] = 1;
1094  } else {
1095  myAdditionallyDrawn[which] = myAdditionallyDrawn[which] + 1;
1096  }
1097  update();
1098  return true;
1099 }
1100 
1101 
1102 bool
1104  if (getTrackedID() == static_cast<int>(which->getGlID())) {
1105  stopTrack();
1106  }
1107  if (myAdditionallyDrawn.find(which) == myAdditionallyDrawn.end()) {
1108  return false;
1109  }
1110  int cnt = myAdditionallyDrawn[which];
1111  if (cnt == 1) {
1112  myAdditionallyDrawn.erase(which);
1113  } else {
1114  myAdditionallyDrawn[which] = myAdditionallyDrawn[which] - 1;
1115  }
1116  update();
1117  return true;
1118 }
1119 
1120 
1121 void
1123  Boundary bound = myChanger->getViewport(fixRatio);
1124  glMatrixMode(GL_PROJECTION);
1125  glLoadIdentity();
1126  // as a rough rule, each GLObject is drawn at z = -GUIGlObjectType
1127  // thus, objects with a higher value will be closer (drawn on top)
1128  // // @todo last param should be 0 after modifying all glDraw methods
1129  glOrtho(0, getWidth(), 0, getHeight(), -GLO_MAX - 1, GLO_MAX + 1);
1130  glMatrixMode(GL_MODELVIEW);
1131  glLoadIdentity();
1132  SUMOReal scaleX = (SUMOReal)getWidth() / bound.getWidth();
1133  SUMOReal scaleY = (SUMOReal)getHeight() / bound.getHeight();
1134  glScaled(scaleX, scaleY, 1);
1135  glTranslated(-bound.xmin(), -bound.ymin(), 0);
1136 }
1137 
1138 /****************************************************************************/
1139 
#define GL2PS_PS
Definition: gl2ps.h:100
void paintGLGrid()
paints a grid
A decal (an image) that can be shown.
GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, GLint viewport[4], GLint format, GLint sort, GLint options, GLint colormode, GLint colorsize, GL2PSrgba *colormap, GLint nr, GLint ng, GLint nb, GLint buffersize, FILE *stream, const char *filename)
Definition: gl2ps.c:5650
virtual long onConfigure(FXObject *, FXSelector, void *)
void setValues(SUMOReal zoom, SUMOReal xoff, SUMOReal yoff)
Sets the given values into the dialog.
int pfDrawString(const char *c)
Definition: polyfonts.c:1074
SUMOReal getHeight() const
Returns the height of the boundary.
Definition: Boundary.cpp:142
GUICompleteSchemeStorage gSchemeStorage
bool showSizeLegend
Information whether the size legend shall be drawn.
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
FXImage * checkGDALImage(Decal &d)
check whether we can read image data or position with gdal
virtual void setViewport(SUMOReal zoom, SUMOReal xPos, SUMOReal yPos)=0
Sets the viewport Used for: Adapting a new viewport.
FXImage * image
The image pointer for later cleanup.
const SUMOReal SUMO_const_laneWidth
Definition: StdDefs.h:46
SUMOReal getWidth() const
Returns the width of the boudary.
Definition: Boundary.cpp:136
a polygon
void showToolTipFor(unsigned int id)
invokes the tooltip for the given object
virtual void setViewport(const Position &lookFrom, const Position &lookAt)
applies the given viewport settings
void setDefault(const std::string &name)
Makes the scheme with the given name the default.
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:106
GUIGlObjectType
virtual void centerTo(GUIGlID id, bool applyZoom, SUMOReal zoomDist=20)
centers to the chosen artifact
bool myAmInitialised
Internal information whether doInit() was called.
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:119
virtual void recenterView()
recenters the view
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 *)
virtual SUMOReal getZoom() const =0
Returns the zoom factor computed stored in this changer.
GLCanvas - ID.
Definition: GUIAppEnum.h:191
SUMOReal ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:124
The dialog to change the view (gui) settings.
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
Definition: GeoConvHelper.h:97
#define GEO_OUTPUT_ACCURACY
Definition: config.h:16
bool x2cartesian(Position &from, bool includeInBoundary=true)
GUIMainWindow * myApp
The application.
#define GL2PS_DRAW_BACKGROUND
Definition: gl2ps.h:126
SUMOReal xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:112
virtual SUMOTime getCurrentTimeStep() const
get the current simulation time
MFXMutex myDecalsLock
The mutex to use before accessing the decals list in order to avoid thread conficts.
void pfSetPosition(SUMOReal x, SUMOReal y)
Definition: polyfonts.c:480
SUMOReal p2m(SUMOReal pixel) const
pixels-to-meters conversion method
bool addAdditionalGLVisualisation(GUIGlObject *const which)
Adds an object to call its additional visualisation method.
virtual long onLeftBtnPress(FXObject *, FXSelector, void *)
bool myInEditMode
Information whether too-tip informations shall be generated.
virtual void openObjectDialog()
virtual Boundary getCenteringBoundary() const =0
Returns the boundary to which the view shall be centered in order to show the object.
virtual long onKeyRelease(FXObject *o, FXSelector sel, void *data)
GUIGlObject * getNetObject() const
Returns the network object.
SUMOReal getGridHeight() const
int glID
The gl-id of the texture that holds this image.
void setSnapshots(std::map< SUMOTime, std::string > snaps)
Sets the snapshot time to file map.
static const RGBColor BLACK
Definition: RGBColor.h:196
SUMOReal width
The width of the image (net coordinates in x-direction, in m)
GUIDialog_ViewSettings * myVisualizationChanger
bool isGaming() const
return whether the gui is in gaming mode
Definition: GUIMainWindow.h:77
GUIDialog_EditViewport * myViewportChooser
A RT-tree for efficient storing of SUMO&#39;s GL-objects.
Definition: SUMORTree.h:74
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
bool dither
Information whether dithering shall be enabled.
GUIGlID getGlID() const
Returns the numerical id of the object.
Definition: GUIGlObject.h:115
SUMOReal xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:118
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
int myMouseHotspotX
Offset to the mouse-hotspot from the mouse position.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
FXDEFMAP(GUIDialog_AppSettings) GUIDialog_AppSettingsMap[]
SUMOReal scale
information about a lane&#39;s width (temporary, used for a single view)
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:91
virtual int getTrackedID() const
FXLabel & getCartesianLabel()
std::vector< GUIGlID > getObjectsAtPosition(Position pos, SUMOReal radius)
returns the ids of the object at position within the given (rectangular) radius using GL_SELECT ...
std::vector< Decal > myDecals
The list of decals to show.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
Definition: GUIGlObject.h:159
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 int doPaintGL(int, const Boundary &)
bool removeAdditionalGLVisualisation(GUIGlObject *const which)
Removes an object from the list of objects that show additional things.
#define max(a, b)
Definition: polyfonts.c:65
virtual long onPaint(FXObject *, FXSelector, void *)
std::string name
The name of this setting.
std::map< GUIGlObject *, int > myAdditionallyDrawn
List of objects for which GUIGlObject::drawGLAdditional is called.
Boundary getVisibleBoundary() const
virtual long onMiddleBtnPress(FXObject *, FXSelector, void *)
static void drawTexturedBox(unsigned int which, SUMOReal size)
Draws a named texture as a box with the given size.
virtual void setStatusBarText(const std::string &)
Definition: GUIMainWindow.h:71
virtual long onKeyPress(FXObject *o, FXSelector sel, void *data)
#define GL2PS_PGF
Definition: gl2ps.h:105
virtual SUMOReal getXPos() const =0
Returns the x-offset of the field to show stored in this changer.
virtual long onMiddleBtnRelease(FXObject *, FXSelector, void *)
static void sleep(long ms)
bool isInEditMode()
returns true, if the edit button was pressed
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
SUMOReal centerY
The center of the image in y-direction (net coordinates, in m)
#define GL2PS_USE_CURRENT_VIEWPORT
Definition: gl2ps.h:135
virtual GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)=0
Returns an own popup-menu.
FXComboBox & getColoringSchemesCombo()
GL2PSDLL_API GLint gl2psEndPage(void)
Definition: gl2ps.c:5817
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:99
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
SUMOReal z() const
Returns the z-position.
Definition: Position.h:73
virtual bool onLeftBtnRelease(void *data)
FXComboBox & getColoringSchemesCombo()
bool initialised
Whether this image was initialised (inserted as a texture)
A 2D- or 3D-Shape.
Definition: Shape.h:46
virtual bool onRightBtnRelease(void *data)
FXLabel & getGeoLabel()
virtual long onMouseWheel(FXObject *, FXSelector, void *)
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.
#define GL2PS_TEX
Definition: gl2ps.h:102
void saveViewport(const SUMOReal x, const SUMOReal y, const SUMOReal zoom)
Makes the given viewport the default.
void pfSetScaleXY(SUMOReal sx, SUMOReal sy)
Definition: polyfonts.c:472
SUMOReal gridXSize
Information about the grid spacings.
std::map< SUMOTime, std::string > mySnapshots
static FXbool saveImage(const std::string &file, int width, int height, FXColor *data)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
void updatePositionInformation() const
#define GL2PS_SIMPLE_SORT
Definition: gl2ps.h:110
static void drawTextBox(const std::string &text, const Position &pos, const SUMOReal layer, const SUMOReal size, const RGBColor &txtColor=RGBColor::BLACK, const RGBColor &bgColor=RGBColor::WHITE, const RGBColor &borderColor=RGBColor::BLACK, const SUMOReal angle=0)
draw Text box with given parameters
Definition: GLHelper.cpp:396
GUIPerspectiveChanger * myChanger
The perspective changer.
std::string makeSnapshot(const std::string &destFile)
Takes a snapshots and writes it into the given file.
virtual void onLeftBtnPress(void *data)
GUIGLObjectPopupMenu * myPopup
The current popup-menu.
RGBColor backgroundColor
The background color to use.
void destroyPopup()
destoys the popup
bool antialiase
Information whether antialiase shall be enabled.
FXint myWindowCursorPositionX
Position of the cursor relative to the window.
Boundary getViewport(bool fixRatio=true)
unsigned int GUIGlID
Definition: GUIGlObject.h:48
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
void unlock()
release mutex lock
Definition: MFXMutex.cpp:96
virtual void showViewportEditor()
FXbool makeCurrent()
A reimplementation due to some internal reasons.
SUMOReal height
The height of the image (net coordinates in y-direction, in m)
void applyGLTransform(bool fixRatio=true)
#define GL2PS_PDF
Definition: gl2ps.h:103
virtual long onLeftBtnRelease(FXObject *, FXSelector, void *)
void add(SUMOReal x, SUMOReal y)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:76
SUMOReal centerX
The center of the image in x-direction (net coordinates, in m)
GUIVisualizationSettings & getDefault()
Returns the default scheme.
Boundary & grow(SUMOReal by)
extends the boundary by the given amount
Definition: Boundary.cpp:200
void setViewport(GUISUMOAbstractView *view)
Sets the default viewport.
GUIVisualizationSettings * myVisualizationSettings
virtual void onMouseWheel(void *data)
SUMOReal m2p(SUMOReal meter) const
meter-to-pixels conversion method
void paintGL()
performs the painting of the simulation
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
void setWindowCursorPosition(FXint x, FXint y)
Returns the information whether rotation is allowd.
void setCurrent(GUIVisualizationSettings *settings)
Sets current settings (called if reopened)
static FXImage * loadImage(FXApp *a, const std::string &file)
#define GL2PS_SVG
Definition: gl2ps.h:104
SUMOReal getGridWidth() const
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:86
void text()
Definition: gl2psTest.c:260
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
SUMOReal layer
The layer of the image.
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:120
virtual void centerTo(const Position &pos, SUMOReal 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.
bool skip2D
Whether this image should be skipped in 2D-views.
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:83
#define SUMOReal
Definition: config.h:218
virtual void onMouseMove(void *data)
void updateToolTip()
A method that updates the tooltip.
A dialog to change the viewport.
SUMOReal ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:130
virtual void onRightBtnPress(void *data)
virtual void onGamingClick(Position)
empty max
void unblockObject(GUIGlID id)
Marks an object as unblocked.
virtual SUMOReal getYPos() const =0
Returns the y-offset of the field to show stored in this changer.
virtual long onRightBtnPress(FXObject *, FXSelector, void *)
bool haveGrabbed() const
Returns the information whether one of the spin dialers is grabbed.
virtual long onMouseLeft(FXObject *, FXSelector, void *)
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
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
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:201
GUIGlObject * getObjectBlocking(GUIGlID id)
Returns the object from the container locking it.
const std::string & getFullName() const
Returns the full name appearing in the tool tip.
Definition: GUIGlObject.h:107
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:75
GUISelectedStorage gSelected
A global holder of selected objects.
#define GL2PS_OVERFLOW
Definition: gl2ps.h:120
SUMOReal rot
The rotation of the image in the ground plane (in degrees)
GUIGlChildWindow * myParent
The parent window.
virtual long onRightBtnRelease(FXObject *, FXSelector, void *)
static const Position INVALID
Definition: Position.h:262
std::vector< GUIGlID > getObjectsInBoundary(const Boundary &bound)
returns the ids of all objects in the given boundary
void setOldValues(const Position &lookFrom, const Position &lookAt)
Resets old values.
#define GL2PS_EPS
Definition: gl2ps.h:101