move to raster buckets & tile parser handling raster decoding

This commit is contained in:
Justin R. Miller
2014-04-09 11:38:42 -07:00
parent 482ac31fde
commit e5713f31a6
9 changed files with 95 additions and 40 deletions

View File

@@ -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;

View File

@@ -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);

View 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

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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()) {

View 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.
}