summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorVladimir Agafonkin <agafonkin@gmail.com>2016-07-27 20:18:41 +0300
committerGitHub <noreply@github.com>2016-07-27 20:18:41 +0300
commit9ecc0d95979ca2fa3154f4b47c8f9fa4717fe696 (patch)
treeb5e09683505cec994e3198a92cd8863d54979e3e /include
parent6edaf2dc81ab771d1da27c939b19502753aa895f (diff)
downloadqtlocation-mapboxgl-9ecc0d95979ca2fa3154f4b47c8f9fa4717fe696.tar.gz
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
Diffstat (limited to 'include')
-rw-r--r--include/mbgl/style/conversion/source.hpp89
-rw-r--r--include/mbgl/style/sources/geojson_source.hpp35
-rw-r--r--include/mbgl/util/geojson.hpp18
3 files changed, 110 insertions, 32 deletions
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 <mbgl/style/conversion.hpp>
+#include <mbgl/style/conversion/geojson.hpp>
+#include <mbgl/style/conversion/tileset.hpp>
#include <mbgl/style/source.hpp>
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/raster_source.hpp>
#include <mbgl/style/sources/vector_source.hpp>
-#include <mbgl/style/conversion.hpp>
-#include <mbgl/style/conversion/tileset.hpp>
-#include <mbgl/style/conversion/geojson.hpp>
namespace mbgl {
namespace style {
@@ -18,17 +18,17 @@ public:
template <class V>
Result<std::unique_ptr<Source>> 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<std::string> 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<std::string> url = toString(*urlVal);
if (!url) {
- return Error { "source url must be a string" };
+ return Error{ "source url must be a string" };
}
return *url;
}
template <class V>
- Result<std::unique_ptr<Source>> convertRasterSource(const std::string& id, const V& value) const {
+ Result<std::unique_ptr<Source>> convertRasterSource(const std::string& id,
+ const V& value) const {
Result<variant<std::string, Tileset>> urlOrTileset = convertURLOrTileset(value);
if (!urlOrTileset) {
return urlOrTileset.error();
@@ -75,7 +76,7 @@ private:
if (tileSizeValue) {
optional<float> size = toNumber(*tileSizeValue);
if (!size || *size < 0 || *size > std::numeric_limits<uint16_t>::max()) {
- return Error { "invalid tileSize" };
+ return Error{ "invalid tileSize" };
}
tileSize = *size;
}
@@ -84,7 +85,8 @@ private:
}
template <class V>
- Result<std::unique_ptr<Source>> convertVectorSource(const std::string& id, const V& value) const {
+ Result<std::unique_ptr<Source>> convertVectorSource(const std::string& id,
+ const V& value) const {
Result<variant<std::string, Tileset>> urlOrTileset = convertURLOrTileset(value);
if (!urlOrTileset) {
return urlOrTileset.error();
@@ -94,13 +96,70 @@ private:
}
template <class V>
- Result<std::unique_ptr<Source>> convertGeoJSONSource(const std::string& id, const V& value) const {
+ Result<std::unique_ptr<Source>> 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<uint8_t>(*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<uint16_t>(*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<double>(*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<uint8_t>(*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<double>(*toNumber(*clusterRadiusValue));
+ } else {
+ return Error{ "GeoJSON source clusterRadius value must be a number" };
+ }
}
- auto result = std::make_unique<GeoJSONSource>(id);
+ auto result = std::make_unique<GeoJSONSource>(id, options);
if (isObject(*dataValue)) {
Result<GeoJSON> 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);
diff --git a/include/mbgl/style/sources/geojson_source.hpp b/include/mbgl/style/sources/geojson_source.hpp
index 3736dd44bc..37ddce1bcc 100644
--- a/include/mbgl/style/sources/geojson_source.hpp
+++ b/include/mbgl/style/sources/geojson_source.hpp
@@ -3,15 +3,46 @@
#include <mbgl/style/source.hpp>
#include <mbgl/util/geojson.hpp>
+#include <mapbox/geojson.hpp>
+
+namespace mapbox {
+
+namespace geojsonvt {
+class GeoJSONVT;
+} // namespace geojsonvt
+
+namespace supercluster {
+class Supercluster;
+} // namespace supercluster
+
+} // namespace mapbox
+
namespace mbgl {
namespace style {
+using GeoJSONVTPointer = std::unique_ptr<mapbox::geojsonvt::GeoJSONVT>;
+using SuperclusterPointer = std::unique_ptr<mapbox::supercluster::Supercluster>;
+
+struct GeoJSONOptions {
+ // GeoJSON-VT options
+ uint8_t maxzoom = 18;
+ uint16_t buffer = 128;
+ double tolerance = 0.375;
+
+ // Supercluster options
+ bool cluster = false;
+ uint16_t clusterRadius = 50;
+ uint8_t clusterMaxZoom = 17;
+};
+
class GeoJSONSource : public Source {
public:
- GeoJSONSource(const std::string& id);
+ GeoJSONSource(const std::string& id, const GeoJSONOptions options_ = GeoJSONOptions());
void setURL(const std::string& url);
- void setGeoJSON(GeoJSON&&);
+ void setGeoJSON(const GeoJSON&);
+
+ std::string getURL();
// Private implementation
diff --git a/include/mbgl/util/geojson.hpp b/include/mbgl/util/geojson.hpp
index 3fd8c6ac4b..b4e789a3ac 100644
--- a/include/mbgl/util/geojson.hpp
+++ b/include/mbgl/util/geojson.hpp
@@ -1,22 +1,10 @@
#pragma once
-#include <memory>
-
-namespace mapbox {
-namespace geojsonvt {
-class GeoJSONVT;
-} // namespace geojsonvt
-} // namespace mapbox
+#include <mapbox/geojson.hpp>
namespace mbgl {
-class GeoJSON {
-public:
- GeoJSON(std::unique_ptr<mapbox::geojsonvt::GeoJSONVT>);
- GeoJSON(GeoJSON&&);
- ~GeoJSON();
-
- std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> impl;
-};
+using GeoJSON = mapbox::geojson::geojson;
+using FeatureCollection = mapbox::geojson::feature_collection;
} // namespace mbgl