summaryrefslogtreecommitdiff
path: root/src/mbgl/style/sources/geojson_source_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style/sources/geojson_source_impl.cpp')
-rw-r--r--src/mbgl/style/sources/geojson_source_impl.cpp69
1 files changed, 50 insertions, 19 deletions
diff --git a/src/mbgl/style/sources/geojson_source_impl.cpp b/src/mbgl/style/sources/geojson_source_impl.cpp
index 24ac1d7976..c3cb942709 100644
--- a/src/mbgl/style/sources/geojson_source_impl.cpp
+++ b/src/mbgl/style/sources/geojson_source_impl.cpp
@@ -1,6 +1,7 @@
#include <mbgl/style/sources/geojson_source_impl.hpp>
-#include <mbgl/util/constants.hpp>
#include <mbgl/tile/tile_id.hpp>
+#include <mbgl/util/constants.hpp>
+#include <mbgl/util/feature.hpp>
#include <mbgl/util/string.hpp>
#include <mapbox/geojsonvt.hpp>
@@ -13,9 +14,9 @@ namespace style {
class GeoJSONVTData : public GeoJSONData {
public:
- GeoJSONVTData(const GeoJSON& geoJSON,
- const mapbox::geojsonvt::Options& options)
- : impl(geoJSON, options) {}
+ GeoJSONVTData(const GeoJSON& geoJSON, const mapbox::geojsonvt::Options& options)
+ : impl(geoJSON, options) {
+ }
mapbox::feature::feature_collection<int16_t> getTile(const CanonicalTileID& tileID) final {
return impl.getTile(tileID.z, tileID.x, tileID.y).features;
@@ -25,9 +26,8 @@ public:
return {};
}
- mapbox::feature::feature_collection<double> getLeaves(const std::uint32_t,
- const std::uint32_t,
- const std::uint32_t) final {
+ mapbox::feature::feature_collection<double>
+ getLeaves(const std::uint32_t, const std::uint32_t, const std::uint32_t) final {
return {};
}
@@ -43,7 +43,8 @@ class SuperclusterData : public GeoJSONData {
public:
SuperclusterData(const mapbox::feature::feature_collection<double>& features,
const mapbox::supercluster::Options& options)
- : impl(features, options) {}
+ : impl(features, options) {
+ }
mapbox::feature::feature_collection<int16_t> getTile(const CanonicalTileID& tileID) final {
return impl.getTile(tileID.z, tileID.x, tileID.y);
@@ -54,8 +55,8 @@ public:
}
mapbox::feature::feature_collection<double> getLeaves(const std::uint32_t cluster_id,
- const std::uint32_t limit,
- const std::uint32_t offset) final {
+ const std::uint32_t limit,
+ const std::uint32_t offset) final {
return impl.getLeaves(cluster_id, limit, offset);
}
@@ -67,23 +68,53 @@ private:
mapbox::supercluster::Supercluster impl;
};
-GeoJSONSource::Impl::Impl(std::string id_, GeoJSONOptions options_)
- : Source::Impl(SourceType::GeoJSON, std::move(id_)),
- options(std::move(options_)) {
+template <class T>
+T evaluateFeature(const mapbox::feature::feature<double>& f,
+ const std::shared_ptr<expression::Expression>& expression,
+ optional<T> accumulated = nullopt) {
+ const expression::EvaluationResult result = expression->evaluate(accumulated, f);
+ if (result) {
+ optional<T> typed = expression::fromExpressionValue<T>(*result);
+ if (typed) {
+ return std::move(*typed);
+ }
+ }
+ return T();
+}
+
+GeoJSONSource::Impl::Impl(std::string id_, optional<GeoJSONOptions> options_)
+ : Source::Impl(SourceType::GeoJSON, std::move(id_)) {
+ options = options_ ? std::move(*options_) : GeoJSONOptions{};
}
GeoJSONSource::Impl::Impl(const Impl& other, const GeoJSON& geoJSON)
- : Source::Impl(other),
- options(other.options) {
+ : Source::Impl(other), options(other.options) {
constexpr double scale = util::EXTENT / util::tileSize;
-
- if (options.cluster
- && geoJSON.is<mapbox::feature::feature_collection<double>>()
- && !geoJSON.get<mapbox::feature::feature_collection<double>>().empty()) {
+ if (options.cluster && geoJSON.is<mapbox::feature::feature_collection<double>>() &&
+ !geoJSON.get<mapbox::feature::feature_collection<double>>().empty()) {
mapbox::supercluster::Options clusterOptions;
clusterOptions.maxZoom = options.clusterMaxZoom;
clusterOptions.extent = util::EXTENT;
clusterOptions.radius = ::round(scale * options.clusterRadius);
+ Feature feature;
+ clusterOptions.map = [&](const PropertyMap& properties) -> PropertyMap {
+ PropertyMap ret{};
+ for (const auto& p : options.clusterProperties) {
+ feature.properties = properties;
+ ret[p.first] = evaluateFeature<Value>(feature, p.second.first);
+ }
+ return ret;
+ };
+ clusterOptions.reduce = [&](PropertyMap& toReturn, const PropertyMap& toFill) {
+ for (const auto& p : options.clusterProperties) {
+ if (toFill.count(p.first) == 0) {
+ continue;
+ }
+ feature.properties = toFill;
+ optional<Value> accumulated(toReturn[p.first]);
+ toReturn[p.first] = evaluateFeature<Value>(feature, p.second.second, accumulated);
+ }
+ };
data = std::make_shared<SuperclusterData>(
geoJSON.get<mapbox::feature::feature_collection<double>>(), clusterOptions);
} else {