source: geovis/trunk/Renderer.h @ 6673

Last change on this file since 6673 was 6649, checked in by ldelgass, 8 years ago

Fix validation of map extents

File size: 23.2 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2004-2015  HUBzero Foundation, LLC
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#ifndef GEOVIS_RENDERER_H
9#define GEOVIS_RENDERER_H
10
11#include <sys/time.h> // For struct timeval
12#include <ctime> // For time_t
13#include <string>
14#include <vector>
15#include <tr1/unordered_map>
16#include <typeinfo>
17
18#include <osg/ref_ptr>
19#include <osg/Node>
20#include <osg/Image>
21#include <osg/TransferFunction>
22#include <osgText/String>
23#include <osgViewer/Viewer>
24#include <osgGA/StateSetManipulator>
25#include <osgUtil/IncrementalCompileOperation>
26
27#include <osgEarth/Version>
28#include <osgEarth/StringUtils>
29#include <osgEarth/Map>
30#include <osgEarth/Viewpoint>
31#include <osgEarth/ImageLayer>
32#include <osgEarth/ElevationLayer>
33#include <osgEarth/ModelLayer>
34#include <osgEarth/MaskLayer>
35#include <osgEarth/TileSource>
36#include <osgEarth/ModelSource>
37#include <osgEarth/GeoData>
38#include <osgEarthAnnotation/AnnotationNode>
39#include <osgEarthAnnotation/FeatureNode>
40#include <osgEarthUtil/Sky>
41#include <osgEarthUtil/RTTPicker>
42#include <osgEarthUtil/EarthManipulator>
43#include <osgEarthUtil/MouseCoordsTool>
44#include <osgEarthUtil/Controls>
45#include <osgEarthUtil/Formatter>
46#include <osgEarthUtil/MGRSFormatter>
47#include <osgEarthUtil/AutoClipPlaneHandler>
48#include <osgEarthUtil/VerticalScale>
49
50#define USE_RTT_PICKER
51
52#include "Types.h"
53#include "Trace.h"
54#include "MouseCoordsTool.h"
55#include "ScaleBar.h"
56#include "Placard.h"
57
58// Controls if TGA format is sent to client
59//#define RENDER_TARGA
60#define TARGA_BYTES_PER_PIXEL 3
61
62namespace GeoVis {
63
64class ScreenCaptureCallback : public osg::Camera::DrawCallback
65{
66public:
67    ScreenCaptureCallback(osg::Texture2D *texture = NULL) :
68        osg::Camera::DrawCallback(),
69        _texture(texture)
70    {
71        _image = new osg::Image;
72    }
73
74    virtual void operator()(osg::RenderInfo &renderInfo) const
75    {
76        FRAME("Enter ScreenCaptureCallback");
77        int width, height;
78        if (renderInfo.getCurrentCamera() == NULL) {
79            ERROR("No camera");
80            return;
81        }
82        if (renderInfo.getCurrentCamera()->getViewport() == NULL) {
83            ERROR("No viewport");
84            return;
85        }
86        width = (int)renderInfo.getCurrentCamera()->getViewport()->width();
87        height = (int)renderInfo.getCurrentCamera()->getViewport()->height();
88        FRAME("readPixels: %d x %d", width, height);
89#if 0 //USE_OFFSCREEN_FRAMEBUFFER
90        _image = _texture->getImage();
91#else
92#ifdef RENDER_TARGA
93        _image->readPixels(0, 0, width, height,
94                           GL_BGR, GL_UNSIGNED_BYTE);
95#else
96        _image->readPixels(0, 0, width, height,
97                           GL_RGB, GL_UNSIGNED_BYTE);
98#endif
99#endif
100    }
101
102    osg::Image *getImage()
103    {
104        return _image.get();
105    }
106
107    osg::Texture2D *getTexture()
108    {
109        return _texture.get();
110    }
111
112private:
113    osg::ref_ptr<osg::Texture2D> _texture;
114    osg::ref_ptr<osg::Image> _image;
115};
116
117/**
118 * \brief GIS Renderer
119 */
120class Renderer
121{
122public:
123    typedef std::string ColorMapId;
124    typedef std::string ViewpointId;
125
126    enum GraticuleType {
127        GRATICULE_UTM,
128        GRATICULE_MGRS,
129        GRATICULE_GEODETIC,
130        GRATICULE_SHADER
131    };
132
133    enum CoordinateDisplayType {
134        COORDS_LATLONG_DECIMAL_DEGREES,
135        COORDS_LATLONG_DEGREES_DECIMAL_MINUTES,
136        COORDS_LATLONG_DEGREES_MINUTES_SECONDS,
137        COORDS_MGRS
138    };
139
140    enum SelectMode {
141        SELECT_OFF,
142        SELECT_ON
143    };
144
145    Renderer();
146    virtual ~Renderer();
147
148    void setResourcePath(const std::string& path)
149    {
150        TRACE("Set resource path to %s", path.c_str());
151        _resourcePath = path;
152    }
153
154    void setCacheBaseDirectory(const std::string& path)
155    {
156        TRACE("Set cache base dir to %s", path.c_str());
157        _cacheBaseDir = path;
158    }
159
160    std::string getCacheDirectory() const
161    {
162        return _cacheDir;
163    }
164
165    void setupCache();
166
167    std::string getIconFile(const char *name) const;
168
169    std::string getBaseImage() const;
170
171    std::string getPinIcon() const;
172
173    void setAttribution(const std::string& attrib);
174
175    // Colormaps
176
177    void addColorMap(const ColorMapId& id, osg::TransferFunction1D *xfer);
178
179    void deleteColorMap(const ColorMapId& id);
180
181    void setColorMapNumberOfTableEntries(const ColorMapId& id, int numEntries);
182
183    bool renderColorMap(const ColorMapId& id, int width, int height,
184                        osg::Image *imgData,
185                        bool opaque, float bgColor[3],
186                        bool bgr = false,
187                        int bytesPerPixel = 3) const;
188
189    void getColorMapRange(const ColorMapId& id, float *min, float *max) const;
190
191    std::string getColorMapFilePath(const ColorMapId& id) const;
192
193    void saveCLRFile(const std::string& path, osg::TransferFunction1D *xfer);
194
195    // Scene
196
197    void loadEarthFile(const char *path);
198
199    void resetMap(osgEarth::MapOptions::CoordinateSystemType type,
200                  const osg::Vec4f& bgColor = osg::Vec4f(1,1,1,1),
201                  const char *profile = NULL,
202                  double bounds[4] = NULL,
203                  const char *boundsSRS = NULL);
204
205    void clearMap();
206
207    // Map options
208
209    void setCoordinateReadout(bool state,
210                              CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
211                              int precision = -1);
212
213    void setReadout(int mouseX, int mouseY);
214
215    void clearReadout();
216
217    void setScaleBar(bool state);
218
219    void setScaleBarUnits(ScaleBarUnits units);
220
221    void setGraticule(bool enable, GraticuleType type = GRATICULE_SHADER);
222
223    void setViewerLightType(osg::View::LightingMode mode);
224
225    void setLighting(bool state);
226
227    void setTerrainColor(const osg::Vec4f& color);
228
229    void setTerrainEdges(bool state) {}
230
231    void setTerrainLineColor(const osg::Vec4f& color) {}
232
233    void setTerrainLineWidth(float width) {}
234
235    void setTerrainLighting(bool state);
236
237    void setTerrainVerticalScale(double scale);
238
239    void setTerrainWireframe(bool state);
240
241    void setEphemerisTime(time_t utcTime);
242
243    void setEphemerisTime(int year, int month, int day, double hours);
244
245    void setSkyAmbient(float ambientLevel);
246
247    // Image raster layers
248
249    int getNumImageLayers() const
250    {
251        return (_map.valid() ? _map->getNumImageLayers() : 0);
252    }
253
254    void getImageLayerNames(std::vector<std::string>& names) const
255    {
256        if (_map.valid()) {
257            osgEarth::ImageLayerVector layerVector;
258            _map->getImageLayers(layerVector);
259            osgEarth::ImageLayerVector::const_iterator itr;
260            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
261                //osgEarth::UID uid = (*itr)->getUID();
262                names.push_back((*itr)->getName());
263            }
264        }
265    }
266
267    bool addImageLayer(const char *name,
268                       osgEarth::TileSourceOptions& opts,
269                       unsigned int pos = UINT_MAX,
270                       bool enableCache = true,
271                       bool coverage = false,
272                       bool makeShared = false,
273                       bool visible = true,
274                       unsigned int minLOD = 0,
275                       unsigned int maxLOD = 23);
276
277    void removeImageLayer(const char *name);
278
279    void moveImageLayer(const char *name, unsigned int pos);
280
281    bool getImageLayerExtent(const char *name, osgEarth::GeoExtent &ext);
282
283    void setImageLayerVisibleRange(const char *name, float min, float max);
284
285    void setImageLayerLODRange(const char *name, int min, int max);
286
287    void setImageLayerOpacity(const char *name, double opacity);
288
289    void setImageLayerVisibility(const char *name, bool state);
290
291    void addColorFilter(const char *name, const char *shader);
292
293    void removeColorFilter(const char *name, int idx = -1);
294
295    // Sequence control
296
297    bool layerHasSequence(const char *name);
298
299    bool sequencePause(const char *name);
300
301    bool sequencePlay(const char *name);
302
303    bool sequenceSeek(const char *name, unsigned int frame);
304
305    // Elevation raster layers
306
307    int getNumElevationLayers() const
308    {
309        return (_map.valid() ? _map->getNumElevationLayers() : 0);
310    }
311
312    void getElevationLayerNames(std::vector<std::string>& names) const
313    {
314        if (_map.valid()) {
315            osgEarth::ElevationLayerVector layerVector;
316            _map->getElevationLayers(layerVector);
317            osgEarth::ElevationLayerVector::const_iterator itr;
318            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
319                //osgEarth::UID uid = (*itr)->getUID();
320                names.push_back((*itr)->getName());
321            }
322        }
323    }
324
325    void addElevationLayer(const char *name,
326                           osgEarth::TileSourceOptions& opts,
327                           unsigned int pos = UINT_MAX,
328                           bool enableCache = true,
329                           bool visible = true,
330                           const char *verticalDatum = NULL,
331                           unsigned int minLOD = 0,
332                           unsigned int maxLOD = 23);
333
334    void removeElevationLayer(const char *name);
335
336    void moveElevationLayer(const char *name, unsigned int pos);
337
338    bool getElevationLayerExtent(const char *name, osgEarth::GeoExtent &ext);
339
340    void setElevationLayerVisibleRange(const char *name, float min, float max);
341
342    void setElevationLayerVisibility(const char *name, bool state);
343
344    // Terrain mask layers
345
346    int getNumTerrainMaskLayers() const
347    {
348        if (!_map.valid()) return 0;
349
350        osgEarth::MaskLayerVector layers;
351        _map->getTerrainMaskLayers(layers);
352        return (int)layers.size();
353    }
354
355    void getTerrainMaskLayerNames(std::vector<std::string>& names) const
356    {
357        if (_map.valid()) {
358            osgEarth::MaskLayerVector layerVector;
359            _map->getTerrainMaskLayers(layerVector);
360            osgEarth::MaskLayerVector::const_iterator itr;
361            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
362                //osgEarth::UID uid = (*itr)->getUID();
363                names.push_back((*itr)->getName());
364            }
365        }
366    }
367
368    osgEarth::MaskLayer *getTerrainMaskLayerByName(const std::string& name)
369    {
370        if (!_map.valid())
371            return NULL;
372
373        osgEarth::MaskLayerVector layerVector;
374        _map->getTerrainMaskLayers(layerVector);
375        osgEarth::MaskLayerVector::iterator itr;
376        for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
377            if ((*itr)->getName() == name) {
378                return (*itr).get();
379            }
380        }
381        return NULL;
382    }
383
384    void addTerrainMaskLayer(const char *name,
385                             osgEarth::MaskSourceOptions& opts,
386                             unsigned int minLOD = 0);
387
388    void removeTerrainMaskLayer(const char *name);
389
390    bool getTerrainMaskLayerExtent(const char *name, osgEarth::GeoExtent &ext);
391
392    // Model layers
393
394    int getNumModelLayers() const
395    {
396        return (_map.valid() ? _map->getNumModelLayers() : 0);
397    }
398
399    void getModelLayerNames(std::vector<std::string>& names) const
400    {
401        if (_map.valid()) {
402            osgEarth::ModelLayerVector layerVector;
403            _map->getModelLayers(layerVector);
404            osgEarth::ModelLayerVector::const_iterator itr;
405            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
406                //osgEarth::UID uid = (*itr)->getUID();
407                names.push_back((*itr)->getName());
408            }
409        }
410    }
411
412    void addModelLayer(const char *name,
413                       osgEarth::ModelSourceOptions& opts,
414                       unsigned int pos = UINT_MAX,
415                       bool enableCache = true,
416                       bool lighting = true,
417                       bool visible = true,
418                       bool terrainPatch = false);
419
420    void removeModelLayer(const char *name);
421
422    void moveModelLayer(const char *name, unsigned int pos);
423
424    bool getModelLayerExtent(const char *name, osgEarth::GeoExtent &ext);
425
426    //void setModelLayerVisibleRange(const char *name, float min, float max);
427
428    void setModelLayerOpacity(const char *name, double opacity);
429
430    void setModelLayerVisibility(const char *name, bool state);
431
432    // Render window
433
434    void setWindowSize(int width, int height);
435
436    int getWindowWidth() const
437    {
438        return _windowWidth;
439    }
440
441    int getWindowHeight() const
442    {
443        return _windowHeight;
444    }
445
446    // Camera
447
448    void saveNamedViewpoint(const char *name);
449
450    bool restoreNamedViewpoint(const char *name, double durationSecs);
451
452    bool removeNamedViewpoint(const char *name);
453
454    osgEarth::Viewpoint getViewpoint();
455
456    void setViewpoint(const osgEarth::Viewpoint& v, double durationSecs = 0.0);
457
458    double getMaxDistanceFromExtent(const osgEarth::GeoExtent& extent);
459
460    void setViewpointFromExtent(const osgEarth::GeoExtent& ext,
461                                double durationSecs = 0.0);
462
463    void setViewpointFromRect(double xmin, double ymin,
464                              double xmax, double ymax,
465                              const osgEarth::SpatialReference *srs = NULL,
466                              double durationSecs = 0.0);
467
468    void resetCamera(bool resetOrientation = true);
469
470    void setCameraOrientation(const double quat[4], bool absolute = true);
471
472    void panCamera(double x, double y);
473
474    void rotateCamera(double x, double y);
475
476    void zoomCamera(double z);
477
478    void setCameraDistance(double dist);
479
480    void setLODScale(float scale);
481
482    // Keyboard events
483
484    void keyPress(int key);
485
486    void keyRelease(int key);
487
488    // Mouse events
489
490    void setThrowingEnabled(bool state);
491
492    void mouseClick(int button, double x, double y);
493
494    void mouseDoubleClick(int button, double x, double y);
495
496    void mouseDrag(int button, double x, double y);
497
498    void mouseRelease(int button, double x, double y);
499
500    void mouseMotion(double x, double y);
501
502    void mouseScroll(int direction);
503
504    void pickPending(bool value)
505    { _pickPending = value; }
506
507    // Rendering an image
508
509    void setBackgroundColor(float color[3]);
510
511    void eventuallyRender();
512
513    bool render();
514
515    osg::Image *getRenderedFrame();
516
517    bool mapMouseCoords(float mouseX, float mouseY,
518                        osgEarth::GeoPoint &pt, bool invertY = true);
519
520    double computeMapScale();
521
522    const osgEarth::SpatialReference *getMapSRS()
523    {
524        if (_mapNode.valid()) {
525            return _mapNode->getMapSRS();
526        } else {
527            return NULL;
528        }
529    }
530
531    void addPlaceNode(double latitude, double longitude, char *labelText);
532
533    void hoverPlaceNode(int x, int y, bool invertY = true);
534
535    void deletePlaceNode(int x, int y, bool invertY = true);
536
537    bool getMousePoint(double *x, double *y, double *z)
538    {
539        return (_coordsCallback.valid() && _coordsCallback->report(x, y, z));
540    }
541
542    bool mouseToLatLong(int mouseX, int mouseY,
543                        double *latitude, double *longitude);
544
545    bool getWorldCoords(const osgEarth::GeoPoint& mapPt, osg::Vec3d *world);
546
547    bool worldToScreen(const osg::Vec3d& world, osg::Vec3d *screen,
548                       bool invertY = true);
549
550    bool worldToScreen(std::vector<osg::Vec3d>& coords, bool invertY = true);
551
552    void setMaximumFrameRateInHertz(double rate)
553    {
554        if (rate > 60.0)
555            rate = 60.0;
556        if (rate < 0.25)
557            rate = 0.25;
558        _minFrameTime = 1.0/rate;
559        if (_viewer.valid()) {
560            osgUtil::IncrementalCompileOperation *op =
561                _viewer->getDatabasePager()->getIncrementalCompileOperation();
562            if (op != NULL) {
563                TRACE("Setting DB Pager target frame rate to %g", rate);
564                op->setTargetFrameRate(rate);
565            }
566        }
567        TRACE("Frame rate target: %.2f Hz", (float)getMaximumFrameRateInHertz());
568        TRACE("Frame time target: %.2f msec", _minFrameTime * 1000.0f);
569    }
570
571    void setMaximumBitrate(double bitsPerSecond)
572    {
573        TRACE("Setting max bitrate to %g", bitsPerSecond);
574        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
575        double fps = bitsPerSecond / ((double)bitsPerFrame);
576        setMaximumFrameRateInHertz(fps);
577        TRACE("Bandwidth target: %.2f Mbps", (float)(getMaximumBitrate()/1.0e6));
578    }
579
580    double getMaximumFrameRateInHertz()
581    {
582        return (1.0/_minFrameTime);
583    }
584
585    double getMaximumBitrate()
586    {
587        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
588        return ((double)bitsPerFrame * getMaximumFrameRateInHertz());
589    }
590
591    void markFrameStart();
592
593    void markFrameEnd();
594
595    void setIdleTimeout(long timeout)
596    {
597        if (timeout != -1L &&
598            (double)timeout < _minFrameTime) {
599            ERROR("Timeout must be more than %g sec", _minFrameTime);
600            return;
601        }
602        TRACE("Setting idle timeout to %ld sec", timeout);
603        _idleTimeout = timeout;
604    }
605
606    long getIdleTimeout()
607    {
608        return _idleTimeout;
609    }
610
611    void getTimeout(struct timeval *tv);
612
613    void mapNodeUpdate();
614
615    std::string getCanonicalPath(const std::string& url) const;
616
617    void writeScene(const std::string& file);
618
619    // Placard info window
620
621    void enablePlacard(const char *layerName, bool state);
622
623    void setPlacardConfig(const Placard& placardConf, const char *layerName);
624
625    Placard getPlacardConfig(const char *layerName)
626    {
627        Placard ret;
628        PlacardHashmap::iterator itr = _placardConfigs.find(layerName);
629        if (itr != _placardConfigs.end()) {
630            ret = itr->second;
631        }
632        return ret;
633    }
634
635    // Selection
636
637    void setSelectMode(SelectMode mode);
638
639    void selectFeatures(std::vector<unsigned long>& featureIDs,
640                        const char *layerName, bool clear = true);
641
642    void deselectFeatures(std::vector<unsigned long>& featureIDs,
643                          const char *layerName);
644
645    void addPlacard(const osgEarth::GeoPoint& location,
646                    osgEarth::Features::Feature *feature,
647                    const char *layerName);
648
649    void clearSelection();
650
651    void addRhumbBox(double latMin, double latMax,
652                     double longMin, double longMax);
653
654    void initBoxSelection(int x, int y);
655    void updateBoxSelection(int x, int y);
656    void getBoxSelection(double *latMin, double *latMax,
657                         double *longMin, double *longMax,
658                         const osgEarth::SpatialReference *outSRS = NULL);
659    void clearBoxSelection();
660
661    // These methods are based on the deprecated annotation API
662    bool select(osgEarth::Annotation::AnnotationNode *node)
663    {
664        if (_selected.find(node) == _selected.end()) {
665            _selected.insert(node);
666            return true;
667        } else {
668            return false;
669        }
670    }
671    std::set<osgEarth::Annotation::AnnotationNode*>& getHovered()
672    { return _hovered; }
673    std::set<osgEarth::Annotation::AnnotationNode*>& getSelected()
674    { return _selected; }
675
676    // Scene Graph
677
678    osg::Group *getSceneRoot()
679    { return _sceneRoot.get(); }
680    osgEarth::MapNode *getMapNode()
681    { return _mapNode.get(); }
682    osg::Group *getAnnotations()
683    {
684        initAnnotations();
685        return _annotations.get();
686    }
687    osg::Group *getPlaceNodes()
688    {
689        initAnnotations();
690        return _placeNodes.get();
691    }
692
693private:
694    typedef std::tr1::unordered_map<ColorMapId, osg::ref_ptr<osg::TransferFunction1D> > ColorMapHashmap;
695    typedef std::tr1::unordered_map<ViewpointId, osgEarth::Viewpoint> ViewpointHashmap;
696    typedef std::tr1::unordered_map<std::string, Placard> PlacardHashmap;
697    typedef std::tr1::unordered_map<std::string, std::set<unsigned long> > FeatureSelectionHashmap;
698
699    void initAnnotations();
700
701    void clearSelectionAnnotationNodes();
702
703    void initViewer();
704
705    void finalizeViewer();
706   
707    void initControls();
708
709    void updateDebugLabel();
710
711    void initEarthManipulator();
712
713    void initMouseCoordsTool(CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
714                             int precision = -1);
715
716    osgEarth::Util::MGRSFormatter::Precision getMGRSPrecision(int precisionInMeters);
717
718    void initColorMaps();
719
720    void initCamera();
721
722    bool isPagerIdle();
723
724    bool checkNeedToDoFrame();
725
726    osgGA::EventQueue *getEventQueue();
727
728    bool _needsRedraw;
729    int _windowWidth, _windowHeight;
730    double _mapScale;
731    float _bgColor[3];
732
733    long _idleTimeout;
734    double _minFrameTime;
735    double _lastFrameTime;
736    double _renderTime;
737    osg::Timer_t _startFrameTime;
738    osg::Timer_t _renderStartTime;
739    osg::Timer_t _renderStopTime;
740
741    ColorMapHashmap _colorMaps;
742
743    std::string _resourcePath;
744    std::string _cacheBaseDir;
745    std::string _cacheDir;
746    std::string _baseURI;
747    std::string _attribution;
748
749    osg::ref_ptr<osg::Group> _sceneRoot;
750    osg::ref_ptr<osg::Group> _graticule;
751    osg::ref_ptr<osg::Group> _annotations;
752    PlacardHashmap _placardConfigs;
753    double _anchorLat, _anchorLong;
754    SelectMode _selectMode;
755    osg::ref_ptr<osgEarth::Annotation::FeatureNode> _selectionBox;
756#ifdef USE_RTT_PICKER
757    osg::ref_ptr<osgEarth::Util::RTTPicker> _picker;
758#endif
759    bool _pickPending;
760    osg::ref_ptr<osg::Group> _placeNodes;
761    FeatureSelectionHashmap _selectedFeatures;
762    std::set<osgEarth::Annotation::AnnotationNode *> _hovered;
763    std::set<osgEarth::Annotation::AnnotationNode *> _selected;
764    osg::ref_ptr<osgEarth::MapNode> _mapNode;
765    osg::ref_ptr<osgEarth::Map> _map;
766    osg::ref_ptr<osgEarth::Util::SkyNode> _skyNode;
767    osg::ref_ptr<osgViewer::Viewer> _viewer;
768    osg::ref_ptr<ScreenCaptureCallback> _captureCallback;
769    osg::ref_ptr<osgEarth::Util::AutoClipPlaneCullCallback> _clipPlaneCullCallback;
770    osg::ref_ptr<osgEarth::Util::Controls::HBox> _coordsBox;
771    osg::ref_ptr<MouseCoordsTool> _mouseCoordsTool;
772    osg::ref_ptr<MouseCoordsCallback> _coordsCallback;
773    osg::ref_ptr<osgEarth::Util::Controls::HBox> _debugBox;
774    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _debugLabel;
775    osg::ref_ptr<osgEarth::Util::Controls::HBox> _copyrightScaleBox;
776    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _copyrightLabel;
777    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _scaleLabel;
778    osg::ref_ptr<osgEarth::Util::Controls::Frame> _scaleBar;
779    ScaleBarUnits _scaleBarUnits;
780    osg::ref_ptr<osgEarth::Util::EarthManipulator> _manipulator;
781    osg::ref_ptr<osgGA::StateSetManipulator> _stateManip;
782    osg::ref_ptr<osgEarth::Util::VerticalScale> _verticalScale;
783    ViewpointHashmap _viewpoints;
784};
785
786class MapNodeCallback : public osg::NodeCallback
787{
788public:
789    MapNodeCallback(Renderer *renderer) :
790        _renderer(renderer)
791    {}
792
793    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
794    {
795        _renderer->mapNodeUpdate();
796        traverse(node, nv);
797    }
798private:
799    Renderer *_renderer;
800};
801
802class SelectPlaceNodesVisitor : public osg::NodeVisitor
803{
804public:
805    SelectPlaceNodesVisitor(Renderer *renderer,
806                            double latMin, double latMax,
807                            double longMin, double longMax) :
808        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
809        _renderer(renderer),
810        _latMin(latMin), _latMax(latMax),
811        _longMin(longMin), _longMax(longMax)
812    {}
813
814    virtual void apply(osg::Node& node);
815
816private:
817    Renderer *_renderer;
818    double _latMin, _latMax, _longMin, _longMax;
819};
820
821}
822
823#endif
Note: See TracBrowser for help on using the repository browser.