585 lines
22 KiB
Plaintext
585 lines
22 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/>
|
||
|
*/
|
||
|
#pragma once
|
||
|
|
||
|
#include <osgEarth/Common>
|
||
|
#include <osgEarth/Config>
|
||
|
#include <osgEarth/Status>
|
||
|
#include <osgEarth/PluginLoader>
|
||
|
#include <osgEarth/Cache>
|
||
|
#include <osgEarth/SceneGraphCallback>
|
||
|
#include <osgEarth/LayerShader>
|
||
|
#include <osgEarth/Revisioning>
|
||
|
#include <osgEarth/IOTypes>
|
||
|
#include <osgEarth/DateTime>
|
||
|
#include <osg/BoundingBox>
|
||
|
#include <osg/Callback>
|
||
|
#include <vector>
|
||
|
|
||
|
namespace osg {
|
||
|
class StateSet;
|
||
|
}
|
||
|
namespace osgDB {
|
||
|
class Options;
|
||
|
}
|
||
|
|
||
|
//! Macro to use when defining a LayerOptions class
|
||
|
#define META_LayerOptions(LIBRARY, MYCLASS, SUPERCLASS) \
|
||
|
protected: \
|
||
|
virtual void mergeConfig(const osgEarth::Config& conf) { \
|
||
|
SUPERCLASS ::mergeConfig(conf); \
|
||
|
fromConfig(conf); \
|
||
|
} \
|
||
|
using super = SUPERCLASS; \
|
||
|
public: \
|
||
|
OE_COMMENT("Construct empty layer options") \
|
||
|
MYCLASS () : SUPERCLASS() { fromConfig(_conf); } \
|
||
|
\
|
||
|
OE_COMMENT("Construct layer options from serialized data") \
|
||
|
MYCLASS (const osgEarth::ConfigOptions& opt) : SUPERCLASS(opt) { fromConfig(_conf); } \
|
||
|
\
|
||
|
osgEarth::Config& _internal() { return _conf; } \
|
||
|
const osgEarth::Config& _internal() const { return _conf; }
|
||
|
|
||
|
|
||
|
//! Macro to use when defining a Layer class
|
||
|
#define META_Layer(LIBRARY, MYCLASS, OPTIONS, SUPERCLASS, SLUG) \
|
||
|
private: \
|
||
|
OPTIONS * _options; \
|
||
|
OPTIONS _optionsConcrete; \
|
||
|
const OPTIONS * _options0; \
|
||
|
const OPTIONS _optionsConcrete0; \
|
||
|
MYCLASS ( const MYCLASS& rhs, const osg::CopyOp& op ) { } \
|
||
|
using super = SUPERCLASS; \
|
||
|
protected: \
|
||
|
OE_COMMENT("Construct a new layer with default options") \
|
||
|
MYCLASS (OPTIONS* optr, const OPTIONS* optr0) : \
|
||
|
SUPERCLASS (optr? optr: &_optionsConcrete, optr0? optr0 : &_optionsConcrete0), \
|
||
|
_options(optr ? optr : &_optionsConcrete), \
|
||
|
_options0(optr0 ? optr0 : &_optionsConcrete0) { } \
|
||
|
public: \
|
||
|
META_Object(LIBRARY, MYCLASS); \
|
||
|
\
|
||
|
OE_COMMENT("Construct a new layer with default options") \
|
||
|
MYCLASS () : \
|
||
|
SUPERCLASS (&_optionsConcrete, &_optionsConcrete0), \
|
||
|
_options(&_optionsConcrete), \
|
||
|
_options0(&_optionsConcrete0) { MYCLASS::init(); } \
|
||
|
\
|
||
|
OE_COMMENT("Construct a new layer with user-defined options") \
|
||
|
MYCLASS (const OPTIONS& o) : \
|
||
|
SUPERCLASS (&_optionsConcrete, &_optionsConcrete0), \
|
||
|
_options(&_optionsConcrete), _optionsConcrete(o), \
|
||
|
_options0(&_optionsConcrete0), _optionsConcrete0(o) { MYCLASS::init(); } \
|
||
|
\
|
||
|
OE_COMMENT("Mutable options for this layer") \
|
||
|
OPTIONS& options() { return *_options; } \
|
||
|
\
|
||
|
OE_COMMENT("Immutable options for this layer") \
|
||
|
const OPTIONS& options() const { return *_options; } \
|
||
|
\
|
||
|
OE_COMMENT("Immutable original (constructor) options for this layer") \
|
||
|
const OPTIONS& options_original() const { return *_options0; } \
|
||
|
\
|
||
|
OE_COMMENT("Configuration key for this layer (e.g. for earth files)") \
|
||
|
virtual const char* getConfigKey() const { return #SLUG ; }
|
||
|
|
||
|
|
||
|
//! Macro for defining a layer with a default Options structure
|
||
|
#define META_LayerNoOptions(LIBRARY, MYCLASS, SUPERCLASS, SLUG) \
|
||
|
public: \
|
||
|
struct Options : public SUPERCLASS::Options { \
|
||
|
META_LayerOptions(LIBRARY, Options, SUPERCLASS::Options); \
|
||
|
private: \
|
||
|
void fromConfig(const osgEarth::Config&) { } \
|
||
|
}; \
|
||
|
META_Layer(LIBRARY, MYCLASS, Options, SUPERCLASS, SLUG)
|
||
|
|
||
|
|
||
|
|
||
|
//! Macro to use when defining a Layer class
|
||
|
#define META_Layer_Abstract(LIBRARY, MYCLASS, OPTIONS, SUPERCLASS) \
|
||
|
private: \
|
||
|
OPTIONS * _options; \
|
||
|
const OPTIONS * _options0; \
|
||
|
MYCLASS ( const MYCLASS& rhs, const osg::CopyOp& op ) { } \
|
||
|
protected: \
|
||
|
OE_COMMENT("Construct a new layer with default options") \
|
||
|
MYCLASS (OPTIONS* optr, const OPTIONS* optr0) : \
|
||
|
SUPERCLASS (optr, optr0), \
|
||
|
_options(optr), \
|
||
|
_options0(optr0) { } \
|
||
|
MYCLASS () : SUPERCLASS () { } \
|
||
|
using super = SUPERCLASS; \
|
||
|
public: \
|
||
|
OE_COMMENT("Mutable options for this layer") \
|
||
|
OPTIONS& options() { return *_options; } \
|
||
|
\
|
||
|
OE_COMMENT("Immutable options for this layer") \
|
||
|
const OPTIONS& options() const { return *_options; } \
|
||
|
\
|
||
|
OE_COMMENT("Immutable original (constructor) options for this layer") \
|
||
|
const OPTIONS& options_original() const { return *_options0; }
|
||
|
|
||
|
//! Templated inline property implementation macro
|
||
|
#define OE_LAYER_PROPERTY_IMPL(CLASS, TYPE, FUNC, OPTION) \
|
||
|
void CLASS ::set ## FUNC (const TYPE & value) { options(). OPTION () = value; }\
|
||
|
const TYPE & CLASS ::get ## FUNC () const { return options(). OPTION ().get(); }
|
||
|
|
||
|
|
||
|
namespace osgEarth
|
||
|
{
|
||
|
class GeoExtent;
|
||
|
class SequenceControl;
|
||
|
class TerrainEngine;
|
||
|
class TerrainResources;
|
||
|
class TileKey;
|
||
|
|
||
|
//! Base class for layer property callbacks
|
||
|
struct LayerCallback : public osg::Referenced
|
||
|
{
|
||
|
virtual void onOpen(class Layer*) { }
|
||
|
virtual void onClose(class Layer*) { }
|
||
|
typedef void (LayerCallback::*MethodPtr)(class Layer* layer);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Base class for all Map layers.
|
||
|
*
|
||
|
* Subclass Layer to create a new layer type. Use the META_Layer macro
|
||
|
* to establish the standard options framework.
|
||
|
*
|
||
|
* When you create a Layer, init() is called. Do all one-time construction
|
||
|
* activity where.
|
||
|
*
|
||
|
* When you add a Layer to a Map, the follow methods are called in order:
|
||
|
*
|
||
|
* setReadOptions() sets OSG options for IO activity;
|
||
|
* open() to initialize any underlying data sources;
|
||
|
* addedToMap() to signal to the layer that it is now a member of a Map.
|
||
|
*/
|
||
|
class OSGEARTH_EXPORT Layer : public osg::Object
|
||
|
{
|
||
|
public:
|
||
|
META_Object(osgEarth, Layer);
|
||
|
|
||
|
/** Layer options for serialization */
|
||
|
class OSGEARTH_EXPORT Options : public ConfigOptions
|
||
|
{
|
||
|
public:
|
||
|
META_LayerOptions(osgEarth, Options, ConfigOptions);
|
||
|
OE_OPTION(std::string, name);
|
||
|
OE_OPTION(bool, openAutomatically, true);
|
||
|
OE_OPTION(bool, terrainPatch, false);
|
||
|
OE_OPTION(std::string, cacheId);
|
||
|
OE_OPTION(CachePolicy, cachePolicy);
|
||
|
OE_OPTION(std::string, shaderDefine);
|
||
|
OE_OPTION(std::string, attribution);
|
||
|
OE_OPTION(ShaderOptions, shader);
|
||
|
OE_OPTION_VECTOR(ShaderOptions, shaders);
|
||
|
OE_OPTION(ProxySettings, proxySettings);
|
||
|
OE_OPTION(std::string, osgOptionString);
|
||
|
OE_OPTION(unsigned, l2CacheSize, 0u);
|
||
|
virtual Config getConfig() const;
|
||
|
private:
|
||
|
void fromConfig(const Config& conf);
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
//! Hints that a layer can set to influence the operation of
|
||
|
//! the map engine
|
||
|
class Hints
|
||
|
{
|
||
|
public:
|
||
|
OE_OPTION(CachePolicy, cachePolicy);
|
||
|
OE_OPTION(unsigned, L2CacheSize);
|
||
|
OE_OPTION(bool, dynamic);
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
//! Constructs a map layer
|
||
|
Layer();
|
||
|
|
||
|
//! This layer's unique ID.
|
||
|
//! This value is generated automatically at runtime and is not
|
||
|
//! guaranteed to be the same from one run to the next.
|
||
|
UID getUID() const { return _uid; }
|
||
|
|
||
|
//! osgDB read options for this Layer.
|
||
|
//! If you set this, do so prior to calling open().
|
||
|
virtual void setReadOptions(const osgDB::Options* options);
|
||
|
|
||
|
//! osgDB read options for this Layer.
|
||
|
const osgDB::Options* getReadOptions() const;
|
||
|
|
||
|
//! Open a layer.
|
||
|
virtual Status open() final;
|
||
|
|
||
|
//! Open a layer. Shortcut for calling setReadOptions() followed by open().
|
||
|
virtual Status open(const osgDB::Options* options) final;
|
||
|
|
||
|
//! Close this layer.
|
||
|
virtual Status close();
|
||
|
|
||
|
//! Whether the layer is open
|
||
|
bool isOpen() const;
|
||
|
|
||
|
//! Status of this layer
|
||
|
const Status& getStatus() const;
|
||
|
|
||
|
//! @deprecated (remove after 2.10)
|
||
|
//! Sequence controller if the layer has one.
|
||
|
virtual SequenceControl* getSequenceControl() { return 0L; }
|
||
|
|
||
|
//! Serialize this layer into a Config object (if applicable)
|
||
|
virtual Config getConfig() const;
|
||
|
|
||
|
//! Whether to automatically open this layer (by calling open) when
|
||
|
//! adding the layer to a Map or when opening a map containing this Layer.
|
||
|
virtual void setOpenAutomatically(bool value);
|
||
|
|
||
|
//! Whether to automatically open this layer (by calling open) when
|
||
|
//! adding the layer to a Map or when opening a map containing this Layer.
|
||
|
virtual bool getOpenAutomatically() const;
|
||
|
|
||
|
//! Cacheing policy. Only set this before opening the layer or adding to a map.
|
||
|
void setCachePolicy(const CachePolicy& value);
|
||
|
const CachePolicy& getCachePolicy() const;
|
||
|
|
||
|
//! Optional scene graph provided by the layer.
|
||
|
//! When this layer is added to a Map, the MapNode will call this method and
|
||
|
//! add the return value to its scene graph; and remove it when the Layer
|
||
|
//! is removed from the Map.
|
||
|
virtual osg::Node* getNode() const { return 0L; }
|
||
|
|
||
|
//! Extent of this layer's data.
|
||
|
//! This method may return GeoExtent::INVALID which means that the
|
||
|
//! extent is unavailable (not necessarily that there is no data).
|
||
|
virtual const GeoExtent& getExtent() const;
|
||
|
|
||
|
//! Temporal extent of this layer's data.
|
||
|
virtual DateTimeExtent getDateTimeExtent() const;
|
||
|
|
||
|
//! Unique caching ID for this layer.
|
||
|
//! Only set this before opening the layer or adding to a map.
|
||
|
//! WARNING: You should be Very Careful when using this. The Layer will
|
||
|
//! automatically generate a cache ID that is sufficient most of the time.
|
||
|
//! Setting your own cache ID will require manual cache invalidation when
|
||
|
//! you change certain properties. Use are your own risk!
|
||
|
void setCacheID(const std::string& value);
|
||
|
virtual std::string getCacheID() const;
|
||
|
|
||
|
//! Callbacks that one can use to detect scene graph changes
|
||
|
SceneGraphCallbacks* getSceneGraphCallbacks() const;
|
||
|
|
||
|
//! Hints that a subclass can set to influence the engine
|
||
|
const Hints& getHints() const;
|
||
|
|
||
|
//! Options string to pass to OpenSceneGraph reader/writers
|
||
|
const std::string& getOsgOptionString() const;
|
||
|
|
||
|
public:
|
||
|
|
||
|
//! Layer's stateset, creating it is necessary
|
||
|
osg::StateSet* getOrCreateStateSet();
|
||
|
|
||
|
//! Layer's stateset, or NULL if none exists
|
||
|
osg::StateSet* getStateSet() const;
|
||
|
|
||
|
//! Stateset that should be applied to an entire terrain traversal
|
||
|
virtual osg::StateSet* getSharedStateSet(osg::NodeVisitor* nv) const { return NULL; }
|
||
|
|
||
|
//! How (and if) to use this layer when rendering terrain tiles.
|
||
|
enum RenderType
|
||
|
{
|
||
|
//! Layer does not draw anything (directly)
|
||
|
RENDERTYPE_NONE,
|
||
|
|
||
|
//! Layer requires a terrain rendering pass that draws terrain tiles with texturing
|
||
|
RENDERTYPE_TERRAIN_SURFACE,
|
||
|
|
||
|
//! Layer requires a terrain rendering pass that emits terrian patches or
|
||
|
//! invokes a custom drawing function
|
||
|
RENDERTYPE_TERRAIN_PATCH,
|
||
|
|
||
|
//! Layer that renders its own node graph or other geometry (no terrain)
|
||
|
RENDERTYPE_CUSTOM = RENDERTYPE_NONE
|
||
|
};
|
||
|
|
||
|
//! Rendering type of this layer
|
||
|
RenderType getRenderType() const { return _renderType; }
|
||
|
|
||
|
//! Rendering type of this layer
|
||
|
void setRenderType(RenderType value) { _renderType = value; }
|
||
|
|
||
|
//! Callback that modifies the layer's bounding box for a given tile key
|
||
|
virtual void modifyTileBoundingBox(const TileKey& key, osg::BoundingBox& box) const;
|
||
|
|
||
|
//! Class type name without namespace. For example if the leaf class type
|
||
|
const char* getTypeName() const;
|
||
|
|
||
|
//! Attribution to be displayed by the application
|
||
|
virtual std::string getAttribution() const;
|
||
|
|
||
|
//! Attribution to be displayed by the application
|
||
|
virtual void setAttribution(const std::string& attribution);
|
||
|
|
||
|
//! Set a serialized user property
|
||
|
void setUserProperty(
|
||
|
const std::string& key,
|
||
|
const std::string& value);
|
||
|
|
||
|
//! Get a serialized user property
|
||
|
template<typename T>
|
||
|
inline T getUserProperty(
|
||
|
const std::string& key,
|
||
|
T fallback) const;
|
||
|
|
||
|
public:
|
||
|
|
||
|
//! Traversal callback
|
||
|
class OSGEARTH_EXPORT TraversalCallback : public osg::Callback
|
||
|
{
|
||
|
public:
|
||
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) const =0;
|
||
|
protected:
|
||
|
void traverse(osg::Node* node, osg::NodeVisitor* nv) const;
|
||
|
};
|
||
|
|
||
|
//! Callback invoked by the terrain engine on this layer before applying
|
||
|
//! @deprecated replace with cull() override
|
||
|
void setCullCallback(TraversalCallback* tc);
|
||
|
const TraversalCallback* getCullCallback() const;
|
||
|
|
||
|
//! Called to traverse this layer
|
||
|
//! @deprecated Replace with cull() override
|
||
|
void apply(osg::Node* node, osg::NodeVisitor* nv) const;
|
||
|
|
||
|
//! Called by the terrain engine during the update traversal
|
||
|
virtual void update(osg::NodeVisitor& nv) { }
|
||
|
|
||
|
//! Map will call this function when this Layer is added to a Map.
|
||
|
virtual void addedToMap(const class Map*) { }
|
||
|
|
||
|
//! Map will call this function when this Layer is removed from a Map.
|
||
|
virtual void removedFromMap(const class Map*) { }
|
||
|
|
||
|
public: // osg::Object
|
||
|
|
||
|
virtual void setName(const std::string& name);
|
||
|
|
||
|
virtual void resizeGLObjectBuffers(unsigned maxSize);
|
||
|
|
||
|
virtual void releaseGLObjects(osg::State* state) const;
|
||
|
|
||
|
|
||
|
public: // Public internal methods
|
||
|
|
||
|
//! Creates a layer from serialized data - internal use
|
||
|
static osg::ref_ptr<Layer> create(const ConfigOptions& options);
|
||
|
|
||
|
//! Creates a layer from serialized data and attempt to cast it
|
||
|
//! to a specific type
|
||
|
template<class T>
|
||
|
static osg::ref_ptr<T> create_as(const ConfigOptions& options) {
|
||
|
auto layer = create(options);
|
||
|
return osg::ref_ptr<T>(dynamic_cast<T*>(layer.get()));
|
||
|
}
|
||
|
|
||
|
//! Extracts config options from a DB options - internal use
|
||
|
static const ConfigOptions& getConfigOptions(const osgDB::Options*);
|
||
|
|
||
|
//! Adds a property notification callback to this layer
|
||
|
void addCallback(LayerCallback* cb);
|
||
|
|
||
|
//! Removes a property notification callback from this layer
|
||
|
void removeCallback(LayerCallback* cb);
|
||
|
|
||
|
//! Revision number of this layer
|
||
|
int getRevision() const { return (int)_revision; }
|
||
|
|
||
|
//! Increment the revision number for this layer, which will
|
||
|
//! invalidate caches.
|
||
|
virtual void dirty();
|
||
|
|
||
|
class Options;
|
||
|
|
||
|
public: // deprecated
|
||
|
|
||
|
//! @deprecated - use getOpenAutomatically
|
||
|
bool getEnabled() const;
|
||
|
|
||
|
//! @deprecated - use setOpenAutomatically
|
||
|
void setEnabled(bool value);
|
||
|
|
||
|
protected:
|
||
|
|
||
|
//! Constructs a map layer by deserializing options.
|
||
|
Layer(
|
||
|
Layer::Options* options,
|
||
|
const Layer::Options* options0);
|
||
|
|
||
|
//! DTOR
|
||
|
virtual ~Layer();
|
||
|
|
||
|
//! post-ctor initialization, chain to subclasses.
|
||
|
//! MAKE SURE you call the superclass init() if you override this!
|
||
|
virtual void init();
|
||
|
|
||
|
//! Called by open() to connect to external resources and return a status.
|
||
|
//! MAKE SURE you call superclass openImplementation() if you override this!
|
||
|
//! This is where you will connect to back-end data sources if
|
||
|
//! appropriate. When added to a map, init() is called before open()
|
||
|
//! and addedToMap() is called after open() if it succeeds.
|
||
|
//! By default, returns STATUS_OK.
|
||
|
virtual Status openImplementation();
|
||
|
|
||
|
//! Called by close() to shut down the resources associated with a layer.
|
||
|
virtual Status closeImplementation();
|
||
|
|
||
|
//! Prepares the layer for rendering if necessary.
|
||
|
virtual void prepareForRendering(TerrainEngine*);
|
||
|
|
||
|
//! Sets the status for this layer - internal
|
||
|
const Status& setStatus(const Status& status) const;
|
||
|
|
||
|
//! Sets the status for this layer with a message - internal
|
||
|
const Status& setStatus(const Status::Code& statusCode, const std::string& message) const;
|
||
|
|
||
|
//! invoke layer callbacks
|
||
|
void fireCallback(LayerCallback::MethodPtr);
|
||
|
|
||
|
//! mutable layer hints for the subclass to optionally access
|
||
|
Hints& layerHints();
|
||
|
|
||
|
//! MapNode will call this function when terrain resources are available.
|
||
|
//! @deprecated Implement prepareForRendering instead
|
||
|
virtual void setTerrainResources(TerrainResources*) { }
|
||
|
|
||
|
private:
|
||
|
const std::string& _layerName;
|
||
|
UID _uid;
|
||
|
osg::ref_ptr<osg::StateSet> _stateSet;
|
||
|
RenderType _renderType;
|
||
|
mutable Status _status;
|
||
|
osg::ref_ptr<SceneGraphCallbacks> _sceneGraphCallbacks;
|
||
|
osg::ref_ptr<TraversalCallback> _traversalCallback;
|
||
|
Hints _hints;
|
||
|
std::atomic_int _revision = { 1 };
|
||
|
std::string _runtimeCacheId;
|
||
|
osg::ref_ptr<osgDB::Options> _readOptions;
|
||
|
osg::ref_ptr<CacheSettings> _cacheSettings;
|
||
|
std::vector<osg::ref_ptr<LayerShader> > _shaders;
|
||
|
mutable Threading::ReadWriteMutex _inuse_mutex;
|
||
|
|
||
|
//! Prepares the layer for rendering if necessary.
|
||
|
void invoke_prepareForRendering(TerrainEngine*);
|
||
|
|
||
|
protected:
|
||
|
typedef std::vector<osg::ref_ptr<LayerCallback> > CallbackVector;
|
||
|
CallbackVector _callbacks;
|
||
|
|
||
|
osgDB::Options* getMutableReadOptions() { return _readOptions.get(); }
|
||
|
|
||
|
void bumpRevision();
|
||
|
|
||
|
// subclass can call this to change an option that requires
|
||
|
// a re-opening of the layer.
|
||
|
template<typename T, typename V>
|
||
|
void setOptionThatRequiresReopen(T& target, const V& value);
|
||
|
|
||
|
// subclass can call this to change an option that requires
|
||
|
// a re-opening of the layer.
|
||
|
template<typename T>
|
||
|
void resetOptionThatRequiresReopen(T& target);
|
||
|
|
||
|
//! internal cache information
|
||
|
CacheSettings* getCacheSettings() { return _cacheSettings.get(); }
|
||
|
const CacheSettings* getCacheSettings() const { return _cacheSettings.get(); }
|
||
|
|
||
|
//! subclass access to a mutex that serializes the
|
||
|
//! Layer open and close methods with respect to any asynchronous
|
||
|
//! functions that require the layer to remain open
|
||
|
Threading::ReadWriteMutex& inUseMutex() const { return _inuse_mutex; }
|
||
|
|
||
|
//! Layers that this layer wants to add to the map
|
||
|
std::vector<osg::ref_ptr<Layer>> _sublayers;
|
||
|
|
||
|
public:
|
||
|
|
||
|
Layer::Options& options() { return *_options; }
|
||
|
const Layer::Options& options() const { return *_options; }
|
||
|
const Layer::Options& options_original() const { return *_options0; }
|
||
|
virtual const char* getConfigKey() const { return "layer" ; }
|
||
|
|
||
|
//! A layer can report statistics for debugging by overriding this function
|
||
|
using Stats = std::vector<std::pair<std::string, std::string>>;
|
||
|
virtual Stats reportStats() const { return {}; }
|
||
|
|
||
|
private:
|
||
|
Layer::Options * _options;
|
||
|
Layer::Options _optionsConcrete;
|
||
|
const Layer::Options * _options0;
|
||
|
const Layer::Options _optionsConcrete0;
|
||
|
|
||
|
// no copying
|
||
|
Layer(const Layer& rhs, const osg::CopyOp& op);
|
||
|
|
||
|
// allow the map access to the addedToMap/removedFromMap methods
|
||
|
friend class Map;
|
||
|
friend class MapNode;
|
||
|
};
|
||
|
|
||
|
using LayerVector = std::vector<osg::ref_ptr<Layer>>;
|
||
|
|
||
|
|
||
|
template<typename T, typename V>
|
||
|
void Layer::setOptionThatRequiresReopen(T& target, const V& value) {
|
||
|
if (target != value) {
|
||
|
bool wasOpen = isOpen();
|
||
|
if (wasOpen) close();
|
||
|
target = value;
|
||
|
if (wasOpen) open();
|
||
|
}
|
||
|
}
|
||
|
template<typename T>
|
||
|
void Layer::resetOptionThatRequiresReopen(T& target) {
|
||
|
if (target.isSet()) {
|
||
|
bool wasOpen = isOpen();
|
||
|
if (wasOpen) close();
|
||
|
target.unset();
|
||
|
if (wasOpen) open();
|
||
|
}
|
||
|
}
|
||
|
template<typename T>
|
||
|
T Layer::getUserProperty(const std::string& key, T fallback) const {
|
||
|
return options()._internal().value(key, fallback);
|
||
|
}
|
||
|
|
||
|
|
||
|
#define REGISTER_OSGEARTH_LAYER(NAME,CLASS) \
|
||
|
extern "C" void osgdb_osgearth_##NAME(void) {} \
|
||
|
static osgEarth::RegisterPluginLoader< osgEarth::PluginLoader<CLASS, osgEarth::Layer> > g_proxy_##CLASS_##NAME(OE_STRINGIFY(osgearth_layer_##NAME));
|
||
|
|
||
|
#define USE_OSGEARTH_LAYER(NAME) \
|
||
|
extern "C" void osgdb_osgearth_##NAME(void); \
|
||
|
static osgDB::PluginFunctionProxy proxy_osgearth_layer_##NAME(OE_STRINGIFY(osgdb_osgearth_##NAME));
|
||
|
|
||
|
} // namespace osgEarth
|