move geometry reader to header file

This commit is contained in:
Konstantin Käfer
2014-01-17 16:53:37 +01:00
parent 2e3b8ed071
commit c59f62274d
3 changed files with 88 additions and 51 deletions

View File

@@ -0,0 +1,75 @@
#ifndef LLMR_GEOMETRY_GEOMETRY
#define LLMR_GEOMETRY_GEOMETRY
#include <llmr/util/pbf.hpp>
#include <cstdlib>
namespace llmr {
class geometry {
public:
inline geometry(const uint8_t *data, uint32_t bytes);
enum command {
end = 0,
move_to = 1,
line_to = 2,
close = 7
};
inline command next(int32_t &rx, int32_t &ry);
private:
pbf pbf;
uint32_t cmd;
uint32_t length;
int32_t x, y;
int32_t ox, oy;
};
geometry::geometry(const uint8_t *data, uint32_t bytes)
: pbf(data, bytes),
cmd(1),
length(0),
x(0), y(0),
ox(0), oy(0) {}
geometry::command geometry::next(int32_t &rx, int32_t &ry) {
if (pbf.data < pbf.end) {
if (!length) {
uint32_t cmd_length = (uint32_t)pbf.varint();
cmd = cmd_length & 0x7;
length = cmd_length >> 3;
}
length--;
if (cmd == move_to || cmd == line_to) {
rx = (x += pbf.svarint());
ry = (y += pbf.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,4 +1,5 @@
#pragma once
#ifndef LLMR_UTIL_PBF
#define LLMR_UTIL_PBF
/*
* Some parts are from upb - a minimalist implementation of protocol buffers.
@@ -23,8 +24,6 @@ namespace llmr {
struct pbf {
inline pbf(const unsigned char *data, uint32_t length);
inline pbf(const char *data, uint32_t length);
// inline pbf(const std::string& buffer);
inline bool next();
template <typename T = uint32_t> inline T varint();
@@ -61,11 +60,6 @@ pbf::pbf(const unsigned char *data, uint32_t length)
end(data + length)
{}
pbf::pbf(const char *data, uint32_t length)
: data((const unsigned char *)data),
end((const unsigned char *)data + length)
{}
// pbf::pbf(const std::string& buffer)
// : data((const unsigned char *)buffer.data()),
// end((const unsigned char *)buffer.data() + buffer.size())
@@ -206,3 +200,5 @@ void pbf::skipBytes(uint32_t bytes)
} // end namespace llmr
#endif

View File

@@ -5,9 +5,10 @@
// #include <iostream>
#include <thread>
#include "pbf.hpp"
#include <llmr/util/pbf.hpp>
#include <llmr/util/vec2.hpp>
#include <llmr/util/string.hpp>
#include <llmr/geometry/geometry.hpp>
#include <cmath>
using namespace llmr;
@@ -175,50 +176,15 @@ void tile::parseFeature(const uint8_t *data, uint32_t bytes) {
}
void tile::loadGeometry(const uint8_t *data, uint32_t bytes) {
pbf geometry(data, bytes);
geometry geometry(data, bytes);
uint32_t cmd = 1;
uint32_t length = 0;
int32_t x = 0, y = 0;
// var lines = [];
// var line = null;
int32_t ox = 0, oy = 0;
while (geometry.data < geometry.end) {
if (!length) {
uint32_t cmd_length = (uint32_t)geometry.varint();
cmd = cmd_length & 0x7;
length = cmd_length >> 3;
geometry::command cmd;
int32_t x, y;
while ((cmd = geometry.next(x, y)) != geometry::end) {
if (cmd == geometry::move_to) {
lineVertex.addDegenerate();
}
length--;
if (cmd == 1 || cmd == 2) {
x += geometry.svarint();
y += geometry.svarint();
if (cmd == 1) {
// moveTo
// fprintf(stderr, "[m %d/%d] ", x, y);
// degenerate vertex
lineVertex.addDegenerate();
ox = x;
oy = y;
} else {
// lineTo
// fprintf(stderr, "[l %d/%d] ", x, y);
}
lineVertex.addCoordinate(x, y);
} else if (cmd == 7) {
// closePolygon
// fprintf(stderr, "[c]\n");
lineVertex.addCoordinate(ox, oy);
} else {
// throw new Error('unknown command ' + cmd);
// throw std::runtime_error("unknown command");
fprintf(stderr, "unknown command");
exit(1);
}
lineVertex.addCoordinate(x, y);
}
}