Merge branch 'order-feature-dropping' into categoricality

This commit is contained in:
Erica Fischer
2023-02-08 14:48:38 -08:00
2 changed files with 1427 additions and 25 deletions
+149 -25
View File
@@ -320,6 +320,14 @@ struct ordercmp {
}
}
if (prevent[P_INPUT_ORDER]) {
if (a.original_seq < b.original_seq) {
return true;
} else if (a.original_seq > b.original_seq) {
return false;
} // else they are equal, so continue to the index
}
if (a.index < b.index) {
return true;
}
@@ -471,6 +479,37 @@ struct partial {
long long clustered = 0;
std::set<std::string> need_tilestats;
std::map<std::string, accum_state> attribute_accum_state;
partial(serial_feature &sf, int z_, int tx_, int ty_, int line_detail_, int maxzoom_, double simplification_) {
geoms.clear();
geoms.push_back(sf.geometry);
layer = sf.layer;
t = sf.t;
segment = sf.segment;
original_seq = sf.seq;
keys = sf.keys;
values = sf.values;
full_keys = sf.full_keys;
full_values = sf.full_values;
id = sf.id;
has_id = sf.has_id;
index = sf.index;
label_point = sf.label_point;
extent = sf.extent;
z = z_;
tx = tx_;
ty = ty_;
line_detail = line_detail_;
extra_detail = line_detail_;
maxzoom = maxzoom_;
simplification = simplification_;
coalesced = false;
renamed = -1;
clustered = 0;
}
};
struct partial_arg {
@@ -480,6 +519,105 @@ struct partial_arg {
drawvec *shared_nodes;
};
// THIS IS RIDICULOUS to have three almost-identical representations for features. FIX FIX FIX
static mvt_value find_attribute_value(const serial_feature *c1, std::string key, const char *stringpool, long long pool_off[]) {
if (key == ORDER_BY_SIZE) {
mvt_value v;
v.type = mvt_double;
v.numeric_value.double_value = c1->extent;
return v;
}
const std::vector<long long> &keys1 = c1->keys;
const std::vector<long long> &values1 = c1->values;
const char *stringpool1 = stringpool + pool_off[c1->segment];
for (size_t i = 0; i < keys1.size(); i++) {
mvt_value key1 = retrieve_string(keys1[i], stringpool1, NULL);
if (key == key1.string_value) {
return retrieve_string(values1[i], stringpool1, NULL);
}
}
for (size_t i = 0; i < c1->full_keys.size(); i++) {
if (c1->full_keys[i] == key) {
return stringified_to_mvt_value(c1->full_values[i].type, c1->full_values[i].s.c_str());
}
}
mvt_value v;
v.type = mvt_null;
v.numeric_value.null_value = 0;
return v;
}
static mvt_value find_attribute_value(const partial *c1, std::string key, const char *stringpool, long long pool_off[]) {
if (key == ORDER_BY_SIZE) {
mvt_value v;
v.type = mvt_double;
v.numeric_value.double_value = c1->extent;
return v;
}
const std::vector<long long> &keys1 = c1->keys;
const std::vector<long long> &values1 = c1->values;
const char *stringpool1 = stringpool + pool_off[c1->segment];
for (size_t i = 0; i < keys1.size(); i++) {
mvt_value key1 = retrieve_string(keys1[i], stringpool1, NULL);
if (key == key1.string_value) {
return retrieve_string(values1[i], stringpool1, NULL);
}
}
for (size_t i = 0; i < c1->full_keys.size(); i++) {
if (c1->full_keys[i] == key) {
return stringified_to_mvt_value(c1->full_values[i].type, c1->full_values[i].s.c_str());
}
}
mvt_value v;
v.type = mvt_null;
v.numeric_value.null_value = 0;
return v;
}
static bool order_partials(const char *stringpool, long long pool_off[], const serial_feature &a, const partial &b) {
for (size_t i = 0; i < order_by.size(); i++) {
mvt_value v1 = coerce_double(find_attribute_value(&a, order_by[i].name, stringpool, pool_off));
mvt_value v2 = coerce_double(find_attribute_value(&b, order_by[i].name, stringpool, pool_off));
if (order_by[i].descending) {
if (v2 < v1) {
return true;
} else if (v1 < v2) {
return false;
} // else they are equal, so continue to the next attribute
} else {
if (v1 < v2) {
return true;
} else if (v2 < v1) {
return false;
} // else they are equal, so continue to the next attribute
}
}
if (prevent[P_INPUT_ORDER]) {
if (a.seq < b.original_seq) {
return true;
} else if (a.seq > b.original_seq) {
return false;
} // else they are equal, so continue to the index
}
if (a.index < b.index) {
return true;
}
return false; // greater than or equal
}
drawvec revive_polygon(drawvec &geom, double area, int z, int detail) {
// From area in world coordinates to area in tile coordinates
long long divisor = 1LL << (32 - detail - z);
@@ -2032,6 +2170,15 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
if (sf.dropped) {
if (find_partial(partials, sf, which_partial, layer_unmaps, LLONG_MAX)) {
// would it have been better to drop this other feature instead?
if (order_by.size() > 0) {
if (order_partials(stringpool, pool_off, sf, partials[which_partial])) {
partials[which_partial] = partial(sf, z, tx, ty, line_detail, maxzoom, simplification);
// XXX preserve_attributes
}
}
preserve_attributes(arg->attribute_accum, sf, stringpool, pool_off, partials[which_partial]);
strategy->dropped_by_rate++;
continue;
@@ -2178,33 +2325,10 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
}
}
partial p;
p.geoms.push_back(sf.geometry);
p.layer = sf.layer;
p.t = sf.t;
p.segment = sf.segment;
p.original_seq = sf.seq;
partial p(sf, z, tx, ty, line_detail, maxzoom, simplification);
p.reduced = reduced;
p.coalesced = false;
p.z = z;
p.tx = tx;
p.ty = ty;
p.line_detail = line_detail;
p.extra_detail = line_detail;
p.maxzoom = maxzoom;
p.keys = sf.keys;
p.values = sf.values;
p.full_keys = sf.full_keys;
p.full_values = sf.full_values;
p.spacing = spacing;
p.simplification = simplification;
p.id = sf.id;
p.has_id = sf.has_id;
p.index = sf.index;
p.label_point = sf.label_point;
p.renamed = -1;
p.extent = sf.extent;
p.clustered = 0;
if (line_detail == detail && extra_detail >= 0 && z == maxzoom) {
p.extra_detail = extra_detail;