diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index 768be1410..f54773a52 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -2,6 +2,7 @@ #define LLMR_MAP_MAP #include +#include #include #include #include @@ -64,8 +65,8 @@ private: bool findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::forward_list& retain); bool findLoadedParent(const Tile::ID& id, int32_t minCoveringZoom, std::forward_list& retain); bool updateTiles(); - std::shared_ptr addTile(const Tile::ID& id); - std::shared_ptr hasTile(const Tile::ID& id); + std::shared_ptr addTile(const Tile::ID& id); + std::shared_ptr hasTile(const Tile::ID& id); void update(); @@ -81,8 +82,8 @@ private: float pixel_ratio; - std::forward_list> tiles; - std::forward_list> historic_tiles; + std::forward_list> tiles; + std::forward_list> historic_tiles; }; } diff --git a/include/llmr/map/tile.hpp b/include/llmr/map/tile.hpp index c2ff37a3e..bd0505f5c 100644 --- a/include/llmr/map/tile.hpp +++ b/include/llmr/map/tile.hpp @@ -2,104 +2,19 @@ #define LLMR_MAP_TILE #include -#include -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include namespace llmr { -class Style; -class Bucket; -class LayerDescription; -class BucketDescription; -class VectorTile; -class VectorTileLayer; -class FillVertexBuffer; -class LineVertexBuffer; -class PointVertexBuffer; -class TriangleElementsBuffer; -class LineElementsBuffer; -class PointElementsBuffer; -class PlainShader; - -class Tile : public std::enable_shared_from_this, - private util::noncopyable { +class Tile { public: - struct exception : std::exception {}; - struct geometry_too_long_exception : exception {}; - -public: - typedef std::shared_ptr Ptr; - typedef vec3 ID; - enum state { - initial, - loading, - loaded, - parsed, - obsolete - }; - public: - Tile(ID id, const Style& style); - ~Tile(); - - // Start loading the tile. - void request(); - - // Other functions - bool parse(); - void parseStyleLayers(const VectorTile& tile, const std::vector& layers); - std::shared_ptr createBucket(const VectorTile& tile, const BucketDescription& bucket_desc); - std::shared_ptr createFillBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); - std::shared_ptr createLineBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); - std::shared_ptr createPointBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); - - void cancel(); - - const std::string toString() const; - static ID parent(const ID& id, int32_t z); static std::forward_list children(const ID& id, int32_t z); - -public: - const ID id; - uint8_t clip_id; - std::atomic state; - - // Holds the actual geometries in this tile. - DebugFontBuffer debugFontBuffer; - VertexArrayObject debugFontArray; - - std::shared_ptr fillVertexBuffer; - std::shared_ptr lineVertexBuffer; - std::shared_ptr pointVertexBuffer; - - std::shared_ptr triangleElementsBuffer; - std::shared_ptr lineElementsBuffer; - std::shared_ptr pointElementsBuffer; - - // Holds the buckets of this tile. - // They contain the location offsets in the buffers stored above - std::map> buckets; - - mat4 matrix; -private: - // Source data - std::string data; - const Style& style; - platform::Request *req = nullptr; }; } diff --git a/include/llmr/map/tile_data.hpp b/include/llmr/map/tile_data.hpp new file mode 100644 index 000000000..05dc59d42 --- /dev/null +++ b/include/llmr/map/tile_data.hpp @@ -0,0 +1,103 @@ +#ifndef LLMR_MAP_TILE_DATA +#define LLMR_MAP_TILE_DATA + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace llmr { + +class Style; +class Bucket; +class LayerDescription; +class BucketDescription; +class VectorTile; +class VectorTileLayer; +class FillVertexBuffer; +class LineVertexBuffer; +class PointVertexBuffer; +class TriangleElementsBuffer; +class LineElementsBuffer; +class PointElementsBuffer; +class PlainShader; + +class TileData : public std::enable_shared_from_this, + private util::noncopyable { +public: + struct exception : std::exception {}; + struct geometry_too_long_exception : exception {}; + +public: + typedef std::shared_ptr Ptr; + + enum state { + initial, + loading, + loaded, + parsed, + obsolete + }; + +public: + TileData(Tile::ID id, const Style& style); + ~TileData(); + + // Start loading the tile. + void request(); + + // Other functions + bool parse(); + void parseStyleLayers(const VectorTile& tile, const std::vector& layers); + std::shared_ptr createBucket(const VectorTile& tile, const BucketDescription& bucket_desc); + std::shared_ptr createFillBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); + std::shared_ptr createLineBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); + std::shared_ptr createPointBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); + + void cancel(); + + const std::string toString() const; + +public: + const Tile::ID id; + uint8_t clip_id; + std::atomic state; + + // Holds the actual geometries in this tile. + DebugFontBuffer debugFontBuffer; + VertexArrayObject debugFontArray; + + std::shared_ptr fillVertexBuffer; + std::shared_ptr lineVertexBuffer; + std::shared_ptr pointVertexBuffer; + + std::shared_ptr triangleElementsBuffer; + std::shared_ptr lineElementsBuffer; + std::shared_ptr pointElementsBuffer; + + // Holds the buckets of this tile. + // They contain the location offsets in the buffers stored above + std::map> buckets; + + mat4 matrix; +private: + // Source data + std::string data; + const Style& style; + platform::Request *req = nullptr; +}; + +} + +#endif diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index f00441943..76a8d788b 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -1,7 +1,7 @@ #ifndef LLMR_RENDERER_PAINTER #define LLMR_RENDERER_PAINTER -#include +#include #include #include #include @@ -33,7 +33,7 @@ public: void setup(); void clear(); void changeMatrix(); - void render(const std::shared_ptr& tile); + void render(const std::shared_ptr& tile); void renderMatte(); void renderBackground(); void renderFill(FillBucket& bucket, const std::string& layer_name, const Tile::ID& id); @@ -45,8 +45,8 @@ public: void finishClippingMask(); private: void setupShaders(); - void renderLayers(const std::shared_ptr& tile, const std::vector& layers); - void renderDebug(const std::shared_ptr& tile); + void renderLayers(const std::shared_ptr& tile, const std::vector& layers); + void renderDebug(const std::shared_ptr& tile); void useProgram(uint32_t program); void lineWidth(float lineWidth); diff --git a/src/map/map.cpp b/src/map/map.cpp index 68360db03..41d574527 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -238,22 +238,22 @@ void Map::update() { } -Tile::Ptr Map::hasTile(const Tile::ID& id) { - for (Tile::Ptr& tile : tiles) { +TileData::Ptr Map::hasTile(const Tile::ID& id) { + for (TileData::Ptr& tile : tiles) { if (tile->id == id) { return tile; } } - return Tile::Ptr(); + return TileData::Ptr(); } -Tile::Ptr Map::addTile(const Tile::ID& id) { - Tile::Ptr tile = hasTile(id); +TileData::Ptr Map::addTile(const Tile::ID& id) { + TileData::Ptr tile = hasTile(id); if (!tile.get()) { // We couldn't find the tile in the list. Create a new one. - tile = std::make_shared(id, style); + tile = std::make_shared(id, style); assert(tile); // std::cerr << "init " << id.z << "/" << id.x << "/" << id.y << std::endl; // std::cerr << "add " << tile->toString() << std::endl; @@ -278,8 +278,8 @@ bool Map::findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::f auto ids = Tile::children(id, z + 1); for (const Tile::ID& child_id : ids) { - const Tile::Ptr& tile = hasTile(child_id); - if (tile && tile->state == Tile::parsed) { + const TileData::Ptr& tile = hasTile(child_id); + if (tile && tile->state == TileData::parsed) { assert(tile); retain.emplace_front(tile->id); } else { @@ -305,8 +305,8 @@ bool Map::findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::f bool Map::findLoadedParent(const Tile::ID& id, int32_t minCoveringZoom, std::forward_list& retain) { for (int32_t z = id.z - 1; z >= minCoveringZoom; --z) { const Tile::ID parent_id = Tile::parent(id, z); - const Tile::Ptr tile = hasTile(parent_id); - if (tile && tile->state == Tile::parsed) { + const TileData::Ptr tile = hasTile(parent_id); + if (tile && tile->state == TileData::parsed) { assert(tile); retain.emplace_front(tile->id); return true; @@ -344,10 +344,10 @@ bool Map::updateTiles() { // Add existing child/parent tiles if the actual tile is not yet loaded for (const Tile::ID& id : required) { - Tile::Ptr tile = addTile(id); + TileData::Ptr tile = addTile(id); assert(tile); - if (tile->state != Tile::parsed) { + if (tile->state != TileData::parsed) { // The tile we require is not yet loaded. Try to find a parent or // child tile that we already have. @@ -362,7 +362,7 @@ bool Map::updateTiles() { } } - if (tile->state == Tile::initial) { + if (tile->state == TileData::initial) { // If the tile is new, we have to make sure to load it. tile->request(); changed = true; @@ -371,7 +371,7 @@ bool Map::updateTiles() { // Remove tiles that we definitely don't need, i.e. tiles that are not on // the required list. - tiles.remove_if([&retain, &changed](const Tile::Ptr& tile) { + tiles.remove_if([&retain, &changed](const TileData::Ptr& tile) { assert(tile); bool obsolete = std::find(retain.begin(), retain.end(), tile->id) == retain.end(); if (obsolete) { @@ -384,7 +384,7 @@ bool Map::updateTiles() { // Sort tiles by zoom level, front to back. // We're painting front-to-back, so we want to draw more detailed tiles first // before filling in other parts with lower zoom levels. - tiles.sort([](const Tile::Ptr& a, const Tile::Ptr& b) { + tiles.sort([](const TileData::Ptr& a, const TileData::Ptr& b) { return a->id.z > b->id.z; }); @@ -406,9 +406,9 @@ bool Map::render() { // the stencil buffer. uint8_t i = 1; painter.prepareClippingMask(); - for (Tile::Ptr& tile : tiles) { + for (TileData::Ptr& tile : tiles) { assert(tile); - if (tile->state == Tile::parsed) { + if (tile->state == TileData::parsed) { // The position matrix. transform.matrixFor(tile->matrix, tile->id); matrix::multiply(tile->matrix, painter.projMatrix, tile->matrix); @@ -418,8 +418,8 @@ bool Map::render() { } painter.finishClippingMask(); - for (Tile::Ptr& tile : tiles) { - if (tile->state == Tile::parsed) { + for (TileData::Ptr& tile : tiles) { + if (tile->state == TileData::parsed) { painter.render(tile); } } diff --git a/src/map/tile.cpp b/src/map/tile.cpp index d666accd1..9dd2ad582 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -1,18 +1,6 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#include using namespace llmr; @@ -41,198 +29,3 @@ std::forward_list Tile::children(const ID& id, int32_t z) { return children; } - -Tile::Tile(ID id, const Style& style) - : id(id), - state(initial), - fillVertexBuffer(std::make_shared()), - lineVertexBuffer(std::make_shared()), - pointVertexBuffer(std::make_shared()), - triangleElementsBuffer(std::make_shared()), - lineElementsBuffer(std::make_shared()), - pointElementsBuffer(std::make_shared()), - style(style) { - - // Initialize tile debug coordinates - char coord[32]; - snprintf(coord, sizeof(coord), "%d/%d/%d", id.z, id.x, id.y); - debugFontBuffer.addText(coord, 50, 200, 5); -} - -Tile::~Tile() { -} - -const std::string Tile::toString() const { - return util::sprintf("[tile %d/%d/%d]", id.z, id.x, id.y); -} - -void Tile::request() { - state = Tile::loading; - - // Create http request - std::string url = util::sprintf(kTileURL, - id.z, id.x, id.y); - - // Note: Somehow this feels slower than the change to request_http() - std::shared_ptr tile = shared_from_this(); - platform::Request *request = platform::request_http(url, [=](platform::Response& res) { - if (res.code == 200 && tile->state != obsolete) { - tile->state = Tile::loaded; - tile->data.swap(res.body); - tile->parse(); - } else if (tile->state != obsolete) { - fprintf(stderr, "tile loading failed\n"); - } - }, []() { - platform::restart(); - }); - req = request; -} - -void Tile::cancel() { - // TODO: thread safety - if (state != obsolete) { - state = obsolete; - platform::cancel_request_http(req); - } else { - assert((!"logic error? multiple cancelleations")); - } -} - -bool Tile::parse() { - // std::lock_guard lock(mtx); - - if (state != loaded) { - return false; - } - - try { - VectorTile tile(pbf((const uint8_t *)data.data(), data.size())); - parseStyleLayers(tile, style.layers); - } catch (const std::exception& ex) { - fprintf(stderr, "[%p] exception [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what()); - cancel(); - return false; - } - - if (state == obsolete) { - return false; - } else { - state = parsed; - } - - return true; -} - -void Tile::parseStyleLayers(const VectorTile& tile, const std::vector& layers) { - for (const LayerDescription& layer_desc : layers) { - if (layer_desc.child_layer.size()) { - // This is a layer group. - // TODO: create framebuffer - parseStyleLayers(tile, layer_desc.child_layer); - // TODO: render framebuffer on previous framebuffer - } else { - // This is a singular layer. Check if this bucket already exists. If not, - // parse this bucket. - auto bucket_it = buckets.find(layer_desc.bucket_name); - if (bucket_it == buckets.end()) { - auto bucket_it = style.buckets.find(layer_desc.bucket_name); - if (bucket_it != style.buckets.end()) { - // Only create the new bucket if we have an actual specification - // for it. - std::shared_ptr bucket = createBucket(tile, bucket_it->second); - if (bucket) { - // Bucket creation might fail because the data tile may not - // contain any data that falls into this bucket. - buckets[layer_desc.bucket_name] = bucket; - } - } else { - // There is no proper specification for this bucket, even though - // it is referenced in the stylesheet. - fprintf(stderr, "Stylesheet specifies bucket %s, but it is not defined\n", layer_desc.bucket_name.c_str()); - } - } - } - } -} - -std::shared_ptr Tile::createBucket(const VectorTile& tile, const BucketDescription& bucket_desc) { - auto layer_it = tile.layers.find(bucket_desc.source_layer); - if (layer_it != tile.layers.end()) { - const VectorTileLayer& layer = layer_it->second; - if (bucket_desc.type == BucketType::Fill) { - return createFillBucket(layer, bucket_desc); - } else if (bucket_desc.type == BucketType::Line) { - return createLineBucket(layer, bucket_desc); - } else if (bucket_desc.type == BucketType::Point) { - return createPointBucket(layer, bucket_desc); - } else { - // TODO: create other bucket types. - } - } else { - // The layer specified in the bucket does not exist. Do nothing. - } - - return nullptr; -} - -std::shared_ptr Tile::createFillBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) { - std::shared_ptr bucket = std::make_shared(fillVertexBuffer, triangleElementsBuffer, lineElementsBuffer, bucket_desc); - - // auto init_start = std::chrono::high_resolution_clock::now(); - - FilteredVectorTileLayer filtered_layer(layer, bucket_desc); - for (pbf feature : filtered_layer) { - while (feature.next(4)) { // geometry - pbf geometry_pbf = feature.message(); - if (geometry_pbf) { - bucket->addGeometry(geometry_pbf); - bucket->tessellate(); - } - } - } - - // auto init_end = std::chrono::high_resolution_clock::now(); - // auto init = (double)std::chrono::duration_cast(init_end - init_start).count() / 1000.0; - - // auto tess_start = std::chrono::high_resolution_clock::now(); - // auto tess_end = std::chrono::high_resolution_clock::now(); - // auto tess = (double)std::chrono::duration_cast(tess_end - tess_start).count() / 1000.0; - - - // fprintf(stderr, "%s/%s init: %f tess: %f\n", bucket_desc.source_layer.c_str(), bucket_desc.source_field.c_str(), init, tess); - - return bucket; -} - -std::shared_ptr Tile::createLineBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) { - std::shared_ptr bucket = std::make_shared(lineVertexBuffer, triangleElementsBuffer, pointElementsBuffer, bucket_desc); - - FilteredVectorTileLayer filtered_layer(layer, bucket_desc); - for (pbf feature : filtered_layer) { - while (feature.next(4)) { // geometry - pbf geometry_pbf = feature.message(); - if (geometry_pbf) { - bucket->addGeometry(geometry_pbf); - } - } - } - - return bucket; -} - -std::shared_ptr Tile::createPointBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) { - std::shared_ptr bucket = std::make_shared(pointVertexBuffer, bucket_desc); - - FilteredVectorTileLayer filtered_layer(layer, bucket_desc); - for (pbf feature : filtered_layer) { - while (feature.next(4)) { // geometry - pbf geometry_pbf = feature.message(); - if (geometry_pbf) { - bucket->addGeometry(geometry_pbf); - } - } - } - - return bucket; -} diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp new file mode 100644 index 000000000..5b69b1d8a --- /dev/null +++ b/src/map/tile_data.cpp @@ -0,0 +1,215 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace llmr; + +TileData::TileData(Tile::ID id, const Style& style) + : id(id), + state(initial), + fillVertexBuffer(std::make_shared()), + lineVertexBuffer(std::make_shared()), + pointVertexBuffer(std::make_shared()), + triangleElementsBuffer(std::make_shared()), + lineElementsBuffer(std::make_shared()), + pointElementsBuffer(std::make_shared()), + style(style) { + + // Initialize tile debug coordinates + char coord[32]; + snprintf(coord, sizeof(coord), "%d/%d/%d", id.z, id.x, id.y); + debugFontBuffer.addText(coord, 50, 200, 5); +} + +TileData::~TileData() { +} + +const std::string TileData::toString() const { + return util::sprintf("[tile %d/%d/%d]", id.z, id.x, id.y); +} + +void TileData::request() { + state = loading; + + // Create http request + std::string url = util::sprintf(kTileURL, + id.z, id.x, id.y); + + // Note: Somehow this feels slower than the change to request_http() + std::shared_ptr tile = shared_from_this(); + platform::Request *request = platform::request_http(url, [=](platform::Response& res) { + if (res.code == 200 && tile->state != obsolete) { + tile->state = loaded; + tile->data.swap(res.body); + tile->parse(); + } else if (tile->state != obsolete) { + fprintf(stderr, "tile loading failed\n"); + } + }, []() { + platform::restart(); + }); + req = request; +} + +void TileData::cancel() { + if (state != obsolete) { + state = obsolete; + platform::cancel_request_http(req); + } else { + assert((!"logic error? multiple cancelleations")); + } +} + +bool TileData::parse() { + if (state != loaded) { + return false; + } + + try { + double parse_time_start = platform::time(); + VectorTile tile(pbf((const uint8_t *)data.data(), data.size())); + parseStyleLayers(tile, style.layers); + double parse_time = (platform::time() - parse_time_start) * 1000.0; + if (state == obsolete) { + fprintf(stderr, "[%p] parsing [%d/%d/%d] cancelled after %8.3fms\n", this, id.z, id.x, id.y, parse_time); + } else { + fprintf(stderr, "[%p] parsing [%d/%d/%d] took %8.3fms\n", this, id.z, id.x, id.y, parse_time); + } + } catch (const std::exception& ex) { + fprintf(stderr, "[%p] exception [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what()); + cancel(); + return false; + } + + if (state == obsolete) { + return false; + } else { + state = parsed; + } + + return true; +} + +void TileData::parseStyleLayers(const VectorTile& tile, const std::vector& layers) { + for (const LayerDescription& layer_desc : layers) { + // Cancel early when parsing. + if (state == obsolete) { + return; + } + + if (layer_desc.child_layer.size()) { + // This is a layer group. + // TODO: create framebuffer + parseStyleLayers(tile, layer_desc.child_layer); + // TODO: render framebuffer on previous framebuffer + } else { + // This is a singular layer. Check if this bucket already exists. If not, + // parse this bucket. + auto bucket_it = buckets.find(layer_desc.bucket_name); + if (bucket_it == buckets.end()) { + auto bucket_it = style.buckets.find(layer_desc.bucket_name); + if (bucket_it != style.buckets.end()) { + // Only create the new bucket if we have an actual specification + // for it. + std::shared_ptr bucket = createBucket(tile, bucket_it->second); + if (bucket) { + // Bucket creation might fail because the data tile may not + // contain any data that falls into this bucket. + buckets[layer_desc.bucket_name] = bucket; + } + } else { + // There is no proper specification for this bucket, even though + // it is referenced in the stylesheet. + fprintf(stderr, "Stylesheet specifies bucket %s, but it is not defined\n", layer_desc.bucket_name.c_str()); + } + } + } + } +} + +std::shared_ptr TileData::createBucket(const VectorTile& tile, const BucketDescription& bucket_desc) { + auto layer_it = tile.layers.find(bucket_desc.source_layer); + if (layer_it != tile.layers.end()) { + const VectorTileLayer& layer = layer_it->second; + if (bucket_desc.type == BucketType::Fill) { + return createFillBucket(layer, bucket_desc); + } else if (bucket_desc.type == BucketType::Line) { + return createLineBucket(layer, bucket_desc); + } else if (bucket_desc.type == BucketType::Point) { + return createPointBucket(layer, bucket_desc); + } else { + // TODO: create other bucket types. + } + } else { + // The layer specified in the bucket does not exist. Do nothing. + } + + return nullptr; +} + +std::shared_ptr TileData::createFillBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) { + std::shared_ptr bucket = std::make_shared(fillVertexBuffer, triangleElementsBuffer, lineElementsBuffer, bucket_desc); + + FilteredVectorTileLayer filtered_layer(layer, bucket_desc); + for (pbf feature : filtered_layer) { + if (state == obsolete) return nullptr; + + while (feature.next(4)) { // geometry + pbf geometry_pbf = feature.message(); + if (geometry_pbf) { + bucket->addGeometry(geometry_pbf); + bucket->tessellate(); + } + } + } + + return bucket; +} + +std::shared_ptr TileData::createLineBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) { + std::shared_ptr bucket = std::make_shared(lineVertexBuffer, triangleElementsBuffer, pointElementsBuffer, bucket_desc); + + FilteredVectorTileLayer filtered_layer(layer, bucket_desc); + for (pbf feature : filtered_layer) { + if (state == obsolete) return nullptr; + + while (feature.next(4)) { // geometry + pbf geometry_pbf = feature.message(); + if (geometry_pbf) { + bucket->addGeometry(geometry_pbf); + } + } + } + + return bucket; +} + +std::shared_ptr TileData::createPointBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) { + std::shared_ptr bucket = std::make_shared(pointVertexBuffer, bucket_desc); + + FilteredVectorTileLayer filtered_layer(layer, bucket_desc); + for (pbf feature : filtered_layer) { + if (state == obsolete) return nullptr; + + while (feature.next(4)) { // geometry + pbf geometry_pbf = feature.message(); + if (geometry_pbf) { + bucket->addGeometry(geometry_pbf); + } + } + } + + return bucket; +} diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 90ba77631..d6f02cc34 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -130,8 +130,8 @@ void Painter::clear() { glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -void Painter::render(const Tile::Ptr& tile) { - if (tile->state != Tile::parsed) { +void Painter::render(const TileData::Ptr& tile) { + if (tile->state != TileData::parsed) { return; } @@ -147,7 +147,7 @@ void Painter::render(const Tile::Ptr& tile) { renderBackground(); } -void Painter::renderLayers(const std::shared_ptr& tile, const std::vector& layers) { +void Painter::renderLayers(const std::shared_ptr& tile, const std::vector& layers) { // Render everything top-to-bottom by using reverse iterators typedef std::vector::const_reverse_iterator iterator; for (iterator it = layers.rbegin(), end = layers.rend(); it != end; ++it) { @@ -423,7 +423,7 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co bucket.drawPoints(*pointShader); } -void Painter::renderDebug(const Tile::Ptr& tile) { +void Painter::renderDebug(const TileData::Ptr& tile) { // Disable depth test and don't count this towards the depth buffer, // but *don't* disable stencil test, as we want to clip the red tile border // to the tile viewport.