1/* -*-c++-*- */
2/* osgEarth - Geospatial SDK for OpenSceneGraph
3* Copyright 2019 Pelican Mapping
4* http://osgearth.org
5*
6* osgEarth is free software; you can redistribute it and/or modify
7* it under the terms of the GNU Lesser General Public License as published by
8* the Free Software Foundation; either version 2 of the License, or
9* (at your option) any later version.
10*
11* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
16* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
17* IN THE SOFTWARE.
18*
19* You should have received a copy of the GNU Lesser General Public License
20* along with this program.  If not, see <http://www.gnu.org/licenses/>
21*/
22#ifndef OSGEARTH_UTIL_GRATICULE_LABELING_ENGINE_H
23#define OSGEARTH_UTIL_GRATICULE_LABELING_ENGINE_H 1
24
25#include <osgEarthUtil/Common>
26#include <osgEarthUtil/ClipSpace>
27#include <osgEarth/GeoData>
28#include <osgEarth/MapNode>
29#include <osgEarth/Containers>
30#include <osgEarthAnnotation/LabelNode>
31
32namespace osgEarth { namespace Util
33{
34    using namespace osgEarth;
35    using namespace osgEarth::Annotation;
36
37    /**
38     * Node that plots graticule coordinates labels along the edge of the
39     * viewport when you are looking straight down on a zoomed-in area.
40     */
41    class GraticuleLabelingEngine : public osg::Group
42    {
43    public:
44        //! Construct a new labeling engine with the map's SRS
45        GraticuleLabelingEngine(const SpatialReference* srs);
46
47        bool getVisible(osg::Camera* camera);
48
49        //! Set the labeling style for all labels
50        void setStyle(const Style& style);
51
52        //! Set the labeling style for X and Y labels separately
53        void setStyles(const Style& xStyle, const Style& yStyle);
54
55    public: // osg::Node
56        void traverse(osg::NodeVisitor& nv);
57
58    protected:
59        typedef std::vector< osg::ref_ptr<LabelNode> > LabelNodeVector;
60
61        struct CameraData
62        {
63            CameraData():
64                visible(false)
65            {
66            }
67
68            LabelNodeVector xLabels;
69            LabelNodeVector yLabels;
70            bool visible;
71        };
72
73        bool cullTraverse(osgUtil::CullVisitor& nv, CameraData& data);
74
75        // Override to place labels
76        virtual bool updateLabels(const osg::Vec3d& LL_world, osg::Vec3d& UL_world, osg::Vec3d& LR_world, ClipSpace& window, CameraData& data);
77
78        typedef PerObjectFastMap<osg::Camera*, CameraData> CameraDataMap;
79        CameraDataMap _cameraDataMap;
80
81        struct AcceptCameraData : public CameraDataMap::Functor {
82            AcceptCameraData(osg::NodeVisitor& nv) : _nv(nv) { }
83            void operator()(CameraData& data);
84            osg::NodeVisitor& _nv;
85        };
86
87        struct UpdateLabelStyles : public CameraDataMap::Functor {
88            UpdateLabelStyles(const Style& xStyle, const Style& yStyle) : _xStyle(&xStyle), _yStyle(&yStyle) { }
89            void operator()(CameraData& data);
90            const Style* _xStyle;
91            const Style* _yStyle;
92        };
93
94        osg::ref_ptr<const SpatialReference> _srs;
95        Style _xLabelStyle, _yLabelStyle;
96    };
97
98} } // namespace osgEarth::Util
99
100#endif // OSGEARTH_UTIL_GRATICULE_LABELING_ENGINE_H
101