Coalesce geometries of features with the same attributes

This commit is contained in:
Eric Fischer 2014-09-29 15:33:14 -07:00
parent f0d2dbd2a8
commit a08e57357a
2 changed files with 44 additions and 2 deletions

View File

@ -51,8 +51,8 @@ in some places), so I need to figure out an equitable way to throw features away
It also throws away any polygons that are too small to draw. I'm not sure yet It also throws away any polygons that are too small to draw. I'm not sure yet
if it is appropriate to do more than that. if it is appropriate to do more than that.
It should consolidate features in the same tile that share the same type and attributes, Features in the same tile that share the same type and attributes are coalesced
to make the tile data smaller, but doesn't do that yet. together into a single geometry.
Development Development
----------- -----------

42
tile.cc
View File

@ -446,6 +446,27 @@ struct coalesce {
int *meta; int *meta;
}; };
int coalcmp(const void *v1, const void *v2) {
const struct coalesce *c1 = (const struct coalesce *) v1;
const struct coalesce *c2 = (const struct coalesce *) v2;
int cmp = c1->type - c2->type;
if (cmp != 0) {
return cmp;
}
int i;
for (i = 0; i < c1->nmeta && i < c2->nmeta; i++) {
cmp = c1->meta[i] - c2->meta[i];
if (cmp != 0) {
return cmp;
}
}
return c1->nmeta - c2->nmeta;
}
long long write_tile(struct index *start, struct index *end, char *metabase, unsigned *file_bbox, int z, unsigned tx, unsigned ty, int detail, int basezoom, struct pool *file_keys, char *layername, sqlite3 *outdb) { long long write_tile(struct index *start, struct index *end, char *metabase, unsigned *file_bbox, int z, unsigned tx, unsigned ty, int detail, int basezoom, struct pool *file_keys, char *layername, sqlite3 *outdb) {
GOOGLE_PROTOBUF_VERIFY_VERSION; GOOGLE_PROTOBUF_VERIFY_VERSION;
@ -554,7 +575,28 @@ long long write_tile(struct index *start, struct index *end, char *metabase, uns
} }
} }
qsort(features, nfeatures, sizeof(struct coalesce), coalcmp);
int x; int x;
int out = 0;
for (x = 0; x < nfeatures; x++) {
if (out > 0 && features[out - 1].ngeom + features[x].ngeom < 20000 && coalcmp(&features[x], &features[out - 1]) == 0) {
struct draw *tmp = (struct draw *) malloc((features[x].ngeom + features[out - 1].ngeom) * sizeof(struct draw));
memcpy(tmp, features[out - 1].geom, features[out - 1].ngeom * sizeof(struct draw));
memcpy(tmp + features[out - 1].ngeom, features[x].geom, features[x].ngeom * sizeof(struct draw));
free(features[x].geom);
free(features[out - 1].geom);
free(features[x].meta);
features[out - 1].ngeom += features[x].ngeom;
features[out - 1].geom = tmp;
} else {
features[out++] = features[x];
}
}
nfeatures = out;
for (x = 0; x < nfeatures; x++) { for (x = 0; x < nfeatures; x++) {
mapnik::vector::tile_feature *feature = layer->add_features(); mapnik::vector::tile_feature *feature = layer->add_features();