#include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { using namespace style; GeometryTile::GeometryTile(const OverscaledTileID& id_, std::string sourceID_, const style::UpdateParameters& parameters) : Tile(id_), sourceID(std::move(sourceID_)), style(parameters.style), mailbox(std::make_shared(*util::RunLoop::Get())), worker(parameters.workerScheduler, ActorRef(*this, mailbox), id_, *parameters.style.glyphAtlas, obsolete, parameters.mode) { } GeometryTile::~GeometryTile() { cancel(); } void GeometryTile::cancel() { obsolete = true; } void GeometryTile::setError(std::exception_ptr err) { observer->onTileError(*this, err); } void GeometryTile::setData(std::unique_ptr data_) { // Mark the tile as pending again if it was complete before to prevent signaling a complete // state despite pending parse operations. if (availableData == DataAvailability::All) { availableData = DataAvailability::Some; } ++correlationID; worker.invoke(&GeometryTileWorker::setData, std::move(data_), correlationID); redoLayout(); } void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) { if (requestedConfig == desiredConfig) { return; } // Mark the tile as pending again if it was complete before to prevent signaling a complete // state despite pending parse operations. if (availableData == DataAvailability::All) { availableData = DataAvailability::Some; } ++correlationID; requestedConfig = desiredConfig; worker.invoke(&GeometryTileWorker::setPlacementConfig, desiredConfig, correlationID); } void GeometryTile::symbolDependenciesChanged() { worker.invoke(&GeometryTileWorker::symbolDependenciesChanged); } void GeometryTile::redoLayout() { // Mark the tile as pending again if it was complete before to prevent signaling a complete // state despite pending parse operations. if (availableData == DataAvailability::All) { availableData = DataAvailability::Some; } std::vector> copy; for (const Layer* layer : style.getLayers()) { // Avoid cloning and including irrelevant layers. if (layer->is() || layer->is() || layer->baseImpl->source != sourceID || id.overscaledZ < std::floor(layer->baseImpl->minZoom) || id.overscaledZ >= std::ceil(layer->baseImpl->maxZoom) || layer->baseImpl->visibility == VisibilityType::None) { continue; } copy.push_back(layer->baseImpl->clone()); } ++correlationID; worker.invoke(&GeometryTileWorker::setLayers, std::move(copy), correlationID); } void GeometryTile::onLayout(LayoutResult result) { availableData = DataAvailability::Some; buckets = std::move(result.buckets); featureIndex = std::move(result.featureIndex); data = std::move(result.tileData); observer->onTileChanged(*this); } void GeometryTile::onPlacement(PlacementResult result) { if (result.correlationID == correlationID) { availableData = DataAvailability::All; } for (auto& bucket : result.buckets) { buckets[bucket.first] = std::move(bucket.second); } featureIndex->setCollisionTile(std::move(result.collisionTile)); observer->onTileChanged(*this); } void GeometryTile::onError(std::exception_ptr err) { availableData = DataAvailability::All; observer->onTileError(*this, err); } Bucket* GeometryTile::getBucket(const Layer& layer) { const auto it = buckets.find(layer.baseImpl->id); if (it == buckets.end()) { return nullptr; } assert(it->second); return it->second.get(); } void GeometryTile::queryRenderedFeatures( std::unordered_map>& result, const GeometryCoordinates& queryGeometry, const TransformState& transformState, const optional>& layerIDs) { if (!featureIndex || !data) return; featureIndex->query(result, queryGeometry, transformState.getAngle(), util::tileSize * id.overscaleFactor(), std::pow(2, transformState.getZoom() - id.overscaledZ), layerIDs, *data, id.canonical, style); } } // namespace mbgl