move geometry reader to header file
This commit is contained in:
75
include/llmr/geometry/geometry.hpp
Normal file
75
include/llmr/geometry/geometry.hpp
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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
|
||||
geometry::command cmd;
|
||||
int32_t x, y;
|
||||
while ((cmd = geometry.next(x, y)) != geometry::end) {
|
||||
if (cmd == geometry::move_to) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user