mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 08:25:40 +02:00
Checkpoint on parameterizing 32s
This commit is contained in:
@@ -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
@@ -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
@@ -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++;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user