[core] *Tile ↔ *TileData
Tile is now the main base class; RasterTile, VectorTile, etc are its subclasses. GeometryTileData and its subclasses form the piece that's passed to the worker.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
#include <mbgl/style/filter.hpp>
|
||||
#include <mbgl/style/filter_evaluator.hpp>
|
||||
#include <mbgl/style/parser.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
namespace mbgl {
|
||||
namespace algorithm {
|
||||
|
||||
template <typename GetTileDataFn,
|
||||
typename CreateTileDataFn,
|
||||
typename RetainTileDataFn,
|
||||
template <typename GetTileFn,
|
||||
typename CreateTileFn,
|
||||
typename RetainTileFn,
|
||||
typename RenderTileFn,
|
||||
typename IdealTileIDs,
|
||||
typename SourceInfo>
|
||||
void updateRenderables(GetTileDataFn getTileData,
|
||||
CreateTileDataFn createTileData,
|
||||
RetainTileDataFn retainTileData,
|
||||
void updateRenderables(GetTileFn getTile,
|
||||
CreateTileFn createTile,
|
||||
RetainTileFn retainTile,
|
||||
RenderTileFn renderTile,
|
||||
const IdealTileIDs& idealTileIDs,
|
||||
const SourceInfo& info,
|
||||
@@ -31,29 +31,29 @@ void updateRenderables(GetTileDataFn getTileData,
|
||||
assert(dataTileZoom >= idealRenderTileID.canonical.z);
|
||||
|
||||
const OverscaledTileID idealDataTileID(dataTileZoom, idealRenderTileID.canonical);
|
||||
auto data = getTileData(idealDataTileID);
|
||||
auto data = getTile(idealDataTileID);
|
||||
if (!data) {
|
||||
data = createTileData(idealDataTileID);
|
||||
data = createTile(idealDataTileID);
|
||||
assert(data);
|
||||
}
|
||||
|
||||
// if (source has the tile and bucket is loaded) {
|
||||
if (data->isRenderable()) {
|
||||
retainTileData(*data, true);
|
||||
retainTile(*data, true);
|
||||
renderTile(idealRenderTileID, *data);
|
||||
} else {
|
||||
bool triedPrevious = data->hasTriedOptional();
|
||||
|
||||
// The tile isn't loaded yet, but retain it anyway because it's an ideal tile.
|
||||
retainTileData(*data, true);
|
||||
retainTile(*data, true);
|
||||
covered = true;
|
||||
overscaledZ = dataTileZoom + 1;
|
||||
if (overscaledZ > info.maxZoom) {
|
||||
// We're looking for an overzoomed child tile.
|
||||
const auto childDataTileID = idealDataTileID.scaledTo(overscaledZ);
|
||||
data = getTileData(childDataTileID);
|
||||
data = getTile(childDataTileID);
|
||||
if (data && data->isRenderable()) {
|
||||
retainTileData(*data, false);
|
||||
retainTile(*data, false);
|
||||
renderTile(idealRenderTileID, *data);
|
||||
} else {
|
||||
covered = false;
|
||||
@@ -62,9 +62,9 @@ void updateRenderables(GetTileDataFn getTileData,
|
||||
// Check all four actual child tiles.
|
||||
for (const auto& childTileID : idealDataTileID.canonical.children()) {
|
||||
const OverscaledTileID childDataTileID(overscaledZ, childTileID);
|
||||
data = getTileData(childDataTileID);
|
||||
data = getTile(childDataTileID);
|
||||
if (data && data->isRenderable()) {
|
||||
retainTileData(*data, false);
|
||||
retainTile(*data, false);
|
||||
renderTile(childDataTileID.unwrapTo(idealRenderTileID.wrap), *data);
|
||||
} else {
|
||||
// At least one child tile doesn't exist, so we are going to look for
|
||||
@@ -89,14 +89,14 @@ void updateRenderables(GetTileDataFn getTileData,
|
||||
checked.emplace(parentRenderTileID);
|
||||
}
|
||||
|
||||
data = getTileData(parentDataTileID);
|
||||
data = getTile(parentDataTileID);
|
||||
if (!data && triedPrevious) {
|
||||
data = createTileData(parentDataTileID);
|
||||
data = createTile(parentDataTileID);
|
||||
}
|
||||
|
||||
if (data) {
|
||||
triedPrevious = data->hasTriedOptional();
|
||||
retainTileData(*data, false);
|
||||
retainTile(*data, false);
|
||||
|
||||
if (data->isRenderable()) {
|
||||
renderTile(parentRenderTileID, *data);
|
||||
|
||||
@@ -80,13 +80,13 @@ AnnotationIDs AnnotationManager::getPointAnnotationsInBounds(const LatLngBounds&
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<AnnotationTile> AnnotationManager::getTile(const CanonicalTileID& tileID) {
|
||||
std::unique_ptr<AnnotationTileData> AnnotationManager::getTileData(const CanonicalTileID& tileID) {
|
||||
if (symbolAnnotations.empty() && shapeAnnotations.empty())
|
||||
return nullptr;
|
||||
|
||||
auto tile = std::make_unique<AnnotationTile>();
|
||||
auto tileData = std::make_unique<AnnotationTileData>();
|
||||
|
||||
AnnotationTileLayer& pointLayer = *tile->layers.emplace(
|
||||
AnnotationTileLayer& pointLayer = *tileData->layers.emplace(
|
||||
PointLayerID,
|
||||
std::make_unique<AnnotationTileLayer>(PointLayerID)).first->second;
|
||||
|
||||
@@ -98,10 +98,10 @@ std::unique_ptr<AnnotationTile> AnnotationManager::getTile(const CanonicalTileID
|
||||
}));
|
||||
|
||||
for (const auto& shape : shapeAnnotations) {
|
||||
shape.second->updateTile(tileID, *tile);
|
||||
shape.second->updateTileData(tileID, *tileData);
|
||||
}
|
||||
|
||||
return tile;
|
||||
return tileData;
|
||||
}
|
||||
|
||||
void AnnotationManager::updateStyle(Style& style) {
|
||||
@@ -134,18 +134,18 @@ void AnnotationManager::updateStyle(Style& style) {
|
||||
|
||||
obsoleteShapeAnnotationLayers.clear();
|
||||
|
||||
for (auto& data : monitors) {
|
||||
data->setData(getTile(data->id.canonical), {}, {});
|
||||
for (auto& tile : tiles) {
|
||||
tile->setData(getTileData(tile->id.canonical), {}, {});
|
||||
}
|
||||
}
|
||||
|
||||
void AnnotationManager::addTileData(AnnotationTileData& data) {
|
||||
monitors.insert(&data);
|
||||
data.setData(getTile(data.id.canonical), {}, {});
|
||||
void AnnotationManager::addTile(AnnotationTile& tile) {
|
||||
tiles.insert(&tile);
|
||||
tile.setData(getTileData(tile.id.canonical), {}, {});
|
||||
}
|
||||
|
||||
void AnnotationManager::removeTileData(AnnotationTileData& data) {
|
||||
monitors.erase(&data);
|
||||
void AnnotationManager::removeTile(AnnotationTile& tile) {
|
||||
tiles.erase(&tile);
|
||||
}
|
||||
|
||||
void AnnotationManager::addIcon(const std::string& name, std::shared_ptr<const SpriteImage> sprite) {
|
||||
|
||||
@@ -41,8 +41,8 @@ public:
|
||||
|
||||
void updateStyle(style::Style&);
|
||||
|
||||
void addTileData(AnnotationTileData&);
|
||||
void removeTileData(AnnotationTileData&);
|
||||
void addTile(AnnotationTile&);
|
||||
void removeTile(AnnotationTile&);
|
||||
|
||||
static const std::string SourceID;
|
||||
static const std::string PointLayerID;
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
void add(const AnnotationID&, const FillAnnotation&, const uint8_t);
|
||||
void add(const AnnotationID&, const StyleSourcedAnnotation&, const uint8_t);
|
||||
|
||||
std::unique_ptr<AnnotationTile> getTile(const CanonicalTileID&);
|
||||
std::unique_ptr<AnnotationTileData> getTileData(const CanonicalTileID&);
|
||||
|
||||
AnnotationID nextID = 0;
|
||||
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
SymbolAnnotationMap symbolAnnotations;
|
||||
ShapeAnnotationMap shapeAnnotations;
|
||||
std::vector<std::string> obsoleteShapeAnnotationLayers;
|
||||
std::set<AnnotationTileData*> monitors;
|
||||
std::set<AnnotationTile*> tiles;
|
||||
|
||||
SpriteStore spriteStore;
|
||||
SpriteAtlas spriteAtlas;
|
||||
|
||||
@@ -8,19 +8,19 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
AnnotationTileData::AnnotationTileData(const OverscaledTileID& overscaledTileID,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters& parameters)
|
||||
: GeometryTileData(overscaledTileID, sourceID, parameters.style, parameters.mode),
|
||||
AnnotationTile::AnnotationTile(const OverscaledTileID& overscaledTileID,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters& parameters)
|
||||
: GeometryTile(overscaledTileID, sourceID, parameters.style, parameters.mode),
|
||||
annotationManager(parameters.annotationManager) {
|
||||
annotationManager.addTileData(*this);
|
||||
annotationManager.addTile(*this);
|
||||
}
|
||||
|
||||
AnnotationTileData::~AnnotationTileData() {
|
||||
annotationManager.removeTileData(*this);
|
||||
AnnotationTile::~AnnotationTile() {
|
||||
annotationManager.removeTile(*this);
|
||||
}
|
||||
|
||||
void AnnotationTileData::setNecessity(Necessity) {}
|
||||
void AnnotationTile::setNecessity(Necessity) {}
|
||||
|
||||
AnnotationTileFeature::AnnotationTileFeature(FeatureType type_, GeometryCollection geometries_,
|
||||
std::unordered_map<std::string, std::string> properties_)
|
||||
@@ -39,7 +39,7 @@ optional<Value> AnnotationTileFeature::getValue(const std::string& key) const {
|
||||
AnnotationTileLayer::AnnotationTileLayer(const std::string &name_)
|
||||
: name(name_) {}
|
||||
|
||||
util::ptr<GeometryTileLayer> AnnotationTile::getLayer(const std::string& name) const {
|
||||
util::ptr<GeometryTileLayer> AnnotationTileData::getLayer(const std::string& name) const {
|
||||
auto it = layers.find(name);
|
||||
if (it != layers.end()) {
|
||||
return it->second;
|
||||
|
||||
@@ -11,12 +11,12 @@ namespace style {
|
||||
class UpdateParameters;
|
||||
}
|
||||
|
||||
class AnnotationTileData : public GeometryTileData {
|
||||
class AnnotationTile : public GeometryTile {
|
||||
public:
|
||||
AnnotationTileData(const OverscaledTileID&,
|
||||
AnnotationTile(const OverscaledTileID&,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters&);
|
||||
~AnnotationTileData();
|
||||
~AnnotationTile();
|
||||
|
||||
void setNecessity(Necessity) final;
|
||||
|
||||
@@ -52,7 +52,7 @@ private:
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class AnnotationTile : public GeometryTile {
|
||||
class AnnotationTileData : public GeometryTileData {
|
||||
public:
|
||||
util::ptr<GeometryTileLayer> getLayer(const std::string&) const override;
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
void ShapeAnnotationImpl::updateTile(const CanonicalTileID& tileID, AnnotationTile& tile) {
|
||||
void ShapeAnnotationImpl::updateTileData(const CanonicalTileID& tileID, AnnotationTileData& data) {
|
||||
static const double baseTolerance = 4;
|
||||
|
||||
if (!shapeTiler) {
|
||||
@@ -108,7 +108,7 @@ void ShapeAnnotationImpl::updateTile(const CanonicalTileID& tileID, AnnotationTi
|
||||
if (!shapeTile)
|
||||
return;
|
||||
|
||||
AnnotationTileLayer& layer = *tile.layers.emplace(layerID,
|
||||
AnnotationTileLayer& layer = *data.layers.emplace(layerID,
|
||||
std::make_unique<AnnotationTileLayer>(layerID)).first->second;
|
||||
|
||||
for (auto& shapeFeature : shapeTile.features) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class AnnotationTile;
|
||||
class AnnotationTileData;
|
||||
class CanonicalTileID;
|
||||
|
||||
namespace style {
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
virtual void updateStyle(style::Style&) const = 0;
|
||||
virtual const ShapeAnnotationGeometry& geometry() const = 0;
|
||||
|
||||
void updateTile(const CanonicalTileID&, AnnotationTile&);
|
||||
void updateTileData(const CanonicalTileID&, AnnotationTileData&);
|
||||
|
||||
const AnnotationID id;
|
||||
const uint8_t maxZoom;
|
||||
|
||||
@@ -57,7 +57,7 @@ void FeatureIndex::query(
|
||||
const double tileSize,
|
||||
const double scale,
|
||||
const optional<std::vector<std::string>>& filterLayerIDs,
|
||||
const GeometryTile& geometryTile,
|
||||
const GeometryTileData& geometryTileData,
|
||||
const CanonicalTileID& tileID,
|
||||
const style::Style& style) const {
|
||||
|
||||
@@ -75,7 +75,7 @@ void FeatureIndex::query(
|
||||
if (indexedFeature.sortIndex == previousSortIndex) continue;
|
||||
previousSortIndex = indexedFeature.sortIndex;
|
||||
|
||||
addFeature(result, indexedFeature, queryGeometry, filterLayerIDs, geometryTile, tileID, style, bearing, pixelsToTileUnits);
|
||||
addFeature(result, indexedFeature, queryGeometry, filterLayerIDs, geometryTileData, tileID, style, bearing, pixelsToTileUnits);
|
||||
}
|
||||
|
||||
// query symbol features
|
||||
@@ -83,7 +83,7 @@ void FeatureIndex::query(
|
||||
std::vector<IndexedSubfeature> symbolFeatures = collisionTile->queryRenderedSymbols(box, scale);
|
||||
std::sort(symbolFeatures.begin(), symbolFeatures.end(), topDownSymbols);
|
||||
for (const auto& symbolFeature : symbolFeatures) {
|
||||
addFeature(result, symbolFeature, queryGeometry, filterLayerIDs, geometryTile, tileID, style, bearing, pixelsToTileUnits);
|
||||
addFeature(result, symbolFeature, queryGeometry, filterLayerIDs, geometryTileData, tileID, style, bearing, pixelsToTileUnits);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ void FeatureIndex::addFeature(
|
||||
const IndexedSubfeature& indexedFeature,
|
||||
const GeometryCollection& queryGeometry,
|
||||
const optional<std::vector<std::string>>& filterLayerIDs,
|
||||
const GeometryTile& geometryTile,
|
||||
const GeometryTileData& geometryTileData,
|
||||
const CanonicalTileID& tileID,
|
||||
const style::Style& style,
|
||||
const float bearing,
|
||||
@@ -103,7 +103,7 @@ void FeatureIndex::addFeature(
|
||||
return;
|
||||
}
|
||||
|
||||
auto sourceLayer = geometryTile.getLayer(indexedFeature.sourceLayerName);
|
||||
auto sourceLayer = geometryTileData.getLayer(indexedFeature.sourceLayerName);
|
||||
assert(sourceLayer);
|
||||
|
||||
auto geometryTileFeature = sourceLayer->getFeature(indexedFeature.index);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/types.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/util/grid_index.hpp>
|
||||
#include <mbgl/util/feature.hpp>
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
const double tileSize,
|
||||
const double scale,
|
||||
const optional<std::vector<std::string>>& layerIDs,
|
||||
const GeometryTile&,
|
||||
const GeometryTileData&,
|
||||
const CanonicalTileID&,
|
||||
const style::Style&) const;
|
||||
|
||||
@@ -61,7 +61,7 @@ private:
|
||||
const IndexedSubfeature&,
|
||||
const GeometryCollection& queryGeometry,
|
||||
const optional<std::vector<std::string>>& filterLayerIDs,
|
||||
const GeometryTile&,
|
||||
const GeometryTileData&,
|
||||
const CanonicalTileID&,
|
||||
const style::Style&,
|
||||
const float bearing,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <mbgl/renderer/bucket.hpp>
|
||||
#include <mbgl/map/mode.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/geometry/elements_buffer.hpp>
|
||||
#include <mbgl/geometry/circle_buffer.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/tile_data.hpp>
|
||||
#include <mbgl/map/mode.hpp>
|
||||
#include <mbgl/geometry/debug_font_buffer.hpp>
|
||||
#include <mbgl/geometry/vao.hpp>
|
||||
@@ -8,6 +7,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class OverscaledTileID;
|
||||
class PlainShader;
|
||||
|
||||
namespace gl {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/renderer/bucket.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/geometry/elements_buffer.hpp>
|
||||
#include <mbgl/geometry/fill_buffer.hpp>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/renderer/bucket.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/geometry/vao.hpp>
|
||||
#include <mbgl/geometry/elements_buffer.hpp>
|
||||
#include <mbgl/geometry/line_buffer.hpp>
|
||||
|
||||
@@ -32,7 +32,7 @@ class SpriteAtlas;
|
||||
class GlyphAtlas;
|
||||
class LineAtlas;
|
||||
struct FrameData;
|
||||
class TileData;
|
||||
class Tile;
|
||||
|
||||
class DebugBucket;
|
||||
class FillBucket;
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
|
||||
void renderClipMasks();
|
||||
|
||||
void renderDebugText(TileData&, const mat4&);
|
||||
void renderDebugText(Tile&, const mat4&);
|
||||
void renderFill(FillBucket&, const style::FillLayer&, const UnwrappedTileID&, const mat4&);
|
||||
void renderLine(LineBucket&, const style::LineLayer&, const UnwrappedTileID&, const mat4&);
|
||||
void renderCircle(CircleBucket&, const style::CircleLayer&, const UnwrappedTileID&, const mat4&);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <mbgl/renderer/painter.hpp>
|
||||
#include <mbgl/renderer/debug_bucket.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/tile/tile_data.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/shader/plain_shader.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/gl/debugging.hpp>
|
||||
@@ -16,7 +16,7 @@ void Painter::renderTileDebug(const RenderTile& tile) {
|
||||
if (frame.debugOptions != MapDebugOptions::NoDebug) {
|
||||
setClipping(tile.clip);
|
||||
if (frame.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) {
|
||||
renderDebugText(tile.data, tile.matrix);
|
||||
renderDebugText(tile.tile, tile.matrix);
|
||||
}
|
||||
if (frame.debugOptions & MapDebugOptions::TileBorders) {
|
||||
renderDebugFrame(tile.matrix);
|
||||
@@ -24,19 +24,19 @@ void Painter::renderTileDebug(const RenderTile& tile) {
|
||||
}
|
||||
}
|
||||
|
||||
void Painter::renderDebugText(TileData& tileData, const mat4 &matrix) {
|
||||
void Painter::renderDebugText(Tile& tile, const mat4 &matrix) {
|
||||
MBGL_DEBUG_GROUP("debug text");
|
||||
|
||||
config.depthTest = GL_FALSE;
|
||||
|
||||
if (!tileData.debugBucket || tileData.debugBucket->renderable != tileData.isRenderable() ||
|
||||
tileData.debugBucket->complete != tileData.isComplete() ||
|
||||
!(tileData.debugBucket->modified == tileData.modified) ||
|
||||
!(tileData.debugBucket->expires == tileData.expires) ||
|
||||
tileData.debugBucket->debugMode != frame.debugOptions) {
|
||||
tileData.debugBucket = std::make_unique<DebugBucket>(
|
||||
tileData.id, tileData.isRenderable(), tileData.isComplete(), tileData.modified,
|
||||
tileData.expires, frame.debugOptions);
|
||||
if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() ||
|
||||
tile.debugBucket->complete != tile.isComplete() ||
|
||||
!(tile.debugBucket->modified == tile.modified) ||
|
||||
!(tile.debugBucket->expires == tile.expires) ||
|
||||
tile.debugBucket->debugMode != frame.debugOptions) {
|
||||
tile.debugBucket = std::make_unique<DebugBucket>(
|
||||
tile.id, tile.isRenderable(), tile.isComplete(), tile.modified,
|
||||
tile.expires, frame.debugOptions);
|
||||
}
|
||||
|
||||
config.program = plainShader->getID();
|
||||
@@ -45,18 +45,18 @@ void Painter::renderDebugText(TileData& tileData, const mat4 &matrix) {
|
||||
// Draw white outline
|
||||
plainShader->u_color = {{ 1.0f, 1.0f, 1.0f, 1.0f }};
|
||||
config.lineWidth = 4.0f * frame.pixelRatio;
|
||||
tileData.debugBucket->drawLines(*plainShader, store);
|
||||
tile.debugBucket->drawLines(*plainShader, store);
|
||||
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
// Draw line "end caps"
|
||||
MBGL_CHECK_ERROR(glPointSize(2));
|
||||
tileData.debugBucket->drawPoints(*plainShader, store);
|
||||
tile.debugBucket->drawPoints(*plainShader, store);
|
||||
#endif
|
||||
|
||||
// Draw black text.
|
||||
plainShader->u_color = {{ 0.0f, 0.0f, 0.0f, 1.0f }};
|
||||
config.lineWidth = 2.0f * frame.pixelRatio;
|
||||
tileData.debugBucket->drawLines(*plainShader, store);
|
||||
tile.debugBucket->drawLines(*plainShader, store);
|
||||
|
||||
config.depthFunc.reset();
|
||||
config.depthTest = GL_TRUE;
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class TileData;
|
||||
class Tile;
|
||||
|
||||
class RenderTile {
|
||||
public:
|
||||
RenderTile(const UnwrappedTileID& id_, TileData& data_) : id(id_), data(data_) {
|
||||
RenderTile(const UnwrappedTileID& id_, Tile& tile_) : id(id_), tile(tile_) {
|
||||
}
|
||||
|
||||
RenderTile(const RenderTile&) = delete;
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
RenderTile& operator=(RenderTile&&) = default;
|
||||
|
||||
const UnwrappedTileID id;
|
||||
TileData& data;
|
||||
Tile& tile;
|
||||
ClipID clip;
|
||||
mat4 matrix;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <mbgl/renderer/symbol_bucket.hpp>
|
||||
#include <mbgl/style/filter_evaluator.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/sprite/sprite_image.hpp>
|
||||
#include <mbgl/sprite/sprite_store.hpp>
|
||||
#include <mbgl/sprite/sprite_atlas.hpp>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/renderer/bucket.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/map/mode.hpp>
|
||||
#include <mbgl/geometry/vao.hpp>
|
||||
#include <mbgl/geometry/elements_buffer.hpp>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <mbgl/style/bucket_parameters.hpp>
|
||||
#include <mbgl/style/filter_evaluator.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/filter.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <mbgl/renderer/render_pass.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/rapidjson.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <mapbox/geojsonvt.hpp>
|
||||
#include <mapbox/geojsonvt/convert.hpp>
|
||||
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/util/mapbox.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/tile_cover.hpp>
|
||||
|
||||
#include <mbgl/tile/raster_tile_data.hpp>
|
||||
#include <mbgl/tile/raster_tile.hpp>
|
||||
#include <mbgl/tile/geojson_tile.hpp>
|
||||
#include <mbgl/tile/vector_tile.hpp>
|
||||
#include <mbgl/annotation/annotation_tile.hpp>
|
||||
@@ -62,7 +62,7 @@ Source::~Source() = default;
|
||||
bool Source::isLoaded() const {
|
||||
if (!loaded) return false;
|
||||
|
||||
for (const auto& pair : tileDataMap) {
|
||||
for (const auto& pair : tiles) {
|
||||
if (!pair.second->isComplete()) {
|
||||
return false;
|
||||
}
|
||||
@@ -155,7 +155,7 @@ void Source::load(FileSource& fileSource) {
|
||||
|
||||
if (reloadTiles) {
|
||||
// Tile information changed because we got new GeoJSON data, or a new tile URL.
|
||||
tileDataMap.clear();
|
||||
tiles.clear();
|
||||
renderTiles.clear();
|
||||
cache.clear();
|
||||
}
|
||||
@@ -185,17 +185,17 @@ const std::map<UnwrappedTileID, RenderTile>& Source::getRenderTiles() const {
|
||||
return renderTiles;
|
||||
}
|
||||
|
||||
std::unique_ptr<TileData> Source::createTile(const OverscaledTileID& overscaledTileID,
|
||||
std::unique_ptr<Tile> Source::createTile(const OverscaledTileID& overscaledTileID,
|
||||
const UpdateParameters& parameters) {
|
||||
// If we don't find working tile data, we're just going to load it.
|
||||
if (type == SourceType::Raster) {
|
||||
return std::make_unique<RasterTileData>(overscaledTileID, parameters, *tileset);
|
||||
return std::make_unique<RasterTile>(overscaledTileID, parameters, *tileset);
|
||||
} else if (type == SourceType::Vector) {
|
||||
return std::make_unique<VectorTileData>(overscaledTileID, id, parameters, *tileset);
|
||||
return std::make_unique<VectorTile>(overscaledTileID, id, parameters, *tileset);
|
||||
} else if (type == SourceType::Annotations) {
|
||||
return std::make_unique<AnnotationTileData>(overscaledTileID, id, parameters);
|
||||
return std::make_unique<AnnotationTile>(overscaledTileID, id, parameters);
|
||||
} else if (type == SourceType::GeoJSON) {
|
||||
return std::make_unique<GeoJSONTileData>(overscaledTileID, id, parameters, geojsonvt.get());
|
||||
return std::make_unique<GeoJSONTile>(overscaledTileID, id, parameters, geojsonvt.get());
|
||||
} else {
|
||||
Log::Warning(Event::Style, "Source type '%s' is not implemented",
|
||||
SourceTypeClass(type).c_str());
|
||||
@@ -203,9 +203,9 @@ std::unique_ptr<TileData> Source::createTile(const OverscaledTileID& overscaledT
|
||||
}
|
||||
}
|
||||
|
||||
TileData* Source::getTileData(const OverscaledTileID& overscaledTileID) const {
|
||||
auto it = tileDataMap.find(overscaledTileID);
|
||||
if (it != tileDataMap.end()) {
|
||||
Tile* Source::getTile(const OverscaledTileID& overscaledTileID) const {
|
||||
auto it = tiles.find(overscaledTileID);
|
||||
if (it != tiles.end()) {
|
||||
return it->second.get();
|
||||
} else {
|
||||
return nullptr;
|
||||
@@ -241,16 +241,16 @@ bool Source::update(const UpdateParameters& parameters) {
|
||||
// we're actively using, e.g. as a replacement for tile that aren't loaded yet.
|
||||
std::set<OverscaledTileID> retain;
|
||||
|
||||
auto retainTileDataFn = [&retain](TileData& tileData, bool required) -> void {
|
||||
retain.emplace(tileData.id);
|
||||
tileData.setNecessity(required ? TileData::Necessity::Required
|
||||
: TileData::Necessity::Optional);
|
||||
auto retainTileFn = [&retain](Tile& tile, bool required) -> void {
|
||||
retain.emplace(tile.id);
|
||||
tile.setNecessity(required ? Tile::Necessity::Required
|
||||
: Tile::Necessity::Optional);
|
||||
};
|
||||
auto getTileDataFn = [this](const OverscaledTileID& dataTileID) -> TileData* {
|
||||
return getTileData(dataTileID);
|
||||
auto getTileFn = [this](const OverscaledTileID& dataTileID) -> Tile* {
|
||||
return getTile(dataTileID);
|
||||
};
|
||||
auto createTileDataFn = [this, ¶meters](const OverscaledTileID& dataTileID) -> TileData* {
|
||||
std::unique_ptr<TileData> data = cache.get(dataTileID);
|
||||
auto createTileFn = [this, ¶meters](const OverscaledTileID& dataTileID) -> Tile* {
|
||||
std::unique_ptr<Tile> data = cache.get(dataTileID);
|
||||
if (!data) {
|
||||
data = createTile(dataTileID, parameters);
|
||||
if (data) {
|
||||
@@ -258,17 +258,17 @@ bool Source::update(const UpdateParameters& parameters) {
|
||||
}
|
||||
}
|
||||
if (data) {
|
||||
return tileDataMap.emplace(dataTileID, std::move(data)).first->second.get();
|
||||
return tiles.emplace(dataTileID, std::move(data)).first->second.get();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
auto renderTileFn = [this](const UnwrappedTileID& renderTileID, TileData& tileData) {
|
||||
renderTiles.emplace(renderTileID, RenderTile{ renderTileID, tileData });
|
||||
auto renderTileFn = [this](const UnwrappedTileID& renderTileID, Tile& tile) {
|
||||
renderTiles.emplace(renderTileID, RenderTile{ renderTileID, tile });
|
||||
};
|
||||
|
||||
renderTiles.clear();
|
||||
algorithm::updateRenderables(getTileDataFn, createTileDataFn, retainTileDataFn, renderTileFn,
|
||||
algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, renderTileFn,
|
||||
idealTiles, *tileset, dataTileZoom);
|
||||
|
||||
if (type != SourceType::Raster && type != SourceType::Annotations && cache.getSize() == 0) {
|
||||
@@ -281,15 +281,15 @@ bool Source::update(const UpdateParameters& parameters) {
|
||||
}
|
||||
|
||||
// Remove stale data tiles from the active set of tiles.
|
||||
// This goes through the (sorted!) tileDataMap and retain set in lockstep and removes items from
|
||||
// tileDataMap that don't have the corresponding key in the retain set.
|
||||
auto dataIt = tileDataMap.begin();
|
||||
// This goes through the (sorted!) tiles and retain set in lockstep and removes items from
|
||||
// tiles that don't have the corresponding key in the retain set.
|
||||
auto dataIt = tiles.begin();
|
||||
auto retainIt = retain.begin();
|
||||
while (dataIt != tileDataMap.end()) {
|
||||
while (dataIt != tiles.end()) {
|
||||
if (retainIt == retain.end() || dataIt->first < *retainIt) {
|
||||
dataIt->second->setNecessity(TileData::Necessity::Optional);
|
||||
dataIt->second->setNecessity(Tile::Necessity::Optional);
|
||||
cache.add(dataIt->first, std::move(dataIt->second));
|
||||
tileDataMap.erase(dataIt++);
|
||||
tiles.erase(dataIt++);
|
||||
} else {
|
||||
if (!(*retainIt < dataIt->first)) {
|
||||
++dataIt;
|
||||
@@ -301,14 +301,14 @@ bool Source::update(const UpdateParameters& parameters) {
|
||||
const PlacementConfig newConfig{ parameters.transformState.getAngle(),
|
||||
parameters.transformState.getPitch(),
|
||||
parameters.debugOptions & MapDebugOptions::Collision };
|
||||
for (auto& pair : tileDataMap) {
|
||||
auto tileData = pair.second.get();
|
||||
if (parameters.shouldReparsePartialTiles && tileData->isIncomplete()) {
|
||||
if (!tileData->parsePending()) {
|
||||
for (auto& pair : tiles) {
|
||||
auto tile = pair.second.get();
|
||||
if (parameters.shouldReparsePartialTiles && tile->isIncomplete()) {
|
||||
if (!tile->parsePending()) {
|
||||
allTilesUpdated = false;
|
||||
}
|
||||
} else {
|
||||
tileData->redoPlacement(newConfig);
|
||||
tile->redoPlacement(newConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ std::unordered_map<std::string, std::vector<Feature>> Source::queryRenderedFeatu
|
||||
tileSpaceQueryGeometry.push_back(coordinateToTilePoint(tile.id, c));
|
||||
}
|
||||
|
||||
tile.data.queryRenderedFeatures(result,
|
||||
tile.tile.queryRenderedFeatures(result,
|
||||
tileSpaceQueryGeometry,
|
||||
parameters.transformState,
|
||||
parameters.layerIDs);
|
||||
@@ -377,12 +377,12 @@ void Source::setObserver(SourceObserver* observer_) {
|
||||
observer = observer_;
|
||||
}
|
||||
|
||||
void Source::onTileLoaded(TileData& tileData, bool isNewTile) {
|
||||
observer->onTileLoaded(*this, tileData.id, isNewTile);
|
||||
void Source::onTileLoaded(Tile& tile, bool isNewTile) {
|
||||
observer->onTileLoaded(*this, tile.id, isNewTile);
|
||||
}
|
||||
|
||||
void Source::onTileError(TileData& tileData, std::exception_ptr error) {
|
||||
observer->onTileError(*this, tileData.id, error);
|
||||
void Source::onTileError(Tile& tile, std::exception_ptr error) {
|
||||
observer->onTileError(*this, tile.id, error);
|
||||
}
|
||||
|
||||
void Source::onNeedsRepaint() {
|
||||
@@ -393,9 +393,9 @@ void Source::dumpDebugLogs() const {
|
||||
Log::Info(Event::General, "Source::id: %s", id.c_str());
|
||||
Log::Info(Event::General, "Source::loaded: %d", loaded);
|
||||
|
||||
for (const auto& pair : tileDataMap) {
|
||||
auto& tileData = pair.second;
|
||||
tileData->dumpDebugLogs();
|
||||
for (const auto& pair : tiles) {
|
||||
auto& tile = pair.second;
|
||||
tile->dumpDebugLogs();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
#include <mbgl/tile/tile_data_observer.hpp>
|
||||
#include <mbgl/tile/tile_data.hpp>
|
||||
#include <mbgl/tile/tile_observer.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/tile/tile_cache.hpp>
|
||||
#include <mbgl/style/types.hpp>
|
||||
|
||||
@@ -38,7 +38,7 @@ class UpdateParameters;
|
||||
class QueryParameters;
|
||||
class SourceObserver;
|
||||
|
||||
class Source : public TileDataObserver, private util::noncopyable {
|
||||
class Source : public TileObserver, private util::noncopyable {
|
||||
public:
|
||||
Source(SourceType,
|
||||
const std::string& id,
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
|
||||
const std::map<UnwrappedTileID, RenderTile>& getRenderTiles() const;
|
||||
|
||||
TileData* getTileData(const OverscaledTileID&) const;
|
||||
Tile* getTile(const OverscaledTileID&) const;
|
||||
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
queryRenderedFeatures(const QueryParameters&) const;
|
||||
@@ -89,12 +89,12 @@ public:
|
||||
bool enabled = false;
|
||||
|
||||
private:
|
||||
// TileDataObserver implementation.
|
||||
void onTileLoaded(TileData&, bool isNewTile) override;
|
||||
void onTileError(TileData&, std::exception_ptr) override;
|
||||
// TileObserver implementation.
|
||||
void onTileLoaded(Tile&, bool isNewTile) override;
|
||||
void onTileError(Tile&, std::exception_ptr) override;
|
||||
void onNeedsRepaint() override;
|
||||
|
||||
std::unique_ptr<TileData> createTile(const OverscaledTileID&, const UpdateParameters&);
|
||||
std::unique_ptr<Tile> createTile(const OverscaledTileID&, const UpdateParameters&);
|
||||
|
||||
private:
|
||||
std::unique_ptr<const Tileset> tileset;
|
||||
@@ -104,8 +104,8 @@ private:
|
||||
// Stores the time when this source was most recently updated.
|
||||
TimePoint updated = TimePoint::min();
|
||||
|
||||
std::map<OverscaledTileID, std::unique_ptr<Tile>> tiles;
|
||||
std::map<UnwrappedTileID, RenderTile> renderTiles;
|
||||
std::map<OverscaledTileID, std::unique_ptr<TileData>> tileDataMap;
|
||||
TileCache cache;
|
||||
|
||||
std::unique_ptr<AsyncRequest> req;
|
||||
|
||||
@@ -291,7 +291,7 @@ RenderData Style::getRenderData() const {
|
||||
|
||||
for (auto& pair : source->getRenderTiles()) {
|
||||
auto& tile = pair.second;
|
||||
if (!tile.data.isRenderable()) {
|
||||
if (!tile.tile.isRenderable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ RenderData Style::getRenderData() const {
|
||||
// already a bucket from this layer that is a parent of this tile. Tiles are ordered
|
||||
// by zoom level when we obtain them from getTiles().
|
||||
for (auto it = result.order.rbegin(); it != result.order.rend() && (&it->layer == layer.get()); ++it) {
|
||||
if (tile.data.id.isChildOf(it->tile->data.id)) {
|
||||
if (tile.tile.id.isChildOf(it->tile->tile.id)) {
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ RenderData Style::getRenderData() const {
|
||||
}
|
||||
}
|
||||
|
||||
auto bucket = tile.data.getBucket(*layer);
|
||||
auto bucket = tile.tile.getBucket(*layer);
|
||||
if (bucket) {
|
||||
result.order.emplace_back(*layer, &tile, bucket);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <mbgl/geometry/anchor.hpp>
|
||||
#include <mbgl/text/shaping.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/geometry/anchor.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <mbgl/text/quads.hpp>
|
||||
#include <mbgl/text/shaping.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/geometry/anchor.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_properties.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/text/glyph.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mbgl/tile/geojson_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/style/update_parameters.hpp>
|
||||
|
||||
#include <mapbox/geojsonvt.hpp>
|
||||
@@ -36,9 +36,9 @@ private:
|
||||
const Features features;
|
||||
};
|
||||
|
||||
class GeoJSONTile : public GeometryTile {
|
||||
class GeoJSONTileData : public GeometryTileData {
|
||||
public:
|
||||
GeoJSONTile(std::shared_ptr<GeoJSONTileLayer>);
|
||||
GeoJSONTileData(std::shared_ptr<GeoJSONTileLayer>);
|
||||
util::ptr<GeometryTileLayer> getLayer(const std::string&) const override;
|
||||
|
||||
private:
|
||||
@@ -46,7 +46,7 @@ private:
|
||||
};
|
||||
|
||||
// Converts the geojsonvt::Tile to a a GeoJSONTile. They have a differing internal structure.
|
||||
std::unique_ptr<GeoJSONTile> convertTile(const mapbox::geojsonvt::Tile& tile) {
|
||||
std::unique_ptr<GeoJSONTileData> convertTile(const mapbox::geojsonvt::Tile& tile) {
|
||||
std::shared_ptr<GeoJSONTileLayer> layer;
|
||||
|
||||
if (tile) {
|
||||
@@ -103,24 +103,20 @@ std::unique_ptr<GeoJSONTile> convertTile(const mapbox::geojsonvt::Tile& tile) {
|
||||
layer = std::make_unique<GeoJSONTileLayer>(std::move(features));
|
||||
}
|
||||
|
||||
return std::make_unique<GeoJSONTile>(layer);
|
||||
return std::make_unique<GeoJSONTileData>(layer);
|
||||
}
|
||||
|
||||
GeoJSONTileData::GeoJSONTileData(const OverscaledTileID& overscaledTileID,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters& parameters,
|
||||
mapbox::geojsonvt::GeoJSONVT* geojsonvt)
|
||||
: GeometryTileData(overscaledTileID, sourceID, parameters.style, parameters.mode) {
|
||||
GeoJSONTile::GeoJSONTile(const OverscaledTileID& overscaledTileID,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters& parameters,
|
||||
mapbox::geojsonvt::GeoJSONVT* geojsonvt)
|
||||
: GeometryTile(overscaledTileID, sourceID, parameters.style, parameters.mode) {
|
||||
if (geojsonvt) {
|
||||
auto tile = convertTile(
|
||||
geojsonvt->getTile(id.canonical.z, id.canonical.x, id.canonical.y));
|
||||
setData(std::move(tile), {}, {});
|
||||
setData(convertTile(geojsonvt->getTile(id.canonical.z, id.canonical.x, id.canonical.y)), {}, {});
|
||||
}
|
||||
}
|
||||
|
||||
GeoJSONTileData::~GeoJSONTileData() = default;
|
||||
|
||||
void GeoJSONTileData::setNecessity(Necessity) {}
|
||||
void GeoJSONTile::setNecessity(Necessity) {}
|
||||
|
||||
GeoJSONTileFeature::GeoJSONTileFeature(FeatureType type_,
|
||||
GeometryCollection&& geometries_,
|
||||
@@ -155,10 +151,10 @@ util::ptr<const GeometryTileFeature> GeoJSONTileLayer::getFeature(std::size_t i)
|
||||
return features[i];
|
||||
}
|
||||
|
||||
GeoJSONTile::GeoJSONTile(std::shared_ptr<GeoJSONTileLayer> layer_) : layer(std::move(layer_)) {
|
||||
GeoJSONTileData::GeoJSONTileData(std::shared_ptr<GeoJSONTileLayer> layer_) : layer(std::move(layer_)) {
|
||||
}
|
||||
|
||||
util::ptr<GeometryTileLayer> GeoJSONTile::getLayer(const std::string&) const {
|
||||
util::ptr<GeometryTileLayer> GeoJSONTileData::getLayer(const std::string&) const {
|
||||
// We're ignoring the layer name because GeoJSON tiles only have one layer.
|
||||
return layer;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
|
||||
namespace mapbox {
|
||||
namespace geojsonvt {
|
||||
@@ -14,13 +14,12 @@ namespace style {
|
||||
class UpdateParameters;
|
||||
}
|
||||
|
||||
class GeoJSONTileData : public GeometryTileData {
|
||||
class GeoJSONTile : public GeometryTile {
|
||||
public:
|
||||
GeoJSONTileData(const OverscaledTileID&,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters&,
|
||||
mapbox::geojsonvt::GeoJSONVT*);
|
||||
~GeoJSONTileData();
|
||||
GeoJSONTile(const OverscaledTileID&,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters&,
|
||||
mapbox::geojsonvt::GeoJSONVT*);
|
||||
|
||||
void setNecessity(Necessity) final;
|
||||
};
|
||||
|
||||
@@ -1,210 +1,206 @@
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
|
||||
#include <clipper/clipper.hpp>
|
||||
#include <mbgl/tile/tile_observer.hpp>
|
||||
#include <mbgl/tile/tile_source.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/style/layer_impl.hpp>
|
||||
#include <mbgl/util/worker.hpp>
|
||||
#include <mbgl/util/work_request.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
#include <mbgl/text/collision_tile.hpp>
|
||||
#include <mbgl/map/transform_state.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
static double signedArea(const GeometryCoordinates& ring) {
|
||||
double sum = 0;
|
||||
|
||||
for (std::size_t i = 0, len = ring.size(), j = len - 1; i < len; j = i++) {
|
||||
const GeometryCoordinate& p1 = ring[i];
|
||||
const GeometryCoordinate& p2 = ring[j];
|
||||
sum += (p2.x - p1.x) * (p1.y + p2.y);
|
||||
}
|
||||
|
||||
return sum;
|
||||
GeometryTile::GeometryTile(const OverscaledTileID& id_,
|
||||
std::string sourceID,
|
||||
style::Style& style_,
|
||||
const MapMode mode_)
|
||||
: Tile(id_),
|
||||
style(style_),
|
||||
worker(style_.workers),
|
||||
tileWorker(id_,
|
||||
sourceID,
|
||||
*style_.spriteStore,
|
||||
*style_.glyphAtlas,
|
||||
*style_.glyphStore,
|
||||
obsolete,
|
||||
mode_) {
|
||||
}
|
||||
|
||||
static ClipperLib::Path toClipperPath(const GeometryCoordinates& ring) {
|
||||
ClipperLib::Path result;
|
||||
result.reserve(ring.size());
|
||||
for (const auto& p : ring) {
|
||||
result.emplace_back(p.x, p.y);
|
||||
}
|
||||
return result;
|
||||
void GeometryTile::setError(std::exception_ptr err) {
|
||||
observer->onTileError(*this, err);
|
||||
}
|
||||
|
||||
static GeometryCoordinates fromClipperPath(const ClipperLib::Path& path) {
|
||||
GeometryCoordinates result;
|
||||
result.reserve(path.size());
|
||||
for (const auto& p : path) {
|
||||
using Coordinate = GeometryCoordinates::coordinate_type;
|
||||
assert(p.x >= std::numeric_limits<Coordinate>::min());
|
||||
assert(p.x <= std::numeric_limits<Coordinate>::max());
|
||||
assert(p.y >= std::numeric_limits<Coordinate>::min());
|
||||
assert(p.y <= std::numeric_limits<Coordinate>::max());
|
||||
result.emplace_back(Coordinate(p.x), Coordinate(p.y));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
void GeometryTile::setData(std::unique_ptr<GeometryTileData> data_,
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> expires_) {
|
||||
modified = modified_;
|
||||
expires = expires_;
|
||||
|
||||
static void processPolynodeBranch(ClipperLib::PolyNode* polynode, GeometryCollection& rings) {
|
||||
// Exterior ring.
|
||||
rings.push_back(fromClipperPath(polynode->Contour));
|
||||
assert(signedArea(rings.back()) > 0);
|
||||
|
||||
// Interior rings.
|
||||
for (auto * ring : polynode->Childs) {
|
||||
rings.push_back(fromClipperPath(ring->Contour));
|
||||
assert(signedArea(rings.back()) < 0);
|
||||
if (!data_) {
|
||||
// This is a 404 response. We're treating these as empty tiles.
|
||||
workRequest.reset();
|
||||
availableData = DataAvailability::All;
|
||||
buckets.clear();
|
||||
redoPlacement();
|
||||
observer->onTileLoaded(*this, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// PolyNodes may be nested in the case of a polygon inside a hole.
|
||||
for (auto * ring : polynode->Childs) {
|
||||
for (auto * subRing : ring->Childs) {
|
||||
processPolynodeBranch(subRing, rings);
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Kick off a fresh parse of this tile. This happens when the tile is new, or
|
||||
// when tile data changed. Replacing the workdRequest will cancel a pending work
|
||||
// request in case there is one.
|
||||
workRequest.reset();
|
||||
workRequest = worker.parseGeometryTile(tileWorker, style.getLayers(), std::move(data_), targetConfig, [this, config = targetConfig] (TileParseResult result) {
|
||||
workRequest.reset();
|
||||
|
||||
if (result.is<TileParseResultData>()) {
|
||||
auto& resultBuckets = result.get<TileParseResultData>();
|
||||
availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some;
|
||||
|
||||
// Persist the configuration we just placed so that we can later check whether we need to
|
||||
// place again in case the configuration has changed.
|
||||
placedConfig = config;
|
||||
|
||||
// Move over all buckets we received in this parse request, potentially overwriting
|
||||
// existing buckets in case we got a refresh parse.
|
||||
buckets = std::move(resultBuckets.buckets);
|
||||
|
||||
if (isComplete()) {
|
||||
featureIndex = std::move(resultBuckets.featureIndex);
|
||||
data = std::move(resultBuckets.tileData);
|
||||
}
|
||||
|
||||
redoPlacement();
|
||||
observer->onTileLoaded(*this, true);
|
||||
} else {
|
||||
availableData = DataAvailability::All;
|
||||
observer->onTileError(*this, result.get<std::exception_ptr>());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GeometryCollection fixupPolygons(const GeometryCollection& rings) {
|
||||
ClipperLib::Clipper clipper;
|
||||
clipper.StrictlySimple(true);
|
||||
|
||||
for (const auto& ring : rings) {
|
||||
clipper.AddPath(toClipperPath(ring), ClipperLib::ptSubject, true);
|
||||
}
|
||||
|
||||
ClipperLib::PolyTree polygons;
|
||||
clipper.Execute(ClipperLib::ctUnion, polygons, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
|
||||
clipper.Clear();
|
||||
|
||||
GeometryCollection result;
|
||||
for (auto * polynode : polygons.Childs) {
|
||||
processPolynodeBranch(polynode, result);
|
||||
}
|
||||
return result;
|
||||
GeometryTile::~GeometryTile() {
|
||||
cancel();
|
||||
}
|
||||
|
||||
std::vector<GeometryCollection> classifyRings(const GeometryCollection& rings) {
|
||||
std::vector<GeometryCollection> polygons;
|
||||
|
||||
std::size_t len = rings.size();
|
||||
|
||||
if (len <= 1) {
|
||||
polygons.push_back(rings);
|
||||
return polygons;
|
||||
bool GeometryTile::parsePending() {
|
||||
if (workRequest) {
|
||||
// There's already parsing or placement going on.
|
||||
return false;
|
||||
}
|
||||
|
||||
GeometryCollection polygon;
|
||||
int8_t ccw = 0;
|
||||
workRequest.reset();
|
||||
workRequest = worker.parsePendingGeometryTileLayers(tileWorker, targetConfig, [this, config = targetConfig] (TileParseResult result) {
|
||||
workRequest.reset();
|
||||
|
||||
for (std::size_t i = 0; i < len; i++) {
|
||||
double area = signedArea(rings[i]);
|
||||
if (result.is<TileParseResultData>()) {
|
||||
auto& resultBuckets = result.get<TileParseResultData>();
|
||||
availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some;
|
||||
|
||||
if (area == 0)
|
||||
continue;
|
||||
// Move over all buckets we received in this parse request, potentially overwriting
|
||||
// existing buckets in case we got a refresh parse.
|
||||
for (auto& bucket : resultBuckets.buckets) {
|
||||
buckets[bucket.first] = std::move(bucket.second);
|
||||
}
|
||||
|
||||
if (ccw == 0)
|
||||
ccw = (area < 0 ? -1 : 1);
|
||||
// Persist the configuration we just placed so that we can later check whether we need to
|
||||
// place again in case the configuration has changed.
|
||||
placedConfig = config;
|
||||
|
||||
if (ccw == (area < 0 ? -1 : 1) && !polygon.empty()) {
|
||||
polygons.push_back(polygon);
|
||||
polygon.clear();
|
||||
if (isComplete()) {
|
||||
featureIndex = std::move(resultBuckets.featureIndex);
|
||||
data = std::move(resultBuckets.tileData);
|
||||
}
|
||||
|
||||
redoPlacement();
|
||||
observer->onTileLoaded(*this, false);
|
||||
} else {
|
||||
availableData = DataAvailability::All;
|
||||
observer->onTileError(*this, result.get<std::exception_ptr>());
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Bucket* GeometryTile::getBucket(const style::Layer& layer) {
|
||||
const auto it = buckets.find(layer.baseImpl->bucketName());
|
||||
if (it == buckets.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
assert(it->second);
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
void GeometryTile::redoPlacement(const PlacementConfig newConfig) {
|
||||
targetConfig = newConfig;
|
||||
redoPlacement();
|
||||
}
|
||||
|
||||
void GeometryTile::redoPlacement() {
|
||||
// Don't start a new placement request when the current one hasn't completed yet, or when
|
||||
// we are parsing buckets.
|
||||
if (workRequest || targetConfig == placedConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
workRequest = worker.redoPlacement(tileWorker, buckets, targetConfig, [this, config = targetConfig](std::unique_ptr<CollisionTile> collisionTile) {
|
||||
workRequest.reset();
|
||||
|
||||
// Persist the configuration we just placed so that we can later check whether we need to
|
||||
// place again in case the configuration has changed.
|
||||
placedConfig = config;
|
||||
|
||||
for (auto& bucket : buckets) {
|
||||
bucket.second->swapRenderData();
|
||||
}
|
||||
|
||||
polygon.push_back(rings[i]);
|
||||
}
|
||||
if (featureIndex) {
|
||||
featureIndex->setCollisionTile(std::move(collisionTile));
|
||||
}
|
||||
|
||||
if (!polygon.empty())
|
||||
polygons.push_back(polygon);
|
||||
|
||||
return polygons;
|
||||
// The target configuration could have changed since we started placement. In this case,
|
||||
// we're starting another placement run.
|
||||
if (placedConfig != targetConfig) {
|
||||
redoPlacement();
|
||||
} else {
|
||||
observer->onNeedsRepaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void limitHoles(GeometryCollection& polygon, uint32_t maxHoles) {
|
||||
if (polygon.size() > 1 + maxHoles) {
|
||||
std::nth_element(polygon.begin() + 1,
|
||||
polygon.begin() + 1 + maxHoles,
|
||||
polygon.end(),
|
||||
[] (const auto& a, const auto& b) {
|
||||
return signedArea(a) > signedArea(b);
|
||||
});
|
||||
polygon.resize(1 + maxHoles);
|
||||
}
|
||||
void GeometryTile::queryRenderedFeatures(
|
||||
std::unordered_map<std::string, std::vector<Feature>>& result,
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
const TransformState& transformState,
|
||||
const optional<std::vector<std::string>>& 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);
|
||||
}
|
||||
|
||||
static Feature::geometry_type convertGeometry(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) {
|
||||
const double size = util::EXTENT * std::pow(2, tileID.z);
|
||||
const double x0 = util::EXTENT * tileID.x;
|
||||
const double y0 = util::EXTENT * tileID.y;
|
||||
|
||||
auto tileCoordinatesToLatLng = [&] (const Point<int16_t>& p) {
|
||||
double y2 = 180 - (p.y + y0) * 360 / size;
|
||||
return Point<double>(
|
||||
(p.x + x0) * 360 / size - 180,
|
||||
360.0 / M_PI * std::atan(std::exp(y2 * M_PI / 180)) - 90.0
|
||||
);
|
||||
};
|
||||
|
||||
GeometryCollection geometries = geometryTileFeature.getGeometries();
|
||||
|
||||
switch (geometryTileFeature.getType()) {
|
||||
case FeatureType::Unknown: {
|
||||
assert(false);
|
||||
return Point<double>(NAN, NAN);
|
||||
}
|
||||
|
||||
case FeatureType::Point: {
|
||||
MultiPoint<double> multiPoint;
|
||||
for (const auto& p : geometries.at(0)) {
|
||||
multiPoint.push_back(tileCoordinatesToLatLng(p));
|
||||
}
|
||||
if (multiPoint.size() == 1) {
|
||||
return multiPoint[0];
|
||||
} else {
|
||||
return multiPoint;
|
||||
}
|
||||
}
|
||||
|
||||
case FeatureType::LineString: {
|
||||
MultiLineString<double> multiLineString;
|
||||
for (const auto& g : geometries) {
|
||||
LineString<double> lineString;
|
||||
for (const auto& p : g) {
|
||||
lineString.push_back(tileCoordinatesToLatLng(p));
|
||||
}
|
||||
multiLineString.push_back(std::move(lineString));
|
||||
}
|
||||
if (multiLineString.size() == 1) {
|
||||
return multiLineString[0];
|
||||
} else {
|
||||
return multiLineString;
|
||||
}
|
||||
}
|
||||
|
||||
case FeatureType::Polygon: {
|
||||
MultiPolygon<double> multiPolygon;
|
||||
for (const auto& pg : classifyRings(geometries)) {
|
||||
Polygon<double> polygon;
|
||||
for (const auto& r : pg) {
|
||||
LinearRing<double> linearRing;
|
||||
for (const auto& p : r) {
|
||||
linearRing.push_back(tileCoordinatesToLatLng(p));
|
||||
}
|
||||
polygon.push_back(std::move(linearRing));
|
||||
}
|
||||
multiPolygon.push_back(std::move(polygon));
|
||||
}
|
||||
if (multiPolygon.size() == 1) {
|
||||
return multiPolygon[0];
|
||||
} else {
|
||||
return multiPolygon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unreachable, but placate GCC.
|
||||
return Point<double>();
|
||||
}
|
||||
|
||||
Feature convertFeature(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) {
|
||||
Feature feature { convertGeometry(geometryTileFeature, tileID) };
|
||||
feature.properties = geometryTileFeature.getProperties();
|
||||
feature.id = geometryTileFeature.getID();
|
||||
return feature;
|
||||
void GeometryTile::cancel() {
|
||||
obsolete = true;
|
||||
workRequest.reset();
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,83 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/tile/tile_worker.hpp>
|
||||
#include <mbgl/text/placement_config.hpp>
|
||||
#include <mbgl/util/atomic.hpp>
|
||||
#include <mbgl/util/feature.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/variant.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
enum class FeatureType : uint8_t {
|
||||
Unknown = 0,
|
||||
Point = 1,
|
||||
LineString = 2,
|
||||
Polygon = 3
|
||||
};
|
||||
class AsyncRequest;
|
||||
class GeometryTileData;
|
||||
class FeatureIndex;
|
||||
|
||||
class CanonicalTileID;
|
||||
namespace style {
|
||||
class Style;
|
||||
}
|
||||
|
||||
// Normalized vector tile coordinates.
|
||||
// Each geometry coordinate represents a point in a bidimensional space,
|
||||
// varying from -V...0...+V, where V is the maximum extent applicable.
|
||||
using GeometryCoordinate = Point<int16_t>;
|
||||
|
||||
class GeometryCoordinates : public std::vector<GeometryCoordinate> {
|
||||
class GeometryTile : public Tile {
|
||||
public:
|
||||
using coordinate_type = int16_t;
|
||||
using std::vector<GeometryCoordinate>::vector;
|
||||
GeometryTile(const OverscaledTileID&,
|
||||
std::string sourceID,
|
||||
style::Style&,
|
||||
const MapMode);
|
||||
|
||||
~GeometryTile();
|
||||
|
||||
void setError(std::exception_ptr err);
|
||||
|
||||
void setData(std::unique_ptr<GeometryTileData>,
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> expires_);
|
||||
|
||||
Bucket* getBucket(const style::Layer&) override;
|
||||
|
||||
bool parsePending() override;
|
||||
|
||||
void redoPlacement(PlacementConfig) override;
|
||||
|
||||
void queryRenderedFeatures(
|
||||
std::unordered_map<std::string, std::vector<Feature>>& result,
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
const TransformState&,
|
||||
const optional<std::vector<std::string>>& layerIDs) override;
|
||||
|
||||
void cancel() override;
|
||||
|
||||
private:
|
||||
void redoPlacement();
|
||||
|
||||
style::Style& style;
|
||||
Worker& worker;
|
||||
TileWorker tileWorker;
|
||||
|
||||
std::unique_ptr<AsyncRequest> workRequest;
|
||||
|
||||
// Contains all the Bucket objects for the tile. Buckets are render
|
||||
// objects and they get added by tile parsing operations.
|
||||
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
|
||||
|
||||
std::unique_ptr<FeatureIndex> featureIndex;
|
||||
std::unique_ptr<const GeometryTileData> data;
|
||||
|
||||
// Stores the placement configuration of the text that is currently placed on the screen.
|
||||
PlacementConfig placedConfig;
|
||||
|
||||
// Stores the placement configuration of how the text should be placed. This isn't necessarily
|
||||
// the one that is being displayed.
|
||||
PlacementConfig targetConfig;
|
||||
|
||||
// Used to signal the worker that it should abandon parsing this tile as soon as possible.
|
||||
util::Atomic<bool> obsolete { false };
|
||||
};
|
||||
|
||||
class GeometryCollection : public std::vector<GeometryCoordinates> {
|
||||
public:
|
||||
using coordinate_type = int16_t;
|
||||
using std::vector<GeometryCoordinates>::vector;
|
||||
};
|
||||
|
||||
class GeometryTileFeature : private util::noncopyable {
|
||||
public:
|
||||
virtual ~GeometryTileFeature() = default;
|
||||
virtual FeatureType getType() const = 0;
|
||||
virtual optional<Value> getValue(const std::string& key) const = 0;
|
||||
virtual Feature::property_map getProperties() const { return Feature::property_map(); }
|
||||
virtual optional<uint64_t> getID() const { return {}; }
|
||||
virtual GeometryCollection getGeometries() const = 0;
|
||||
};
|
||||
|
||||
class GeometryTileLayer : private util::noncopyable {
|
||||
public:
|
||||
virtual ~GeometryTileLayer() = default;
|
||||
virtual std::size_t featureCount() const = 0;
|
||||
virtual util::ptr<const GeometryTileFeature> getFeature(std::size_t) const = 0;
|
||||
virtual std::string getName() const = 0;
|
||||
};
|
||||
|
||||
class GeometryTile : private util::noncopyable {
|
||||
public:
|
||||
virtual ~GeometryTile() = default;
|
||||
virtual util::ptr<GeometryTileLayer> getLayer(const std::string&) const = 0;
|
||||
};
|
||||
|
||||
// classifies an array of rings into polygons with outer rings and holes
|
||||
std::vector<GeometryCollection> classifyRings(const GeometryCollection&);
|
||||
|
||||
// Truncate polygon to the largest `maxHoles` inner rings by area.
|
||||
void limitHoles(GeometryCollection&, uint32_t maxHoles);
|
||||
|
||||
// convert from GeometryTileFeature to Feature (eventually we should eliminate GeometryTileFeature)
|
||||
Feature convertFeature(const GeometryTileFeature&, const CanonicalTileID&);
|
||||
|
||||
// Fix up possibly-non-V2-compliant polygon geometry using angus clipper.
|
||||
// The result is guaranteed to have correctly wound, strictly simple rings.
|
||||
GeometryCollection fixupPolygons(const GeometryCollection&);
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,206 +1,210 @@
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/tile/tile_data_observer.hpp>
|
||||
#include <mbgl/tile/tile_source.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/style/layer_impl.hpp>
|
||||
#include <mbgl/util/worker.hpp>
|
||||
#include <mbgl/util/work_request.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
#include <mbgl/text/collision_tile.hpp>
|
||||
#include <mbgl/map/transform_state.hpp>
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
|
||||
#include <clipper/clipper.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
GeometryTileData::GeometryTileData(const OverscaledTileID& id_,
|
||||
std::string sourceID,
|
||||
style::Style& style_,
|
||||
const MapMode mode_)
|
||||
: TileData(id_),
|
||||
style(style_),
|
||||
worker(style_.workers),
|
||||
tileWorker(id_,
|
||||
sourceID,
|
||||
*style_.spriteStore,
|
||||
*style_.glyphAtlas,
|
||||
*style_.glyphStore,
|
||||
obsolete,
|
||||
mode_) {
|
||||
}
|
||||
static double signedArea(const GeometryCoordinates& ring) {
|
||||
double sum = 0;
|
||||
|
||||
void GeometryTileData::setError(std::exception_ptr err) {
|
||||
observer->onTileError(*this, err);
|
||||
}
|
||||
|
||||
void GeometryTileData::setData(std::unique_ptr<GeometryTile> tile,
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> expires_) {
|
||||
modified = modified_;
|
||||
expires = expires_;
|
||||
|
||||
if (!tile) {
|
||||
// This is a 404 response. We're treating these as empty tiles.
|
||||
workRequest.reset();
|
||||
availableData = DataAvailability::All;
|
||||
buckets.clear();
|
||||
redoPlacement();
|
||||
observer->onTileLoaded(*this, true);
|
||||
return;
|
||||
for (std::size_t i = 0, len = ring.size(), j = len - 1; i < len; j = i++) {
|
||||
const GeometryCoordinate& p1 = ring[i];
|
||||
const GeometryCoordinate& p2 = ring[j];
|
||||
sum += (p2.x - p1.x) * (p1.y + p2.y);
|
||||
}
|
||||
|
||||
// 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;
|
||||
return sum;
|
||||
}
|
||||
|
||||
static ClipperLib::Path toClipperPath(const GeometryCoordinates& ring) {
|
||||
ClipperLib::Path result;
|
||||
result.reserve(ring.size());
|
||||
for (const auto& p : ring) {
|
||||
result.emplace_back(p.x, p.y);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static GeometryCoordinates fromClipperPath(const ClipperLib::Path& path) {
|
||||
GeometryCoordinates result;
|
||||
result.reserve(path.size());
|
||||
for (const auto& p : path) {
|
||||
using Coordinate = GeometryCoordinates::coordinate_type;
|
||||
assert(p.x >= std::numeric_limits<Coordinate>::min());
|
||||
assert(p.x <= std::numeric_limits<Coordinate>::max());
|
||||
assert(p.y >= std::numeric_limits<Coordinate>::min());
|
||||
assert(p.y <= std::numeric_limits<Coordinate>::max());
|
||||
result.emplace_back(Coordinate(p.x), Coordinate(p.y));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void processPolynodeBranch(ClipperLib::PolyNode* polynode, GeometryCollection& rings) {
|
||||
// Exterior ring.
|
||||
rings.push_back(fromClipperPath(polynode->Contour));
|
||||
assert(signedArea(rings.back()) > 0);
|
||||
|
||||
// Interior rings.
|
||||
for (auto * ring : polynode->Childs) {
|
||||
rings.push_back(fromClipperPath(ring->Contour));
|
||||
assert(signedArea(rings.back()) < 0);
|
||||
}
|
||||
|
||||
// Kick off a fresh parse of this tile. This happens when the tile is new, or
|
||||
// when tile data changed. Replacing the workdRequest will cancel a pending work
|
||||
// request in case there is one.
|
||||
workRequest.reset();
|
||||
workRequest = worker.parseGeometryTile(tileWorker, style.getLayers(), std::move(tile), targetConfig, [this, config = targetConfig] (TileParseResult result) {
|
||||
workRequest.reset();
|
||||
// PolyNodes may be nested in the case of a polygon inside a hole.
|
||||
for (auto * ring : polynode->Childs) {
|
||||
for (auto * subRing : ring->Childs) {
|
||||
processPolynodeBranch(subRing, rings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.is<TileParseResultData>()) {
|
||||
auto& resultBuckets = result.get<TileParseResultData>();
|
||||
availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some;
|
||||
GeometryCollection fixupPolygons(const GeometryCollection& rings) {
|
||||
ClipperLib::Clipper clipper;
|
||||
clipper.StrictlySimple(true);
|
||||
|
||||
// Persist the configuration we just placed so that we can later check whether we need to
|
||||
// place again in case the configuration has changed.
|
||||
placedConfig = config;
|
||||
for (const auto& ring : rings) {
|
||||
clipper.AddPath(toClipperPath(ring), ClipperLib::ptSubject, true);
|
||||
}
|
||||
|
||||
// Move over all buckets we received in this parse request, potentially overwriting
|
||||
// existing buckets in case we got a refresh parse.
|
||||
buckets = std::move(resultBuckets.buckets);
|
||||
ClipperLib::PolyTree polygons;
|
||||
clipper.Execute(ClipperLib::ctUnion, polygons, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
|
||||
clipper.Clear();
|
||||
|
||||
if (isComplete()) {
|
||||
featureIndex = std::move(resultBuckets.featureIndex);
|
||||
geometryTile = std::move(resultBuckets.geometryTile);
|
||||
GeometryCollection result;
|
||||
for (auto * polynode : polygons.Childs) {
|
||||
processPolynodeBranch(polynode, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<GeometryCollection> classifyRings(const GeometryCollection& rings) {
|
||||
std::vector<GeometryCollection> polygons;
|
||||
|
||||
std::size_t len = rings.size();
|
||||
|
||||
if (len <= 1) {
|
||||
polygons.push_back(rings);
|
||||
return polygons;
|
||||
}
|
||||
|
||||
GeometryCollection polygon;
|
||||
int8_t ccw = 0;
|
||||
|
||||
for (std::size_t i = 0; i < len; i++) {
|
||||
double area = signedArea(rings[i]);
|
||||
|
||||
if (area == 0)
|
||||
continue;
|
||||
|
||||
if (ccw == 0)
|
||||
ccw = (area < 0 ? -1 : 1);
|
||||
|
||||
if (ccw == (area < 0 ? -1 : 1) && !polygon.empty()) {
|
||||
polygons.push_back(polygon);
|
||||
polygon.clear();
|
||||
}
|
||||
|
||||
polygon.push_back(rings[i]);
|
||||
}
|
||||
|
||||
if (!polygon.empty())
|
||||
polygons.push_back(polygon);
|
||||
|
||||
return polygons;
|
||||
}
|
||||
|
||||
void limitHoles(GeometryCollection& polygon, uint32_t maxHoles) {
|
||||
if (polygon.size() > 1 + maxHoles) {
|
||||
std::nth_element(polygon.begin() + 1,
|
||||
polygon.begin() + 1 + maxHoles,
|
||||
polygon.end(),
|
||||
[] (const auto& a, const auto& b) {
|
||||
return signedArea(a) > signedArea(b);
|
||||
});
|
||||
polygon.resize(1 + maxHoles);
|
||||
}
|
||||
}
|
||||
|
||||
static Feature::geometry_type convertGeometry(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) {
|
||||
const double size = util::EXTENT * std::pow(2, tileID.z);
|
||||
const double x0 = util::EXTENT * tileID.x;
|
||||
const double y0 = util::EXTENT * tileID.y;
|
||||
|
||||
auto tileCoordinatesToLatLng = [&] (const Point<int16_t>& p) {
|
||||
double y2 = 180 - (p.y + y0) * 360 / size;
|
||||
return Point<double>(
|
||||
(p.x + x0) * 360 / size - 180,
|
||||
360.0 / M_PI * std::atan(std::exp(y2 * M_PI / 180)) - 90.0
|
||||
);
|
||||
};
|
||||
|
||||
GeometryCollection geometries = geometryTileFeature.getGeometries();
|
||||
|
||||
switch (geometryTileFeature.getType()) {
|
||||
case FeatureType::Unknown: {
|
||||
assert(false);
|
||||
return Point<double>(NAN, NAN);
|
||||
}
|
||||
|
||||
case FeatureType::Point: {
|
||||
MultiPoint<double> multiPoint;
|
||||
for (const auto& p : geometries.at(0)) {
|
||||
multiPoint.push_back(tileCoordinatesToLatLng(p));
|
||||
}
|
||||
|
||||
redoPlacement();
|
||||
observer->onTileLoaded(*this, true);
|
||||
} else {
|
||||
availableData = DataAvailability::All;
|
||||
observer->onTileError(*this, result.get<std::exception_ptr>());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GeometryTileData::~GeometryTileData() {
|
||||
cancel();
|
||||
}
|
||||
|
||||
bool GeometryTileData::parsePending() {
|
||||
if (workRequest) {
|
||||
// There's already parsing or placement going on.
|
||||
return false;
|
||||
}
|
||||
|
||||
workRequest.reset();
|
||||
workRequest = worker.parsePendingGeometryTileLayers(tileWorker, targetConfig, [this, config = targetConfig] (TileParseResult result) {
|
||||
workRequest.reset();
|
||||
|
||||
if (result.is<TileParseResultData>()) {
|
||||
auto& resultBuckets = result.get<TileParseResultData>();
|
||||
availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some;
|
||||
|
||||
// Move over all buckets we received in this parse request, potentially overwriting
|
||||
// existing buckets in case we got a refresh parse.
|
||||
for (auto& bucket : resultBuckets.buckets) {
|
||||
buckets[bucket.first] = std::move(bucket.second);
|
||||
if (multiPoint.size() == 1) {
|
||||
return multiPoint[0];
|
||||
} else {
|
||||
return multiPoint;
|
||||
}
|
||||
}
|
||||
|
||||
// Persist the configuration we just placed so that we can later check whether we need to
|
||||
// place again in case the configuration has changed.
|
||||
placedConfig = config;
|
||||
|
||||
if (isComplete()) {
|
||||
featureIndex = std::move(resultBuckets.featureIndex);
|
||||
geometryTile = std::move(resultBuckets.geometryTile);
|
||||
case FeatureType::LineString: {
|
||||
MultiLineString<double> multiLineString;
|
||||
for (const auto& g : geometries) {
|
||||
LineString<double> lineString;
|
||||
for (const auto& p : g) {
|
||||
lineString.push_back(tileCoordinatesToLatLng(p));
|
||||
}
|
||||
multiLineString.push_back(std::move(lineString));
|
||||
}
|
||||
if (multiLineString.size() == 1) {
|
||||
return multiLineString[0];
|
||||
} else {
|
||||
return multiLineString;
|
||||
}
|
||||
|
||||
redoPlacement();
|
||||
observer->onTileLoaded(*this, false);
|
||||
} else {
|
||||
availableData = DataAvailability::All;
|
||||
observer->onTileError(*this, result.get<std::exception_ptr>());
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Bucket* GeometryTileData::getBucket(const style::Layer& layer) {
|
||||
const auto it = buckets.find(layer.baseImpl->bucketName());
|
||||
if (it == buckets.end()) {
|
||||
return nullptr;
|
||||
case FeatureType::Polygon: {
|
||||
MultiPolygon<double> multiPolygon;
|
||||
for (const auto& pg : classifyRings(geometries)) {
|
||||
Polygon<double> polygon;
|
||||
for (const auto& r : pg) {
|
||||
LinearRing<double> linearRing;
|
||||
for (const auto& p : r) {
|
||||
linearRing.push_back(tileCoordinatesToLatLng(p));
|
||||
}
|
||||
polygon.push_back(std::move(linearRing));
|
||||
}
|
||||
multiPolygon.push_back(std::move(polygon));
|
||||
}
|
||||
if (multiPolygon.size() == 1) {
|
||||
return multiPolygon[0];
|
||||
} else {
|
||||
return multiPolygon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(it->second);
|
||||
return it->second.get();
|
||||
// Unreachable, but placate GCC.
|
||||
return Point<double>();
|
||||
}
|
||||
|
||||
void GeometryTileData::redoPlacement(const PlacementConfig newConfig) {
|
||||
targetConfig = newConfig;
|
||||
redoPlacement();
|
||||
}
|
||||
|
||||
void GeometryTileData::redoPlacement() {
|
||||
// Don't start a new placement request when the current one hasn't completed yet, or when
|
||||
// we are parsing buckets.
|
||||
if (workRequest || targetConfig == placedConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
workRequest = worker.redoPlacement(tileWorker, buckets, targetConfig, [this, config = targetConfig](std::unique_ptr<CollisionTile> collisionTile) {
|
||||
workRequest.reset();
|
||||
|
||||
// Persist the configuration we just placed so that we can later check whether we need to
|
||||
// place again in case the configuration has changed.
|
||||
placedConfig = config;
|
||||
|
||||
for (auto& bucket : buckets) {
|
||||
bucket.second->swapRenderData();
|
||||
}
|
||||
|
||||
if (featureIndex) {
|
||||
featureIndex->setCollisionTile(std::move(collisionTile));
|
||||
}
|
||||
|
||||
// The target configuration could have changed since we started placement. In this case,
|
||||
// we're starting another placement run.
|
||||
if (placedConfig != targetConfig) {
|
||||
redoPlacement();
|
||||
} else {
|
||||
observer->onNeedsRepaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void GeometryTileData::queryRenderedFeatures(
|
||||
std::unordered_map<std::string, std::vector<Feature>>& result,
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
const TransformState& transformState,
|
||||
const optional<std::vector<std::string>>& layerIDs) {
|
||||
|
||||
if (!featureIndex || !geometryTile) return;
|
||||
|
||||
featureIndex->query(result,
|
||||
{ queryGeometry },
|
||||
transformState.getAngle(),
|
||||
util::tileSize * id.overscaleFactor(),
|
||||
std::pow(2, transformState.getZoom() - id.overscaledZ),
|
||||
layerIDs,
|
||||
*geometryTile,
|
||||
id.canonical,
|
||||
style);
|
||||
}
|
||||
|
||||
void GeometryTileData::cancel() {
|
||||
obsolete = true;
|
||||
workRequest.reset();
|
||||
Feature convertFeature(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) {
|
||||
Feature feature { convertGeometry(geometryTileFeature, tileID) };
|
||||
feature.properties = geometryTileFeature.getProperties();
|
||||
feature.id = geometryTileFeature.getID();
|
||||
return feature;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,79 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/tile_data.hpp>
|
||||
#include <mbgl/tile/tile_worker.hpp>
|
||||
#include <mbgl/text/placement_config.hpp>
|
||||
#include <mbgl/util/atomic.hpp>
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
#include <mbgl/util/feature.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/variant.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class AsyncRequest;
|
||||
class GeometryTile;
|
||||
class GeometryTileSource;
|
||||
class FeatureIndex;
|
||||
|
||||
namespace style {
|
||||
class Style;
|
||||
}
|
||||
|
||||
class GeometryTileData : public TileData {
|
||||
public:
|
||||
GeometryTileData(const OverscaledTileID&,
|
||||
std::string sourceID,
|
||||
style::Style&,
|
||||
const MapMode);
|
||||
|
||||
~GeometryTileData();
|
||||
|
||||
void setError(std::exception_ptr err);
|
||||
|
||||
void setData(std::unique_ptr<GeometryTile> tile,
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> expires_);
|
||||
|
||||
Bucket* getBucket(const style::Layer&) override;
|
||||
|
||||
bool parsePending() override;
|
||||
|
||||
void redoPlacement(PlacementConfig) override;
|
||||
|
||||
void queryRenderedFeatures(
|
||||
std::unordered_map<std::string, std::vector<Feature>>& result,
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
const TransformState&,
|
||||
const optional<std::vector<std::string>>& layerIDs) override;
|
||||
|
||||
void cancel() override;
|
||||
|
||||
private:
|
||||
void redoPlacement();
|
||||
|
||||
style::Style& style;
|
||||
Worker& worker;
|
||||
TileWorker tileWorker;
|
||||
|
||||
std::unique_ptr<AsyncRequest> workRequest;
|
||||
|
||||
// Contains all the Bucket objects for the tile. Buckets are render
|
||||
// objects and they get added by tile parsing operations.
|
||||
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
|
||||
|
||||
std::unique_ptr<FeatureIndex> featureIndex;
|
||||
std::unique_ptr<const GeometryTile> geometryTile;
|
||||
|
||||
// Stores the placement configuration of the text that is currently placed on the screen.
|
||||
PlacementConfig placedConfig;
|
||||
|
||||
// Stores the placement configuration of how the text should be placed. This isn't necessarily
|
||||
// the one that is being displayed.
|
||||
PlacementConfig targetConfig;
|
||||
|
||||
// Used to signal the worker that it should abandon parsing this tile as soon as possible.
|
||||
util::Atomic<bool> obsolete { false };
|
||||
enum class FeatureType : uint8_t {
|
||||
Unknown = 0,
|
||||
Point = 1,
|
||||
LineString = 2,
|
||||
Polygon = 3
|
||||
};
|
||||
|
||||
class CanonicalTileID;
|
||||
|
||||
// Normalized vector tile coordinates.
|
||||
// Each geometry coordinate represents a point in a bidimensional space,
|
||||
// varying from -V...0...+V, where V is the maximum extent applicable.
|
||||
using GeometryCoordinate = Point<int16_t>;
|
||||
|
||||
class GeometryCoordinates : public std::vector<GeometryCoordinate> {
|
||||
public:
|
||||
using coordinate_type = int16_t;
|
||||
using std::vector<GeometryCoordinate>::vector;
|
||||
};
|
||||
|
||||
class GeometryCollection : public std::vector<GeometryCoordinates> {
|
||||
public:
|
||||
using coordinate_type = int16_t;
|
||||
using std::vector<GeometryCoordinates>::vector;
|
||||
};
|
||||
|
||||
class GeometryTileFeature : private util::noncopyable {
|
||||
public:
|
||||
virtual ~GeometryTileFeature() = default;
|
||||
virtual FeatureType getType() const = 0;
|
||||
virtual optional<Value> getValue(const std::string& key) const = 0;
|
||||
virtual Feature::property_map getProperties() const { return Feature::property_map(); }
|
||||
virtual optional<uint64_t> getID() const { return {}; }
|
||||
virtual GeometryCollection getGeometries() const = 0;
|
||||
};
|
||||
|
||||
class GeometryTileLayer : private util::noncopyable {
|
||||
public:
|
||||
virtual ~GeometryTileLayer() = default;
|
||||
virtual std::size_t featureCount() const = 0;
|
||||
virtual util::ptr<const GeometryTileFeature> getFeature(std::size_t) const = 0;
|
||||
virtual std::string getName() const = 0;
|
||||
};
|
||||
|
||||
class GeometryTileData : private util::noncopyable {
|
||||
public:
|
||||
virtual ~GeometryTileData() = default;
|
||||
virtual util::ptr<GeometryTileLayer> getLayer(const std::string&) const = 0;
|
||||
};
|
||||
|
||||
// classifies an array of rings into polygons with outer rings and holes
|
||||
std::vector<GeometryCollection> classifyRings(const GeometryCollection&);
|
||||
|
||||
// Truncate polygon to the largest `maxHoles` inner rings by area.
|
||||
void limitHoles(GeometryCollection&, uint32_t maxHoles);
|
||||
|
||||
// convert from GeometryTileFeature to Feature (eventually we should eliminate GeometryTileFeature)
|
||||
Feature convertFeature(const GeometryTileFeature&, const CanonicalTileID&);
|
||||
|
||||
// Fix up possibly-non-V2-compliant polygon geometry using angus clipper.
|
||||
// The result is guaranteed to have correctly wound, strictly simple rings.
|
||||
GeometryCollection fixupPolygons(const GeometryCollection&);
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <mbgl/tile/raster_tile_data.hpp>
|
||||
#include <mbgl/tile/raster_tile.hpp>
|
||||
#include <mbgl/tile/tile_observer.hpp>
|
||||
#include <mbgl/tile/tile_source_impl.hpp>
|
||||
#include <mbgl/style/source.hpp>
|
||||
#include <mbgl/style/update_parameters.hpp>
|
||||
#include <mbgl/tile/tile_data_observer.hpp>
|
||||
#include <mbgl/tile/tile_source_impl.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
@@ -11,20 +11,20 @@
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
RasterTileData::RasterTileData(const OverscaledTileID& id_,
|
||||
const style::UpdateParameters& parameters,
|
||||
const Tileset& tileset)
|
||||
: TileData(id_),
|
||||
RasterTile::RasterTile(const OverscaledTileID& id_,
|
||||
const style::UpdateParameters& parameters,
|
||||
const Tileset& tileset)
|
||||
: Tile(id_),
|
||||
texturePool(parameters.texturePool),
|
||||
worker(parameters.worker),
|
||||
tileSource(*this, id_, parameters, tileset) {
|
||||
}
|
||||
|
||||
void RasterTileData::setError(std::exception_ptr err) {
|
||||
void RasterTile::setError(std::exception_ptr err) {
|
||||
observer->onTileError(*this, err);
|
||||
}
|
||||
|
||||
void RasterTileData::setData(std::shared_ptr<const std::string> data,
|
||||
void RasterTile::setData(std::shared_ptr<const std::string> data,
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> expires_) {
|
||||
modified = modified_;
|
||||
@@ -55,14 +55,14 @@ void RasterTileData::setData(std::shared_ptr<const std::string> data,
|
||||
});
|
||||
}
|
||||
|
||||
Bucket* RasterTileData::getBucket(const style::Layer&) {
|
||||
Bucket* RasterTile::getBucket(const style::Layer&) {
|
||||
return bucket.get();
|
||||
}
|
||||
|
||||
void RasterTileData::setNecessity(Necessity necessity) {
|
||||
tileSource.setNecessity(static_cast<TileSource<RasterTileData>::Necessity>(necessity));
|
||||
void RasterTile::setNecessity(Necessity necessity) {
|
||||
tileSource.setNecessity(static_cast<TileSource<RasterTile>::Necessity>(necessity));
|
||||
}
|
||||
|
||||
void RasterTileData::cancel() {
|
||||
void RasterTile::cancel() {
|
||||
workRequest.reset();
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/tile_data.hpp>
|
||||
#include <mbgl/renderer/raster_bucket.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/tile/tile_source.hpp>
|
||||
#include <mbgl/renderer/raster_bucket.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -16,9 +16,9 @@ class Layer;
|
||||
class UpdateParameters;
|
||||
}
|
||||
|
||||
class RasterTileData : public TileData {
|
||||
class RasterTile : public Tile {
|
||||
public:
|
||||
RasterTileData(const OverscaledTileID&,
|
||||
RasterTile(const OverscaledTileID&,
|
||||
const style::UpdateParameters&,
|
||||
const Tileset&);
|
||||
|
||||
@@ -37,7 +37,7 @@ private:
|
||||
gl::TexturePool& texturePool;
|
||||
Worker& worker;
|
||||
|
||||
TileSource<RasterTileData> tileSource;
|
||||
TileSource<RasterTile> tileSource;
|
||||
std::unique_ptr<AsyncRequest> workRequest;
|
||||
|
||||
// Contains the Bucket object for the tile. Buckets are render
|
||||
37
src/mbgl/tile/tile.cpp
Normal file
37
src/mbgl/tile/tile.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/tile/tile_observer.hpp>
|
||||
#include <mbgl/renderer/debug_bucket.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
static TileObserver nullObserver;
|
||||
|
||||
Tile::Tile(const OverscaledTileID& id_)
|
||||
: id(id_), observer(&nullObserver) {
|
||||
}
|
||||
|
||||
Tile::~Tile() = default;
|
||||
|
||||
void Tile::setObserver(TileObserver* observer_) {
|
||||
observer = observer_;
|
||||
}
|
||||
|
||||
void Tile::setTriedOptional() {
|
||||
triedOptional = true;
|
||||
observer->onNeedsRepaint();
|
||||
}
|
||||
|
||||
void Tile::dumpDebugLogs() const {
|
||||
Log::Info(Event::General, "Tile::id: %s", util::toString(id).c_str());
|
||||
Log::Info(Event::General, "Tile::renderable: %s", isRenderable() ? "yes" : "no");
|
||||
Log::Info(Event::General, "Tile::complete: %s", isComplete() ? "yes" : "no");
|
||||
}
|
||||
|
||||
void Tile::queryRenderedFeatures(
|
||||
std::unordered_map<std::string, std::vector<Feature>>&,
|
||||
const GeometryCoordinates&,
|
||||
const TransformState&,
|
||||
const optional<std::vector<std::string>>&) {}
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
#include <mbgl/renderer/bucket.hpp>
|
||||
#include <mbgl/text/placement_config.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
@@ -19,18 +19,18 @@ namespace mbgl {
|
||||
class Worker;
|
||||
class DebugBucket;
|
||||
class TransformState;
|
||||
class TileDataObserver;
|
||||
class TileObserver;
|
||||
|
||||
namespace style {
|
||||
class Layer;
|
||||
}
|
||||
|
||||
class TileData : private util::noncopyable {
|
||||
class Tile : private util::noncopyable {
|
||||
public:
|
||||
TileData(const OverscaledTileID&);
|
||||
virtual ~TileData();
|
||||
Tile(const OverscaledTileID&);
|
||||
virtual ~Tile();
|
||||
|
||||
void setObserver(TileDataObserver* observer);
|
||||
void setObserver(TileObserver* observer);
|
||||
|
||||
enum class Necessity : bool {
|
||||
Optional = false,
|
||||
@@ -91,18 +91,18 @@ protected:
|
||||
// Still waiting for data to load or parse.
|
||||
None,
|
||||
|
||||
// TileData is partially parsed, some buckets are still waiting for dependencies
|
||||
// Tile is partially parsed, some buckets are still waiting for dependencies
|
||||
// to arrive, but it is good for rendering. Partial tiles can also be re-parsed,
|
||||
// but might remain in the same state if dependencies are still missing.
|
||||
Some,
|
||||
|
||||
// TileData is fully parsed, and all buckets are available if they exist.
|
||||
// Tile is fully parsed, and all buckets are available if they exist.
|
||||
All,
|
||||
};
|
||||
|
||||
DataAvailability availableData = DataAvailability::None;
|
||||
|
||||
TileDataObserver* observer = nullptr;
|
||||
TileObserver* observer = nullptr;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mbgl/tile/tile_cache.hpp>
|
||||
#include <mbgl/tile/tile_data.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
@@ -17,21 +17,21 @@ void TileCache::setSize(size_t size_) {
|
||||
assert(orderedKeys.size() <= size);
|
||||
}
|
||||
|
||||
void TileCache::add(const OverscaledTileID& key, std::unique_ptr<TileData> data) {
|
||||
if (!data->isRenderable() || !size) {
|
||||
void TileCache::add(const OverscaledTileID& key, std::unique_ptr<Tile> tile) {
|
||||
if (!tile->isRenderable() || !size) {
|
||||
return;
|
||||
}
|
||||
|
||||
// insert new or query existing data
|
||||
if (tiles.emplace(key, std::move(data)).second) {
|
||||
// remove existing data key
|
||||
// insert new or query existing tile
|
||||
if (tiles.emplace(key, std::move(tile)).second) {
|
||||
// remove existing tile key
|
||||
orderedKeys.remove(key);
|
||||
}
|
||||
|
||||
// (re-)insert data key as newest
|
||||
// (re-)insert tile key as newest
|
||||
orderedKeys.push_back(key);
|
||||
|
||||
// purge oldest key/data if necessary
|
||||
// purge oldest key/tile if necessary
|
||||
if (orderedKeys.size() > size) {
|
||||
get(orderedKeys.front());
|
||||
}
|
||||
@@ -39,19 +39,19 @@ void TileCache::add(const OverscaledTileID& key, std::unique_ptr<TileData> data)
|
||||
assert(orderedKeys.size() <= size);
|
||||
}
|
||||
|
||||
std::unique_ptr<TileData> TileCache::get(const OverscaledTileID& key) {
|
||||
std::unique_ptr<Tile> TileCache::get(const OverscaledTileID& key) {
|
||||
|
||||
std::unique_ptr<TileData> data;
|
||||
std::unique_ptr<Tile> tile;
|
||||
|
||||
auto it = tiles.find(key);
|
||||
if (it != tiles.end()) {
|
||||
data = std::move(it->second);
|
||||
tile = std::move(it->second);
|
||||
tiles.erase(it);
|
||||
orderedKeys.remove(key);
|
||||
assert(data->isRenderable());
|
||||
assert(tile->isRenderable());
|
||||
}
|
||||
|
||||
return data;
|
||||
return tile;
|
||||
}
|
||||
|
||||
bool TileCache::has(const OverscaledTileID& key) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class TileData;
|
||||
class Tile;
|
||||
|
||||
class TileCache {
|
||||
public:
|
||||
@@ -16,13 +16,13 @@ public:
|
||||
|
||||
void setSize(size_t);
|
||||
size_t getSize() const { return size; };
|
||||
void add(const OverscaledTileID& key, std::unique_ptr<TileData> data);
|
||||
std::unique_ptr<TileData> get(const OverscaledTileID& key);
|
||||
void add(const OverscaledTileID& key, std::unique_ptr<Tile> data);
|
||||
std::unique_ptr<Tile> get(const OverscaledTileID& key);
|
||||
bool has(const OverscaledTileID& key);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
std::map<OverscaledTileID, std::unique_ptr<TileData>> tiles;
|
||||
std::map<OverscaledTileID, std::unique_ptr<Tile>> tiles;
|
||||
std::list<OverscaledTileID> orderedKeys;
|
||||
|
||||
size_t size;
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#include <mbgl/tile/tile_data.hpp>
|
||||
#include <mbgl/tile/tile_data_observer.hpp>
|
||||
#include <mbgl/renderer/debug_bucket.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
static TileDataObserver nullObserver;
|
||||
|
||||
TileData::TileData(const OverscaledTileID& id_)
|
||||
: id(id_), observer(&nullObserver) {
|
||||
}
|
||||
|
||||
TileData::~TileData() = default;
|
||||
|
||||
void TileData::setObserver(TileDataObserver* observer_) {
|
||||
observer = observer_;
|
||||
}
|
||||
|
||||
void TileData::setTriedOptional() {
|
||||
triedOptional = true;
|
||||
observer->onNeedsRepaint();
|
||||
}
|
||||
|
||||
void TileData::dumpDebugLogs() const {
|
||||
Log::Info(Event::General, "TileData::id: %s", util::toString(id).c_str());
|
||||
Log::Info(Event::General, "TileData::renderable: %s", isRenderable() ? "yes" : "no");
|
||||
Log::Info(Event::General, "TileData::complete: %s", isComplete() ? "yes" : "no");
|
||||
}
|
||||
|
||||
void TileData::queryRenderedFeatures(
|
||||
std::unordered_map<std::string, std::vector<Feature>>&,
|
||||
const GeometryCoordinates&,
|
||||
const TransformState&,
|
||||
const optional<std::vector<std::string>>&) {}
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class TileData;
|
||||
|
||||
class TileDataObserver {
|
||||
public:
|
||||
virtual ~TileDataObserver() = default;
|
||||
|
||||
virtual void onTileLoaded(TileData&, bool /*isNewTile*/) {}
|
||||
virtual void onTileError(TileData&, std::exception_ptr) {}
|
||||
virtual void onNeedsRepaint() {}
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
18
src/mbgl/tile/tile_observer.hpp
Normal file
18
src/mbgl/tile/tile_observer.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Tile;
|
||||
|
||||
class TileObserver {
|
||||
public:
|
||||
virtual ~TileObserver() = default;
|
||||
|
||||
virtual void onTileLoaded(Tile&, bool /*isNewTile*/) {}
|
||||
virtual void onTileError(Tile&, std::exception_ptr) {}
|
||||
virtual void onNeedsRepaint() {}
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -58,7 +58,7 @@ private:
|
||||
void loadedData(const Response&);
|
||||
void loadRequired();
|
||||
|
||||
T& tileData;
|
||||
T& tile;
|
||||
Necessity necessity;
|
||||
Resource resource;
|
||||
FileSource& fileSource;
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
namespace mbgl {
|
||||
|
||||
template <typename T>
|
||||
TileSource<T>::TileSource(T& tileData_,
|
||||
TileSource<T>::TileSource(T& tile_,
|
||||
const OverscaledTileID& id,
|
||||
const style::UpdateParameters& parameters,
|
||||
const Tileset& tileset)
|
||||
: tileData(tileData_),
|
||||
: tile(tile_),
|
||||
necessity(Necessity::Optional),
|
||||
resource(Resource::tile(
|
||||
tileset.tiles.at(0),
|
||||
@@ -51,7 +51,7 @@ void TileSource<T>::loadOptional() {
|
||||
request = fileSource.request(resource, [this](Response res) {
|
||||
request.reset();
|
||||
|
||||
tileData.setTriedOptional();
|
||||
tile.setTriedOptional();
|
||||
|
||||
if (res.error && res.error->reason == Response::Error::Reason::NotFound) {
|
||||
// When the optional request could not be satisfied, don't treat it as an error.
|
||||
@@ -86,16 +86,16 @@ void TileSource<T>::makeOptional() {
|
||||
template <typename T>
|
||||
void TileSource<T>::loadedData(const Response& res) {
|
||||
if (res.error && res.error->reason != Response::Error::Reason::NotFound) {
|
||||
tileData.setError(std::make_exception_ptr(std::runtime_error(res.error->message)));
|
||||
tile.setError(std::make_exception_ptr(std::runtime_error(res.error->message)));
|
||||
} else if (res.notModified) {
|
||||
resource.priorExpires = res.expires;
|
||||
// Do not notify the TileData object; when we get this message, it already has the current
|
||||
// Do not notify the tile; when we get this message, it already has the current
|
||||
// version of the data.
|
||||
} else {
|
||||
resource.priorModified = res.modified;
|
||||
resource.priorExpires = res.expires;
|
||||
resource.priorEtag = res.etag;
|
||||
tileData.setData(res.noContent ? nullptr : res.data, res.modified, res.expires);
|
||||
tile.setData(res.noContent ? nullptr : res.data, res.modified, res.expires);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <mbgl/text/collision_tile.hpp>
|
||||
#include <mbgl/tile/tile_worker.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/style/bucket_parameters.hpp>
|
||||
#include <mbgl/style/layers/background_layer.hpp>
|
||||
#include <mbgl/style/layers/custom_layer.hpp>
|
||||
@@ -40,14 +40,14 @@ TileWorker::~TileWorker() {
|
||||
}
|
||||
|
||||
TileParseResult TileWorker::parseAllLayers(std::vector<std::unique_ptr<Layer>> layers_,
|
||||
std::unique_ptr<const GeometryTile> geometryTile_,
|
||||
std::unique_ptr<const GeometryTileData> tileData_,
|
||||
PlacementConfig config) {
|
||||
// We're doing a fresh parse of the tile, because the underlying data has changed.
|
||||
pending.clear();
|
||||
placementPending.clear();
|
||||
partialParse = false;
|
||||
featureIndex = std::make_unique<FeatureIndex>();
|
||||
geometryTile = std::move(geometryTile_);
|
||||
tileData = std::move(tileData_);
|
||||
|
||||
// Store the layers for use in redoPlacement.
|
||||
layers = std::move(layers_);
|
||||
@@ -98,7 +98,7 @@ TileParseResult TileWorker::prepareResult(const PlacementConfig& config) {
|
||||
if (result.complete) {
|
||||
featureIndex->setCollisionTile(placeLayers(config));
|
||||
result.featureIndex = std::move(featureIndex);
|
||||
result.geometryTile = std::move(geometryTile);
|
||||
result.tileData = std::move(tileData);
|
||||
}
|
||||
|
||||
return std::move(result);
|
||||
@@ -147,7 +147,7 @@ void TileWorker::parseLayer(const Layer* layer) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto geometryLayer = geometryTile->getLayer(layer->baseImpl->sourceLayer);
|
||||
auto geometryLayer = tileData->getLayer(layer->baseImpl->sourceLayer);
|
||||
if (!geometryLayer) {
|
||||
// The layer specified in the bucket does not exist. Do nothing.
|
||||
if (debug::tileParseWarnings) {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
namespace mbgl {
|
||||
|
||||
class CollisionTile;
|
||||
class GeometryTile;
|
||||
class GeometryTileData;
|
||||
class SpriteStore;
|
||||
class GlyphAtlas;
|
||||
class GlyphStore;
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
bool complete = false;
|
||||
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
|
||||
std::unique_ptr<FeatureIndex> featureIndex;
|
||||
std::unique_ptr<const GeometryTile> geometryTile;
|
||||
std::unique_ptr<const GeometryTileData> tileData;
|
||||
};
|
||||
|
||||
using TileParseResult = variant<
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
~TileWorker();
|
||||
|
||||
TileParseResult parseAllLayers(std::vector<std::unique_ptr<style::Layer>>,
|
||||
std::unique_ptr<const GeometryTile> geometryTile,
|
||||
std::unique_ptr<const GeometryTileData> tileData,
|
||||
PlacementConfig);
|
||||
|
||||
TileParseResult parsePendingLayers(PlacementConfig);
|
||||
@@ -83,7 +83,7 @@ private:
|
||||
std::vector<std::unique_ptr<style::Layer>> layers;
|
||||
|
||||
std::unique_ptr<FeatureIndex> featureIndex;
|
||||
std::unique_ptr<const GeometryTile> geometryTile;
|
||||
std::unique_ptr<const GeometryTileData> tileData;
|
||||
|
||||
// Contains buckets that we couldn't parse so far due to missing resources.
|
||||
// They will be attempted on subsequent parses.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <mbgl/tile/vector_tile.hpp>
|
||||
#include <mbgl/tile/tile_source_impl.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/style/update_parameters.hpp>
|
||||
|
||||
#include <protozero/pbf_reader.hpp>
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
std::string getName() const override;
|
||||
|
||||
private:
|
||||
friend class VectorTile;
|
||||
friend class VectorTileData;
|
||||
friend class VectorTileFeature;
|
||||
|
||||
std::string name;
|
||||
@@ -56,9 +56,9 @@ private:
|
||||
std::vector<protozero::pbf_reader> features;
|
||||
};
|
||||
|
||||
class VectorTile : public GeometryTile {
|
||||
class VectorTileData : public GeometryTileData {
|
||||
public:
|
||||
VectorTile(std::shared_ptr<const std::string> data);
|
||||
VectorTileData(std::shared_ptr<const std::string> data);
|
||||
|
||||
util::ptr<GeometryTileLayer> getLayer(const std::string&) const override;
|
||||
|
||||
@@ -68,22 +68,22 @@ private:
|
||||
mutable std::map<std::string, util::ptr<GeometryTileLayer>> layers;
|
||||
};
|
||||
|
||||
VectorTileData::VectorTileData(const OverscaledTileID& id_,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters& parameters,
|
||||
const Tileset& tileset)
|
||||
: GeometryTileData(id_, sourceID, parameters.style, parameters.mode),
|
||||
VectorTile::VectorTile(const OverscaledTileID& id_,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters& parameters,
|
||||
const Tileset& tileset)
|
||||
: GeometryTile(id_, sourceID, parameters.style, parameters.mode),
|
||||
tileSource(*this, id_, parameters, tileset) {
|
||||
}
|
||||
|
||||
void VectorTileData::setNecessity(Necessity necessity) {
|
||||
tileSource.setNecessity(static_cast<TileSource<VectorTileData>::Necessity>(necessity));
|
||||
void VectorTile::setNecessity(Necessity necessity) {
|
||||
tileSource.setNecessity(static_cast<TileSource<VectorTile>::Necessity>(necessity));
|
||||
}
|
||||
|
||||
void VectorTileData::setData(std::shared_ptr<const std::string> data,
|
||||
optional<Timestamp> modified,
|
||||
optional<Timestamp> expires) {
|
||||
GeometryTileData::setData(data ? std::make_unique<VectorTile>(data) : nullptr, modified, expires);
|
||||
void VectorTile::setData(std::shared_ptr<const std::string> data_,
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> expires_) {
|
||||
GeometryTile::setData(data_ ? std::make_unique<VectorTileData>(data_) : nullptr, modified_, expires_);
|
||||
}
|
||||
|
||||
Value parseValue(protozero::pbf_reader data) {
|
||||
@@ -236,11 +236,11 @@ GeometryCollection VectorTileFeature::getGeometries() const {
|
||||
return fixupPolygons(lines);
|
||||
}
|
||||
|
||||
VectorTile::VectorTile(std::shared_ptr<const std::string> data_)
|
||||
VectorTileData::VectorTileData(std::shared_ptr<const std::string> data_)
|
||||
: data(std::move(data_)) {
|
||||
}
|
||||
|
||||
util::ptr<GeometryTileLayer> VectorTile::getLayer(const std::string& name) const {
|
||||
util::ptr<GeometryTileLayer> VectorTileData::getLayer(const std::string& name) const {
|
||||
if (!parsed) {
|
||||
parsed = true;
|
||||
protozero::pbf_reader tile_pbf(*data);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/tile_source.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -11,12 +11,12 @@ namespace style {
|
||||
class UpdateParameters;
|
||||
}
|
||||
|
||||
class VectorTileData : public GeometryTileData {
|
||||
class VectorTile : public GeometryTile {
|
||||
public:
|
||||
VectorTileData(const OverscaledTileID&,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters&,
|
||||
const Tileset&);
|
||||
VectorTile(const OverscaledTileID&,
|
||||
std::string sourceID,
|
||||
const style::UpdateParameters&,
|
||||
const Tileset&);
|
||||
|
||||
void setNecessity(Necessity) final;
|
||||
void setData(std::shared_ptr<const std::string> data,
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
optional<Timestamp> expires);
|
||||
|
||||
private:
|
||||
TileSource<VectorTileData> tileSource;
|
||||
TileSource<VectorTile> tileSource;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <mbgl/util/work_request.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <mbgl/renderer/raster_bucket.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/style/layer.hpp>
|
||||
#include <mbgl/text/collision_tile.hpp>
|
||||
|
||||
@@ -31,11 +31,11 @@ public:
|
||||
|
||||
void parseGeometryTile(TileWorker* worker,
|
||||
std::vector<std::unique_ptr<style::Layer>> layers,
|
||||
std::unique_ptr<GeometryTile> tile,
|
||||
std::unique_ptr<GeometryTileData> tileData,
|
||||
PlacementConfig config,
|
||||
std::function<void(TileParseResult)> callback) {
|
||||
try {
|
||||
callback(worker->parseAllLayers(std::move(layers), std::move(tile), config));
|
||||
callback(worker->parseAllLayers(std::move(layers), std::move(tileData), config));
|
||||
} catch (...) {
|
||||
callback(std::current_exception());
|
||||
}
|
||||
@@ -80,12 +80,12 @@ Worker::parseRasterTile(std::unique_ptr<RasterBucket> bucket,
|
||||
std::unique_ptr<AsyncRequest>
|
||||
Worker::parseGeometryTile(TileWorker& worker,
|
||||
std::vector<std::unique_ptr<style::Layer>> layers,
|
||||
std::unique_ptr<GeometryTile> tile,
|
||||
std::unique_ptr<GeometryTileData> tileData,
|
||||
PlacementConfig config,
|
||||
std::function<void(TileParseResult)> callback) {
|
||||
current = (current + 1) % threads.size();
|
||||
return threads[current]->invokeWithCallback(&Worker::Impl::parseGeometryTile, callback, &worker,
|
||||
std::move(layers), std::move(tile), config);
|
||||
std::move(layers), std::move(tileData), config);
|
||||
}
|
||||
|
||||
std::unique_ptr<AsyncRequest>
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
|
||||
Request parseGeometryTile(TileWorker&,
|
||||
std::vector<std::unique_ptr<style::Layer>>,
|
||||
std::unique_ptr<GeometryTile>,
|
||||
std::unique_ptr<GeometryTileData>,
|
||||
PlacementConfig,
|
||||
std::function<void(TileParseResult)> callback);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <mbgl/style/filter.hpp>
|
||||
#include <mbgl/style/filter_evaluator.hpp>
|
||||
#include <mbgl/style/parser.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
'math/minmax.cpp',
|
||||
'math/clamp.cpp',
|
||||
|
||||
'tile/geometry_tile.cpp',
|
||||
'tile/geometry_tile_data.cpp',
|
||||
'tile/tile_id.cpp',
|
||||
|
||||
'storage/offline.cpp',
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
TEST(GeometryTile, classifyRings1) {
|
||||
TEST(GeometryTileData, classifyRings1) {
|
||||
std::vector<GeometryCollection> polygons = classifyRings({
|
||||
{ {0, 0}, {0, 40}, {40, 40}, {40, 0}, {0, 0} }
|
||||
});
|
||||
@@ -14,7 +14,7 @@ TEST(GeometryTile, classifyRings1) {
|
||||
ASSERT_EQ(polygons[0].size(), 1u);
|
||||
}
|
||||
|
||||
TEST(GeometryTile, classifyRings2) {
|
||||
TEST(GeometryTileData, classifyRings2) {
|
||||
std::vector<GeometryCollection> polygons = classifyRings({
|
||||
{ {0, 0}, {0, 40}, {40, 40}, {40, 0}, {0, 0} },
|
||||
{ {10, 10}, {20, 10}, {20, 20}, {10, 10} }
|
||||
@@ -26,7 +26,7 @@ TEST(GeometryTile, classifyRings2) {
|
||||
ASSERT_EQ(polygons[0].size(), 2u);
|
||||
}
|
||||
|
||||
TEST(GeometryTile, limitHoles1) {
|
||||
TEST(GeometryTileData, limitHoles1) {
|
||||
GeometryCollection polygon = {
|
||||
{ {0, 0}, {0, 40}, {40, 40}, {40, 0}, {0, 0} },
|
||||
{ {30, 30}, {32, 30}, {32, 32}, {30, 30} },
|
||||
@@ -43,7 +43,7 @@ TEST(GeometryTile, limitHoles1) {
|
||||
ASSERT_EQ(polygon[1][0].x, 10);
|
||||
}
|
||||
|
||||
TEST(GeometryTile, limitHoles2) {
|
||||
TEST(GeometryTileData, limitHoles2) {
|
||||
GeometryCollection polygon = {
|
||||
{ {0, 0}, {0, 40}, {40, 40}, {40, 0}, {0, 0} },
|
||||
{ {10, 10}, {20, 10}, {20, 20}, {10, 10} },
|
||||
Reference in New Issue
Block a user