diff --git a/.gitignore b/.gitignore index 9cea8328c..9f2b22afb 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ tile-join tippecanoe-decode tippecanoe-enumerate tippecanoe-json-tool +tippecanoe-overzoom unit # Tests diff --git a/README.md b/README.md index 6a1c85570..a344a2cce 100644 --- a/README.md +++ b/README.md @@ -409,8 +409,9 @@ be reduced to the maximum that can be used with the specified _maxzoom_. * `-Y`_attribute_`:`_description_ or `--attribute-description=`_attribute_`:`_description_: Set the `description` for the specified attribute in the tileset metadata to _description_ instead of the usual `String`, `Number`, or `Boolean`. * `-E`_attribute_`:`_operation_ or `--accumulate-attribute=`_attribute_`:`_operation_: Preserve the named _attribute_ from features that are dropped, coalesced-as-needed, or clustered. The _operation_ may be - `sum`, `product`, `mean`, `max`, `min`, `concat`, or `comma` + `sum`, `product`, `mean`, `max`, `min`, `and`, `or`, `concat`, or `comma` to specify how the named _attribute_ is accumulated onto the attribute of the same name in a feature that does survive. + Note, that `and` and `or` are only intended for boolean input. The attributes and operations may also be specified as JSON keys and values: `--accumulate-attribute='{"attr": "operation", "attr2", "operation2"}'`. * `--set-attribute` _attribute_`:`_value_: Set the value of the specified _attribute_ in each feature to the specified _value_. This is mostly useful to give an attribute in each feature an initial value for `--accumulate-attribute`. The attributes and values may also be specified as JSON keys and values: `--set-attribute='{"attr": value, "attr2", value}'`. diff --git a/main.cpp b/main.cpp index 2c303a99e..4e5d38f80 100644 --- a/main.cpp +++ b/main.cpp @@ -2885,12 +2885,16 @@ void set_attribute_accum(std::map &attribute_accum, s t = op_max; } else if (type == "min") { t = op_min; + } else if (type == "or") { + t = op_or; + } else if (type == "and") { + t = op_and; } else if (type == "concat") { t = op_concat; } else if (type == "comma") { t = op_comma; } else { - fprintf(stderr, "Attribute method (%s) must be sum, product, mean, max, min, concat, or comma\n", type.c_str()); + fprintf(stderr, "Attribute method (%s) must be sum, product, mean, max, min, or, and, concat, or comma\n", type.c_str()); exit(EXIT_ARGS); } diff --git a/tile.cpp b/tile.cpp index d94b1493a..7690c56e8 100644 --- a/tile.cpp +++ b/tile.cpp @@ -1728,6 +1728,32 @@ void add_tilestats(std::string const &layername, int z, std::vectorsecond.file_keys, key, attrib); } +// parse boolean values +// "true" -> true +// "false" -> false +// Anything else is parsed as numeric value using atof; +// - if it is not 0 -> true +// - if it is 0 (including somethign not parsable, e.g. "foo" or "True") -> false +bool atob(const char* str) { + if (0 == strcmp(str, "true")) { + return true; + } + if (0 == strcmp(str, "false")) { + return false; + } + const double floating_point_value = atof(str); + return floating_point_value != 0; +} + +std::string btoa(bool value) { + if (value) { + return "true"; + } + else { + return "false"; + } +} + void preserve_attribute(attribute_op op, serial_feature &, char *stringpool, long long *pool_off, std::string &key, serial_val &val, partial &p) { if (p.need_tilestats.count(key) == 0) { p.need_tilestats.insert(key); @@ -1785,6 +1811,16 @@ void preserve_attribute(attribute_op op, serial_feature &, char *stringpool, lon break; } + case op_or: + p.full_values[i].s = btoa(atob(p.full_values[i].s.c_str()) || atob(val.s.c_str())); + p.full_values[i].type = mvt_bool; + break; + + case op_and: + p.full_values[i].s = btoa(atob(p.full_values[i].s.c_str()) && atob(val.s.c_str())); + p.full_values[i].type = mvt_bool; + break; + case op_mean: { auto state = p.attribute_accum_state.find(key); if (state == p.attribute_accum_state.end()) { diff --git a/tile.hpp b/tile.hpp index cecff0066..677753049 100644 --- a/tile.hpp +++ b/tile.hpp @@ -18,6 +18,8 @@ enum attribute_op { op_comma, op_max, op_min, + op_or, + op_and, }; struct atomic_strategy {