refs #928: bookmarking working build of refactor
This commit is contained in:
committed by
John Firebaugh
parent
831264d530
commit
41c3b82d3e
@@ -1,18 +1,20 @@
|
||||
#include <mbgl/map/vector_tile.hpp>
|
||||
#include <mbgl/geometry/pbf_geometry.hpp>
|
||||
#include <mbgl/style/filter_expression_private.hpp>
|
||||
#include <mbgl/util/variant_io.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <ostream>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
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
|
||||
VectorTileFeature::VectorTileFeature(pbf feature_pbf, const GeometryTileLayer& 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 are packed varints. They should have an even length.
|
||||
pbf tags = feature.message();
|
||||
pbf tags = feature_pbf.message();
|
||||
while (tags) {
|
||||
uint32_t tag_key = tags.varint();
|
||||
|
||||
@@ -31,22 +33,64 @@ VectorTileFeature::VectorTileFeature(pbf feature, const VectorTileLayer& layer)
|
||||
throw std::runtime_error("uneven number of feature tag ids");
|
||||
}
|
||||
}
|
||||
} else if (feature.tag == 3) { // type
|
||||
type = (GeometryFeatureType)feature.varint();
|
||||
} else if (feature.tag == 4) { // geometry
|
||||
geometries = feature.message();
|
||||
} else if (feature_pbf.tag == 3) { // type
|
||||
type = (GeometryFeatureType)feature_pbf.varint();
|
||||
} else if (feature_pbf.tag == 4) { // geometry
|
||||
geometry_pbf = feature_pbf.message();
|
||||
} else {
|
||||
feature.skip();
|
||||
feature_pbf.skip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& mbgl::operator<<(std::ostream& os, const GeometryTileFeature<pbf>& feature) {
|
||||
os << "Feature(" << feature.id << "): " << feature.type << std::endl;
|
||||
for (const auto& prop : feature.properties) {
|
||||
os << " - " << prop.first << ": " << prop.second << std::endl;
|
||||
Geometry VectorTileFeature::nextGeometry() {
|
||||
pbf current_geometry_pbf = geometry_pbf.message();
|
||||
PBFGeometry current_geometry(current_geometry_pbf);
|
||||
int32_t x, y;
|
||||
Geometry result;
|
||||
result.set<std::false_type>();
|
||||
|
||||
if (multigeometry || geometry_pbf.next(4)) {
|
||||
if (type == GeometryFeatureType::Point) {
|
||||
current_geometry.next(x, y);
|
||||
GeometryPoint point(x, y);
|
||||
result.set<GeometryPoint>(point);
|
||||
} else if (type == GeometryFeatureType::LineString) {
|
||||
GeometryLine line;
|
||||
PBFGeometry::command cmd;
|
||||
while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) {
|
||||
if (cmd == PBFGeometry::move_to) {
|
||||
multigeometry = true;
|
||||
result.set<GeometryLine>(line);
|
||||
break;
|
||||
} else {
|
||||
line.emplace_back(x, y);
|
||||
}
|
||||
}
|
||||
if (!multigeometry) {
|
||||
result.set<GeometryLine>(line);
|
||||
}
|
||||
} else if (type == GeometryFeatureType::Polygon) {
|
||||
GeometryPolygon polygon;
|
||||
PBFGeometry::command cmd;
|
||||
while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) {
|
||||
if (cmd == PBFGeometry::move_to) {
|
||||
multigeometry = true;
|
||||
result.set<GeometryPolygon>(polygon);
|
||||
break;
|
||||
} else {
|
||||
// polygon.emplace_back(x, y);
|
||||
}
|
||||
}
|
||||
if (!multigeometry) {
|
||||
result.set<GeometryPolygon>(polygon);
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error("unrecognized geometry type");
|
||||
}
|
||||
}
|
||||
return os;
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
VectorTile::VectorTile(pbf tile) {
|
||||
@@ -60,51 +104,34 @@ VectorTile::VectorTile(pbf tile) {
|
||||
}
|
||||
}
|
||||
|
||||
VectorTileLayer::VectorTileLayer(pbf layer) : layer_pbf(layer) {
|
||||
while (layer.next()) {
|
||||
if (layer.tag == 1) { // name
|
||||
name = layer.string();
|
||||
} else if (layer.tag == 3) { // keys
|
||||
keys.emplace_back(layer.string());
|
||||
VectorTileLayer::VectorTileLayer(pbf layer) : feature_pbf(layer) {
|
||||
while (feature_pbf.next()) {
|
||||
if (feature_pbf.tag == 1) { // name
|
||||
name = feature_pbf.string();
|
||||
} else if (feature_pbf.tag == 3) { // keys
|
||||
keys.emplace_back(feature_pbf.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 if (feature_pbf.tag == 4) { // values
|
||||
values.emplace_back(std::move(parseValue(feature_pbf.message())));
|
||||
} else if (feature_pbf.tag == 5) { // extent
|
||||
extent = feature_pbf.varint();
|
||||
} else {
|
||||
layer.skip();
|
||||
feature_pbf.skip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer_, const FilterExpression& filterExpression_)
|
||||
: GeometryFilteredTileLayer<pbf>(layer_, filterExpression_) {}
|
||||
|
||||
FilteredVectorTileLayer::iterator FilteredVectorTileLayer::begin() const {
|
||||
const VectorTileLayer *layer_ = static_cast<const VectorTileLayer *>(&layer);
|
||||
|
||||
return FilteredVectorTileLayer::iterator(*this, layer_->layer_pbf);
|
||||
: GeometryFilteredTileLayer(layer_, filterExpression_) {
|
||||
feature_pbf = layer_.feature_pbf;
|
||||
}
|
||||
|
||||
FilteredVectorTileLayer::iterator FilteredVectorTileLayer::end() const {
|
||||
const VectorTileLayer *layer_ = static_cast<const VectorTileLayer *>(&layer);
|
||||
template <>
|
||||
GeometryTileTagExtractor<pbf>::GeometryTileTagExtractor(const GeometryTileLayer& layer_)
|
||||
: layer(layer_) {}
|
||||
|
||||
return FilteredVectorTileLayer::iterator(*this, pbf(layer_->layer_pbf.end, 0));
|
||||
}
|
||||
|
||||
FilteredVectorTileLayer::iterator::iterator(const FilteredVectorTileLayer& parent_, const pbf& data_pbf_)
|
||||
: GeometryFilteredTileLayer<pbf>::iterator(parent_),
|
||||
feature_pbf(pbf()),
|
||||
data_pbf(data_pbf_) {}
|
||||
|
||||
VectorTileTagExtractor::VectorTileTagExtractor(const VectorTileLayer& layer_)
|
||||
: GeometryTileTagExtractor(layer_) {}
|
||||
|
||||
void VectorTileTagExtractor::setTags(const pbf& pbf) {
|
||||
tags_pbf = pbf;
|
||||
}
|
||||
|
||||
mapbox::util::optional<Value> VectorTileTagExtractor::getValue(const std::string& key) const {
|
||||
template <>
|
||||
mapbox::util::optional<Value> GeometryTileTagExtractor<pbf>::getValue(const std::string& key) const {
|
||||
if (key == "$type") {
|
||||
return Value(uint64_t(type));
|
||||
}
|
||||
@@ -117,7 +144,7 @@ mapbox::util::optional<Value> VectorTileTagExtractor::getValue(const std::string
|
||||
|
||||
// Now loop through all the key/value pair tags.
|
||||
// tags are packed varints. They should have an even length.
|
||||
pbf tags_pbf_ = tags_pbf;
|
||||
pbf tags_pbf_ = tags;
|
||||
uint32_t tag_key, tag_val;
|
||||
while (tags_pbf_) {
|
||||
tag_key = tags_pbf_.varint();
|
||||
@@ -143,43 +170,40 @@ mapbox::util::optional<Value> VectorTileTagExtractor::getValue(const std::string
|
||||
return value;
|
||||
}
|
||||
|
||||
template bool mbgl::evaluate(const FilterExpression&, const VectorTileTagExtractor&);
|
||||
template bool mbgl::evaluate(const FilterExpression&, const GeometryTileTagExtractor<pbf>&);
|
||||
|
||||
void FilteredVectorTileLayer::iterator::operator++() {
|
||||
valid = false;
|
||||
GeometryTileFeature FilteredVectorTileLayer::nextMatchingFeature() {
|
||||
GeometryTileFeature result;
|
||||
|
||||
const FilterExpression &expression = parent.filterExpression;
|
||||
if (feature_pbf.next(2)) {
|
||||
pbf current_feature_pbf = feature_pbf.message();
|
||||
|
||||
while (data_pbf.next(2)) { // feature
|
||||
feature_pbf = data_pbf.message();
|
||||
pbf feature_pbf_ = feature_pbf;
|
||||
GeometryTileTagExtractor<pbf> extractor(layer);
|
||||
|
||||
GeometryTileTagExtractor<pbf> extractor(parent.layer);
|
||||
|
||||
// Retrieve the basic information
|
||||
while (feature_pbf_.next()) {
|
||||
if (feature_pbf_.tag == 2) { // tags
|
||||
extractor.setTags(feature_pbf.message());
|
||||
} else if (feature_pbf_.tag == 3) { // geometry type
|
||||
extractor.setType(GeometryFeatureType(feature_pbf_.varint()));
|
||||
while (current_feature_pbf.next()) {
|
||||
if (current_feature_pbf.tag == 2) { // tags
|
||||
extractor.setTags(current_feature_pbf);
|
||||
} else if (current_feature_pbf.tag == 3) { // geometry type
|
||||
extractor.setType(GeometryFeatureType(current_feature_pbf.varint()));
|
||||
} else {
|
||||
feature_pbf_.skip();
|
||||
current_feature_pbf.skip();
|
||||
}
|
||||
}
|
||||
|
||||
if (evaluate(expression, extractor)) {
|
||||
valid = true;
|
||||
return; // data loop
|
||||
} else {
|
||||
valid = false;
|
||||
if (evaluate(filterExpression, extractor)) {
|
||||
result = VectorTileFeature(current_feature_pbf.message(), layer);
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
bool FilteredVectorTileLayer::iterator::operator!=(const iterator& other) const {
|
||||
return !(data_pbf.data == other.data_pbf.data && data_pbf.end == other.data_pbf.end && valid == other.valid);
|
||||
}
|
||||
GeometryTileFeature VectorTileLayer::nextFeature() {
|
||||
GeometryTileFeature result;
|
||||
|
||||
const pbf& FilteredVectorTileLayer::iterator:: operator*() const {
|
||||
return feature_pbf;
|
||||
if (feature_pbf.next(2)) {
|
||||
result = VectorTileFeature(feature_pbf.message(), *this);
|
||||
}
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user