Provide some JSON context when reporting parsing errors

This commit is contained in:
Eric Fischer 2016-08-15 13:11:35 -07:00
parent 475ce9dd23
commit b2aa6de898
3 changed files with 38 additions and 9 deletions

View File

@ -1,3 +1,7 @@
## 1.12.9
* Clean up parsing and serialization. Provide some context with parsing errors.
## 1.12.8 ## 1.12.8
* Fix the spelling of the --preserve-input-order option * Fix the spelling of the --preserve-input-order option

View File

@ -63,11 +63,23 @@ static int mb_geometry[GEOM_TYPES] = {
VT_POINT, VT_POINT, VT_LINE, VT_LINE, VT_POLYGON, VT_POLYGON, VT_POINT, VT_POINT, VT_LINE, VT_LINE, VT_POLYGON, VT_POLYGON,
}; };
long long parse_geometry(int t, json_object *j, long long *bbox, drawvec &out, int op, const char *fname, int line, int *initialized, unsigned *initial_x, unsigned *initial_y) { void json_context(json_object *j) {
char *s = json_stringify(j);
if (strlen(s) >= 500) {
sprintf(s + 497, "...");
}
fprintf(stderr, "In JSON object %s\n", s);
free(s);
}
long long parse_geometry(int t, json_object *j, long long *bbox, drawvec &out, int op, const char *fname, int line, int *initialized, unsigned *initial_x, unsigned *initial_y, json_object *feature) {
long long g = 0; long long g = 0;
if (j == NULL || j->type != JSON_ARRAY) { if (j == NULL || j->type != JSON_ARRAY) {
fprintf(stderr, "%s:%d: expected array for type %d\n", fname, line, t); fprintf(stderr, "%s:%d: expected array for type %d\n", fname, line, t);
json_context(feature);
return g; return g;
} }
@ -83,7 +95,7 @@ long long parse_geometry(int t, json_object *j, long long *bbox, drawvec &out, i
} }
} }
g += parse_geometry(within, j->array[i], bbox, out, op, fname, line, initialized, initial_x, initial_y); g += parse_geometry(within, j->array[i], bbox, out, op, fname, line, initialized, initial_x, initial_y, feature);
} }
} 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) {
@ -97,6 +109,8 @@ long long parse_geometry(int t, json_object *j, long long *bbox, drawvec &out, i
if (!warned) { if (!warned) {
fprintf(stderr, "%s:%d: ignoring dimensions beyond two\n", fname, line); fprintf(stderr, "%s:%d: ignoring dimensions beyond two\n", fname, line);
json_context(j);
json_context(feature);
warned = 1; warned = 1;
} }
} }
@ -131,6 +145,8 @@ long long parse_geometry(int t, json_object *j, long long *bbox, drawvec &out, i
g++; g++;
} else { } else {
fprintf(stderr, "%s:%d: malformed point\n", fname, line); fprintf(stderr, "%s:%d: malformed point\n", fname, line);
json_context(j);
json_context(feature);
} }
} }
@ -150,12 +166,13 @@ long long parse_geometry(int t, json_object *j, long long *bbox, drawvec &out, i
return g; return g;
} }
int serialize_geometry(json_object *geometry, json_object *properties, json_object *id, const char *reading, int line, volatile long long *layer_seq, volatile long long *progress_seq, long long *metapos, long long *geompos, long long *indexpos, std::set<std::string> *exclude, std::set<std::string> *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, const char *fname, int basezoom, int layer, double droprate, long long *file_bbox, json_object *tippecanoe, int segment, int *initialized, unsigned *initial_x, unsigned *initial_y, struct reader *readers, std::set<type_and_string> *file_keys, int maxzoom) { int serialize_geometry(json_object *geometry, json_object *properties, json_object *id, const char *reading, int line, volatile long long *layer_seq, volatile long long *progress_seq, long long *metapos, long long *geompos, long long *indexpos, std::set<std::string> *exclude, std::set<std::string> *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, const char *fname, int basezoom, int layer, double droprate, long long *file_bbox, json_object *tippecanoe, int segment, int *initialized, unsigned *initial_x, unsigned *initial_y, struct reader *readers, std::set<type_and_string> *file_keys, int maxzoom, json_object *feature) {
json_object *geometry_type = json_hash_get(geometry, "type"); json_object *geometry_type = json_hash_get(geometry, "type");
if (geometry_type == NULL) { if (geometry_type == NULL) {
static int warned = 0; static int warned = 0;
if (!warned) { if (!warned) {
fprintf(stderr, "%s:%d: null geometry (additional not reported)\n", reading, line); fprintf(stderr, "%s:%d: null geometry (additional not reported)\n", reading, line);
json_context(feature);
warned = 1; warned = 1;
} }
@ -163,13 +180,15 @@ int serialize_geometry(json_object *geometry, json_object *properties, json_obje
} }
if (geometry_type->type != JSON_STRING) { if (geometry_type->type != JSON_STRING) {
fprintf(stderr, "%s:%d: geometry without type\n", reading, line); fprintf(stderr, "%s:%d: geometry type is not a string\n", reading, line);
json_context(feature);
return 0; return 0;
} }
json_object *coordinates = json_hash_get(geometry, "coordinates"); json_object *coordinates = json_hash_get(geometry, "coordinates");
if (coordinates == NULL || coordinates->type != JSON_ARRAY) { if (coordinates == NULL || coordinates->type != JSON_ARRAY) {
fprintf(stderr, "%s:%d: feature without coordinates array\n", reading, line); fprintf(stderr, "%s:%d: feature without coordinates array\n", reading, line);
json_context(feature);
return 0; return 0;
} }
@ -181,6 +200,7 @@ int serialize_geometry(json_object *geometry, json_object *properties, json_obje
} }
if (t >= GEOM_TYPES) { if (t >= GEOM_TYPES) {
fprintf(stderr, "%s:%d: Can't handle geometry type %s\n", reading, line, geometry_type->string); fprintf(stderr, "%s:%d: Can't handle geometry type %s\n", reading, line, geometry_type->string);
json_context(feature);
return 0; return 0;
} }
@ -288,7 +308,7 @@ int serialize_geometry(json_object *geometry, json_object *properties, json_obje
} }
drawvec dv; drawvec dv;
long long g = parse_geometry(t, coordinates, bbox, dv, VT_MOVETO, fname, line, initialized, initial_x, initial_y); long long g = parse_geometry(t, coordinates, bbox, dv, VT_MOVETO, fname, line, initialized, initial_x, initial_y, feature);
if (mb_geometry[t] == VT_POLYGON) { if (mb_geometry[t] == VT_POLYGON) {
dv = fix_polygon(dv); dv = fix_polygon(dv);
} }
@ -440,6 +460,9 @@ void parse_json(json_pull *jp, const char *reading, volatile long long *layer_se
if (j == NULL) { if (j == NULL) {
if (jp->error != NULL) { if (jp->error != NULL) {
fprintf(stderr, "%s:%d: %s\n", reading, jp->line, jp->error); fprintf(stderr, "%s:%d: %s\n", reading, jp->line, jp->error);
if (jp->root != NULL) {
json_context(jp->root);
}
} }
json_free(jp->root); json_free(jp->root);
@ -495,7 +518,7 @@ void parse_json(json_pull *jp, const char *reading, volatile long long *layer_se
} }
found_geometries++; found_geometries++;
serialize_geometry(j, NULL, NULL, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, basezoom, layer, droprate, file_bbox, NULL, segment, initialized, initial_x, initial_y, readers, file_keys, maxzoom); serialize_geometry(j, NULL, NULL, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, basezoom, layer, droprate, file_bbox, NULL, segment, initialized, initial_x, initial_y, readers, file_keys, maxzoom, j);
json_free(j); json_free(j);
continue; continue;
} }
@ -517,6 +540,7 @@ void parse_json(json_pull *jp, const char *reading, volatile long long *layer_se
json_object *geometry = json_hash_get(j, "geometry"); json_object *geometry = json_hash_get(j, "geometry");
if (geometry == NULL) { if (geometry == NULL) {
fprintf(stderr, "%s:%d: feature with no geometry\n", reading, jp->line); fprintf(stderr, "%s:%d: feature with no geometry\n", reading, jp->line);
json_context(j);
json_free(j); json_free(j);
continue; continue;
} }
@ -524,6 +548,7 @@ void parse_json(json_pull *jp, const char *reading, volatile long long *layer_se
json_object *properties = json_hash_get(j, "properties"); json_object *properties = json_hash_get(j, "properties");
if (properties == NULL || (properties->type != JSON_HASH && properties->type != JSON_NULL)) { if (properties == NULL || (properties->type != JSON_HASH && properties->type != JSON_NULL)) {
fprintf(stderr, "%s:%d: feature without properties hash\n", reading, jp->line); fprintf(stderr, "%s:%d: feature without properties hash\n", reading, jp->line);
json_context(j);
json_free(j); json_free(j);
continue; continue;
} }
@ -535,10 +560,10 @@ void parse_json(json_pull *jp, const char *reading, volatile long long *layer_se
if (geometries != NULL) { if (geometries != NULL) {
size_t g; size_t g;
for (g = 0; g < geometries->length; g++) { for (g = 0; g < geometries->length; g++) {
serialize_geometry(geometries->array[g], properties, id, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, basezoom, layer, droprate, file_bbox, tippecanoe, segment, initialized, initial_x, initial_y, readers, file_keys, maxzoom); serialize_geometry(geometries->array[g], properties, id, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, basezoom, layer, droprate, file_bbox, tippecanoe, segment, initialized, initial_x, initial_y, readers, file_keys, maxzoom, j);
} }
} else { } else {
serialize_geometry(geometry, properties, id, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, basezoom, layer, droprate, file_bbox, tippecanoe, segment, initialized, initial_x, initial_y, readers, file_keys, maxzoom); serialize_geometry(geometry, properties, id, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, basezoom, layer, droprate, file_bbox, tippecanoe, segment, initialized, initial_x, initial_y, readers, file_keys, maxzoom, j);
} }
json_free(j); json_free(j);

View File

@ -1 +1 @@
#define VERSION "tippecanoe v1.12.8\n" #define VERSION "tippecanoe v1.12.9\n"