diff --git a/attribute.cpp b/attribute.cpp index 0886c70f..7f33ade9 100644 --- a/attribute.cpp +++ b/attribute.cpp @@ -89,7 +89,7 @@ void set_attribute_accum(std::unordered_map &attribut } template -static void preserve_attribute1(attribute_op const &op, std::string const &key, T const &val, std::vector> &full_keys, std::vector &full_values, std::unordered_map &attribute_accum_state, key_pool &key_pool) { +static void preserve_attribute1(attribute_op const &op, std::string const &key, T const &val, std::vector> &full_keys, std::vector &full_values, key_pool &key_pool) { for (size_t i = 0; i < full_keys.size(); i++) { if (key == *full_keys[i]) { switch (op) { @@ -140,16 +140,11 @@ static void preserve_attribute1(attribute_op const &op, std::string const &key, return; case op_count: { - auto state = attribute_accum_state.find(key); - if (state == attribute_accum_state.end()) { // not already present - accum_state s; - s.count = 2; - attribute_accum_state.insert(std::pair(key, s)); - - full_values[i] = (s.count); - } else { // already present, incrementing - state->second.count += 1; - full_values[i] = (state->second.count); + size_t count = full_values[i].get_count(); + if (count <= 1) { + full_values[i].set_double_count(2, 2); + } else { + full_values[i].set_double_count(count + 1, count + 1); } return; } @@ -168,17 +163,7 @@ static void preserve_attribute1(attribute_op const &op, std::string const &key, break; case op_count: { - auto state = attribute_accum_state.find(key); - if (state == attribute_accum_state.end()) { // not already present - accum_state s; - s.count = 1; - attribute_accum_state.insert(std::pair(key, s)); - - v = (s.count); - } else { // already present, incrementing - fprintf(stderr, "preserve_attribute: can't happen (count)\n"); - exit(EXIT_IMPOSSIBLE); - } + v.set_double_count(1, 1); break; } @@ -191,10 +176,10 @@ static void preserve_attribute1(attribute_op const &op, std::string const &key, full_values.push_back(v); } -void preserve_attribute(attribute_op const &op, std::string const &key, mvt_value const &val, std::vector> &full_keys, std::vector &full_values, std::unordered_map &attribute_accum_state, key_pool &key_pool) { - preserve_attribute1(op, key, val, full_keys, full_values, attribute_accum_state, key_pool); +void preserve_attribute(attribute_op const &op, std::string const &key, mvt_value const &val, std::vector> &full_keys, std::vector &full_values, key_pool &key_pool) { + preserve_attribute1(op, key, val, full_keys, full_values, key_pool); } -void preserve_attribute(attribute_op const &op, std::string const &key, serial_val const &val, std::vector> &full_keys, std::vector &full_values, std::unordered_map &attribute_accum_state, key_pool &key_pool) { - preserve_attribute1(op, key, val, full_keys, full_values, attribute_accum_state, key_pool); +void preserve_attribute(attribute_op const &op, std::string const &key, serial_val const &val, std::vector> &full_keys, std::vector &full_values, key_pool &key_pool) { + preserve_attribute1(op, key, val, full_keys, full_values, key_pool); } diff --git a/attribute.hpp b/attribute.hpp index 5dd9f2a2..f66de8c1 100644 --- a/attribute.hpp +++ b/attribute.hpp @@ -19,19 +19,14 @@ enum attribute_op { op_count, }; -struct accum_state { - double sum = 0; - double count = 0; -}; - struct serial_val; struct key_pool; void set_attribute_accum(std::unordered_map &attribute_accum, std::string name, std::string type); void set_attribute_accum(std::unordered_map &attribute_accum, const char *arg, char **argv); -void preserve_attribute(attribute_op const &op, std::string const &key, serial_val const &val, std::vector> &full_keys, std::vector &full_values, std::unordered_map &attribute_accum_state, key_pool &key_pool); -void preserve_attribute(attribute_op const &op, std::string const &key, mvt_value const &val, std::vector> &full_keys, std::vector &full_values, std::unordered_map &attribute_accum_state, key_pool &key_pool); +void preserve_attribute(attribute_op const &op, std::string const &key, serial_val const &val, std::vector> &full_keys, std::vector &full_values, key_pool &key_pool); +void preserve_attribute(attribute_op const &op, std::string const &key, mvt_value const &val, std::vector> &full_keys, std::vector &full_values, key_pool &key_pool); extern std::map numeric_operations; diff --git a/clip.cpp b/clip.cpp index 76d23089..69decd45 100644 --- a/clip.cpp +++ b/clip.cpp @@ -1371,13 +1371,12 @@ static void add_mean(mvt_feature &feature, mvt_layer &layer, std::string const & }; // accumulate :sum:, :min:, :max:, and :count: versions of the specified attribute -static void preserve_numeric(const std::string &key, const mvt_value &val, // numeric attribute being accumulated - std::vector> &full_keys, // keys of feature being accumulated onto - std::vector &full_values, // values of features being accumulated onto - const std::string &accumulate_numeric, // prefix of accumulations - std::set &keys, // key presence in the source feature - std::map &numeric_out_field, // key index in the output feature - std::unordered_map &attribute_accum_state, // accumulation state for preserve_attribute() +static void preserve_numeric(const std::string &key, const mvt_value &val, // numeric attribute being accumulated + std::vector> &full_keys, // keys of feature being accumulated onto + std::vector &full_values, // values of features being accumulated onto + const std::string &accumulate_numeric, // prefix of accumulations + std::set &keys, // key presence in the source feature + std::map &numeric_out_field, // key index in the output feature key_pool &key_pool, std::set const &keep, std::set const &exclude, std::vector const &exclude_prefix) { @@ -1457,7 +1456,7 @@ static void preserve_numeric(const std::string &key, const mvt_value &val, full_values.push_back(v); } else { full_values.push_back(full_values[out_attr->second]); - preserve_attribute(op.second, prefixed, val, full_keys, full_values, attribute_accum_state, key_pool); + preserve_attribute(op.second, prefixed, val, full_keys, full_values, key_pool); } } } else { @@ -1470,7 +1469,7 @@ static void preserve_numeric(const std::string &key, const mvt_value &val, full_values[prefixed_attr->second] = mvt_value(mvt_value_to_long_long(full_values[prefixed_attr->second]) + 1); } } else { - preserve_attribute(op.second, prefixed, val, full_keys, full_values, attribute_accum_state, key_pool); + preserve_attribute(op.second, prefixed, val, full_keys, full_values, key_pool); } } } @@ -1597,7 +1596,6 @@ static bool feature_out(std::vector const &features, mvt_layer &ou // attributes from the other features of the // multiplier cluster accumulated onto them - std::unordered_map attribute_accum_state; std::vector> full_keys; std::vector full_values; std::map numeric_out_field; @@ -1642,13 +1640,13 @@ static bool feature_out(std::vector const &features, mvt_layer &ou auto found = attribute_accum.find(key); if (found != attribute_accum.end()) { mvt_value val = features[i].layer->values[features[i].tags[j + 1]]; - preserve_attribute(found->second, key, val, full_keys, full_values, attribute_accum_state, key_pool); + preserve_attribute(found->second, key, val, full_keys, full_values, key_pool); } else if (accumulate_numeric.size() > 0) { const mvt_value &val = features[i].layer->values[features[i].tags[j + 1]]; if (val.is_numeric()) { preserve_numeric(key, val, full_keys, full_values, accumulate_numeric, - keys, numeric_out_field, attribute_accum_state, key_pool, + keys, numeric_out_field, key_pool, keep, exclude, exclude_prefix); } } diff --git a/serial.hpp b/serial.hpp index 8437739f..1c86cc05 100644 --- a/serial.hpp +++ b/serial.hpp @@ -166,7 +166,6 @@ struct serial_feature { const char *stringpool; // string pool for keys/values lookup std::shared_ptr tile_stringpool; // string pool for mvt_value construction std::set need_tilestats; - std::unordered_map attribute_accum_state; int z; // tile being produced int tx; diff --git a/tile.cpp b/tile.cpp index ef481cfa..7b590e48 100644 --- a/tile.cpp +++ b/tile.cpp @@ -1500,7 +1500,7 @@ void preserve_attributes(std::unordered_map const *at sv.s = sf.stringpool + sf.values[i] + 1; promote_attribute(key, p, key_pool); - preserve_attribute(f->second, key, sv, p.full_keys, p.full_values, p.attribute_accum_state, key_pool); + preserve_attribute(f->second, key, sv, p.full_keys, p.full_values, key_pool); } else if (type == mvt_double && accumulate_numeric.size() > 0 && !starts_with(key, accumulate_numeric_colon)) { for (auto const &operation : numeric_operations) { serial_val sv; @@ -1509,7 +1509,7 @@ void preserve_attributes(std::unordered_map const *at std::string prefixed_key = accumulate_numeric + ":" + operation.first + ":" + key; promote_attribute_prefix(key, prefixed_key, p, key_pool); - preserve_attribute(operation.second, prefixed_key, sv, p.full_keys, p.full_values, p.attribute_accum_state, key_pool); + preserve_attribute(operation.second, prefixed_key, sv, p.full_keys, p.full_values, key_pool); } } } @@ -1522,12 +1522,12 @@ void preserve_attributes(std::unordered_map const *at const serial_val &sv = sf.full_values[i]; promote_attribute(key, p, key_pool); // promotes it in the target feature - preserve_attribute(f->second, key, sv, p.full_keys, p.full_values, p.attribute_accum_state, key_pool); + preserve_attribute(f->second, key, sv, p.full_keys, p.full_values, key_pool); } else if (type == mvt_double && accumulate_numeric.size() > 0 && !starts_with(key, accumulate_numeric_colon)) { for (auto const &operation : numeric_operations) { std::string prefixed_key = accumulate_numeric + ":" + operation.first + ":" + key; promote_attribute_prefix(key, prefixed_key, p, key_pool); - preserve_attribute(operation.second, prefixed_key, sf.full_values[i], p.full_keys, p.full_values, p.attribute_accum_state, key_pool); + preserve_attribute(operation.second, prefixed_key, sf.full_values[i], p.full_keys, p.full_values, key_pool); } } }