diff options
author | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2018-11-14 16:30:10 +0200 |
---|---|---|
committer | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2018-12-12 15:08:18 +0200 |
commit | a1ca06e304a14582a90b258e817ec6f17d72fb11 (patch) | |
tree | 43d8d6a499388aa17bd1e182bbaa072cd4e77693 /src/mbgl/renderer/sources | |
parent | 664ceb43980cb7d90a0d8b5fa1a48f83662322c9 (diff) | |
download | qtlocation-mapboxgl-a1ca06e304a14582a90b258e817ec6f17d72fb11.tar.gz |
[core] Introduce Renderer::queryFeatureExtension API
New interface allows it's users to query additional information about
feature that was provided by qRF interface. This is particularly
useful for clustered features.
Diffstat (limited to 'src/mbgl/renderer/sources')
-rw-r--r-- | src/mbgl/renderer/sources/render_geojson_source.cpp | 86 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_geojson_source.hpp | 7 |
2 files changed, 93 insertions, 0 deletions
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; |