diff --git a/src/osgEarth/CMakeLists.txt b/src/osgEarth/CMakeLists.txt
index 294919d0d5..ce83d6063a 100644
--- a/src/osgEarth/CMakeLists.txt
+++ b/src/osgEarth/CMakeLists.txt
@@ -114,6 +114,7 @@ SET(LIB_PUBLIC_HEADERS
ColorFilter
Common
Composite
+ CompositeTiledModelLayer
Config
Containers
Coverage
@@ -260,7 +261,6 @@ SET(LIB_PUBLIC_HEADERS
TileHandler
TileMesher
TileRasterizer
- TiledFeatureModelGraph
TiledFeatureModelLayer
TiledModelLayer
TileSource
@@ -283,7 +283,6 @@ SET(LIB_PUBLIC_HEADERS
WMS
XmlUtils
XYZ
- XYZModelGraph
XYZModelLayer
ActivityMonitorTool
@@ -551,6 +550,7 @@ set(TARGET_SRC
Color.cpp
ColorFilter.cpp
Composite.cpp
+ CompositeTiledModelLayer.cpp
Compressors.cpp
Config.cpp
CoverageLayer.cpp
@@ -676,7 +676,6 @@ set(TARGET_SRC
TileHandler.cpp
TileMesher.cpp
TileRasterizer.cpp
- TiledFeatureModelGraph.cpp
TiledFeatureModelLayer.cpp
TiledModelLayer.cpp
TileVisitor.cpp
@@ -699,7 +698,6 @@ set(TARGET_SRC
WMS.cpp
XmlUtils.cpp
XYZ.cpp
- XYZModelGraph.cpp
XYZModelLayer.cpp
ActivityMonitorTool.cpp
diff --git a/src/osgEarth/CompositeTiledModelLayer b/src/osgEarth/CompositeTiledModelLayer
new file mode 100644
index 0000000000..05650aeeda
--- /dev/null
+++ b/src/osgEarth/CompositeTiledModelLayer
@@ -0,0 +1,95 @@
+/* -*-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
+ */
+#ifndef OSGEARTH_COMPOSITE_TILED_MODEL_LAYER
+#define OSGEARTH_COMPOSITE_TILED_MODEL_LAYER 1
+
+#include
+#include
+#include
+
+namespace osgEarth {
+ class Map;
+}
+
+namespace osgEarth
+{
+ class OSGEARTH_EXPORT CompositeTiledModelLayer : public TiledModelLayer
+ {
+ public: // serialization
+ struct OSGEARTH_EXPORT Options : public TiledModelLayer::Options
+ {
+ META_LayerOptions(osgEarth, Options, TiledModelLayer::Options);
+ OE_OPTION(ProfileOptions, profile);
+
+ OE_OPTION_VECTOR(ConfigOptions, layers);
+
+ Config getConfig() const override;
+ void fromConfig(const Config& conf);
+ };
+
+ public:
+ META_Layer(osgEarth, CompositeTiledModelLayer, Options, TiledModelLayer, CompositeTiledModel);
+
+ //! Tiling profile (required)
+ void setProfile(const Profile* profile);
+ const Profile* getProfile() const override { return _profile.get(); }
+
+ unsigned getMinLevel() const override;
+
+ //! Maximum level of detail to access
+ unsigned getMaxLevel() const override;
+
+ public: // Layer
+
+ //! opens the layer and returns the status
+ Status openImplementation() override;
+
+ //! Serialization
+ Config getConfig() const override;
+
+ public: // Layer
+
+ //! called by the map when this layer is added
+ void addedToMap(const Map*) override;
+
+ //! called by the map when this layer is removed
+ void removedFromMap(const Map*) override;
+
+ protected: // TiledModelLayer
+
+ //! Creates an OSG node from a tile key.
+ osg::ref_ptr createTileImplementation(const TileKey&, ProgressCallback*) const override;
+
+ protected:
+
+ virtual ~CompositeTiledModelLayer();
+
+ private:
+ osg::ref_ptr _profile;
+ osg::observer_ptr< const Map > _map;
+
+ unsigned int _minLevel = 0;
+ unsigned int _maxLevel = 0;
+
+ std::vector< osg::ref_ptr< TiledModelLayer > > _layers;
+ };
+
+} // namespace osgEarth
+
+#endif // OSGEARTH_COMPOSITE_TILED_MODEL_LAYER
diff --git a/src/osgEarth/CompositeTiledModelLayer.cpp b/src/osgEarth/CompositeTiledModelLayer.cpp
new file mode 100644
index 0000000000..27893dc637
--- /dev/null
+++ b/src/osgEarth/CompositeTiledModelLayer.cpp
@@ -0,0 +1,191 @@
+/* -*-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
+ */
+#include
+#include
+#include
+
+#include
+
+using namespace osgEarth;
+
+#define LC "[CompositeTiledModelLayer] "
+
+#define OE_TEST OE_NULL
+
+REGISTER_OSGEARTH_LAYER(CompositeTiledModel, CompositeTiledModelLayer);
+
+void CompositeTiledModelLayer::Options::fromConfig(const Config& conf)
+{
+ conf.get("profile", profile());
+
+ const ConfigSet& layers = conf.child("layers").children();
+ for (ConfigSet::const_iterator i = layers.begin(); i != layers.end(); ++i)
+ {
+ _layers.push_back(ConfigOptions(*i));
+ }
+}
+
+Config
+CompositeTiledModelLayer::Options::getConfig() const
+{
+ Config conf = TiledModelLayer::Options::getConfig();
+ conf.set("profile", profile());
+
+ if (_layers.empty() == false)
+ {
+ Config layersConf("layers");
+ for (std::vector::const_iterator i = _layers.begin(); i != _layers.end(); ++i)
+ {
+ layersConf.add(i->getConfig());
+ }
+ conf.set(layersConf);
+ }
+
+ return conf;
+}
+
+//...........................................................................
+
+CompositeTiledModelLayer::~CompositeTiledModelLayer()
+{
+ //NOP
+}
+
+void CompositeTiledModelLayer::setProfile(const Profile* profile)
+{
+ _profile = profile;
+ if (_profile)
+ {
+ options().profile() = profile->toProfileOptions();
+ }
+}
+
+Config
+CompositeTiledModelLayer::getConfig() const
+{
+ Config conf = TiledModelLayer::getConfig();
+ return conf;
+}
+
+Status
+CompositeTiledModelLayer::openImplementation()
+{
+ Status parent = super::openImplementation();
+ if (parent.isError())
+ return parent;
+
+ _profile = Profile::create(*options().profile());
+
+ // Open all the layers
+ for (auto& layerConf : options().layers())
+ {
+ osg::ref_ptr< Layer > layer = Layer::create(layerConf);
+ TiledModelLayer* tiledLayer = dynamic_cast(layer.get());
+ if (tiledLayer)
+ {
+ tiledLayer->open();
+ tiledLayer->setReadOptions(getReadOptions());
+ _layers.push_back(tiledLayer);
+ }
+ else
+ {
+ OE_WARN << LC << "Layer is not a TiledModelLayer" << std::endl;
+ }
+ }
+
+ return Status::NoError;
+}
+
+void
+CompositeTiledModelLayer::addedToMap(const Map* map)
+{
+ for (auto& layer : _layers)
+ {
+ layer->addedToMap(map);
+ }
+
+ // Check to make sure the layers are all using the same profile
+ for (auto& layer : _layers)
+ {
+ if (!layer->getProfile()->isEquivalentTo(_profile))
+ {
+ OE_WARN << LC << "Layer " << layer->getName() << " does not have the same profile as the composite layer" << std::endl;
+ }
+ }
+
+ // Compute the min and max levels
+ if (!_layers.empty())
+ {
+ _minLevel = 1000;
+ _maxLevel = 0;
+ for (auto& layer : _layers)
+ {
+ if (layer->getMinLevel() < _minLevel)
+ {
+ _minLevel = layer->getMinLevel();
+ }
+ if (layer->getMaxLevel() > _maxLevel)
+ {
+ _maxLevel = layer->getMaxLevel();
+ }
+ }
+ }
+
+ super::addedToMap(map);
+}
+
+void
+CompositeTiledModelLayer::removedFromMap(const Map* map)
+{
+ super::removedFromMap(map);
+
+ for (auto& layer : _layers)
+ {
+ layer->removedFromMap(map);
+ }
+}
+
+osg::ref_ptr
+CompositeTiledModelLayer::createTileImplementation(const TileKey& key, ProgressCallback* progress) const
+{
+ osg::ref_ptr group = new osg::Group();
+
+ for (unsigned int i = 0; i < this->_layers.size(); i++)
+ {
+ osg::ref_ptr node = this->_layers[i]->createTile(key, progress);
+ if (node.valid())
+ {
+ group->addChild(node);
+ }
+ }
+ return group;
+}
+
+unsigned
+CompositeTiledModelLayer::getMinLevel() const
+{
+ return _minLevel;
+}
+
+unsigned
+CompositeTiledModelLayer::getMaxLevel() const
+{
+ return _maxLevel;
+}
+
diff --git a/src/osgEarth/TiledFeatureModelGraph.cpp b/src/osgEarth/TiledFeatureModelGraph.cpp
deleted file mode 100644
index 1c95007d64..0000000000
--- a/src/osgEarth/TiledFeatureModelGraph.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* -*-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
- */
-#include
-#include
-#include
-#include
-#include
-
-using namespace osgEarth;
-
-TiledFeatureModelGraph::TiledFeatureModelGraph(const osgEarth::Map* map,
- FeatureSource* features,
- StyleSheet* styleSheet,
- Session* session) :
- SimplePager(map, (features && features->getFeatureProfile()) ? features->getFeatureProfile()->getTilingProfile() : nullptr),
- _features(features),
- _styleSheet(styleSheet),
- _session(session)
-{
- setMinLevel(features->getFeatureProfile()->getFirstLevel());
- setMaxLevel(features->getFeatureProfile()->getMaxLevel());
-
- _session->setResourceCache(new ResourceCache());
-
-
- FeatureSourceIndexOptions indexOptions;
- indexOptions.enabled() = true;
-
- _featureIndex = new FeatureSourceIndex(
- features,
- Registry::objectIndex(),
- indexOptions);
-}
-
-void
-TiledFeatureModelGraph::setFilterChain(FeatureFilterChain* chain)
-{
- _filterChain = chain;
-}
-
-void
-TiledFeatureModelGraph::setOwnerName(const std::string& value)
-{
- _ownerName = value;
-}
-
-
-FeatureCursor*
-TiledFeatureModelGraph::createCursor(FeatureSource* fs, FilterContext& cx, const Query& query, ProgressCallback* progress) const
-{
- NetworkMonitor::ScopedRequestLayer layerRequest(_ownerName);
- FeatureCursor* cursor = fs->createFeatureCursor(query, progress);
- if (cursor && _filterChain.valid())
- {
- cursor = new FilteredFeatureCursor(cursor, _filterChain.get(), &cx);
- }
- return cursor;
-}
-
-osg::ref_ptr
-TiledFeatureModelGraph::createNode(const TileKey& key, ProgressCallback* progress)
-{
- if (progress && progress->isCanceled())
- return nullptr;
-
- NetworkMonitor::ScopedRequestLayer layerRequest(_ownerName);
- // Get features for this key
- Query query;
- query.tileKey() = key;
-
- GeoExtent dataExtent = key.getExtent();
-
- // set up for feature indexing if appropriate:
- osg::ref_ptr< FeatureSourceIndexNode > index = 0L;
-
- if (_featureIndex.valid())
- {
- index = new FeatureSourceIndexNode(_featureIndex.get());
- }
-
- FilterContext fc(_session.get(), new FeatureProfile(dataExtent), dataExtent, index);
-
- GeometryCompilerOptions options;
- options.instancing() = true;
- //options.mergeGeometry() = true;
- GeometryCompiler gc(options);
-
- GeomFeatureNodeFactory factory(options);
-
- if (progress && progress->isCanceled())
- return nullptr;
-
- osg::ref_ptr< FeatureCursor > cursor = _features->createFeatureCursor(
- query,
- _filterChain.get(),
- &fc,
- progress);
-
- osg::ref_ptr node = new osg::Group;
- if (cursor)
- {
- if (progress && progress->isCanceled())
- return nullptr;
-
- FeatureList features;
- cursor->fill(features);
-
- if (_styleSheet->getSelectors().size() > 0)
- {
- osg::Group* group = new osg::Group;
-
- for (StyleSelectors::const_iterator i = _styleSheet->getSelectors().begin();
- i != _styleSheet->getSelectors().end();
- ++i)
- {
- typedef std::map< std::string, FeatureList > StyleToFeaturesMap;
- StyleToFeaturesMap styleToFeatures;
-
- // pull the selected style...
- const StyleSelector& sel = i->second;
-
- if (sel.styleExpression().isSet())
- {
- // establish the working bounds and a context:
- StringExpression styleExprCopy(sel.styleExpression().get());
- for (FeatureList::iterator itr = features.begin(); itr != features.end(); ++itr)
- {
- Feature* feature = itr->get();
-
- feature->set("level", (long long)key.getLevelOfDetail());
-
- const std::string& styleString = feature->eval(styleExprCopy, &fc);
- if (!styleString.empty() && styleString != "null")
- {
- styleToFeatures[styleString].push_back(feature);
- }
-
- if (progress && progress->isCanceled())
- return nullptr;
- }
- }
-
- std::unordered_map literal_styles;
-
- for (StyleToFeaturesMap::iterator itr = styleToFeatures.begin(); itr != styleToFeatures.end(); ++itr)
- {
- const std::string& styleString = itr->first;
- Style* style = nullptr;
-
- if (styleString.length() > 0 && styleString[0] == '{')
- {
- Config conf("style", styleString);
- conf.setReferrer(sel.styleExpression().get().uriContext().referrer());
- conf.set("type", "text/css");
- Style& literal_style = literal_styles[conf.toJSON()];
- if (literal_style.empty())
- literal_style = Style(conf);
- style = &literal_style;
- }
- else
- {
- style = _styleSheet->getStyle(styleString);
- }
-
- if (style)
- {
- osg::Group* styleGroup = factory.getOrCreateStyleGroup(*style, _session.get());
- osg::ref_ptr< osg::Node> styleNode;
- osg::ref_ptr< FeatureListCursor> cursor = new FeatureListCursor(itr->second);
- Query query;
- factory.createOrUpdateNode(cursor.get(), *style, fc, styleNode, query);
- if (styleNode.valid())
- {
- styleGroup->addChild(styleNode);
- if (!group->containsNode(styleGroup))
- {
- group->addChild(styleGroup);
- }
- }
- }
- }
- }
-
-
- node = group;
- }
- else if (_styleSheet->getDefaultStyle())
- {
- osg::ref_ptr< FeatureListCursor> cursor = new FeatureListCursor(features);
- osg::ref_ptr< osg::Group > group = new osg::Group;
- osg::ref_ptr< osg::Group > styleGroup = factory.getOrCreateStyleGroup(*_styleSheet->getDefaultStyle(), _session.get());
- osg::ref_ptr< osg::Node> styleNode;
- factory.createOrUpdateNode(cursor.get(), *_styleSheet->getDefaultStyle(), fc, styleNode, query);
- if (styleNode.valid())
- {
- group->addChild(styleGroup);
- styleGroup->addChild(styleNode);
- node = group;
- }
- }
- }
-
- if (!node->getBound().valid())
- {
- return nullptr;
- }
-
- if (index.valid())
- {
- index->addChild(node);
- return index;
- }
-
- return node;
-}
\ No newline at end of file
diff --git a/src/osgEarth/TiledFeatureModelLayer b/src/osgEarth/TiledFeatureModelLayer
index b4a3f938af..09549c504c 100644
--- a/src/osgEarth/TiledFeatureModelLayer
+++ b/src/osgEarth/TiledFeatureModelLayer
@@ -51,8 +51,7 @@ namespace osgEarth
// constructors
Options();
Options(const ConfigOptions& options);
- OE_OPTION_LAYER(FeatureSource, featureSource);
- OE_OPTION(bool, additive);
+ OE_OPTION_LAYER(FeatureSource, featureSource);
Config getConfig() const override;
protected: // LayerOptions
void mergeConfig(const Config& conf) override;
@@ -79,13 +78,6 @@ namespace osgEarth
void setEnableLighting(const bool& value);
const bool& getEnableLighting() const;
- //! Whether new LODs should be added to the scene (true) or replace existing ones (false)
- void setAdditive(const bool& value);
- const bool& getAdditive() const;
-
- //! Forces a rebuild on this FeatureModelLayer.
- void dirty();
-
public: // Layer
// opens the layer and returns the status
@@ -94,9 +86,6 @@ namespace osgEarth
// closes the layer
Status closeImplementation() override;
- // The Node representing this layer.
- osg::Node* getNode() const override;
-
//! Extent of the feature layer, if available (INVALID if not)
const GeoExtent& getExtent() const override;
@@ -136,10 +125,8 @@ namespace osgEarth
private:
osg::ref_ptr _session;
- osg::ref_ptr _root;
- bool _graphDirty;
-
- void create();
+ osg::ref_ptr _filters;
+ osg::ref_ptr< FeatureSourceIndex > _featureIndex;
};
} // namespace osgEarth
diff --git a/src/osgEarth/TiledFeatureModelLayer.cpp b/src/osgEarth/TiledFeatureModelLayer.cpp
index e0aca4c4cc..86ed286c5a 100644
--- a/src/osgEarth/TiledFeatureModelLayer.cpp
+++ b/src/osgEarth/TiledFeatureModelLayer.cpp
@@ -17,7 +17,8 @@
* along with this program. If not, see
*/
#include
-#include
+#include
+#include
using namespace osgEarth;
@@ -47,8 +48,6 @@ TiledFeatureModelLayer::Options::Options(const ConfigOptions& options) :
void TiledFeatureModelLayer::Options::fromConfig(const Config& conf)
{
- additive().setDefault(false);
- conf.get("additive", additive());
featureSource().get(conf, "features");
}
@@ -63,8 +62,6 @@ TiledFeatureModelLayer::Options::getConfig() const
Config gcConf = GeometryCompilerOptions::getConfig();
conf.merge(gcConf);
- conf.set("additive", additive());
-
featureSource().set(conf, "features");
return conf;
@@ -80,7 +77,6 @@ void TiledFeatureModelLayer::Options::mergeConfig(const Config& conf)
OE_LAYER_PROPERTY_IMPL(TiledFeatureModelLayer, bool, AlphaBlending, alphaBlending);
OE_LAYER_PROPERTY_IMPL(TiledFeatureModelLayer, bool, EnableLighting, enableLighting);
-OE_LAYER_PROPERTY_IMPL(TiledFeatureModelLayer, bool, Additive, additive);
TiledFeatureModelLayer::~TiledFeatureModelLayer()
{
@@ -91,26 +87,6 @@ void
TiledFeatureModelLayer::init()
{
TiledModelLayer::init();
-
- _root = new osg::Group();
-
- // Assign the layer's state set to the root node:
- _root->setStateSet(this->getOrCreateStateSet());
-
- // Graph needs rebuilding
- _graphDirty = true;
-
- // Depth sorting by default
- getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
-}
-
-void TiledFeatureModelLayer::dirty()
-{
- // feature source changed, so the graph needs rebuilding
- _graphDirty = true;
-
- // create the scene graph
- create();
}
Config
@@ -159,12 +135,6 @@ TiledFeatureModelLayer::getStyleSheet() const
return options().styleSheet().getLayer();
}
-osg::Node*
-TiledFeatureModelLayer::getNode() const
-{
- return _root.get();
-}
-
Status
TiledFeatureModelLayer::openImplementation()
{
@@ -186,9 +156,9 @@ TiledFeatureModelLayer::openImplementation()
Status
TiledFeatureModelLayer::closeImplementation()
{
+ super::closeImplementation();
options().featureSource().close();
options().styleSheet().close();
- _graphDirty = true;
return getStatus();
}
@@ -207,7 +177,7 @@ void
TiledFeatureModelLayer::addedToMap(const Map* map)
{
OE_TEST << LC << "addedToMap" << std::endl;
- TiledModelLayer::addedToMap(map);
+
options().featureSource().addedToMap(map);
options().styleSheet().addedToMap(map);
@@ -222,29 +192,36 @@ TiledFeatureModelLayer::addedToMap(const Map* map)
getFeatureSource(),
getReadOptions());
- // re-create the graph if necessary.
- create();
+ // connect the session to the features:
+ _session->setFeatureSource(getFeatureSource());
+ _session->setResourceCache(new ResourceCache());
+
+ FeatureSourceIndexOptions indexOptions;
+ indexOptions.enabled() = true;
+
+ _featureIndex = new FeatureSourceIndex(
+ getFeatureSource(),
+ Registry::objectIndex(),
+ indexOptions);
}
+
+ _filters = FeatureFilterChain::create(options().filters(), getReadOptions());
+
+ TiledModelLayer::addedToMap(map);
}
void
TiledFeatureModelLayer::removedFromMap(const Map* map)
{
- TiledModelLayer::removedFromMap(map);
+ super::removedFromMap(map);
options().featureSource().removedFromMap(map);
options().styleSheet().removedFromMap(map);
- if (_root.valid())
- {
- osg::ref_ptr tfmg = findTopMostNodeOfType(_root.get());
- if (tfmg.valid()) tfmg->setDone();
- _root->removeChildren(0, _root->getNumChildren());
- }
-
_session = 0L;
}
+#if 0
void
TiledFeatureModelLayer::create()
{
@@ -266,6 +243,7 @@ TiledFeatureModelLayer::create()
fmg->setOwnerName(getName());
fmg->setFilterChain(chain.get());
fmg->setAdditive(*_options->additive());
+ fmg->setRangeFactor(*_options->rangeFactor());
fmg->build();
_root->removeChildren(0, _root->getNumChildren());
@@ -279,36 +257,179 @@ TiledFeatureModelLayer::create()
}
}
}
+#endif
osg::ref_ptr
TiledFeatureModelLayer::createTileImplementation(const TileKey& key, ProgressCallback* progress) const
{
- osg::ref_ptr result;
- auto fmg = osgEarth::findTopMostNodeOfType(_root.get());
- if (fmg)
+ if (progress && progress->isCanceled())
+ return nullptr;
+
+ NetworkMonitor::ScopedRequestLayer layerRequest(getName());
+ // Get features for this key
+ Query query;
+ query.tileKey() = key;
+
+ GeoExtent dataExtent = key.getExtent();
+
+ // set up for feature indexing if appropriate:
+ osg::ref_ptr< FeatureSourceIndexNode > index = 0L;
+
+ if (_featureIndex.valid())
+ {
+ index = new FeatureSourceIndexNode(_featureIndex.get());
+ }
+
+ FilterContext fc(_session.get(), new FeatureProfile(dataExtent), dataExtent, index);
+
+ GeometryCompilerOptions options;
+ options.instancing() = true;
+ //options.mergeGeometry() = true;
+ GeometryCompiler gc(options);
+
+ GeomFeatureNodeFactory factory(options);
+
+ if (progress && progress->isCanceled())
+ return nullptr;
+
+ osg::ref_ptr< FeatureCursor > cursor = getFeatureSource()->createFeatureCursor(
+ query,
+ _filters.get(),
+ &fc,
+ progress);
+
+ osg::ref_ptr node = new osg::Group;
+ if (cursor)
+ {
+ if (progress && progress->isCanceled())
+ return nullptr;
+
+ FeatureList features;
+ cursor->fill(features);
+
+ if (getStyleSheet()->getSelectors().size() > 0)
+ {
+ osg::Group* group = new osg::Group;
+
+ for (StyleSelectors::const_iterator i = getStyleSheet()->getSelectors().begin();
+ i != getStyleSheet()->getSelectors().end();
+ ++i)
+ {
+ typedef std::map< std::string, FeatureList > StyleToFeaturesMap;
+ StyleToFeaturesMap styleToFeatures;
+
+ // pull the selected style...
+ const StyleSelector& sel = i->second;
+
+ if (sel.styleExpression().isSet())
+ {
+ // establish the working bounds and a context:
+ StringExpression styleExprCopy(sel.styleExpression().get());
+ for (FeatureList::iterator itr = features.begin(); itr != features.end(); ++itr)
+ {
+ Feature* feature = itr->get();
+
+ feature->set("level", (long long)key.getLevelOfDetail());
+
+ const std::string& styleString = feature->eval(styleExprCopy, &fc);
+ if (!styleString.empty() && styleString != "null")
+ {
+ styleToFeatures[styleString].push_back(feature);
+ }
+
+ if (progress && progress->isCanceled())
+ return nullptr;
+ }
+ }
+
+ std::unordered_map literal_styles;
+
+ for (StyleToFeaturesMap::iterator itr = styleToFeatures.begin(); itr != styleToFeatures.end(); ++itr)
+ {
+ const std::string& styleString = itr->first;
+ Style* style = nullptr;
+
+ if (styleString.length() > 0 && styleString[0] == '{')
+ {
+ Config conf("style", styleString);
+ conf.setReferrer(sel.styleExpression().get().uriContext().referrer());
+ conf.set("type", "text/css");
+ Style& literal_style = literal_styles[conf.toJSON()];
+ if (literal_style.empty())
+ literal_style = Style(conf);
+ style = &literal_style;
+ }
+ else
+ {
+ style = getStyleSheet()->getStyle(styleString);
+ }
+
+ if (style)
+ {
+ osg::Group* styleGroup = factory.getOrCreateStyleGroup(*style, _session.get());
+ osg::ref_ptr< osg::Node> styleNode;
+ osg::ref_ptr< FeatureListCursor> cursor = new FeatureListCursor(itr->second);
+ Query query;
+ factory.createOrUpdateNode(cursor.get(), *style, fc, styleNode, query);
+ if (styleNode.valid())
+ {
+ styleGroup->addChild(styleNode);
+ if (!group->containsNode(styleGroup))
+ {
+ group->addChild(styleGroup);
+ }
+ }
+ }
+ }
+ }
+
+
+ node = group;
+ }
+ else if (getStyleSheet()->getDefaultStyle())
+ {
+ osg::ref_ptr< FeatureListCursor> cursor = new FeatureListCursor(features);
+ osg::ref_ptr< osg::Group > group = new osg::Group;
+ osg::ref_ptr< osg::Group > styleGroup = factory.getOrCreateStyleGroup(*getStyleSheet()->getDefaultStyle(), _session.get());
+ osg::ref_ptr< osg::Node> styleNode;
+ factory.createOrUpdateNode(cursor.get(), *getStyleSheet()->getDefaultStyle(), fc, styleNode, query);
+ if (styleNode.valid())
+ {
+ group->addChild(styleGroup);
+ styleGroup->addChild(styleNode);
+ node = group;
+ }
+ }
+ }
+
+ if (!node->getBound().valid())
{
- result = fmg->createNode(key, progress);
+ return nullptr;
}
- return result;
+
+ if (index.valid())
+ {
+ index->addChild(node);
+ return index;
+ }
+
+ return node;
}
const Profile*
TiledFeatureModelLayer::getProfile() const
{
- auto fmg = osgEarth::findTopMostNodeOfType(_root.get());
- return fmg ? fmg->getProfile() : nullptr;
+ return getFeatureSource()->getFeatureProfile()->getTilingProfile();
}
unsigned
TiledFeatureModelLayer::getMinLevel() const
{
- auto fmg = osgEarth::findTopMostNodeOfType(_root.get());
- return fmg ? fmg->getMinLevel() : 0u;
+ return getFeatureSource()->getFeatureProfile()->getFirstLevel();
}
unsigned
TiledFeatureModelLayer::getMaxLevel() const
{
- auto fmg = osgEarth::findTopMostNodeOfType(_root.get());
- return fmg ? fmg->getMaxLevel() : 99u;
+ return getFeatureSource()->getFeatureProfile()->getMaxLevel();
}
diff --git a/src/osgEarth/TiledModelLayer b/src/osgEarth/TiledModelLayer
index 4750ee0ca4..66a6ca5336 100644
--- a/src/osgEarth/TiledModelLayer
+++ b/src/osgEarth/TiledModelLayer
@@ -37,6 +37,8 @@ namespace osgEarth
struct OSGEARTH_EXPORT Options : public VisibleLayer::Options
{
META_LayerOptions(osgEarth, Options, VisibleLayer::Options);
+ OE_OPTION(bool, additive);
+ OE_OPTION(float, rangeFactor);
virtual Config getConfig() const;
void fromConfig(const Config& conf);
};
@@ -58,10 +60,41 @@ namespace osgEarth
//! Maximum available LOD of the underlying tiled data source.
virtual unsigned getMaxLevel() const = 0;
+ //! Whether new LODs should be added to the scene (true) or replace existing ones (false)
+ void setAdditive(const bool& value);
+ const bool& getAdditive() const;
+
+ //! The range factor. Default is 6
+ void setRangeFactor(const float &value);
+ const float& getRangeFactor() const;
+
+ //! Forces a rebuild on this layer.
+ void dirty();
+
+ public: // Layer
+
+ // The Node representing this layer.
+ osg::Node* getNode() const override;
+
+ // called by the map when this layer is added
+ void addedToMap(const Map*) override;
+
+ // called by the map when this layer is removed
+ void removedFromMap(const Map*) override;
+
+ // post-ctor initialization
+ void init() override;
+
protected:
//! Subclasses must implement this to create a tile.
//! @param key The tile key, in the underlying tiled data source's profile.
//! @param progress A progress callback that can be checked for user cancellation.
virtual osg::ref_ptr createTileImplementation(const TileKey& key, ProgressCallback* progress) const = 0;
+
+ private:
+ osg::observer_ptr< const Map > _map;
+ osg::ref_ptr< osg::Group > _root;
+ bool _graphDirty;
+ void create();
};
}
diff --git a/src/osgEarth/TiledModelLayer.cpp b/src/osgEarth/TiledModelLayer.cpp
index 4a791c994a..4904ffd844 100644
--- a/src/osgEarth/TiledModelLayer.cpp
+++ b/src/osgEarth/TiledModelLayer.cpp
@@ -17,27 +17,49 @@
* along with this program. If not, see
*/
#include "TiledModelLayer"
+#include
+#include
using namespace osgEarth;
-void TiledModelLayer::Options::fromConfig(const Config& conf)
+
+class TiledModelLayerPager : public SimplePager
{
- //minLevel().setDefault(0u);
- //maxLevel().setDefault(99u);
+public:
+ TiledModelLayerPager(const Map* map, TiledModelLayer* layer):
+ SimplePager(map, layer->getProfile()),
+ _layer(layer)
+ {
+ }
- //conf.get("min_level", minLevel());
- //conf.get("max_level", maxLevel());
+ virtual osg::ref_ptr createNode(const TileKey& key, ProgressCallback* progress) override
+ {
+ return _layer->createTile(key, progress);
+ }
+
+ osg::observer_ptr< TiledModelLayer > _layer;
+};
+
+void TiledModelLayer::Options::fromConfig(const Config& conf)
+{
+ additive().setDefault(false);
+ rangeFactor().setDefault(6.0);
+ conf.get("additive", additive());
+ conf.get("range_factor", rangeFactor());
}
Config
TiledModelLayer::Options::getConfig() const
{
Config conf = VisibleLayer::Options::getConfig();
- //conf.set("min_level", minLevel());
- //conf.set("max_level", maxLevel());
+ conf.set("additive", additive());
+ conf.set("range_factor", rangeFactor());
return conf;
}
+OE_LAYER_PROPERTY_IMPL(TiledModelLayer, bool, Additive, additive);
+OE_LAYER_PROPERTY_IMPL(TiledModelLayer, float, RangeFactor, rangeFactor);
+
osg::ref_ptr
TiledModelLayer::createTile(const TileKey& key, ProgressCallback* progress) const
{
@@ -77,3 +99,82 @@ TiledModelLayer::createTile(const TileKey& key, ProgressCallback* progress) cons
return group;
}
}
+
+// The Node representing this layer.
+osg::Node* TiledModelLayer::getNode() const
+{
+ return _root.get();
+}
+
+// called by the map when this layer is added
+void
+TiledModelLayer::addedToMap(const Map* map)
+{
+ super::addedToMap(map);
+
+ _map = map;
+
+ _graphDirty = true;
+
+ // re-create the graph if necessary.
+ create();
+}
+
+// called by the map when this layer is removed
+void
+TiledModelLayer::removedFromMap(const Map* map)
+{
+ super::removedFromMap(map);
+
+ if (_root.valid())
+ {
+ osg::ref_ptr node = findTopMostNodeOfType(_root.get());
+ if (node.valid()) node->setDone();
+ _root->removeChildren(0, _root->getNumChildren());
+ }
+}
+
+void TiledModelLayer::dirty()
+{
+ _graphDirty = true;
+
+ // create the scene graph
+ create();
+}
+
+// post-ctor initialization
+void TiledModelLayer::init()
+{
+ super::init();
+
+ // Create the container group
+
+ _root = new osg::Group();
+
+ // Assign the layer's state set to the root node:
+ _root->setStateSet(this->getOrCreateStateSet());
+
+ // Graph needs rebuilding
+ _graphDirty = true;
+
+ // Depth sorting by default
+ getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+}
+
+void TiledModelLayer::create()
+{
+ if (_map.valid() && _graphDirty)
+ {
+ _root->removeChildren(0, _root->getNumChildren());
+
+ TiledModelLayerPager* pager = new TiledModelLayerPager(_map.get(), this);
+ pager->setAdditive(this->getAdditive());
+ pager->setRangeFactor(this->getRangeFactor());
+ pager->setMinLevel(this->getMinLevel());
+ pager->setMaxLevel(this->getMaxLevel());
+ pager->build();
+ // TODO: NVGL
+ _root->addChild(pager);
+ _graphDirty = false;
+ }
+}
\ No newline at end of file
diff --git a/src/osgEarth/XYZModelGraph b/src/osgEarth/XYZModelGraph
deleted file mode 100644
index a024ea51d8..0000000000
--- a/src/osgEarth/XYZModelGraph
+++ /dev/null
@@ -1,63 +0,0 @@
-/* --*-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
- */
-
-#ifndef OSGEARTH_XYZ_MODEL_GRAPH_H
-#define OSGEARTH_XYZ_MODEL_GRAPH_H 1
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-namespace osgEarth {
-
- /**
- * A scene graph node that loads pre-tiled quadtree model data.
- */
- class OSGEARTH_EXPORT XYZModelGraph : public SimplePager
- {
- public:
- XYZModelGraph(const osgEarth::Map* map, const Profile* profile, const URI& url, bool invertY, const osgDB::Options* options);
-
- void setOwnerName(const std::string& value);
-
- //! Whether to attempt to use NVGL extensions
- void setUseNVGL(bool value);
-
- public: // SimplePager
-
- virtual osg::ref_ptr createNode(const TileKey& key, ProgressCallback* progress) override;
-
- private:
- std::string _ownerName;
- URI _url;
- bool _invertY;
- osg::ref_ptr< osgEarth::StateSetCache > _statesetCache;
- osg::ref_ptr< osgDB::Options > _options;
- osg::ref_ptr< TextureArena > _textures;
- mutable std::vector _texturesCache;
- mutable std::mutex _texturesCacheMutex;
- };
-}
-
-#endif // OSGEARTH_XYZ_MODEL_GRAPH_H
diff --git a/src/osgEarth/XYZModelGraph.cpp b/src/osgEarth/XYZModelGraph.cpp
deleted file mode 100644
index 2563310146..0000000000
--- a/src/osgEarth/XYZModelGraph.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/* -*-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
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-using namespace osgEarth;
-
-XYZModelGraph::XYZModelGraph(const osgEarth::Map* map, const Profile* profile, const URI& url, bool invertY, const osgDB::Options* options) :
- SimplePager(map, profile),
- _url(url),
- _invertY(invertY)
-{
- _options = osgEarth::Registry::instance()->cloneOrCreateOptions(options);
- _options->setObjectCacheHint(osgDB::Options::CACHE_IMAGES);
-
- _statesetCache = new StateSetCache();
-}
-
-void
-XYZModelGraph::setUseNVGL(bool value)
-{
- if (value == true && GLUtils::useNVGL() && !_textures.valid())
- {
- _textures = new TextureArena();
- getOrCreateStateSet()->setAttribute(_textures, 1);
-
- // auto release requires that we install this update callback!
- _textures->setAutoRelease(true);
-
- addUpdateCallback(new LambdaCallback<>([this](osg::NodeVisitor& nv)
- {
- _textures->update(nv);
- return true;
- }));
-
- getOrCreateStateSet()->setAttributeAndModes(
- new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA),
- osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
- }
-}
-
-void
-XYZModelGraph::setOwnerName(const std::string& value)
-{
- _ownerName = value;
-}
-
-osg::ref_ptr
-XYZModelGraph::createNode(const TileKey& key, ProgressCallback* progress)
-{
- OE_PROFILING_ZONE;
- if (progress && progress->isCanceled())
- return nullptr;
-
- NetworkMonitor::ScopedRequestLayer layerRequest(_ownerName);
-
- unsigned x, y;
- key.getTileXY(x, y);
- unsigned cols = 0, rows = 0;
- key.getProfile()->getNumTiles(key.getLevelOfDetail(), cols, rows);
- unsigned inverted_y = rows - y - 1;
-
- if (_invertY == true)
- {
- y = inverted_y;
- }
-
- std::string location = _url.full();
-
- // support OpenLayers template style:
- replaceIn(location, "${x}", Stringify() << x);
- replaceIn(location, "${y}", Stringify() << y);
- replaceIn(location, "${-y}", Stringify() << inverted_y);
- replaceIn(location, "${z}", Stringify() << key.getLevelOfDetail());
-
-
- // failing that, legacy osgearth style:
- replaceIn(location, "{x}", Stringify() << x);
- replaceIn(location, "{y}", Stringify() << y);
- replaceIn(location, "{-y}", Stringify() << inverted_y);
- replaceIn(location, "{z}", Stringify() << key.getLevelOfDetail());
-
- URI myUri(location, _url.context());
-
- osg::ref_ptr< osg::Node > node = myUri.readNode(_options.get()).getNode();
- if (node.valid())
- {
- if (_textures.valid())
- {
- auto xform = findTopMostNodeOfType(node.get());
-
- // Convert the geometry into chonks
- ChonkFactory factory(_textures);
-
- factory.setGetOrCreateFunction(
- ChonkFactory::getWeakTextureCacheFunction(
- _texturesCache, _texturesCacheMutex));
-
- osg::ref_ptr drawable = new ChonkDrawable();
-
- if (xform)
- {
- for (unsigned i = 0; i < xform->getNumChildren(); ++i)
- {
- drawable->add(xform->getChild(i), factory);
- }
- xform->removeChildren(0, xform->getNumChildren());
- xform->addChild(drawable);
- node = xform;
- }
- else
- {
- if (drawable->add(node.get(), factory))
- {
- node = drawable;
- }
- }
- }
- else
- {
- osgEarth::Registry::shaderGenerator().run(node.get(), _statesetCache);
- }
- return node.release();
- }
- return nullptr;
-}
\ No newline at end of file
diff --git a/src/osgEarth/XYZModelLayer b/src/osgEarth/XYZModelLayer
index 6aec9842bc..4714e167f2 100644
--- a/src/osgEarth/XYZModelLayer
+++ b/src/osgEarth/XYZModelLayer
@@ -23,28 +23,30 @@
#include
#include
#include
+#include
+#include
+
namespace osgEarth {
class Map;
}
namespace osgEarth
-{
+{
/**
* Layer that loads a pregenerated quadtree of model files
*/
class OSGEARTH_EXPORT XYZModelLayer : public TiledModelLayer
{
public: // serialization
- struct OSGEARTH_EXPORT Options : public TiledModelLayer::Options
+ struct OSGEARTH_EXPORT Options : public TiledModelLayer::Options
{
META_LayerOptions(osgEarth, Options, TiledModelLayer::Options);
OE_OPTION(URI, url);
- OE_OPTION(bool, additive);
OE_OPTION(bool, invertY);
OE_OPTION(int, minLevel);
OE_OPTION(int, maxLevel);
- OE_OPTION(float, rangeFactor);
+
OE_OPTION(ProfileOptions, profile);
Config getConfig() const override;
void fromConfig(const Config& conf);
@@ -78,36 +80,17 @@ namespace osgEarth
void setMaxLevel(unsigned value);
unsigned getMaxLevel() const override;
- //! The range factor. Default is 6
- void setRangeFactor(float value);
- float getRangeFactor() const;
-
- //! Forces a rebuild on this layer.
- void dirty();
-
public: // Layer
//! opens the layer and returns the status
Status openImplementation() override;
- //! closes the layer
- Status closeImplementation() override;
-
- //! The Node representing this layer.
- osg::Node* getNode() const override;
+ void addedToMap(const Map* map) override;
//! Serialization
Config getConfig() const override;
- public: // Layer
-
- //! called by the map when this layer is added
- void addedToMap(const Map*) override;
-
- //! called by the map when this layer is removed
- void removedFromMap(const Map*) override;
-
- //! post-ctor initialization
+ // post-ctor initialization
void init() override;
protected: // TiledModelLayer
@@ -120,12 +103,13 @@ namespace osgEarth
virtual ~XYZModelLayer();
private:
- osg::ref_ptr _root;
osg::ref_ptr _profile;
- osg::observer_ptr< const Map > _map;
- bool _graphDirty;
-
- void create();
+
+ osg::ref_ptr< osgEarth::StateSetCache > _statesetCache;
+ osg::ref_ptr< osgDB::Options > _readOptions;
+ osg::ref_ptr< TextureArena > _textures;
+ mutable std::vector _texturesCache;
+ mutable std::mutex _texturesCacheMutex;
};
} // namespace osgEarth
diff --git a/src/osgEarth/XYZModelLayer.cpp b/src/osgEarth/XYZModelLayer.cpp
index e4e7e3b13f..fdcd6a6678 100644
--- a/src/osgEarth/XYZModelLayer.cpp
+++ b/src/osgEarth/XYZModelLayer.cpp
@@ -17,8 +17,14 @@
* along with this program. If not, see
*/
#include
-#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
using namespace osgEarth;
@@ -32,15 +38,10 @@ REGISTER_OSGEARTH_LAYER(XYZModel, XYZModelLayer);
void XYZModelLayer::Options::fromConfig(const Config& conf)
{
- invertY().setDefault(false);
- additive().setDefault(false);
- rangeFactor().setDefault(6.0);
-
- conf.get("additive", additive());
+ invertY().setDefault(false);
conf.get("url", url());
conf.get("min_level", minLevel());
- conf.get("max_level", maxLevel());
- conf.get("range_factor", rangeFactor());
+ conf.get("max_level", maxLevel());
conf.get("profile", profile());
}
@@ -48,12 +49,10 @@ Config
XYZModelLayer::Options::getConfig() const
{
Config conf = TiledModelLayer::Options::getConfig();
- conf.set("additive", additive());
conf.set("url", url());
conf.set("min_level", minLevel());
conf.set("max_level", maxLevel());
conf.set("profile", profile());
- conf.set("range_factor", rangeFactor());
return conf;
}
@@ -61,7 +60,6 @@ XYZModelLayer::Options::getConfig() const
//...........................................................................
OE_LAYER_PROPERTY_IMPL(XYZModelLayer, URI, URL, url);
-OE_LAYER_PROPERTY_IMPL(XYZModelLayer, bool, Additive, additive);
void
XYZModelLayer::setMinLevel(unsigned value) {
@@ -83,18 +81,39 @@ XYZModelLayer::getMaxLevel() const {
return options().maxLevel().get();
}
-void
-XYZModelLayer::setRangeFactor(float value)
+void XYZModelLayer::init()
{
- options().rangeFactor() = value;
+ super::init();
}
-float
-XYZModelLayer::getRangeFactor() const
+void XYZModelLayer::addedToMap(const Map* map)
{
- return options().rangeFactor().get();
-}
+ _readOptions = osgEarth::Registry::instance()->cloneOrCreateOptions(getReadOptions());
+ _readOptions->setObjectCacheHint(osgDB::Options::CACHE_IMAGES);
+
+ _statesetCache = new StateSetCache();
+
+ if (*options().useNVGL() == true && GLUtils::useNVGL() && !_textures.valid())
+ {
+ _textures = new TextureArena();
+ getOrCreateStateSet()->setAttribute(_textures, 1);
+
+ // auto release requires that we install this update callback!
+ _textures->setAutoRelease(true);
+ getNode()->addUpdateCallback(new LambdaCallback<>([this](osg::NodeVisitor& nv)
+ {
+ _textures->update(nv);
+ return true;
+ }));
+
+ getOrCreateStateSet()->setAttributeAndModes(
+ new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA),
+ osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
+ }
+
+ super::addedToMap(map);
+}
XYZModelLayer::~XYZModelLayer()
{
@@ -110,31 +129,6 @@ void XYZModelLayer::setProfile(const Profile* profile)
}
}
-void
-XYZModelLayer::init()
-{
- super::init();
-
- _root = new osg::Group();
-
- // Assign the layer's state set to the root node:
- _root->setStateSet(this->getOrCreateStateSet());
-
- // Graph needs rebuilding
- _graphDirty = true;
-
- // Depth sorting by default
- getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
-}
-
-void XYZModelLayer::dirty()
-{
- _graphDirty = true;
-
- // create the scene graph
- create();
-}
-
Config
XYZModelLayer::getConfig() const
{
@@ -142,12 +136,6 @@ XYZModelLayer::getConfig() const
return conf;
}
-osg::Node*
-XYZModelLayer::getNode() const
-{
- return _root.get();
-}
-
Status
XYZModelLayer::openImplementation()
{
@@ -160,73 +148,82 @@ XYZModelLayer::openImplementation()
return Status::NoError;
}
-Status
-XYZModelLayer::closeImplementation()
+osg::ref_ptr
+XYZModelLayer::createTileImplementation(const TileKey& key, ProgressCallback* progress) const
{
- _graphDirty = true;
- return getStatus();
-}
+ OE_PROFILING_ZONE;
+ if (progress && progress->isCanceled())
+ return nullptr;
-void
-XYZModelLayer::addedToMap(const Map* map)
-{
- OE_TEST << LC << "addedToMap" << std::endl;
- super::addedToMap(map);
+ NetworkMonitor::ScopedRequestLayer layerRequest(getName());
- _map = map;
+ unsigned x, y;
+ key.getTileXY(x, y);
+ unsigned cols = 0, rows = 0;
+ key.getProfile()->getNumTiles(key.getLevelOfDetail(), cols, rows);
+ unsigned inverted_y = rows - y - 1;
- _graphDirty = true;
+ if (*options().invertY() == true)
+ {
+ y = inverted_y;
+ }
- // re-create the graph if necessary.
- create();
-}
+ std::string location = options().url()->full();
-void
-XYZModelLayer::removedFromMap(const Map* map)
-{
- super::removedFromMap(map);
+ // support OpenLayers template style:
+ replaceIn(location, "${x}", Stringify() << x);
+ replaceIn(location, "${y}", Stringify() << y);
+ replaceIn(location, "${-y}", Stringify() << inverted_y);
+ replaceIn(location, "${z}", Stringify() << key.getLevelOfDetail());
- if (_root.valid())
- {
- osg::ref_ptr node = findTopMostNodeOfType(_root.get());
- if (node.valid()) node->setDone();
- _root->removeChildren(0, _root->getNumChildren());
- }
-}
-void
-XYZModelLayer::create()
-{
- OE_TEST << LC << "create" << std::endl;
-
- if (_graphDirty && _profile)
- {
- osg::ref_ptr xyzGraph = new XYZModelGraph(_map.get(), _profile.get(), *_options->url(), *_options->invertY(), getReadOptions());
- xyzGraph->setOwnerName(getName());
- xyzGraph->setAdditive(*_options->additive());
- xyzGraph->setMinLevel(*_options->minLevel());
- xyzGraph->setMaxLevel(*_options->maxLevel());
- xyzGraph->setRangeFactor(*_options->rangeFactor());
- xyzGraph->setSceneGraphCallbacks(getSceneGraphCallbacks());
- xyzGraph->setUseNVGL(options().useNVGL().get());
- xyzGraph->build();
-
- _root->removeChildren(0, _root->getNumChildren());
- _root->addChild(xyzGraph.get());
-
- // clear the dirty flag.
- _graphDirty = false;
-
- setStatus(Status::OK());
- }
-}
+ // failing that, legacy osgearth style:
+ replaceIn(location, "{x}", Stringify() << x);
+ replaceIn(location, "{y}", Stringify() << y);
+ replaceIn(location, "{-y}", Stringify() << inverted_y);
+ replaceIn(location, "{z}", Stringify() << key.getLevelOfDetail());
-osg::ref_ptr
-XYZModelLayer::createTileImplementation(const TileKey& key, ProgressCallback* progress) const
-{
- auto pager = osgEarth::findTopMostNodeOfType(_root.get());
- if (pager)
- return pager->createNode(key, progress);
- else
- return {};
+ URI myUri(location, options().url()->context());
+
+ osg::ref_ptr< osg::Node > node = myUri.readNode(_readOptions.get()).getNode();
+ if (node.valid())
+ {
+ if (_textures.valid())
+ {
+ auto xform = findTopMostNodeOfType(node.get());
+
+ // Convert the geometry into chonks
+ ChonkFactory factory(_textures);
+
+ factory.setGetOrCreateFunction(
+ ChonkFactory::getWeakTextureCacheFunction(
+ _texturesCache, _texturesCacheMutex));
+
+ osg::ref_ptr drawable = new ChonkDrawable();
+
+ if (xform)
+ {
+ for (unsigned i = 0; i < xform->getNumChildren(); ++i)
+ {
+ drawable->add(xform->getChild(i), factory);
+ }
+ xform->removeChildren(0, xform->getNumChildren());
+ xform->addChild(drawable);
+ node = xform;
+ }
+ else
+ {
+ if (drawable->add(node.get(), factory))
+ {
+ node = drawable;
+ }
+ }
+ }
+ else
+ {
+ osgEarth::Registry::shaderGenerator().run(node.get(), _statesetCache);
+ }
+ return node.release();
+ }
+ return nullptr;
}
diff --git a/src/osgEarthCesium/TaskProcessor.cpp b/src/osgEarthCesium/TaskProcessor.cpp
index 30f92120ce..7b9d5826de 100644
--- a/src/osgEarthCesium/TaskProcessor.cpp
+++ b/src/osgEarthCesium/TaskProcessor.cpp
@@ -21,6 +21,7 @@
*/
#include "TaskProcessor"
#include
+#include
using namespace osgEarth;
using namespace osgEarth::Threading;
@@ -51,7 +52,7 @@ void TaskProcessor::shutdown()
void TaskProcessor::startTask(std::function f)
{
- auto task = [this, f](Cancelable&) {
+ auto task = [this, f]() {
f();
return true;
};