-
Notifications
You must be signed in to change notification settings - Fork 841
Expand file tree
/
Copy pathElevationPool
More file actions
295 lines (255 loc) · 11 KB
/
ElevationPool
File metadata and controls
295 lines (255 loc) · 11 KB
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
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/* osgEarth
* Copyright 2008-2016 Pelican Mapping
* MIT License
*/
#pragma once
#include <osgEarth/Common>
#include <osgEarth/Elevation>
#include <osgEarth/ElevationLayer>
#include <osgEarth/GeoData>
#include <osgEarth/TileKey>
#include <osgEarth/Threading>
#include <osgEarth/Containers>
#include <unordered_map>
namespace osgEarth
{
/**
* Stores pointers to elevation data wherever it might exist
* so we can quickly access it for queries.
*/
class OSGEARTH_EXPORT ElevationPool : public osg::Referenced
{
public:
using WeakPointer = osg::observer_ptr<ElevationTile>;
using Pointer = osg::ref_ptr<ElevationTile>;
using WeakLUT = std::unordered_map<Internal::RevElevationKey, WeakPointer>;
public:
//! User data that a client can use to speed up queries in
//! a local geographic area or sample a custom set of layers.
class OSGEARTH_EXPORT WorkingSet
{
public:
//! Construct a new local working set cache.
//! @param size Cache size
WorkingSet(unsigned size =32u);
//! Assign a specific set of elevation layer to use
//! for sampling. Usually this is unnecessary as the Pool
//! will synchronize with the map set by setMap, but you
//! may want to use a custom Pool with a specific subset
//! of query layers.
//! @param layers Set of elevation layers to use
void setElevationLayers(const ElevationLayerVector& layers) {
_elevationLayers = layers;
}
//! Invalidate the cache.
void clear();
private:
LRUCache<Internal::RevElevationKey, Pointer> _lru;
ElevationLayerVector _elevationLayers;
friend class ElevationPool;
};
private:
struct MapData {
osg::observer_ptr<const Map> map;
ElevationLayerVector layers;
size_t hash;
int mapRevision;
osg::ref_ptr<const Profile> mapProfile;
osg::ref_ptr<const Profile> mapProfileNoVDatum;
RasterInterpolation interpolation;
std::map<const ElevationLayer*, void*> index;
};
MapData snapshotMapData(WorkingSet* ws);
public:
/**
* Object for doing lots of queries in a localized area at a specific LOD.
* Call prepareEnvelope to initialize one.
*/
class OSGEARTH_EXPORT Envelope
{
public:
//! For each point in an array of points, sample the elevation and store
//! the result in the Z coordinate. Input points must be in the map's SRS.
//! @param begin Iterator pointing to beginning of point array
//! @param end Iterator pointing to end of point array
//! @param progress Optional progress callback (can be nullptr)
//! @param failValue Value to store in Z if the sampling fails
//! @return Number of valid elevations sampled, or -1 if there was an error
int sampleMapCoords(
std::vector<osg::Vec3d>::iterator begin,
std::vector<osg::Vec3d>::iterator end,
ProgressCallback* progress,
float failValue = NO_DATA_VALUE);
public:
// internal
using QuickCache = vector_map<
Internal::RevElevationKey,
osg::ref_ptr<ElevationTile>>;
//! Calculated tile LOD based on resolution
int getLOD() const {
return _lod;
}
private:
MapData _mapDataSnapshot;
Internal::RevElevationKey _key;
QuickCache _cache;
double _pw, _ph, _pxmin, _pymin;
osg::ref_ptr<ElevationTile> _raster;
int _lod;
unsigned _tw, _th;
WorkingSet* _ws;
WorkingSet _default_ws;
osg::ref_ptr<const Map> _map;
osg::ref_ptr<const Profile> _profile;
ElevationPool* _pool;
friend class ElevationPool;
};
public:
//! Construct the elevation pool
ElevationPool();
//! Assign map to the pool. Required.
void setMap(const Map* map);
//! Sample the map's elevation at a point.
//! @param p Point at which to sample
//! @param ws Optional working set (can be NULL)
//! @param progress Optional progress callback
ElevationSample getSample(
const GeoPoint& p,
WorkingSet* ws,
ProgressCallback* progress =nullptr);
//! Sample the map's elevation at a point.
//! @param p Point at which to sample
//! @param resolution Resolution at which to attempt to sample (in point srs)
//! @param ws Optional working set (can be NULL)
//! @param progress Optional progress callback
ElevationSample getSample(
const GeoPoint& p,
const Distance& resolution,
WorkingSet* ws,
ProgressCallback* progress =nullptr);
//! Extract a complete tile of elevation data
//! @param key TileKey or data to extact
//! @param acceptLowerRes Return a lower resolution tile if the requested one isn't available
//! @param out_elev Output elevation texture tile
//! @param ws Optional working set (can be nullptr)
//! @param progress Optional progress callback (can be nullptr)
//! @return true upon success, false upon failure
bool getTile(
const TileKey& key,
bool acceptLowerRes,
osg::ref_ptr<ElevationTile>& out_elev,
WorkingSet* ws,
ProgressCallback* progress);
//! For each point in an array of points, sample the elevation and store
//! the result in the Z coordinate. Input points must be in the map's SRS,
//! and the sampling resolution is taken from the W coordinate.
//! @param begin Iterator pointing to beginning of point array
//! @param end Iterator pointing to end of point array
//! @param ws Optional working set (local cache, can be nullptr)
//! @param progress Optional progress callback (can be nullptr)
//! @param failValue Value to store in Z if the sampling fails
//! @return Number of valid elevations sampled, or -1 if there was an error
int sampleMapCoords(
std::vector<osg::Vec4d>::iterator begin,
std::vector<osg::Vec4d>::iterator end,
WorkingSet* ws,
ProgressCallback* progress,
float failValue =NO_DATA_VALUE);
//! For each point in an array of points, sample the elevation and store
//! the result in the Z coordinate. Input points must be in the map's SRS.
//! @param begin Iterator pointing to beginning of point array
//! @param end Iterator pointing to end of point array
//! @param resolution Resolution at which to sample the points
//! @param ws Optional working set (local cache, can be nullptr)
//! @param progress Optional progress callback (can be nullptr)
//! @param failValue Value to store in Z if the sampling fails
//! @return Number of valid elevations sampled, or -1 if there was an error
int sampleMapCoords(
std::vector<osg::Vec3d>::iterator begin,
std::vector<osg::Vec3d>::iterator end,
const Distance& resolution,
WorkingSet* ws,
ProgressCallback* progress,
float failValue = NO_DATA_VALUE);
//! Creates an envelope for sampling lots of points in a localized region
//! @param out Created envelope (output)
//! @param refPoint Reference point near which you intend to sample points
//! @param resolution Resolution at which to intend to sample points
//! @param ws Optional working set (can be nullptr)
bool prepareEnvelope(
Envelope& out,
const GeoPoint& refPoint,
const Distance& resolution,
WorkingSet* ws =nullptr);
//! The SRS of the map; you can get this to pre-transform points
//! before a call to sampleMapCoords.
const SpatialReference* getMapSRS() const;
protected:
//! Destructor
virtual ~ElevationPool();
private:
// stores weak pointers to elevation textures wherever they may exist
// elsewhere in the system, including the local L2 LRU.
WeakLUT _globalLUT;
Threading::ReadWriteMutex _globalLUTMutex;
// LRU container that stores the last N strong references to accessed tiles.
// Not used directly - just used to hold ref_ptrs to things so they stay
// alive in the global LUT (see above).
mutable LRUCache<Internal::RevElevationKey, Pointer> _L2;
// elevation tile size
unsigned _tileSize;
// current map data reflection
MapData _mapData;
Threading::ReadWriteMutex _mapDataMutex;
// internal - get a sample at a point
ElevationSample getSample(
const GeoPoint& p,
unsigned maxLOD,
WorkingSet* ws,
ProgressCallback* progress);
//! Best LOD this a point for the working set, or -1 if no data in index
int getLOD(double x, double y, WorkingSet*, int maxLOD);
osg::ref_ptr<ElevationTile> getOrCreateRaster(
MapData& snapshot,
const Internal::RevElevationKey& key,
bool acceptLowerRes,
ProgressCallback* progress);
bool findExistingRaster(
const Internal::RevElevationKey& key,
osg::ref_ptr<ElevationTile>& result,
bool* fromGlobalWeakLUT);
};
// backwards compat
using ElevationTexture = ElevationTile;
/**
* Utility to run elevation queries in the background.
*/
class OSGEARTH_EXPORT AsyncElevationSampler
{
public:
//! Construct a new sampler
//! @param map Map the sampler will use to sample elevation data
//! @param threads Number of threads the sampler should use
AsyncElevationSampler(
const Map* map,
unsigned threads =0u);
//! Destructor
virtual ~AsyncElevationSampler() { }
//! Sample elevation at a point at highest available resolution
//! @param p Point at which to sample terrain elevation
//! @return Future result of the sample
jobs::future<ElevationSample> getSample(
const GeoPoint& p);
//! Sample elevation at a point and a target resolution
//! @param p Point at which to sample terrain elevation
//! @param resolution Resolution at which to sample terrain
//! @return Future result of the sample
jobs::future<ElevationSample> getSample(
const GeoPoint& p,
const Distance& resolution);
protected:
osg::observer_ptr<const Map> _map;
ElevationPool::WorkingSet _ws;
jobs::jobpool* _arena;
};
} // namespace