move to raster buckets & tile parser handling raster decoding
This commit is contained in:
@@ -8,7 +8,7 @@ namespace llmr {
|
||||
|
||||
class TileParser {
|
||||
public:
|
||||
TileParser(const std::string& data, TileData& tile, const Style& style, GlyphAtlas& glyphAtlas);
|
||||
TileParser(const std::string& data, TileData& tile, const Style& style, GlyphAtlas& glyphAtlas, bool is_raster = false);
|
||||
|
||||
private:
|
||||
bool obsolete() const;
|
||||
@@ -19,10 +19,12 @@ private:
|
||||
std::unique_ptr<Bucket> createLineBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc);
|
||||
std::unique_ptr<Bucket> createPointBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc);
|
||||
std::unique_ptr<Bucket> createTextBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc);
|
||||
std::unique_ptr<Bucket> createRasterBucket(const BucketDescription& bucket_desc);
|
||||
template <class Bucket> void addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const BucketDescription& bucket_desc);
|
||||
|
||||
private:
|
||||
const VectorTile data;
|
||||
const VectorTile vector_data;
|
||||
const std::string raster_data;
|
||||
TileData& tile;
|
||||
const Style& style;
|
||||
GlyphAtlas& glyphAtlas;
|
||||
|
||||
@@ -28,6 +28,7 @@ class FillBucket;
|
||||
class LineBucket;
|
||||
class PointBucket;
|
||||
class TextBucket;
|
||||
class RasterBucket;
|
||||
|
||||
class Painter : private util::noncopyable {
|
||||
public:
|
||||
@@ -42,6 +43,7 @@ public:
|
||||
void renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& id);
|
||||
void renderPoint(PointBucket& bucket, const std::string& layer_name, const Tile::ID& id);
|
||||
void renderText(TextBucket& bucket, const std::string& layer_name, const Tile::ID& id);
|
||||
void renderRaster(const std::string& layer_name, const std::shared_ptr<TileData>& tile_data);
|
||||
|
||||
void resize(int width, int height);
|
||||
|
||||
@@ -52,7 +54,6 @@ public:
|
||||
bool needsAnimation() const;
|
||||
private:
|
||||
void setupShaders();
|
||||
void renderRaster(const std::string& layer_name, const std::shared_ptr<TileData>& tile_data);
|
||||
void renderLayers(const std::shared_ptr<TileData>& tile, const std::vector<LayerDescription>& layers);
|
||||
void renderLayer(const std::shared_ptr<TileData>& tile_data, const LayerDescription& layer_desc);
|
||||
void renderDebug(const std::shared_ptr<TileData>& tile);
|
||||
|
||||
20
include/llmr/renderer/raster_bucket.hpp
Normal file
20
include/llmr/renderer/raster_bucket.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef LLMR_RENDERER_RASTERBUCKET
|
||||
#define LLMR_RENDERER_RASTERBUCKET
|
||||
|
||||
#include <llmr/renderer/bucket.hpp>
|
||||
#include <llmr/style/bucket_description.hpp>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
class BucketDescription;
|
||||
|
||||
class RasterBucket : public Bucket {
|
||||
public:
|
||||
RasterBucket(const BucketDescription& bucket_desc);
|
||||
|
||||
virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -14,7 +14,8 @@ enum class BucketType {
|
||||
Fill = 1,
|
||||
Line = 2,
|
||||
Point = 3,
|
||||
Text = 4
|
||||
Text = 4,
|
||||
Raster = 5
|
||||
};
|
||||
|
||||
enum class CapType {
|
||||
@@ -42,6 +43,7 @@ inline BucketType bucketType(const std::string& type) {
|
||||
else if (type == "line") return BucketType::Line;
|
||||
else if (type == "point") return BucketType::Point;
|
||||
else if (type == "text") return BucketType::Text;
|
||||
else if (type == "raster") return BucketType::Raster;
|
||||
else return BucketType::None;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,12 +52,15 @@ void Source::render(bool is_baselayer) {
|
||||
|
||||
for (const Tile& tile : tiles) {
|
||||
if (tile.data && tile.data->state == TileData::State::parsed) {
|
||||
if (type == Type::raster && *tile.data->raster && !tile.data->raster->textured) {
|
||||
tile.data->raster->setTexturepool(&texturepool);
|
||||
tile.data->raster->beginFadeInAnimation();
|
||||
}
|
||||
if (type == Type::raster && tile.data->raster->needsAnimation()) {
|
||||
tile.data->raster->updateAnimations();
|
||||
if (type == Type::raster) {
|
||||
std::shared_ptr<Raster> raster = tile.data->raster;
|
||||
if (raster && !raster->textured) {
|
||||
raster->setTexturepool(&texturepool);
|
||||
raster->beginFadeInAnimation();
|
||||
}
|
||||
if (raster && raster->needsAnimation()) {
|
||||
raster->updateAnimations();
|
||||
}
|
||||
}
|
||||
painter.render(tile);
|
||||
}
|
||||
|
||||
@@ -70,19 +70,11 @@ bool TileData::parse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_raster) {
|
||||
// raster tiles don't need parsed, just decoded
|
||||
raster = std::make_shared<Raster>();
|
||||
raster->load(data);
|
||||
state = State::parsed;
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
// Parsing creates state that is encapsulated in TileParser. While parsing,
|
||||
// the TileParser object writes results into this objects. All other state
|
||||
// is going to be discarded afterwards.
|
||||
TileParser parser(data, *this, style, glyphAtlas);
|
||||
TileParser parser(data, *this, style, glyphAtlas, is_raster);
|
||||
} 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();
|
||||
|
||||
@@ -5,19 +5,22 @@
|
||||
#include <llmr/renderer/line_bucket.hpp>
|
||||
#include <llmr/renderer/point_bucket.hpp>
|
||||
#include <llmr/renderer/text_bucket.hpp>
|
||||
#include <llmr/renderer/raster_bucket.hpp>
|
||||
#include <llmr/util/raster.hpp>
|
||||
|
||||
#include <llmr/util/std.hpp>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
|
||||
TileParser::TileParser(const std::string& data, TileData& tile, const Style& style, GlyphAtlas& glyphAtlas)
|
||||
: data(pbf((const uint8_t *)data.data(), data.size())),
|
||||
TileParser::TileParser(const std::string& data, TileData& tile, const Style& style, GlyphAtlas& glyphAtlas, bool is_raster)
|
||||
: vector_data(is_raster ? pbf(0, 0) : pbf((const uint8_t *)data.data(), data.size())),
|
||||
raster_data(is_raster ? data : ""),
|
||||
tile(tile),
|
||||
style(style),
|
||||
glyphAtlas(glyphAtlas),
|
||||
placement(tile.id.z) {
|
||||
parseGlyphs();
|
||||
placement(is_raster ? 0 : tile.id.z) {
|
||||
if (!is_raster) parseGlyphs();
|
||||
parseStyleLayers(style.layers);
|
||||
}
|
||||
|
||||
@@ -26,7 +29,7 @@ bool TileParser::obsolete() const {
|
||||
}
|
||||
|
||||
void TileParser::parseGlyphs() {
|
||||
for (const std::pair<std::string, const VectorTileFace> pair : data.faces) {
|
||||
for (const std::pair<std::string, const VectorTileFace> pair : vector_data.faces) {
|
||||
const std::string &name = pair.first;
|
||||
const VectorTileFace &face = pair.second;
|
||||
|
||||
@@ -77,22 +80,30 @@ void TileParser::parseStyleLayers(const std::vector<LayerDescription>& layers) {
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> TileParser::createBucket(const BucketDescription& bucket_desc) {
|
||||
auto layer_it = data.layers.find(bucket_desc.source_layer);
|
||||
if (layer_it != data.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 if (bucket_desc.type == BucketType::Text) {
|
||||
return createTextBucket(layer, bucket_desc);
|
||||
} else {
|
||||
throw std::runtime_error("unknown bucket type");
|
||||
if (bucket_desc.type == BucketType::Raster) {
|
||||
if (raster_data.length()) {
|
||||
tile.raster = std::make_shared<Raster>();
|
||||
tile.raster->load(raster_data);
|
||||
}
|
||||
return createRasterBucket(bucket_desc);
|
||||
} else {
|
||||
// The layer specified in the bucket does not exist. Do nothing.
|
||||
auto layer_it = vector_data.layers.find(bucket_desc.source_layer);
|
||||
if (layer_it != vector_data.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 if (bucket_desc.type == BucketType::Text) {
|
||||
return createTextBucket(layer, bucket_desc);
|
||||
} else {
|
||||
throw std::runtime_error("unknown bucket type");
|
||||
}
|
||||
} else {
|
||||
// The layer specified in the bucket does not exist. Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -166,3 +177,10 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer& laye
|
||||
|
||||
return std::move(bucket);
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> TileParser::createRasterBucket(const BucketDescription& bucket_desc) {
|
||||
std::unique_ptr<RasterBucket> bucket = std::make_unique<RasterBucket>(bucket_desc);
|
||||
// Raster buckets are just empty dummies so that they behave
|
||||
// similarly to vector buckets in styling configurations.
|
||||
return obsolete() ? nullptr : std::move(bucket);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <llmr/renderer/line_bucket.hpp>
|
||||
#include <llmr/renderer/point_bucket.hpp>
|
||||
#include <llmr/renderer/text_bucket.hpp>
|
||||
#include <llmr/renderer/raster_bucket.hpp>
|
||||
|
||||
#include <llmr/map/transform.hpp>
|
||||
#include <llmr/map/settings.hpp>
|
||||
@@ -209,8 +210,10 @@ void Painter::renderLayer(const std::shared_ptr<TileData>& tile_data, const Laye
|
||||
} else {
|
||||
// This is a singular layer. Try to find the bucket associated with
|
||||
// this layer and render it.
|
||||
if (layer_desc.name == "satellite" && tile_data && tile_data->raster) { // FIXME
|
||||
renderRaster(layer_desc.name, tile_data);
|
||||
if (style.buckets[layer_desc.bucket_name].type == BucketType::Raster) {
|
||||
if (tile_data && tile_data->raster) {
|
||||
renderRaster(layer_desc.name, tile_data);
|
||||
}
|
||||
} else {
|
||||
auto bucket_it = tile_data->buckets.find(layer_desc.bucket_name);
|
||||
if (bucket_it != tile_data->buckets.end()) {
|
||||
|
||||
14
src/renderer/raster_bucket.cpp
Normal file
14
src/renderer/raster_bucket.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <llmr/renderer/raster_bucket.hpp>
|
||||
#include <llmr/renderer/painter.hpp>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
RasterBucket::RasterBucket(const BucketDescription& bucket_desc) {
|
||||
}
|
||||
|
||||
void RasterBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) {
|
||||
// The painter renders rasters directly. This function is a no-op
|
||||
// and exists just to satisfy the abstract superclass requirements.
|
||||
// That way, we can avoid having raster buckets pass around
|
||||
// references to tile data and/or rasters directly.
|
||||
}
|
||||
Reference in New Issue
Block a user