[core] geometry@0.8.0 / geojsonvt@6.0.0 (#5514)
* [core] geometry.hpp 0.8.0 * geojsonvt @ 6.0.0 * Update platform deps, build scripts * Perf optimizations/cleanup * Rebase in geometry@080 * D.R.Y. etc * Ensure fill annotation geometries have closed rings. * Optimizations * Update to geojsonvt @ 6.1.0 for clean handoff between geojson parsing and geojsonvt * Apply close multi/poly geoms for line annotations as well
This commit is contained in:
2
.mason
2
.mason
Submodule .mason updated: 3017f67422...c3be66082b
@@ -9,12 +9,8 @@
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
typedef std::multimap<std::string, Value> Properties;
|
||||
|
||||
style::Filter parse(const char* expression) {
|
||||
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> doc;
|
||||
doc.Parse<0>(expression);
|
||||
@@ -29,7 +25,7 @@ static void Parse_Filter(benchmark::State& state) {
|
||||
|
||||
static void Parse_EvaluateFilter(benchmark::State& state) {
|
||||
const style::Filter filter = parse(R"FILTER(["==", "foo", "bar"])FILTER");
|
||||
const Properties properties = { { "foo", std::string("bar") } };
|
||||
const PropertyMap properties = { { "foo", std::string("bar") } };
|
||||
|
||||
while (state.KeepRunning()) {
|
||||
filter(FeatureType::Unknown, [&] (const std::string& key) -> optional<Value> {
|
||||
|
||||
1
configure
vendored
1
configure
vendored
@@ -118,6 +118,7 @@ print_flags zlib static_libs cflags ldflags
|
||||
print_flags nunicode static_libs cflags ldflags
|
||||
print_flags libzip static_libs cflags ldflags
|
||||
print_flags geometry cflags
|
||||
print_flags geojson static_libs cflags ldflags
|
||||
print_flags geojsonvt static_libs cflags ldflags
|
||||
print_flags variant cflags
|
||||
print_flags rapidjson static_libs cflags ldflags
|
||||
|
||||
@@ -151,13 +151,24 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator()(const NullValue&,
|
||||
const NullValue&) const {
|
||||
// Should be unreachable; null is not currently allowed by the style specification.
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator()(const std::vector<Value>&,
|
||||
const std::vector<Value>&) const {
|
||||
// Should be unreachable; nested values are not currently allowed by the style specification.
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator()(const std::unordered_map<std::string, Value>&,
|
||||
const std::unordered_map<std::string, Value>&) const {
|
||||
// Should be unreachable; nested values are not currently allowed by the style specification.
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
namespace mbgl {
|
||||
|
||||
using Value = mapbox::geometry::value;
|
||||
|
||||
using NullValue = mapbox::geometry::null_value_t;
|
||||
using PropertyMap = mapbox::geometry::property_map;
|
||||
using FeatureIdentifier = mapbox::geometry::identifier;
|
||||
class Feature : public mapbox::geometry::feature<double> {
|
||||
public:
|
||||
Feature(geometry_type&& geometry_)
|
||||
: mapbox::geometry::feature<double> { std::move(geometry_) } {}
|
||||
|
||||
optional<uint64_t> id;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -41,4 +41,21 @@ Point<S> convertPoint(const Point<T>& p) {
|
||||
return Point<S>(p.x, p.y);
|
||||
}
|
||||
|
||||
struct ToFeatureType {
|
||||
template <class T>
|
||||
FeatureType operator()(const Point<T> &) const { return FeatureType::Point; }
|
||||
template <class T>
|
||||
FeatureType operator()(const MultiPoint<T> &) const { return FeatureType::Point; }
|
||||
template <class T>
|
||||
FeatureType operator()(const LineString<T> &) const { return FeatureType::LineString; }
|
||||
template <class T>
|
||||
FeatureType operator()(const MultiLineString<T> &) const { return FeatureType::LineString; }
|
||||
template <class T>
|
||||
FeatureType operator()(const Polygon<T> &) const { return FeatureType::Polygon; }
|
||||
template <class T>
|
||||
FeatureType operator()(const MultiPolygon<T> &) const { return FeatureType::Polygon; }
|
||||
template <class T>
|
||||
FeatureType operator()(const mapbox::geometry::geometry_collection<T> &) const { return FeatureType::Unknown; }
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -192,6 +192,7 @@
|
||||
'<@(protozero_cflags)',
|
||||
'<@(boost_cflags)',
|
||||
'<@(geometry_cflags)',
|
||||
'<@(geojson_cflags)',
|
||||
'<@(geojsonvt_cflags)',
|
||||
'<@(rapidjson_cflags)',
|
||||
'<@(variant_cflags)',
|
||||
@@ -207,7 +208,7 @@
|
||||
'<@(opengl_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(geojsonvt_static_libs)',
|
||||
'<@(geojson_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
@@ -9,8 +9,9 @@ SQLITE_VERSION=3.9.1
|
||||
ZLIB_VERSION=system
|
||||
NUNICODE_VERSION=1.6
|
||||
LIBZIP_VERSION=0.11.2
|
||||
GEOMETRY_VERSION=0.5.0
|
||||
GEOJSONVT_VERSION=4.1.2-cxx11abi
|
||||
GEOMETRY_VERSION=0.8.0
|
||||
GEOJSON_VERSION=0.1.4
|
||||
GEOJSONVT_VERSION=6.1.0
|
||||
VARIANT_VERSION=1.1.0
|
||||
RAPIDJSON_VERSION=1.0.2
|
||||
JNI_HPP_VERSION=2.0.0
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
*/
|
||||
class PropertyValueEvaluator {
|
||||
public:
|
||||
id operator()(const std::nullptr_t &) const {
|
||||
id operator()(const mbgl::NullValue &) const {
|
||||
return [NSNull null];
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ NS_ARRAY_OF(MGLShape <MGLFeature> *) *MGLFeaturesFromMBGLFeatures(const std::vec
|
||||
GeometryEvaluator<double> evaluator;
|
||||
MGLShape <MGLFeaturePrivate> *shape = mapbox::geometry::geometry<double>::visit(feature.geometry, evaluator);
|
||||
if (feature.id) {
|
||||
shape.identifier = @(*feature.id);
|
||||
shape.identifier = mbgl::FeatureIdentifier::visit(*feature.id, PropertyValueEvaluator());
|
||||
}
|
||||
shape.attributes = attributes;
|
||||
[shapes addObject:shape];
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
|
||||
mapbox::geometry::point<double> point = { -90.066667, 29.95 };
|
||||
mbgl::Feature pointFeature(point);
|
||||
pointFeature.id = UINT64_MAX;
|
||||
pointFeature.id = { UINT64_MAX };
|
||||
pointFeature.properties["null"] = nullptr;
|
||||
pointFeature.properties["bool"] = true;
|
||||
pointFeature.properties["unsigned int"] = UINT64_MAX;
|
||||
|
||||
@@ -1739,7 +1739,7 @@
|
||||
"$(sqlite_ldflags)",
|
||||
"$(zlib_ldflags)",
|
||||
"$(opengl_ldflags)",
|
||||
"$(geojsonvt_static_libs)",
|
||||
"$(geojson_static_libs)",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.sdk.ios;
|
||||
PRODUCT_NAME = Mapbox;
|
||||
@@ -1779,7 +1779,7 @@
|
||||
"$(sqlite_ldflags)",
|
||||
"$(zlib_ldflags)",
|
||||
"$(opengl_ldflags)",
|
||||
"$(geojsonvt_static_libs)",
|
||||
"$(geojson_static_libs)",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.sdk.ios;
|
||||
PRODUCT_NAME = Mapbox;
|
||||
@@ -1833,7 +1833,7 @@
|
||||
"$(sqlite_ldflags)",
|
||||
"$(zlib_ldflags)",
|
||||
"$(opengl_ldflags)",
|
||||
"$(geojsonvt_static_libs)",
|
||||
"$(geojson_static_libs)",
|
||||
);
|
||||
PRODUCT_NAME = Mapbox;
|
||||
PUBLIC_HEADERS_FOLDER_PATH = Headers;
|
||||
@@ -1863,7 +1863,7 @@
|
||||
"$(sqlite_ldflags)",
|
||||
"$(zlib_ldflags)",
|
||||
"$(opengl_ldflags)",
|
||||
"$(geojsonvt_static_libs)",
|
||||
"$(geojson_static_libs)",
|
||||
);
|
||||
PRODUCT_NAME = Mapbox;
|
||||
PUBLIC_HEADERS_FOLDER_PATH = Headers;
|
||||
|
||||
@@ -5,8 +5,9 @@ PROTOZERO_VERSION=1.3.0
|
||||
BOOST_VERSION=1.60.0
|
||||
SQLITE_VERSION=system
|
||||
ZLIB_VERSION=system
|
||||
GEOMETRY_VERSION=0.5.0
|
||||
GEOJSONVT_VERSION=4.1.2
|
||||
GEOMETRY_VERSION=0.8.0
|
||||
GEOJSON_VERSION=0.1.4
|
||||
GEOJSONVT_VERSION=6.1.0
|
||||
VARIANT_VERSION=1.1.0
|
||||
RAPIDJSON_VERSION=1.0.2
|
||||
GTEST_VERSION=1.7.0
|
||||
|
||||
@@ -119,7 +119,7 @@ if [[ "${BUILD_FOR_DEVICE}" == true ]]; then
|
||||
-o ${OUTPUT}/static/${NAME}.framework/${NAME} \
|
||||
${LIBS[@]/#/${PRODUCTS}/${BUILDTYPE}-iphoneos/lib} \
|
||||
${LIBS[@]/#/${PRODUCTS}/${BUILDTYPE}-iphonesimulator/lib} \
|
||||
`find mason_packages/ios-${IOS_SDK_VERSION} -type f -name libgeojsonvt.a`
|
||||
`find mason_packages/ios-${IOS_SDK_VERSION} -type f -name libgeojson.a`
|
||||
|
||||
cp -rv ${PRODUCTS}/${BUILDTYPE}-iphoneos/${NAME}.bundle ${STATIC_BUNDLE_DIR}
|
||||
fi
|
||||
@@ -149,7 +149,7 @@ else
|
||||
libtool -static -no_warning_for_no_symbols \
|
||||
-o ${OUTPUT}/static/${NAME}.framework/${NAME} \
|
||||
${LIBS[@]/#/${PRODUCTS}/${BUILDTYPE}-iphonesimulator/lib} \
|
||||
`find mason_packages/ios-${IOS_SDK_VERSION} -type f -name libgeojsonvt.a`
|
||||
`find mason_packages/ios-${IOS_SDK_VERSION} -type f -name libgeojson.a`
|
||||
|
||||
cp -rv ${PRODUCTS}/${BUILDTYPE}-iphonesimulator/${NAME}.bundle ${STATIC_BUNDLE_DIR}
|
||||
fi
|
||||
|
||||
@@ -14,8 +14,9 @@ SQLITE_VERSION=3.9.1
|
||||
LIBUV_VERSION=1.7.5
|
||||
ZLIB_VERSION=system
|
||||
NUNICODE_VERSION=1.6
|
||||
GEOMETRY_VERSION=0.5.0
|
||||
GEOJSONVT_VERSION=4.1.2${CXX11ABI:-}
|
||||
GEOMETRY_VERSION=0.8.0
|
||||
GEOJSON_VERSION=0.1.4${CXX11ABI:-}
|
||||
GEOJSONVT_VERSION=6.1.0
|
||||
VARIANT_VERSION=1.1.0
|
||||
RAPIDJSON_VERSION=1.0.2
|
||||
GTEST_VERSION=1.7.0${CXX11ABI:-}
|
||||
|
||||
@@ -1039,7 +1039,7 @@
|
||||
OTHER_LDFLAGS = (
|
||||
"$(zlib_ldflags)",
|
||||
"$(opengl_ldflags)",
|
||||
"$(geojsonvt_static_libs)",
|
||||
"$(geojson_static_libs)",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxGL;
|
||||
PRODUCT_NAME = Mapbox;
|
||||
@@ -1078,7 +1078,7 @@
|
||||
OTHER_LDFLAGS = (
|
||||
"$(zlib_ldflags)",
|
||||
"$(opengl_ldflags)",
|
||||
"$(geojsonvt_static_libs)",
|
||||
"$(geojson_static_libs)",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxGL;
|
||||
PRODUCT_NAME = Mapbox;
|
||||
|
||||
@@ -8,8 +8,9 @@ GLFW_VERSION=3.1.2
|
||||
SQLITE_VERSION=3.9.1
|
||||
ZLIB_VERSION=system
|
||||
NUNICODE_VERSION=1.6
|
||||
GEOMETRY_VERSION=0.5.0
|
||||
GEOJSONVT_VERSION=4.1.2
|
||||
GEOMETRY_VERSION=0.8.0
|
||||
GEOJSON_VERSION=0.1.4
|
||||
GEOJSONVT_VERSION=6.1.0
|
||||
VARIANT_VERSION=1.1.0
|
||||
RAPIDJSON_VERSION=1.0.2
|
||||
GTEST_VERSION=1.7.0
|
||||
|
||||
@@ -6,9 +6,10 @@ using namespace mapbox::geometry;
|
||||
|
||||
using Value = mbgl::Value;
|
||||
using Feature = mbgl::Feature;
|
||||
using FeatureIdentifier = mbgl::FeatureIdentifier;
|
||||
using Geometry = mbgl::Feature::geometry_type;
|
||||
using GeometryCollection = mapbox::geometry::geometry_collection<double>;
|
||||
using Properties = mbgl::Feature::property_map;
|
||||
using Properties = mbgl::PropertyMap;
|
||||
|
||||
template <class T>
|
||||
struct ToType {
|
||||
@@ -76,7 +77,7 @@ public:
|
||||
};
|
||||
|
||||
struct ToValue {
|
||||
v8::Local<v8::Value> operator()(std::nullptr_t) {
|
||||
v8::Local<v8::Value> operator()(mbgl::NullValue) {
|
||||
Nan::EscapableHandleScope scope;
|
||||
return scope.Escape(Nan::Null());
|
||||
}
|
||||
@@ -159,7 +160,7 @@ v8::Local<v8::Object> toJS(const Feature& feature) {
|
||||
Nan::Set(result, Nan::New("properties").ToLocalChecked(), toJS(feature.properties));
|
||||
|
||||
if (feature.id) {
|
||||
Nan::Set(result, Nan::New("id").ToLocalChecked(), Nan::New(double(*feature.id)));
|
||||
Nan::Set(result, Nan::New("id").ToLocalChecked(), FeatureIdentifier::visit(*feature.id, ToValue()));
|
||||
}
|
||||
|
||||
return scope.Escape(result);
|
||||
|
||||
@@ -13,6 +13,6 @@ namespace node_mbgl {
|
||||
v8::Local<v8::Value> toJS(const mbgl::Value&);
|
||||
v8::Local<v8::Object> toJS(const mbgl::Feature&);
|
||||
v8::Local<v8::Object> toJS(const mbgl::Feature::geometry_type&);
|
||||
v8::Local<v8::Object> toJS(const mbgl::Feature::property_map&);
|
||||
v8::Local<v8::Object> toJS(const mbgl::PropertyMap&);
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ CXX11ABI=${CXX11ABI:-$(scripts/check-cxx11abi.sh)}
|
||||
UNIQUE_RESOURCE_VERSION=dev
|
||||
PROTOZERO_VERSION=1.3.0
|
||||
BOOST_VERSION=1.60.0
|
||||
GEOMETRY_VERSION=0.5.0
|
||||
GEOJSONVT_VERSION=4.1.2${CXX11ABI:-}
|
||||
GEOMETRY_VERSION=0.8.0
|
||||
GEOJSON_VERSION=0.1.4${CXX11ABI:-}
|
||||
GEOJSONVT_VERSION=6.1.0
|
||||
GTEST_VERSION=1.7.0${CXX11ABI:-}
|
||||
LIBJPEG_TURBO_VERSION=1.4.2
|
||||
NUNICODE_VERSION=1.6
|
||||
|
||||
@@ -9,7 +9,7 @@ using namespace style;
|
||||
|
||||
FillAnnotationImpl::FillAnnotationImpl(AnnotationID id_, FillAnnotation annotation_, uint8_t maxZoom_)
|
||||
: ShapeAnnotationImpl(id_, maxZoom_),
|
||||
annotation(std::move(annotation_)) {
|
||||
annotation({ ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.color, annotation_.outlineColor }) {
|
||||
}
|
||||
|
||||
void FillAnnotationImpl::updateStyle(Style& style) const {
|
||||
|
||||
@@ -9,7 +9,7 @@ using namespace style;
|
||||
|
||||
LineAnnotationImpl::LineAnnotationImpl(AnnotationID id_, LineAnnotation annotation_, uint8_t maxZoom_)
|
||||
: ShapeAnnotationImpl(id_, maxZoom_),
|
||||
annotation(std::move(annotation_)) {
|
||||
annotation({ ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.width, annotation_.color }) {
|
||||
}
|
||||
|
||||
void LineAnnotationImpl::updateStyle(Style& style) const {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include <mapbox/geojsonvt/convert.hpp>
|
||||
|
||||
#include <mbgl/annotation/shape_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/annotation_tile.hpp>
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
@@ -7,6 +5,7 @@
|
||||
#include <mbgl/math/clamp.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -19,86 +18,16 @@ ShapeAnnotationImpl::ShapeAnnotationImpl(const AnnotationID id_, const uint8_t m
|
||||
layerID("com.mapbox.annotations.shape." + util::toString(id)) {
|
||||
}
|
||||
|
||||
struct ToGeoJSONVT {
|
||||
const double tolerance;
|
||||
|
||||
ToGeoJSONVT(const double tolerance_)
|
||||
: tolerance(tolerance_) {
|
||||
}
|
||||
|
||||
geojsonvt::ProjectedFeature operator()(const LineString<double>& line) const {
|
||||
geojsonvt::ProjectedRings converted;
|
||||
converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::LineString, line));
|
||||
return convertFeature(geojsonvt::ProjectedFeatureType::LineString, converted);
|
||||
}
|
||||
|
||||
geojsonvt::ProjectedFeature operator()(const Polygon<double>& polygon) const {
|
||||
geojsonvt::ProjectedRings converted;
|
||||
for (const auto& ring : polygon) {
|
||||
converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::Polygon, ring));
|
||||
}
|
||||
return convertFeature(geojsonvt::ProjectedFeatureType::Polygon, converted);
|
||||
}
|
||||
|
||||
geojsonvt::ProjectedFeature operator()(const MultiLineString<double>& lines) const {
|
||||
geojsonvt::ProjectedRings converted;
|
||||
for (const auto& line : lines) {
|
||||
converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::LineString, line));
|
||||
}
|
||||
return convertFeature(geojsonvt::ProjectedFeatureType::LineString, converted);
|
||||
}
|
||||
|
||||
geojsonvt::ProjectedFeature operator()(const MultiPolygon<double>& polygons) const {
|
||||
geojsonvt::ProjectedRings converted;
|
||||
for (const auto& polygon : polygons) {
|
||||
for (const auto& ring : polygon) {
|
||||
converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::Polygon, ring));
|
||||
}
|
||||
}
|
||||
return convertFeature(geojsonvt::ProjectedFeatureType::Polygon, converted);
|
||||
}
|
||||
|
||||
private:
|
||||
geojsonvt::LonLat convertPoint(const Point<double>& p) const {
|
||||
return {
|
||||
util::wrap(p.x, -util::LONGITUDE_MAX, util::LONGITUDE_MAX),
|
||||
util::clamp(p.y, -util::LATITUDE_MAX, util::LATITUDE_MAX)
|
||||
};
|
||||
}
|
||||
|
||||
geojsonvt::ProjectedRing convertPoints(geojsonvt::ProjectedFeatureType type, const std::vector<Point<double>>& points) const {
|
||||
std::vector<geojsonvt::LonLat> converted;
|
||||
|
||||
for (const auto& p : points) {
|
||||
converted.push_back(convertPoint(p));
|
||||
}
|
||||
|
||||
assert(points.size() > 0);
|
||||
if (type == geojsonvt::ProjectedFeatureType::Polygon && points.size() > 0 && points.front() != points.back()) {
|
||||
converted.push_back(converted.front());
|
||||
}
|
||||
|
||||
return geojsonvt::Convert::projectRing(converted, tolerance);
|
||||
}
|
||||
|
||||
geojsonvt::ProjectedFeature convertFeature(geojsonvt::ProjectedFeatureType type, const geojsonvt::ProjectedRings& rings) const {
|
||||
return geojsonvt::Convert::create(geojsonvt::Tags(), type, rings);
|
||||
}
|
||||
};
|
||||
|
||||
void ShapeAnnotationImpl::updateTileData(const CanonicalTileID& tileID, AnnotationTileData& data) {
|
||||
static const double baseTolerance = 4;
|
||||
|
||||
if (!shapeTiler) {
|
||||
const uint64_t maxAmountOfTileFeatures = (1ull << maxZoom) * util::EXTENT;
|
||||
const double tolerance = baseTolerance / maxAmountOfTileFeatures;
|
||||
|
||||
std::vector<geojsonvt::ProjectedFeature> features = {
|
||||
ShapeAnnotationGeometry::visit(geometry(), ToGeoJSONVT(tolerance))
|
||||
};
|
||||
|
||||
mapbox::geometry::feature_collection<double> features;
|
||||
features.emplace_back(ShapeAnnotationGeometry::visit(geometry(), [] (auto&& geom) {
|
||||
return Feature(std::move(geom));
|
||||
}));
|
||||
mapbox::geojsonvt::Options options;
|
||||
options.maxZoom = maxZoom;
|
||||
options.maxZoom = util::clamp<uint8_t>(maxZoom, 0, 18);
|
||||
options.buffer = 255u;
|
||||
options.extent = util::EXTENT;
|
||||
options.tolerance = baseTolerance;
|
||||
@@ -106,34 +35,20 @@ void ShapeAnnotationImpl::updateTileData(const CanonicalTileID& tileID, Annotati
|
||||
}
|
||||
|
||||
const auto& shapeTile = shapeTiler->getTile(tileID.z, tileID.x, tileID.y);
|
||||
if (!shapeTile)
|
||||
if (shapeTile.features.empty())
|
||||
return;
|
||||
|
||||
AnnotationTileLayer& layer = *data.layers.emplace(layerID,
|
||||
std::make_unique<AnnotationTileLayer>(layerID)).first->second;
|
||||
|
||||
for (auto& shapeFeature : shapeTile.features) {
|
||||
FeatureType featureType = FeatureType::Unknown;
|
||||
|
||||
if (shapeFeature.type == geojsonvt::TileFeatureType::LineString) {
|
||||
featureType = FeatureType::LineString;
|
||||
} else if (shapeFeature.type == geojsonvt::TileFeatureType::Polygon) {
|
||||
featureType = FeatureType::Polygon;
|
||||
}
|
||||
ToGeometryCollection toGeometryCollection;
|
||||
ToFeatureType toFeatureType;
|
||||
for (const auto& shapeFeature : shapeTile.features) {
|
||||
FeatureType featureType = apply_visitor(toFeatureType, shapeFeature.geometry);
|
||||
GeometryCollection renderGeometry = apply_visitor(toGeometryCollection, shapeFeature.geometry);
|
||||
|
||||
assert(featureType != FeatureType::Unknown);
|
||||
|
||||
GeometryCollection renderGeometry;
|
||||
for (auto& shapeRing : shapeFeature.tileGeometry.get<geojsonvt::TileRings>()) {
|
||||
GeometryCoordinates renderLine;
|
||||
|
||||
for (auto& shapePoint : shapeRing) {
|
||||
renderLine.emplace_back(shapePoint.x, shapePoint.y);
|
||||
}
|
||||
|
||||
renderGeometry.push_back(renderLine);
|
||||
}
|
||||
|
||||
// https://github.com/mapbox/geojson-vt-cpp/issues/44
|
||||
if (featureType == FeatureType::Polygon) {
|
||||
renderGeometry = fixupPolygons(renderGeometry);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <mapbox/geojsonvt.hpp>
|
||||
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
@@ -32,4 +33,33 @@ public:
|
||||
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> shapeTiler;
|
||||
};
|
||||
|
||||
struct CloseShapeAnnotation {
|
||||
ShapeAnnotationGeometry operator()(const mbgl::LineString<double> &geom) const {
|
||||
return geom;
|
||||
}
|
||||
ShapeAnnotationGeometry operator()(const mbgl::MultiLineString<double> &geom) const {
|
||||
return geom;
|
||||
}
|
||||
ShapeAnnotationGeometry operator()(const mbgl::Polygon<double> &geom) const {
|
||||
mbgl::Polygon<double> closed = geom;
|
||||
for (auto &ring : closed) {
|
||||
if (!ring.empty() && ring.front() != ring.back()) {
|
||||
ring.emplace_back(ring.front());
|
||||
}
|
||||
}
|
||||
return closed;
|
||||
}
|
||||
ShapeAnnotationGeometry operator()(const mbgl::MultiPolygon<double> &geom) const {
|
||||
mbgl::MultiPolygon<double> closed = geom;
|
||||
for (auto &polygon : closed) {
|
||||
for (auto &ring : polygon) {
|
||||
if (!ring.empty() && ring.front() != ring.back()) {
|
||||
ring.emplace_back(ring.front());
|
||||
}
|
||||
}
|
||||
}
|
||||
return closed;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/util/rapidjson.hpp>
|
||||
|
||||
#include <mapbox/geojson.hpp>
|
||||
#include <mapbox/geojson/rapidjson.hpp>
|
||||
#include <mapbox/geojsonvt.hpp>
|
||||
#include <mapbox/geojsonvt/convert.hpp>
|
||||
|
||||
@@ -18,6 +20,7 @@ using namespace mapbox::geojsonvt;
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
Result<GeoJSON> convertGeoJSON(const JSValue& value) {
|
||||
Options options;
|
||||
@@ -25,7 +28,8 @@ Result<GeoJSON> convertGeoJSON(const JSValue& value) {
|
||||
options.extent = util::EXTENT;
|
||||
|
||||
try {
|
||||
return GeoJSON { std::make_unique<GeoJSONVT>(Convert::convert(value, 0), options) };
|
||||
const auto geojson = mapbox::geojson::convert(value);
|
||||
return GeoJSON { std::make_unique<GeoJSONVT>(geojson, options) };
|
||||
} catch (const std::exception& ex) {
|
||||
return Error { ex.what() };
|
||||
}
|
||||
@@ -82,7 +86,8 @@ void GeoJSONSource::Impl::load(FileSource& fileSource) {
|
||||
Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", geoJSON.error().message);
|
||||
// Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
|
||||
// tiles to load.
|
||||
urlOrGeoJSON = GeoJSON { std::make_unique<GeoJSONVT>(std::vector<ProjectedFeature>()) };
|
||||
mapbox::geojson::feature_collection features;
|
||||
urlOrGeoJSON = GeoJSON { std::make_unique<GeoJSONVT>(features) };
|
||||
} else {
|
||||
urlOrGeoJSON = std::move(*geoJSON);
|
||||
}
|
||||
|
||||
@@ -11,16 +11,16 @@ namespace mbgl {
|
||||
|
||||
class GeoJSONTileFeature : public GeometryTileFeature {
|
||||
public:
|
||||
GeoJSONTileFeature(FeatureType, GeometryCollection&&, Feature::property_map&&);
|
||||
GeoJSONTileFeature(FeatureType, GeometryCollection&&, PropertyMap&&);
|
||||
FeatureType getType() const override;
|
||||
optional<Value> getValue(const std::string&) const override;
|
||||
Feature::property_map getProperties() const override { return properties; }
|
||||
PropertyMap getProperties() const override { return properties; }
|
||||
GeometryCollection getGeometries() const override;
|
||||
|
||||
private:
|
||||
const FeatureType type;
|
||||
const GeometryCollection geometries;
|
||||
const Feature::property_map properties;
|
||||
const PropertyMap properties;
|
||||
};
|
||||
|
||||
class GeoJSONTileLayer : public GeometryTileLayer {
|
||||
@@ -49,52 +49,28 @@ private:
|
||||
std::unique_ptr<GeoJSONTileData> convertTile(const mapbox::geojsonvt::Tile& tile) {
|
||||
std::shared_ptr<GeoJSONTileLayer> layer;
|
||||
|
||||
if (tile) {
|
||||
if (!tile.features.empty()) {
|
||||
std::vector<std::shared_ptr<const GeoJSONTileFeature>> features;
|
||||
GeometryCoordinates line;
|
||||
|
||||
ToFeatureType toFeatureType;
|
||||
ToGeometryCollection toGeometryCollection;
|
||||
|
||||
for (auto& feature : tile.features) {
|
||||
const FeatureType featureType =
|
||||
(feature.type == mapbox::geojsonvt::TileFeatureType::Point
|
||||
? FeatureType::Point
|
||||
: (feature.type == mapbox::geojsonvt::TileFeatureType::LineString
|
||||
? FeatureType::LineString
|
||||
: (feature.type == mapbox::geojsonvt::TileFeatureType::Polygon
|
||||
? FeatureType::Polygon
|
||||
: FeatureType::Unknown)));
|
||||
const FeatureType featureType = apply_visitor(toFeatureType, feature.geometry);
|
||||
|
||||
if (featureType == FeatureType::Unknown) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GeometryCollection geometry;
|
||||
|
||||
// Flatten the geometry; GeoJSONVT distinguishes between a Points array and Rings array
|
||||
// (Points = GeoJSON types Point, MultiPoint, LineString)
|
||||
// (Rings = GeoJSON types MultiLineString, Polygon, MultiPolygon)
|
||||
// However, in Mapbox GL, we use one structure for both types, and just have one outer
|
||||
// element for Points.
|
||||
if (feature.tileGeometry.is<mapbox::geojsonvt::TilePoints>()) {
|
||||
line.clear();
|
||||
for (auto& point : feature.tileGeometry.get<mapbox::geojsonvt::TilePoints>()) {
|
||||
line.emplace_back(point.x, point.y);
|
||||
}
|
||||
geometry.emplace_back(std::move(line));
|
||||
} else if (feature.tileGeometry.is<mapbox::geojsonvt::TileRings>()) {
|
||||
for (auto& ring : feature.tileGeometry.get<mapbox::geojsonvt::TileRings>()) {
|
||||
line.clear();
|
||||
for (auto& point : ring) {
|
||||
line.emplace_back(point.x, point.y);
|
||||
}
|
||||
geometry.emplace_back(std::move(line));
|
||||
}
|
||||
}
|
||||
GeometryCollection geometry = apply_visitor(toGeometryCollection, feature.geometry);
|
||||
|
||||
// https://github.com/mapbox/geojson-vt-cpp/issues/44
|
||||
if (featureType == FeatureType::Polygon) {
|
||||
geometry = fixupPolygons(geometry);
|
||||
}
|
||||
|
||||
Feature::property_map properties{ feature.tags.begin(), feature.tags.end() };
|
||||
PropertyMap properties = feature.properties;
|
||||
|
||||
features.emplace_back(std::make_shared<GeoJSONTileFeature>(
|
||||
featureType, std::move(geometry), std::move(properties)));
|
||||
@@ -118,7 +94,7 @@ void GeoJSONTile::setNecessity(Necessity) {}
|
||||
|
||||
GeoJSONTileFeature::GeoJSONTileFeature(FeatureType type_,
|
||||
GeometryCollection&& geometries_,
|
||||
Feature::property_map&& properties_)
|
||||
PropertyMap&& properties_)
|
||||
: type(type_), geometries(std::move(geometries_)), properties(std::move(properties_)) {
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -41,8 +42,8 @@ public:
|
||||
virtual ~GeometryTileFeature() = default;
|
||||
virtual FeatureType getType() const = 0;
|
||||
virtual optional<Value> getValue(const std::string& key) const = 0;
|
||||
virtual Feature::property_map getProperties() const { return Feature::property_map(); }
|
||||
virtual optional<uint64_t> getID() const { return {}; }
|
||||
virtual PropertyMap getProperties() const { return PropertyMap(); }
|
||||
virtual optional<FeatureIdentifier> getID() const { return {}; }
|
||||
virtual GeometryCollection getGeometries() const = 0;
|
||||
};
|
||||
|
||||
@@ -73,4 +74,70 @@ Feature convertFeature(const GeometryTileFeature&, const CanonicalTileID&);
|
||||
// The result is guaranteed to have correctly wound, strictly simple rings.
|
||||
GeometryCollection fixupPolygons(const GeometryCollection&);
|
||||
|
||||
struct ToGeometryCollection {
|
||||
GeometryCollection operator()(const mapbox::geometry::point<int16_t>& geom) const {
|
||||
return { { geom } };
|
||||
}
|
||||
GeometryCollection operator()(const mapbox::geometry::multi_point<int16_t>& geom) const {
|
||||
GeometryCoordinates coordinates;
|
||||
coordinates.reserve(geom.size());
|
||||
for (const auto& point : geom) {
|
||||
coordinates.emplace_back(point);
|
||||
}
|
||||
return { coordinates };
|
||||
}
|
||||
GeometryCollection operator()(const mapbox::geometry::line_string<int16_t>& geom) const {
|
||||
GeometryCoordinates coordinates;
|
||||
coordinates.reserve(geom.size());
|
||||
for (const auto& point : geom) {
|
||||
coordinates.emplace_back(point);
|
||||
}
|
||||
return { coordinates };
|
||||
}
|
||||
GeometryCollection operator()(const mapbox::geometry::multi_line_string<int16_t>& geom) const {
|
||||
GeometryCollection collection;
|
||||
collection.reserve(geom.size());
|
||||
for (const auto& ring : geom) {
|
||||
GeometryCoordinates coordinates;
|
||||
coordinates.reserve(ring.size());
|
||||
for (const auto& point : ring) {
|
||||
coordinates.emplace_back(point);
|
||||
}
|
||||
collection.push_back(std::move(coordinates));
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
GeometryCollection operator()(const mapbox::geometry::polygon<int16_t>& geom) const {
|
||||
GeometryCollection collection;
|
||||
collection.reserve(geom.size());
|
||||
for (const auto& ring : geom) {
|
||||
GeometryCoordinates coordinates;
|
||||
coordinates.reserve(ring.size());
|
||||
for (const auto& point : ring) {
|
||||
coordinates.emplace_back(point);
|
||||
}
|
||||
collection.push_back(std::move(coordinates));
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
GeometryCollection operator()(const mapbox::geometry::multi_polygon<int16_t>& geom) const {
|
||||
GeometryCollection collection;
|
||||
for (auto& polygon : geom) {
|
||||
for (auto& ring : polygon) {
|
||||
GeometryCoordinates coordinates;
|
||||
coordinates.reserve(ring.size());
|
||||
for (auto& point : ring) {
|
||||
coordinates.emplace_back(point);
|
||||
}
|
||||
collection.push_back(std::move(coordinates));
|
||||
}
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
GeometryCollection operator()(const mapbox::geometry::geometry_collection<int16_t>&) const {
|
||||
GeometryCollection collection;
|
||||
return collection;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -24,12 +24,12 @@ public:
|
||||
FeatureType getType() const override { return type; }
|
||||
optional<Value> getValue(const std::string&) const override;
|
||||
std::unordered_map<std::string,Value> getProperties() const override;
|
||||
optional<uint64_t> getID() const override;
|
||||
optional<FeatureIdentifier> getID() const override;
|
||||
GeometryCollection getGeometries() const override;
|
||||
|
||||
private:
|
||||
const VectorTileLayer& layer;
|
||||
optional<uint64_t> id;
|
||||
optional<FeatureIdentifier> id;
|
||||
FeatureType type = FeatureType::Unknown;
|
||||
packed_iter_type tags_iter;
|
||||
packed_iter_type geometry_iter;
|
||||
@@ -120,7 +120,7 @@ VectorTileFeature::VectorTileFeature(protozero::pbf_reader feature_pbf, const Ve
|
||||
while (feature_pbf.next()) {
|
||||
switch (feature_pbf.tag()) {
|
||||
case 1: // id
|
||||
id = feature_pbf.get_uint64();
|
||||
id = { feature_pbf.get_uint64() };
|
||||
break;
|
||||
case 2: // tags
|
||||
tags_iter = feature_pbf.get_packed_uint32();
|
||||
@@ -185,7 +185,7 @@ std::unordered_map<std::string,Value> VectorTileFeature::getProperties() const {
|
||||
return properties;
|
||||
}
|
||||
|
||||
optional<uint64_t> VectorTileFeature::getID() const {
|
||||
optional<FeatureIdentifier> VectorTileFeature::getID() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"sources": {
|
||||
"mapbox": {
|
||||
"type": "geojson",
|
||||
"data": { "type": "Feature", "geometry": { "type": "Point", "coordinates": [100.0, 0.0] } }
|
||||
"data": { "type": "Feature", "geometry": { "type": "Point", "coordinates": [100.0, 0.0] }, "properties": {} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,20 +8,16 @@
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mbgl::style;
|
||||
|
||||
typedef std::multimap<std::string, mbgl::Value> Properties;
|
||||
|
||||
Filter parse(const char * expression) {
|
||||
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> doc;
|
||||
doc.Parse<0>(expression);
|
||||
return *conversion::convert<Filter>(doc);
|
||||
}
|
||||
|
||||
bool evaluate(const Filter& filter, const Properties& properties, FeatureType type = FeatureType::Unknown) {
|
||||
bool evaluate(const Filter& filter, const PropertyMap& properties, FeatureType type = FeatureType::Unknown) {
|
||||
return filter(type, [&] (const std::string& key) -> optional<Value> {
|
||||
auto it = properties.find(key);
|
||||
if (it == properties.end())
|
||||
@@ -47,6 +43,7 @@ TEST(Filter, EqualsNumber) {
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", std::string("0") }}));
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", false }}));
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", true }}));
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", nullptr }}));
|
||||
ASSERT_FALSE(evaluate(f, {{}}));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user