diff options
author | zmiao <miao.zhao@mapbox.com> | 2019-08-16 15:03:48 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-16 15:03:48 +0300 |
commit | 0f34eb7b253e83b8c4aef7ed6c83cd7b3801fa4c (patch) | |
tree | a0e06d1c81b04fca84f8ed8effeaeaefc2e79e13 | |
parent | 9f8696c00c7ef11abb3850e4694bc7375365295e (diff) | |
download | qtlocation-mapboxgl-0f34eb7b253e83b8c4aef7ed6c83cd7b3801fa4c.tar.gz |
Indroduce clusterProperty option for aggregation (#15287)
* indroduce clusterProperty option for aggregation
* remove unnecessary codes
* update geojson_option conversion
* fix reviewing findings
-rw-r--r-- | include/mbgl/annotation/annotation.hpp | 1 | ||||
-rw-r--r-- | include/mbgl/style/expression/dsl.hpp | 29 | ||||
-rw-r--r-- | include/mbgl/style/expression/expression.hpp | 6 | ||||
-rw-r--r-- | include/mbgl/style/sources/geojson_source.hpp | 13 | ||||
-rw-r--r-- | platform/node/test/ignores.json | 1 | ||||
-rw-r--r-- | src/mbgl/style/conversion/geojson_options.cpp | 69 | ||||
-rw-r--r-- | src/mbgl/style/expression/compound_expression.cpp | 13 | ||||
-rw-r--r-- | src/mbgl/style/expression/dsl.cpp | 23 | ||||
-rw-r--r-- | src/mbgl/style/expression/expression.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/style/expression/parsing_context.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/style/sources/geojson_source.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/sources/geojson_source_impl.cpp | 69 | ||||
-rw-r--r-- | src/mbgl/style/sources/geojson_source_impl.hpp | 2 | ||||
-rw-r--r-- | test/style/conversion/geojson_options.test.cpp | 12 | ||||
-rw-r--r-- | test/style/expression/expression.test.cpp | 3 | ||||
m--------- | vendor/supercluster.hpp | 0 |
16 files changed, 204 insertions, 50 deletions
diff --git a/include/mbgl/annotation/annotation.hpp b/include/mbgl/annotation/annotation.hpp index fb9ea5eba2..17728741bb 100644 --- a/include/mbgl/annotation/annotation.hpp +++ b/include/mbgl/annotation/annotation.hpp @@ -4,7 +4,6 @@ #include <mbgl/util/variant.hpp> #include <mbgl/util/color.hpp> #include <mbgl/style/property_value.hpp> -#include <mbgl/style/property_value.hpp> #include <cstdint> #include <vector> diff --git a/include/mbgl/style/expression/dsl.hpp b/include/mbgl/style/expression/dsl.hpp index bcab999ab2..4abeac7989 100644 --- a/include/mbgl/style/expression/dsl.hpp +++ b/include/mbgl/style/expression/dsl.hpp @@ -1,13 +1,13 @@ #pragma once -#include <mbgl/style/expression/value.hpp> #include <mbgl/style/expression/expression.hpp> #include <mbgl/style/expression/interpolator.hpp> +#include <mbgl/style/expression/value.hpp> #include <mbgl/util/ignore.hpp> +#include <initializer_list> #include <memory> #include <string> -#include <initializer_list> namespace mbgl { namespace style { @@ -24,15 +24,18 @@ std::vector<std::unique_ptr<Expression>> vec(Args... args) { return result; } +std::unique_ptr<Expression> createExpression(const char* expr); +std::unique_ptr<Expression> createExpression(const mbgl::style::conversion::Convertible& expr); std::unique_ptr<Expression> error(std::string); std::unique_ptr<Expression> literal(const char* value); std::unique_ptr<Expression> literal(Value value); std::unique_ptr<Expression> literal(std::initializer_list<double> value); -std::unique_ptr<Expression> literal(std::initializer_list<const char *> value); +std::unique_ptr<Expression> literal(std::initializer_list<const char*> value); -std::unique_ptr<Expression> assertion(type::Type, std::unique_ptr<Expression>, - std::unique_ptr<Expression> def = nullptr); +std::unique_ptr<Expression> +assertion(type::Type, std::unique_ptr<Expression>, + std::unique_ptr<Expression> def = nullptr); std::unique_ptr<Expression> number(std::unique_ptr<Expression>, std::unique_ptr<Expression> def = nullptr); std::unique_ptr<Expression> string(std::unique_ptr<Expression>, @@ -46,21 +49,17 @@ std::unique_ptr<Expression> toString(std::unique_ptr<Expression>, std::unique_ptr<Expression> def = nullptr); std::unique_ptr<Expression> toFormatted(std::unique_ptr<Expression>, std::unique_ptr<Expression> def = nullptr); - + std::unique_ptr<Expression> get(const char* value); std::unique_ptr<Expression> get(std::unique_ptr<Expression>); std::unique_ptr<Expression> id(); std::unique_ptr<Expression> zoom(); -std::unique_ptr<Expression> eq(std::unique_ptr<Expression>, - std::unique_ptr<Expression>); -std::unique_ptr<Expression> ne(std::unique_ptr<Expression>, - std::unique_ptr<Expression>); -std::unique_ptr<Expression> gt(std::unique_ptr<Expression>, - std::unique_ptr<Expression>); -std::unique_ptr<Expression> lt(std::unique_ptr<Expression>, - std::unique_ptr<Expression>); +std::unique_ptr<Expression> eq(std::unique_ptr<Expression>, std::unique_ptr<Expression>); +std::unique_ptr<Expression> ne(std::unique_ptr<Expression>, std::unique_ptr<Expression>); +std::unique_ptr<Expression> gt(std::unique_ptr<Expression>, std::unique_ptr<Expression>); +std::unique_ptr<Expression> lt(std::unique_ptr<Expression>, std::unique_ptr<Expression>); std::unique_ptr<Expression> step(std::unique_ptr<Expression> input, std::unique_ptr<Expression> output0, @@ -86,7 +85,7 @@ std::unique_ptr<Expression> interpolate(Interpolator interpolator, double input3, std::unique_ptr<Expression> output3); std::unique_ptr<Expression> concat(std::vector<std::unique_ptr<Expression>> inputs); - + std::unique_ptr<Expression> format(const char* value); std::unique_ptr<Expression> format(std::unique_ptr<Expression>); diff --git a/include/mbgl/style/expression/expression.hpp b/include/mbgl/style/expression/expression.hpp index 5f66fc6dc7..ad57748677 100644 --- a/include/mbgl/style/expression/expression.hpp +++ b/include/mbgl/style/expression/expression.hpp @@ -31,6 +31,9 @@ public: EvaluationContext(float zoom_, GeometryTileFeature const * feature_) : zoom(zoom_), feature(feature_) {} + EvaluationContext(optional<mbgl::Value> accumulated_, GeometryTileFeature const * feature_) : + accumulated(std::move(accumulated_)), feature(feature_) + {} EvaluationContext(optional<float> zoom_, GeometryTileFeature const * feature_, optional<double> colorRampParameter_) : zoom(std::move(zoom_)), feature(feature_), colorRampParameter(std::move(colorRampParameter_)) {} @@ -41,6 +44,7 @@ public: }; optional<float> zoom; + optional<mbgl::Value> accumulated; GeometryTileFeature const * feature = nullptr; optional<double> colorRampParameter; // Contains formatted section object, std::unordered_map<std::string, Value>. @@ -162,7 +166,7 @@ public: type::Type getType() const { return type; }; EvaluationResult evaluate(optional<float> zoom, const Feature& feature, optional<double> colorRampParameter) const; - + EvaluationResult evaluate(optional<mbgl::Value> accumulated, const Feature& feature) const; /** * Statically analyze the expression, attempting to enumerate possible outputs. Returns * an array of values plus the sentinel null optional value, used to indicate that the diff --git a/include/mbgl/style/sources/geojson_source.hpp b/include/mbgl/style/sources/geojson_source.hpp index a03b910279..4aec1584a6 100644 --- a/include/mbgl/style/sources/geojson_source.hpp +++ b/include/mbgl/style/sources/geojson_source.hpp @@ -1,9 +1,14 @@ #pragma once +#include <mbgl/style/expression/expression.hpp> #include <mbgl/style/source.hpp> +#include <mbgl/util/constants.hpp> #include <mbgl/util/geojson.hpp> #include <mbgl/util/optional.hpp> -#include <mbgl/util/constants.hpp> + +#include <memory> +#include <unordered_map> +#include <utility> namespace mbgl { @@ -24,11 +29,15 @@ struct GeoJSONOptions { bool cluster = false; uint16_t clusterRadius = 50; uint8_t clusterMaxZoom = 17; + using ClusterExpression = std::pair<std::shared_ptr<mbgl::style::expression::Expression>, + std::shared_ptr<mbgl::style::expression::Expression>>; + using ClusterProperties = std::unordered_map<std::string, ClusterExpression>; + ClusterProperties clusterProperties; }; class GeoJSONSource : public Source { public: - GeoJSONSource(const std::string& id, const GeoJSONOptions& = {}); + GeoJSONSource(const std::string& id, optional<GeoJSONOptions> = nullopt); ~GeoJSONSource() final; void setURL(const std::string& url); diff --git a/platform/node/test/ignores.json b/platform/node/test/ignores.json index 7665972aad..bc2535227f 100644 --- a/platform/node/test/ignores.json +++ b/platform/node/test/ignores.json @@ -85,7 +85,6 @@ "render-tests/text-variable-anchor/pitched-rotated-debug": "https://github.com/mapbox/mapbox-gl-native/issues/14211", "render-tests/text-variable-anchor/rotated-offset": "https://github.com/mapbox/mapbox-gl-native/issues/14211", "render-tests/text-variable-anchor/remember-last-placement": "skip - fails on gl-native, as symbol index is not functional at static map mode - needs issue", - "render-tests/geojson/clustered-properties": "https://github.com/mapbox/mapbox-gl-native/issues/14043", "render-tests/remove-feature-state/composite-expression": "https://github.com/mapbox/mapbox-gl-native/issues/12413", "render-tests/remove-feature-state/data-expression": "https://github.com/mapbox/mapbox-gl-native/issues/12413", "render-tests/remove-feature-state/vector-source": "https://github.com/mapbox/mapbox-gl-native/issues/12413", diff --git a/src/mbgl/style/conversion/geojson_options.cpp b/src/mbgl/style/conversion/geojson_options.cpp index 11bd7cc507..08553e34bb 100644 --- a/src/mbgl/style/conversion/geojson_options.cpp +++ b/src/mbgl/style/conversion/geojson_options.cpp @@ -1,11 +1,15 @@ #include <mbgl/style/conversion/geojson_options.hpp> #include <mbgl/style/conversion_impl.hpp> +#include <mbgl/style/expression/dsl.hpp> + +#include <sstream> namespace mbgl { namespace style { namespace conversion { -optional<GeoJSONOptions> Converter<GeoJSONOptions>::operator()(const Convertible& value, Error& error) const { +optional<GeoJSONOptions> Converter<GeoJSONOptions>::operator()(const Convertible& value, + Error& error) const { GeoJSONOptions options; const auto minzoomValue = objectMember(value, "minzoom"); @@ -83,12 +87,71 @@ optional<GeoJSONOptions> Converter<GeoJSONOptions>::operator()(const Convertible if (toBool(*lineMetricsValue)) { options.lineMetrics = *toBool(*lineMetricsValue); } else { - error = { "GeoJSON source lineMetrics value must be a boolean" }; + error.message = "GeoJSON source lineMetrics value must be a boolean"; + return nullopt; + } + } + + const auto clusterProperties = objectMember(value, "clusterProperties"); + if (clusterProperties) { + if (!isObject(*clusterProperties)) { + error.message = "GeoJSON source clusterProperties value must be an object"; + return nullopt; + } + GeoJSONOptions::ClusterProperties result; + assert(error.message.empty()); + eachMember( + *clusterProperties, + [&](const std::string& k, + const mbgl::style::conversion::Convertible& v) -> optional<conversion::Error> { + // Each property shall be formed as ["key" : [operator, [mapExpression]]] + // or ["key" : [[operator, ['accumulated'], ['get', key]], [mapExpression]]] + if (!isArray(v) || arrayLength(v) != 2) { + error.message = + "GeoJSON source clusterProperties member must be an array with length of 2"; + return nullopt; + } + auto map = expression::dsl::createExpression(arrayMember(v, 1)); + if (!map) { + error.message = + "Failed to convert GeoJSON source clusterProperties map expression"; + return nullopt; + } + std::unique_ptr<expression::Expression> reduce; + if (isArray(arrayMember(v, 0))) { + reduce = expression::dsl::createExpression(arrayMember(v, 0)); + } else { + auto reduceOp = toString(arrayMember(v, 0)); + if (!reduceOp) { + error.message = + "GeoJSON source clusterProperties member must contain a valid operator"; + return nullopt; + } + std::stringstream ss; + // Reformulate reduce expression to [operator, ['accumulated'], ['get', key]] + // The reason to create expression via parsing string instead of invoking function + // createCompoundExpression is due to expression type disunity can’t be resolved + // with current logic of createCompoundExpression + ss << std::string(R"([")") << *reduceOp + << std::string(R"(", ["accumulated"], ["get", ")") << k + << std::string(R"("]])"); + reduce = expression::dsl::createExpression(ss.str().c_str()); + } + if (!reduce) { + error.message = + "Failed to convert GeoJSON source clusterProperties reduce expression"; + return nullopt; + } + result.emplace(k, std::make_pair(std::move(map), std::move(reduce))); + return nullopt; + }); + if (!error.message.empty()) { return nullopt; } + options.clusterProperties = std::move(result); } - return { options }; + return { std::move(options) }; } } // namespace conversion diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp index 34f0f5dea3..c637856ad9 100644 --- a/src/mbgl/style/expression/compound_expression.cpp +++ b/src/mbgl/style/expression/compound_expression.cpp @@ -368,6 +368,18 @@ const auto& lineProgressCompoundExpression() { return signature; } +const auto& accumulatedCompoundExpression() { + const static auto signature = detail::makeSignature("accumulated", [](const EvaluationContext& params) -> Result<Value> { + if (!params.accumulated) { + return EvaluationError { + "The 'accumulated' expression is unavailable in the current evaluation context." + }; + } + return Value(toExpressionValue(*params.accumulated)); + }); + return signature; +} + const auto& hasContextCompoundExpression() { static auto signature = detail::makeSignature("has", [](const EvaluationContext& params, const std::string& key) -> Result<bool> { if (!params.feature) { @@ -871,6 +883,7 @@ MAPBOX_ETERNAL_CONSTEXPR const auto compoundExpressionRegistry = mapbox::eternal { "zoom", zoomCompoundExpression }, { "heatmap-density", heatmapDensityCompoundExpression }, { "line-progress", lineProgressCompoundExpression }, + { "accumulated", accumulatedCompoundExpression }, { "has", hasContextCompoundExpression }, { "has", hasObjectCompoundExpression }, { "get", getContextCompoundExpression }, diff --git a/src/mbgl/style/expression/dsl.cpp b/src/mbgl/style/expression/dsl.cpp index 70442de968..fac7dfbbd9 100644 --- a/src/mbgl/style/expression/dsl.cpp +++ b/src/mbgl/style/expression/dsl.cpp @@ -10,6 +10,10 @@ #include <mbgl/style/expression/compound_expression.hpp> #include <mbgl/style/expression/format_expression.hpp> +#include <mapbox/geojsonvt.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <rapidjson/document.h> + namespace mbgl { namespace style { namespace expression { @@ -21,6 +25,25 @@ std::unique_ptr<Expression> compound(const char* op, std::vector<std::unique_ptr assert(result); return std::move(*result); } + +std::unique_ptr<Expression> createExpression(const char* expr) { + using JSValue = rapidjson::GenericValue<rapidjson::UTF8<>, rapidjson::CrtAllocator>; + rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> document; + document.Parse<0>(expr); + if (document.HasParseError()) return nullptr; + + const JSValue* expression = &document; + expression::ParsingContext ctx; + expression::ParseResult parsed = + ctx.parseExpression(mbgl::style::conversion::Convertible(expression)); + return parsed ? std::move(*parsed) : nullptr; +} + +std::unique_ptr<Expression> createExpression(const mbgl::style::conversion::Convertible& expr) { + expression::ParsingContext ctx; + expression::ParseResult parsed = ctx.parseExpression(expr); + return parsed ? std::move(*parsed) : nullptr; +} std::unique_ptr<Expression> error(std::string message) { return std::make_unique<Error>(std::move(message)); diff --git a/src/mbgl/style/expression/expression.cpp b/src/mbgl/style/expression/expression.cpp index d61f435eec..6bfda99064 100644 --- a/src/mbgl/style/expression/expression.cpp +++ b/src/mbgl/style/expression/expression.cpp @@ -25,13 +25,17 @@ public: return optional<mbgl::Value>(); } }; - - + EvaluationResult Expression::evaluate(optional<float> zoom, const Feature& feature, optional<double> colorRampParameter) const { GeoJSONFeature f(feature); return this->evaluate(EvaluationContext(zoom, &f, colorRampParameter)); } +EvaluationResult Expression::evaluate(optional<mbgl::Value> accumulated, const Feature& feature) const { + GeoJSONFeature f(feature); + return this->evaluate(EvaluationContext(accumulated, &f)); +} + } // namespace expression } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/expression/parsing_context.cpp b/src/mbgl/style/expression/parsing_context.cpp index a7c04f563d..6ce3a9bfaa 100644 --- a/src/mbgl/style/expression/parsing_context.cpp +++ b/src/mbgl/style/expression/parsing_context.cpp @@ -73,7 +73,8 @@ bool isConstant(const Expression& expression) { return isFeatureConstant(expression) && isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "heatmap-density"}}) && - isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "line-progress"}}); + isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "line-progress"}}) && + isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "accumulated"}}); } using namespace mbgl::style::conversion; diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp index 4e3478322d..72a51e212f 100644 --- a/src/mbgl/style/sources/geojson_source.cpp +++ b/src/mbgl/style/sources/geojson_source.cpp @@ -9,7 +9,7 @@ namespace mbgl { namespace style { -GeoJSONSource::GeoJSONSource(const std::string& id, const GeoJSONOptions& options) +GeoJSONSource::GeoJSONSource(const std::string& id, optional<GeoJSONOptions> options) : Source(makeMutable<Impl>(std::move(id), options)) { } 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 { diff --git a/src/mbgl/style/sources/geojson_source_impl.hpp b/src/mbgl/style/sources/geojson_source_impl.hpp index b88ab35ee0..26b9d95a39 100644 --- a/src/mbgl/style/sources/geojson_source_impl.hpp +++ b/src/mbgl/style/sources/geojson_source_impl.hpp @@ -26,7 +26,7 @@ public: class GeoJSONSource::Impl : public Source::Impl { public: - Impl(std::string id, GeoJSONOptions); + Impl(std::string id, optional<GeoJSONOptions>); Impl(const GeoJSONSource::Impl&, const GeoJSON&); ~Impl() final; diff --git a/test/style/conversion/geojson_options.test.cpp b/test/style/conversion/geojson_options.test.cpp index 181189775b..aa84686dce 100644 --- a/test/style/conversion/geojson_options.test.cpp +++ b/test/style/conversion/geojson_options.test.cpp @@ -38,6 +38,7 @@ TEST(GeoJSONOptions, RetainsDefaults) { ASSERT_EQ(converted.cluster, defaults.cluster); ASSERT_EQ(converted.clusterRadius, defaults.clusterRadius); ASSERT_EQ(converted.clusterMaxZoom, defaults.clusterMaxZoom); + ASSERT_TRUE(converted.clusterProperties.empty()); } TEST(GeoJSONOptions, FullConversion) { @@ -49,7 +50,12 @@ TEST(GeoJSONOptions, FullConversion) { "cluster": true, "clusterRadius": 4, "clusterMaxZoom": 5, - "lineMetrics": true + "lineMetrics": true, + "clusterProperties": { + "max": ["max", ["get", "scalerank"]], + "sum": [["+", ["accumulated"], ["get", "sum"]], ["get", "scalerank"]], + "has_island": ["any", ["==", ["get", "featureclass"], "island"]] + } })JSON", error); // GeoJSON-VT @@ -63,4 +69,8 @@ TEST(GeoJSONOptions, FullConversion) { ASSERT_EQ(converted.cluster, true); ASSERT_EQ(converted.clusterRadius, 4); ASSERT_EQ(converted.clusterMaxZoom, 5); + ASSERT_EQ(converted.clusterProperties.size(), 3); + ASSERT_EQ(converted.clusterProperties.count("max"), 1); + ASSERT_EQ(converted.clusterProperties.count("sum"), 1); + ASSERT_EQ(converted.clusterProperties.count("has_island"), 1); } diff --git a/test/style/expression/expression.test.cpp b/test/style/expression/expression.test.cpp index 8e2acfcd32..dd986c98f5 100644 --- a/test/style/expression/expression.test.cpp +++ b/test/style/expression/expression.test.cpp @@ -36,8 +36,7 @@ TEST(Expression, IsExpression) { // TODO: "feature-state": https://github.com/mapbox/mapbox-gl-native/issues/12613 // TODO: "interpolate-hcl": https://github.com/mapbox/mapbox-gl-native/issues/8720 // TODO: "interpolate-lab": https://github.com/mapbox/mapbox-gl-native/issues/8720 - // TODO: "accumulated": https://github.com/mapbox/mapbox-gl-native/issues/14043 - if (name == "feature-state" || name == "interpolate-hcl" || name == "interpolate-lab" || name == "accumulated") { + if (name == "feature-state" || name == "interpolate-hcl" || name == "interpolate-lab") { if (expression::isExpression(conversion::Convertible(expression))) { ASSERT_TRUE(false) << "Expression name" << name << "is implemented - please update Expression.IsExpression test."; } diff --git a/vendor/supercluster.hpp b/vendor/supercluster.hpp -Subproject 274ec138306c7b110bf4dde47706aeb43dc8147 +Subproject 03c026c49c3e25cb4c65f91a308ab869e98f649 |