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; }
void validate_value(protozero::pbf_reader value) { using namespace osrm; while (value.next()) { switch (value.tag()) { case util::vector_tile::VARIANT_TYPE_BOOL: value.get_bool(); break; case util::vector_tile::VARIANT_TYPE_DOUBLE: value.get_double(); break; case util::vector_tile::VARIANT_TYPE_FLOAT: value.get_float(); break; case util::vector_tile::VARIANT_TYPE_STRING: value.get_string(); break; case util::vector_tile::VARIANT_TYPE_UINT64: value.get_uint64(); break; case util::vector_tile::VARIANT_TYPE_SINT64: value.get_sint64(); break; } } }
inline void check_empty(protozero::pbf_reader message) { while (message.next()) { switch (message.tag()) { case 1: { REQUIRE(!message.get_message().next()); break; } case 2: { REQUIRE(77 == message.get_int32()); break; } default: { REQUIRE(false); // should never be here break; } } } }
inline void check_subsub(protozero::pbf_reader message) { while (message.next()) { switch (message.tag()) { case 1: { REQUIRE("foobar" == message.get_string()); break; } case 2: { REQUIRE(99 == message.get_int32()); break; } default: { REQUIRE(false); // should never be here break; } } } }
void validate_node_layer(protozero::pbf_reader &layer_message) { using namespace osrm; auto number_of_nodes_found = 0u; const auto check_osmnode_feature = [](protozero::pbf_reader feature_message) { feature_message.next(); // advance parser to first entry BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::GEOMETRY_TAG); BOOST_CHECK_EQUAL(feature_message.get_enum(), util::vector_tile::GEOMETRY_TYPE_POINT); feature_message.next(); // advance to next entry BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::ID_TAG); feature_message.get_uint64(); // id feature_message.next(); // advance to next entry // Note - on this layer, there should be no feature attributes, the next thing // we get should be the geometry BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_GEOMETRIES_TAG); auto geometry_iter_pair = feature_message.get_packed_uint32(); BOOST_CHECK_GT(std::distance(geometry_iter_pair.begin(), geometry_iter_pair.end()), 1); }; while (layer_message.next()) { switch (layer_message.tag()) { case util::vector_tile::VERSION_TAG: BOOST_CHECK_EQUAL(layer_message.get_uint32(), 2); break; case util::vector_tile::NAME_TAG: BOOST_CHECK_EQUAL(layer_message.get_string(), "osmnodes"); break; case util::vector_tile::EXTENT_TAG: BOOST_CHECK_EQUAL(layer_message.get_uint32(), util::vector_tile::EXTENT); break; case util::vector_tile::FEATURE_TAG: check_osmnode_feature(layer_message.get_message()); number_of_nodes_found++; break; case util::vector_tile::KEY_TAG: BOOST_CHECK(false); // There should be no properties on node features break; case util::vector_tile::VARIANT_TAG: BOOST_CHECK(false); // There should be no properties on node features break; default: BOOST_CHECK(false); // invalid tag break; } } BOOST_CHECK_EQUAL(number_of_nodes_found, 1791); }
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; } } }
namespace { std::string get_name(protozero::pbf_reader layer) { // copy! while (layer.next(1)) { // required string name return layer.get_string(); } return ""; } } // anon namespace TEST_CASE("reading vector tiles") { 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(); } }
#include <test.hpp> TEST_CASE("basic") { SECTION("default constructed pbf message is okay") { protozero::pbf_reader item; REQUIRE(item.length() == 0); REQUIRE(!item); // test operator bool() REQUIRE(!item.next()); } SECTION("empty buffer is okay") { const std::string buffer; protozero::pbf_reader item(buffer); REQUIRE(item.length() == 0); REQUIRE(!item); // test operator bool() REQUIRE(!item.next()); } SECTION("check every possible value for single byte in buffer") { char buffer[1]; for (int i = 0; i <= 255; ++i) { *buffer = static_cast<char>(i); protozero::pbf_reader item(buffer, 1); REQUIRE(item.length() == 1); REQUIRE(!!item); // test operator bool() REQUIRE_THROWS({
void validate_feature_layer(protozero::pbf_reader &layer_message) { using namespace osrm; const auto check_feature = [](protozero::pbf_reader feature_message) { feature_message.next(); // advance parser to first entry BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::GEOMETRY_TAG); BOOST_CHECK_EQUAL(feature_message.get_enum(), util::vector_tile::GEOMETRY_TYPE_LINE); feature_message.next(); // advance to next entry BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::ID_TAG); feature_message.get_uint64(); // id feature_message.next(); // advance to next entry BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_ATTRIBUTES_TAG); // properties auto property_iter_pair = feature_message.get_packed_uint32(); auto value_begin = property_iter_pair.begin(); auto value_end = property_iter_pair.end(); BOOST_CHECK_EQUAL(std::distance(value_begin, value_end), 14); auto iter = value_begin; BOOST_CHECK_EQUAL(*iter++, 0); // speed key BOOST_CHECK_LT(*iter++, 128); // speed value BOOST_CHECK_EQUAL(*iter++, 1); // component key // component value BOOST_CHECK_GE(*iter, 128); BOOST_CHECK_LE(*iter, 129); iter++; BOOST_CHECK_EQUAL(*iter++, 2); // data source key *iter++; // skip value check, can be valud uint32 BOOST_CHECK_EQUAL(*iter++, 3); // weight key BOOST_CHECK_GT(*iter++, 130); // weight value BOOST_CHECK_EQUAL(*iter++, 4); // duration key BOOST_CHECK_GT(*iter++, 130); // duration value // name BOOST_CHECK_EQUAL(*iter++, 5); BOOST_CHECK_GT(*iter++, 130); // rate BOOST_CHECK_EQUAL(*iter++, 6); BOOST_CHECK_GT(*iter++, 130); BOOST_CHECK(iter == value_end); // geometry feature_message.next(); auto geometry_iter_pair = feature_message.get_packed_uint32(); BOOST_CHECK_GT(std::distance(geometry_iter_pair.begin(), geometry_iter_pair.end()), 1); }; auto number_of_speed_keys = 0u; auto number_of_speed_values = 0u; while (layer_message.next()) { switch (layer_message.tag()) { case util::vector_tile::VERSION_TAG: BOOST_CHECK_EQUAL(layer_message.get_uint32(), 2); break; case util::vector_tile::NAME_TAG: BOOST_CHECK_EQUAL(layer_message.get_string(), "speeds"); break; case util::vector_tile::EXTENT_TAG: BOOST_CHECK_EQUAL(layer_message.get_uint32(), util::vector_tile::EXTENT); break; case util::vector_tile::FEATURE_TAG: check_feature(layer_message.get_message()); break; case util::vector_tile::KEY_TAG: layer_message.get_string(); number_of_speed_keys++; break; case util::vector_tile::VARIANT_TAG: validate_value(layer_message.get_message()); number_of_speed_values++; break; default: BOOST_CHECK(false); // invalid tag break; } } BOOST_CHECK_EQUAL(number_of_speed_keys, 7); BOOST_CHECK_GT(number_of_speed_values, 128); // speed value resolution }
void validate_turn_layer(protozero::pbf_reader &layer_message) { using namespace osrm; const auto check_turn_feature = [](protozero::pbf_reader feature_message) { feature_message.next(); // advance parser to first entry BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::GEOMETRY_TAG); BOOST_CHECK_EQUAL(feature_message.get_enum(), util::vector_tile::GEOMETRY_TYPE_POINT); feature_message.next(); // advance to next entry BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::ID_TAG); feature_message.get_uint64(); // id feature_message.next(); // advance to next entry BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_ATTRIBUTES_TAG); // properties auto feature_iter_pair = feature_message.get_packed_uint32(); BOOST_CHECK_EQUAL(std::distance(feature_iter_pair.begin(), feature_iter_pair.end()), 12); auto iter = feature_iter_pair.begin(); BOOST_CHECK_EQUAL(*iter++, 0); // bearing_in key *iter++; BOOST_CHECK_EQUAL(*iter++, 1); // turn_angle key *iter++; BOOST_CHECK_EQUAL(*iter++, 2); // turn cost (duration) key *iter++; // skip value check, can be valud uint32 BOOST_CHECK_EQUAL(*iter++, 3); // turn weight key *iter++; // skip value check, can be valud uint32 BOOST_CHECK_EQUAL(*iter++, 4); // turn type key *iter++; // skip value check, can be valud uint32 BOOST_CHECK_EQUAL(*iter++, 5); // turn modifier *iter++; // skip value check, can be valud uint32 BOOST_CHECK(iter == feature_iter_pair.end()); // geometry feature_message.next(); auto geometry_iter_pair = feature_message.get_packed_uint32(); BOOST_CHECK_GT(std::distance(geometry_iter_pair.begin(), geometry_iter_pair.end()), 1); }; auto number_of_turn_keys = 0u; auto number_of_turns_found = 0u; while (layer_message.next()) { switch (layer_message.tag()) { case util::vector_tile::VERSION_TAG: BOOST_CHECK_EQUAL(layer_message.get_uint32(), 2); break; case util::vector_tile::NAME_TAG: BOOST_CHECK_EQUAL(layer_message.get_string(), "turns"); break; case util::vector_tile::EXTENT_TAG: BOOST_CHECK_EQUAL(layer_message.get_uint32(), util::vector_tile::EXTENT); break; case util::vector_tile::FEATURE_TAG: check_turn_feature(layer_message.get_message()); number_of_turns_found++; break; case util::vector_tile::KEY_TAG: layer_message.get_string(); number_of_turn_keys++; break; case util::vector_tile::VARIANT_TAG: validate_value(layer_message.get_message()); break; default: BOOST_CHECK(false); // invalid tag break; } } BOOST_CHECK_EQUAL(number_of_turn_keys, 6); BOOST_CHECK(number_of_turns_found > 700); }
vector_tile::Tile tile; tile.ParseFromString(out_tile.get_buffer()); REQUIRE(1 == tile.layers_size()); vector_tile::Tile_Layer const& layer = tile.layers(0); CHECK(std::string("layer") == layer.name()); REQUIRE(1 == layer.features_size()); vector_tile::Tile_Feature const& f = layer.features(0); unsigned z = 0; unsigned x = 0; unsigned y = 0; double resolution = mapnik::EARTH_CIRCUMFERENCE/(1 << z); double tile_x = -0.5 * mapnik::EARTH_CIRCUMFERENCE + x * resolution; double tile_y = 0.5 * mapnik::EARTH_CIRCUMFERENCE - y * resolution; double scale = static_cast<double>(layer.extent())/resolution; protozero::pbf_reader layer_reader; out_tile.layer_reader(0, layer_reader); REQUIRE(layer_reader.next(mapnik::vector_tile_impl::Layer_Encoding::FEATURES)); protozero::pbf_reader feature_reader = layer_reader.get_message(); int32_t geometry_type = mapnik::vector_tile_impl::Geometry_Type::UNKNOWN; mapnik::vector_tile_impl::GeometryPBF::pbf_itr geom_itr; while (feature_reader.next()) { if (feature_reader.tag() == mapnik::vector_tile_impl::Feature_Encoding::GEOMETRY) { geom_itr = feature_reader.get_packed_uint32(); } else if (feature_reader.tag() == mapnik::vector_tile_impl::Feature_Encoding::TYPE) { geometry_type = feature_reader.get_enum(); }
static std::string get_name(protozero::pbf_reader layer) { // copy! while (layer.next(1)) { // required string name return layer.get_string(); } return ""; }
#include <test.hpp> namespace TestBoolean { enum class Test : protozero::pbf_tag_type { required_bool_b = 1 }; } // end namespace TestBoolean TEST_CASE("read bool field using pbf_reader: false") { const std::string buffer = load_data("bool/data-false"); protozero::pbf_reader item{buffer}; REQUIRE(item.next()); REQUIRE_FALSE(item.get_bool()); REQUIRE_FALSE(item.next()); } TEST_CASE("read bool field using pbf_reader: true") { const std::string buffer = load_data("bool/data-true"); protozero::pbf_reader item{buffer}; REQUIRE(item.next()); REQUIRE(item.get_bool()); REQUIRE_FALSE(item.next()); }
mapnik::Map map2(tile_size,tile_size,"+init=epsg:3857"); tile_type tile2; CHECK(tile2.ParseFromString(buffer)); std::string key(""); CHECK(false == mapnik::vector_tile_impl::is_solid_extent(tile2,key)); CHECK("" == key); CHECK(false == mapnik::vector_tile_impl::is_solid_extent(buffer,key)); CHECK("" == key); CHECK(1 == tile2.layers_size()); vector_tile::Tile_Layer const& layer2 = tile2.layers(0); CHECK(std::string("layer") == layer2.name()); CHECK(1 == layer2.features_size()); mapnik::layer lyr2("layer",map.srs()); protozero::pbf_reader pbf_tile(buffer.c_str(), buffer.size()); pbf_tile.next(); protozero::pbf_reader layer3 = pbf_tile.get_message(); std::shared_ptr<mapnik::vector_tile_impl::tile_datasource_pbf> ds = std::make_shared< mapnik::vector_tile_impl::tile_datasource_pbf>( layer3,0,0,0,map2.width()); CHECK(ds->get_name() == "layer"); ds->set_envelope(bbox); CHECK( ds->type() == mapnik::datasource::Vector ); CHECK( ds->get_geometry_type() == mapnik::datasource_geometry_t::Collection ); mapnik::layer_descriptor lay_desc = ds->get_descriptor(); std::vector<std::string> expected_names; expected_names.push_back("bool"); expected_names.push_back("boolf"); expected_names.push_back("double");