fix multipolygon rendering bug

git-svn-id: https://osmand.googlecode.com/svn/trunk@875 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2011-01-09 00:08:41 +00:00
parent d7af7d05f5
commit 8c8cc3b266
2 changed files with 82 additions and 61 deletions

View file

@ -494,8 +494,8 @@ public class MapRenderRepositories {
x = o.getPoint31XTile(km == 0 ? i : len - i - 1); x = o.getPoint31XTile(km == 0 ? i : len - i - 1);
y = o.getPoint31YTile(km == 0 ? i : len - i - 1); y = o.getPoint31YTile(km == 0 ? i : len - i - 1);
boolean inside = leftX <= x && x <= rightX && y >= topY && y <= bottomY; boolean inside = leftX <= x && x <= rightX && y >= topY && y <= bottomY;
calculateLineCoordinates(inside, x, y, pinside, px, py, leftX, rightX, bottomY, topY, coordinates); boolean lineEnded = calculateLineCoordinates(inside, x, y, pinside, px, py, leftX, rightX, bottomY, topY, coordinates);
if(pinside && !inside){ if(lineEnded){
processMultipolygonLine(completedRings, incompletedRings, completedRingNames, incompletedRingNames, processMultipolygonLine(completedRings, incompletedRings, completedRingNames, incompletedRingNames,
coordinates, o.getName()); coordinates, o.getName());
// create new line if it goes outside // create new line if it goes outside
@ -677,6 +677,8 @@ public class MapRenderRepositories {
int x = (int) (i.get(i.size() - 1) >> 32); int x = (int) (i.get(i.size() - 1) >> 32);
int y = (int) (i.get(i.size() - 1) & mask); int y = (int) (i.get(i.size() - 1) & mask);
x = (int) (i.get(4) >> 32);
y = (int) (i.get(4) & mask);
// 31 - (zoom + 8) // 31 - (zoom + 8)
int EVAL_DELTA = 6 << (23 - zoom); int EVAL_DELTA = 6 << (23 - zoom);
int UNDEFINED_MIN_DIFF = -1 - EVAL_DELTA; int UNDEFINED_MIN_DIFF = -1 - EVAL_DELTA;
@ -779,41 +781,13 @@ public class MapRenderRepositories {
completedRings.add(i); completedRings.add(i);
completedRingNames.add(name); completedRingNames.add(name);
} }
} }
private void calculateLineCoordinates(boolean inside, int x, int y, boolean pinside, int px, int py, int leftX, int rightX, /**
int bottomY, int topY, List<Long> coordinates) { * @return -1 if there is no instersection or x<<32 | y
if (pinside) { */
if(!inside) { private long calculateIntersection(int x, int y, boolean pinside, int px, int py, int leftX, int rightX,
int by = -1; int bottomY, int topY){
int bx = -1;
if (by == -1 && y < topY && py >= topY) {
int tx = (int) (px + ((double) (x - px) * (topY - py)) / (y - py));
if (leftX <= tx && tx <= rightX) {
bx = tx;
by = topY;
}
}
if (by == -1 && y > bottomY && py <= bottomY) {
int tx = (int) (px + ((double) (x - px) * (py - bottomY)) / (py - y));
if (leftX <= tx && tx <= rightX) {
bx = tx;
by = bottomY;
}
}
if (by == -1 && x < leftX && px >= leftX) {
by = (int) (py + ((double) (y - py) * (leftX - px)) / (x - px));
bx = leftX;
}
if (by == -1 && x > rightX && px <= rightX) {
by = (int) (py + ((double) (y - py) * (px - rightX)) / (px - x));
bx = rightX;
}
coordinates.add((((long) bx) << 32) | ((long) by));
}
} else if (inside) {
int by = -1; int by = -1;
int bx = -1; int bx = -1;
if (by == -1 && py < topY && y >= topY) { if (by == -1 && py < topY && y >= topY) {
@ -831,19 +805,65 @@ public class MapRenderRepositories {
} }
} }
if (by == -1 && px < leftX && x >= leftX) { if (by == -1 && px < leftX && x >= leftX) {
by = (int) (py + ((double) (y - py) * (leftX - px)) / (x - px)); int ty = (int) (py + ((double) (y - py) * (leftX - px)) / (x - px));
if (ty >= topY && ty <= bottomY) {
by = ty;
bx = leftX; bx = leftX;
} }
}
if (by == -1 && px > rightX && x <= rightX) { if (by == -1 && px > rightX && x <= rightX) {
by = (int) (py + ((double) (y - py) * (px - rightX)) / (px - x)); int ty = (int) (py + ((double) (y - py) * (px - rightX)) / (px - x));
if (ty >= topY && ty <= bottomY) {
by = ty;
bx = rightX; bx = rightX;
} }
coordinates.add((((long) bx) << 32) | ((long) by));
}
if(by == -1){
if(px == rightX || px == leftX || py == topY || py == bottomY){
bx = px;
by = py;
}
}
if (by != -1) {
return (((long) bx) << 32) | ((long) by);
}
return -1l;
} }
if (inside) { private boolean calculateLineCoordinates(boolean inside, int x, int y, boolean pinside, int px, int py, int leftX, int rightX,
int bottomY, int topY, List<Long> coordinates) {
boolean lineEnded = false;
if (pinside) {
if (!inside) {
long is = calculateIntersection(x, y, pinside, px, py, leftX, rightX, bottomY, topY);
if (is == -1) {
// it is an error (!)
is = (((long) px) << 32) | ((long) py);
}
coordinates.add(is);
lineEnded = true;
} else {
coordinates.add((((long) x) << 32) | ((long) y)); coordinates.add((((long) x) << 32) | ((long) y));
} }
} else {
long is = calculateIntersection(x, y, pinside, px, py, leftX, rightX, bottomY, topY);
if(inside){
// assert is != -1;
coordinates.add(is);
coordinates.add((((long) x) << 32) | ((long) y));
} else if(is != -1){
int bx = (int) (is >> 32);
int by = (int) (is & 0xffffffff);
coordinates.add(is);
is = calculateIntersection(x, y, pinside, bx, by, leftX, rightX, bottomY, topY);
coordinates.add(is);
lineEnded = true;
}
}
return lineEnded;
} }

View file

@ -697,10 +697,11 @@ public class OsmandRenderer {
} }
rc.main.updatePaint(paint); rc.main.updatePaint(paint);
canvas.drawPath(path, paint); canvas.drawPath(path, paint);
if (rc.second.strokeWidth != 0) { // for test purpose
//rc.second.strokeWidth = 1.5f; // rc.second.strokeWidth = 1.5f;
//rc.second.color = Color.BLACK; // rc.second.color = Color.BLACK;
if (rc.second.strokeWidth != 0) {
rc.second.updatePaint(paint); rc.second.updatePaint(paint);
canvas.drawPath(path, paint); canvas.drawPath(path, paint);
} }