Add an option to calculate feature density as a feature attribute

This commit is contained in:
Eric Fischer
2016-05-27 16:25:40 -07:00
parent 4030cc7c58
commit 692112ec3a
7 changed files with 58 additions and 6 deletions
+41 -5
View File
@@ -73,6 +73,7 @@ struct coalesce {
int type;
int m;
bool coalesced;
double spacing;
bool operator<(const coalesce &o) const {
int cmp = coalindexcmp(this, &o);
@@ -259,7 +260,7 @@ struct sll {
}
};
void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, unsigned tx, unsigned ty, int buffer, int line_detail, int *within, long long *geompos, FILE **geomfile, const char *fname, signed char t, int layer, long long metastart, signed char feature_minzoom, int child_shards, int max_zoom_increment, long long seq, int tippecanoe_minzoom, int tippecanoe_maxzoom, int segment, unsigned *initial_x, unsigned *initial_y, int m, std::vector<long long> &metakeys, std::vector <long long> &metavals) {
void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, unsigned tx, unsigned ty, int buffer, int line_detail, int *within, long long *geompos, FILE **geomfile, const char *fname, signed char t, int layer, long long metastart, signed char feature_minzoom, int child_shards, int max_zoom_increment, long long seq, int tippecanoe_minzoom, int tippecanoe_maxzoom, int segment, unsigned *initial_x, unsigned *initial_y, int m, std::vector<long long> &metakeys, std::vector<long long> &metavals) {
if (geom.size() > 0 && nextzoom <= maxzoom) {
int xo, yo;
int span = 1 << (nextzoom - z);
@@ -387,6 +388,7 @@ struct partial {
int z;
int line_detail;
int maxzoom;
double spacing;
signed char t;
};
@@ -599,9 +601,10 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
double fraction_accum = 0;
unsigned long long previndex = 0;
unsigned long long previndex = 0, density_previndex = 0;
double scale = (double) (1LL << (64 - 2 * (z + 8)));
double gap = 0;
double gap = 0, density_gap = 0;
double spacing = 0;
long long original_features = 0;
long long unclipped_features = 0;
@@ -796,6 +799,11 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
continue;
}
unsigned long long index = 0;
if (additional[A_CALCULATE_FEATURE_DENSITY] || gamma > 0) {
index = encode(bbox[0] / 2 + bbox[2] / 2, bbox[1] / 2 + bbox[3] / 2);
}
if (gamma >= 0 && (t == VT_POINT ||
(additional[A_LINE_DROP] && t == VT_LINE) ||
(additional[A_POLYGON_DROP] && t == VT_POLYGON))) {
@@ -806,14 +814,25 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
continue;
}
if (gamma > 0) {
unsigned long long index = encode(bbox[0] / 2 + bbox[2] / 2, bbox[1] / 2 + bbox[3] / 2);
if (gamma > 0 || additional[A_CALCULATE_FEATURE_DENSITY]) {
if (manage_gap(index, &previndex, scale, gamma, &gap)) {
continue;
}
}
}
if (additional[A_CALCULATE_FEATURE_DENSITY]) {
// Gamma is always 1 for this calculation so there is a reasonable
// interpretation when no features are being dropped.
// The spacing is only calculated if a feature would be retained by
// that standard, so that duplicates aren't reported as infinitely dense.
double o_density_previndex = density_previndex;
if (!manage_gap(index, &density_previndex, scale, 1, &density_gap)) {
spacing = (index - o_density_previndex) / scale;
}
}
fraction_accum += fraction;
if (fraction_accum < 1) {
continue;
@@ -840,6 +859,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
p.maxzoom = maxzoom;
p.keys = metakeys;
p.values = metavals;
p.spacing = spacing;
partials.push_back(p);
}
}
@@ -900,6 +920,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
c.stringpool = stringpool + pool_off[partials[i].segment];
c.keys = partials[i].keys;
c.values = partials[i].values;
c.spacing = partials[i].spacing;
features[layer].push_back(c);
}
@@ -995,6 +1016,21 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
features[k][x].geom.clear();
decode_meta(features[k][x].m, features[k][x].keys, features[k][x].values, features[k][x].stringpool, layer, feature);
if (additional[A_CALCULATE_FEATURE_DENSITY]) {
int glow = 255;
if (features[k][x].spacing > 0) {
glow = (1 / features[k][x].spacing);
if (glow > 255) {
glow = 255;
}
}
mvt_value v;
v.type = mvt_sint;
v.numeric_value.sint_value = glow;
layer.tag(feature, "tippecanoe_feature_density", v);
}
layer.features.push_back(feature);
}