mirror of
https://github.com/mapbox/tippecanoe.git
synced 2025-03-25 05:15:16 +00:00
Simplify the filter format, and actually run the filter.
This commit is contained in:
parent
7be21f6046
commit
5878213516
@ -482,7 +482,14 @@ The options are:
|
||||
|
||||
* `-x` *key* or `--exclude=`*key*: Remove attributes of type *key* from the output. You can use this to remove the field you are matching against if you no longer need it after joining, or to remove any other attributes you don't want.
|
||||
* `-i` or `--if-matched`: Only include features that matched the CSV.
|
||||
* `-J` *filter-file* or `--gl-filter-file`=*filter-file*: Check features against a per-layer filter (as defined in the [Mapbox GL Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#types-filter)) and only include those that match.
|
||||
* `-j` *filter* or `--gl-filter`=*filter*: Check features against a per-layer filter (as defined in the [Mapbox GL Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#types-filter)) and only include those that match. Any features in layers that have no filter specified will be passed through.
|
||||
* `-J` *filter-file* or `--gl-filter-file`=*filter-file*: Like `-j`, but read the filter from a file.
|
||||
|
||||
Example: to find the Natural Earth countries with low `scalerank` but high `LABELRANK`:
|
||||
|
||||
```
|
||||
tile-join -o filtered.mbtiles -j '{ "ne_10m_admin_0_countries": [ "all", [ "<", "scalerank", 3 ], [ ">", "LABELRANK", 5 ] ] }' ne_10m_admin_0_countries.mbtiles
|
||||
```
|
||||
|
||||
### Setting or disabling tile size limits
|
||||
|
||||
|
@ -174,19 +174,7 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f) {
|
||||
}
|
||||
|
||||
bool evaluate(std::map<std::string, mvt_value> const &feature, std::string const &layer, json_object *filter) {
|
||||
json_object *layers = json_hash_get(filter, "layers");
|
||||
|
||||
if (layers == NULL) {
|
||||
fprintf(stderr, "Filter: no \"layers\" key at top level\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (layers->type != JSON_HASH) {
|
||||
fprintf(stderr, "Filter: \"layers\" is not a hash\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
json_object *f = json_hash_get(layers, layer.c_str());
|
||||
json_object *f = json_hash_get(filter, layer.c_str());
|
||||
|
||||
if (f != NULL) {
|
||||
return eval(feature, f);
|
||||
|
@ -6,6 +6,6 @@
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "mvt.hpp"
|
||||
|
||||
bool evaluate(std::map<std::string, mvt_value> const &feature, std::string const &layer, json_pull *filter);
|
||||
bool evaluate(std::map<std::string, mvt_value> const &feature, std::string const &layer, json_object *filter);
|
||||
|
||||
#endif
|
||||
|
@ -69,7 +69,7 @@ json_pull *json_begin_file(FILE *f) {
|
||||
}
|
||||
|
||||
static ssize_t read_string(json_pull *j, char *buffer, size_t n) {
|
||||
char *cp = j->source;
|
||||
const char *cp = j->source;
|
||||
size_t out = 0;
|
||||
|
||||
while (out < n && cp[out] != '\0') {
|
||||
@ -81,7 +81,7 @@ static ssize_t read_string(json_pull *j, char *buffer, size_t n) {
|
||||
return out;
|
||||
}
|
||||
|
||||
json_pull *json_begin_string(char *s) {
|
||||
json_pull *json_begin_string(const char *s) {
|
||||
return json_begin(read_string, s);
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ typedef struct json_pull {
|
||||
int line;
|
||||
|
||||
ssize_t (*read)(struct json_pull *, char *buf, size_t n);
|
||||
void *source;
|
||||
const void *source;
|
||||
char *buffer;
|
||||
ssize_t buffer_tail;
|
||||
ssize_t buffer_head;
|
||||
@ -56,7 +56,7 @@ typedef struct json_pull {
|
||||
} json_pull;
|
||||
|
||||
json_pull *json_begin_file(FILE *f);
|
||||
json_pull *json_begin_string(char *s);
|
||||
json_pull *json_begin_string(const char *s);
|
||||
|
||||
json_pull *json_begin(ssize_t (*read)(struct json_pull *, char *buffer, size_t n), void *source);
|
||||
void json_end(json_pull *p);
|
||||
|
@ -566,6 +566,18 @@ The options are:
|
||||
\fB\fC\-x\fR \fIkey\fP or \fB\fC\-\-exclude=\fR\fIkey\fP: Remove attributes of type \fIkey\fP from the output. You can use this to remove the field you are matching against if you no longer need it after joining, or to remove any other attributes you don't want.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-i\fR or \fB\fC\-\-if\-matched\fR: Only include features that matched the CSV.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-j\fR \fIfilter\fP or \fB\fC\-\-gl\-filter\fR=\fIfilter\fP: Check features against a per\-layer filter (as defined in the Mapbox GL Style Specification \[la]https://www.mapbox.com/mapbox-gl-js/style-spec/#types-filter\[ra]) and only include those that match. Any features in layers that have no filter specified will be passed through.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-J\fR \fIfilter\-file\fP or \fB\fC\-\-gl\-filter\-file\fR=\fIfilter\-file\fP: Like \fB\fC\-j\fR, but read the filter from a file.
|
||||
.RE
|
||||
.PP
|
||||
Example: to find the Natural Earth countries with low \fB\fCscalerank\fR but high \fB\fCLABELRANK\fR:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
tile\-join \-o filtered.mbtiles \-j '{ "ne_10m_admin_0_countries": [ "all", [ "<", "scalerank", 3 ], [ ">", "LABELRANK", 5 ] ] }' ne_10m_admin_0_countries.mbtiles
|
||||
.fi
|
||||
.RE
|
||||
.SS Setting or disabling tile size limits
|
||||
.RS
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "mbtiles.hpp"
|
||||
#include "geometry.hpp"
|
||||
#include "dirtiles.hpp"
|
||||
#include "evaluator.hpp"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
@ -130,6 +131,10 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::map<std::st
|
||||
}
|
||||
|
||||
attributes.insert(std::pair<std::string, mvt_value>("$type", v));
|
||||
|
||||
if (!evaluate(attributes, layer.name, filter)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
mvt_feature outfeature;
|
||||
@ -1050,6 +1055,19 @@ json_object *read_filter(const char *fname) {
|
||||
return filter;
|
||||
}
|
||||
|
||||
json_object *parse_filter(const char *s) {
|
||||
json_pull *jp = json_begin_string(s);
|
||||
json_object *filter = json_read_tree(jp);
|
||||
if (filter == NULL) {
|
||||
fprintf(stderr, "Could not parse filter %s\n", s);
|
||||
fprintf(stderr, "%s\n", jp->error);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// XXX clone tree instead of leaving pull open
|
||||
return filter;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *out_mbtiles = NULL;
|
||||
char *out_dir = NULL;
|
||||
@ -1095,6 +1113,7 @@ int main(int argc, char **argv) {
|
||||
{"maximum-zoom", required_argument, 0, 'z'},
|
||||
{"minimum-zoom", required_argument, 0, 'Z'},
|
||||
{"gl-filter-file", required_argument, 0, 'J'},
|
||||
{"gl-filter", required_argument, 0, 'j'},
|
||||
|
||||
{"no-tile-size-limit", no_argument, &pk, 1},
|
||||
{"no-tile-compression", no_argument, &pC, 1},
|
||||
@ -1163,6 +1182,10 @@ int main(int argc, char **argv) {
|
||||
filter = read_filter(optarg);
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
filter = parse_filter(optarg);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (strcmp(optarg, "k") == 0) {
|
||||
pk = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user