380 lines
14 KiB
Plaintext
380 lines
14 KiB
Plaintext
|
/* -*-c++-*- */
|
||
|
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||
|
* Copyright 2020 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_MAP_H
|
||
|
#define OSGEARTH_MAP_H 1
|
||
|
|
||
|
#include <osgEarth/Common>
|
||
|
#include <osgEarth/GeoData>
|
||
|
#include <osgEarth/Profile>
|
||
|
#include <osgEarth/MapCallback>
|
||
|
#include <osgEarth/Revisioning>
|
||
|
#include <osgEarth/Threading>
|
||
|
#include <osgEarth/ElevationPool>
|
||
|
#include <osgEarth/Cache>
|
||
|
#include <osgDB/Options>
|
||
|
#include <functional>
|
||
|
|
||
|
namespace osgEarth
|
||
|
{
|
||
|
/**
|
||
|
* Map is the main data model. A Map hold a collection of
|
||
|
* Layers, each of which provides data of some kind to the
|
||
|
* overall Map. Use a MapNode to render the contents of a
|
||
|
* Map.
|
||
|
*/
|
||
|
class OSGEARTH_EXPORT Map : public osg::Object
|
||
|
{
|
||
|
public:
|
||
|
META_Object(osgEarth, Map);
|
||
|
|
||
|
//! Construct a new, empty map.
|
||
|
Map();
|
||
|
|
||
|
//! Construct a new, empty map with custom read options.
|
||
|
Map(const osgDB::Options* readOptions);
|
||
|
|
||
|
//! This Map's unique ID
|
||
|
UID getUID() const { return _uid; }
|
||
|
|
||
|
//! The map's master tiling profile, which defines its SRS and tiling structure
|
||
|
void setProfile(const Profile* value);
|
||
|
const Profile* getProfile() const;
|
||
|
|
||
|
//! Spatial reference system of the map's profile (convenience)
|
||
|
const SpatialReference* getSRS() const;
|
||
|
|
||
|
//! SRS of the world (scene)
|
||
|
const SpatialReference* getWorldSRS() const;
|
||
|
|
||
|
//! Elevation data interpolation method
|
||
|
void setElevationInterpolation(const RasterInterpolation& value);
|
||
|
const RasterInterpolation& getElevationInterpolation() const;
|
||
|
|
||
|
//! Adds a Layer to the map.
|
||
|
void addLayer(Layer* layer);
|
||
|
|
||
|
//! Adds a collection of layers to the map.
|
||
|
void addLayers(const LayerVector& layers);
|
||
|
|
||
|
//! Inserts a Layer at a specific index in the Map.
|
||
|
void insertLayer(Layer* layer, unsigned index);
|
||
|
|
||
|
//! Removes a layer from the map.
|
||
|
void removeLayer(Layer* layer);
|
||
|
|
||
|
//! Moves a layer to another position in the Map.
|
||
|
void moveLayer(Layer* layer, unsigned index);
|
||
|
|
||
|
//! Index of the specified layer, or returns getNumLayers() if the layer is not found.
|
||
|
unsigned getIndexOfLayer(const Layer* layer) const;
|
||
|
|
||
|
//! Copies references of the map layers into the output list.
|
||
|
//! This method is thread safe. It returns the map revision that was
|
||
|
//! in effect when the data was copied.
|
||
|
Revision getLayers(LayerVector& out_layers) const;
|
||
|
|
||
|
//! Copies references of the map layers into the output list for which
|
||
|
//! the predicate function returns true.
|
||
|
//! This method is thread safe. It returns the map revision that was
|
||
|
//! in effect when the data was copied.
|
||
|
inline Revision getLayers(
|
||
|
LayerVector& out_layers,
|
||
|
const std::function<bool(const Layer*)>& predicate) const;
|
||
|
|
||
|
//! Number of layers in the map.
|
||
|
unsigned getNumLayers() const;
|
||
|
|
||
|
//! Gets a layer by name.
|
||
|
Layer* getLayerByName(const std::string& name) const;
|
||
|
template<typename T> T* getLayerByName(const std::string& name) const;
|
||
|
|
||
|
//! Gets an image layer by its unique ID.
|
||
|
Layer* getLayerByUID(UID layerUID) const;
|
||
|
template<typename T> T* getLayerByUID(UID layerUID) const;
|
||
|
|
||
|
//! Gets the layer at the specified index.
|
||
|
Layer* getLayerAt(unsigned index) const;
|
||
|
template<typename T> T* getLayerAt(unsigned index) const;
|
||
|
|
||
|
//! Fills the vector with references to all layers of the specified type
|
||
|
//! and returns the corresponding revision number.
|
||
|
template<typename T>
|
||
|
Revision getLayers(std::vector< osg::ref_ptr<T> >& output) const;
|
||
|
|
||
|
//! Fills the vector with references to all layers of the specified type
|
||
|
//! and returns the corresponding revision number.
|
||
|
template<typename T>
|
||
|
Revision getOpenLayers(std::vector< osg::ref_ptr<T> >& output) const;
|
||
|
|
||
|
//! Fills the vector with references to all layers satisflying the predicate
|
||
|
//! and returns the corresponding revision number.
|
||
|
template<typename T>
|
||
|
Revision getLayers(
|
||
|
std::vector< osg::ref_ptr<T> >& output,
|
||
|
const std::function<bool(const T*)>& predicate) const;
|
||
|
|
||
|
//! Fills the vector with references to all layers of the specified type.
|
||
|
//! and returns the corresponding revision number.
|
||
|
template<typename T>
|
||
|
Revision getLayers(osg::MixinVector< osg::ref_ptr<T> >& output) const;
|
||
|
|
||
|
//! Fills the vector with references to all layers satisflying the predicate
|
||
|
//! and returns the corresponding revision number.
|
||
|
template<typename T>
|
||
|
Revision getLayers(
|
||
|
osg::MixinVector<osg::ref_ptr<T>>& output,
|
||
|
const std::function<bool(const Layer*)>& predicate) const;
|
||
|
|
||
|
//! Fills the vector with references to all layers of the specified type.
|
||
|
//! and returns the corresponding revision number.
|
||
|
template<typename T>
|
||
|
Revision getOpenLayers(osg::MixinVector< osg::ref_ptr<T> >& output) const;
|
||
|
|
||
|
//! The first layer of the specified type. This is useful when you
|
||
|
//! know there in only one layer of the type you are looking for.
|
||
|
template<typename T> T* getLayer() const;
|
||
|
|
||
|
//! Adds a map layer callback to this map. This will be notified whenever layers are
|
||
|
//! added, removed, or re-ordered.
|
||
|
MapCallback* addMapCallback(MapCallback* callback) const;
|
||
|
|
||
|
//! Removes a callback previously added with addMapCallback.
|
||
|
void removeMapCallback(MapCallback* callback) const;
|
||
|
|
||
|
//! Begins a batch-update operation. Call this if you intend to add multiple
|
||
|
//! layers at once; then call endUpdate() to complete the operation.
|
||
|
//! Between calls to beginUpdate() and endUpdate(), Map will not invoke
|
||
|
//! any callbacks you added wtih addMapCallback.
|
||
|
void beginUpdate();
|
||
|
|
||
|
//! Completes a batch update operation that started with a call to
|
||
|
//! beginUpdate(). Fires all callbacks for operations that occurred
|
||
|
//! since the call to beginUpdate().
|
||
|
void endUpdate();
|
||
|
|
||
|
//! Removes all layers from this map.
|
||
|
void clear();
|
||
|
|
||
|
//! Sets the readable name of this map.
|
||
|
void setMapName( const std::string& name );
|
||
|
const std::string& getMapName() const { return _name; }
|
||
|
|
||
|
//! Cache for this Map. Set to NULL for no cache.
|
||
|
//! Only call this during intiailization.
|
||
|
void setCache( Cache* cache );
|
||
|
Cache* getCache() const;
|
||
|
|
||
|
//! Caching policy (now the map should use the cache)
|
||
|
void setCachePolicy(const CachePolicy& value);
|
||
|
const CachePolicy& getCachePolicy() const;
|
||
|
|
||
|
//! Gets the revision # of the map. The revision # changes every time
|
||
|
//! you add, remove, or move layers. You can use this to track changes
|
||
|
//! in the map model (as a alternative to installing a MapCallback).
|
||
|
Revision getDataModelRevision() const;
|
||
|
|
||
|
//! Gets the database options associated with this map.
|
||
|
const osgDB::Options* getReadOptions() const { return _readOptions.get(); }
|
||
|
|
||
|
//! Gets a version of the map profile without any vertical datum
|
||
|
const Profile* getProfileNoVDatum() const { return _profileNoVDatum.get(); }
|
||
|
|
||
|
//! Access to an elevation sampling service tied to this map
|
||
|
ElevationPool* getElevationPool() const;
|
||
|
|
||
|
//! Returns true if data for the given tile key and layers is likely
|
||
|
//! to generate data quickly. This is used for pager thread pool shunting.
|
||
|
//! Really just a best guess based on available information.
|
||
|
bool isFast(const TileKey& key, const LayerVector& layers) const;
|
||
|
|
||
|
//! List of attribution strings to be displayed by the application
|
||
|
void getAttributions(StringSet& attributions) const;
|
||
|
|
||
|
//! Number of layers marked as terrain pathes
|
||
|
int getNumTerrainPatchLayers() const;
|
||
|
|
||
|
protected:
|
||
|
|
||
|
virtual ~Map();
|
||
|
|
||
|
// disables copy construction
|
||
|
Map(const Map& rhs, const osg::CopyOp& copy) { }
|
||
|
|
||
|
public: // serialization data
|
||
|
class OSGEARTH_EXPORT Options : public ConfigOptions {
|
||
|
public:
|
||
|
META_ConfigOptions(osgEarth, Options, ConfigOptions);
|
||
|
OE_OPTION(std::string, name);
|
||
|
OE_OPTION(ProfileOptions, profile);
|
||
|
OE_OPTION(CacheOptions, cache);
|
||
|
OE_OPTION(CachePolicy, cachePolicy);
|
||
|
OE_OPTION(RasterInterpolation, elevationInterpolation, INTERP_BILINEAR);
|
||
|
OE_OPTION(std::string, profileLayer);
|
||
|
OE_OPTION(std::string, osgOptionString);
|
||
|
OE_OPTION(bool, disableElevationRanges, false);
|
||
|
virtual Config getConfig() const;
|
||
|
private:
|
||
|
void fromConfig(const Config&);
|
||
|
};
|
||
|
|
||
|
//! Internal - create from serialized options
|
||
|
Map(
|
||
|
const Map::Options& options,
|
||
|
const osgDB::Options* readOptions);
|
||
|
|
||
|
//! Ready-only access to the serialization options for this map
|
||
|
const Options& options() const { return _optionsConcrete; }
|
||
|
|
||
|
private:
|
||
|
UID _uid;
|
||
|
std::string _name;
|
||
|
LayerVector _layers;
|
||
|
mutable MapCallbackList _mapCallbacks;
|
||
|
mutable Threading::ReadWriteMutex _mapDataMutex;
|
||
|
osg::ref_ptr<const Profile> _profile;
|
||
|
osg::ref_ptr<const Profile> _profileNoVDatum;
|
||
|
Revision _dataModelRevision;
|
||
|
osg::ref_ptr<osgDB::Options> _readOptions;
|
||
|
osg::ref_ptr<ElevationPool> _elevationPool;
|
||
|
osg::ref_ptr<CacheSettings> _cacheSettings;
|
||
|
int _numTerrainPatchLayers;
|
||
|
|
||
|
struct LayerCB : public LayerCallback {
|
||
|
LayerCB(Map*);
|
||
|
osg::observer_ptr<Map> _map;
|
||
|
void onOpen(Layer* layer);
|
||
|
void onClose(Layer* layer);
|
||
|
};
|
||
|
osg::ref_ptr<LayerCallback> _layerCB;
|
||
|
friend struct LayerCB;
|
||
|
void notifyOnLayerOpenOrClose(Layer*);
|
||
|
|
||
|
void installLayerCallbacks(Layer*);
|
||
|
void uninstallLayerCallbacks(Layer*);
|
||
|
|
||
|
void init();
|
||
|
Options _optionsConcrete;
|
||
|
Options& options() { return _optionsConcrete; }
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// Templated inline methods
|
||
|
|
||
|
template<typename T> T* Map::getLayerByName(const std::string& name) const {
|
||
|
return dynamic_cast<T*>(getLayerByName(name));
|
||
|
}
|
||
|
|
||
|
template<typename T> T* Map::getLayerByUID(UID layerUID) const {
|
||
|
return dynamic_cast<T*>(getLayerByUID(layerUID));
|
||
|
}
|
||
|
|
||
|
template<typename T> T* Map::getLayerAt(unsigned index) const {
|
||
|
return dynamic_cast<T*>(getLayerAt(index));
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
Revision Map::getLayers(std::vector<osg::ref_ptr<T>>& output) const {
|
||
|
Threading::ScopedReadLock lock(_mapDataMutex);
|
||
|
for (auto& i : _layers) {
|
||
|
T* obj = dynamic_cast<T*>(i.get());
|
||
|
if (obj) output.push_back(obj);
|
||
|
}
|
||
|
return _dataModelRevision;
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
Revision Map::getLayers(std::vector<osg::ref_ptr<T>>& output, const std::function<bool(const T*)>& predicate) const {
|
||
|
Threading::ScopedReadLock lock(_mapDataMutex);
|
||
|
for (auto& i : _layers) {
|
||
|
T* obj = dynamic_cast<T*>(i.get());
|
||
|
if (obj != nullptr && predicate(obj))
|
||
|
output.push_back(obj);
|
||
|
}
|
||
|
return _dataModelRevision;
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
Revision Map::getOpenLayers(std::vector<osg::ref_ptr<T>>& output) const {
|
||
|
Threading::ScopedReadLock lock(_mapDataMutex);
|
||
|
for (auto& i : _layers) {
|
||
|
if (i->isOpen()) {
|
||
|
T* obj = dynamic_cast<T*>(i.get());
|
||
|
if (obj) output.push_back(obj);
|
||
|
}
|
||
|
}
|
||
|
return _dataModelRevision;
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
Revision Map::getLayers(osg::MixinVector<osg::ref_ptr<T>>& output) const {
|
||
|
Threading::ScopedReadLock lock(_mapDataMutex);
|
||
|
for (auto& i : _layers) {
|
||
|
T* obj = dynamic_cast<T*>(i.get());
|
||
|
if (obj) output.push_back(obj);
|
||
|
}
|
||
|
return _dataModelRevision;
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
Revision Map::getLayers(osg::MixinVector<osg::ref_ptr<T>>& output, const std::function<bool(const Layer*)>& predicate) const {
|
||
|
Threading::ScopedReadLock lock(_mapDataMutex);
|
||
|
for (auto& i : _layers) {
|
||
|
T* obj = dynamic_cast<T*>(i.get());
|
||
|
if (obj != nullptr && predicate(obj))
|
||
|
output.push_back(obj);
|
||
|
}
|
||
|
return _dataModelRevision;
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
Revision Map::getOpenLayers(osg::MixinVector<osg::ref_ptr<T>>& output) const {
|
||
|
Threading::ScopedReadLock lock(_mapDataMutex);
|
||
|
for (auto& i : _layers) {
|
||
|
if (i->isOpen()) {
|
||
|
T* obj = dynamic_cast<T*>(i.get());
|
||
|
if (obj) output.push_back(obj);
|
||
|
}
|
||
|
}
|
||
|
return _dataModelRevision;
|
||
|
}
|
||
|
|
||
|
template<typename T> T* Map::getLayer() const {
|
||
|
Threading::ScopedReadLock lock(_mapDataMutex);
|
||
|
for (auto& i : _layers) {
|
||
|
T* obj = dynamic_cast<T*>(i.get());
|
||
|
if (obj) return obj;
|
||
|
}
|
||
|
return 0L;
|
||
|
}
|
||
|
|
||
|
Revision Map::getLayers(LayerVector& output, const std::function<bool(const Layer*)>& predicate) const {
|
||
|
Threading::ScopedReadLock lock(_mapDataMutex);
|
||
|
for (auto& i : _layers) {
|
||
|
if (predicate(i.get()))
|
||
|
output.push_back(i.get());
|
||
|
}
|
||
|
return _dataModelRevision;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif // OSGEARTH_MAP_H
|