diff options
author | Jesse Crocker <jesse@gaiagps.com> | 2017-09-11 15:10:17 -0700 |
---|---|---|
committer | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-10-10 16:51:48 -0700 |
commit | 08df6ebca0adbea5589545d96d2a9e94feeb148f (patch) | |
tree | b4015b77584d81912c6c3de61d1de07b76e38533 | |
parent | 9e79659007131450cde7e6e1a361f8ba3321fe98 (diff) | |
download | qtlocation-mapboxgl-08df6ebca0adbea5589545d96d2a9e94feeb148f.tar.gz |
[core] Custom Vector Sources
-rw-r--r-- | cmake/core-files.cmake | 6 | ||||
-rw-r--r-- | cmake/test-files.cmake | 1 | ||||
-rw-r--r-- | include/mbgl/style/sources/custom_vector_source.hpp | 40 | ||||
-rw-r--r-- | include/mbgl/style/sources/geojson_source.hpp | 2 | ||||
-rw-r--r-- | include/mbgl/style/types.hpp | 3 | ||||
-rw-r--r-- | platform/default/mbgl/storage/offline_download.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/render_source.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_custom_vector_source.cpp | 118 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_custom_vector_source.hpp | 51 | ||||
-rw-r--r-- | src/mbgl/style/sources/custom_vector_source.cpp | 18 | ||||
-rw-r--r-- | src/mbgl/style/sources/custom_vector_source_impl.cpp | 32 | ||||
-rw-r--r-- | src/mbgl/style/sources/custom_vector_source_impl.hpp | 27 | ||||
-rw-r--r-- | src/mbgl/style/types.cpp | 1 | ||||
-rw-r--r-- | test/style/custom_vector_source.test.cpp | 12 |
14 files changed, 315 insertions, 1 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 2eadc747d1..18d07cd20e 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -243,6 +243,8 @@ set(MBGL_CORE_FILES src/mbgl/renderer/layers/render_symbol_layer.hpp # renderer/sources + src/mbgl/renderer/sources/render_custom_vector_source.cpp + src/mbgl/renderer/sources/render_custom_vector_source.hpp src/mbgl/renderer/sources/render_geojson_source.cpp src/mbgl/renderer/sources/render_geojson_source.hpp src/mbgl/renderer/sources/render_image_source.cpp @@ -444,10 +446,14 @@ set(MBGL_CORE_FILES src/mbgl/style/layers/symbol_layer_properties.hpp # style/sources + include/mbgl/style/sources/custom_vector_source.hpp include/mbgl/style/sources/geojson_source.hpp include/mbgl/style/sources/image_source.hpp include/mbgl/style/sources/raster_source.hpp include/mbgl/style/sources/vector_source.hpp + src/mbgl/style/sources/custom_vector_source.cpp + src/mbgl/style/sources/custom_vector_source_impl.cpp + src/mbgl/style/sources/custom_vector_source_impl.hpp src/mbgl/style/sources/geojson_source.cpp src/mbgl/style/sources/geojson_source_impl.cpp src/mbgl/style/sources/geojson_source_impl.hpp diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake index 027c34f31e..39b619a6ac 100644 --- a/cmake/test-files.cmake +++ b/cmake/test-files.cmake @@ -89,6 +89,7 @@ set(MBGL_TEST_FILES test/style/conversion/stringify.test.cpp # style + test/style/custom_vector_source.test.cpp test/style/filter.test.cpp # style/function diff --git a/include/mbgl/style/sources/custom_vector_source.hpp b/include/mbgl/style/sources/custom_vector_source.hpp new file mode 100644 index 0000000000..a256c8e7f7 --- /dev/null +++ b/include/mbgl/style/sources/custom_vector_source.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include <mbgl/style/source.hpp> +#include <mbgl/style/sources/geojson_source.hpp> +#include <mbgl/util/geo.hpp> +#include <mbgl/util/geojson.hpp> +#include <mbgl/util/variant.hpp> + +namespace mbgl { +namespace style { + +struct Error { std::string message; }; + +using FetchTileResult = variant< + mapbox::geojson::geojson, + Error>; + +using FetchTileCallback = std::function<void(const CanonicalTileID& tileID, const FetchTileResult&)>; +using FetchTileFunction = std::function<void(const CanonicalTileID&, FetchTileCallback)>; + +class CustomVectorSource : public Source { +public: + CustomVectorSource(std::string id, + GeoJSONOptions options, + FetchTileFunction fetchTile); + + void loadDescription(FileSource&) final; + + // Private implementation + class Impl; + const Impl& impl() const; +}; + +template <> +inline bool Source::is<CustomVectorSource>() const { + return getType() == SourceType::CustomVector; +} + +} // namespace style +} // namespace mbgl diff --git a/include/mbgl/style/sources/geojson_source.hpp b/include/mbgl/style/sources/geojson_source.hpp index 5bdf1ef957..372e7c7a78 100644 --- a/include/mbgl/style/sources/geojson_source.hpp +++ b/include/mbgl/style/sources/geojson_source.hpp @@ -3,6 +3,7 @@ #include <mbgl/style/source.hpp> #include <mbgl/util/geojson.hpp> #include <mbgl/util/optional.hpp> +#include <mbgl/util/constants.hpp> namespace mbgl { @@ -14,6 +15,7 @@ struct GeoJSONOptions { // GeoJSON-VT options uint8_t minzoom = 0; uint8_t maxzoom = 18; + uint16_t tileSize = util::tileSize; uint16_t buffer = 128; double tolerance = 0.375; diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp index ec7358de8c..346219d7dc 100644 --- a/include/mbgl/style/types.hpp +++ b/include/mbgl/style/types.hpp @@ -11,7 +11,8 @@ enum class SourceType : uint8_t { GeoJSON, Video, Annotations, - Image + Image, + CustomVector }; namespace style { diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp index ff61114888..8bb16993a5 100644 --- a/platform/default/mbgl/storage/offline_download.cpp +++ b/platform/default/mbgl/storage/offline_download.cpp @@ -129,6 +129,7 @@ OfflineRegionStatus OfflineDownload::getStatus() const { case SourceType::Video: case SourceType::Annotations: + case SourceType::CustomVector: break; } } @@ -214,6 +215,7 @@ void OfflineDownload::activateDownload() { case SourceType::Video: case SourceType::Annotations: + case SourceType::CustomVector: break; } } diff --git a/src/mbgl/renderer/render_source.cpp b/src/mbgl/renderer/render_source.cpp index 7723a1c7ca..8c5abfb32d 100644 --- a/src/mbgl/renderer/render_source.cpp +++ b/src/mbgl/renderer/render_source.cpp @@ -6,6 +6,7 @@ #include <mbgl/renderer/tile_parameters.hpp> #include <mbgl/annotation/render_annotation_source.hpp> #include <mbgl/renderer/sources/render_image_source.hpp> +#include <mbgl/renderer/sources/render_custom_vector_source.hpp> #include <mbgl/tile/tile.hpp> namespace mbgl { @@ -27,6 +28,8 @@ std::unique_ptr<RenderSource> RenderSource::create(Immutable<Source::Impl> impl) return std::make_unique<RenderAnnotationSource>(staticImmutableCast<AnnotationSource::Impl>(impl)); case SourceType::Image: return std::make_unique<RenderImageSource>(staticImmutableCast<ImageSource::Impl>(impl)); + case SourceType::CustomVector: + return std::make_unique<RenderCustomVectorSource>(staticImmutableCast<CustomVectorSource::Impl>(impl)); } // Not reachable, but placate GCC. diff --git a/src/mbgl/renderer/sources/render_custom_vector_source.cpp b/src/mbgl/renderer/sources/render_custom_vector_source.cpp new file mode 100644 index 0000000000..b6c27bb00c --- /dev/null +++ b/src/mbgl/renderer/sources/render_custom_vector_source.cpp @@ -0,0 +1,118 @@ +#include <mbgl/renderer/sources/render_custom_vector_source.hpp> +#include <mbgl/renderer/render_tile.hpp> +#include <mbgl/renderer/paint_parameters.hpp> +#include <mbgl/tile/geojson_tile.hpp> +#include <mbgl/util/logging.hpp> + +#include <mbgl/algorithm/generate_clip_ids.hpp> +#include <mbgl/algorithm/generate_clip_ids_impl.hpp> + +#include <mapbox/geojsonvt.hpp> + +namespace mbgl { + +using namespace style; + +RenderCustomVectorSource::RenderCustomVectorSource(Immutable<style::CustomVectorSource::Impl> impl_) + : RenderSource(impl_) { + tilePyramid.setObserver(this); +} + +const style::CustomVectorSource::Impl& RenderCustomVectorSource::impl() const { + return static_cast<const style::CustomVectorSource::Impl&>(*baseImpl); +} + +bool RenderCustomVectorSource::isLoaded() const { + return tilePyramid.isLoaded(); +} + +void RenderCustomVectorSource::setTileData(const CanonicalTileID& tileID, + const style::FetchTileResult& result) { + if (result.is<style::Error>()) { + Log::Error(Event::Render, "FetchTile (%d, %d, %d) error: %s", tileID.z, tileID.x, tileID.y, result.get<style::Error>().message.c_str()); + return; + } + + auto geoJSON = result.get<mapbox::geojson::geojson>(); + auto data = mapbox::geometry::feature_collection<int16_t>(); + if (geoJSON.is<FeatureCollection>() && !geoJSON.get<FeatureCollection>().empty()) { + const GeoJSONOptions options = impl().getOptions(); + + const double scale = util::EXTENT / options.tileSize; + + mapbox::geojsonvt::Options vtOptions; + vtOptions.maxZoom = options.maxzoom; + vtOptions.extent = util::EXTENT; + vtOptions.buffer = std::round(scale * options.buffer); + vtOptions.tolerance = scale * options.tolerance; + auto geojsonVt = std::make_unique<mapbox::geojsonvt::GeoJSONVT>(geoJSON, vtOptions); + data = geojsonVt->getTile(tileID.z, tileID.x, tileID.y).features; + } + for (auto const& item : tilePyramid.tiles) { + if (item.first.canonical == tileID) { + static_cast<GeoJSONTile*>(item.second.get())->updateData(data); + } + } +} + +void RenderCustomVectorSource::update(Immutable<style::Source::Impl> baseImpl_, + const std::vector<Immutable<Layer::Impl>>& layers, + const bool needsRendering, + const bool needsRelayout, + const TileParameters& parameters) { + std::swap(baseImpl, baseImpl_); + + enabled = needsRendering; + + auto fetchTile = impl().getFetchTileFunction(); + + FetchTileCallback fetchTileCallback = std::bind(&RenderCustomVectorSource::setTileData, this, std::placeholders::_1, std::placeholders::_2); + + const GeoJSONOptions options = impl().getOptions(); + tilePyramid.update(layers, + needsRendering, + needsRelayout, + parameters, + SourceType::CustomVector, + util::tileSize, + { options.minzoom, options.maxzoom }, + [&] (const OverscaledTileID& tileID) { + fetchTile(tileID.canonical, fetchTileCallback); + return std::make_unique<GeoJSONTile>(tileID, impl().id, parameters, mapbox::geometry::feature_collection<int16_t>()); + }); +} + +void RenderCustomVectorSource::startRender(PaintParameters& parameters) { + parameters.clipIDGenerator.update(tilePyramid.getRenderTiles()); + tilePyramid.startRender(parameters); +} + +void RenderCustomVectorSource::finishRender(PaintParameters& parameters) { + tilePyramid.finishRender(parameters); +} + +std::vector<std::reference_wrapper<RenderTile>> RenderCustomVectorSource::getRenderTiles() { + return tilePyramid.getRenderTiles(); +} + +std::unordered_map<std::string, std::vector<Feature>> +RenderCustomVectorSource::queryRenderedFeatures(const ScreenLineString& geometry, + const TransformState& transformState, + const std::vector<const RenderLayer*>& layers, + const RenderedQueryOptions& options) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options); +} + +std::vector<Feature> RenderCustomVectorSource::querySourceFeatures(const SourceQueryOptions& options) const { + return tilePyramid.querySourceFeatures(options); +} + +void RenderCustomVectorSource::onLowMemory() { + tilePyramid.onLowMemory(); +} + +void RenderCustomVectorSource::dumpDebugLogs() const { + tilePyramid.dumpDebugLogs(); +} + +} // namespace mbgl diff --git a/src/mbgl/renderer/sources/render_custom_vector_source.hpp b/src/mbgl/renderer/sources/render_custom_vector_source.hpp new file mode 100644 index 0000000000..43e5094cc1 --- /dev/null +++ b/src/mbgl/renderer/sources/render_custom_vector_source.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include <mbgl/renderer/render_source.hpp> +#include <mbgl/renderer/tile_pyramid.hpp> +#include <mbgl/style/sources/custom_vector_source_impl.hpp> + +namespace mbgl { + +class RenderCustomVectorSource : public RenderSource { +public: + RenderCustomVectorSource(Immutable<style::CustomVectorSource::Impl>); + + bool isLoaded() const final; + + void update(Immutable<style::Source::Impl>, + const std::vector<Immutable<style::Layer::Impl>>&, + bool needsRendering, + bool needsRelayout, + const TileParameters&) final; + + void startRender(PaintParameters&) final; + void finishRender(PaintParameters&) final; + + std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() final; + + std::unordered_map<std::string, std::vector<Feature>> + queryRenderedFeatures(const ScreenLineString& geometry, + const TransformState& transformState, + const std::vector<const RenderLayer*>& layers, + const RenderedQueryOptions& options) const final; + + std::vector<Feature> + querySourceFeatures(const SourceQueryOptions&) const final; + + void onLowMemory() final; + void dumpDebugLogs() const final; + + void setTileData(const CanonicalTileID& tileID, const style::FetchTileResult& result); + +private: + const style::CustomVectorSource::Impl& impl() const; + + TilePyramid tilePyramid; +}; + +template <> +inline bool RenderSource::is<RenderCustomVectorSource>() const { + return baseImpl->type == SourceType::CustomVector; +} + +} // namespace mbgl diff --git a/src/mbgl/style/sources/custom_vector_source.cpp b/src/mbgl/style/sources/custom_vector_source.cpp new file mode 100644 index 0000000000..e0bbd85af7 --- /dev/null +++ b/src/mbgl/style/sources/custom_vector_source.cpp @@ -0,0 +1,18 @@ +#include <mbgl/style/sources/custom_vector_source.hpp> +#include <mbgl/style/sources/custom_vector_source_impl.hpp> + +namespace mbgl { +namespace style { + +CustomVectorSource::CustomVectorSource(std::string id, + const GeoJSONOptions options, + FetchTileFunction fetchTileFn) + : Source(makeMutable<CustomVectorSource::Impl>(std::move(id), options, fetchTileFn)) { +} + +void CustomVectorSource::loadDescription(FileSource&) { + loaded = true; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/sources/custom_vector_source_impl.cpp b/src/mbgl/style/sources/custom_vector_source_impl.cpp new file mode 100644 index 0000000000..1b5ee4e5d1 --- /dev/null +++ b/src/mbgl/style/sources/custom_vector_source_impl.cpp @@ -0,0 +1,32 @@ +#include <mbgl/style/sources/custom_vector_source_impl.hpp> + +#include <mbgl/style/source_observer.hpp> +#include <mbgl/tile/geojson_tile.hpp> +#include <mbgl/tile/vector_tile.hpp> +#include <mbgl/util/tile_cover.hpp> + +namespace mbgl { +namespace style { + +CustomVectorSource::Impl::Impl(std::string id_, + const GeoJSONOptions options_, + FetchTileFunction fetchTileFn_) + : Source::Impl(SourceType::CustomVector, std::move(id_)), + options(options_), + fetchTileFn(fetchTileFn_) { +} + +optional<std::string> CustomVectorSource::Impl::getAttribution() const { + return {}; +} + +GeoJSONOptions CustomVectorSource::Impl::getOptions() const { + return options; +} + +FetchTileFunction CustomVectorSource::Impl::getFetchTileFunction() const { + return fetchTileFn; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/sources/custom_vector_source_impl.hpp b/src/mbgl/style/sources/custom_vector_source_impl.hpp new file mode 100644 index 0000000000..aa07bc800d --- /dev/null +++ b/src/mbgl/style/sources/custom_vector_source_impl.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include <mbgl/style/source_impl.hpp> +#include <mbgl/style/sources/custom_vector_source.hpp> +#include <mbgl/tile/tile_id.hpp> + +namespace mbgl { +namespace style { + +class CustomVectorSource::Impl : public Source::Impl { +public: + Impl(std::string id, + GeoJSONOptions options, + FetchTileFunction fetchTileFn); + + optional<std::string> getAttribution() const final; + + GeoJSONOptions getOptions() const; + FetchTileFunction getFetchTileFunction() const; + +private: + GeoJSONOptions options; + FetchTileFunction fetchTileFn; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/types.cpp b/src/mbgl/style/types.cpp index 0a1781e01b..cd5e597fc0 100644 --- a/src/mbgl/style/types.cpp +++ b/src/mbgl/style/types.cpp @@ -12,6 +12,7 @@ MBGL_DEFINE_ENUM(SourceType, { { SourceType::Video, "video" }, { SourceType::Annotations, "annotations" }, { SourceType::Image, "image" }, + { SourceType::CustomVector, "customvector" } }); MBGL_DEFINE_ENUM(VisibilityType, { diff --git a/test/style/custom_vector_source.test.cpp b/test/style/custom_vector_source.test.cpp new file mode 100644 index 0000000000..1d9be99a58 --- /dev/null +++ b/test/style/custom_vector_source.test.cpp @@ -0,0 +1,12 @@ +#include <mbgl/test/util.hpp> + +#include <mbgl/style/sources/custom_vector_source.hpp> +#include <mbgl/style/sources/geojson_source.hpp> +#include <mbgl/tile/tile_id.hpp> +#include <mbgl/util/geo.hpp> + +using namespace mbgl; + +//TODO: AHM: Add tests with real expectations +TEST(CustomVectorSource, EmptyTest) { +} |