/* -*-c++-*- */ /* osgEarth - Geospatial SDK for OpenSceneGraph * Copyright 2020 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ #pragma once #include #include #include #include #include #include #include #include namespace osgEarth { namespace Util { using namespace osgEarth; using namespace osgEarth::Util; /** * Graticule that shows lat/long lines and automatically places labels. */ class OSGEARTH_EXPORT GeodeticGraticule : public VisibleLayer { public: // serialization class OSGEARTH_EXPORT Options : public VisibleLayer::Options { public: META_LayerOptions(osgEarth, Options, VisibleLayer::Options); OE_OPTION(Color, color, Color(Color::Yellow, 0.5f)); OE_OPTION(Style, gridLabelStyle); OE_OPTION(Style, edgeLabelStyle); OE_OPTION(float, lineWidth, 2.0f); OE_OPTION(int, gridLines, 10); OE_OPTION(std::string, resolutions, { "10 5 2.5 1.0 0.5 0.25 0.125 0.0625 0.03125" }); OE_OPTION(bool, gridLinesVisible, true); OE_OPTION(bool, gridLabelsVisible, true); OE_OPTION(bool, edgeLabelsVisible, true); virtual Config getConfig() const; private: void fromConfig( const Config& conf ); }; public: META_Layer(osgEarth, GeodeticGraticule, Options, VisibleLayer, GeodeticGraticule); //! Rebuild the graticule after changing options. void dirty(); //! Grid line color void setColor(const Color& value); const Color& getColor() const; //! Grid line width in pixels void setLineWidth(const float& value); const float& getLineWidth() const; //! A target number of grid lines to view on screen at once. void setNumGridLines(const int& value); const int& getNumGridLines() const; //! Get whether to show the grid lines bool getGridLinesVisible() const; //! Set whether to show the grid lines void setGridLinesVisible(bool gridLinesVisible); //! Get whether to show the grid labels bool getGridLabelsVisible() const; //! Set whether to show the grid labels void setGridLabelsVisible(bool gridLabelsVisible); //! Get whether to show the edge labels bool getEdgeLabelsVisible() const; //! Set whether to show the edge labels void setEdgeLabelsVisible(bool edgeLabelsVisible); //! Set the styling to use for grid labels void setGridLabelStyle(const Style& style); const Style& getGridLabelStyle() const { return options().gridLabelStyle().get(); } //! Set ths styling to use for edge labels void setEdgeLabelStyle(const Style& style); const Style& getEdgeLabelStyle() const { return options().edgeLabelStyle().get(); } public: // Layer void addedToMap(const Map* map) override; void removedFromMap(const Map* map) override; osg::Node* getNode() const override; void init() override; public: // osg::Object void resizeGLObjectBuffers(unsigned maxSize) override; void releaseGLObjects(osg::State* state) const override; protected: /** dtor */ virtual ~GeodeticGraticule() { } private: void rebuild(); void updateGridLineVisibility(); UID _uid; osg::ref_ptr _profile; osg::ref_ptr _root; osg::ref_ptr _mapSRS; osg::ref_ptr _callback; osg::ref_ptr _formatter; float _defaultResolution; osg::Vec2f _centerOffset; std::vector< double > _resolutions; struct OSGEARTH_EXPORT CameraData { osg::ref_ptr _stateset; osg::ref_ptr _resolutionUniform; osg::ref_ptr _labelStateset; std::vector< osg::ref_ptr > _labelPool; float _resolution; osg::Matrixd _lastViewMatrix; GeoExtent _viewExtent; double _lon; double _lat; double _metersPerPixel; void releaseGLObjects(osg::State*) const; ~CameraData(); }; typedef std::unordered_map CameraDataMap; mutable CameraDataMap _cameraDataMap; mutable std::mutex _cameraDataMapMutex; CameraData& getCameraData(osg::Camera*) const; void initLabelPool(CameraData&); std::string getText(const GeoPoint& location, bool lat); GeodeticLabelingEngine* _labelingEngine; GeoExtent getViewExtent(osgUtil::CullVisitor*) const; public: void updateLabels(); void cull(osgUtil::CullVisitor*); osg::StateSet* getStateSet(osgUtil::CullVisitor* cv); private: osg::observer_ptr _mapNode; void setMapNode(MapNode*); struct MyGroup : public osg::Group { MyGroup(GeodeticGraticule*); GeodeticGraticule* _graticule; void traverse(osg::NodeVisitor& nv); }; friend struct MyGroup; }; } }