mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-05 18:05:42 +02:00
Straighten out hilbert and quadkey encoding
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#include "evaluator.hpp"
|
#include "evaluator.hpp"
|
||||||
#include "serial.hpp"
|
#include "serial.hpp"
|
||||||
#include "attribute.hpp"
|
#include "attribute.hpp"
|
||||||
|
#include "projection.hpp"
|
||||||
|
|
||||||
static std::vector<std::pair<double, double>> clip_poly1(std::vector<std::pair<double, double>> &geom,
|
static std::vector<std::pair<double, double>> clip_poly1(std::vector<std::pair<double, double>> &geom,
|
||||||
long long minx, long long miny, long long maxx, long long maxy,
|
long long minx, long long miny, long long maxx, long long maxy,
|
||||||
|
|||||||
+12
-9
@@ -497,7 +497,7 @@ drawvec simplify_lines(drawvec &geom, int z, int tx, int ty, int detail, bool ma
|
|||||||
|
|
||||||
// to quadkey
|
// to quadkey
|
||||||
struct node n;
|
struct node n;
|
||||||
n.index = encode_quadkey((unsigned) d.x, (unsigned) d.y);
|
n.index = encode_quadkey(coordinate_to_encodable(d.x), coordinate_to_encodable(d.y));
|
||||||
|
|
||||||
if (bsearch(&n, shared_nodes_map, nodepos / sizeof(node), sizeof(node), nodecmp) != NULL) {
|
if (bsearch(&n, shared_nodes_map, nodepos / sizeof(node), sizeof(node), nodecmp) != NULL) {
|
||||||
geom[i].necessary = true;
|
geom[i].necessary = true;
|
||||||
@@ -578,8 +578,8 @@ drawvec reorder_lines(const drawvec &geom) {
|
|||||||
// instead of down and to the right
|
// instead of down and to the right
|
||||||
// so that it will coalesce better
|
// so that it will coalesce better
|
||||||
|
|
||||||
unsigned long long l1 = encode_index(geom[0].x, geom[0].y);
|
unsigned long long l1 = encode_index(coordinate_to_encodable(geom[0].x), coordinate_to_encodable(geom[0].y));
|
||||||
unsigned long long l2 = encode_index(geom[geom.size() - 1].x, geom[geom.size() - 1].y);
|
unsigned long long l2 = encode_index(coordinate_to_encodable(geom[geom.size() - 1].x), coordinate_to_encodable(geom[geom.size() - 1].y));
|
||||||
|
|
||||||
if (l1 > l2) {
|
if (l1 > l2) {
|
||||||
drawvec out;
|
drawvec out;
|
||||||
@@ -1302,6 +1302,9 @@ drawvec checkerboard_anchors(drawvec const &geom, int tx, int ty, int z, unsigne
|
|||||||
unsigned wx, wy;
|
unsigned wx, wy;
|
||||||
decode_index(label_point, &wx, &wy);
|
decode_index(label_point, &wx, &wy);
|
||||||
|
|
||||||
|
long long wwx = decoded_to_coordinate(wx);
|
||||||
|
long long wwy = decoded_to_coordinate(wy);
|
||||||
|
|
||||||
// upper left of tile in world coordinates
|
// upper left of tile in world coordinates
|
||||||
long long tx1 = 0, ty1 = 0;
|
long long tx1 = 0, ty1 = 0;
|
||||||
// lower right of tile in world coordinates;
|
// lower right of tile in world coordinates;
|
||||||
@@ -1340,16 +1343,16 @@ drawvec checkerboard_anchors(drawvec const &geom, int tx, int ty, int z, unsigne
|
|||||||
|
|
||||||
const long long label_spacing = spiral_dist * (tx2 - tx1);
|
const long long label_spacing = spiral_dist * (tx2 - tx1);
|
||||||
|
|
||||||
long long x1 = floor(std::min(bx1 - wx, bx2 - wx) / label_spacing);
|
long long x1 = floor(std::min(bx1 - wwx, bx2 - wwx) / label_spacing);
|
||||||
long long x2 = ceil(std::max(bx1 - wx, bx2 - wx) / label_spacing);
|
long long x2 = ceil(std::max(bx1 - wwx, bx2 - wwx) / label_spacing);
|
||||||
|
|
||||||
long long y1 = floor(std::min(by1 - wy, by2 - wy) / label_spacing - 0.5);
|
long long y1 = floor(std::min(by1 - wwy, by2 - wwy) / label_spacing - 0.5);
|
||||||
long long y2 = ceil(std::max(by1 - wy, by2 - wy) / label_spacing);
|
long long y2 = ceil(std::max(by1 - wwy, by2 - wwy) / label_spacing);
|
||||||
|
|
||||||
for (long long lx = x1; lx <= x2; lx++) {
|
for (long long lx = x1; lx <= x2; lx++) {
|
||||||
for (long long ly = y1; ly <= y2; ly++) {
|
for (long long ly = y1; ly <= y2; ly++) {
|
||||||
long long x = lx * label_spacing + wx;
|
long long x = lx * label_spacing + wwx;
|
||||||
long long y = ly * label_spacing + wy;
|
long long y = ly * label_spacing + wwy;
|
||||||
|
|
||||||
if (((unsigned long long) lx & 1) == 1) {
|
if (((unsigned long long) lx & 1) == 1) {
|
||||||
y += label_spacing / 2;
|
y += label_spacing / 2;
|
||||||
|
|||||||
@@ -20,8 +20,6 @@
|
|||||||
#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.
|
||||||
|
|||||||
@@ -2069,7 +2069,7 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct node n;
|
struct node n;
|
||||||
n.index = encode_quadkey((unsigned) x, (unsigned) y);
|
n.index = encode_quadkey(coordinate_to_encodable(x), coordinate_to_encodable(y));
|
||||||
|
|
||||||
fwrite_check((char *) &n, sizeof(struct node), 1, readers[0].nodefile, &readers[0].nodepos, "vertices");
|
fwrite_check((char *) &n, sizeof(struct node), 1, readers[0].nodefile, &readers[0].nodepos, "vertices");
|
||||||
}
|
}
|
||||||
@@ -2152,7 +2152,7 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
|
|||||||
unsigned wx, wy;
|
unsigned wx, wy;
|
||||||
decode_quadkey(here.index, &wx, &wy);
|
decode_quadkey(here.index, &wx, &wy);
|
||||||
double lon, lat;
|
double lon, lat;
|
||||||
tile2lonlat(wx, wy, 32, &lon, &lat);
|
tile2lonlat(decoded_to_coordinate(wx), decoded_to_coordinate(wy), GLOBAL_DETAIL, &lon, &lat);
|
||||||
printf("{\"type\":\"Feature\", \"properties\":{}, \"geometry\":{\"type\":\"Point\", \"coordinates\":[%f,%f]}}\n", lon, lat);
|
printf("{\"type\":\"Feature\", \"properties\":{}, \"geometry\":{\"type\":\"Point\", \"coordinates\":[%f,%f]}}\n", lon, lat);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -2505,6 +2505,9 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
|
|||||||
unsigned xx, yy;
|
unsigned xx, yy;
|
||||||
decode_index(map[ip].ix, &xx, &yy);
|
decode_index(map[ip].ix, &xx, &yy);
|
||||||
|
|
||||||
|
long long gxx = decoded_to_coordinate(xx);
|
||||||
|
long long gyy = decoded_to_coordinate(yy);
|
||||||
|
|
||||||
long long nprogress = 100 * ip / indices;
|
long long nprogress = 100 * ip / indices;
|
||||||
if (nprogress != progress) {
|
if (nprogress != progress) {
|
||||||
progress = nprogress;
|
progress = nprogress;
|
||||||
@@ -2520,8 +2523,8 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
|
|||||||
if (z != 0) {
|
if (z != 0) {
|
||||||
// These are tile numbers, not pixels,
|
// These are tile numbers, not pixels,
|
||||||
// so shift, not round
|
// so shift, not round
|
||||||
xxx = xx >> (32 - z);
|
xxx = gxx >> (GLOBAL_DETAIL - z);
|
||||||
yyy = yy >> (32 - z);
|
yyy = gyy >> (GLOBAL_DETAIL - z);
|
||||||
}
|
}
|
||||||
|
|
||||||
double scale = (double) (1LL << (64 - 2 * (z + 8)));
|
double scale = (double) (1LL << (64 - 2 * (z + 8)));
|
||||||
|
|||||||
@@ -200,6 +200,14 @@ void decode_quadkey(unsigned long long index, unsigned *wx, unsigned *wy) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned coordinate_to_encodable(long long coord) {
|
||||||
|
return (unsigned) (coord / (1LL << (GLOBAL_DETAIL - 32)));
|
||||||
|
}
|
||||||
|
|
||||||
|
long long decoded_to_coordinate(unsigned coord) {
|
||||||
|
return ((long long) coord) * (1LL << (GLOBAL_DETAIL - 32));
|
||||||
|
}
|
||||||
|
|
||||||
void set_projection_or_exit(const char *optarg) {
|
void set_projection_or_exit(const char *optarg) {
|
||||||
struct projection *p;
|
struct projection *p;
|
||||||
for (p = projections; p->name != NULL; p++) {
|
for (p = projections; p->name != NULL; p++) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef PROJECTION_HPP
|
#ifndef PROJECTION_HPP
|
||||||
#define PROJECTION_HPP
|
#define PROJECTION_HPP
|
||||||
|
|
||||||
|
#define GLOBAL_DETAIL 32
|
||||||
|
|
||||||
void lonlat2tile(double lon, double lat, int zoom, long long *x, long long *y);
|
void lonlat2tile(double lon, double lat, int zoom, long long *x, long long *y);
|
||||||
void epsg3857totile(double ix, double iy, int zoom, long long *x, long long *y);
|
void epsg3857totile(double ix, double iy, int zoom, long long *x, long long *y);
|
||||||
void tile2lonlat(long long x, long long y, int zoom, double *lon, double *lat);
|
void tile2lonlat(long long x, long long y, int zoom, double *lon, double *lat);
|
||||||
@@ -26,4 +28,7 @@ void decode_quadkey(unsigned long long index, unsigned *wx, unsigned *wy);
|
|||||||
unsigned long long encode_hilbert(unsigned int wx, unsigned int wy);
|
unsigned long long encode_hilbert(unsigned int wx, unsigned int wy);
|
||||||
void decode_hilbert(unsigned long long index, unsigned *wx, unsigned *wy);
|
void decode_hilbert(unsigned long long index, unsigned *wx, unsigned *wy);
|
||||||
|
|
||||||
|
unsigned coordinate_to_encodable(long long coord);
|
||||||
|
long long decoded_to_coordinate(unsigned coord);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+4
-3
@@ -409,7 +409,7 @@ static void add_scaled_node(struct reader *r, serialization_state *sst, draw g)
|
|||||||
long long y = SHIFT_LEFT(g.y);
|
long long y = SHIFT_LEFT(g.y);
|
||||||
|
|
||||||
struct node n;
|
struct node n;
|
||||||
n.index = encode_quadkey((unsigned) x, (unsigned) y);
|
n.index = encode_quadkey(coordinate_to_encodable(x), coordinate_to_encodable(y));
|
||||||
|
|
||||||
fwrite_check((char *) &n, sizeof(struct node), 1, r->nodefile, &r->nodepos, sst->fname);
|
fwrite_check((char *) &n, sizeof(struct node), 1, r->nodefile, &r->nodepos, sst->fname);
|
||||||
}
|
}
|
||||||
@@ -704,14 +704,15 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
|
|||||||
midy = SHIFT_LEFT(scaled_geometry[ix].y) & ((1LL << GLOBAL_DETAIL) - 1);
|
midy = SHIFT_LEFT(scaled_geometry[ix].y) & ((1LL << GLOBAL_DETAIL) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bbox_index = encode_index(midx, midy);
|
bbox_index = encode_index(coordinate_to_encodable(midx), coordinate_to_encodable(midy));
|
||||||
|
|
||||||
if (sf.t == VT_POLYGON && additional[A_GENERATE_POLYGON_LABEL_POINTS]) {
|
if (sf.t == VT_POLYGON && additional[A_GENERATE_POLYGON_LABEL_POINTS]) {
|
||||||
drawvec dv = polygon_to_anchor(scaled_geometry);
|
drawvec dv = polygon_to_anchor(scaled_geometry);
|
||||||
if (dv.size() > 0) {
|
if (dv.size() > 0) {
|
||||||
dv[0].x = SHIFT_LEFT(dv[0].x) & ((1LL << GLOBAL_DETAIL) - 1);
|
dv[0].x = SHIFT_LEFT(dv[0].x) & ((1LL << GLOBAL_DETAIL) - 1);
|
||||||
dv[0].y = SHIFT_LEFT(dv[0].y) & ((1LL << GLOBAL_DETAIL) - 1);
|
dv[0].y = SHIFT_LEFT(dv[0].y) & ((1LL << GLOBAL_DETAIL) - 1);
|
||||||
sf.label_point = encode_index(dv[0].x, dv[0].y);
|
// this could just be serialized as numbers instead of encoding and decoding
|
||||||
|
sf.label_point = encode_index(coordinate_to_encodable(dv[0].x), coordinate_to_encodable(dv[0].y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user