summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2018-11-14 16:30:10 +0200
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2018-12-12 15:08:18 +0200
commita1ca06e304a14582a90b258e817ec6f17d72fb11 (patch)
tree43d8d6a499388aa17bd1e182bbaa072cd4e77693
parent664ceb43980cb7d90a0d8b5fa1a48f83662322c9 (diff)
downloadqtlocation-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.
-rw-r--r--include/mbgl/renderer/renderer.hpp9
-rw-r--r--include/mbgl/util/geojson.hpp2
-rw-r--r--src/mbgl/renderer/render_source.hpp9
-rw-r--r--src/mbgl/renderer/renderer.cpp8
-rw-r--r--src/mbgl/renderer/renderer_impl.cpp11
-rw-r--r--src/mbgl/renderer/renderer_impl.hpp6
-rw-r--r--src/mbgl/renderer/sources/render_geojson_source.cpp86
-rw-r--r--src/mbgl/renderer/sources/render_geojson_source.hpp7
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;