From bf571571a9e97f10051e1ae5b2b9b3fcc901f457 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Mon, 8 Aug 2016 15:36:49 -0700 Subject: [PATCH] Factor out (initial) feature serialization --- geojson.cpp | 88 ++++++++++++++++++++--------------------------------- main.cpp | 2 +- serial.cpp | 48 +++++++++++++++++++++++++++++ serial.hpp | 27 ++++++++++++++++ 4 files changed, 109 insertions(+), 56 deletions(-) diff --git a/geojson.cpp b/geojson.cpp index dfa9189..b99d8cf 100644 --- a/geojson.cpp +++ b/geojson.cpp @@ -31,12 +31,12 @@ extern "C" { #include "projection.hpp" #include "version.hpp" #include "memfile.hpp" -#include "serial.hpp" #include "main.hpp" #include "mbtiles.hpp" #include "geojson.hpp" #include "geometry.hpp" #include "options.hpp" +#include "serial.hpp" #define GEOM_POINT 0 /* array of positions */ #define GEOM_MULTIPOINT 1 /* array of arrays of positions */ @@ -63,20 +63,6 @@ static int mb_geometry[GEOM_TYPES] = { VT_POINT, VT_POINT, VT_LINE, VT_LINE, VT_POLYGON, VT_POLYGON, }; -static void write_geometry(drawvec const &dv, long long *fpos, FILE *out, const char *fname, long long wx, long long wy) { - for (size_t i = 0; i < dv.size(); i++) { - if (dv[i].op == VT_CLOSEPATH) { - serialize_byte(out, dv[i].op, fpos, fname); - } else { - serialize_byte(out, dv[i].op, fpos, fname); - serialize_long_long(out, dv[i].x - wx, fpos, fname); - serialize_long_long(out, dv[i].y - wy, fpos, fname); - wx = dv[i].x; - wy = dv[i].y; - } - } -} - long long parse_geometry(int t, json_object *j, long long *bbox, drawvec &out, int op, const char *fname, int line, int *initialized, unsigned *initial_x, unsigned *initial_y) { long long g = 0; @@ -249,7 +235,6 @@ int serialize_geometry(json_object *geometry, json_object *properties, json_obje nprop = properties->length; } - long long metastart = *metapos; char *metakey[nprop]; std::vector metaval; metaval.resize(nprop); @@ -331,44 +316,6 @@ int serialize_geometry(json_object *geometry, json_object *properties, json_obje } } - long long geomstart = *geompos; - - serialize_byte(geomfile, mb_geometry[t], geompos, fname); - serialize_long_long(geomfile, *layer_seq, geompos, fname); - - serialize_long_long(geomfile, (layer << 3) | (has_id << 2) | ((tippecanoe_minzoom != -1) << 1) | (tippecanoe_maxzoom != -1), geompos, fname); - if (tippecanoe_minzoom != -1) { - serialize_int(geomfile, tippecanoe_minzoom, geompos, fname); - } - if (tippecanoe_maxzoom != -1) { - serialize_int(geomfile, tippecanoe_maxzoom, geompos, fname); - } - if (has_id) { - serialize_ulong_long(geomfile, id_value, geompos, fname); - } - - serialize_int(geomfile, segment, geompos, fname); - - write_geometry(dv, geompos, geomfile, fname, *initial_x >> geometry_scale, *initial_y >> geometry_scale); - serialize_byte(geomfile, VT_END, geompos, fname); - - serialize_int(geomfile, m, geompos, fname); - if (inline_meta) { - serialize_long_long(geomfile, -1, geompos, fname); - - for (size_t i = 0; i < m; i++) { - serialize_long_long(geomfile, addpool(poolfile, treefile, metakey[i], VT_STRING), geompos, fname); - serialize_long_long(geomfile, addpool(poolfile, treefile, metaval[i].c_str(), metatype[i]), geompos, fname); - } - } else { - serialize_long_long(geomfile, metastart, geompos, fname); - - for (size_t i = 0; i < m; i++) { - serialize_long_long(metafile, addpool(poolfile, treefile, metakey[i], VT_STRING), metapos, fname); - serialize_long_long(metafile, addpool(poolfile, treefile, metaval[i].c_str(), metatype[i]), metapos, fname); - } - } - /* * Note that feature_minzoom for lines is the dimension * of the geometry in world coordinates, but @@ -397,7 +344,38 @@ int serialize_geometry(json_object *geometry, json_object *properties, json_obje feature_minzoom = basezoom - floor(log(r) / -log(droprate)); } - serialize_byte(geomfile, feature_minzoom, geompos, fname); + long long geomstart = *geompos; + + serial_feature sf; + sf.layer = layer; + sf.segment = segment; + sf.seq = *layer_seq; + sf.t = mb_geometry[t]; + sf.has_id = has_id; + sf.id = id_value; + sf.has_tippecanoe_minzoom = (tippecanoe_minzoom != -1); + sf.tippecanoe_minzoom = tippecanoe_minzoom; + sf.has_tippecanoe_maxzoom = (tippecanoe_maxzoom != -1); + sf.tippecanoe_maxzoom = tippecanoe_maxzoom; + sf.geometry = dv; + sf.m = m; + sf.feature_minzoom = feature_minzoom; + + if (inline_meta) { + sf.metapos = -1; + for (size_t i = 0; i < m; i++) { + sf.keys.push_back(addpool(poolfile, treefile, metakey[i], VT_STRING)); + sf.values.push_back(addpool(poolfile, treefile, metaval[i].c_str(), metatype[i])); + } + } else { + sf.metapos = *metapos; + for (size_t i = 0; i < m; i++) { + serialize_long_long(metafile, addpool(poolfile, treefile, metakey[i], VT_STRING), metapos, fname); + serialize_long_long(metafile, addpool(poolfile, treefile, metaval[i].c_str(), metatype[i]), metapos, fname); + } + } + + serialize_feature(geomfile, &sf, geompos, fname, *initial_x >> geometry_scale, *initial_y >> geometry_scale); struct index index; index.start = geomstart; diff --git a/main.cpp b/main.cpp index 6510f41..402215e 100644 --- a/main.cpp +++ b/main.cpp @@ -42,11 +42,11 @@ extern "C" { #include "projection.hpp" #include "version.hpp" #include "memfile.hpp" -#include "serial.hpp" #include "mbtiles.hpp" #include "main.hpp" #include "geojson.hpp" #include "geometry.hpp" +#include "serial.hpp" #include "options.hpp" static int low_detail = 12; diff --git a/serial.cpp b/serial.cpp index dc9d6c5..ae32eae 100644 --- a/serial.cpp +++ b/serial.cpp @@ -2,7 +2,11 @@ #include #include #include +#include +#include #include "protozero/varint.hpp" +#include "geometry.hpp" +#include "tile.hpp" #include "serial.hpp" size_t fwrite_check(const void *ptr, size_t size, size_t nitems, FILE *stream, const char *fname) { @@ -151,3 +155,47 @@ int deserialize_byte_io(FILE *f, signed char *n, long long *geompos) { (*geompos)++; return 1; } + +static void write_geometry(drawvec const &dv, long long *fpos, FILE *out, const char *fname, long long wx, long long wy) { + for (size_t i = 0; i < dv.size(); i++) { + if (dv[i].op == VT_CLOSEPATH) { + serialize_byte(out, dv[i].op, fpos, fname); + } else { + serialize_byte(out, dv[i].op, fpos, fname); + serialize_long_long(out, dv[i].x - wx, fpos, fname); + serialize_long_long(out, dv[i].y - wy, fpos, fname); + wx = dv[i].x; + wy = dv[i].y; + } + } +} + +void serialize_feature(FILE *geomfile, serial_feature *sf, long long *geompos, const char *fname, long long wx, long long wy) { + serialize_byte(geomfile, sf->t, geompos, fname); + serialize_long_long(geomfile, sf->seq, geompos, fname); + + serialize_long_long(geomfile, (sf->layer << 3) | (sf->has_id ? 4 : 0) | (sf->has_tippecanoe_minzoom ? 2 : 0) | (sf->has_tippecanoe_maxzoom ? 1 : 0), geompos, fname); + if (sf->has_tippecanoe_minzoom) { + serialize_int(geomfile, sf->tippecanoe_minzoom, geompos, fname); + } + if (sf->has_tippecanoe_maxzoom) { + serialize_int(geomfile, sf->tippecanoe_maxzoom, geompos, fname); + } + if (sf->has_id) { + serialize_ulong_long(geomfile, sf->id, geompos, fname); + } + + serialize_int(geomfile, sf->segment, geompos, fname); + + write_geometry(sf->geometry, geompos, geomfile, fname, wx, wy); + serialize_byte(geomfile, VT_END, geompos, fname); + + serialize_int(geomfile, sf->m, geompos, fname); + serialize_long_long(geomfile, sf->metapos, geompos, fname); + for (size_t i = 0; i < sf->keys.size(); i++) { + serialize_long_long(geomfile, sf->keys[i], geompos, fname); + serialize_long_long(geomfile, sf->values[i], geompos, fname); + } + + serialize_byte(geomfile, sf->feature_minzoom, geompos, fname); +} diff --git a/serial.hpp b/serial.hpp index f1256a8..474af6f 100644 --- a/serial.hpp +++ b/serial.hpp @@ -18,3 +18,30 @@ int deserialize_long_long_io(FILE *f, long long *n, long long *geompos); int deserialize_ulong_long_io(FILE *f, unsigned long long *n, long long *geompos); int deserialize_uint_io(FILE *f, unsigned *n, long long *geompos); int deserialize_byte_io(FILE *f, signed char *n, long long *geompos); + +struct serial_feature { + long long layer; + int segment; + long long seq; + + signed char t; + signed char feature_minzoom; + + bool has_id; + unsigned long long id; + + bool has_tippecanoe_minzoom; + int tippecanoe_minzoom; + + bool has_tippecanoe_maxzoom; + int tippecanoe_maxzoom; + + drawvec geometry; + + int m; + std::vector keys; + std::vector values; + long long metapos; +}; + +void serialize_feature(FILE *geomfile, serial_feature *sf, long long *geompos, const char *fname, long long wx, long long wy);