Factor out and improve no-op drawing elimination

This commit is contained in:
Eric Fischer 2014-09-24 11:42:20 -07:00
parent ef3d9867fc
commit fbf60b6d80

75
tile.cc
View File

@ -126,19 +126,21 @@ int draw(struct draw *geom, int n, mapnik::vector::tile_feature *feature) {
int dx = wwx - px; int dx = wwx - px;
int dy = wwy - py; int dy = wwy - py;
if (dx != 0 || dy != 0 || length == 0) { if (dx == 0 && dy == 0 && op == VT_LINETO) {
if (feature != NULL) { printf("0 delta\n");
feature->add_geometry((dx << 1) ^ (dx >> 31)); }
feature->add_geometry((dy << 1) ^ (dy >> 31));
}
px = wwx; if (feature != NULL) {
py = wwy; feature->add_geometry((dx << 1) ^ (dx >> 31));
length++; feature->add_geometry((dy << 1) ^ (dy >> 31));
}
if (op == VT_LINETO && (dx != 0 || dy != 0)) { px = wwx;
drew = 1; py = wwy;
} length++;
if (op == VT_LINETO && (dx != 0 || dy != 0)) {
drew = 1;
} }
} else if (op == VT_CLOSEPATH) { } else if (op == VT_CLOSEPATH) {
length++; length++;
@ -154,6 +156,53 @@ int draw(struct draw *geom, int n, mapnik::vector::tile_feature *feature) {
return drew; return drew;
} }
int remove_noop(struct draw *geom, int n) {
// first pass: remove empty linetos
long long x = 0, y = 0;
int out = 0;
int i;
for (i = 0; i < n; i++) {
if (geom[i].op == VT_LINETO && geom[i].x == x && geom[i].y == y) {
continue;
}
if (geom[i].op == VT_CLOSEPATH) {
geom[out++] = geom[i];
} else { /* moveto or lineto */
geom[out++] = geom[i];
x = geom[i].x;
y = geom[i].y;
}
}
// second pass: remove unused movetos
n = out;
out = 0;
for (i = 0; i < n; i++) {
if (geom[i].op == VT_MOVETO) {
if (i + 1 >= n) {
continue;
}
if (geom[i + 1].op == VT_MOVETO) {
continue;
}
if (geom[i + 1].op == VT_CLOSEPATH) {
i++; // also remove unused closepath
continue;
}
}
geom[out++] = geom[i];
}
return out;
}
void 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) { void 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) {
GOOGLE_PROTOBUF_VERIFY_VERSION; GOOGLE_PROTOBUF_VERIFY_VERSION;
@ -215,6 +264,10 @@ void write_tile(struct index *start, struct index *end, char *metabase, unsigned
deserialize_int(&meta, &t); deserialize_int(&meta, &t);
decode_feature(&meta, geom, z, tx, ty, detail); decode_feature(&meta, geom, z, tx, ty, detail);
if (t == VT_LINE || t == VT_POLYGON) {
len = remove_noop(geom, len);
}
if (t == VT_POINT || draw(geom, len, NULL)) { if (t == VT_POINT || draw(geom, len, NULL)) {
struct pool_val *pv = pool_long_long(&dup, &i->fpos, 0); struct pool_val *pv = pool_long_long(&dup, &i->fpos, 0);
if (pv->n == 0) { if (pv->n == 0) {