From cf81880949cfca5529b34b5c9591569ceb6545ed Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Thu, 18 Oct 2018 16:15:35 -0700 Subject: [PATCH] Use the right message numbers for splines; additional spline support --- decode.cpp | 7 ++++++- geometry.hpp | 1 + mbtiles.hpp | 1 + mvt.cpp | 12 ++++++++++-- mvt.hpp | 3 ++- plugin.cpp | 4 ++++ tests/muni/decode/multi.mbtiles.stats.json | 8 ++++---- tile-join.cpp | 4 ++++ tile.cpp | 2 ++ write_json.cpp | 16 +++++++++++++--- 10 files changed, 47 insertions(+), 11 deletions(-) diff --git a/decode.cpp b/decode.cpp index 3355d5f75..0c0957d68 100644 --- a/decode.cpp +++ b/decode.cpp @@ -51,7 +51,7 @@ void do_stats(mvt_tile &tile, size_t size, bool compressed, int z, unsigned x, u for (size_t i = 0; i < tile.layers.size(); i++) { state.json_write_string(tile.layers[i].name); - size_t points = 0, lines = 0, polygons = 0; + size_t points = 0, lines = 0, polygons = 0, splines = 0; for (size_t j = 0; j < tile.layers[i].features.size(); j++) { if (tile.layers[i].features[j].type == mvt_point) { points++; @@ -59,6 +59,8 @@ void do_stats(mvt_tile &tile, size_t size, bool compressed, int z, unsigned x, u lines++; } else if (tile.layers[i].features[j].type == mvt_polygon) { polygons++; + } else if (tile.layers[i].features[j].type == mvt_spline) { + splines++; } } @@ -73,6 +75,9 @@ void do_stats(mvt_tile &tile, size_t size, bool compressed, int z, unsigned x, u state.json_write_string("polygons"); state.json_write_unsigned(polygons); + state.json_write_string("splines"); + state.json_write_unsigned(splines); + state.json_write_string("extent"); state.json_write_signed(tile.layers[i].extent); diff --git a/geometry.hpp b/geometry.hpp index 191e3f1db..a75685619 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -9,6 +9,7 @@ #define VT_POINT 1 #define VT_LINE 2 #define VT_POLYGON 3 +#define VT_SPLINE 4 #define VT_END 0 #define VT_MOVETO 1 diff --git a/mbtiles.hpp b/mbtiles.hpp index e91ee8885..071ca1246 100644 --- a/mbtiles.hpp +++ b/mbtiles.hpp @@ -34,6 +34,7 @@ struct layermap_entry { size_t points = 0; size_t lines = 0; size_t polygons = 0; + size_t splines = 0; size_t retain = 0; // keep for tilestats, even if no features directly here layermap_entry(size_t _id) { diff --git a/mvt.cpp b/mvt.cpp index 909f885f7..c8216d1fb 100644 --- a/mvt.cpp +++ b/mvt.cpp @@ -375,7 +375,7 @@ bool mvt_tile::decode(std::string &message, bool &was_compressed) { break; } - case 11: /* knots */ + case 8: /* knots */ { auto pi = feature_reader.get_packed_uint64(); for (auto it = pi.first; it != pi.second; ++it) { @@ -384,6 +384,10 @@ bool mvt_tile::decode(std::string &message, bool &was_compressed) { break; } + case 9: /* spline degree */ + feature.spline_degree = feature_reader.get_uint32(); + break; + default: feature_reader.skip(); break; @@ -649,7 +653,11 @@ std::string mvt_tile::encode(int z) { feature_writer.add_packed_sint32(7, std::begin(elevations), std::end(elevations)); } - feature_writer.add_packed_uint64(11, std::begin(layers[i].features[f].knots), std::end(layers[i].features[f].knots)); + feature_writer.add_packed_uint64(8, std::begin(layers[i].features[f].knots), std::end(layers[i].features[f].knots)); + + if (layers[i].features[f].spline_degree != 2) { + feature_writer.add_uint32(9, layers[i].features[f].spline_degree); + } layer_writer.add_message(2, feature_string); } diff --git a/mvt.hpp b/mvt.hpp index 1cd9293ff..ca0d9574e 100644 --- a/mvt.hpp +++ b/mvt.hpp @@ -52,7 +52,7 @@ enum mvt_geometry_type { mvt_point = 1, mvt_linestring = 2, mvt_polygon = 3, - mvt_curve = 4, + mvt_spline = 4, }; struct mvt_feature { @@ -60,6 +60,7 @@ struct mvt_feature { std::vector properties{}; std::vector geometry{}; std::vector knots{}; + size_t spline_degree = 2; int /* mvt_geometry_type */ type = 0; unsigned long long id = 0; bool has_id = false; diff --git a/plugin.cpp b/plugin.cpp index 0b87c06e3..92f9666b1 100644 --- a/plugin.cpp +++ b/plugin.cpp @@ -254,6 +254,8 @@ std::vector parse_layers(int fd, int z, unsigned x, unsigned y, std:: fk->second.lines++; } else if (feature.type == mvt_polygon) { fk->second.polygons++; + } else if (feature.type == mvt_spline) { + fk->second.splines++; } for (size_t i = 0; i < properties->length; i++) { @@ -508,6 +510,8 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std:: fk->second.lines++; } else if (sf.t == mvt_polygon) { fk->second.polygons++; + } else if (sf.t == mvt_spline) { + fk->second.splines++; } } diff --git a/tests/muni/decode/multi.mbtiles.stats.json b/tests/muni/decode/multi.mbtiles.stats.json index 7c793bdc6..c814feff7 100644 --- a/tests/muni/decode/multi.mbtiles.stats.json +++ b/tests/muni/decode/multi.mbtiles.stats.json @@ -1,9 +1,9 @@ [ -{ "zoom": 11, "x": 326, "y": 791, "bytes": 366, "compressed": true, "layers": { "muni": { "points": 14, "lines": 0, "polygons": 0, "extent": 4096 } } } +{ "zoom": 11, "x": 326, "y": 791, "bytes": 366, "compressed": true, "layers": { "muni": { "points": 14, "lines": 0, "polygons": 0, "splines": 0, "extent": 4096 } } } , -{ "zoom": 11, "x": 327, "y": 792, "bytes": 6207, "compressed": true, "layers": { "muni": { "points": 528, "lines": 0, "polygons": 0, "extent": 4096 } } } +{ "zoom": 11, "x": 327, "y": 792, "bytes": 6207, "compressed": true, "layers": { "muni": { "points": 528, "lines": 0, "polygons": 0, "splines": 0, "extent": 4096 } } } , -{ "zoom": 11, "x": 327, "y": 791, "bytes": 43268, "compressed": true, "layers": { "muni": { "points": 4285, "lines": 0, "polygons": 0, "extent": 4096 }, "subway": { "points": 19, "lines": 0, "polygons": 0, "extent": 4096 } } } +{ "zoom": 11, "x": 327, "y": 791, "bytes": 43268, "compressed": true, "layers": { "muni": { "points": 4285, "lines": 0, "polygons": 0, "splines": 0, "extent": 4096 }, "subway": { "points": 19, "lines": 0, "polygons": 0, "splines": 0, "extent": 4096 } } } , -{ "zoom": 11, "x": 954, "y": 791, "bytes": 73, "compressed": true, "layers": { "muni": { "points": 12, "lines": 0, "polygons": 0, "extent": 4096 } } } +{ "zoom": 11, "x": 954, "y": 791, "bytes": 73, "compressed": true, "layers": { "muni": { "points": 12, "lines": 0, "polygons": 0, "splines": 0, "extent": 4096 } } } ] diff --git a/tile-join.cpp b/tile-join.cpp index 34e82c2d2..a27f99db5 100644 --- a/tile-join.cpp +++ b/tile-join.cpp @@ -182,6 +182,8 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::map("$type", v)); @@ -414,6 +416,8 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::mapsecond.lines++; } else if (feat.type == mvt_polygon) { file_keys->second.polygons++; + } else if (feat.type == mvt_spline) { + file_keys->second.splines++; } } } diff --git a/tile.cpp b/tile.cpp index 54d75c6ae..eeb0f1b15 100644 --- a/tile.cpp +++ b/tile.cpp @@ -1411,6 +1411,8 @@ serial_feature next_feature(FILE *geoms, std::atomic *geompos_in, cha v.string_value = "LineString"; } else if (sf.t == mvt_polygon) { v.string_value = "Polygon"; + } else if (sf.t == mvt_spline) { + v.string_value = "Spline"; } attributes.insert(std::pair("$type", v)); diff --git a/write_json.cpp b/write_json.cpp index c7ff98924..9969e3b15 100644 --- a/write_json.cpp +++ b/write_json.cpp @@ -545,7 +545,7 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y state.json_end_array(); } } - } else if (feat.type == VT_LINE) { + } else if (feat.type == VT_LINE || feat.type == VT_SPLINE) { int movetos = 0; for (size_t i = 0; i < ops.size(); i++) { if (ops[i].op == VT_MOVETO) { @@ -555,7 +555,12 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y if (movetos < 2) { state.json_write_string("type"); - state.json_write_string("LineString"); + + if (feat.type == VT_LINE) { + state.json_write_string("LineString"); + } else { + state.json_write_string("Spline"); + } for (auto c : coordinate_writers) { state.json_write_string(c.tag); @@ -569,7 +574,12 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y } } else { state.json_write_string("type"); - state.json_write_string("MultiLineString"); + + if (feat.type == VT_LINE) { + state.json_write_string("MultiLineString"); + } else { + state.json_write_string("MultiSpline"); + } for (auto c : coordinate_writers) { state.json_write_string(c.tag);