diff options
Diffstat (limited to 'src/mbgl/style/sources/geojson_source_impl.cpp')
-rw-r--r-- | src/mbgl/style/sources/geojson_source_impl.cpp | 69 |
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 { |