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 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 */
19 #include <osgEarth/Viewpoint>
20
21 using namespace osgEarth;
22
23
24 Viewpoint::Viewpoint() :
25 _heading( Angle( 0.0, Units::DEGREES) ),
26 _pitch ( Angle( -30.0, Units::DEGREES) ),
27 _range ( Distance(10000.0, Units::METERS) )
28 {
IndexPair(int i, int j)29 //NOP
30 }
31
32 Viewpoint::Viewpoint( const Viewpoint& rhs ) :
33 _name ( rhs._name ),
34 _point ( rhs._point ),
35 _heading ( rhs._heading ),
36 _pitch ( rhs._pitch ),
37 _range ( rhs._range ),
38 _posOffset( rhs._posOffset),
39 _node ( rhs._node.get() )
40 {
41 //NOP
42 }
43
44 Viewpoint::Viewpoint(const char* name, double lon, double lat, double z, double h, double p, double range)
45 {
setJ(int j)46 if (name) _name = name;
47 _point->set( SpatialReference::get("wgs84"), lon, lat, z, ALTMODE_ABSOLUTE );
48 _heading->set( h, Units::DEGREES );
49 _pitch->set( p, Units::DEGREES );
equals(IndexPair pair)50 _range->set( range, Units::METERS );
51 }
52
53 Viewpoint::Viewpoint(const Config& conf)
equals(Object o)54 {
55 conf.get( "name", _name );
56 conf.get( "heading", _heading );
57 conf.get( "pitch", _pitch );
58 conf.get( "range", _range );
59
60 // piecewise point.
61 std::string horiz = conf.value("srs");
62 if ( horiz.empty() )
63 horiz = "wgs84";
64
65 const std::string vert = conf.value("vdatum");
66
67 // try to parse an SRS, defaulting to WGS84 if not able to do so
68 osg::ref_ptr<const SpatialReference> srs = SpatialReference::create(horiz, vert);
69
70 // try x/y/z variant:
71 if ( conf.hasValue("x") )
72 {
73 _point = GeoPoint(
74 srs.get(),
75 conf.value<double>("x", 0.0),
76 conf.value<double>("y", 0.0),
77 conf.value<double>("z", 0.0),
78 ALTMODE_ABSOLUTE );
79 }
80 else if ( conf.hasValue("lat") )
81 {
82 _point = GeoPoint(
83 srs.get(),
84 conf.value<double>("long", 0.0),
85 conf.value<double>("lat", 0.0),
86 conf.value<double>("height", 0.0),
87 ALTMODE_ABSOLUTE );
88 }
89
90 double xOffset = conf.value("x_offset", 0.0);
91 double yOffset = conf.value("y_offset", 0.0);
92 double zOffset = conf.value("z_offset", 0.0);
93 if ( xOffset != 0.0 || yOffset != 0.0 || zOffset != 0.0 )
94 {
95 _posOffset->set(xOffset, yOffset, zOffset);
96 }
97 }
98
99 osg::ref_ptr<osg::Node>
100 Viewpoint::getNode() const
101 {
102 osg::ref_ptr<osg::Node> node;
103 _node.lock(node);
104 return node;
105 }
106
107 #define CONF_STR Stringify() << std::fixed << std::setprecision(4)
108
109 Config
110 Viewpoint::getConfig() const
111 {
112 Config conf( "viewpoint" );
113
114 conf.set( "name", _name );
115 conf.set( "heading", _heading );
116 conf.set( "pitch", _pitch );
117 conf.set( "range", _range );
118
119 if ( _point.isSet() )
120 {
121 if ( _point->getSRS()->isGeographic() )
122 {
123 conf.set("long", _point->x());
124 conf.set("lat", _point->y());
125 conf.set("height", _point->z());
126 }
127 else
128 {
129 conf.set("x", _point->x());
130 conf.set("y", _point->y());
131 conf.set("z", _point->z());
132 }
133
134 conf.set("srs", _point->getSRS()->getHorizInitString());
135
136 if ( _point->getSRS()->getVerticalDatum() )
137 conf.set("vdatum", _point->getSRS()->getVertInitString());
138 }
139
140 if ( _posOffset.isSet() )
141 {
142 conf.set("x_offset", _posOffset->x());
143 conf.set("y_offset", _posOffset->y());
144 conf.set("z_offset", _posOffset->z());
145 }
146
147 return conf;
148 }
149
150 bool
151 Viewpoint::isValid() const
152 {
153 return
154 (_point.isSet() && _point->isValid()) ||
155 (_node.valid());
156 }
157
158 std::string
159 Viewpoint::toString() const
160 {
161 if ( _point.isSet() )
162 {
163 return Stringify()
164 << "x=" << _point->x()
165 << ", y=" << _point->y()
166 << ", z=" << _point->z()
167 << ", h=" << _heading->to(Units::DEGREES).asParseableString()
168 << ", p=" << _pitch->to(Units::DEGREES).asParseableString()
169 << ", d=" << _range->asParseableString()
170 << ", xo=" << _posOffset->x()
171 << ", yo=" << _posOffset->y()
172 << ", zo=" << _posOffset->z();
173 }
174 else
175 {
176 return Stringify()
177 << "attached to node; "
178 << ", h=" << _heading->to(Units::DEGREES).asParseableString()
179 << ", p=" << _pitch->to(Units::DEGREES).asParseableString()
180 << ", d=" << _range->asParseableString()
181 << ", xo=" << _posOffset->x()
182 << ", yo=" << _posOffset->y()
183 << ", zo=" << _posOffset->z();
184 }
185 }
186