From afa6a73a797dfea509bea16253c26a1d6f67a255 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 23 Aug 2024 13:12:43 -0700 Subject: [PATCH] Bounding box of tile-relative mvt geometry --- Makefile | 2 +- clip.cpp | 17 ++++++++--------- mvt.cpp | 31 +++++++++++++++++++++++++++++++ mvt.hpp | 4 ++++ unit.cpp | 21 +++++++++++++++++++++ 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 838de916..45f3949f 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,7 @@ tile-join: tile-join.o projection.o mbtiles.o mvt.o memfile.o dirtiles.o jsonpul tippecanoe-json-tool: jsontool.o jsonpull/jsonpull.o csv.o text.o geojson-loop.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread -unit: unit.o text.o sort.o mvt.o +unit: unit.o text.o sort.o mvt.o projection.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread tippecanoe-overzoom: overzoom.o mvt.o clip.o evaluator.o jsonpull/jsonpull.o text.o attribute.o read_json.o projection.o diff --git a/clip.cpp b/clip.cpp index 91077eed..c9db2938 100644 --- a/clip.cpp +++ b/clip.cpp @@ -1184,20 +1184,17 @@ struct index_event { } }; -void get_quadkey_bounds(std::vector const &geom, - unsigned long long *start, unsigned long long *end, - int z, int x, int y, int extent) { -} - -mvt_tile assign_to_bins(mvt_tile const &features, std::vector const &bins, int z, int x, int y, int extent) { +mvt_tile assign_to_bins(mvt_tile const &features, std::vector const &bins, int z, int x, int y, int detail) { std::vector events; // Index bins for (size_t i = 0; i < bins.size(); i++) { for (size_t j = 0; j < bins[i].features.size(); j++) { + long long xmin, ymin, xmax, ymax; unsigned long long start, end; - get_quadkey_bounds(bins[i].features[j].geometry, &start, &end, z, x, y, extent); + get_bbox(bins[i].features[j].geometry, &xmin, &ymin, &xmax, &ymax, z, x, y, detail); + // get_quadkey_bounds(xmin, xmax, ymin, ymax, &start, &end, z, x, y, detail); events.emplace_back(start, index_event::ENTER, i, j); events.emplace_back(end, index_event::EXIT, i, j); } @@ -1206,9 +1203,11 @@ mvt_tile assign_to_bins(mvt_tile const &features, std::vector const & // Index points for (size_t i = 0; i < features.layers.size(); i++) { for (size_t j = 0; j < features.layers[i].features.size(); j++) { + long long xmin, ymin, xmax, ymax; unsigned long long start, end; - get_quadkey_bounds(bins[i].features[j].geometry, &start, &end, z, x, y, extent); + get_bbox(bins[i].features[j].geometry, &xmin, &ymin, &xmax, &ymax, z, x, y, detail); + // get_quadkey_bounds(xmin, xmax, ymin, ymax, &start, &end, z, x, y, detail); events.emplace_back(start, index_event::CHECK, i, j); } } @@ -1448,7 +1447,7 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int } if (bins.size() > 0) { - outtile = assign_to_bins(outtile, bins, nz, nx, ny, 1 << detail); + outtile = assign_to_bins(outtile, bins, nz, nx, ny, detail); } for (ssize_t i = outtile.layers.size() - 1; i >= 0; i--) { diff --git a/mvt.cpp b/mvt.cpp index 1628fe57..7c600f2d 100644 --- a/mvt.cpp +++ b/mvt.cpp @@ -835,3 +835,34 @@ long long mvt_value_to_long_long(mvt_value const &v) { exit(EXIT_IMPOSSIBLE); } } + +void get_bbox(std::vector const &geom, + long long *xmin, long long *ymin, long long *xmax, long long *ymax, + int z, int tx, int ty, int detail) { + *xmin = LLONG_MAX; + *ymin = LLONG_MAX; + *xmax = 0; + *ymax = 0; + + for (auto const &g : geom) { + if (g.op == mvt_moveto || g.op == mvt_lineto) { + long long x = g.x; + long long y = g.y; + + // to world scale + x = x * (1LL << (32 - z - detail)); + y = y * (1LL << (32 - z - detail)); + + // to world origin + if (z > 0) { + x += (1LL << (32 - z)) * tx; + y += (1LL << (32 - z)) * ty; + } + + *xmin = std::min(*xmin, x); + *ymin = std::min(*ymin, y); + *xmax = std::max(*xmax, x); + *ymax = std::max(*ymax, y); + } + } +} diff --git a/mvt.hpp b/mvt.hpp index b6d5dbbe..33f3c173 100644 --- a/mvt.hpp +++ b/mvt.hpp @@ -199,4 +199,8 @@ bool is_unsigned_integer(const char *s, unsigned long long *v); struct serial_val; serial_val mvt_value_to_serial_val(mvt_value const &v); + +void get_bbox(std::vector const &geom, + long long *xmin, long long *ymin, long long *xmax, long long *ymax, + int z, int tx, int ty, int detail); #endif diff --git a/unit.cpp b/unit.cpp index 1cfb2f25..8d864808 100644 --- a/unit.cpp +++ b/unit.cpp @@ -3,6 +3,8 @@ #include "text.hpp" #include "sort.hpp" #include "tile-cache.hpp" +#include "mvt.hpp" +#include "projection.hpp" #include #include @@ -124,3 +126,22 @@ TEST_CASE("Bit reversal", "bit reversal") { REQUIRE(bit_reverse(0x1234567812489BCF) == 0xF3D912481E6A2C48); REQUIRE(bit_reverse(0xF3D912481E6A2C48) == 0x1234567812489BCF); } + +TEST_CASE("mvt_geometry bbox") { + std::vector geom; + + geom.emplace_back(mvt_moveto, 128, 128); + geom.emplace_back(mvt_lineto, 256, 256); + + long long xmin, ymin, xmax, ymax; + get_bbox(geom, &xmin, &ymin, &xmax, &ymax, 11, 327, 791, 9); + + double lon, lat; + tile2lonlat(xmin, ymin, 32, &lon, &lat); + REQUIRE(std::to_string(lon) == "-122.475586"); + REQUIRE(std::to_string(lat) == "37.822802"); + + tile2lonlat(xmax, ymax, 32, &lon, &lat); + REQUIRE(std::to_string(lon) == "-122.431641"); + REQUIRE(std::to_string(lat) == "37.788081"); +}