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
23 #include <osgEarthAnnotation/CircleNode>
24 #include <osgEarthAnnotation/AnnotationRegistry>
25 #include <osgEarthAnnotation/AnnotationUtils>
26 #include <osgEarthFeatures/GeometryCompiler>
27 #include <osgEarthSymbology/GeometryFactory>
28 #include <osgEarthSymbology/ExtrusionSymbol>
29 #include <osgEarth/MapNode>
30 #include <osgEarth/DrapeableNode>
31 #include <osg/MatrixTransform>
32 #include <cmath>
33
34 using namespace osgEarth;
35 using namespace osgEarth::Annotation;
36 using namespace osgEarth::Features;
37 using namespace osgEarth::Symbology;
38
39
CircleNode()40 CircleNode::CircleNode() :
41 LocalGeometryNode()
42 {
43 construct();
44 }
45
46 void
set(const GeoPoint & position,const Distance & radius,const Style & style,const Angle & arcStart,const Angle & arcEnd,const bool pie)47 CircleNode::set(const GeoPoint& position,
48 const Distance& radius,
49 const Style& style,
50 const Angle& arcStart,
51 const Angle& arcEnd,
52 const bool pie)
53 {
54 _radius = radius;
55 _arcStart = arcStart;
56 _arcEnd = arcEnd;
57 _pie = pie;
58 _style = style;
59
60 setPosition(position);
61
62 buildGeometry();
63 }
64
65 void
construct()66 CircleNode::construct()
67 {
68 setName("Circle");
69
70 _radius.set(1.0, Units::KILOMETERS);
71 _arcStart.set(0.0, Units::RADIANS);
72 _arcEnd.set(2.0*osg::PI, Units::RADIANS);
73 _pie = false;
74 _numSegments = 0;
75 }
76
77 const Linear&
getRadius() const78 CircleNode::getRadius() const
79 {
80 return _radius;
81 }
82
83 void
setRadius(const Linear & radius)84 CircleNode::setRadius( const Linear& radius )
85 {
86 if (_radius != radius )
87 {
88 _radius = radius;
89 buildGeometry();
90 }
91 }
92
93 unsigned int
getNumSegments() const94 CircleNode::getNumSegments() const
95 {
96 return _numSegments;
97 }
98
99 void
setNumSegments(unsigned int numSegments)100 CircleNode::setNumSegments(unsigned int numSegments )
101 {
102 if (_numSegments != numSegments )
103 {
104 _numSegments = numSegments;
105 buildGeometry();
106 }
107 }
108
109 const Angle&
getArcStart(void) const110 CircleNode::getArcStart(void) const
111 {
112 return (_arcStart);
113 }
114
115 void
setArcStart(const Angle & arcStart)116 CircleNode::setArcStart(const Angle& arcStart)
117 {
118 _arcStart = arcStart;
119 buildGeometry();
120 }
121
122 const Angle&
getArcEnd(void) const123 CircleNode::getArcEnd(void) const
124 {
125 return (_arcEnd);
126 }
127
128 void
setArcEnd(const Angle & arcEnd)129 CircleNode::setArcEnd(const Angle& arcEnd)
130 {
131 _arcEnd = arcEnd;
132 buildGeometry();
133 }
134
135 const bool&
getPie(void) const136 CircleNode::getPie(void) const
137 {
138 return (_pie);
139 }
140
141 void
setPie(const bool & pie)142 CircleNode::setPie(const bool& pie)
143 {
144 _pie = pie;
145 buildGeometry();
146 }
147
148 void
buildGeometry()149 CircleNode::buildGeometry()
150 {
151 // construct a local-origin circle.
152 GeometryFactory factory;
153 osg::ref_ptr<Geometry> geom;
154 if (std::abs(_arcEnd.as(Units::DEGREES) - _arcStart.as(Units::DEGREES)) >= 360.0)
155 {
156 geom = factory.createCircle(osg::Vec3d(0,0,0), _radius, _numSegments);
157 }
158 else
159 {
160 geom = factory.createArc(osg::Vec3d(0,0,0), _radius, _arcStart, _arcEnd, _numSegments, 0L, _pie);
161 }
162
163 if ( geom.valid() )
164 {
165 setGeometry(geom.get());
166 }
167 }
168
169
170 //-------------------------------------------------------------------
171
172 OSGEARTH_REGISTER_ANNOTATION( circle, osgEarth::Annotation::CircleNode );
173
174
CircleNode(const Config & conf,const osgDB::Options * dbOptions)175 CircleNode::CircleNode(const Config& conf,
176 const osgDB::Options* dbOptions) :
177 LocalGeometryNode(conf, dbOptions)
178 {
179 construct();
180
181 conf.get( "radius", _radius );
182 conf.get( "num_segments", _numSegments );
183
184 buildGeometry();
185 }
186
187 Config
getConfig() const188 CircleNode::getConfig() const
189 {
190 Config conf = LocalGeometryNode::getConfig();
191 conf.key() = "circle";
192
193 conf.set( "radius", _radius );
194
195 if ( _numSegments != 0 )
196 conf.add( "num_segments", _numSegments );
197
198 return conf;
199 }
200