diff --git a/decode.cpp b/decode.cpp index 63d70b8..f9d226a 100644 --- a/decode.cpp +++ b/decode.cpp @@ -85,9 +85,10 @@ void do_stats(mvt_tile &tile, size_t size, bool compressed, int z, unsigned x, u state.json_write_newline(); } -void handle(std::string message, int z, unsigned x, unsigned y, std::set const &to_decode, bool pipeline, bool stats, json_writer &state) { +std::vector> handle(std::string message, int z, unsigned x, unsigned y, std::set const &to_decode, bool pipeline, bool stats, json_writer &state) { mvt_tile tile; bool was_compressed; + std::vector> pending; try { if (!tile.decode(message, was_compressed)) { @@ -101,7 +102,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::set todo = layer_to_geojson(layer, z, x, y, !pipeline, pipeline, pipeline, false, 0, 0, 0, !force, state); + + for (auto f : todo) { + pending.push_back(std::pair(layer, f)); + } if (!pipeline) { if (true) { @@ -221,6 +226,14 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::set> todo) { + if (todo.size() > 0) { + printf("doing partial feature\n"); + } } void decode(char *fname, int z, unsigned x, unsigned y, std::set const &to_decode, bool pipeline, bool stats) { @@ -229,6 +242,7 @@ void decode(char *fname, int z, unsigned x, unsigned y, std::set co int oz = z; unsigned ox = x, oy = y; json_writer state(stdout); + std::vector> pending; int fd = open(fname, O_RDONLY | O_CLOEXEC); if (fd >= 0) { @@ -240,7 +254,8 @@ void decode(char *fname, int z, unsigned x, unsigned y, std::set co if (strcmp(map, "SQLite format 3") != 0) { if (z >= 0) { std::string s = std::string(map, st.st_size); - handle(s, z, x, y, to_decode, pipeline, stats, state); + std::vector> todo = handle(s, z, x, y, to_decode, pipeline, stats, state); + handle_split(todo); munmap(map, st.st_size); return; } else { @@ -339,6 +354,7 @@ void decode(char *fname, int z, unsigned x, unsigned y, std::set co state.json_write_newline(); } + int prevz = -1; if (isdir) { within = 0; for (size_t i = 0; i < tiles.size(); i++) { @@ -370,8 +386,19 @@ void decode(char *fname, int z, unsigned x, unsigned y, std::set co } fclose(f); - handle(s, tiles[i].z, tiles[i].x, tiles[i].y, to_decode, pipeline, stats, state); + if (tiles[i].z != prevz) { + handle_split(pending); + pending.clear(); + prevz = tiles[i].z; + } + + std::vector> todo = handle(s, tiles[i].z, tiles[i].x, tiles[i].y, to_decode, pipeline, stats, state); + for (auto lf : todo) { + pending.push_back(lf); + } } + + handle_split(pending); } else { const char *sql = "SELECT tile_data, zoom_level, tile_column, tile_row from tiles where zoom_level between ? and ? order by zoom_level, tile_column, tile_row;"; sqlite3_stmt *stmt; @@ -411,10 +438,21 @@ void decode(char *fname, int z, unsigned x, unsigned y, std::set co ty = (1LL << tz) - 1 - ty; const char *s = (const char *) sqlite3_column_blob(stmt, 0); - handle(std::string(s, len), tz, tx, ty, to_decode, pipeline, stats, state); + if (tz != prevz) { + handle_split(pending); + pending.clear(); + prevz = tz; + } + + std::vector> todo = handle(std::string(s, len), tz, tx, ty, to_decode, pipeline, stats, state); + for (auto lf : todo) { + pending.push_back(lf); + } } sqlite3_finalize(stmt); + + handle_split(pending); } if (!pipeline && !stats) { @@ -451,7 +489,9 @@ void decode(char *fname, int z, unsigned x, unsigned y, std::set co fprintf(stderr, "%s: Warning: using tile %d/%u/%u instead of %d/%u/%u\n", fname, z, x, y, oz, ox, oy); } - handle(std::string(s, len), z, x, y, to_decode, pipeline, stats, state); + std::vector> todo = handle(std::string(s, len), z, x, y, to_decode, pipeline, stats, state); + handle_split(todo); + handled = 1; } diff --git a/geometry.cpp b/geometry.cpp index de68616..2c89506 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -806,17 +806,17 @@ drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid, int z } for (size_t i = 0; i < geom.size(); i++) { - if (geom[i].op == VT_LINETO) { + if (i > 0) { if (geom[i - 1].x / width != geom[i].x / width) { if (geom[i - 1].x < geom[i].x) { for (long long xx = geom[i - 1].x / width * width + width; xx <= geom[i].x / width * width; xx += width) { long long yy = (xx - geom[i - 1].x) * (geom[i].y - geom[i - 1].y) / (geom[i].x - geom[i - 1].x) + geom[i - 1].y; - out.push_back(draw(VT_LINETO, xx, yy, ++*pointid)); + out.push_back(draw(geom[i].op, xx, yy, ++*pointid)); } } else { for (long long xx = geom[i].x / width * width + width; xx <= geom[i - 1].x / width * width; xx += width) { long long yy = (xx - geom[i].x) * (geom[i - 1].y - geom[i].y) / (geom[i - 1].x - geom[i].x) + geom[i].y; - out.push_back(draw(VT_LINETO, xx, yy, ++*pointid)); + out.push_back(draw(geom[i].op, xx, yy, ++*pointid)); } } } @@ -829,17 +829,17 @@ drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid, int z out.clear(); for (size_t i = 0; i < geom.size(); i++) { - if (geom[i].op == VT_LINETO) { + if (i > 0) { if (geom[i - 1].y / width != geom[i].y / width) { if (geom[i - 1].y < geom[i].y) { for (long long yy = geom[i - 1].y / width * width + width; yy <= geom[i].y / width * width; yy += width) { long long xx = (yy - geom[i - 1].y) * (geom[i].x - geom[i - 1].x) / (geom[i].y - geom[i - 1].y) + geom[i - 1].x; - out.push_back(draw(VT_LINETO, xx, yy, ++*pointid)); + out.push_back(draw(geom[i].op, xx, yy, ++*pointid)); } } else { for (long long yy = geom[i].y / width * width + width; yy <= geom[i - 1].y / width * width; yy += width) { long long xx = (yy - geom[i].y) * (geom[i - 1].x - geom[i].x) / (geom[i - 1].y - geom[i].y) + geom[i].x; - out.push_back(draw(VT_LINETO, xx, yy, ++*pointid)); + out.push_back(draw(geom[i].op, xx, yy, ++*pointid)); } } } @@ -868,7 +868,7 @@ drawvec clip_lines(drawvec geom, int z, unsigned x, unsigned y, long long buffer area += buffer * area / 256; for (size_t i = 0; i < geom.size(); i++) { - if (i > 0 && (geom[i - 1].op == VT_MOVETO || geom[i - 1].op == VT_LINETO) && geom[i].op == VT_LINETO) { + if (i > 0) { double x1 = geom[i - 1].x; double y1 = geom[i - 1].y; @@ -885,9 +885,9 @@ drawvec clip_lines(drawvec geom, int z, unsigned x, unsigned y, long long buffer } if (x2 == geom[i].x && y2 == geom[i].y) { - out.push_back(draw(VT_LINETO, x2, y2, geom[i].id)); + out.push_back(draw(geom[i].op, x2, y2, geom[i].id)); } else { - out.push_back(draw(VT_LINETO, x2, y2)); + out.push_back(draw(geom[i].op, x2, y2)); } out.push_back(draw(VT_MOVETO, geom[i].x, geom[i].y, geom[i].id)); diff --git a/write_json.cpp b/write_json.cpp index ce1af02..42bf930 100644 --- a/write_json.cpp +++ b/write_json.cpp @@ -271,10 +271,17 @@ struct lonlat { } }; -void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, bool dropped, unsigned long long index, long long sequence, long long extent, bool complain, json_writer &state) { +std::vector layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, bool dropped, unsigned long long index, long long sequence, long long extent, bool complain, json_writer &state) { + std::vector incomplete; + for (size_t f = 0; f < layer.features.size(); f++) { mvt_feature const &feat = layer.features[f]; + if (feat.clipid != 0) { + incomplete.push_back(feat); + continue; + } + state.json_write_hash(); state.json_write_string("type"); state.json_write_string("Feature"); @@ -596,6 +603,8 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y state.json_comma_newline(); } } + + return incomplete; } void fprintq(FILE *fp, const char *s) { diff --git a/write_json.hpp b/write_json.hpp index d0b9d18..a8033e3 100644 --- a/write_json.hpp +++ b/write_json.hpp @@ -60,7 +60,7 @@ struct json_writer { void adds(std::string const &s); }; -void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, bool dropped, unsigned long long index, long long sequence, long long extent, bool complain, json_writer &state); +std::vector layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, bool dropped, unsigned long long index, long long sequence, long long extent, bool complain, json_writer &state); void fprintq(FILE *f, const char *s); #endif