diff --git a/attribute.cpp b/attribute.cpp index e969ab12..ac7b82cd 100644 --- a/attribute.cpp +++ b/attribute.cpp @@ -6,6 +6,13 @@ #include "jsonpull/jsonpull.h" #include "milo/dtoa_milo.h" +std::map numeric_operations = { + {"sum", op_sum}, + {"min", op_min}, + {"max", op_max}, + {"count", op_count}, +}; + void set_attribute_accum(std::unordered_map &attribute_accum, std::string name, std::string type) { attribute_op t; diff --git a/attribute.hpp b/attribute.hpp index af860ffa..ce54dcba 100644 --- a/attribute.hpp +++ b/attribute.hpp @@ -3,6 +3,7 @@ #include #include +#include enum attribute_op { op_sum, @@ -26,4 +27,6 @@ void set_attribute_accum(std::unordered_map &attribut void set_attribute_accum(std::unordered_map &attribute_accum, const char *arg, char **argv); void preserve_attribute(attribute_op const &op, const std::string &key, serial_val const &val, std::vector &full_keys, std::vector &full_values, std::unordered_map &attribute_accum_state); +extern std::map numeric_operations; + #endif diff --git a/clip.cpp b/clip.cpp index b10d25a6..1a554233 100644 --- a/clip.cpp +++ b/clip.cpp @@ -1120,6 +1120,8 @@ struct tile_feature { size_t seq = 0; }; +bool accumulate_numeric = true; // XXX + static void feature_out(std::vector const &features, mvt_layer &outlayer, std::set const &keep, std::unordered_map const &attribute_accum, std::shared_ptr const &tile_stringpool) { // Add geometry to output feature @@ -1139,7 +1141,7 @@ static void feature_out(std::vector const &features, mvt_layer &ou outfeature.seq = features[0].seq; - if (attribute_accum.size() > 0) { + if (attribute_accum.size() > 0 || accumulate_numeric) { // convert the attributes of the output feature // from mvt_value to serial_val so they can have // attributes from the other features of the @@ -1148,6 +1150,7 @@ static void feature_out(std::vector const &features, mvt_layer &ou std::unordered_map attribute_accum_state; std::vector full_keys; std::vector full_values; + std::map numeric; for (size_t i = 0; i + 1 < features[0].tags.size(); i += 2) { auto f = attribute_accum.find(features[0].layer->keys[features[0].tags[i]]); @@ -1155,6 +1158,12 @@ static void feature_out(std::vector const &features, mvt_layer &ou // this attribute has an accumulator, so convert it full_keys.push_back(features[0].layer->keys[features[0].tags[i]]); full_values.push_back(mvt_value_to_serial_val(features[0].layer->values[features[0].tags[i + 1]])); + } else if (accumulate_numeric && features[0].layer->values[features[0].tags[i + 1]].is_numeric()) { + // convert numeric for accumulation + const std::string &key = features[0].layer->keys[features[0].tags[i]]; + numeric.emplace(key, full_keys.size()); + full_keys.push_back(key); + full_values.push_back(mvt_value_to_serial_val(features[0].layer->values[features[0].tags[i + 1]])); } else { // otherwise just tag it directly onto the output feature if (keep.size() == 0 || keep.find(features[0].layer->keys[features[0].tags[i]]) != keep.end()) { @@ -1163,6 +1172,14 @@ static void feature_out(std::vector const &features, mvt_layer &ou } } + // also create any numeric accumulation attributes that are needed + // but don't exist yet + for (auto const &k : numeric) { + for (auto const &op : numeric_operations) { + std::string key = k.first + ":" + op.first; + } + } + // accumulate whatever attributes are specified to be accumulated // onto the feature that will survive into the output, from the // features that will not diff --git a/geometry.cpp b/geometry.cpp index 321ad28c..58d4f163 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -18,7 +18,6 @@ #include "main.hpp" #include "options.hpp" #include "errors.hpp" -#include "projection.hpp" drawvec decode_geometry(const char **meta, int z, unsigned tx, unsigned ty, long long *bbox, unsigned initial_x, unsigned initial_y) { drawvec out; diff --git a/tile.cpp b/tile.cpp index a5fa1ba2..89a869ea 100644 --- a/tile.cpp +++ b/tile.cpp @@ -1456,13 +1456,6 @@ void promote_attribute_prefix(std::string const &key, std::string const &prefixe } } -std::map numeric_operations = { - {"sum", op_sum}, - {"min", op_min}, - {"max", op_max}, - {"count", op_count}, -}; - // accumulate attribute values from sf onto p void preserve_attributes(std::unordered_map const *attribute_accum, const serial_feature &sf, serial_feature &p) { for (size_t i = 0; i < sf.keys.size(); i++) {