mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-05 01:45:41 +02:00
Inching toward attribute accumulation in megatile handling
This commit is contained in:
@@ -6,6 +6,13 @@
|
|||||||
#include "jsonpull/jsonpull.h"
|
#include "jsonpull/jsonpull.h"
|
||||||
#include "milo/dtoa_milo.h"
|
#include "milo/dtoa_milo.h"
|
||||||
|
|
||||||
|
std::map<std::string, attribute_op> numeric_operations = {
|
||||||
|
{"sum", op_sum},
|
||||||
|
{"min", op_min},
|
||||||
|
{"max", op_max},
|
||||||
|
{"count", op_count},
|
||||||
|
};
|
||||||
|
|
||||||
void set_attribute_accum(std::unordered_map<std::string, attribute_op> &attribute_accum, std::string name, std::string type) {
|
void set_attribute_accum(std::unordered_map<std::string, attribute_op> &attribute_accum, std::string name, std::string type) {
|
||||||
attribute_op t;
|
attribute_op t;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
enum attribute_op {
|
enum attribute_op {
|
||||||
op_sum,
|
op_sum,
|
||||||
@@ -26,4 +27,6 @@ void set_attribute_accum(std::unordered_map<std::string, attribute_op> &attribut
|
|||||||
void set_attribute_accum(std::unordered_map<std::string, attribute_op> &attribute_accum, const char *arg, char **argv);
|
void set_attribute_accum(std::unordered_map<std::string, attribute_op> &attribute_accum, const char *arg, char **argv);
|
||||||
void preserve_attribute(attribute_op const &op, const std::string &key, serial_val const &val, std::vector<std::string> &full_keys, std::vector<serial_val> &full_values, std::unordered_map<std::string, accum_state> &attribute_accum_state);
|
void preserve_attribute(attribute_op const &op, const std::string &key, serial_val const &val, std::vector<std::string> &full_keys, std::vector<serial_val> &full_values, std::unordered_map<std::string, accum_state> &attribute_accum_state);
|
||||||
|
|
||||||
|
extern std::map<std::string, attribute_op> numeric_operations;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1120,6 +1120,8 @@ struct tile_feature {
|
|||||||
size_t seq = 0;
|
size_t seq = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool accumulate_numeric = true; // XXX
|
||||||
|
|
||||||
static void feature_out(std::vector<tile_feature> const &features, mvt_layer &outlayer, std::set<std::string> const &keep, std::unordered_map<std::string, attribute_op> const &attribute_accum, std::shared_ptr<std::string> const &tile_stringpool) {
|
static void feature_out(std::vector<tile_feature> const &features, mvt_layer &outlayer, std::set<std::string> const &keep, std::unordered_map<std::string, attribute_op> const &attribute_accum, std::shared_ptr<std::string> const &tile_stringpool) {
|
||||||
// Add geometry to output feature
|
// Add geometry to output feature
|
||||||
|
|
||||||
@@ -1139,7 +1141,7 @@ static void feature_out(std::vector<tile_feature> const &features, mvt_layer &ou
|
|||||||
|
|
||||||
outfeature.seq = features[0].seq;
|
outfeature.seq = features[0].seq;
|
||||||
|
|
||||||
if (attribute_accum.size() > 0) {
|
if (attribute_accum.size() > 0 || accumulate_numeric) {
|
||||||
// convert the attributes of the output feature
|
// convert the attributes of the output feature
|
||||||
// from mvt_value to serial_val so they can have
|
// from mvt_value to serial_val so they can have
|
||||||
// attributes from the other features of the
|
// attributes from the other features of the
|
||||||
@@ -1148,6 +1150,7 @@ static void feature_out(std::vector<tile_feature> const &features, mvt_layer &ou
|
|||||||
std::unordered_map<std::string, accum_state> attribute_accum_state;
|
std::unordered_map<std::string, accum_state> attribute_accum_state;
|
||||||
std::vector<std::string> full_keys;
|
std::vector<std::string> full_keys;
|
||||||
std::vector<serial_val> full_values;
|
std::vector<serial_val> full_values;
|
||||||
|
std::map<std::string, size_t> numeric;
|
||||||
|
|
||||||
for (size_t i = 0; i + 1 < features[0].tags.size(); i += 2) {
|
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]]);
|
auto f = attribute_accum.find(features[0].layer->keys[features[0].tags[i]]);
|
||||||
@@ -1155,6 +1158,12 @@ static void feature_out(std::vector<tile_feature> const &features, mvt_layer &ou
|
|||||||
// this attribute has an accumulator, so convert it
|
// this attribute has an accumulator, so convert it
|
||||||
full_keys.push_back(features[0].layer->keys[features[0].tags[i]]);
|
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]]));
|
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 {
|
} else {
|
||||||
// otherwise just tag it directly onto the output feature
|
// 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()) {
|
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<tile_feature> 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
|
// accumulate whatever attributes are specified to be accumulated
|
||||||
// onto the feature that will survive into the output, from the
|
// onto the feature that will survive into the output, from the
|
||||||
// features that will not
|
// features that will not
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
#include "main.hpp"
|
#include "main.hpp"
|
||||||
#include "options.hpp"
|
#include "options.hpp"
|
||||||
#include "errors.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 decode_geometry(const char **meta, int z, unsigned tx, unsigned ty, long long *bbox, unsigned initial_x, unsigned initial_y) {
|
||||||
drawvec out;
|
drawvec out;
|
||||||
|
|||||||
@@ -1456,13 +1456,6 @@ void promote_attribute_prefix(std::string const &key, std::string const &prefixe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, attribute_op> numeric_operations = {
|
|
||||||
{"sum", op_sum},
|
|
||||||
{"min", op_min},
|
|
||||||
{"max", op_max},
|
|
||||||
{"count", op_count},
|
|
||||||
};
|
|
||||||
|
|
||||||
// accumulate attribute values from sf onto p
|
// accumulate attribute values from sf onto p
|
||||||
void preserve_attributes(std::unordered_map<std::string, attribute_op> const *attribute_accum, const serial_feature &sf, serial_feature &p) {
|
void preserve_attributes(std::unordered_map<std::string, attribute_op> const *attribute_accum, const serial_feature &sf, serial_feature &p) {
|
||||||
for (size_t i = 0; i < sf.keys.size(); i++) {
|
for (size_t i = 0; i < sf.keys.size(); i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user