Carry sum of numeric attributes into the bins

This commit is contained in:
Erica Fischer
2024-08-29 13:24:12 -07:00
parent 2ee982c54f
commit 8bd955ae5b
4 changed files with 64 additions and 4 deletions
+28 -2
View File
@@ -1319,7 +1319,8 @@ mvt_tile assign_to_bins(mvt_tile const &features, std::vector<mvt_layer> const &
std::sort(events.begin(), events.end());
std::set<active_bin> active;
std::vector<size_t> counters; // separate because set items can't be mutated from an iterator
std::vector<size_t> counters; // separate because set items can't be mutated from an iterator
std::vector<std::map<std::string, double>> sums; // separate because set items can't be mutated from an iterator
mvt_layer outlayer;
outlayer.extent = 1 << detail;
@@ -1335,10 +1336,12 @@ mvt_tile assign_to_bins(mvt_tile const &features, std::vector<mvt_layer> const &
outfeature.geometry = bin.geometry;
outfeature.type = bin.type;
a.outfeature = outlayer.features.size();
a.counter = counters.size();
counters.push_back(0);
sums.emplace_back();
outlayer.features.push_back(std::move(outfeature));
counters.push_back(0);
active.insert(std::move(a));
} else if (e.kind == index_event::CHECK) {
auto const &feature = features.layers[e.layer].features[e.feature];
@@ -1363,6 +1366,22 @@ mvt_tile assign_to_bins(mvt_tile const &features, std::vector<mvt_layer> const &
printf("\n");
#endif
counters[a.counter]++;
for (size_t i = 0; i + 1 < feature.tags.size(); i += 2) {
const mvt_value &val = features.layers[e.layer].values[feature.tags[i + 1]];
const std::string &key = features.layers[e.layer].keys[feature.tags[i]];
if (val.is_numeric()) {
auto find_attr = sums[a.counter].find(key);
if (find_attr == sums[a.counter].end()) {
sums[a.counter].emplace(key, 0);
find_attr = sums[a.counter].find(key);
}
find_attr->second += mvt_value_to_double(val);
}
}
break;
}
}
@@ -1384,6 +1403,13 @@ mvt_tile assign_to_bins(mvt_tile const &features, std::vector<mvt_layer> const &
v.type = mvt_uint;
v.numeric_value.uint_value = counters[found->counter];
outlayer.tag(outfeature, "bin-count", v);
for (auto const &kv : sums[found->counter]) {
mvt_value v2;
v2.type = mvt_double;
v2.numeric_value.double_value = kv.second;
outlayer.tag(outfeature, "tippecanoe:sum:" + kv.first, v2);
}
} else {
outfeature.geometry.clear();
}
+25
View File
@@ -836,6 +836,31 @@ long long mvt_value_to_long_long(mvt_value const &v) {
}
}
// This extracts a double value from an mvt_value
double mvt_value_to_double(mvt_value const &v) {
switch (v.type) {
case mvt_string:
return atof(v.c_str());
case mvt_float:
return v.numeric_value.float_value;
case mvt_double:
return v.numeric_value.double_value;
case mvt_int:
return v.numeric_value.int_value;
case mvt_uint:
return v.numeric_value.uint_value;
case mvt_sint:
return v.numeric_value.sint_value;
case mvt_bool:
return v.numeric_value.bool_value;
case mvt_null:
return 0;
default:
fprintf(stderr, "unhandled mvt_type %d\n", v.type);
exit(EXIT_IMPOSSIBLE);
}
}
void get_bbox(std::vector<mvt_geometry> const &geom,
long long *xmin, long long *ymin, long long *xmax, long long *ymax,
int z, int tx, int ty, int detail) {
+9
View File
@@ -118,6 +118,14 @@ struct mvt_value {
s->push_back('\0');
}
bool is_numeric() const {
return type == mvt_float ||
type == mvt_double ||
type == mvt_int ||
type == mvt_uint ||
type == mvt_sint;
}
bool operator<(const mvt_value &o) const;
bool operator==(const mvt_value &o) const;
std::string toString() const;
@@ -193,6 +201,7 @@ int dezig(unsigned n);
mvt_value stringified_to_mvt_value(int type, const char *s, std::shared_ptr<std::string> const &tile_stringpool);
long long mvt_value_to_long_long(mvt_value const &v);
double mvt_value_to_double(mvt_value const &v);
bool is_integer(const char *s, long long *v);
bool is_unsigned_integer(const char *s, unsigned long long *v);
+2 -2
View File
@@ -1,6 +1,6 @@
{ "type": "FeatureCollection", "properties": { "zoom": 2, "x": 0, "y": 1 }, "features": [
{ "type": "FeatureCollection", "properties": { "layer": "ne_10m_admin_0_countries", "version": 2, "extent": 4096 }, "features": [
{ "type": "Feature", "properties": { "bin": "8188fffffffffff", "bin-count": 1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -154.028320, 4.258768 ], [ -150.908203, 0.790990 ], [ -152.402344, -3.425692 ], [ -156.862793, -4.258768 ], [ -159.938965, -0.944781 ], [ -158.598633, 3.337954 ], [ -154.028320, 4.258768 ] ] ] } }
{ "type": "Feature", "properties": { "bin": "8188fffffffffff", "bin-count": 1, "tippecanoe:sum:ABBREV_LEN": 4, "tippecanoe:sum:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:sum:GDP_MD": 194, "tippecanoe:sum:GDP_YEAR": 2019, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:sum:HOMEPART": 1, "tippecanoe:sum:LABELRANK": 6, "tippecanoe:sum:LABEL_X": -157.384577, "tippecanoe:sum:LABEL_Y": 1.820437, "tippecanoe:sum:LEVEL": 2, "tippecanoe:sum:LONG_LEN": 8, "tippecanoe:sum:MAPCOLOR13": 12, "tippecanoe:sum:MAPCOLOR7": 5, "tippecanoe:sum:MAPCOLOR8": 7, "tippecanoe:sum:MAPCOLOR9": 6, "tippecanoe:sum:MAX_LABEL": 10, "tippecanoe:sum:MIN_LABEL": 5, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:sum:NAME_LEN": 8, "tippecanoe:sum:NE_ID": 1159320981, "tippecanoe:sum:POP_EST": 117606, "tippecanoe:sum:POP_RANK": 9, "tippecanoe:sum:POP_YEAR": 2019, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:sum:TINY": 2, "tippecanoe:sum:WOE_ID": 23424867, "tippecanoe:sum:WOE_ID_EH": 23424867, "tippecanoe:sum:scalerank": 3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -154.028320, 4.258768 ], [ -150.908203, 0.790990 ], [ -152.402344, -3.425692 ], [ -156.862793, -4.258768 ], [ -159.938965, -0.944781 ], [ -158.598633, 3.337954 ], [ -154.028320, 4.258768 ] ] ] } }
,
{ "type": "Feature", "properties": { "bin": "816f7ffffffffff", "bin-count": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -124.738770, 5.309766 ], [ -120.476074, 5.156599 ], [ -118.234863, 1.537901 ], [ -120.256348, -1.691649 ], [ -124.299316, -1.450040 ], [ -126.474609, 1.625758 ], [ -125.661621, 3.601142 ], [ -124.738770, 5.309766 ] ] ] } }
,
@@ -36,7 +36,7 @@
,
{ "type": "Feature", "properties": { "bin": "810ebffffffffff", "bin-count": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -96.437988, 63.253412 ], [ -86.440430, 62.186014 ], [ -84.550781, 57.527622 ], [ -90.659180, 54.303704 ], [ -98.569336, 55.216490 ], [ -102.128906, 59.467408 ], [ -96.437988, 63.253412 ] ] ] } }
,
{ "type": "Feature", "properties": { "bin": "81137ffffffffff", "bin-count": 1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -100.832520, 67.533772 ], [ -96.437988, 63.253412 ], [ -102.128906, 59.467408 ], [ -110.961914, 59.512029 ], [ -116.455078, 63.194018 ], [ -112.543945, 67.415927 ], [ -100.832520, 67.533772 ] ] ] } }
{ "type": "Feature", "properties": { "bin": "81137ffffffffff", "bin-count": 1, "tippecanoe:sum:ABBREV_LEN": 4, "tippecanoe:sum:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:sum:GDP_MD": 1736425, "tippecanoe:sum:GDP_YEAR": 2019, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:sum:HOMEPART": 1, "tippecanoe:sum:LABELRANK": 2, "tippecanoe:sum:LABEL_X": -101.9107, "tippecanoe:sum:LABEL_Y": 60.324287, "tippecanoe:sum:LEVEL": 2, "tippecanoe:sum:LONG_LEN": 6, "tippecanoe:sum:MAPCOLOR13": 2, "tippecanoe:sum:MAPCOLOR7": 6, "tippecanoe:sum:MAPCOLOR8": 6, "tippecanoe:sum:MAPCOLOR9": 2, "tippecanoe:sum:MAX_LABEL": 5.7, "tippecanoe:sum:MIN_LABEL": 1.7, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:sum:NAME_LEN": 6, "tippecanoe:sum:NE_ID": 1159320467, "tippecanoe:sum:POP_EST": 37589262, "tippecanoe:sum:POP_RANK": 15, "tippecanoe:sum:POP_YEAR": 2019, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:sum:TINY": -99, "tippecanoe:sum:WOE_ID": 23424775, "tippecanoe:sum:WOE_ID_EH": 23424775, "tippecanoe:sum:scalerank": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -100.832520, 67.533772 ], [ -96.437988, 63.253412 ], [ -102.128906, 59.467408 ], [ -110.961914, 59.512029 ], [ -116.455078, 63.194018 ], [ -112.543945, 67.415927 ], [ -100.832520, 67.533772 ] ] ] } }
,
{ "type": "Feature", "properties": { "bin": "810fbffffffffff", "bin-count": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -92.680664, 71.230221 ], [ -79.299316, 69.854762 ], [ -78.068848, 65.183030 ], [ -86.440430, 62.186014 ], [ -96.437988, 63.253412 ], [ -100.832520, 67.533772 ], [ -92.680664, 71.230221 ] ] ] } }
,