Checkpoint on parameterizing 32s

This commit is contained in:
Erica Fischer
2024-03-14 13:30:38 -07:00
parent e796400377
commit cea16d3f7e
6 changed files with 48 additions and 44 deletions
+14 -14
View File
@@ -69,7 +69,7 @@ drawvec simple_clip_poly(drawvec &geom, long long minx, long long miny, long lon
} }
drawvec simple_clip_poly(drawvec &geom, int z, int buffer, drawvec &edge_nodes, bool prevent_simplify_shared_nodes) { drawvec simple_clip_poly(drawvec &geom, int z, int buffer, drawvec &edge_nodes, bool prevent_simplify_shared_nodes) {
long long area = 1LL << (32 - z); long long area = 1LL << (GLOBAL_DETAIL - z);
long long clip_buffer = buffer * area / 256; long long clip_buffer = buffer * area / 256;
return simple_clip_poly(geom, -clip_buffer, -clip_buffer, area + clip_buffer, area + clip_buffer, return simple_clip_poly(geom, -clip_buffer, -clip_buffer, area + clip_buffer, area + clip_buffer,
@@ -78,7 +78,7 @@ drawvec simple_clip_poly(drawvec &geom, int z, int buffer, drawvec &edge_nodes,
drawvec clip_point(drawvec &geom, int z, long long buffer) { drawvec clip_point(drawvec &geom, int z, long long buffer) {
long long min = 0; long long min = 0;
long long area = 1LL << (32 - z); long long area = 1LL << (GLOBAL_DETAIL - z);
min -= buffer * area / 256; min -= buffer * area / 256;
area += buffer * area / 256; area += buffer * area / 256;
@@ -100,7 +100,7 @@ drawvec clip_point(drawvec &geom, long long minx, long long miny, long long maxx
drawvec clip_lines(drawvec &geom, int z, long long buffer) { drawvec clip_lines(drawvec &geom, int z, long long buffer) {
long long min = 0; long long min = 0;
long long area = 1LL << (32 - z); long long area = 1LL << (GLOBAL_DETAIL - z);
min -= buffer * area / 256; min -= buffer * area / 256;
area += buffer * area / 256; area += buffer * area / 256;
@@ -294,7 +294,7 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try
if (clip) { if (clip) {
long long area = 0xFFFFFFFF; long long area = 0xFFFFFFFF;
if (z != 0) { if (z != 0) {
area = 1LL << (32 - z); area = 1LL << (GLOBAL_DETAIL - z);
} }
long long clip_buffer = buffer * area / 256; long long clip_buffer = buffer * area / 256;
@@ -383,15 +383,15 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try
} }
void to_tile_scale(drawvec &geom, int z, int detail) { void to_tile_scale(drawvec &geom, int z, int detail) {
if (32 - detail - z < 0) { if (GLOBAL_DETAIL - detail - z < 0) {
for (size_t i = 0; i < geom.size(); i++) { for (size_t i = 0; i < geom.size(); i++) {
geom[i].x = std::round((double) geom[i].x * (1LL << (-(32 - detail - z)))); geom[i].x = std::round((double) geom[i].x * (1LL << (-(GLOBAL_DETAIL - detail - z))));
geom[i].y = std::round((double) geom[i].y * (1LL << (-(32 - detail - z)))); geom[i].y = std::round((double) geom[i].y * (1LL << (-(GLOBAL_DETAIL - detail - z))));
} }
} else { } else {
for (size_t i = 0; i < geom.size(); i++) { for (size_t i = 0; i < geom.size(); i++) {
geom[i].x = std::round((double) geom[i].x / (1LL << (32 - detail - z))); geom[i].x = std::round((double) geom[i].x / (1LL << (GLOBAL_DETAIL - detail - z)));
geom[i].y = std::round((double) geom[i].y / (1LL << (32 - detail - z))); geom[i].y = std::round((double) geom[i].y / (1LL << (GLOBAL_DETAIL - detail - z)));
} }
} }
} }
@@ -400,8 +400,8 @@ drawvec from_tile_scale(drawvec const &geom, int z, int detail) {
drawvec out; drawvec out;
for (size_t i = 0; i < geom.size(); i++) { for (size_t i = 0; i < geom.size(); i++) {
draw d = geom[i]; draw d = geom[i];
d.x *= (1LL << (32 - detail - z)); d.x *= (1LL << (GLOBAL_DETAIL - detail - z));
d.y *= (1LL << (32 - detail - z)); d.y *= (1LL << (GLOBAL_DETAIL - detail - z));
out.push_back(d); out.push_back(d);
} }
return out; return out;
@@ -526,7 +526,7 @@ double get_area(const drawvec &geom, size_t i, size_t j) {
// do not use the full precision, shift them nearer to the origin so // do not use the full precision, shift them nearer to the origin so
// their product is more likely to be exactly representable as a double. // their product is more likely to be exactly representable as a double.
// //
// (In practice they are actually 34-bit integers: 32 bits for the // (In practice they are actually (GLOBAL_DETAIL + 2)-bit integers: GLOBAL_DETAIL bits for the
// Mercator world plane, plus another two bits so features can stick // Mercator world plane, plus another two bits so features can stick
// off either the left or right side. But that is still too many bits // off either the left or right side. But that is still too many bits
// for the product to fit either in a 64-bit long long or in a // for the product to fit either in a 64-bit long long or in a
@@ -931,7 +931,7 @@ std::string overzoom(const mvt_tile &tile, int oz, int ox, int oy, int nz, int n
// Convert feature geometry to world coordinates // Convert feature geometry to world coordinates
long long tilesize = 1LL << (32 - oz); // source tile size in world coordinates long long tilesize = 1LL << (GLOBAL_DETAIL - oz); // source tile size in world coordinates
draw ring_closure(0, 0, 0); draw ring_closure(0, 0, 0);
bool sametile = (nz == oz && nx == ox && ny == oy && outlayer.extent >= layer.extent); bool sametile = (nz == oz && nx == ox && ny == oy && outlayer.extent >= layer.extent);
@@ -953,7 +953,7 @@ std::string overzoom(const mvt_tile &tile, int oz, int ox, int oy, int nz, int n
// Now offset from world coordinates to output tile coordinates, // Now offset from world coordinates to output tile coordinates,
// but retain world scale, because that is what tippecanoe clipping expects // but retain world scale, because that is what tippecanoe clipping expects
long long outtilesize = 1LL << (32 - nz); // destination tile size in world coordinates long long outtilesize = 1LL << (GLOBAL_DETAIL - nz); // destination tile size in world coordinates
for (auto &g : geom) { for (auto &g : geom) {
g.x -= nx * outtilesize; g.x -= nx * outtilesize;
g.y -= ny * outtilesize; g.y -= ny * outtilesize;
+4 -2
View File
@@ -25,8 +25,10 @@
#include "pmtiles_file.hpp" #include "pmtiles_file.hpp"
#include "errors.hpp" #include "errors.hpp"
#define MAX_MAXZOOM 32 // should this be higher?
int minzoom = 0; int minzoom = 0;
int maxzoom = 32; int maxzoom = MAX_MAXZOOM;
bool force = false; bool force = false;
bool progress_time() { bool progress_time() {
@@ -456,7 +458,7 @@ void decode(char *fname, int z, unsigned x, unsigned y, std::set<std::string> co
int tx = sqlite3_column_int(stmt, 2); int tx = sqlite3_column_int(stmt, 2);
int ty = sqlite3_column_int(stmt, 3); int ty = sqlite3_column_int(stmt, 3);
if (tz < 0 || tz >= 32) { if (tz < 0 || tz >= MAX_MAXZOOM) {
fprintf(stderr, "Impossible zoom level %d in mbtiles\n", tz); fprintf(stderr, "Impossible zoom level %d in mbtiles\n", tz);
exit(EXIT_IMPOSSIBLE); exit(EXIT_IMPOSSIBLE);
} }
+2 -2
View File
@@ -45,7 +45,7 @@ drawvec readPoints(const FlatGeobuf::Geometry *geometry) {
for (unsigned int i = 0; i < xy->size(); i+=2) { for (unsigned int i = 0; i < xy->size(); i+=2) {
long long x, y; long long x, y;
projection->project(xy->Get(i), xy->Get(i+1), 32, &x, &y); projection->project(xy->Get(i), xy->Get(i+1), GLOBAL_DETAIL, &x, &y);
dv.push_back(draw(VT_MOVETO, x, y)); dv.push_back(draw(VT_MOVETO, x, y));
} }
return dv; return dv;
@@ -59,7 +59,7 @@ drawvec readLinePart(const FlatGeobuf::Geometry *geometry) {
for (unsigned int i = 0; i < xy->size(); i+=2) { for (unsigned int i = 0; i < xy->size(); i+=2) {
long long x, y; long long x, y;
projection->project(xy->Get(i), xy->Get(i+1), 32, &x, &y); projection->project(xy->Get(i), xy->Get(i+1), GLOBAL_DETAIL, &x, &y);
if (i == 0 || (ends != NULL && current_end < ends->size() && i == ends->Get(current_end)*2)) { if (i == 0 || (ends != NULL && current_end < ends->size() && i == ends->Get(current_end)*2)) {
dv.push_back(draw(VT_MOVETO, x, y)); dv.push_back(draw(VT_MOVETO, x, y));
if (i > 0) current_end++; if (i > 0) current_end++;
+2
View File
@@ -20,6 +20,8 @@
#define VT_LINETO 2 #define VT_LINETO 2
#define VT_CLOSEPATH 7 #define VT_CLOSEPATH 7
#define GLOBAL_DETAIL 32
// The bitfield is to make sizeof(draw) be 16 instead of 24 // The bitfield is to make sizeof(draw) be 16 instead of 24
// at the cost, apparently, of a 0.7% increase in running time // at the cost, apparently, of a 0.7% increase in running time
// for packing and unpacking. // for packing and unpacking.
+24 -24
View File
@@ -57,8 +57,6 @@ extern "C" {
#define CMD_BITS 3 #define CMD_BITS 3
// Offset coordinates to keep them positive
#define COORD_OFFSET (4LL << 32)
#define SHIFT_RIGHT(a) ((long long) std::round((double) (a) / (1LL << geometry_scale))) #define SHIFT_RIGHT(a) ((long long) std::round((double) (a) / (1LL << geometry_scale)))
#define XSTRINGIFY(s) STRINGIFY(s) #define XSTRINGIFY(s) STRINGIFY(s)
@@ -449,7 +447,7 @@ static void rewrite(serial_feature const &osf, int z, int nextzoom, int maxzoom,
int k; int k;
for (k = 0; k < 4; k++) { for (k = 0; k < 4; k++) {
// Division instead of right-shift because coordinates can be negative // Division instead of right-shift because coordinates can be negative
bbox2[k] = osf.bbox[k] / (1 << (32 - nextzoom - 8)); bbox2[k] = osf.bbox[k] / (1 << (GLOBAL_DETAIL - nextzoom - 8));
} }
// Decrement the top and left edges so that any features that are // Decrement the top and left edges so that any features that are
// touching the edge can potentially be included in the adjacent tiles too. // touching the edge can potentially be included in the adjacent tiles too.
@@ -472,8 +470,8 @@ static void rewrite(serial_feature const &osf, int z, int nextzoom, int maxzoom,
// Offset from tile coordinates back to world coordinates // Offset from tile coordinates back to world coordinates
unsigned sx = 0, sy = 0; unsigned sx = 0, sy = 0;
if (z != 0) { if (z != 0) {
sx = tx << (32 - z); sx = tx << (GLOBAL_DETAIL - z);
sy = ty << (32 - z); sy = ty << (GLOBAL_DETAIL - z);
} }
drawvec geom2; drawvec geom2;
@@ -543,7 +541,7 @@ struct simplification_worker_arg {
// so that the area of the feature is still somehow represented // so that the area of the feature is still somehow represented
static drawvec revive_polygon(drawvec &geom, double area, int z, int detail) { static drawvec revive_polygon(drawvec &geom, double area, int z, int detail) {
// From area in world coordinates to area in tile coordinates // From area in world coordinates to area in tile coordinates
long long divisor = 1LL << (32 - detail - z); long long divisor = 1LL << (GLOBAL_DETAIL - detail - z);
area /= divisor * divisor; area /= divisor * divisor;
if (area == 0) { if (area == 0) {
@@ -613,7 +611,7 @@ static double simplify_feature(serial_feature *p, drawvec const &shared_nodes, n
// it would leave something else within the same tile pixel. // it would leave something else within the same tile pixel.
if (t == VT_LINE && !prevent[P_SIMPLIFY_SHARED_NODES]) { if (t == VT_LINE && !prevent[P_SIMPLIFY_SHARED_NODES]) {
// continues to deduplicate to line_detail even if we have extra detail // continues to deduplicate to line_detail even if we have extra detail
geom = remove_noop(geom, t, 32 - z - line_detail); geom = remove_noop(geom, t, GLOBAL_DETAIL - z - line_detail);
} }
bool already_marked = false; bool already_marked = false;
@@ -918,26 +916,26 @@ static bool clip_to_tile(serial_feature &sf, int z, long long buffer) {
int quick = quick_check(sf.bbox, z, buffer); int quick = quick_check(sf.bbox, z, buffer);
if (z == 0) { if (z == 0) {
if (sf.bbox[0] <= (1LL << 32) * buffer / 256 || sf.bbox[2] >= (1LL << 32) - ((1LL << 32) * buffer / 256)) { if (sf.bbox[0] <= (1LL << GLOBAL_DETAIL) * buffer / 256 || sf.bbox[2] >= (1LL << GLOBAL_DETAIL) - ((1LL << GLOBAL_DETAIL) * buffer / 256)) {
// If the geometry extends off the edge of the world, concatenate on another copy // If the geometry extends off the edge of the world, concatenate on another copy
// shifted by 360 degrees, and then make sure both copies get clipped down to size. // shifted by 360 degrees, and then make sure both copies get clipped down to size.
size_t n = sf.geometry.size(); size_t n = sf.geometry.size();
if (sf.bbox[0] <= (1LL << 32) * buffer / 256) { if (sf.bbox[0] <= (1LL << GLOBAL_DETAIL) * buffer / 256) {
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
sf.geometry.push_back(draw(sf.geometry[i].op, sf.geometry[i].x + (1LL << 32), sf.geometry[i].y)); sf.geometry.push_back(draw(sf.geometry[i].op, sf.geometry[i].x + (1LL << GLOBAL_DETAIL), sf.geometry[i].y));
} }
} }
if (sf.bbox[2] >= (1LL << 32) - ((1LL << 32) * buffer / 256)) { if (sf.bbox[2] >= (1LL << GLOBAL_DETAIL) - ((1LL << GLOBAL_DETAIL) * buffer / 256)) {
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
sf.geometry.push_back(draw(sf.geometry[i].op, sf.geometry[i].x - (1LL << 32), sf.geometry[i].y)); sf.geometry.push_back(draw(sf.geometry[i].op, sf.geometry[i].x - (1LL << GLOBAL_DETAIL), sf.geometry[i].y));
} }
} }
sf.bbox[0] = 0; sf.bbox[0] = 0;
sf.bbox[2] = 1LL << 32; sf.bbox[2] = 1LL << GLOBAL_DETAIL;
quick = -1; quick = -1;
} }
@@ -1250,7 +1248,7 @@ void *run_prefilter(void *v) {
} }
mvt_layer tmp_layer; mvt_layer tmp_layer;
tmp_layer.extent = 1LL << 32; tmp_layer.extent = 1LL << GLOBAL_DETAIL;
tmp_layer.name = (*(rpa->layer_unmaps))[sf.segment][sf.layer]; tmp_layer.name = (*(rpa->layer_unmaps))[sf.segment][sf.layer];
if (sf.t == VT_POLYGON) { if (sf.t == VT_POLYGON) {
@@ -1267,8 +1265,8 @@ void *run_prefilter(void *v) {
// Offset from tile coordinates back to world coordinates // Offset from tile coordinates back to world coordinates
unsigned sx = 0, sy = 0; unsigned sx = 0, sy = 0;
if (rpa->z != 0) { if (rpa->z != 0) {
sx = rpa->tx << (32 - rpa->z); sx = rpa->tx << (GLOBAL_DETAIL - rpa->z);
sy = rpa->ty << (32 - rpa->z); sy = rpa->ty << (GLOBAL_DETAIL - rpa->z);
} }
for (size_t i = 0; i < tmp_feature.geometry.size(); i++) { for (size_t i = 0; i < tmp_feature.geometry.size(); i++) {
tmp_feature.geometry[i].x += sx; tmp_feature.geometry[i].x += sx;
@@ -1406,12 +1404,12 @@ static bool line_is_too_small(drawvec const &geometry, int z, int detail) {
return true; return true;
} }
long long x = std::round((double) geometry[0].x / (1LL << (32 - detail - z))); long long x = std::round((double) geometry[0].x / (1LL << (GLOBAL_DETAIL - detail - z)));
long long y = std::round((double) geometry[0].y / (1LL << (32 - detail - z))); long long y = std::round((double) geometry[0].y / (1LL << (GLOBAL_DETAIL - detail - z)));
for (auto &g : geometry) { for (auto &g : geometry) {
long long xx = std::round((double) g.x / (1LL << (32 - detail - z))); long long xx = std::round((double) g.x / (1LL << (GLOBAL_DETAIL - detail - z)));
long long yy = std::round((double) g.y / (1LL << (32 - detail - z))); long long yy = std::round((double) g.y / (1LL << (GLOBAL_DETAIL - detail - z)));
if (xx != x || yy != y) { if (xx != x || yy != y) {
return false; return false;
@@ -2194,7 +2192,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
layer_features[x].geometry = remove_noop(layer_features[x].geometry, layer_features[x].t, 0); layer_features[x].geometry = remove_noop(layer_features[x].geometry, layer_features[x].t, 0);
if (!(prevent[P_SIMPLIFY] || (z == maxzoom && prevent[P_SIMPLIFY_LOW]))) { if (!(prevent[P_SIMPLIFY] || (z == maxzoom && prevent[P_SIMPLIFY_LOW]))) {
// XXX revisit: why does this not take zoom into account? // XXX revisit: why does this not take zoom into account?
layer_features[x].geometry = simplify_lines(layer_features[x].geometry, 32, 0, 0, 0, layer_features[x].geometry = simplify_lines(layer_features[x].geometry, GLOBAL_DETAIL, 0, 0, 0,
!(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), simplification, layer_features[x].t == VT_POLYGON ? 4 : 0, shared_nodes, NULL, 0); !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), simplification, layer_features[x].t == VT_POLYGON ? 4 : 0, shared_nodes, NULL, 0);
} }
} }
@@ -2633,8 +2631,10 @@ exit(EXIT_IMPOSSIBLE);
*arg->midy = y; *arg->midy = y;
*arg->most = len; *arg->most = len;
} else if (len == *arg->most) { } else if (len == *arg->most) {
unsigned long long a = (((unsigned long long) x) << 32) | y; // the details of the construction of a and b don't really matter very much;
unsigned long long b = (((unsigned long long) *arg->midx) << 32) | *arg->midy; // this is just a tie breaker if two maxzoom tiles have identical sizes
unsigned long long a = (((unsigned long long) x) << (8 * sizeof(y))) | y;
unsigned long long b = (((unsigned long long) *arg->midx) << (8 * sizeof(y))) | *arg->midy;
if (a < b) { if (a < b) {
*arg->midx = x; *arg->midx = x;
@@ -2820,7 +2820,7 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *global_stringpool, std::
int err = INT_MAX; int err = INT_MAX;
double zoom_gamma = gamma; double zoom_gamma = gamma;
unsigned long long zoom_mingap = ((1LL << (32 - z)) / 256 * cluster_distance) * ((1LL << (32 - z)) / 256 * cluster_distance); unsigned long long zoom_mingap = ((1LL << (GLOBAL_DETAIL - z)) / 256 * cluster_distance) * ((1LL << (GLOBAL_DETAIL - z)) / 256 * cluster_distance);
long long zoom_minextent = 0; long long zoom_minextent = 0;
unsigned long long zoom_mindrop_sequence = 0; unsigned long long zoom_mindrop_sequence = 0;
size_t zoom_tile_size = 0; size_t zoom_tile_size = 0;
+2 -2
View File
@@ -389,12 +389,12 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y
long long py = feat.geometry[g].y; long long py = feat.geometry[g].y;
if (op == VT_MOVETO || op == VT_LINETO) { if (op == VT_MOVETO || op == VT_LINETO) {
long long wscale = 1LL << (32 - z); long long wscale = 1LL << (GLOBAL_DETAIL - z);
long long wx = wscale * x + (wscale / layer.extent) * px; long long wx = wscale * x + (wscale / layer.extent) * px;
long long wy = wscale * y + (wscale / layer.extent) * py; long long wy = wscale * y + (wscale / layer.extent) * py;
double lat, lon; double lat, lon;
projection->unproject(wx, wy, 32, &lon, &lat); projection->unproject(wx, wy, GLOBAL_DETAIL, &lon, &lat);
ops.push_back(lonlat(op, lon, lat, px, py)); ops.push_back(lonlat(op, lon, lat, px, py));
} else { } else {