diff options
author | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-11-22 10:18:53 -0800 |
---|---|---|
committer | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-11-22 13:56:38 -0800 |
commit | acae19386129056b9425b114b01f062feecd297e (patch) | |
tree | 8b0db927fe5a78de3393f735d9317aba1034ba7e /src | |
parent | e3f1d8e3a0beb648ec90ac4d9baa5f27c6cf3935 (diff) | |
download | qtlocation-mapboxgl-acae19386129056b9425b114b01f062feecd297e.tar.gz |
[core] Custom Geometry Sources
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/renderer/render_source.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_custom_geometry_source.cpp | 86 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_custom_geometry_source.hpp | 50 | ||||
-rw-r--r-- | src/mbgl/style/custom_tile_loader.cpp | 114 | ||||
-rw-r--r-- | src/mbgl/style/custom_tile_loader.hpp | 47 | ||||
-rw-r--r-- | src/mbgl/style/sources/custom_geometry_source.cpp | 45 | ||||
-rw-r--r-- | src/mbgl/style/sources/custom_geometry_source_impl.cpp | 40 | ||||
-rw-r--r-- | src/mbgl/style/sources/custom_geometry_source_impl.hpp | 29 | ||||
-rw-r--r-- | src/mbgl/style/types.cpp | 1 | ||||
-rw-r--r-- | src/mbgl/tile/custom_geometry_tile.cpp | 81 | ||||
-rw-r--r-- | src/mbgl/tile/custom_geometry_tile.hpp | 34 |
11 files changed, 530 insertions, 0 deletions
diff --git a/src/mbgl/renderer/render_source.cpp b/src/mbgl/renderer/render_source.cpp index 7723a1c7ca..6624bb7d96 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_geometry_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<RenderCustomGeometrySource>(staticImmutableCast<CustomGeometrySource::Impl>(impl)); } // Not reachable, but placate GCC. diff --git a/src/mbgl/renderer/sources/render_custom_geometry_source.cpp b/src/mbgl/renderer/sources/render_custom_geometry_source.cpp new file mode 100644 index 0000000000..111f0234ed --- /dev/null +++ b/src/mbgl/renderer/sources/render_custom_geometry_source.cpp @@ -0,0 +1,86 @@ +#include <mbgl/renderer/sources/render_custom_geometry_source.hpp> +#include <mbgl/renderer/render_tile.hpp> +#include <mbgl/renderer/paint_parameters.hpp> +#include <mbgl/tile/custom_geometry_tile.hpp> + +#include <mbgl/algorithm/generate_clip_ids.hpp> +#include <mbgl/algorithm/generate_clip_ids_impl.hpp> + +namespace mbgl { + +using namespace style; + +RenderCustomGeometrySource::RenderCustomGeometrySource(Immutable<style::CustomGeometrySource::Impl> impl_) + : RenderSource(impl_) { + tilePyramid.setObserver(this); +} + +const style::CustomGeometrySource::Impl& RenderCustomGeometrySource::impl() const { + return static_cast<const style::CustomGeometrySource::Impl&>(*baseImpl); +} + +bool RenderCustomGeometrySource::isLoaded() const { + return tilePyramid.isLoaded(); +} + +void RenderCustomGeometrySource::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 tileLoader = impl().getTileLoader(); + if (!tileLoader) { + return; + } + + tilePyramid.update(layers, + needsRendering, + needsRelayout, + parameters, + SourceType::CustomVector, + util::tileSize, + impl().getZoomRange(), + [&] (const OverscaledTileID& tileID) { + return std::make_unique<CustomGeometryTile>(tileID, impl().id, parameters, impl().getTileOptions(), *tileLoader); + }); +} + +void RenderCustomGeometrySource::startRender(PaintParameters& parameters) { + parameters.clipIDGenerator.update(tilePyramid.getRenderTiles()); + tilePyramid.startRender(parameters); +} + +void RenderCustomGeometrySource::finishRender(PaintParameters& parameters) { + tilePyramid.finishRender(parameters); +} + +std::vector<std::reference_wrapper<RenderTile>> RenderCustomGeometrySource::getRenderTiles() { + return tilePyramid.getRenderTiles(); +} + +std::unordered_map<std::string, std::vector<Feature>> +RenderCustomGeometrySource::queryRenderedFeatures(const ScreenLineString& geometry, + const TransformState& transformState, + const std::vector<const RenderLayer*>& layers, + const RenderedQueryOptions& options, + const CollisionIndex& collisionIndex) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, collisionIndex); +} + +std::vector<Feature> RenderCustomGeometrySource::querySourceFeatures(const SourceQueryOptions& options) const { + return tilePyramid.querySourceFeatures(options); +} + +void RenderCustomGeometrySource::onLowMemory() { + tilePyramid.onLowMemory(); +} + +void RenderCustomGeometrySource::dumpDebugLogs() const { + tilePyramid.dumpDebugLogs(); +} + +} // namespace mbgl diff --git a/src/mbgl/renderer/sources/render_custom_geometry_source.hpp b/src/mbgl/renderer/sources/render_custom_geometry_source.hpp new file mode 100644 index 0000000000..82e691d5c9 --- /dev/null +++ b/src/mbgl/renderer/sources/render_custom_geometry_source.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include <mbgl/renderer/render_source.hpp> +#include <mbgl/renderer/tile_pyramid.hpp> +#include <mbgl/style/sources/custom_geometry_source_impl.hpp> + +namespace mbgl { + +class RenderCustomGeometrySource : public RenderSource { +public: + RenderCustomGeometrySource(Immutable<style::CustomGeometrySource::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 CollisionIndex& collisionIndex) const final; + + std::vector<Feature> + querySourceFeatures(const SourceQueryOptions&) const final; + + void onLowMemory() final; + void dumpDebugLogs() const final; + +private: + const style::CustomGeometrySource::Impl& impl() const; + + TilePyramid tilePyramid; +}; + +template <> +inline bool RenderSource::is<RenderCustomGeometrySource>() const { + return baseImpl->type == style::SourceType::CustomVector; +} + +} // namespace mbgl diff --git a/src/mbgl/style/custom_tile_loader.cpp b/src/mbgl/style/custom_tile_loader.cpp new file mode 100644 index 0000000000..2fc94c9d5a --- /dev/null +++ b/src/mbgl/style/custom_tile_loader.cpp @@ -0,0 +1,114 @@ +#include <mbgl/style/custom_tile_loader.hpp> + +namespace mbgl { +namespace style { + +CustomTileLoader::CustomTileLoader(const TileFunction& fetchTileFn, const TileFunction& cancelTileFn) { + fetchTileFunction = fetchTileFn; + cancelTileFunction = cancelTileFn; +} + +void CustomTileLoader::fetchTile(const OverscaledTileID& tileID, ActorRef<SetTileDataFunction> callbackRef) { + std::lock_guard<std::mutex> lock(dataCacheMutex); + auto cachedTileData = dataCache.find(tileID.canonical); + if (cachedTileData != dataCache.end()) { + callbackRef.invoke(&SetTileDataFunction::operator(), *(cachedTileData->second)); + } + auto tileCallbacks = tileCallbackMap.find(tileID.canonical); + if (tileCallbacks == tileCallbackMap.end()) { + auto tuple = std::make_tuple(tileID.overscaledZ, tileID.wrap, callbackRef); + tileCallbackMap.insert({ tileID.canonical, std::vector<OverscaledIDFunctionTuple>(1, tuple) }); + } else { + for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) { + if (std::get<0>(*iter) == tileID.overscaledZ && std::get<1>(*iter) == tileID.wrap ) { + std::get<2>(*iter) = callbackRef; + return; + } + } + tileCallbacks->second.emplace_back(std::make_tuple(tileID.overscaledZ, tileID.wrap, callbackRef)); + } + if (cachedTileData == dataCache.end()) { + invokeTileFetch(tileID.canonical); + } +} + +void CustomTileLoader::cancelTile(const OverscaledTileID& tileID) { + if (tileCallbackMap.find(tileID.canonical) != tileCallbackMap.end()) { + invokeTileCancel(tileID.canonical); + } +} + +void CustomTileLoader::removeTile(const OverscaledTileID& tileID) { + auto tileCallbacks = tileCallbackMap.find(tileID.canonical); + if (tileCallbacks == tileCallbackMap.end()) return; + for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) { + if (std::get<0>(*iter) == tileID.overscaledZ && std::get<1>(*iter) == tileID.wrap ) { + tileCallbacks->second.erase(iter); + invokeTileCancel(tileID.canonical); + break; + } + } + if (tileCallbacks->second.size() == 0) { + std::lock_guard<std::mutex> lock(dataCacheMutex); + tileCallbackMap.erase(tileCallbacks); + dataCache.erase(tileID.canonical); + } +} + +void CustomTileLoader::setTileData(const CanonicalTileID& tileID, const GeoJSON& data) { + std::lock_guard<std::mutex> lock(dataCacheMutex); + + auto iter = tileCallbackMap.find(tileID); + if (iter == tileCallbackMap.end()) return; + dataCache[tileID] = std::make_unique<mapbox::geojson::geojson>(std::move(data));; + for (auto tuple : iter->second) { + auto actor = std::get<2>(tuple); + actor.invoke(&SetTileDataFunction::operator(), data); + } +} + +void CustomTileLoader::invalidateTile(const CanonicalTileID& tileID) { + auto tileCallbacks = tileCallbackMap.find(tileID); + if (tileCallbacks == tileCallbackMap.end()) { return; } + for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) { + auto actor = std::get<2>(*iter); + actor.invoke(&SetTileDataFunction::operator(), mapbox::geojson::feature_collection()); + invokeTileCancel(tileID); + } + tileCallbackMap.erase(tileCallbacks); + { + std::lock_guard<std::mutex> lock(dataCacheMutex); + dataCache.erase(tileID); + } +} + +void CustomTileLoader::invalidateRegion(const LatLngBounds& bounds, Range<uint8_t> ) { + for (auto idtuple= tileCallbackMap.begin(); idtuple != tileCallbackMap.end(); idtuple++) { + const LatLngBounds tileBounds(idtuple->first); + if (tileBounds.intersects(bounds) || bounds.contains(tileBounds) || tileBounds.contains(bounds)) { + for (auto iter = idtuple->second.begin(); iter != idtuple->second.end(); iter++) { + std::lock_guard<std::mutex> lock(dataCacheMutex); + auto actor = std::get<2>(*iter); + actor.invoke(&SetTileDataFunction::operator(), mapbox::geojson::feature_collection()); + invokeTileCancel(idtuple->first); + dataCache.erase(idtuple->first); + } + idtuple->second.clear(); + } + } +} + +void CustomTileLoader::invokeTileFetch(const CanonicalTileID& tileID) { + if (fetchTileFunction != nullptr) { + fetchTileFunction(tileID); + } +} + +void CustomTileLoader::invokeTileCancel(const CanonicalTileID& tileID) { + if (cancelTileFunction != nullptr) { + cancelTileFunction(tileID); + } +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/custom_tile_loader.hpp b/src/mbgl/style/custom_tile_loader.hpp new file mode 100644 index 0000000000..fa3173ffc0 --- /dev/null +++ b/src/mbgl/style/custom_tile_loader.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include <mbgl/style/sources/custom_geometry_source.hpp> +#include <mbgl/tile/tile_id.hpp> +#include <mbgl/util/geo.hpp> +#include <mbgl/util/geojson.hpp> +#include <mbgl/actor/actor_ref.hpp> + +#include <map> +#include <mutex> + +namespace mbgl { +namespace style { + +using SetTileDataFunction = std::function<void(const GeoJSON&)>; + +class CustomTileLoader : private util::noncopyable { +public: + + using OverscaledIDFunctionTuple = std::tuple<uint8_t, int16_t, ActorRef<SetTileDataFunction>>; + + CustomTileLoader(const TileFunction& fetchTileFn, const TileFunction& cancelTileFn); + + void fetchTile(const OverscaledTileID& tileID, ActorRef<SetTileDataFunction> callbackRef); + void cancelTile(const OverscaledTileID& tileID); + + void removeTile(const OverscaledTileID& tileID); + void setTileData(const CanonicalTileID& tileID, const GeoJSON& data); + + void invalidateTile(const CanonicalTileID&); + void invalidateRegion(const LatLngBounds&, Range<uint8_t>); + +private: + void invokeTileFetch(const CanonicalTileID& tileID); + void invokeTileCancel(const CanonicalTileID& tileID); + + TileFunction fetchTileFunction; + TileFunction cancelTileFunction; + std::unordered_map<CanonicalTileID, std::vector<OverscaledIDFunctionTuple>> tileCallbackMap; + // Keep around a cache of tile data to serve back for wrapped and over-zooomed tiles + std::map<CanonicalTileID, std::unique_ptr<GeoJSON>> dataCache; + std::mutex dataCacheMutex; + +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/sources/custom_geometry_source.cpp b/src/mbgl/style/sources/custom_geometry_source.cpp new file mode 100644 index 0000000000..657573b1f4 --- /dev/null +++ b/src/mbgl/style/sources/custom_geometry_source.cpp @@ -0,0 +1,45 @@ +#include <mbgl/style/sources/custom_geometry_source.hpp> +#include <mbgl/style/custom_tile_loader.hpp> +#include <mbgl/style/sources/custom_geometry_source_impl.hpp> +#include <mbgl/actor/scheduler.hpp> +#include <mbgl/tile/tile_id.hpp> + +#include <tuple> +#include <map> + +namespace mbgl { +namespace style { + +CustomGeometrySource::CustomGeometrySource(std::string id, + const CustomGeometrySource::Options options) + : Source(makeMutable<CustomGeometrySource::Impl>(std::move(id), options)), + mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())), + loader(std::make_unique<CustomTileLoader>(options.fetchTileFunction, options.cancelTileFunction)) { +} + +CustomGeometrySource::~CustomGeometrySource() = default; + +const CustomGeometrySource::Impl& CustomGeometrySource::impl() const { + return static_cast<const CustomGeometrySource::Impl&>(*baseImpl); +} + +void CustomGeometrySource::loadDescription(FileSource&) { + baseImpl = makeMutable<CustomGeometrySource::Impl>(impl(), ActorRef<CustomTileLoader>(*loader, mailbox)); + loaded = true; +} + +void CustomGeometrySource::setTileData(const CanonicalTileID& tileID, + const GeoJSON& data) { + loader->setTileData(tileID, data); +} + +void CustomGeometrySource::invalidateTile(const CanonicalTileID& tileID) { + loader->invalidateTile(tileID); +} + +void CustomGeometrySource::invalidateRegion(const LatLngBounds& bounds) { + loader->invalidateRegion(bounds, impl().getZoomRange()); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/sources/custom_geometry_source_impl.cpp b/src/mbgl/style/sources/custom_geometry_source_impl.cpp new file mode 100644 index 0000000000..67d52bdc24 --- /dev/null +++ b/src/mbgl/style/sources/custom_geometry_source_impl.cpp @@ -0,0 +1,40 @@ +#include <mbgl/style/sources/custom_geometry_source_impl.hpp> +#include <mbgl/style/source_observer.hpp> + +namespace mbgl { +namespace style { + +CustomGeometrySource::Impl::Impl(std::string id_, + const CustomGeometrySource::Options options) + : Source::Impl(SourceType::CustomVector, std::move(id_)), + tileOptions(options.tileOptions), + zoomRange(options.zoomRange), + loaderRef({}) { +} + +CustomGeometrySource::Impl::Impl(const Impl& impl, ActorRef<CustomTileLoader> loaderRef_) + : Source::Impl(impl), + tileOptions(impl.tileOptions), + zoomRange(impl.zoomRange), + loaderRef(loaderRef_){ + +} + +optional<std::string> CustomGeometrySource::Impl::getAttribution() const { + return {}; +} + +CustomGeometrySource::TileOptions CustomGeometrySource::Impl::getTileOptions() const { + return tileOptions; +} + +Range<uint8_t> CustomGeometrySource::Impl::getZoomRange() const { + return zoomRange; +} + +optional<ActorRef<CustomTileLoader>> CustomGeometrySource::Impl::getTileLoader() const { + return loaderRef; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/sources/custom_geometry_source_impl.hpp b/src/mbgl/style/sources/custom_geometry_source_impl.hpp new file mode 100644 index 0000000000..ce7187202d --- /dev/null +++ b/src/mbgl/style/sources/custom_geometry_source_impl.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include <mbgl/style/source_impl.hpp> +#include <mbgl/style/sources/custom_geometry_source.hpp> +#include <mbgl/style/custom_tile_loader.hpp> +#include <mbgl/actor/actor_ref.hpp> + +namespace mbgl { +namespace style { + +class CustomGeometrySource::Impl : public Source::Impl { +public: + Impl(std::string id, CustomGeometrySource::Options options); + Impl(const Impl&, ActorRef<CustomTileLoader>); + + optional<std::string> getAttribution() const final; + + CustomGeometrySource::TileOptions getTileOptions() const; + Range<uint8_t> getZoomRange() const; + optional<ActorRef<CustomTileLoader>> getTileLoader() const; + +private: + CustomGeometrySource::TileOptions tileOptions; + Range<uint8_t> zoomRange; + optional<ActorRef<CustomTileLoader>> loaderRef; +}; + +} // 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/src/mbgl/tile/custom_geometry_tile.cpp b/src/mbgl/tile/custom_geometry_tile.cpp new file mode 100644 index 0000000000..0d0ff5be61 --- /dev/null +++ b/src/mbgl/tile/custom_geometry_tile.cpp @@ -0,0 +1,81 @@ +#include <mbgl/tile/custom_geometry_tile.hpp> +#include <mbgl/tile/geojson_tile_data.hpp> +#include <mbgl/renderer/query.hpp> +#include <mbgl/renderer/tile_parameters.hpp> +#include <mbgl/actor/scheduler.hpp> +#include <mbgl/style/filter_evaluator.hpp> + +#include <mapbox/geojsonvt.hpp> + +namespace mbgl { + +CustomGeometryTile::CustomGeometryTile(const OverscaledTileID& overscaledTileID, + std::string sourceID_, + const TileParameters& parameters, + const style::CustomGeometrySource::TileOptions options_, + ActorRef<style::CustomTileLoader> loader_) + : GeometryTile(overscaledTileID, sourceID_, parameters), + necessity(TileNecessity::Optional), + options(options_), + loader(loader_), + actor(*Scheduler::GetCurrent(), std::bind(&CustomGeometryTile::setTileData, this, std::placeholders::_1)) { +} + +CustomGeometryTile::~CustomGeometryTile() { + loader.invoke(&style::CustomTileLoader::removeTile, id); +} + +void CustomGeometryTile::setTileData(const GeoJSON& geoJSON) { + + auto featureData = mapbox::geometry::feature_collection<int16_t>(); + if (geoJSON.is<FeatureCollection>() && !geoJSON.get<FeatureCollection>().empty()) { + const double scale = util::EXTENT / options.tileSize; + + mapbox::geojsonvt::TileOptions vtOptions; + vtOptions.extent = util::EXTENT; + vtOptions.buffer = std::round(scale * options.buffer); + vtOptions.tolerance = scale * options.tolerance; + featureData = mapbox::geojsonvt::geoJSONToTile(geoJSON, id.canonical.z, id.canonical.x, id.canonical.y, vtOptions).features; + } else { + setNecessity(TileNecessity::Optional); + } + setData(std::make_unique<GeoJSONTileData>(std::move(featureData))); +} + +//Fetching tile data for custom sources is assumed to be an expensive operation. +// Only required tiles make fetchTile requests. Attempt to cancel a tile +// that is no longer required. +void CustomGeometryTile::setNecessity(TileNecessity newNecessity) { + if (newNecessity != necessity) { + necessity = newNecessity; + if (necessity == TileNecessity::Required) { + loader.invoke(&style::CustomTileLoader::fetchTile, id, actor.self()); + } else if (!isRenderable()) { + loader.invoke(&style::CustomTileLoader::cancelTile, id); + } + } +} + +void CustomGeometryTile::querySourceFeatures( + std::vector<Feature>& result, + const SourceQueryOptions& queryOptions) { + + // Ignore the sourceLayer, there is only one + auto layer = getData()->getLayer({}); + + if (layer) { + auto featureCount = layer->featureCount(); + for (std::size_t i = 0; i < featureCount; i++) { + auto feature = layer->getFeature(i); + + // Apply filter, if any + if (queryOptions.filter && !(*queryOptions.filter)(*feature)) { + continue; + } + + result.push_back(convertFeature(*feature, id.canonical)); + } + } +} + +} // namespace mbgl diff --git a/src/mbgl/tile/custom_geometry_tile.hpp b/src/mbgl/tile/custom_geometry_tile.hpp new file mode 100644 index 0000000000..66cc412e8c --- /dev/null +++ b/src/mbgl/tile/custom_geometry_tile.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include <mbgl/tile/geometry_tile.hpp> +#include <mbgl/util/feature.hpp> +#include <mbgl/style/custom_tile_loader.hpp> + +namespace mbgl { + +class TileParameters; + +class CustomGeometryTile: public GeometryTile { +public: + CustomGeometryTile(const OverscaledTileID&, + std::string sourceID, + const TileParameters&, + const style::CustomGeometrySource::TileOptions, + ActorRef<style::CustomTileLoader> loader); + ~CustomGeometryTile() override; + void setTileData(const GeoJSON& data); + + void setNecessity(TileNecessity) final; + + void querySourceFeatures( + std::vector<Feature>& result, + const SourceQueryOptions&) override; + +private: + TileNecessity necessity; + const style::CustomGeometrySource::TileOptions options; + ActorRef<style::CustomTileLoader> loader; + Actor<style::SetTileDataFunction> actor; +}; + +} // namespace mbgl |