1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
#include <test.hpp>
#include <string>
#include <vector>
namespace {
// Input data.vector is encoded according to
// https://github.com/mapbox/mapnik-vector-tile/blob/master/proto/vector_tile.proto
std::string get_name(protozero::pbf_reader layer) { // copy!
while (layer.next(1)) { // required string name
return layer.get_string();
}
REQUIRE(false); // should never be here
return "";
}
} // anonymous namespace
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(false); // should never be here
}
}
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()};
const 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()};
const 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);
}
}
|