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) {
long long area = 1LL << (32 - z);
long long area = 1LL << (GLOBAL_DETAIL - z);
long long clip_buffer = buffer * area / 256;
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) {
long long min = 0;
long long area = 1LL << (32 - z);
long long area = 1LL << (GLOBAL_DETAIL - z);
min -= 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) {
long long min = 0;
long long area = 1LL << (32 - z);
long long area = 1LL << (GLOBAL_DETAIL - z);
min -= 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) {
long long area = 0xFFFFFFFF;
if (z != 0) {
area = 1LL << (32 - z);
area = 1LL << (GLOBAL_DETAIL - z);
}
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) {
if (32 - detail - z < 0) {
if (GLOBAL_DETAIL - detail - z < 0) {
for (size_t i = 0; i < geom.size(); i++) {
geom[i].x = std::round((double) geom[i].x * (1LL << (-(32 - detail - z))));
geom[i].y = std::round((double) geom[i].y * (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 << (-(GLOBAL_DETAIL - detail - z))));
}
} else {
for (size_t i = 0; i < geom.size(); i++) {
geom[i].x = std::round((double) geom[i].x / (1LL << (32 - detail - z)));
geom[i].y = std::round((double) geom[i].y / (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 << (GLOBAL_DETAIL - detail - z)));
}
}
}
@@ -400,8 +400,8 @@ drawvec from_tile_scale(drawvec const &geom, int z, int detail) {
drawvec out;
for (size_t i = 0; i < geom.size(); i++) {
draw d = geom[i];
d.x *= (1LL << (32 - detail - z));
d.y *= (1LL << (32 - detail - z));
d.x *= (1LL << (GLOBAL_DETAIL - detail - z));
d.y *= (1LL << (GLOBAL_DETAIL - detail - z));
out.push_back(d);
}
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
// 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
// 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
@@ -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
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);
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,
// 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) {
g.x -= nx * outtilesize;
g.y -= ny * outtilesize;
+4 -2
View File
@@ -25,8 +25,10 @@
#include "pmtiles_file.hpp"
#include "errors.hpp"
#define MAX_MAXZOOM 32 // should this be higher?
int minzoom = 0;
int maxzoom = 32;
int maxzoom = MAX_MAXZOOM;
bool force = false;
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 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);
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) {
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));
}
return dv;
@@ -59,7 +59,7 @@ drawvec readLinePart(const FlatGeobuf::Geometry *geometry) {
for (unsigned int i = 0; i < xy->size(); i+=2) {
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)) {
dv.push_back(draw(VT_MOVETO, x, y));
if (i > 0) current_end++;
+2
View File
@@ -20,6 +20,8 @@
#define VT_LINETO 2
#define VT_CLOSEPATH 7
#define GLOBAL_DETAIL 32
// 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.
+24 -24
View File
@@ -57,8 +57,6 @@ extern "C" {
#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 XSTRINGIFY(s) STRINGIFY(s)
@@ -449,7 +447,7 @@ static void rewrite(serial_feature const &osf, int z, int nextzoom, int maxzoom,
int k;
for (k = 0; k < 4; k++) {
// 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
// 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
unsigned sx = 0, sy = 0;
if (z != 0) {
sx = tx << (32 - z);
sy = ty << (32 - z);
sx = tx << (GLOBAL_DETAIL - z);
sy = ty << (GLOBAL_DETAIL - z);
}
drawvec geom2;
@@ -543,7 +541,7 @@ struct simplification_worker_arg {
// so that the area of the feature is still somehow represented
static drawvec revive_polygon(drawvec &geom, double area, int z, int detail) {
// 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;
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.
if (t == VT_LINE && !prevent[P_SIMPLIFY_SHARED_NODES]) {
// 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;
@@ -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);
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
// shifted by 360 degrees, and then make sure both copies get clipped down to 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++) {
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++) {
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[2] = 1LL << 32;
sf.bbox[2] = 1LL << GLOBAL_DETAIL;
quick = -1;
}
@@ -1250,7 +1248,7 @@ void *run_prefilter(void *v) {
}
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];
if (sf.t == VT_POLYGON) {
@@ -1267,8 +1265,8 @@ void *run_prefilter(void *v) {
// Offset from tile coordinates back to world coordinates
unsigned sx = 0, sy = 0;
if (rpa->z != 0) {
sx = rpa->tx << (32 - rpa->z);
sy = rpa->ty << (32 - rpa->z);
sx = rpa->tx << (GLOBAL_DETAIL - rpa->z);
sy = rpa->ty << (GLOBAL_DETAIL - rpa->z);
}
for (size_t i = 0; i < tmp_feature.geometry.size(); i++) {
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;
}
long long x = std::round((double) geometry[0].x / (1LL << (32 - detail - z)));
long long y = std::round((double) geometry[0].y / (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 << (GLOBAL_DETAIL - detail - z)));
for (auto &g : geometry) {
long long xx = std::round((double) g.x / (1LL << (32 - detail - z)));
long long yy = std::round((double) g.y / (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 << (GLOBAL_DETAIL - detail - z)));
if (xx != x || yy != y) {
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);
if (!(prevent[P_SIMPLIFY] || (z == maxzoom && prevent[P_SIMPLIFY_LOW]))) {
// 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);
}
}
@@ -2633,8 +2631,10 @@ exit(EXIT_IMPOSSIBLE);
*arg->midy = y;
*arg->most = len;
} else if (len == *arg->most) {
unsigned long long a = (((unsigned long long) x) << 32) | y;
unsigned long long b = (((unsigned long long) *arg->midx) << 32) | *arg->midy;
// the details of the construction of a and b don't really matter very much;
// 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) {
*arg->midx = x;
@@ -2820,7 +2820,7 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *global_stringpool, std::
int err = INT_MAX;
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;
unsigned long long zoom_mindrop_sequence = 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;
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 wy = wscale * y + (wscale / layer.extent) * py;
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));
} else {