Indirect lists of mvt_feature through pointers for faster sorting

This commit is contained in:
Erica Fischer
2025-02-12 11:32:28 -08:00
parent 9d00c92ff2
commit 355cc31d5b
9 changed files with 52 additions and 48 deletions
+26 -22
View File
@@ -1674,7 +1674,7 @@ static bool feature_out(std::vector<tile_feature> const &features, mvt_layer &ou
}
}
outlayer.features.push_back(std::move(outfeature));
outlayer.features.push_back(std::make_shared<mvt_feature>(outfeature));
return true;
}
@@ -1685,6 +1685,9 @@ static struct preservecmp {
bool operator()(const mvt_feature &a, const mvt_feature &b) {
return a.seq < b.seq;
}
bool operator()(const std::shared_ptr<mvt_feature> &a, const std::shared_ptr<mvt_feature> &b) {
return a->seq < b->seq;
}
} preservecmp;
struct index_event {
@@ -1825,39 +1828,39 @@ mvt_tile assign_to_bins(mvt_tile &features,
std::map<unsigned long long, std::pair<size_t, size_t>> fid_to_feature;
for (size_t i = 0; i < features.layers.size(); i++) {
for (size_t j = 0; j < features.layers[i].features.size(); j++) {
if (features.layers[i].features[j].geometry.size() > 0) {
if (features.layers[i].features[j].has_id) {
fid_to_feature.emplace(features.layers[i].features[j].id, std::make_pair(i, j));
if (features.layers[i].features[j]->geometry.size() > 0) {
if (features.layers[i].features[j]->has_id) {
fid_to_feature.emplace(features.layers[i].features[j]->id, std::make_pair(i, j));
}
}
}
}
for (auto &binlayer : bins) {
size_t seq = 0;
size_t seq = 0;
for (auto &bin : binlayer.features) {
{
tile_feature outfeature;
for (auto const &g : bin.geometry) {
for (auto const &g : bin->geometry) {
outfeature.geom.emplace_back(g.op, g.x, g.y);
}
outfeature.t = bin.type;
outfeature.has_id = bin.has_id;
outfeature.id = bin.id;
outfeature.tags = bin.tags;
outfeature.t = bin->type;
outfeature.has_id = bin->has_id;
outfeature.id = bin->id;
outfeature.tags = bin->tags;
outfeature.layer = &binlayer;
outfeature.seq = seq++;
outfeatures.push_back({std::move(outfeature)});
}
for (size_t k = 0; k < bin.tags.size(); k += 2) {
if (binlayer.keys[bin.tags[k]] == bin_by_id_list) {
std::vector<size_t> ids = parse_ids_string(binlayer.values[bin.tags[k + 1]]);
for (size_t k = 0; k < bin->tags.size(); k += 2) {
if (binlayer.keys[bin->tags[k]] == bin_by_id_list) {
std::vector<size_t> ids = parse_ids_string(binlayer.values[bin->tags[k + 1]]);
for (auto &id : ids) {
auto f = fid_to_feature.find(id);
if (f != fid_to_feature.end()) {
mvt_feature &feature = features.layers[f->second.first].features[f->second.second];
mvt_feature &feature = *features.layers[f->second.first].features[f->second.second];
if (feature.geometry.size() > 0) {
tile_feature outfeature;
for (auto const &g : feature.geometry) {
@@ -1888,7 +1891,7 @@ mvt_tile assign_to_bins(mvt_tile &features,
long long xmin, ymin, xmax, ymax;
unsigned long long start, end;
get_bbox(bins[i].features[j].geometry, &xmin, &ymin, &xmax, &ymax, z, x, y, bins[i].detail());
get_bbox(bins[i].features[j]->geometry, &xmin, &ymin, &xmax, &ymax, z, x, y, bins[i].detail());
get_quadkey_bounds(xmin, ymin, xmax, ymax, &start, &end);
events.emplace_back(start, index_event::ENTER, i, j, xmin, ymin, xmax, ymax);
events.emplace_back(end, index_event::EXIT, i, j, xmin, ymin, xmax, ymax);
@@ -1901,8 +1904,8 @@ mvt_tile assign_to_bins(mvt_tile &features,
long long xmin, ymin, xmax, ymax;
unsigned long long start, end;
if (features.layers[i].features[j].geometry.size() > 0) {
get_bbox(features.layers[i].features[j].geometry, &xmin, &ymin, &xmax, &ymax, z, x, y, features.layers[i].detail());
if (features.layers[i].features[j]->geometry.size() > 0) {
get_bbox(features.layers[i].features[j]->geometry, &xmin, &ymin, &xmax, &ymax, z, x, y, features.layers[i].detail());
get_quadkey_bounds(xmin, ymin, xmax, ymax, &start, &end);
events.emplace_back(start, index_event::CHECK, i, j, xmin, ymin, xmax, ymax);
}
@@ -1920,7 +1923,7 @@ mvt_tile assign_to_bins(mvt_tile &features,
a.xmax = e.xmax;
a.ymax = e.ymax;
const mvt_feature &bin = bins[e.layer].features[e.feature];
const mvt_feature &bin = *bins[e.layer].features[e.feature];
{
tile_feature outfeature;
@@ -1944,7 +1947,7 @@ mvt_tile assign_to_bins(mvt_tile &features,
continue; // only bin by id, not geometrically
}
auto const &feature = features.layers[e.layer].features[e.feature];
auto const &feature = *features.layers[e.layer].features[e.feature];
if (feature.geometry.size() == 0) {
// already assigned by ID
@@ -1956,7 +1959,7 @@ mvt_tile assign_to_bins(mvt_tile &features,
ssize_t which_outfeature = outfeatures.size() - 1;
for (auto const &a : active) {
auto const &bin = bins[a.layer].features[a.feature];
auto const &bin = *bins[a.layer].features[a.feature];
if (bbox_intersects(e.xmin, e.ymin, e.xmax, e.ymax,
a.xmin, a.ymin, a.xmax, a.ymax)) {
@@ -1999,7 +2002,7 @@ mvt_tile assign_to_bins(mvt_tile &features,
keep, exclude, exclude_prefix, attribute_accum,
accumulate_numeric, key_pool, buffer, true,
clipbboxes, z, x, y)) {
mvt_feature &nfeature = outlayer.features.back();
mvt_feature &nfeature = *outlayer.features.back();
mvt_value val;
val.type = mvt_uint;
val.numeric_value.uint_value = outfeatures[i].size() - 1;
@@ -2071,7 +2074,8 @@ std::string overzoom(std::vector<source_tile> const &tiles, int nz, int nx, int
static const std::string retain_points_multiplier_first = "tippecanoe:retain_points_multiplier_first";
static const std::string retain_points_multiplier_sequence = "tippecanoe:retain_points_multiplier_sequence";
for (auto feature : layer.features) {
for (auto feature_ref : layer.features) {
auto feature = *feature_ref; // this needs to be a copy, because tile-join still needs the original unmutated
drawvec geom;
int t = feature.type;