[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.
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user