git-subtree-dir: third_party/protozero git-subtree-split: d5d8debf1b17c6bb652395957b76cde7787e5377
154 lines
5.7 KiB
C++
154 lines
5.7 KiB
C++
|
|
#include <test.hpp>
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
// Input data.vector is encoded according to
|
|
// https://github.com/mapbox/mapnik-vector-tile/blob/master/proto/vector_tile.proto
|
|
|
|
static std::string get_name(protozero::pbf_reader layer) { // copy!
|
|
while (layer.next(1)) { // required string name
|
|
return layer.get_string();
|
|
}
|
|
return "";
|
|
}
|
|
|
|
TEST_CASE("reading vector tiles") {
|
|
static const std::vector<std::string> expected_layer_names = {
|
|
"landuse", "waterway", "water", "aeroway", "barrier_line", "building",
|
|
"landuse_overlay", "tunnel", "road", "bridge", "admin",
|
|
"country_label_line", "country_label", "marine_label", "state_label",
|
|
"place_label", "water_label", "area_label", "rail_station_label",
|
|
"airport_label", "road_label", "waterway_label", "building_label"
|
|
};
|
|
|
|
const std::string buffer = load_data("vector_tile/data.vector");
|
|
protozero::pbf_reader item{buffer};
|
|
std::vector<std::string> layer_names;
|
|
|
|
SECTION("iterate over message using next()") {
|
|
while (item.next()) {
|
|
if (item.tag() == 3) { // repeated message Layer
|
|
protozero::pbf_reader layer{item.get_message()};
|
|
while (layer.next()) {
|
|
switch (layer.tag()) {
|
|
case 1: // required string name
|
|
layer_names.push_back(layer.get_string());
|
|
break;
|
|
default:
|
|
layer.skip();
|
|
}
|
|
}
|
|
} else {
|
|
item.skip();
|
|
}
|
|
}
|
|
|
|
REQUIRE(layer_names == expected_layer_names);
|
|
}
|
|
|
|
SECTION("iterate over message using next(tag)") {
|
|
while (item.next(3)) { // repeated message Layer
|
|
protozero::pbf_reader layermsg{item.get_message()};
|
|
while (layermsg.next(1)) { // required string name
|
|
layer_names.push_back(layermsg.get_string());
|
|
}
|
|
}
|
|
|
|
REQUIRE(layer_names == expected_layer_names);
|
|
}
|
|
|
|
SECTION("iterate over message using next(tag, type)") {
|
|
while (item.next(3, protozero::pbf_wire_type::length_delimited)) { // repeated message Layer
|
|
protozero::pbf_reader layermsg{item.get_message()};
|
|
while (layermsg.next(1, protozero::pbf_wire_type::length_delimited)) { // required string name
|
|
layer_names.push_back(layermsg.get_string());
|
|
}
|
|
}
|
|
|
|
REQUIRE(layer_names == expected_layer_names);
|
|
}
|
|
|
|
SECTION("iterate over features in road layer") {
|
|
int n=0;
|
|
int n_id = 0;
|
|
int n_geomtype = 0;
|
|
while (item.next(3)) { // repeated message Layer
|
|
protozero::pbf_reader layer{item.get_message()};
|
|
std::string name = get_name(layer);
|
|
if (name == "road") {
|
|
while (layer.next(2)) { // repeated Feature
|
|
++n;
|
|
protozero::pbf_reader feature{layer.get_message()};
|
|
while (feature.next()) {
|
|
switch (feature.tag()) {
|
|
case 1: { // optional uint64 id
|
|
const auto id = feature.get_uint64();
|
|
REQUIRE(id >= 1ULL);
|
|
REQUIRE(id <= 504ULL);
|
|
++n_id;
|
|
break;
|
|
}
|
|
case 3: { // optional GeomType
|
|
const auto geom_type = feature.get_uint32();
|
|
REQUIRE(geom_type >= 1UL);
|
|
REQUIRE(geom_type <= 3UL);
|
|
++n_geomtype;
|
|
break;
|
|
}
|
|
default:
|
|
feature.skip();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
REQUIRE(n == 502);
|
|
REQUIRE(n_id == 502);
|
|
REQUIRE(n_geomtype == 502);
|
|
}
|
|
|
|
SECTION("iterate over features in road layer using tag_and_type") {
|
|
int n=0;
|
|
int n_id = 0;
|
|
int n_geomtype = 0;
|
|
while (item.next(3)) { // repeated message Layer
|
|
protozero::pbf_reader layer{item.get_message()};
|
|
std::string name = get_name(layer);
|
|
if (name == "road") {
|
|
while (layer.next(2)) { // repeated Feature
|
|
++n;
|
|
protozero::pbf_reader feature{layer.get_message()};
|
|
while (feature.next()) {
|
|
switch (feature.tag_and_type()) {
|
|
case protozero::tag_and_type(1, protozero::pbf_wire_type::varint): { // optional uint64 id
|
|
const auto id = feature.get_uint64();
|
|
REQUIRE(id >= 1ULL);
|
|
REQUIRE(id <= 504ULL);
|
|
++n_id;
|
|
break;
|
|
}
|
|
case protozero::tag_and_type(3, protozero::pbf_wire_type::varint): { // optional GeomType
|
|
const auto geom_type = feature.get_uint32();
|
|
REQUIRE(geom_type >= 1UL);
|
|
REQUIRE(geom_type <= 3UL);
|
|
++n_geomtype;
|
|
break;
|
|
}
|
|
default:
|
|
feature.skip();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
REQUIRE(n == 502);
|
|
REQUIRE(n_id == 502);
|
|
REQUIRE(n_geomtype == 502);
|
|
}
|
|
}
|
|
|