/usr/include/osgEarth/ElevationPool is in libosgearth-dev 2.9.0+dfsg-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | /* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
* Copyright 2008-2016 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 <http://www.gnu.org/licenses/>
*/
#ifndef OSGEARTH_ELEVATION_POOL_H
#define OSGEARTH_ELEVATION_POOL_H
#include <osgEarth/Common>
#include <osgEarth/ElevationLayer>
#include <osgEarth/MapFrame>
#include <osgEarth/GeoData>
#include <osgEarth/TileKey>
#include <osgEarth/ThreadingUtils>
#include <osg/Timer>
#include <map>
namespace osgEarth
{
using namespace Threading;
// defined at the end of this file
class ElevationEnvelope;
class Map;
//! Result of an elevation query.
struct ElevationSample : public osg::Referenced
{
float elevation;
float resolution;
ElevationSample(float a, float b) : elevation(a), resolution(b) { }
};
/**
* A pool of elevation data that can be used to manage regional elevation
* data queries. To use this, call createEnvelope() and use that object
* to make your elevation queries at a particular LOD. The queries can
* be anywhere geographically, but the algorithm will optimize lots of
* queries in a particular area (like a terrain tile).
*
* Each Map contains an ElevationPool you can access for queries against
* that Map.
*
* ElevationEnvelope* envelope = pool->createEnvelope(srs, lod);
* float z = envelope->getElevation(point);
*/
class OSGEARTH_EXPORT ElevationPool : public osg::Referenced
{
public:
/** ctor */
ElevationPool();
/** Sets the map from which to read elevation data. */
void setMap(const Map* map);
/**
* Sets a vector of ElevationLayers from which to read elevation data.
* Omit this is you just want to use all the elevation layes in the Map
* that you set with setMap().
*/
void setElevationLayers(const ElevationLayerVector& layers);
const ElevationLayerVector& getElevationLayers() const { return _layers; }
/** Sets the dimension of heightfield tiles to read from the map */
void setTileSize(unsigned size);
unsigned getTileSize() const { return _tileSize; }
/** Creates a query envelope to use for elevation queries in a certain area. */
ElevationEnvelope* createEnvelope(const SpatialReference* srs, unsigned lod);
//! Queries the elevation at a GeoPoint for a given LOD.
Future<ElevationSample> getElevation(const GeoPoint& p, unsigned lod=23);
/** Maximum number of elevation tiles to cache */
void setMaxEntries(unsigned maxEntries) { _maxEntries = maxEntries; }
unsigned getMaxEntries() const { return _maxEntries; }
/** Clears any cached tiles from the elevation pool. */
void clear();
void stopThreading();
protected:
osg::observer_ptr<const osg::Referenced> _map;
ElevationLayerVector _layers;
enum Status
{
STATUS_EMPTY = 0u,
STATUS_IN_PROGRESS = 1u,
STATUS_AVAILABLE = 2u,
STATUS_FAIL = 3u
};
// Single elevation tile along with its load status
class Tile : public osg::Referenced
{
public:
Tile() : _status(STATUS_EMPTY) { }
TileKey _key; // key used to request this tile
Bounds _bounds;
GeoHeightField _hf;
OpenThreads::Atomic _status;
osg::Timer_t _loadTime;
};
// Custom comparator for Tile that sorts Tiles in a set from
// highest resolution to lowest resolution; This ensures we are
// sampling overlapping tiles in the proper order
struct TileSortHiResToLoRes
{
bool operator()(
const osg::ref_ptr<Tile>& lhs,
const osg::ref_ptr<Tile>& rhs) const
{
// works because the KEY less-than function checks the LOD number
// first, which corresponds to the resolution. Higher LOD = higher res.
return rhs->_key < lhs->_key;
}
};
// Keeps track of the most-recently-used tiles, in order from MRU (front)
// to LRU (back). Multiple pointers to the same Tile may exist in the MRU list.
// Once all pointers to a Tile disappear from the MRU (by popping off the back)
// the corresponding Tile observer in the Tiles data structure will go NULL
// and the Tile will destruct.
typedef std::list<osg::ref_ptr<Tile> > MRU;
MRU _mru;
// Cached set of tiles, sorted by TileKey. These are observer pointers; the
// actual references are held in the MRU. That way when all pointers drop off
// the back of the MRU, the Tile is destroyed and the main observer goes to
// NULL and is removed.
typedef std::map<TileKey, osg::observer_ptr<Tile> > Tiles;
Tiles _tiles;
Threading::Mutex _tilesMutex;
// Track the number of entries in the MRU manually since std::list::size
// can be O(n) on some platforms
unsigned _entries;
unsigned _maxEntries;
// dimension of sampling heightfield
unsigned _tileSize;
// QuerySet is a collection of Tiles, sorted from high to low resolution,
// that a ElevationEnvelope uses for a terrain sampling opteration.
typedef std::set<osg::ref_ptr<Tile>, TileSortHiResToLoRes> QuerySet;
// Asynchronous elevation query operation
struct GetElevationOp : public osg::Operation {
GetElevationOp(ElevationPool*, const GeoPoint&, unsigned lod);
osg::observer_ptr<ElevationPool> _pool;
GeoPoint _point;
unsigned _lod;
Promise<ElevationSample> _promise;
void operator()(osg::Object*);
};
friend struct GetElevationOp;
osg::ref_ptr<osg::OperationQueue> _opQueue;
std::vector< osg::ref_ptr<osg::OperationThread> > _opThreads;
virtual ~ElevationPool();
protected:
// safely popluate the tile; called when Tile._status = IN_PROGRESS
bool fetchTileFromMap(const TileKey& key, MapFrame& frame, Tile* tile);
// safely fetch a tile from the central repo, loading from map if necessary
bool getTile(const TileKey& key, MapFrame& frame, osg::ref_ptr<Tile>& output);
// safely fetch a tile from the central repo, loading from map if necessary
bool tryTile(const TileKey& key, MapFrame& frame, osg::ref_ptr<Tile>& output);
// safely remove the oldest item on the MRU
void popMRU();
// clears and resets the pool.
void clearImpl();
friend class ElevationEnvelope;
};
/**
* Set of terrain tiles corresponding to a geographic extent that the pager
* uses to clamp a feature set. You cannot create this object directly;
* instead call ElevationPool::createEnvelope().
*/
class OSGEARTH_EXPORT ElevationEnvelope : public osg::Referenced
{
public:
/**
* Gets a single elevation, or returns NO_DATA_VALUE upon failure.
* The Z value is ignored.
*/
float getElevation(double x, double y);
/**
* Gets a single elevation along with the resolution of the data from
* which that sample was taken.
*/
std::pair<float, float> getElevationAndResolution(double x, double y);
/**
* Gets a elevation value for each input point and puts them in output.
* Returns the number of successful elevations. Failed queries are set to
* NO_DATA_VALUE in the output vector.
*/
unsigned getElevations(
const std::vector<osg::Vec3d>& input,
std::vector<float>& output);
/**
* Gets the elevation extrema over a collection of point data.
* Returns false if the points don't fall inside the envelope
*/
bool getElevationExtrema(
const std::vector<osg::Vec3d>& points,
float& out_min, float& out_max);
/**
* The SRS that this envelope expects query points to be in
*/
const SpatialReference* getSRS() const;
/**
* LOD at which this envelope will try to sample the elevation
*/
unsigned getLOD() const { return _lod; }
protected:
ElevationEnvelope();
virtual ~ElevationEnvelope();
ElevationPool::QuerySet _tiles;
osg::ref_ptr<const SpatialReference> _inputSRS;
unsigned _lod;
MapFrame _frame;
ElevationPool* _pool;
friend class ElevationPool;
private:
bool sample(double x, double y, float& out_elevation, float& out_resolution);
};
} // namespace
#endif // OSGEARTH_ELEVATION_POOL_H
|