diff --git a/geojson.c b/geojson.c index 69d6e67c..d9ff6a5d 100644 --- a/geojson.c +++ b/geojson.c @@ -100,7 +100,7 @@ void serialize_string(FILE *out, const char *s, long long *fpos, const char *fna *fpos += len + 1; } -void parse_geometry(int t, json_object *j, unsigned *bbox, long long *fpos, FILE *out, int op, const char *fname, json_pull *source) { +void parse_geometry(int t, json_object *j, unsigned *bbox, long long *fpos, FILE *out, int op, const char *fname, json_pull *source, long long *wx, long long *wy) { if (j == NULL || j->type != JSON_ARRAY) { fprintf(stderr, "%s:%d: expected array for type %d\n", fname, source->line, t); return; @@ -119,7 +119,7 @@ void parse_geometry(int t, json_object *j, unsigned *bbox, long long *fpos, FILE } } - parse_geometry(within, j->array[i], bbox, fpos, out, op, fname, source); + parse_geometry(within, j->array[i], bbox, fpos, out, op, fname, source, wx, wy); } } else { if (j->length >= 2 && j->array[0]->type == JSON_NUMBER && j->array[1]->type == JSON_NUMBER) { @@ -153,8 +153,10 @@ void parse_geometry(int t, json_object *j, unsigned *bbox, long long *fpos, FILE } serialize_byte(out, op, fpos, fname); - serialize_uint(out, x, fpos, fname); - serialize_uint(out, y, fpos, fname); + serialize_long_long(out, x - *wx, fpos, fname); + serialize_long_long(out, y - *wy, fpos, fname); + *wx = x; + *wy = y; } else { fprintf(stderr, "%s:%d: malformed point\n", fname, source->line); } @@ -652,7 +654,8 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max serialize_byte(geomfile, mb_geometry[t], &geompos, fname); serialize_byte(geomfile, n, &geompos, fname); serialize_long_long(geomfile, metastart, &geompos, fname); - parse_geometry(t, coordinates, bbox, &geompos, geomfile, VT_MOVETO, fname, jp); + long long wx = 0, wy = 0; + parse_geometry(t, coordinates, bbox, &geompos, geomfile, VT_MOVETO, fname, jp, &wx, &wy); serialize_byte(geomfile, VT_END, &geompos, fname); /* diff --git a/geometry.cc b/geometry.cc index de5a4671..6a79dcff 100644 --- a/geometry.cc +++ b/geometry.cc @@ -25,6 +25,8 @@ drawvec decode_geometry(char **meta, int z, unsigned tx, unsigned ty, int detail bbox[2] = LONG_LONG_MIN; bbox[3] = LONG_LONG_MIN; + long long wx = 0, wy = 0; + while (1) { draw d; @@ -34,12 +36,16 @@ drawvec decode_geometry(char **meta, int z, unsigned tx, unsigned ty, int detail } if (d.op == VT_MOVETO || d.op == VT_LINETO) { - unsigned wx, wy; - deserialize_uint(meta, &wx); - deserialize_uint(meta, &wy); + long long dx, dy; - long long wwx = (unsigned) wx; - long long wwy = (unsigned) wy; + deserialize_long_long(meta, &dx); + deserialize_long_long(meta, &dy); + + wx += dx; + wy += dy; + + long long wwx = wx; + long long wwy = wy; if (z != 0) { wwx -= tx << (32 - z); diff --git a/tile.cc b/tile.cc index f01506aa..7c055645 100644 --- a/tile.cc +++ b/tile.cc @@ -506,13 +506,16 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, unsigned *f serialize_byte(geomfile[j], t, &geompos[j], fname); serialize_byte(geomfile[j], layer, &geompos[j], fname); serialize_long_long(geomfile[j], metastart, &geompos[j], fname); + long long wx = 0, wy = 0; for (unsigned u = 0; u < geom.size(); u++) { serialize_byte(geomfile[j], geom[u].op, &geompos[j], fname); if (geom[u].op != VT_CLOSEPATH) { - serialize_uint(geomfile[j], geom[u].x + sx, &geompos[j], fname); - serialize_uint(geomfile[j], geom[u].y + sy, &geompos[j], fname); + serialize_long_long(geomfile[j], geom[u].x + sx - wx, &geompos[j], fname); + serialize_long_long(geomfile[j], geom[u].y + sy - wy, &geompos[j], fname); + wx = geom[u].x + sx; + wy = geom[u].y + sy; } }