91 lines
3.2 KiB
C++
91 lines
3.2 KiB
C++
#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/util/string.hpp>
|
|
#include <mbgl/tile/tile_observer.hpp>
|
|
#include <mbgl/style/custom_tile_loader.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_),
|
|
mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())),
|
|
actorRef(*this, mailbox) {
|
|
}
|
|
|
|
CustomGeometryTile::~CustomGeometryTile() {
|
|
loader.invoke(&style::CustomTileLoader::removeTile, id);
|
|
}
|
|
|
|
void CustomGeometryTile::setTileData(const GeoJSON& geoJSON) {
|
|
|
|
auto featureData = mapbox::feature::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 = ::round(scale * options.buffer);
|
|
vtOptions.tolerance = scale * options.tolerance;
|
|
featureData = mapbox::geojsonvt::geoJSONToTile(geoJSON,
|
|
id.canonical.z, id.canonical.x, id.canonical.y,
|
|
vtOptions, options.wrap, options.clip).features;
|
|
}
|
|
setData(std::make_unique<GeoJSONTileData>(std::move(featureData)));
|
|
}
|
|
|
|
void CustomGeometryTile::invalidateTileData() {
|
|
stale = true;
|
|
observer->onTileChanged(*this);
|
|
}
|
|
|
|
//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 || stale ) {
|
|
necessity = newNecessity;
|
|
if (necessity == TileNecessity::Required) {
|
|
loader.invoke(&style::CustomTileLoader::fetchTile, id, actorRef);
|
|
stale = false;
|
|
} 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)(style::expression::EvaluationContext { static_cast<float>(id.overscaledZ), feature.get() })) {
|
|
continue;
|
|
}
|
|
|
|
result.push_back(convertFeature(*feature, id.canonical));
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace mbgl
|