saving current state
This commit is contained in:
@@ -62,72 +62,74 @@ void TileParser::addGlyph(uint64_t tileid, const std::string stackname,
|
||||
}
|
||||
}
|
||||
|
||||
void TileParser::parseStyleLayers(const std::vector<LayerDescription> &layers) {
|
||||
for (const LayerDescription &layer_desc : layers) {
|
||||
void TileParser::parseStyleLayers(std::shared_ptr<StyleLayerGroup> layers) {
|
||||
if (!layers) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const std::shared_ptr<StyleLayer> &layer_desc : *layers) {
|
||||
// Cancel early when parsing.
|
||||
if (obsolete()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (layer_desc.bucket_name == "background") {
|
||||
if (layer_desc->id == "background") {
|
||||
// background is a special, fake bucket
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layer_desc.child_layer.size()) {
|
||||
} else if (layer_desc->layers) {
|
||||
// This is a layer group.
|
||||
// TODO: create framebuffer
|
||||
parseStyleLayers(layer_desc.child_layer);
|
||||
// TODO: render framebuffer on previous framebuffer
|
||||
} else {
|
||||
parseStyleLayers(layer_desc->layers);
|
||||
} else if (layer_desc->bucket) {
|
||||
// This is a singular layer. Check if this bucket already exists. If not,
|
||||
// parse this bucket.
|
||||
auto bucket_it = tile.buckets.find(layer_desc.bucket_name);
|
||||
auto bucket_it = tile.buckets.find(layer_desc->bucket->name);
|
||||
if (bucket_it == tile.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::unique_ptr<Bucket> bucket = createBucket(bucket_it->second);
|
||||
if (bucket) {
|
||||
// Bucket creation might fail because the data tile may not
|
||||
// contain any data that falls into this bucket.
|
||||
tile.buckets[layer_desc.bucket_name] = std::move(bucket);
|
||||
}
|
||||
} else {
|
||||
// There is no proper specification for this bucket, even though
|
||||
// it is referenced in the stylesheet.
|
||||
if (debug::tileParseWarnings) {
|
||||
fprintf(stderr, "Stylesheet specifies bucket %s, but it is not defined\n",
|
||||
layer_desc.bucket_name.c_str());
|
||||
}
|
||||
// We need to create this bucket since it doesn't exist yet.
|
||||
std::unique_ptr<Bucket> bucket = createBucket(layer_desc->bucket);
|
||||
if (bucket) {
|
||||
// Bucket creation might fail because the data tile may not
|
||||
// contain any data that falls into this bucket.
|
||||
tile.buckets[layer_desc->bucket->name] = std::move(bucket);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] layer does not have child layers or buckets\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> TileParser::createBucket(const BucketDescription &bucket_desc) {
|
||||
auto layer_it = vector_data.layers.find(bucket_desc.source_layer);
|
||||
std::unique_ptr<Bucket> TileParser::createBucket(std::shared_ptr<StyleBucket> bucket_desc) {
|
||||
if (!bucket_desc) {
|
||||
fprintf(stderr, "missing bucket desc\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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::Icon) {
|
||||
return createIconBucket(layer, bucket_desc);
|
||||
} else if (bucket_desc.type == BucketType::Text) {
|
||||
return createTextBucket(layer, bucket_desc);
|
||||
if (bucket_desc->render.is<StyleBucketFill>()) {
|
||||
fprintf(stderr, "create fill bucket\n");
|
||||
return createFillBucket(layer, bucket_desc->filter, bucket_desc->render.get<StyleBucketFill>());
|
||||
} else if (bucket_desc->render.is<StyleBucketLine>()) {
|
||||
fprintf(stderr, "create line bucket\n");
|
||||
return createLineBucket(layer, bucket_desc->filter, bucket_desc->render.get<StyleBucketLine>());
|
||||
} else if (bucket_desc->render.is<StyleBucketIcon>()) {
|
||||
fprintf(stderr, "create icon bucket\n");
|
||||
return createIconBucket(layer, bucket_desc->filter, bucket_desc->render.get<StyleBucketIcon>());
|
||||
} else if (bucket_desc->render.is<StyleBucketText>()) {
|
||||
fprintf(stderr, "create text bucket\n");
|
||||
return createTextBucket(layer, bucket_desc->filter, bucket_desc->render.get<StyleBucketText>());
|
||||
} else if (bucket_desc->render.is<StyleBucketRaster>()) {
|
||||
fprintf(stderr, "create raster bucket\n");
|
||||
return nullptr;
|
||||
} else {
|
||||
throw std::runtime_error("unknown bucket type");
|
||||
fprintf(stderr, "[WARNING] unknown bucket render type for layer '%s'\n", bucket_desc->source_layer.c_str());
|
||||
}
|
||||
} else {
|
||||
// The layer specified in the bucket does not exist. Do nothing.
|
||||
if (debug::tileParseWarnings) {
|
||||
fprintf(stderr, "[WARNING] layer '%s' does not exist in tile %d/%d/%d of source '%s'\n",
|
||||
bucket_desc.source_layer.c_str(), tile.id.z, tile.id.x, tile.id.y,
|
||||
bucket_desc.source_name.c_str());
|
||||
fprintf(stderr, "[WARNING] layer '%s' does not exist in tile %d/%d/%d\n",
|
||||
bucket_desc->source_layer.c_str(), tile.id.z, tile.id.x, tile.id.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,9 +137,8 @@ std::unique_ptr<Bucket> TileParser::createBucket(const BucketDescription &bucket
|
||||
}
|
||||
|
||||
template <class Bucket>
|
||||
void TileParser::addBucketFeatures(Bucket &bucket, const VectorTileLayer &layer,
|
||||
const BucketDescription &bucket_desc) {
|
||||
FilteredVectorTileLayer filtered_layer(layer, bucket_desc);
|
||||
void TileParser::addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const PropertyFilterExpression &filter) {
|
||||
FilteredVectorTileLayer filtered_layer(layer, filter);
|
||||
for (pbf feature : filtered_layer) {
|
||||
if (obsolete())
|
||||
return;
|
||||
@@ -154,64 +155,38 @@ void TileParser::addBucketFeatures(Bucket &bucket, const VectorTileLayer &layer,
|
||||
}
|
||||
|
||||
template <class Bucket, typename... Args>
|
||||
void TileParser::addBucketFeatures(Bucket &bucket, const VectorTileLayer &layer,
|
||||
const BucketDescription &bucket_desc, Args &&... args) {
|
||||
FilteredVectorTileLayer filtered_layer(layer, bucket_desc);
|
||||
void TileParser::addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const PropertyFilterExpression &filter, Args&& ...args) {
|
||||
FilteredVectorTileLayer filtered_layer(layer, filter);
|
||||
for (const pbf &feature_pbf : filtered_layer) {
|
||||
if (obsolete())
|
||||
if (obsolete()) {
|
||||
return;
|
||||
}
|
||||
bucket->addFeature({feature_pbf, layer}, std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> TileParser::createFillBucket(const VectorTileLayer &layer,
|
||||
const BucketDescription &bucket_desc) {
|
||||
if (!bucket_desc.render.valid() || !bucket_desc.render.is<BucketFillDescription>()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<FillBucket> bucket = std::make_unique<FillBucket>(
|
||||
tile.fillVertexBuffer, tile.triangleElementsBuffer, tile.lineElementsBuffer,
|
||||
bucket_desc.render.get<BucketFillDescription>());
|
||||
addBucketFeatures(bucket, layer, bucket_desc);
|
||||
std::unique_ptr<Bucket> TileParser::createFillBucket(const VectorTileLayer& layer, const PropertyFilterExpression &filter, const StyleBucketFill &fill) {
|
||||
std::unique_ptr<FillBucket> bucket = std::make_unique<FillBucket>(tile.fillVertexBuffer, tile.triangleElementsBuffer, tile.lineElementsBuffer, fill);
|
||||
addBucketFeatures(bucket, layer, filter);
|
||||
return obsolete() ? nullptr : std::move(bucket);
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> TileParser::createLineBucket(const VectorTileLayer &layer,
|
||||
const BucketDescription &bucket_desc) {
|
||||
if (!bucket_desc.render.valid() || !bucket_desc.render.is<BucketLineDescription>()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<LineBucket> bucket = std::make_unique<LineBucket>(
|
||||
tile.lineVertexBuffer, tile.triangleElementsBuffer, tile.pointElementsBuffer,
|
||||
bucket_desc.render.get<BucketLineDescription>());
|
||||
addBucketFeatures(bucket, layer, bucket_desc);
|
||||
std::unique_ptr<Bucket> TileParser::createLineBucket(const VectorTileLayer& layer, const PropertyFilterExpression &filter, const StyleBucketLine &line) {
|
||||
std::unique_ptr<LineBucket> bucket = std::make_unique<LineBucket>(tile.lineVertexBuffer, tile.triangleElementsBuffer, tile.pointElementsBuffer, line);
|
||||
addBucketFeatures(bucket, layer, filter);
|
||||
return obsolete() ? nullptr : std::move(bucket);
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> TileParser::createIconBucket(const VectorTileLayer &layer,
|
||||
const BucketDescription &bucket_desc) {
|
||||
if (!bucket_desc.render.valid() || !bucket_desc.render.is<BucketIconDescription>()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<IconBucket> bucket = std::make_unique<IconBucket>(
|
||||
tile.iconVertexBuffer, bucket_desc.render.get<BucketIconDescription>());
|
||||
addBucketFeatures(bucket, layer, bucket_desc, *spriteAtlas);
|
||||
std::unique_ptr<Bucket> TileParser::createIconBucket(const VectorTileLayer& layer, const PropertyFilterExpression &filter, const StyleBucketIcon &icon) {
|
||||
std::unique_ptr<IconBucket> bucket = std::make_unique<IconBucket>(tile.iconVertexBuffer, icon);
|
||||
addBucketFeatures(bucket, layer, filter, *spriteAtlas);
|
||||
return obsolete() ? nullptr : std::move(bucket);
|
||||
}
|
||||
|
||||
typedef std::pair<uint16_t, uint16_t> GlyphRange;
|
||||
std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer& layer, const PropertyFilterExpression &filter, const StyleBucketText &text) {
|
||||
|
||||
std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer &layer,
|
||||
const BucketDescription &bucket_desc) {
|
||||
|
||||
if (!bucket_desc.render.valid() || !bucket_desc.render.is<BucketTextDescription>()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const BucketTextDescription &properties = bucket_desc.render.get<BucketTextDescription>();
|
||||
const StyleBucketText &properties = text;
|
||||
|
||||
std::unique_ptr<TextBucket> bucket = std::make_unique<TextBucket>(
|
||||
tile.textVertexBuffer, tile.triangleElementsBuffer, properties, placement);
|
||||
@@ -224,7 +199,7 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer &laye
|
||||
{
|
||||
std::set<GlyphRange> ranges;
|
||||
|
||||
FilteredVectorTileLayer filtered_layer(layer, bucket_desc);
|
||||
FilteredVectorTileLayer filtered_layer(layer, filter);
|
||||
for (const pbf &feature_pbf : filtered_layer) {
|
||||
if (obsolete())
|
||||
return nullptr;
|
||||
@@ -234,7 +209,7 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer &laye
|
||||
util::replaceTokens(properties.field, feature.properties));
|
||||
|
||||
// Loop through all characters of this text and collect unique codepoints.
|
||||
for (uint32_t chr : string) {
|
||||
for (char32_t chr : string) {
|
||||
ranges.insert(getGlyphRange(chr));
|
||||
}
|
||||
|
||||
@@ -265,3 +240,9 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer &laye
|
||||
|
||||
return std::move(bucket);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//typedef std::pair<uint16_t, uint16_t> GlyphRange;
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user