Inline PBFGeometry

This commit is contained in:
John Firebaugh
2015-03-10 10:31:24 -07:00
parent 4d3dcea82c
commit 5fa628bc00
2 changed files with 36 additions and 100 deletions

View File

@@ -1,77 +0,0 @@
#ifndef MBGL_GEOMETRY_PBF_GEOMETRY
#define MBGL_GEOMETRY_PBF_GEOMETRY
#include <mbgl/util/pbf.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <cstdlib>
namespace mbgl {
class PBFGeometry : private util::noncopyable {
public:
inline explicit PBFGeometry(pbf data);
enum command : uint8_t {
end = 0,
move_to = 1,
line_to = 2,
close = 7
};
inline command next(int32_t &rx, int32_t &ry);
private:
pbf data;
uint8_t cmd;
uint32_t length;
int32_t x, y;
int32_t ox, oy;
};
PBFGeometry::PBFGeometry(pbf data_)
: data(data_),
cmd(1),
length(0),
x(0), y(0),
ox(0), oy(0) {}
PBFGeometry::command PBFGeometry::next(int32_t &rx, int32_t &ry) {
if (data.data < data.end) {
if (length == 0) {
uint32_t cmd_length = static_cast<uint32_t>(data.varint());
cmd = cmd_length & 0x7;
length = cmd_length >> 3;
}
--length;
if (cmd == move_to || cmd == line_to) {
rx = (x += data.svarint());
ry = (y += data.svarint());
if (cmd == move_to) {
ox = x;
oy = y;
return move_to;
} else {
return line_to;
}
} else if (cmd == close) {
rx = ox;
ry = oy;
return close;
} else {
fprintf(stderr, "unknown command: %d\n", cmd);
// TODO: gracefully handle geometry parse failures
return end;
}
} else {
return end;
}
}
}
#endif

View File

@@ -1,10 +1,4 @@
#include <mbgl/map/vector_tile.hpp>
#include <mbgl/geometry/pbf_geometry.hpp>
#include <mbgl/style/filter_expression_private.hpp>
#include <mbgl/util/pbf.hpp>
#include <type_traits>
#include <ostream>
using namespace mbgl;
@@ -52,29 +46,48 @@ mapbox::util::optional<Value> VectorTileFeature::getValue(const std::string& key
}
GeometryCollection VectorTileFeature::getGeometries() const {
GeometryCollection result;
pbf data(geometry_pbf);
uint8_t cmd = 1;
uint32_t length = 0;
int32_t x = 0;
int32_t y = 0;
PBFGeometry geometry(geometry_pbf);
PBFGeometry::command cmd;
int32_t x, y;
GeometryCollection lines;
std::vector<Coordinate> line;
lines.emplace_back();
std::vector<Coordinate>* line = &lines.back();
while ((cmd = geometry.next(x, y)) != PBFGeometry::end) {
if (cmd == PBFGeometry::move_to) {
if (!line.empty()) {
result.push_back(line);
line.clear();
}
while (data.data < data.end) {
if (length == 0) {
uint32_t cmd_length = data.varint();
cmd = cmd_length & 0x7;
length = cmd_length >> 3;
}
--length;
if (cmd == 1 || cmd == 2) {
x += data.svarint();
y += data.svarint();
if (cmd == 1 && !line->empty()) { // moveTo
lines.emplace_back();
line = &lines.back();
}
line->emplace_back(x, y);
} else if (cmd == 7) { // closePolygon
if (!line->empty()) {
line->push_back((*line)[0]);
}
} else {
throw std::runtime_error("unknown command");
}
line.emplace_back(x, y);
}
if (!line.empty()) {
result.push_back(line);
}
return std::move(result);
return lines;
}
VectorTile::VectorTile(pbf tile_pbf) {