File: reader_test_cases.cpp

package info (click to toggle)
protozero 1.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,548 kB
  • sloc: cpp: 20,364; sh: 18; makefile: 14
file content (159 lines) | stat: -rw-r--r-- 5,990 bytes parent folder | download | duplicates (2)
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);
    }
}