diff options
Diffstat (limited to 'src/mbgl/renderer/sources/render_geojson_source.cpp')
-rw-r--r-- | src/mbgl/renderer/sources/render_geojson_source.cpp | 86 |
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(); } |