mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-05 09:55:41 +02:00
Most of the way to making decode output GeoJSON
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "vector_tile.pb.h"
|
#include "vector_tile.pb.h"
|
||||||
|
#include "tile.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "projection.h"
|
#include "projection.h"
|
||||||
@@ -51,8 +52,35 @@ int dezig(unsigned n) {
|
|||||||
return (n >> 1) ^ (-(n & 1));
|
return (n >> 1) ^ (-(n & 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printq(const char *s) {
|
||||||
|
putchar('"');
|
||||||
|
for (; *s; s++) {
|
||||||
|
if (*s == '\\' || *s == '"') {
|
||||||
|
printf("\\%c", *s);
|
||||||
|
} else if (*s >= 0 && *s < ' ') {
|
||||||
|
printf("\\u%04x", *s);
|
||||||
|
} else {
|
||||||
|
putchar(*s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putchar('"');
|
||||||
|
}
|
||||||
|
|
||||||
|
struct draw {
|
||||||
|
int op;
|
||||||
|
double lon;
|
||||||
|
double lat;
|
||||||
|
|
||||||
|
draw(int op, double lon, double lat) {
|
||||||
|
this->op = op;
|
||||||
|
this->lon = lon;
|
||||||
|
this->lat = lat;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void handle(std::string message, int z, unsigned x, unsigned y) {
|
void handle(std::string message, int z, unsigned x, unsigned y) {
|
||||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||||
|
int within = 0;
|
||||||
|
|
||||||
// https://github.com/mapbox/mapnik-vector-tile/blob/master/examples/c%2B%2B/tileinfo.cpp
|
// https://github.com/mapbox/mapnik-vector-tile/blob/master/examples/c%2B%2B/tileinfo.cpp
|
||||||
mapnik::vector::tile tile;
|
mapnik::vector::tile tile;
|
||||||
@@ -69,6 +97,8 @@ void handle(std::string message, int z, unsigned x, unsigned y) {
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("{ \"type\": \"FeatureCollection\", \"features\": [\n");
|
||||||
|
|
||||||
for (int l = 0; l < tile.layers_size(); l++) {
|
for (int l = 0; l < tile.layers_size(); l++) {
|
||||||
mapnik::vector::tile_layer layer = tile.layers(l);
|
mapnik::vector::tile_layer layer = tile.layers(l);
|
||||||
int extent = layer.extent();
|
int extent = layer.extent();
|
||||||
@@ -77,16 +107,57 @@ void handle(std::string message, int z, unsigned x, unsigned y) {
|
|||||||
mapnik::vector::tile_feature feat = layer.features(f);
|
mapnik::vector::tile_feature feat = layer.features(f);
|
||||||
int px = 0, py = 0;
|
int px = 0, py = 0;
|
||||||
|
|
||||||
|
if (within) {
|
||||||
|
printf(",\n");
|
||||||
|
}
|
||||||
|
within = 1;
|
||||||
|
|
||||||
|
printf("{ \"type\": \"Feature\"");
|
||||||
|
printf(", \"properties\": { ");
|
||||||
|
|
||||||
|
for (unsigned t = 0; t + 1 < feat.tags_size(); t += 2) {
|
||||||
|
if (t != 0) {
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *key = layer.keys(feat.tags(t)).c_str();
|
||||||
|
mapnik::vector::tile_value const &val = layer.values(feat.tags(t + 1));
|
||||||
|
|
||||||
|
if (val.has_string_value()) {
|
||||||
|
printq(key);
|
||||||
|
printf(": ");
|
||||||
|
printq(val.string_value().c_str());
|
||||||
|
} else if (val.has_int_value()) {
|
||||||
|
printq(key);
|
||||||
|
printf(": %lld", (long long) val.int_value());
|
||||||
|
} else if (val.has_double_value()) {
|
||||||
|
printq(key);
|
||||||
|
printf(": %g", val.double_value());
|
||||||
|
} else if (val.has_float_value()) {
|
||||||
|
printq(key);
|
||||||
|
printf(": %g", val.float_value());
|
||||||
|
} else if (val.has_sint_value()) {
|
||||||
|
printq(key);
|
||||||
|
printf(": %lld", (long long) val.sint_value());
|
||||||
|
} else if (val.has_uint_value()) {
|
||||||
|
printq(key);
|
||||||
|
printf(": %lld", (long long) val.uint_value());
|
||||||
|
} else if (val.has_bool_value()) {
|
||||||
|
printq(key);
|
||||||
|
printf(": %s", val.bool_value() ? "true" : "false");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" }, \"geometry\": { ");
|
||||||
|
|
||||||
|
std::vector<draw> ops;
|
||||||
|
|
||||||
for (int g = 0; g < feat.geometry_size(); g++) {
|
for (int g = 0; g < feat.geometry_size(); g++) {
|
||||||
uint32_t geom = feat.geometry(g);
|
uint32_t geom = feat.geometry(g);
|
||||||
uint32_t op = geom & 7;
|
uint32_t op = geom & 7;
|
||||||
uint32_t count = geom >> 3;
|
uint32_t count = geom >> 3;
|
||||||
|
|
||||||
if (op == 1 || op == 2) {
|
if (op == VT_MOVETO || op == VT_LINETO) {
|
||||||
if (op == 1) {
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned k = 0; k < count; k++) {
|
for (unsigned k = 0; k < count; k++) {
|
||||||
px += dezig(feat.geometry(g + 1));
|
px += dezig(feat.geometry(g + 1));
|
||||||
py += dezig(feat.geometry(g + 2));
|
py += dezig(feat.geometry(g + 2));
|
||||||
@@ -98,12 +169,72 @@ void handle(std::string message, int z, unsigned x, unsigned y) {
|
|||||||
|
|
||||||
double lat, lon;
|
double lat, lon;
|
||||||
tile2latlon(wx, wy, 32, &lat, &lon);
|
tile2latlon(wx, wy, 32, &lat, &lon);
|
||||||
printf("%f,%f ", lat, lon);
|
|
||||||
|
ops.push_back(draw(op, lon, lat));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ops.push_back(draw(op, 0, 27));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (feat.type() == VT_POINT) {
|
||||||
|
if (ops.size() == 1) {
|
||||||
|
printf("\"type\": \"Point\", \"coordinates\": [ %f, %f ]", ops[0].lon, ops[0].lat);
|
||||||
|
} else {
|
||||||
|
printf("\"type\": \"MultiPoint\", \"coordinates\": [ ");
|
||||||
|
for (unsigned i = 0; i < ops.size(); i++) {
|
||||||
|
if (i != 0) {
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
printf("[ %f, %f ]", ops[i].lon, ops[i].lat);
|
||||||
|
}
|
||||||
|
printf(" ]");
|
||||||
|
}
|
||||||
|
} else if (feat.type() == VT_LINE) {
|
||||||
|
int movetos = 0;
|
||||||
|
for (unsigned i = 0; i < ops.size(); i++) {
|
||||||
|
if (ops[i].op == VT_MOVETO) {
|
||||||
|
movetos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (movetos < 2) {
|
||||||
|
printf("\"type\": \"LineString\", \"coordinates\": [ ");
|
||||||
|
for (unsigned i = 0; i < ops.size(); i++) {
|
||||||
|
if (i != 0) {
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
printf("[ %f, %f ]", ops[i].lon, ops[i].lat);
|
||||||
|
}
|
||||||
|
printf(" ]");
|
||||||
|
} else {
|
||||||
|
printf("\"type\": \"MultiLineString\", \"coordinates\": [ [ ");
|
||||||
|
int state = 0;
|
||||||
|
for (unsigned i = 0; i < ops.size(); i++) {
|
||||||
|
if (ops[i].op == VT_MOVETO) {
|
||||||
|
if (state == 0) {
|
||||||
|
printf("[ %f, %f ]", ops[i].lon, ops[i].lat);
|
||||||
|
state = 1;
|
||||||
|
} else {
|
||||||
|
printf(" ], [ ");
|
||||||
|
printf("[ %f, %f ]", ops[i].lon, ops[i].lat);
|
||||||
|
state = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf(", [ %f, %f ]", ops[i].lon, ops[i].lat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf(" ] ]");
|
||||||
|
}
|
||||||
|
} else if (feat.type() == VT_POLYGON) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" } }\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("] }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void decode(char *fname, int z, unsigned x, unsigned y) {
|
void decode(char *fname, int z, unsigned x, unsigned y) {
|
||||||
|
|||||||
Reference in New Issue
Block a user