summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmiao <miao.zhao@mapbox.com>2020-02-25 11:49:57 +0200
committerzmiao <miao.zhao@mapbox.com>2020-03-05 20:53:16 +0200
commit9fbcb45c89ee3cec2b94253515a23df5986a4c7b (patch)
tree34b0c98b47e99e986b8713d3baf2bfc27f952b58
parent9ff1435aaa8856b776091c8cdae1666299818ab2 (diff)
downloadqtlocation-mapboxgl-9fbcb45c89ee3cec2b94253515a23df5986a4c7b.tar.gz
[core] Make within expression support generic geoJSON data
-rw-r--r--src/mbgl/style/expression/within.cpp73
1 files changed, 51 insertions, 22 deletions
diff --git a/src/mbgl/style/expression/within.cpp b/src/mbgl/style/expression/within.cpp
index 9039ff2fe4..9de5af39eb 100644
--- a/src/mbgl/style/expression/within.cpp
+++ b/src/mbgl/style/expression/within.cpp
@@ -10,6 +10,8 @@
#include <rapidjson/document.h>
+#include <utility>
+
namespace mbgl {
namespace {
@@ -17,14 +19,20 @@ class PolygonFeature : public GeometryTileFeature {
public:
const Feature& feature;
mutable optional<GeometryCollection> geometry;
+ FeatureType type;
PolygonFeature(const Feature& feature_, const CanonicalTileID& canonical) : feature(feature_) {
- geometry = convertGeometry(feature.geometry, canonical);
- assert(geometry);
- geometry = fixupPolygons(*geometry);
+ type = apply_visitor(ToFeatureType(), feature.geometry);
+ if (type == FeatureType::Polygon) {
+ geometry = convertGeometry(feature.geometry, canonical);
+ assert(geometry);
+ geometry = fixupPolygons(*geometry);
+ } else {
+ mbgl::Log::Warning(mbgl::Event::General, "Provided feature does not contain polygon geometries.");
+ }
}
- FeatureType getType() const override { return FeatureType::Polygon; }
+ FeatureType getType() const override { return type; }
const PropertyMap& getProperties() const override { return feature.properties; }
FeatureIdentifier getID() const override { return feature.id; }
optional<mbgl::Value> getValue(const std::string& /*key*/) const override { return optional<mbgl::Value>(); }
@@ -109,23 +117,28 @@ bool linesWithinPolygons(const mbgl::GeometryTileFeature& feature,
mbgl::optional<mbgl::GeoJSON> parseValue(const mbgl::style::conversion::Convertible& value_,
mbgl::style::expression::ParsingContext& ctx) {
if (isObject(value_)) {
- const auto geometryType = objectMember(value_, "type");
- if (geometryType) {
- const auto type = toString(*geometryType);
- if (type && *type == "Polygon") {
- mbgl::style::conversion::Error error;
- auto geojson = toGeoJSON(value_, error);
- if (geojson && error.message.empty()) {
- return geojson;
- }
- ctx.error(error.message);
- }
+ mbgl::style::conversion::Error error;
+ auto geojson = toGeoJSON(value_, error);
+ if (geojson && error.message.empty()) {
+ return geojson;
}
+ ctx.error(error.message);
}
+
ctx.error("'within' expression requires valid geojson source that contains polygon geometry type.");
return nullopt;
}
+mbgl::optional<std::pair<Feature::geometry_type, WithinBBox>> generateResult(
+ const PolygonFeature& polyFeature, mbgl::style::expression::ParsingContext& ctx) {
+ if (polyFeature.getType() == FeatureType::Polygon) {
+ auto refinedGeoSet = convertGeometry(polyFeature, CanonicalTileID(0, 0, 0));
+ auto bbox = calculateBBox(refinedGeoSet);
+ return std::make_pair(std::move(refinedGeoSet), bbox);
+ }
+ ctx.error("'within' expression requires valid geojson source that contains polygon geometry type.");
+ return nullopt;
+}
} // namespace
namespace style {
@@ -173,15 +186,31 @@ ParseResult Within::parse(const Convertible& value, ParsingContext& ctx) {
}
return parsedValue->match(
- [&parsedValue](const mapbox::geometry::geometry<double>& geometrySet) {
- mbgl::Feature f(geometrySet);
- PolygonFeature polyFeature(f, CanonicalTileID(0, 0, 0));
- auto refinedGeoSet = convertGeometry(polyFeature, CanonicalTileID(0, 0, 0));
- auto bbox = calculateBBox(refinedGeoSet);
- return ParseResult(std::make_unique<Within>(*parsedValue, std::move(refinedGeoSet), bbox));
+ [&parsedValue, &ctx](const mapbox::geometry::geometry<double>& geometrySet) {
+ PolygonFeature polyFeature(mbgl::Feature(geometrySet), CanonicalTileID(0, 0, 0));
+ if (auto ret = generateResult(polyFeature, ctx)) {
+ return ParseResult(std::make_unique<Within>(*parsedValue, std::move(ret->first), ret->second));
+ }
+ return ParseResult();
+ },
+ [&parsedValue, &ctx](const mapbox::feature::feature<double>& feature) {
+ PolygonFeature polyFeature(mbgl::Feature(feature), CanonicalTileID(0, 0, 0));
+ if (auto ret = generateResult(polyFeature, ctx)) {
+ return ParseResult(std::make_unique<Within>(*parsedValue, std::move(ret->first), ret->second));
+ }
+ return ParseResult();
+ },
+ [&parsedValue, &ctx](const mapbox::feature::feature_collection<double>& features) {
+ for (const auto& feature : features) {
+ PolygonFeature polyFeature(mbgl::Feature(feature), CanonicalTileID(0, 0, 0));
+ if (auto ret = generateResult(polyFeature, ctx)) {
+ return ParseResult(std::make_unique<Within>(*parsedValue, std::move(ret->first), ret->second));
+ }
+ }
+ return ParseResult();
},
[&ctx](const auto&) {
- ctx.error("'within' expression requires geojson source that contains valid geometry data.");
+ ctx.error("'within' expression requires valid geojson source that contains polygon geometry type.");
return ParseResult();
});
}