~ubuntu-branches/debian/sid/osgearth/sid

« back to all changes in this revision

Viewing changes to src/osgEarth/GeoData

  • Committer: Bazaar Package Importer
  • Author(s): Pirmin Kalberer
  • Date: 2011-07-14 22:13:36 UTC
  • Revision ID: james.westby@ubuntu.com-20110714221336-94igk9rskxveh794
Tags: upstream-2.0+dfsg
ImportĀ upstreamĀ versionĀ 2.0+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*-c++-*- */
 
2
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
 
3
 * Copyright 2008-2010 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
#ifndef OSGEARTH_GEODATA_H
 
20
#define OSGEARTH_GEODATA_H 1
 
21
 
 
22
#include <osg/Referenced>
 
23
#include <osg/Image>
 
24
#include <osg/Shape>
 
25
#include <osgTerrain/Locator>
 
26
#include <osgEarth/Common>
 
27
#include <osgEarth/SpatialReference>
 
28
#include <osgEarth/VerticalSpatialReference>
 
29
#include <osgEarth/HeightFieldUtils>
 
30
#include <osgEarth/Units>
 
31
 
 
32
namespace osgEarth
 
33
{
 
34
    /**
 
35
     * An "anonymous" bounding extent (i.e., no geo reference information)
 
36
     */
 
37
    class OSGEARTH_EXPORT Bounds : public osg::BoundingBoxImpl<osg::Vec3d>
 
38
    {
 
39
    public:
 
40
        Bounds();
 
41
        Bounds(double xmin, double ymin, double xmax, double ymax );
 
42
 
 
43
        double width() const;
 
44
        double height() const;
 
45
        double depth() const;
 
46
        bool contains(double x, double y ) const;
 
47
        Bounds unionWith(const Bounds& rhs) const; 
 
48
        void expandBy( double x, double y );
 
49
        void expandBy( double x, double y, double z );
 
50
        void expandBy( const Bounds& rhs );
 
51
        osg::Vec2d center2d() const;
 
52
    };
 
53
 
 
54
    /**
 
55
     * A georeferenced extent. A bounding box that is aligned with a
 
56
     * spatial reference's coordinate system.
 
57
     *
 
58
     * TODO: this class needs better integrated support for geographic extents
 
59
     * that cross the date line.
 
60
     */
 
61
    class OSGEARTH_EXPORT GeoExtent
 
62
    {
 
63
    public:
 
64
        /** Default ctor creates an "invalid" extent */
 
65
        GeoExtent(); 
 
66
 
 
67
        /** Contructs a valid extent */
 
68
        GeoExtent(
 
69
            const SpatialReference* srs,
 
70
            double xmin = FLT_MAX, double ymin = FLT_MAX,
 
71
            double xmax = -FLT_MAX, double ymax = -FLT_MAX );
 
72
 
 
73
        /** Copy ctor */
 
74
        GeoExtent( const GeoExtent& rhs );
 
75
 
 
76
        /** create from Bounds object */
 
77
        GeoExtent( const SpatialReference* srs, const Bounds& bounds );
 
78
 
 
79
        bool operator == ( const GeoExtent& rhs ) const;
 
80
        bool operator != ( const GeoExtent& rhs ) const;
 
81
 
 
82
        /** Gets the spatial reference system underlying this extent. */
 
83
        const SpatialReference* getSRS() const;
 
84
 
 
85
        double xMin() const { return _xmin; }
 
86
        double& xMin() { return _xmin; }
 
87
        double yMin() const { return _ymin; }
 
88
        double& yMin() { return _ymin; }
 
89
        double xMax() const { return _xmax; }
 
90
        double& xMax() { return _xmax; }
 
91
        double yMax() const { return _ymax; }
 
92
        double& yMax() { return _ymax; }
 
93
 
 
94
        double width() const;
 
95
        double height() const;
 
96
 
 
97
        void getCentroid( double& out_x, double& out_y ) const;
 
98
 
 
99
        /**
 
100
         * Returns true is that extent is in a Geographic (lat/long) SRS that spans
 
101
         * the international date line.
 
102
         */
 
103
        bool crossesDateLine() const;
 
104
 
 
105
        /**
 
106
         * Returns the raw bounds in a single function call
 
107
         */
 
108
        void getBounds(double &xmin, double &ymin, double &xmax, double &ymax) const;
 
109
 
 
110
        /** True if this object defines a real, valid extent with positive area */
 
111
        bool isValid() const;
 
112
        bool defined() const { return isValid(); }
 
113
 
 
114
        /**
 
115
         * If this extent crosses the international date line, populates two extents, one for
 
116
         * each side, and returns true. Otherwise returns false and leaves the reference
 
117
         * parameters untouched.
 
118
         */
 
119
        bool splitAcrossDateLine( GeoExtent& first, GeoExtent& second ) const;
 
120
 
 
121
        /**
 
122
         * Returns this extent transformed into another spatial reference.
 
123
         */
 
124
        GeoExtent transform( const SpatialReference* to_srs ) const;
 
125
 
 
126
        /**
 
127
         * Returns true if the specified point falls within the bounds of the extent.
 
128
         *
 
129
         * @param x, y
 
130
         *      Coordinates to test
 
131
         * @param xy_srs
 
132
         *      SRS of input x and y coordinates; if null, the method assumes x and y
 
133
         *      are in the same SRS as this object.
 
134
         */
 
135
        bool contains(double x, double y, const SpatialReference* xy_srs =0L) const;
 
136
 
 
137
        /**
 
138
         * Returns TRUE if this extent intersects another extent.
 
139
         */
 
140
        bool intersects( const GeoExtent& rhs ) const;
 
141
 
 
142
        /** Direct access to the anonymous bounding box */
 
143
        Bounds bounds() const;
 
144
 
 
145
        /**
 
146
         * Grow this extent to include the specified point (which is assumed to be
 
147
         * in the extent's SRS.
 
148
         */
 
149
        void expandToInclude( double x, double y );
 
150
 
 
151
        /**
 
152
         * Grow this extent to include the specified GeoExtent (which is assumed to be
 
153
         * in the extent's SRS.
 
154
         */
 
155
        void expandToInclude( const GeoExtent& rhs );
 
156
        
 
157
        /**
 
158
         * Intersect this extent with another extent in the same SRS and return the
 
159
         * result.
 
160
         */
 
161
        GeoExtent intersectionSameSRS( const GeoExtent& rhs ) const;
 
162
 
 
163
        /**
 
164
         * Returns a human-readable string containing the extent data (without the SRS)
 
165
         */
 
166
        std::string toString() const;
 
167
 
 
168
        /**
 
169
         *Inflates this GeoExtent by the given ratios
 
170
         */
 
171
        void scale(double x_scale, double y_scale);
 
172
 
 
173
                /**
 
174
                 * Expands the extent by x and y.
 
175
                 */
 
176
                void expand( double x, double y );
 
177
 
 
178
        /**
 
179
         *Gets the area of this GeoExtent
 
180
         */
 
181
        double area() const;
 
182
 
 
183
    public:
 
184
        static GeoExtent INVALID;
 
185
 
 
186
    private:
 
187
        osg::ref_ptr<const SpatialReference> _srs;
 
188
        double _xmin, _ymin, _xmax, _ymax;
 
189
    };
 
190
 
 
191
    /**
 
192
     * A geospatial area with tile data LOD extents
 
193
     */
 
194
    class OSGEARTH_EXPORT DataExtent : public GeoExtent
 
195
    {
 
196
    public:
 
197
        DataExtent(const GeoExtent& extent, unsigned int minLevel, unsigned int maxLevel);
 
198
 
 
199
        /** The minimum LOD of the extent */
 
200
        unsigned int getMinLevel() const;
 
201
 
 
202
        /** The maximum LOD of the extent */
 
203
        unsigned int getMaxLevel() const;
 
204
 
 
205
    private:
 
206
        unsigned int _minLevel;
 
207
        unsigned int _maxLevel;
 
208
    };
 
209
 
 
210
    typedef std::vector< DataExtent > DataExtentList;
 
211
 
 
212
 
 
213
    /**
 
214
     * A georeferenced image; i.e. an osg::Image and an associated GeoExtent with SRS.
 
215
     */
 
216
    class OSGEARTH_EXPORT GeoImage
 
217
    {
 
218
    public:
 
219
        /** Construct an empty (invalid) geoimage. */
 
220
        GeoImage();
 
221
 
 
222
        /**
 
223
         * Constructs a new goereferenced image.
 
224
         */
 
225
        GeoImage( osg::Image* image, const GeoExtent& extent );
 
226
 
 
227
        static GeoImage INVALID;
 
228
 
 
229
    public:
 
230
        /**
 
231
         * True if this is a valid geo image. 
 
232
         */
 
233
        bool valid() const { return _image.valid(); }
 
234
 
 
235
        /**
 
236
         * Gets a pointer to the underlying OSG image.
 
237
         */
 
238
        osg::Image* getImage() const;
 
239
 
 
240
        /**
 
241
         * Gets the geospatial extent of the image.
 
242
         */
 
243
        const GeoExtent& getExtent() const;
 
244
 
 
245
        /**
 
246
         * Shortcut to get the spatial reference system describing
 
247
         * the projection of the image.
 
248
         */
 
249
        const SpatialReference* getSRS() const;
 
250
 
 
251
        /**
 
252
         * Crops the image to a new geospatial extent. 
 
253
         *
 
254
         * @param extent
 
255
         *      New extent to which to crop the image.
 
256
         * @param exact
 
257
         *      If "exact" is true, the output image will have exactly the extents requested;
 
258
         *      this process may require resampling and will therefore be more expensive. If
 
259
         *      "exact" is false, we do a simple crop of the image that is rounded to the nearest
 
260
         *      pixel. The resulting extent will be close but usually not exactly what was
 
261
         *      requested - however, this method is faster.
 
262
         * @param width, height
 
263
         *      New pixel size for the output image. By default, the method will automatically
 
264
         *      calculate a new pixel size.
 
265
         */
 
266
        GeoImage crop( 
 
267
            const GeoExtent& extent,
 
268
            bool exact = false,
 
269
            unsigned int width = 0,
 
270
            unsigned int height = 0) const;
 
271
 
 
272
        /**
 
273
         * Warps the image into a new spatial reference system.
 
274
         *
 
275
         * @param to_srs
 
276
         *      SRS into which to warp the image.
 
277
         * @param to_extent
 
278
         *      Supply this extent if you wish to warp AND crop the image in one step. This is
 
279
         *      faster than calling reproject() and then crop().
 
280
         * @param width, height
 
281
         *      New pixel size for the output image. Be default, the method will automatically
 
282
         *      calculate a new pixel size.
 
283
         */
 
284
        GeoImage reproject(
 
285
            const SpatialReference* to_srs,
 
286
            const GeoExtent* to_extent = 0,
 
287
            unsigned int width = 0,
 
288
            unsigned int height = 0) const;
 
289
 
 
290
        /**
 
291
         * Adds a one-pixel transparent border around an image.
 
292
         */
 
293
        GeoImage addTransparentBorder(
 
294
            bool leftBorder=true, 
 
295
            bool rightBorder=true, 
 
296
            bool bottomBorder=true, 
 
297
            bool topBorder=true);
 
298
 
 
299
        /**
 
300
         * Returns the underlying OSG image and releases the reference pointer.
 
301
         */
 
302
        osg::Image* takeImage();
 
303
 
 
304
                /**
 
305
                 * Gets the units per pixel of this geoimage
 
306
                 */
 
307
                double getUnitsPerPixel() const;
 
308
 
 
309
    private:
 
310
        osg::ref_ptr<osg::Image> _image;
 
311
        GeoExtent _extent;
 
312
    };
 
313
 
 
314
    typedef std::vector<GeoImage> GeoImageVector;
 
315
 
 
316
    /**
 
317
     * A georeferenced heightfield.
 
318
     */
 
319
    class OSGEARTH_EXPORT GeoHeightField
 
320
    {
 
321
    public:
 
322
        /** Constructs an empty (invalid) heightfield. */
 
323
        GeoHeightField();
 
324
 
 
325
        /**
 
326
         * Constructs a new georeferenced heightfield.
 
327
         */
 
328
        GeoHeightField(
 
329
            osg::HeightField* heightField,
 
330
            const GeoExtent& extent,
 
331
            const VerticalSpatialReference* vsrs);
 
332
 
 
333
        static GeoHeightField INVALID;
 
334
 
 
335
        /**
 
336
         * True if this is a valid heightfield. 
 
337
         */
 
338
        bool valid() const { return _heightField.valid(); }
 
339
 
 
340
        /**
 
341
         * Gets the elevation value at a specified point.
 
342
         *
 
343
         * @param srs
 
344
         *      Spatial reference of the query coordinates. (If you pass in NULL, the method
 
345
         *      will assume that the SRS is equivalent to that of the GeoHeightField. Be sure
 
346
         *      this is case of you will get incorrect results.)
 
347
         * @param x, y
 
348
         *      Coordinates at which to query the elevation value.
 
349
         * @param interp
 
350
         *      Interpolation method for the elevation query.
 
351
         * @param outputVSRS
 
352
         *      Convert the output elevation value to this VSRS (NULL to ignore)
 
353
         * @param out_elevation
 
354
         *      Output: the elevation value
 
355
         * @return
 
356
         *      True if the elevation query was succesful; false if not (e.g. if the query
 
357
         *      fell outside the geospatial extent of the heightfield)
 
358
         */
 
359
        bool getElevation(
 
360
            const SpatialReference* inputSRS, 
 
361
            double x, double y,
 
362
            ElevationInterpolation interp,
 
363
            const VerticalSpatialReference* outputVSRS,
 
364
            float& out_elevation ) const;
 
365
        
 
366
        /**
 
367
         * Subsamples the heightfield, returning a new heightfield corresponding to
 
368
         * the destEx extent. The destEx must be a smaller, inset area of sourceEx.
 
369
         */
 
370
        GeoHeightField createSubSample( const GeoExtent& destEx, ElevationInterpolation interpolation) const;
 
371
 
 
372
        /**
 
373
         * Gets the geospatial extent of the heightfield.
 
374
         */
 
375
        const GeoExtent& getExtent() const;
 
376
 
 
377
        /**
 
378
         * Gets a pointer to the underlying OSG heightfield.
 
379
         */
 
380
        const osg::HeightField* getHeightField() const;
 
381
        osg::HeightField* getHeightField();
 
382
 
 
383
        /**
 
384
         * Gets a pointer to the underlying OSG heightfield, and releases the internal reference.
 
385
         */
 
386
        osg::HeightField* takeHeightField();
 
387
 
 
388
    protected:
 
389
        osg::ref_ptr<osg::HeightField> _heightField;
 
390
        GeoExtent _extent;
 
391
        osg::ref_ptr<const VerticalSpatialReference> _vsrs;
 
392
    };
 
393
 
 
394
        typedef std::vector<GeoHeightField> GeoHeightFieldVector;
 
395
 
 
396
    
 
397
    /**
 
398
     * A representation of the surface of the earth based on a grid of
 
399
     * height values that are relative to a reference ellipsoid.
 
400
     */
 
401
    class OSGEARTH_EXPORT Geoid : public osg::Referenced
 
402
    {
 
403
    public:
 
404
        Geoid();
 
405
 
 
406
        /** Gets the readable name of this geoid. */
 
407
        void setName( const std::string& value );
 
408
        const std::string& getName() const { return _name; }
 
409
 
 
410
        /** Sets the underlying heightfield data */
 
411
        void setHeightField( const GeoHeightField& hf );
 
412
 
 
413
        /** Queries to geoid for the height offset at the specified coordinates. */
 
414
        float getOffset(
 
415
            double lat_deg, double lon_deg, 
 
416
            const ElevationInterpolation& interp =INTERP_BILINEAR) const;
 
417
 
 
418
        /** The linear units in which height values are expressed. */
 
419
        const Units& getUnits() const { return _units; }
 
420
        void setUnits( const Units& value );
 
421
 
 
422
        /** Whether this is a valid object to use */
 
423
        bool isValid() const { return _valid; }
 
424
 
 
425
        /** True if two geoids are mathmatically equivalent. */
 
426
        bool isEquivalentTo( const Geoid& rhs ) const;
 
427
 
 
428
    private:
 
429
        std::string _name;
 
430
        GeoHeightField _hf;
 
431
        Units _units;
 
432
        bool _valid;
 
433
        void validate();
 
434
    };
 
435
 
 
436
}
 
437
 
 
438
#endif // OSGEARTH_GEODATA_H