From 9ecc0d95979ca2fa3154f4b47c8f9fa4717fe696 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Wed, 27 Jul 2016 20:18:41 +0300 Subject: GeoJSON point clustering (#5724) * add supercluster dependency * prepare GeoJSONTile for Supercluster * prepare GeoJSONSource for accepting options * try removing mbgl::GeoJSON * fix setGeoJSON types * add GeoJSONSource getURL * add geojson to include path * add Supercluster index in GeoJSONSource * fix GeoJSONSource getZoomRange * bring back mbgl::GeoJSON header * fix tidy warnings hopefully * try test-suite with enabled cluster test * fix formatting in clustering-related files --- include/mbgl/style/conversion/source.hpp | 89 ++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 15 deletions(-) (limited to 'include/mbgl/style/conversion') diff --git a/include/mbgl/style/conversion/source.hpp b/include/mbgl/style/conversion/source.hpp index 00c6afb9fe..c4b2fe303f 100644 --- a/include/mbgl/style/conversion/source.hpp +++ b/include/mbgl/style/conversion/source.hpp @@ -1,12 +1,12 @@ #pragma once +#include +#include +#include #include #include #include #include -#include -#include -#include namespace mbgl { namespace style { @@ -18,17 +18,17 @@ public: template Result> operator()(const V& value, const std::string& id) const { if (!isObject(value)) { - return Error { "source must be an object" }; + return Error{ "source must be an object" }; } auto typeValue = objectMember(value, "type"); if (!typeValue) { - return Error { "source must have a type" }; + return Error{ "source must have a type" }; } optional type = toString(*typeValue); if (!type) { - return Error { "source type must be a string" }; + return Error{ "source type must be a string" }; } if (*type == "raster") { @@ -38,7 +38,7 @@ public: } else if (*type == "geojson") { return convertGeoJSONSource(id, value); } else { - return Error { "invalid source type" }; + return Error{ "invalid source type" }; } } @@ -57,14 +57,15 @@ private: optional url = toString(*urlVal); if (!url) { - return Error { "source url must be a string" }; + return Error{ "source url must be a string" }; } return *url; } template - Result> convertRasterSource(const std::string& id, const V& value) const { + Result> convertRasterSource(const std::string& id, + const V& value) const { Result> urlOrTileset = convertURLOrTileset(value); if (!urlOrTileset) { return urlOrTileset.error(); @@ -75,7 +76,7 @@ private: if (tileSizeValue) { optional size = toNumber(*tileSizeValue); if (!size || *size < 0 || *size > std::numeric_limits::max()) { - return Error { "invalid tileSize" }; + return Error{ "invalid tileSize" }; } tileSize = *size; } @@ -84,7 +85,8 @@ private: } template - Result> convertVectorSource(const std::string& id, const V& value) const { + Result> convertVectorSource(const std::string& id, + const V& value) const { Result> urlOrTileset = convertURLOrTileset(value); if (!urlOrTileset) { return urlOrTileset.error(); @@ -94,13 +96,70 @@ private: } template - Result> convertGeoJSONSource(const std::string& id, const V& value) const { + Result> convertGeoJSONSource(const std::string& id, + const V& value) const { auto dataValue = objectMember(value, "data"); if (!dataValue) { - return Error { "GeoJSON source must have a data value" }; + return Error{ "GeoJSON source must have a data value" }; + } + + GeoJSONOptions options; + + const auto maxzoomValue = objectMember(value, "maxzoom"); + if (maxzoomValue) { + if (toNumber(*maxzoomValue)) { + options.maxzoom = static_cast(*toNumber(*maxzoomValue)); + } else { + return Error{ "GeoJSON source maxzoom value must be a number" }; + } + } + + const auto bufferValue = objectMember(value, "buffer"); + if (bufferValue) { + if (toNumber(*bufferValue)) { + options.buffer = static_cast(*toNumber(*bufferValue)); + } else { + return Error{ "GeoJSON source buffer value must be a number" }; + } + } + + const auto toleranceValue = objectMember(value, "tolerance"); + if (toleranceValue) { + if (toNumber(*toleranceValue)) { + options.tolerance = static_cast(*toNumber(*toleranceValue)); + } else { + return Error{ "GeoJSON source tolerance value must be a number" }; + } + } + + const auto clusterValue = objectMember(value, "cluster"); + if (clusterValue) { + if (toBool(*clusterValue)) { + options.cluster = *toBool(*clusterValue); + } else { + return Error{ "GeoJSON source cluster value must be a boolean" }; + } + } + + const auto clusterMaxZoomValue = objectMember(value, "clusterMaxZoom"); + if (clusterMaxZoomValue) { + if (toNumber(*clusterMaxZoomValue)) { + options.clusterMaxZoom = static_cast(*toNumber(*clusterMaxZoomValue)); + } else { + return Error{ "GeoJSON source clusterMaxZoom value must be a number" }; + } + } + + const auto clusterRadiusValue = objectMember(value, "clusterRadius"); + if (clusterRadiusValue) { + if (toNumber(*clusterRadiusValue)) { + options.clusterRadius = static_cast(*toNumber(*clusterRadiusValue)); + } else { + return Error{ "GeoJSON source clusterRadius value must be a number" }; + } } - auto result = std::make_unique(id); + auto result = std::make_unique(id, options); if (isObject(*dataValue)) { Result geoJSON = convertGeoJSON(*dataValue); @@ -111,7 +170,7 @@ private: } else if (toString(*dataValue)) { result->setURL(*toString(*dataValue)); } else { - return Error { "GeoJSON data must be a URL or an object" }; + return Error{ "GeoJSON data must be a URL or an object" }; } return std::move(result); -- cgit v1.2.1