From fa56adc530b7675f1e760ee79fd46e3a2b08466b Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Thu, 16 Mar 2017 15:06:26 -0700 Subject: [PATCH] Clean up utility functions that are also used in other projects --- geojson.cpp | 13 +++---- geometry.hpp | 4 --- main.cpp | 5 +-- mbtiles.cpp | 98 ++++++++++++++++++++++++++------------------------ mbtiles.hpp | 2 +- mvt.hpp | 12 +++++++ projection.cpp | 27 +++++++++++--- tile-join.cpp | 22 ++++++------ tile.cpp | 4 +-- 9 files changed, 110 insertions(+), 77 deletions(-) diff --git a/geojson.cpp b/geojson.cpp index 528df3d..223ff93 100644 --- a/geojson.cpp +++ b/geojson.cpp @@ -38,6 +38,7 @@ extern "C" { #include "options.hpp" #include "serial.hpp" #include "text.hpp" +#include "mvt.hpp" #define GEOM_POINT 0 /* array of positions */ #define GEOM_MULTIPOINT 1 /* array of arrays of positions */ @@ -333,7 +334,7 @@ int serialize_geometry(json_object *geometry, json_object *properties, json_obje metakey[m] = properties->keys[i]->string; if (properties->values[i] != NULL && properties->values[i]->type == JSON_STRING) { - tas.type = metatype[m] = VT_STRING; + tas.type = metatype[m] = mvt_string; metaval[m] = std::string(properties->values[i]->string); std::string err = check_utf8(metaval[m]); if (err != "") { @@ -343,17 +344,17 @@ int serialize_geometry(json_object *geometry, json_object *properties, json_obje } m++; } else if (properties->values[i] != NULL && properties->values[i]->type == JSON_NUMBER) { - tas.type = metatype[m] = VT_NUMBER; + tas.type = metatype[m] = mvt_double; metaval[m] = std::string(properties->values[i]->string); m++; } else if (properties->values[i] != NULL && (properties->values[i]->type == JSON_TRUE || properties->values[i]->type == JSON_FALSE)) { - tas.type = metatype[m] = VT_BOOLEAN; + tas.type = metatype[m] = mvt_bool; metaval[m] = std::string(properties->values[i]->type == JSON_TRUE ? "true" : "false"); m++; } else if (properties->values[i] != NULL && (properties->values[i]->type == JSON_NULL)) { ; } else { - tas.type = metatype[m] = VT_STRING; + tas.type = metatype[m] = mvt_string; const char *v = json_stringify(properties->values[i]); metaval[m] = std::string(v); free((void *) v); // stringify @@ -464,13 +465,13 @@ int serialize_geometry(json_object *geometry, json_object *properties, json_obje 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.keys.push_back(addpool(poolfile, treefile, metakey[i], mvt_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, metakey[i], mvt_string), metapos, fname); serialize_long_long(metafile, addpool(poolfile, treefile, metaval[i].c_str(), metatype[i]), metapos, fname); } } diff --git a/geometry.hpp b/geometry.hpp index 413b0f8..1b92574 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -7,10 +7,6 @@ #define VT_LINETO 2 #define VT_CLOSEPATH 7 -#define VT_STRING 1 -#define VT_NUMBER 2 -#define VT_BOOLEAN 7 - // The bitfield is to make sizeof(draw) be 16 instead of 24 // at the cost, apparently, of a 0.7% increase in running time // for packing and unpacking. diff --git a/main.cpp b/main.cpp index cf896c6..55dc110 100644 --- a/main.cpp +++ b/main.cpp @@ -50,6 +50,7 @@ extern "C" { #include "geometry.hpp" #include "serial.hpp" #include "options.hpp" +#include "mvt.hpp" static int low_detail = 12; static int full_detail = -1; @@ -1832,7 +1833,7 @@ int read_input(std::vector &sources, char *fname, int maxzoom, int minzo if (additional[A_CALCULATE_FEATURE_DENSITY]) { for (auto ai = merged_lm.begin(); ai != merged_lm.end(); ++ai) { type_and_string tas; - tas.type = VT_NUMBER; + tas.type = mvt_double; tas.string = "tippecanoe_feature_density"; ai->second.file_keys.insert(tas); } @@ -1842,7 +1843,7 @@ int read_input(std::vector &sources, char *fname, int maxzoom, int minzo ai->second.minzoom = minzoom; ai->second.maxzoom = maxzoom; } - mbtiles_write_metadata(outdb, fname, minzoom, maxzoom, minlat, minlon, maxlat, maxlon, midlat, midlon, forcetable, attribution, merged_lm); + mbtiles_write_metadata(outdb, fname, minzoom, maxzoom, minlat, minlon, maxlat, maxlon, midlat, midlon, forcetable, attribution, merged_lm, true); return ret; } diff --git a/mbtiles.cpp b/mbtiles.cpp index 141e2d9..d2d3480 100644 --- a/mbtiles.cpp +++ b/mbtiles.cpp @@ -11,10 +11,8 @@ #include #include #include -#include "main.hpp" -#include "pool.hpp" +#include "mvt.hpp" #include "mbtiles.hpp" -#include "geometry.hpp" sqlite3 *mbtiles_open(char *dbname, char **argv, int forcetable) { sqlite3 *outdb; @@ -133,7 +131,7 @@ bool type_and_string::operator<(const type_and_string &o) const { return false; } -void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, int minzoom, int maxzoom, double minlat, double minlon, double maxlat, double maxlon, double midlat, double midlon, int forcetable, const char *attribution, std::map const &layermap) { +void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, int minzoom, int maxzoom, double minlat, double minlon, double maxlat, double maxlon, double midlat, double midlon, int forcetable, const char *attribution, std::map const &layermap, bool vector) { char *sql, *err; sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('name', %Q);", fname); @@ -219,7 +217,7 @@ void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, int minzoom, int sqlite3_free(sql); } - sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('format', %Q);", "pbf"); + sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('format', %Q);", vector ? "pbf" : "png"); if (sqlite3_exec(outdb, sql, NULL, NULL, &err) != SQLITE_OK) { fprintf(stderr, "set format: %s\n", err); if (!forcetable) { @@ -228,58 +226,64 @@ void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, int minzoom, int } sqlite3_free(sql); - std::string buf("{"); - aprintf(&buf, "\"vector_layers\": [ "); + if (vector) { + std::string buf("{"); + aprintf(&buf, "\"vector_layers\": [ "); - std::vector lnames; - for (auto ai = layermap.begin(); ai != layermap.end(); ++ai) { - lnames.push_back(ai->first); - } - - for (size_t i = 0; i < lnames.size(); i++) { - if (i != 0) { - aprintf(&buf, ", "); + std::vector lnames; + for (auto ai = layermap.begin(); ai != layermap.end(); ++ai) { + lnames.push_back(ai->first); } - auto fk = layermap.find(lnames[i]); - aprintf(&buf, "{ \"id\": \""); - quote(&buf, lnames[i].c_str()); - aprintf(&buf, "\", \"description\": \"\", \"minzoom\": %d, \"maxzoom\": %d, \"fields\": {", fk->second.minzoom, fk->second.maxzoom); - - std::set::iterator j; - bool first = true; - for (j = fk->second.file_keys.begin(); j != fk->second.file_keys.end(); ++j) { - if (first) { - first = false; - } else { + for (size_t i = 0; i < lnames.size(); i++) { + if (i != 0) { aprintf(&buf, ", "); } - aprintf(&buf, "\""); - quote(&buf, j->string.c_str()); + auto fk = layermap.find(lnames[i]); + aprintf(&buf, "{ \"id\": \""); + quote(&buf, lnames[i].c_str()); + aprintf(&buf, "\", \"description\": \"\", \"minzoom\": %d, \"maxzoom\": %d, \"fields\": {", fk->second.minzoom, fk->second.maxzoom); - if (j->type == VT_NUMBER) { - aprintf(&buf, "\": \"Number\""); - } else if (j->type == VT_BOOLEAN) { - aprintf(&buf, "\": \"Boolean\""); - } else { - aprintf(&buf, "\": \"String\""); + std::set::iterator j; + bool first = true; + for (j = fk->second.file_keys.begin(); j != fk->second.file_keys.end(); ++j) { + if (first) { + first = false; + } else { + aprintf(&buf, ", "); + } + + aprintf(&buf, "\""); + quote(&buf, j->string.c_str()); + + if (j->type == mvt_double || + j->type == mvt_float || + j->type == mvt_double || + j->type == mvt_uint || + j->type == mvt_sint) { + aprintf(&buf, "\": \"Number\""); + } else if (j->type == mvt_bool) { + aprintf(&buf, "\": \"Boolean\""); + } else { + aprintf(&buf, "\": \"String\""); + } + } + + aprintf(&buf, "} }"); + } + + aprintf(&buf, " ] }"); + + sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('json', %Q);", buf.c_str()); + if (sqlite3_exec(outdb, sql, NULL, NULL, &err) != SQLITE_OK) { + fprintf(stderr, "set json: %s\n", err); + if (!forcetable) { + exit(EXIT_FAILURE); } } - - aprintf(&buf, "} }"); + sqlite3_free(sql); } - - aprintf(&buf, " ] }"); - - sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('json', %Q);", buf.c_str()); - if (sqlite3_exec(outdb, sql, NULL, NULL, &err) != SQLITE_OK) { - fprintf(stderr, "set json: %s\n", err); - if (!forcetable) { - exit(EXIT_FAILURE); - } - } - sqlite3_free(sql); } void mbtiles_close(sqlite3 *outdb, char **argv) { diff --git a/mbtiles.hpp b/mbtiles.hpp index 4b79497..3cb4ecf 100644 --- a/mbtiles.hpp +++ b/mbtiles.hpp @@ -20,7 +20,7 @@ sqlite3 *mbtiles_open(char *dbname, char **argv, int forcetable); void mbtiles_write_tile(sqlite3 *outdb, int z, int tx, int ty, const char *data, int size); -void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, int minzoom, int maxzoom, double minlat, double minlon, double maxlat, double maxlon, double midlat, double midlon, int forcetable, const char *attribution, std::map const &layermap); +void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, int minzoom, int maxzoom, double minlat, double minlon, double maxlat, double maxlon, double midlat, double midlon, int forcetable, const char *attribution, std::map const &layermap, bool vector); void mbtiles_close(sqlite3 *outdb, char **argv); diff --git a/mvt.hpp b/mvt.hpp index ff07467..6e9d792 100644 --- a/mvt.hpp +++ b/mvt.hpp @@ -13,6 +13,18 @@ struct mvt_geometry { int /* mvt_operation */ op; mvt_geometry(int op, long long x, long long y); + + bool operator<(mvt_geometry const &s) const { + if (y < s.y || (y == s.y && x < s.x)) { + return true; + } else { + return false; + } + } + + bool operator==(mvt_geometry const &s) const { + return y == s.y && x == s.x; + } }; enum mvt_geometry_type { diff --git a/projection.cpp b/projection.cpp index 351399e..f1d84f6 100644 --- a/projection.cpp +++ b/projection.cpp @@ -83,13 +83,32 @@ unsigned long long encode(unsigned int wx, unsigned int wy) { return out; } +static unsigned char decodex[256]; +static unsigned char decodey[256]; + void decode(unsigned long long index, unsigned *wx, unsigned *wy) { + static int initialized = 0; + if (!initialized) { + for (size_t ix = 0; ix < 256; ix++) { + size_t xx = 0, yy = 0; + + for (size_t i = 0; i < 32; i++) { + xx |= ((ix >> (64 - 2 * (i + 1) + 1)) & 1) << (32 - (i + 1)); + yy |= ((ix >> (64 - 2 * (i + 1) + 0)) & 1) << (32 - (i + 1)); + } + + decodex[ix] = xx; + decodey[ix] = yy; + } + + initialized = 1; + } + *wx = *wy = 0; - int i; - for (i = 0; i < 32; i++) { - *wx |= ((index >> (64 - 2 * (i + 1) + 1)) & 1) << (32 - (i + 1)); - *wy |= ((index >> (64 - 2 * (i + 1) + 0)) & 1) << (32 - (i + 1)); + for (size_t i = 0; i < 8; i++) { + *wx |= ((unsigned) decodex[(index >> (8 * i)) & 0xFF]) << (4 * i); + *wy |= ((unsigned) decodey[(index >> (8 * i)) & 0xFF]) << (4 * i); } } diff --git a/tile-join.cpp b/tile-join.cpp index 944238b..9aee481 100644 --- a/tile-join.cpp +++ b/tile-join.cpp @@ -101,25 +101,25 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::map 0) { if (joinval[0] == '"') { joinval = dequote(joinval); } else if ((joinval[0] >= '0' && joinval[0] <= '9') || joinval[0] == '-') { - attr_type = VT_NUMBER; + attr_type = mvt_double; } } @@ -158,7 +158,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::map= 0) { @@ -156,7 +156,7 @@ mvt_value retrieve_string(long long off, char *stringpool, int *otype) { tv.numeric_value.double_value = d; } } - } else if (type == VT_BOOLEAN) { + } else if (type == mvt_bool) { tv.type = mvt_bool; tv.numeric_value.bool_value = (s[0] == 't'); } else {