VectorTileFeature::VectorTileFeature(pbf feature, const VectorTileLayer& layer) { while (feature.next()) { if (feature.tag == 1) { // id id = feature.varint<uint64_t>(); } else if (feature.tag == 2) { // tags // tags are packed varints. They should have an even length. pbf tags = feature.message(); while (tags) { uint32_t tag_key = tags.varint(); if (layer.keys.size() <= tag_key) { throw std::runtime_error("feature referenced out of range key"); } if (tags) { uint32_t tag_val = tags.varint(); if (layer.values.size() <= tag_val) { throw std::runtime_error("feature referenced out of range value"); } properties.emplace(layer.keys[tag_key], layer.values[tag_val]); } else { throw std::runtime_error("uneven number of feature tag ids"); } } } else if (feature.tag == 3) { // type type = (FeatureType)feature.varint(); } else if (feature.tag == 4) { // geometry geometry = feature.message(); } else { feature.skip(); } } }
VectorTile::VectorTile(pbf tile) { while (tile.next()) { if (tile.tag == 3) { // layer VectorTileLayer layer(tile.message()); layers.emplace(layer.name, std::forward<VectorTileLayer>(layer)); } else { tile.skip(); } } }
VectorTileFeature::VectorTileFeature(pbf feature_pbf, const VectorTileLayer& layer_) : layer(layer_) { while (feature_pbf.next()) { if (feature_pbf.tag == 1) { // id id = feature_pbf.varint<uint64_t>(); } else if (feature_pbf.tag == 2) { // tags tags_pbf = feature_pbf.message(); } else if (feature_pbf.tag == 3) { // type type = (FeatureType)feature_pbf.varint(); } else if (feature_pbf.tag == 4) { // geometry geometry_pbf = feature_pbf.message(); } else { feature_pbf.skip(); } } }
Value parseValue(pbf data) { while (data.next()) { switch (data.tag) { case 1: // string_value return data.string(); case 2: // float_value return static_cast<double>(data.float32()); case 3: // double_value return data.float64(); case 4: // int_value return data.varint<int64_t>(); case 5: // uint_value return data.varint<uint64_t>(); case 6: // sint_value return data.svarint<int64_t>(); case 7: // bool_value return data.boolean(); default: data.skip(); break; } } return false; }
VectorTileLayer::VectorTileLayer(pbf layer) : data(layer) { std::vector<std::string> stacks; while (layer.next()) { if (layer.tag == 1) { // name name = layer.string(); } else if (layer.tag == 3) { // keys keys.emplace_back(layer.string()); key_index.emplace(keys.back(), keys.size() - 1); } else if (layer.tag == 4) { // values values.emplace_back(std::move(parseValue(layer.message()))); } else if (layer.tag == 5) { // extent extent = layer.varint(); } else { layer.skip(); } } }