From a504840bd53bae142af7641bb25959dd1d083e4d Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Wed, 1 Jun 2016 16:55:52 -0700 Subject: [PATCH] Warn if the GeoJSON specifies a different projection --- geojson.cpp | 21 ++++++++++++++++++++- main.cpp | 18 +++++++++--------- main.hpp | 2 -- projection.hpp | 8 ++++++++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/geojson.cpp b/geojson.cpp index 7531296..c2ef911 100644 --- a/geojson.cpp +++ b/geojson.cpp @@ -90,7 +90,7 @@ long long parse_geometry(int t, json_object *j, long long *bbox, long long *fpos long long x, y; double lon = j->array[0]->number; double lat = j->array[1]->number; - projection(lon, lat, 32, &x, &y); + projection->project(lon, lat, 32, &x, &y); if (j->length > 2) { static int warned = 0; @@ -405,6 +405,21 @@ int serialize_geometry(json_object *geometry, json_object *properties, const cha return 1; } +void check_crs(json_object *j, const char *reading) { + json_object *crs = json_hash_get(j, "crs"); + if (crs != NULL) { + json_object *properties = json_hash_get(crs, "properties"); + if (properties != NULL) { + json_object *name = json_hash_get(properties, "name"); + if (name->type == JSON_STRING) { + if (strcmp(name->string, projection->alias) != 0) { + fprintf(stderr, "%s: Warning: GeoJSON specified projection \"%s\", not \"%s\".\n", reading, name->string, projection->alias); + } + } + } + } +} + void parse_json(json_pull *jp, const char *reading, volatile long long *layer_seq, volatile long long *progress_seq, long long *metapos, long long *geompos, long long *indexpos, std::set *exclude, std::set *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, char *fname, int basezoom, int layer, double droprate, long long *file_bbox, int segment, int *initialized, unsigned *initial_x, unsigned *initial_y, struct reader *readers, std::set *file_keys, int maxzoom) { long long found_hashes = 0; long long found_features = 0; @@ -476,6 +491,10 @@ void parse_json(json_pull *jp, const char *reading, volatile long long *layer_se } } + if (strcmp(type->string, "FeatureCollection") == 0) { + check_crs(j, reading); + } + if (strcmp(type->string, "Feature") != 0) { continue; } diff --git a/main.cpp b/main.cpp index 770ef1d..db7b716 100644 --- a/main.cpp +++ b/main.cpp @@ -58,7 +58,6 @@ int geometry_scale = 0; int prevent[256]; int additional[256]; -void (*projection)(double ix, double iy, int zoom, long long *ox, long long *oy) = lonlat2tile; struct source { std::string layer; @@ -1706,17 +1705,14 @@ static bool has_name(struct option *long_options, int *pl) { return false; } -struct projection { - const char *name; - void (*project)(double ix, double iy, int zoom, long long *ox, long long *oy); -}; - struct projection projections[] = { - {"EPSG:4326", lonlat2tile}, - {"EPSG:3857", epsg3857totile}, + {"EPSG:4326", lonlat2tile, "urn:ogc:def:crs:OGC:1.3:CRS84"}, + {"EPSG:3857", epsg3857totile, "urn:ogc:def:crs:EPSG::3857"}, {NULL, NULL}, }; +struct projection *projection = &projections[0]; + int main(int argc, char **argv) { #ifdef MTRACE mtrace(); @@ -1995,7 +1991,11 @@ int main(int argc, char **argv) { struct projection *p; for (p = projections; p->name != NULL; p++) { if (strcmp(p->name, optarg) == 0) { - projection = p->project; + projection = p; + break; + } + if (strcmp(p->alias, optarg) == 0) { + projection = p; break; } } diff --git a/main.hpp b/main.hpp index 9e4c4ed..e842511 100644 --- a/main.hpp +++ b/main.hpp @@ -13,5 +13,3 @@ extern int quiet; extern int CPUS; extern int TEMP_FILES; - -extern void (*projection)(double ix, double iy, int zoom, long long *ox, long long *oy); diff --git a/projection.hpp b/projection.hpp index 8d18b2e..8543aaf 100644 --- a/projection.hpp +++ b/projection.hpp @@ -3,3 +3,11 @@ 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); unsigned long long encode(unsigned int wx, unsigned int wy); void decode(unsigned long long index, unsigned *wx, unsigned *wy); + +struct projection { + const char *name; + void (*project)(double ix, double iy, int zoom, long long *ox, long long *oy); + const char *alias; +}; + +extern struct projection *projection;