summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/sources/render_geojson_source.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer/sources/render_geojson_source.cpp')
-rw-r--r--src/mbgl/renderer/sources/render_geojson_source.cpp86
1 files changed, 86 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();
}