mirror of
https://github.com/mapbox/tippecanoe.git
synced 2025-01-22 04:18:01 +00:00
Better handling of features that cross the antimeridian
This commit is contained in:
parent
53471521f3
commit
c832b34160
@ -160,7 +160,7 @@ void parse_geometry(int t, json_object *j, unsigned *bbox, long long *fpos, FILE
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (j->length >= 2 && j->array[0]->type == JSON_NUMBER && j->array[1]->type == JSON_NUMBER) {
|
if (j->length >= 2 && j->array[0]->type == JSON_NUMBER && j->array[1]->type == JSON_NUMBER) {
|
||||||
unsigned x, y;
|
long long x, y;
|
||||||
double lon = j->array[0]->number;
|
double lon = j->array[0]->number;
|
||||||
double lat = j->array[1]->number;
|
double lat = j->array[1]->number;
|
||||||
latlon2tile(lat, lon, 32, &x, &y);
|
latlon2tile(lat, lon, 32, &x, &y);
|
||||||
|
24
projection.c
24
projection.c
@ -2,39 +2,19 @@
|
|||||||
#include "projection.h"
|
#include "projection.h"
|
||||||
|
|
||||||
// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
||||||
void latlon2tile(double lat, double lon, int zoom, unsigned int *x, unsigned int *y) {
|
void latlon2tile(double lat, double lon, int zoom, long long *x, long long *y) {
|
||||||
double lat_rad = lat * M_PI / 180;
|
double lat_rad = lat * M_PI / 180;
|
||||||
unsigned long long n = 1LL << zoom;
|
unsigned long long n = 1LL << zoom;
|
||||||
|
|
||||||
long long llx = n * ((lon + 180) / 360);
|
long long llx = n * ((lon + 180) / 360);
|
||||||
long long lly = n * (1 - (log(tan(lat_rad) + 1 / cos(lat_rad)) / M_PI)) / 2;
|
long long lly = n * (1 - (log(tan(lat_rad) + 1 / cos(lat_rad)) / M_PI)) / 2;
|
||||||
|
|
||||||
if (lat >= 85.0511) {
|
|
||||||
lly = 0;
|
|
||||||
}
|
|
||||||
if (lat <= -85.0511) {
|
|
||||||
lly = n - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (llx < 0) {
|
|
||||||
llx = 0;
|
|
||||||
}
|
|
||||||
if (lly < 0) {
|
|
||||||
lly = 0;
|
|
||||||
}
|
|
||||||
if (llx >= n) {
|
|
||||||
llx = n - 1;
|
|
||||||
}
|
|
||||||
if (lly >= n) {
|
|
||||||
lly = n - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*x = llx;
|
*x = llx;
|
||||||
*y = lly;
|
*y = lly;
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
||||||
void tile2latlon(unsigned int x, unsigned int y, int zoom, double *lat, double *lon) {
|
void tile2latlon(long long x, long long y, int zoom, double *lat, double *lon) {
|
||||||
unsigned long long n = 1LL << zoom;
|
unsigned long long n = 1LL << zoom;
|
||||||
*lon = 360.0 * x / n - 180.0;
|
*lon = 360.0 * x / n - 180.0;
|
||||||
*lat = atan(sinh(M_PI * (1 - 2.0 * y / n))) * 180.0 / M_PI;
|
*lat = atan(sinh(M_PI * (1 - 2.0 * y / n))) * 180.0 / M_PI;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
void latlon2tile(double lat, double lon, int zoom, unsigned int *x, unsigned int *y);
|
void latlon2tile(double lat, double lon, int zoom, long long *x, long long *y);
|
||||||
void tile2latlon(unsigned int x, unsigned int y, int zoom, double *lat, double *lon);
|
void tile2latlon(long long x, long long y, int zoom, double *lat, double *lon);
|
||||||
unsigned long long encode(unsigned int wx, unsigned int wy);
|
unsigned long long encode(unsigned int wx, unsigned int wy);
|
||||||
void decode(unsigned long long index, unsigned *wx, unsigned *wy);
|
void decode(unsigned long long index, unsigned *wx, unsigned *wy);
|
||||||
|
20
tile.cc
20
tile.cc
@ -544,6 +544,26 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, int z, unsi
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (z == 0) {
|
||||||
|
if (bbox[0] < 0 || bbox[2] > 1LL << 32) {
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
unsigned n = geom.size();
|
||||||
|
for (unsigned i = 0; i < n; i++) {
|
||||||
|
geom.push_back(draw(geom[i].op, geom[i].x - (1LL << 32), geom[i].y));
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < n; i++) {
|
||||||
|
geom.push_back(draw(geom[i].op, geom[i].x + (1LL << 32), geom[i].y));
|
||||||
|
}
|
||||||
|
|
||||||
|
bbox[0] = 0;
|
||||||
|
bbox[2] = 1LL << 32;
|
||||||
|
|
||||||
|
quick = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (quick != 1) {
|
if (quick != 1) {
|
||||||
if (t == VT_LINE) {
|
if (t == VT_LINE) {
|
||||||
geom = clip_lines(geom, z, line_detail, buffer);
|
geom = clip_lines(geom, z, line_detail, buffer);
|
||||||
|
Loading…
Reference in New Issue
Block a user