Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[core] refactor to use vector-tile@1.0.0-rc4 #6165

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ mason_use(protozero VERSION 1.4.2 HEADER_ONLY)
mason_use(pixelmatch VERSION 0.10.0 HEADER_ONLY)
mason_use(geojson VERSION 0.4.0 HEADER_ONLY)
mason_use(icu VERSION 58.1)
mason_use(vectortile VERSION 1.0.0-rc4 HEADER_ONLY)

if(WITH_COVERAGE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
Expand Down
1 change: 1 addition & 0 deletions cmake/core.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ target_add_mason_package(mbgl-core PRIVATE kdbush)
target_add_mason_package(mbgl-core PRIVATE earcut)
target_add_mason_package(mbgl-core PRIVATE protozero)
target_add_mason_package(mbgl-core PRIVATE icu)
target_add_mason_package(mbgl-core PRIVATE vectortile)

mbgl_platform_core()

Expand Down
4 changes: 4 additions & 0 deletions src/mbgl/text/glyph_pbf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
#include <mbgl/util/token.hpp>
#include <mbgl/util/url.hpp>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wshadow"
#include <protozero/pbf_reader.hpp>
#pragma GCC diagnostic pop

namespace {

Expand Down
216 changes: 25 additions & 191 deletions src/mbgl/tile/vector_tile.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include <mbgl/tile/vector_tile.hpp>
#include <mbgl/tile/tile_loader_impl.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>

#include <protozero/pbf_reader.hpp>
#include <mbgl/style/update_parameters.hpp>
#include <mapbox/vector_tile.hpp>
#include <protozero/types.hpp>

#include <unordered_map>
#include <unordered_map>
Expand All @@ -13,45 +14,33 @@ namespace mbgl {

class VectorTileLayer;

using packed_iter_type = protozero::iterator_range<protozero::pbf_reader::const_uint32_iterator>;

class VectorTileFeature : public GeometryTileFeature {
public:
VectorTileFeature(protozero::pbf_reader, const VectorTileLayer&);
using feature_type = std::unique_ptr<const mapbox::vector_tile::feature>;
VectorTileFeature(feature_type feature);

FeatureType getType() const override { return type; }
FeatureType getType() const override { return static_cast<FeatureType>(tile_feature->getType()); }
optional<Value> getValue(const std::string&) const override;
std::unordered_map<std::string,Value> getProperties() const override;
optional<FeatureIdentifier> getID() const override;
GeometryCollection getGeometries() const override;

private:
const VectorTileLayer& layer;
optional<FeatureIdentifier> id;
FeatureType type = FeatureType::Unknown;
packed_iter_type tags_iter;
packed_iter_type geometry_iter;
feature_type tile_feature;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gl-native uses camel case for core variable names, so tileFeature.

};

class VectorTileLayer : public GeometryTileLayer {
public:
VectorTileLayer(protozero::pbf_reader);
VectorTileLayer(const protozero::data_view &);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No space before &.


std::size_t featureCount() const override { return features.size(); }
std::size_t featureCount() const override { return tile_layer.featureCount(); }
std::unique_ptr<GeometryTileFeature> getFeature(std::size_t) const override;
std::string getName() const override;

private:
friend class VectorTileData;
friend class VectorTileFeature;

std::string name;
uint32_t version = 1;
uint32_t extent = 4096;
std::unordered_map<std::string, uint32_t> keysMap;
std::vector<std::reference_wrapper<const std::string>> keys;
std::vector<Value> values;
std::vector<protozero::pbf_reader> features;
mapbox::vector_tile::layer tile_layer;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tileLayer

};

class VectorTileData : public GeometryTileData {
Expand Down Expand Up @@ -91,153 +80,27 @@ void VectorTile::setData(std::shared_ptr<const std::string> data_,
GeometryTile::setData(data_ ? std::make_unique<VectorTileData>(data_) : nullptr);
}

Value parseValue(protozero::pbf_reader data) {
while (data.next())
{
switch (data.tag()) {
case 1: // string_value
return data.get_string();
case 2: // float_value
return static_cast<double>(data.get_float());
case 3: // double_value
return data.get_double();
case 4: // int_value
return data.get_int64();
case 5: // uint_value
return data.get_uint64();
case 6: // sint_value
return data.get_sint64();
case 7: // bool_value
return data.get_bool();
default:
data.skip();
break;
}
}
return false;
}

VectorTileFeature::VectorTileFeature(protozero::pbf_reader feature_pbf, const VectorTileLayer& layer_)
: layer(layer_) {
while (feature_pbf.next()) {
switch (feature_pbf.tag()) {
case 1: // id
id = { feature_pbf.get_uint64() };
break;
case 2: // tags
tags_iter = feature_pbf.get_packed_uint32();
break;
case 3: // type
type = static_cast<FeatureType>(feature_pbf.get_enum());
break;
case 4: // geometry
geometry_iter = feature_pbf.get_packed_uint32();
break;
default:
feature_pbf.skip();
break;
}
}
}
VectorTileFeature::VectorTileFeature(feature_type feature)
: tile_feature(std::move(feature)) { }

optional<Value> VectorTileFeature::getValue(const std::string& key) const {
auto keyIter = layer.keysMap.find(key);
if (keyIter == layer.keysMap.end()) {
return optional<Value>();
}

auto start_itr = tags_iter.begin();
const auto & end_itr = tags_iter.end();
while (start_itr != end_itr) {
uint32_t tag_key = static_cast<uint32_t>(*start_itr++);

if (layer.keysMap.size() <= tag_key) {
throw std::runtime_error("feature referenced out of range key");
}

if (start_itr == end_itr) {
throw std::runtime_error("uneven number of feature tag ids");
}

uint32_t tag_val = static_cast<uint32_t>(*start_itr++);;
if (layer.values.size() <= tag_val) {
throw std::runtime_error("feature referenced out of range value");
}

if (tag_key == keyIter->second) {
return layer.values[tag_val];
}
}

return optional<Value>();
return tile_feature->getValue(key);
}

std::unordered_map<std::string,Value> VectorTileFeature::getProperties() const {
std::unordered_map<std::string,Value> properties;
auto start_itr = tags_iter.begin();
const auto & end_itr = tags_iter.end();
while (start_itr != end_itr) {
uint32_t tag_key = static_cast<uint32_t>(*start_itr++);
if (start_itr == end_itr) {
throw std::runtime_error("uneven number of feature tag ids");
}
uint32_t tag_val = static_cast<uint32_t>(*start_itr++);
properties[layer.keys.at(tag_key)] = layer.values.at(tag_val);
}
return properties;
return tile_feature->getProperties();
}

optional<FeatureIdentifier> VectorTileFeature::getID() const {
return id;
return tile_feature->getID();
}

GeometryCollection VectorTileFeature::getGeometries() const {
uint8_t cmd = 1;
uint32_t length = 0;
int32_t x = 0;
int32_t y = 0;
const float scale = float(util::EXTENT) / layer.extent;

GeometryCollection lines;

lines.emplace_back();
GeometryCoordinates* line = &lines.back();

auto g_itr = geometry_iter.begin();
while (g_itr != geometry_iter.end()) {
if (length == 0) {
uint32_t cmd_length = static_cast<uint32_t>(*g_itr++);
cmd = cmd_length & 0x7;
length = cmd_length >> 3;
}

--length;

if (cmd == 1 || cmd == 2) {
x += protozero::decode_zigzag32(static_cast<uint32_t>(*g_itr++));
y += protozero::decode_zigzag32(static_cast<uint32_t>(*g_itr++));

if (cmd == 1 && !line->empty()) { // moveTo
lines.emplace_back();
line = &lines.back();
}

line->emplace_back(::round(x * scale), ::round(y * scale));

} else if (cmd == 7) { // closePolygon
if (!line->empty()) {
line->push_back((*line)[0]);
}

} else {
throw std::runtime_error("unknown command");
}
}

if (layer.version >= 2 || type != FeatureType::Polygon) {
const float scale = float(util::EXTENT) / tile_feature->getExtent();
GeometryCollection lines = tile_feature->getGeometries<GeometryCollection>(scale);
if (tile_feature->getVersion() >= 2 || tile_feature->getType() != mapbox::vector_tile::GeomType::POLYGON) {
return lines;
}

return fixupPolygons(lines);
}

Expand All @@ -248,10 +111,9 @@ VectorTileData::VectorTileData(std::shared_ptr<const std::string> data_)
const GeometryTileLayer* VectorTileData::getLayer(const std::string& name) const {
if (!parsed) {
parsed = true;
protozero::pbf_reader tile_pbf(*data);
while (tile_pbf.next(3)) {
VectorTileLayer layer(tile_pbf.get_message());
layers.emplace(layer.name, std::move(layer));
mapbox::vector_tile::buffer tile_buffer(*data);
for (auto const& tile_layer : tile_buffer.getLayers()) {
layers.emplace(tile_layer.first, tile_layer.second);
}
}

Expand All @@ -262,43 +124,15 @@ const GeometryTileLayer* VectorTileData::getLayer(const std::string& name) const
return nullptr;
}

VectorTileLayer::VectorTileLayer(protozero::pbf_reader layer_pbf) {
while (layer_pbf.next()) {
switch (layer_pbf.tag()) {
case 1: // name
name = layer_pbf.get_string();
break;
case 2: // feature
features.push_back(layer_pbf.get_message());
break;
case 3: // keys
{
auto iter = keysMap.emplace(layer_pbf.get_string(), keysMap.size());
keys.emplace_back(std::reference_wrapper<const std::string>(iter.first->first));
}
break;
case 4: // values
values.emplace_back(parseValue(layer_pbf.get_message()));
break;
case 5: // extent
extent = layer_pbf.get_uint32();
break;
case 15: // version
version = layer_pbf.get_uint32();
break;
default:
layer_pbf.skip();
break;
}
}
}
VectorTileLayer::VectorTileLayer(const protozero::data_view & layer_view) :
tile_layer(layer_view) { }

std::unique_ptr<GeometryTileFeature> VectorTileLayer::getFeature(std::size_t i) const {
return std::make_unique<VectorTileFeature>(features.at(i), *this);
return std::make_unique<VectorTileFeature>(tile_layer.getFeature(i));
}

std::string VectorTileLayer::getName() const {
return name;
return tile_layer.getName();
}

} // namespace mbgl