Add the option to specify layer file, name, and description as JSON

This commit is contained in:
Eric Fischer 2018-05-24 11:30:42 -07:00
parent 7128ac44d5
commit 53731709b2
3 changed files with 60 additions and 7 deletions

View File

@ -148,6 +148,11 @@ If your input is formatted as newline-delimited GeoJSON, use `-P` to make input
* `-l` _name_ or `--layer=`_name_: Use the specified layer name instead of deriving a name from the input filename or output tileset. If there are multiple input files
specified, the files are all merged into the single named layer, even if they try to specify individual names with `-L`.
* `-L` _name_`:`_file.json_ or `--named-layer=`_name_`:`_file.json_: Specify layer names for individual files. If your shell supports it, you can use a subshell redirect like `-L` _name_`:<(cat dir/*.json)` to specify a layer name for the output of streamed input.
* `-L{`_layer-json_`}` or `--named-layer={`_layer-json_`}`: Specify an input file and layer options by a JSON object. The JSON object must contain a `"file"` key to specify the filename to read from. It may also contain a `"layer"` field to specify the name of the layer, and/or a `"description"` field to specify the layer's description in the tileset metadata. Example:
```
tippecanoe -z5 -o world.mbtiles -L'{"file":"ne_10m_admin_0_countries.json", "layer":"countries", "description":"Natural Earth countries"}'
```
CSV input files currently support only Point geometries, from columns named `latitude`, `longitude`, `lat`, `lon`, `long`, `lng`, `x`, or `y`.

View File

@ -2374,6 +2374,42 @@ void set_attribute_accum(std::map<std::string, attribute_op> &attribute_accum, c
attribute_accum.insert(std::pair<std::string, attribute_op>(name, t));
}
void parse_json_source(const char *arg, struct source &src) {
json_pull *jp = json_begin_string(arg);
json_object *o = json_read_tree(jp);
if (o == NULL) {
fprintf(stderr, "%s: -L%s: %s\n", *av, arg, jp->error);
exit(EXIT_FAILURE);
}
if (o->type != JSON_HASH) {
fprintf(stderr, "%s: -L%s: not a JSON object\n", *av, arg);
exit(EXIT_FAILURE);
}
json_object *fname = json_hash_get(o, "file");
if (fname == NULL || fname->type != JSON_STRING) {
fprintf(stderr, "%s: -L%s: requires \"file\": filename\n", *av, arg);
exit(EXIT_FAILURE);
}
src.file = std::string(fname->string);
json_object *layer = json_hash_get(o, "layer");
if (layer != NULL && layer->type == JSON_STRING) {
src.layer = std::string(layer->string);
}
json_object *description = json_hash_get(o, "description");
if (description != NULL && description->type == JSON_STRING) {
src.description = std::string(description->string);
}
json_free(o);
json_end(jp);
}
int main(int argc, char **argv) {
#ifdef MTRACE
mtrace();
@ -2607,14 +2643,18 @@ int main(int argc, char **argv) {
break;
case 'L': {
char *cp = strchr(optarg, ':');
if (cp == NULL || cp == optarg) {
fprintf(stderr, "%s: -L requires layername:file\n", argv[0]);
exit(EXIT_FAILURE);
}
struct source src;
src.layer = std::string(optarg).substr(0, cp - optarg);
src.file = std::string(cp + 1);
if (optarg[0] == '{') {
parse_json_source(optarg, src);
} else {
char *cp = strchr(optarg, ':');
if (cp == NULL || cp == optarg) {
fprintf(stderr, "%s: -L requires layername:file\n", argv[0]);
exit(EXIT_FAILURE);
}
src.layer = std::string(optarg).substr(0, cp - optarg);
src.file = std::string(cp + 1);
}
sources.push_back(src);
break;
}

View File

@ -159,6 +159,14 @@ or if metadata fields can't be set. You probably don't want to use this.
specified, the files are all merged into the single named layer, even if they try to specify individual names with \fB\fC\-L\fR\&.
.IP \(bu 2
\fB\fC\-L\fR \fIname\fP\fB\fC:\fR\fIfile.json\fP or \fB\fC\-\-named\-layer=\fR\fIname\fP\fB\fC:\fR\fIfile.json\fP: Specify layer names for individual files. If your shell supports it, you can use a subshell redirect like \fB\fC\-L\fR \fIname\fP\fB\fC:<(cat dir/*.json)\fR to specify a layer name for the output of streamed input.
.IP \(bu 2
\fB\fC\-L{\fR\fIlayer\-json\fP\fB\fC}\fR or \fB\fC\-\-named\-layer={\fR\fIlayer\-json\fP\fB\fC}\fR: Specify an input file and layer options by a JSON object. The JSON object must contain a \fB\fC"file"\fR key to specify the filename to read from. It may also contain a \fB\fC"layer"\fR field to specify the name of the layer, and/or a \fB\fC"description"\fR field to specify the layer's description in the tileset metadata. Example:
.RE
.PP
.RS
.nf
tippecanoe \-z5 \-o world.mbtiles \-L'{"file":"ne_10m_admin_0_countries.json", "layer":"countries", "description":"Natural Earth countries"}'
.fi
.RE
.PP
CSV input files currently support only Point geometries, from columns named \fB\fClatitude\fR, \fB\fClongitude\fR, \fB\fClat\fR, \fB\fClon\fR, \fB\fClong\fR, \fB\fClng\fR, \fB\fCx\fR, or \fB\fCy\fR\&.