mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-05 09:55:41 +02:00
Factor out the JSON token reading loop
This commit is contained in:
@@ -598,6 +598,118 @@ int serialize_geometry(json_object *geometry, json_object *properties, const cha
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parse_json(json_pull *jp, const char *reading, long long *seq, long long *metapos, long long *geompos, long long *indexpos, struct pool *exclude, struct pool *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, char *fname, int maxzoom, int layer, double droprate, unsigned *file_bbox) {
|
||||||
|
long long found_hashes = 0;
|
||||||
|
long long found_features = 0;
|
||||||
|
long long found_geometries = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
json_object *j = json_read(jp);
|
||||||
|
if (j == NULL) {
|
||||||
|
if (jp->error != NULL) {
|
||||||
|
fprintf(stderr, "%s:%d: %s\n", reading, jp->line, jp->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_free(jp->root);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j->type == JSON_HASH) {
|
||||||
|
found_hashes++;
|
||||||
|
|
||||||
|
if (found_hashes == 50 && found_features == 0 && found_geometries == 0) {
|
||||||
|
fprintf(stderr, "%s:%d: Warning: not finding any GeoJSON features or geometries in input yet after 50 objects.\n", reading, jp->line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *type = json_hash_get(j, "type");
|
||||||
|
if (type == NULL || type->type != JSON_STRING) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_features == 0) {
|
||||||
|
int i;
|
||||||
|
int is_geometry = 0;
|
||||||
|
for (i = 0; i < GEOM_TYPES; i++) {
|
||||||
|
if (strcmp(type->string, geometry_names[i]) == 0) {
|
||||||
|
is_geometry = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_geometry) {
|
||||||
|
if (j->parent != NULL) {
|
||||||
|
if (j->parent->type == JSON_ARRAY) {
|
||||||
|
if (j->parent->parent->type == JSON_HASH) {
|
||||||
|
json_object *geometries = json_hash_get(j->parent->parent, "geometries");
|
||||||
|
if (geometries != NULL) {
|
||||||
|
// Parent of Parent must be a GeometryCollection
|
||||||
|
is_geometry = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (j->parent->type == JSON_HASH) {
|
||||||
|
json_object *geometry = json_hash_get(j->parent, "geometry");
|
||||||
|
if (geometry != NULL) {
|
||||||
|
// Parent must be a Feature
|
||||||
|
is_geometry = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_geometry) {
|
||||||
|
if (found_features != 0 && found_geometries == 0) {
|
||||||
|
fprintf(stderr, "%s:%d: Warning: found a mixture of features and bare geometries\n", reading, jp->line);
|
||||||
|
}
|
||||||
|
found_geometries++;
|
||||||
|
|
||||||
|
serialize_geometry(j, NULL, reading, jp, seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox, NULL);
|
||||||
|
json_free(j);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(type->string, "Feature") != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_features == 0 && found_geometries != 0) {
|
||||||
|
fprintf(stderr, "%s:%d: Warning: found a mixture of features and bare geometries\n", reading, jp->line);
|
||||||
|
}
|
||||||
|
found_features++;
|
||||||
|
|
||||||
|
json_object *geometry = json_hash_get(j, "geometry");
|
||||||
|
if (geometry == NULL) {
|
||||||
|
fprintf(stderr, "%s:%d: feature with no geometry\n", reading, jp->line);
|
||||||
|
json_free(j);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *properties = json_hash_get(j, "properties");
|
||||||
|
if (properties == NULL || (properties->type != JSON_HASH && properties->type != JSON_NULL)) {
|
||||||
|
fprintf(stderr, "%s:%d: feature without properties hash\n", reading, jp->line);
|
||||||
|
json_free(j);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *tippecanoe = json_hash_get(j, "tippecanoe");
|
||||||
|
|
||||||
|
json_object *geometries = json_hash_get(geometry, "geometries");
|
||||||
|
if (geometries != NULL) {
|
||||||
|
int g;
|
||||||
|
for (g = 0; g < geometries->length; g++) {
|
||||||
|
serialize_geometry(geometries->array[g], properties, reading, jp, seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox, tippecanoe);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
serialize_geometry(geometry, properties, reading, jp, seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox, tippecanoe);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_free(j);
|
||||||
|
|
||||||
|
/* XXX check for any non-features in the outer object */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int read_json(int argc, char **argv, char *fname, const char *layername, int maxzoom, int minzoom, sqlite3 *outdb, struct pool *exclude, struct pool *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, char *prevent, char *additional) {
|
int read_json(int argc, char **argv, char *fname, const char *layername, int maxzoom, int minzoom, sqlite3 *outdb, struct pool *exclude, struct pool *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, char *prevent, char *additional) {
|
||||||
int ret = EXIT_SUCCESS;
|
int ret = EXIT_SUCCESS;
|
||||||
|
|
||||||
@@ -694,9 +806,6 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
json_pull *jp;
|
json_pull *jp;
|
||||||
const char *reading;
|
const char *reading;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
long long found_hashes = 0;
|
|
||||||
long long found_features = 0;
|
|
||||||
long long found_geometries = 0;
|
|
||||||
|
|
||||||
if (layer >= argc) {
|
if (layer >= argc) {
|
||||||
reading = "standard input";
|
reading = "standard input";
|
||||||
@@ -712,111 +821,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
|
|
||||||
jp = json_begin_file(fp);
|
jp = json_begin_file(fp);
|
||||||
|
|
||||||
while (1) {
|
parse_json(jp, reading, &seq, &metapos, &geompos, &indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox);
|
||||||
json_object *j = json_read(jp);
|
|
||||||
if (j == NULL) {
|
|
||||||
if (jp->error != NULL) {
|
|
||||||
fprintf(stderr, "%s:%d: %s\n", reading, jp->line, jp->error);
|
|
||||||
}
|
|
||||||
|
|
||||||
json_free(jp->root);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j->type == JSON_HASH) {
|
|
||||||
found_hashes++;
|
|
||||||
|
|
||||||
if (found_hashes == 50 && found_features == 0 && found_geometries == 0) {
|
|
||||||
fprintf(stderr, "%s:%d: Warning: not finding any GeoJSON features or geometries in input yet after 50 objects.\n", reading, jp->line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
json_object *type = json_hash_get(j, "type");
|
|
||||||
if (type == NULL || type->type != JSON_STRING) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_features == 0) {
|
|
||||||
int i;
|
|
||||||
int is_geometry = 0;
|
|
||||||
for (i = 0; i < GEOM_TYPES; i++) {
|
|
||||||
if (strcmp(type->string, geometry_names[i]) == 0) {
|
|
||||||
is_geometry = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_geometry) {
|
|
||||||
if (j->parent != NULL) {
|
|
||||||
if (j->parent->type == JSON_ARRAY) {
|
|
||||||
if (j->parent->parent->type == JSON_HASH) {
|
|
||||||
json_object *geometries = json_hash_get(j->parent->parent, "geometries");
|
|
||||||
if (geometries != NULL) {
|
|
||||||
// Parent of Parent must be a GeometryCollection
|
|
||||||
is_geometry = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (j->parent->type == JSON_HASH) {
|
|
||||||
json_object *geometry = json_hash_get(j->parent, "geometry");
|
|
||||||
if (geometry != NULL) {
|
|
||||||
// Parent must be a Feature
|
|
||||||
is_geometry = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_geometry) {
|
|
||||||
if (found_features != 0 && found_geometries == 0) {
|
|
||||||
fprintf(stderr, "%s:%d: Warning: found a mixture of features and bare geometries\n", reading, jp->line);
|
|
||||||
}
|
|
||||||
found_geometries++;
|
|
||||||
|
|
||||||
serialize_geometry(j, NULL, reading, jp, &seq, &metapos, &geompos, &indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox, NULL);
|
|
||||||
json_free(j);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(type->string, "Feature") != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_features == 0 && found_geometries != 0) {
|
|
||||||
fprintf(stderr, "%s:%d: Warning: found a mixture of features and bare geometries\n", reading, jp->line);
|
|
||||||
}
|
|
||||||
found_features++;
|
|
||||||
|
|
||||||
json_object *geometry = json_hash_get(j, "geometry");
|
|
||||||
if (geometry == NULL) {
|
|
||||||
fprintf(stderr, "%s:%d: feature with no geometry\n", reading, jp->line);
|
|
||||||
json_free(j);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_object *properties = json_hash_get(j, "properties");
|
|
||||||
if (properties == NULL || (properties->type != JSON_HASH && properties->type != JSON_NULL)) {
|
|
||||||
fprintf(stderr, "%s:%d: feature without properties hash\n", reading, jp->line);
|
|
||||||
json_free(j);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_object *tippecanoe = json_hash_get(j, "tippecanoe");
|
|
||||||
|
|
||||||
json_object *geometries = json_hash_get(geometry, "geometries");
|
|
||||||
if (geometries != NULL) {
|
|
||||||
int g;
|
|
||||||
for (g = 0; g < geometries->length; g++) {
|
|
||||||
serialize_geometry(geometries->array[g], properties, reading, jp, &seq, &metapos, &geompos, &indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox, tippecanoe);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
serialize_geometry(geometry, properties, reading, jp, &seq, &metapos, &geompos, &indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, layer, droprate, file_bbox, tippecanoe);
|
|
||||||
}
|
|
||||||
|
|
||||||
json_free(j);
|
|
||||||
|
|
||||||
/* XXX check for any non-features in the outer object */
|
|
||||||
}
|
|
||||||
|
|
||||||
json_end(jp);
|
json_end(jp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|||||||
Reference in New Issue
Block a user