diff options
-rw-r--r-- | include/mbgl/renderer/renderer.hpp | 9 | ||||
-rw-r--r-- | include/mbgl/util/geojson.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/render_source.hpp | 9 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.cpp | 11 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.hpp | 6 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_geojson_source.cpp | 86 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_geojson_source.hpp | 7 |
8 files changed, 137 insertions, 1 deletions
diff --git a/include/mbgl/renderer/renderer.hpp b/include/mbgl/renderer/renderer.hpp index 798928087a..644dd0fcf9 100644 --- a/include/mbgl/renderer/renderer.hpp +++ b/include/mbgl/renderer/renderer.hpp @@ -4,7 +4,7 @@ #include <mbgl/renderer/mode.hpp> #include <mbgl/annotation/annotation.hpp> #include <mbgl/util/geo.hpp> -#include <mbgl/util/geo.hpp> +#include <mbgl/util/geojson.hpp> #include <functional> #include <memory> @@ -44,6 +44,13 @@ public: AnnotationIDs queryShapeAnnotations(const ScreenBox& box) const; AnnotationIDs getAnnotationIDs(const std::vector<Feature>&) const; + // Feature extension query + FeatureExtensionValue queryFeatureExtensions(const std::string& sourceID, + const Feature& feature, + const std::string& extension, + const std::string& extensionField, + const optional<std::map<std::string, Value>>& args = {}) const; + // Debug void dumpDebugLogs(); diff --git a/include/mbgl/util/geojson.hpp b/include/mbgl/util/geojson.hpp index b4e789a3ac..2a6569be49 100644 --- a/include/mbgl/util/geojson.hpp +++ b/include/mbgl/util/geojson.hpp @@ -1,10 +1,12 @@ #pragma once #include <mapbox/geojson.hpp> +#include <mbgl/util/feature.hpp> namespace mbgl { using GeoJSON = mapbox::geojson::geojson; using FeatureCollection = mapbox::geojson::feature_collection; +using FeatureExtensionValue = mapbox::util::variant<Value, FeatureCollection>; } // namespace mbgl diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp index dc80cb1dc6..31c26fd09a 100644 --- a/src/mbgl/renderer/render_source.hpp +++ b/src/mbgl/renderer/render_source.hpp @@ -4,6 +4,7 @@ #include <mbgl/tile/tile_observer.hpp> #include <mbgl/util/mat4.hpp> #include <mbgl/util/geo.hpp> +#include <mbgl/util/geojson.hpp> #include <mbgl/util/feature.hpp> #include <mbgl/style/source_impl.hpp> #include <mbgl/style/layer_impl.hpp> @@ -70,6 +71,14 @@ public: virtual std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const = 0; + virtual FeatureExtensionValue + queryFeatureExtensions(const Feature&, + const std::string&, + const std::string&, + const optional<std::map<std::string, Value>>&) const { + return {}; + } + virtual void reduceMemoryUse() = 0; virtual void dumpDebugLogs() const = 0; diff --git a/src/mbgl/renderer/renderer.cpp b/src/mbgl/renderer/renderer.cpp index 6b73e568fc..5a92a675c5 100644 --- a/src/mbgl/renderer/renderer.cpp +++ b/src/mbgl/renderer/renderer.cpp @@ -100,6 +100,14 @@ std::vector<Feature> Renderer::querySourceFeatures(const std::string& sourceID, return impl->querySourceFeatures(sourceID, options); } +FeatureExtensionValue Renderer::queryFeatureExtensions(const std::string& sourceID, + const Feature& feature, + const std::string& extension, + const std::string& extensionField, + const optional<std::map<std::string, Value>>& args) const { + return impl->queryFeatureExtensions(sourceID, feature, extension, extensionField, args); +} + void Renderer::dumpDebugLogs() { impl->dumDebugLogs(); } diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index c844d1f87c..9058b0d62b 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -722,6 +722,17 @@ std::vector<Feature> Renderer::Impl::querySourceFeatures(const std::string& sour return source->querySourceFeatures(options); } +FeatureExtensionValue Renderer::Impl::queryFeatureExtensions(const std::string& sourceID, + const Feature& feature, + const std::string& extension, + const std::string& extensionField, + const optional<std::map<std::string, Value>>& args) const { + if (RenderSource* renderSource = getRenderSource(sourceID)) { + return renderSource->queryFeatureExtensions(feature, extension, extensionField, args); + } + return {}; +} + void Renderer::Impl::reduceMemoryUse() { assert(BackendScope::exists()); for (const auto& entry : renderSources) { diff --git a/src/mbgl/renderer/renderer_impl.hpp b/src/mbgl/renderer/renderer_impl.hpp index 4124f6f416..4555ba27d5 100644 --- a/src/mbgl/renderer/renderer_impl.hpp +++ b/src/mbgl/renderer/renderer_impl.hpp @@ -53,6 +53,12 @@ public: std::vector<Feature> querySourceFeatures(const std::string& sourceID, const SourceQueryOptions&) const; std::vector<Feature> queryShapeAnnotations(const ScreenLineString&) const; + FeatureExtensionValue queryFeatureExtensions(const std::string& sourceID, + const Feature& feature, + const std::string& extension, + const std::string& extensionField, + const optional<std::map<std::string, Value>>& args) const; + void reduceMemoryUse(); void dumDebugLogs(); diff --git a/src/mbgl/renderer/sources/render_geojson_source.cpp b/src/mbgl/renderer/sources/render_geojson_source.cpp index 0099ebcf5e..a688026788 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.cpp +++ b/src/mbgl/renderer/sources/render_geojson_source.cpp @@ -7,15 +7,74 @@ #include <mbgl/algorithm/generate_clip_ids.hpp> #include <mbgl/algorithm/generate_clip_ids_impl.hpp> +#include <mapbox/eternal.hpp> + namespace mbgl { using namespace style; +namespace { + +template<typename T, typename C> +optional<T> getProperty(const C& cont, const typename C::key_type& name) { + const auto it = cont.find(name); + if (it == cont.end() || !(it->second.template is<T>())) { + return nullopt; + } + return it->second.template get<T>(); +} + +using FeatureExtensionGetterPtr = FeatureExtensionValue (*)(std::shared_ptr<style::GeoJSONData>, + std::uint32_t, + const optional<std::map<std::string, Value>>&); + +FeatureExtensionValue getChildren(std::shared_ptr<style::GeoJSONData> clusterData, + std::uint32_t clusterID, + const optional<std::map<std::string, Value>>&) { + return clusterData->getChildren(clusterID); +} + +FeatureExtensionValue getLeaves(std::shared_ptr<style::GeoJSONData> clusterData, + std::uint32_t clusterID, + const optional<std::map<std::string, Value>>& args) { + if (args) { + const auto limit = getProperty<uint64_t>(*args, "limit"); + const auto offset = getProperty<uint64_t>(*args, "offset"); + // Offset cannot be set without limit. + if (limit) { + if (offset) { + return clusterData->getLeaves(clusterID, + static_cast<std::uint32_t>(*limit), + static_cast<std::uint32_t>(*offset)); + } + return clusterData->getLeaves(clusterID, static_cast<std::uint32_t>(*limit)); + } + } + + return clusterData->getLeaves(clusterID); +} + +FeatureExtensionValue getClusterExpansionZoom(std::shared_ptr<style::GeoJSONData> clusterData, + std::uint32_t clusterID, + const optional<std::map<std::string, Value>>&) { + return Value{static_cast<uint64_t>(clusterData->getClusterExpansionZoom(clusterID))}; +} + +MAPBOX_ETERNAL_CONSTEXPR const auto extensionGetters = mapbox::eternal::hash_map<mapbox::eternal::string, FeatureExtensionGetterPtr>({ + {"children", &getChildren}, + {"leaves", &getLeaves}, + {"expansion-zoom", &getClusterExpansionZoom} +}); + +} + RenderGeoJSONSource::RenderGeoJSONSource(Immutable<style::GeoJSONSource::Impl> impl_) : RenderSource(impl_) { tilePyramid.setObserver(this); } +RenderGeoJSONSource::~RenderGeoJSONSource() = default; + const style::GeoJSONSource::Impl& RenderGeoJSONSource::impl() const { return static_cast<const style::GeoJSONSource::Impl&>(*baseImpl); } @@ -94,6 +153,33 @@ std::vector<Feature> RenderGeoJSONSource::querySourceFeatures(const SourceQueryO return tilePyramid.querySourceFeatures(options); } +mapbox::util::variant<Value, FeatureCollection> +RenderGeoJSONSource::queryFeatureExtensions(const Feature& feature, + const std::string& extension, + const std::string& extensionField, + const optional<std::map<std::string, Value>>& args) const { + if (extension != "supercluster") { + return {}; + } + + const auto extensionIt = extensionGetters.find(extensionField.c_str()); + if (extensionIt == extensionGetters.end()) { + return {}; + } + + const auto clusterID = getProperty<uint64_t>(feature.properties, "cluster_id"); + if (!clusterID) { + return {}; + } + + auto jsonData = data.lock(); + if (!jsonData) { + return {}; + } + + return extensionIt->second(std::move(jsonData), static_cast<std::uint32_t>(*clusterID), args); +} + void RenderGeoJSONSource::reduceMemoryUse() { tilePyramid.reduceMemoryUse(); } diff --git a/src/mbgl/renderer/sources/render_geojson_source.hpp b/src/mbgl/renderer/sources/render_geojson_source.hpp index 6351c5f6f8..c23559c09a 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.hpp +++ b/src/mbgl/renderer/sources/render_geojson_source.hpp @@ -13,6 +13,7 @@ class GeoJSONData; class RenderGeoJSONSource : public RenderSource { public: RenderGeoJSONSource(Immutable<style::GeoJSONSource::Impl>); + ~RenderGeoJSONSource() final; bool isLoaded() const final; @@ -37,6 +38,12 @@ public: std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const final; + FeatureExtensionValue + queryFeatureExtensions(const Feature& feature, + const std::string& extension, + const std::string& extensionField, + const optional<std::map<std::string, Value>>& args) const final; + void reduceMemoryUse() final; void dumpDebugLogs() const final; |