fix: SimplifyDP handling of 'multi' geometries

This commit is contained in:
Hannes Janetzek 2014-04-20 00:19:56 +02:00
parent d6b95c936a
commit 0139452787

View File

@ -20,6 +20,8 @@ package org.oscim.utils.geom;
import static org.oscim.utils.geom.GeometryUtils.squareSegmentDistance; import static org.oscim.utils.geom.GeometryUtils.squareSegmentDistance;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Douglas-Peucker line simplification with stack and some bit twiddling. * Douglas-Peucker line simplification with stack and some bit twiddling.
@ -28,8 +30,9 @@ import org.oscim.core.GeometryBuffer;
* https://github.com/ekeneijeoma/simplify-java * https://github.com/ekeneijeoma/simplify-java
*/ */
public class SimplifyDP { public class SimplifyDP {
final static Logger log = LoggerFactory.getLogger(SimplifyDP.class);
int[] markers = new int[1]; boolean[] markers = new boolean[128];
int[] stack = new int[32]; int[] stack = new int[32];
public void simplify(GeometryBuffer geom, float sqTolerance) { public void simplify(GeometryBuffer geom, float sqTolerance) {
@ -48,27 +51,24 @@ public class SimplifyDP {
continue; continue;
} }
int cnt = simplify(geom.points, inPos, len, outPos, sqTolerance); int end = simplify(geom.points, inPos, len, outPos, sqTolerance);
idx[i] = (short) cnt; if (end > inPos + len)
outPos += cnt; log.error("out larger than cur: {} > {}", end, inPos + len);
idx[i] = (short) (end - outPos);
outPos = end;
inPos += len; inPos += len;
} }
} }
public int simplify(float[] points, int inPos, int length, int out, float sqTolerance) { public int simplify(float[] points, int inPos, int length, int out, float sqTolerance) {
/* cheap int bitset (use length / 32 ints) if ((length >> 1) >= markers.length)
* might should use boolean, or BitSet, markers = new boolean[length >> 1];
* as this is not really a memory hog :) */ //else
int n = (length >> 5) + 1; // Arrays.fill(markers, false);
if (markers.length < n) {
markers = new int[n];
} else {
for (int i = 0; i < n; i++)
markers[i] = 0;
}
int first = 0; int first = inPos;
int last = inPos + length - 2; int last = inPos + length - 2;
int index = 0; int index = 0;
@ -88,11 +88,7 @@ public class SimplifyDP {
} }
if (maxSqDist > sqTolerance) { if (maxSqDist > sqTolerance) {
/* get marker for 'pos' and shift marker relative markers[(index - inPos) >> 1] = true;
* position into it;
* (pos & 0x1F == pos % 32) */
int pos = index >> 1;
markers[pos >> 5] |= 1 << (pos & 0x1F);
if (sp + 4 == stack.length) { if (sp + 4 == stack.length) {
int tmp[] = new int[stack.length + 64]; int tmp[] = new int[stack.length + 64];
@ -119,22 +115,15 @@ public class SimplifyDP {
last = inPos + length - 2; last = inPos + length - 2;
O: for (int i = 0; i < markers.length; i++) { for (int i = 0; i < length / 2; i++) {
int marker = markers[i]; if (!markers[i])
/* point position of this marker */ continue;
int mPos = (i << 6); markers[i] = false;
for (int j = 0; j < 32; j++) { int pos = inPos + i * 2;
/* check if marker is set */
if ((marker & (1 << j)) != 0) {
int pos = mPos + (j << 1);
if (pos >= last)
break O;
points[out++] = points[pos]; points[out++] = points[pos];
points[out++] = points[pos + 1]; points[out++] = points[pos + 1];
}
}
} }
points[out++] = points[last]; points[out++] = points[last];
points[out++] = points[last + 1]; points[out++] = points[last + 1];