diff --git a/geojson.c b/geojson.c index 8d02bc3..95581d0 100644 --- a/geojson.c +++ b/geojson.c @@ -301,7 +301,7 @@ void range_search(struct index *ix, long long n, unsigned long long start, unsig } } -void check(struct index *ix, long long n, char *metabase, unsigned *file_bbox) { +void check(struct index *ix, long long n, char *metabase, unsigned *file_bbox, struct pool *file_keys) { fprintf(stderr, "\n"); int z; @@ -336,12 +336,25 @@ void check(struct index *ix, long long n, char *metabase, unsigned *file_bbox) { printf("%d/%u/%u %x %x %lld to %lld\n", z, tx, ty, wx, wy, (long long)(i - ix), (long long)(j - ix)); - write_tile(i, j, metabase, file_bbox, z, tx, ty, z == BASE_ZOOM ? 12 : 10, BASE_ZOOM); + write_tile(i, j, metabase, file_bbox, z, tx, ty, z == BASE_ZOOM ? 12 : 10, BASE_ZOOM, file_keys); } } } -void read_json(FILE *f) { +void quote(FILE *fp, char *s) { + for (; *s != '\0'; s++) { + if (*s == '\\' || *s == '\"') { + fputc('\\', fp); + fputc(*s, fp); + } else if (*s < ' ') { + fprintf(fp, "\\u%04x", *s); + } else { + fputc(*s, fp); + } + } +} + +void read_json(FILE *f, char *fname) { char metaname[] = "/tmp/meta.XXXXXXXX"; char indexname[] = "/tmp/index.XXXXXXXX"; @@ -529,14 +542,73 @@ next_feature: exit(EXIT_FAILURE); } + struct pool file_keys; + file_keys.n = 0; + file_keys.vals = NULL; + file_keys.head = NULL; + file_keys.tail = NULL; + qsort(index, indexst.st_size / sizeof(struct index), sizeof(struct index), indexcmp); - check(index, indexst.st_size / sizeof(struct index), meta, file_bbox); + check(index, indexst.st_size / sizeof(struct index), meta, file_bbox, &file_keys); munmap(index, indexst.st_size); munmap(meta, metast.st_size); close(indexfd); close(metafd); + + FILE *fp = fopen("tiles/metadata.json", "w"); + if (fp == NULL) { + fprintf(stderr, "metadata.json: %s\n", strerror(errno)); + } else { + fprintf(fp, "{\n"); + + fprintf(fp, "\"name\": \""); + quote(fp, fname); + fprintf(fp, "\",\n"); + + fprintf(fp, "\"description\": \""); + quote(fp, fname); + fprintf(fp, "\",\n"); + + double minlat = 0, minlon = 0, maxlat = 0, maxlon = 0, midlat = 0, midlon = 0; + + fprintf(fp, "\"version\": 1,\n"); + fprintf(fp, "\"minzoom\": %d,\n", 0); + fprintf(fp, "\"maxzoom\": %d,\n", BASE_ZOOM); + fprintf(fp, "\"center\": \"%f,%f,%d\",\n", midlon, midlat, BASE_ZOOM); + fprintf(fp, "\"bounds\": \"%f,%f,%f,%f\",\n", minlon, minlat, maxlon, maxlat); + fprintf(fp, "\"type\": \"overlay\",\n"); + + fprintf(fp, "\"json\": \"{"); + fprintf(fp, "\\\"vector_layers\\\": [ { \\\"id\\\": \\\""); + quote(fp, "name"); + fprintf(fp, "\\\", \\\"description\\\": \\\"\\\", \\\"minzoom\\\": %d, \\\"maxzoom\\\": %d, \\\"fields\\\": {", 0, BASE_ZOOM); + + struct pool_val *pv; + for (pv = file_keys.head; pv != NULL; pv = pv->next) { + fprintf(fp, "\\\""); + quote(fp, pv->s); + + if (pv->type == VT_NUMBER) { + fprintf(fp, "\\\": \\\"Number\\\""); + } else { + fprintf(fp, "\\\": \\\"String\\\""); + } + + if (pv->next != NULL) { + fprintf(fp, ", "); + } + } + + fprintf(fp, "} } ]"); + fprintf(fp, "}\",\n"); + + fprintf(fp, "\"format\": \"%s\"\n", "pbf"); // no trailing comma + fprintf(fp, "}\n"); + + fclose(fp); + } } int main(int argc, char **argv) { @@ -547,12 +619,12 @@ int main(int argc, char **argv) { if (f == NULL) { fprintf(stderr, "%s: %s: %s\n", argv[0], argv[i], strerror(errno)); } else { - read_json(f); + read_json(f, argv[i]); fclose(f); } } } else { - read_json(stdin); + read_json(stdin, "standard input"); } return 0; } diff --git a/tile.cc b/tile.cc index 9d28229..5f6656f 100644 --- a/tile.cc +++ b/tile.cc @@ -122,7 +122,7 @@ int draw(char **meta, mapnik::vector::tile_feature *feature, int z, unsigned tx, } -void write_tile(struct index *start, struct index *end, char *metabase, unsigned *file_bbox, int z, unsigned tx, unsigned ty, int detail, int basezoom) { +void write_tile(struct index *start, struct index *end, char *metabase, unsigned *file_bbox, int z, unsigned tx, unsigned ty, int detail, int basezoom, struct pool *file_keys) { GOOGLE_PROTOBUF_VERIFY_VERSION; mapnik::vector::tile tile; @@ -199,6 +199,9 @@ void write_tile(struct index *start, struct index *end, char *metabase, unsigned feature->add_tags(key->n); feature->add_tags(value->n); + + // Dup to retain after munmap + pool(file_keys, strdup(key->s), t); } } } diff --git a/tile.h b/tile.h index 5ecd231..8ff23d5 100644 --- a/tile.h +++ b/tile.h @@ -36,6 +36,7 @@ struct pool { void deserialize_int(char **f, int *n); struct pool_val *deserialize_string(char **f, struct pool *p, int type); +struct pool_val *pool(struct pool *p, char *s, int type); void pool_free(struct pool *p); @@ -47,4 +48,4 @@ struct index { }; -void write_tile(struct index *start, struct index *end, char *metabase, unsigned *file_bbox, int z, unsigned x, unsigned y, int detail, int basezoom); +void write_tile(struct index *start, struct index *end, char *metabase, unsigned *file_bbox, int z, unsigned x, unsigned y, int detail, int basezoom, struct pool *file_keys);