use OBBs for label collision detections
This commit is contained in:
parent
f2f93d180b
commit
e69bebb2c5
@ -15,6 +15,7 @@
|
|||||||
package org.oscim.renderer.layer;
|
package org.oscim.renderer.layer;
|
||||||
|
|
||||||
import org.oscim.theme.renderinstruction.Text;
|
import org.oscim.theme.renderinstruction.Text;
|
||||||
|
import org.oscim.utils.OBB2D;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -120,6 +121,9 @@ public class TextItem {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* copy properties from 'ti' and add offset
|
||||||
|
*
|
||||||
|
* */
|
||||||
public TextItem move(TextItem ti, float dx, float dy, float scale) {
|
public TextItem move(TextItem ti, float dx, float dy, float scale) {
|
||||||
this.x = dx + (ti.x * scale);
|
this.x = dx + (ti.x * scale);
|
||||||
this.y = dy + (ti.y * scale);
|
this.y = dy + (ti.y * scale);
|
||||||
@ -129,6 +133,13 @@ public class TextItem {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAxisAlignedBBox(){
|
||||||
|
this.x1 = x - width / 2;
|
||||||
|
this.y1 = y - text.fontHeight / 2;
|
||||||
|
this.x2 = x + width / 2;
|
||||||
|
this.y2 = y + text.fontHeight / 2;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean bboxOverlaps(TextItem it1, TextItem it2, float add) {
|
public static boolean bboxOverlaps(TextItem it1, TextItem it2, float add) {
|
||||||
if (it1.y1 < it1.y2) {
|
if (it1.y1 < it1.y2) {
|
||||||
if (it2.y1 < it2.y2)
|
if (it2.y1 < it2.y2)
|
||||||
@ -174,4 +185,5 @@ public class TextItem {
|
|||||||
public byte origin;
|
public byte origin;
|
||||||
|
|
||||||
public int active;
|
public int active;
|
||||||
|
public OBB2D bbox;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
package org.oscim.renderer.overlays;
|
package org.oscim.renderer.overlays;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.generator.JobTile;
|
import org.oscim.generator.JobTile;
|
||||||
@ -33,8 +35,8 @@ import org.oscim.renderer.layer.TextItem;
|
|||||||
import org.oscim.renderer.layer.TextLayer;
|
import org.oscim.renderer.layer.TextLayer;
|
||||||
import org.oscim.theme.renderinstruction.Line;
|
import org.oscim.theme.renderinstruction.Line;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.utils.GeometryUtils;
|
|
||||||
import org.oscim.utils.GlUtils;
|
import org.oscim.utils.GlUtils;
|
||||||
|
import org.oscim.utils.OBB2D;
|
||||||
import org.oscim.utils.PausableThread;
|
import org.oscim.utils.PausableThread;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
@ -43,9 +45,10 @@ import android.graphics.Paint.Cap;
|
|||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
import android.opengl.Matrix;
|
import android.opengl.Matrix;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
public class TextOverlayExp extends BasicOverlay {
|
public class TextOverlayExp extends BasicOverlay {
|
||||||
// private final static String TAG = TextOverlayExp.class.getName();
|
private final static String TAG = TextOverlayExp.class.getName();
|
||||||
|
|
||||||
private TileSet mTileSet;
|
private TileSet mTileSet;
|
||||||
private final LabelThread mThread;
|
private final LabelThread mThread;
|
||||||
@ -98,24 +101,24 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
mThread.start();
|
mThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// private HashMap<TextItem, PlacementItem> mItemMap;
|
private HashMap<MapTile, PlacementItem> mItemMap;
|
||||||
//
|
|
||||||
// class PlacementItem extends TextItem {
|
class PlacementItem extends TextItem {
|
||||||
// int tileX;
|
int tileX;
|
||||||
// int tileY;
|
int tileY;
|
||||||
//
|
|
||||||
// boolean isTileNeighbour(PlacementItem other) {
|
boolean isTileNeighbour(PlacementItem other) {
|
||||||
// int dx = other.tileX - tileX;
|
int dx = other.tileX - tileX;
|
||||||
// if (dx > 1 || dx < -1)
|
if (dx > 1 || dx < -1)
|
||||||
// return false;
|
return false;
|
||||||
//
|
|
||||||
// int dy = other.tileY - tileY;
|
int dy = other.tileY - tileY;
|
||||||
// if (dy > 1 || dy < -1)
|
if (dy > 1 || dy < -1)
|
||||||
// return false;
|
return false;
|
||||||
//
|
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// local pool, avoids synchronized TextItem.get()/release()
|
// local pool, avoids synchronized TextItem.get()/release()
|
||||||
private TextItem mPool;
|
private TextItem mPool;
|
||||||
@ -158,20 +161,32 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TextItem.bboxOverlaps(ti, lp, 10)) {
|
// if (!TextItem.bboxOverlaps(ti, lp, 10)) {
|
||||||
lp = lp.next;
|
// lp = lp.next;
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
byte intersect = GeometryUtils.linesIntersect(
|
if (ti.bbox == null) {
|
||||||
ti.x1, ti.y1, ti.x2, ti.y2,
|
ti.bbox = new OBB2D(ti.x, ti.y, ti.x1, ti.y1, ti.width + 10,
|
||||||
lp.x1, lp.y1, lp.x2, lp.y2);
|
ti.text.fontHeight + 10);
|
||||||
|
//Log.d(TAG,"add > " + ti.string + " " + Arrays.toString(ti.bbox.axis)+ " / " + Arrays.toString(ti.bbox.origin));
|
||||||
|
}
|
||||||
|
if (lp.bbox == null) {
|
||||||
|
lp.bbox = new OBB2D(lp.x, lp.y, lp.x1, lp.y1, lp.width + 10,
|
||||||
|
lp.text.fontHeight + 10);
|
||||||
|
//Log.d(TAG,"add > " + lp.string + " " + Arrays.toString(lp.bbox.axis) + " / " + Arrays.toString(lp.bbox.origin));
|
||||||
|
}
|
||||||
|
byte intersect = (byte) (ti.bbox.overlaps(lp.bbox) ? 1 : 0);
|
||||||
|
|
||||||
|
// byte intersect = GeometryUtils.linesIntersect(
|
||||||
|
// ti.x1, ti.y1, ti.x2, ti.y2,
|
||||||
|
// lp.x1, lp.y1, lp.x2, lp.y2);
|
||||||
|
|
||||||
if (intersect != 0) {
|
if (intersect != 0) {
|
||||||
//Log.d(TAG, "intersection " + lp.string + " <> " + ti.string
|
Log.d(TAG, "intersection " + lp.string + " <> " + ti.string
|
||||||
// + " at " + ti.x + ":" + ti.y);
|
+ " at " + ti.x + ":" + ti.y);
|
||||||
|
|
||||||
if (lp.active < ti.active) {
|
if (lp.text.priority > ti.text.priority || lp.active < ti.active) {
|
||||||
//if (lp.length > ti.length) {
|
//if (lp.length > ti.length) {
|
||||||
//Log.d(TAG, "drop " + lp.string);
|
//Log.d(TAG, "drop " + lp.string);
|
||||||
TextItem tmp = lp;
|
TextItem tmp = lp;
|
||||||
@ -187,21 +202,21 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
|
|
||||||
return intersect;
|
return intersect;
|
||||||
|
|
||||||
// if ((lp.n1 != null && lp.n1 == ti.n2) ||
|
// if ((lp.n1 != null && lp.n1 == ti.n2) ||
|
||||||
// (lp.n2 != null && lp.n2 == ti.n1)) {
|
// (lp.n2 != null && lp.n2 == ti.n1)) {
|
||||||
// Log.d(TAG, "overlap with adjacent label " + lp.string
|
// Log.d(TAG, "overlap with adjacent label " + lp.string
|
||||||
// + " at " + ti.x + ":" + ti.y + ", " + lp.x + ":" + lp.y);
|
// + " at " + ti.x + ":" + ti.y + ", " + lp.x + ":" + lp.y);
|
||||||
//
|
//
|
||||||
// return intersect;
|
// return intersect;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// if ((ti.n1 != null || ti.n2 != null) && (lp.n1 == null && lp.n2 == null)) {
|
// if ((ti.n1 != null || ti.n2 != null) && (lp.n1 == null && lp.n2 == null)) {
|
||||||
// Log.d(TAG, "overlap, other is unique " + lp.string + " " + ti.string
|
// Log.d(TAG, "overlap, other is unique " + lp.string + " " + ti.string
|
||||||
// + " at " + ti.x + ":" + ti.y + ", " + lp.x + ":" + lp.y);
|
// + " at " + ti.x + ":" + ti.y + ", " + lp.x + ":" + lp.y);
|
||||||
// return intersect;
|
// return intersect;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// return intersect;
|
// return intersect;
|
||||||
}
|
}
|
||||||
|
|
||||||
lp = lp.next;
|
lp = lp.next;
|
||||||
@ -223,7 +238,7 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
TextLayer tl = mTmpLayer;
|
TextLayer tl = mTmpLayer;
|
||||||
mTmpLayer = null;
|
mTmpLayer = null;
|
||||||
|
|
||||||
//mDebugLayer = new Layers();
|
Layers dbg = null; //new Layers();
|
||||||
|
|
||||||
// mTiles might be from another zoomlevel than the current:
|
// mTiles might be from another zoomlevel than the current:
|
||||||
// this scales MapPosition to the zoomlevel of mTiles...
|
// this scales MapPosition to the zoomlevel of mTiles...
|
||||||
@ -241,23 +256,24 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
double angle = Math.toRadians(mTmpPos.angle);
|
double angle = Math.toRadians(mTmpPos.angle);
|
||||||
float cos = (float) Math.cos(angle);
|
float cos = (float) Math.cos(angle);
|
||||||
float sin = (float) Math.sin(angle);
|
float sin = (float) Math.sin(angle);
|
||||||
|
Log.d(TAG, "angle " + mTmpPos.angle + " " + cos + " " + sin);
|
||||||
|
|
||||||
int maxx = Tile.TILE_SIZE << (mTmpPos.zoomLevel - 1);
|
int maxx = Tile.TILE_SIZE << (mTmpPos.zoomLevel - 1);
|
||||||
|
|
||||||
TextItem ti2 = null;
|
TextItem ti2 = null;
|
||||||
|
|
||||||
if (mDebugLayer != null) {
|
if (dbg != null) {
|
||||||
mDebugLayer.clear();
|
dbg.clear();
|
||||||
LineLayer ll = (LineLayer) mDebugLayer.getLayer(0, Layer.LINE);
|
LineLayer ll = (LineLayer) dbg.getLayer(0, Layer.LINE);
|
||||||
ll.line = new Line((Color.BLUE & 0xaaffffff), 1, Cap.BUTT);
|
ll.line = new Line((Color.BLUE & 0xaaffffff), 1, Cap.BUTT);
|
||||||
ll.width = 2;
|
ll.width = 2;
|
||||||
ll = (LineLayer) mDebugLayer.getLayer(3, Layer.LINE);
|
ll = (LineLayer) dbg.getLayer(3, Layer.LINE);
|
||||||
ll.line = new Line((Color.YELLOW & 0xaaffffff), 1, Cap.BUTT);
|
ll.line = new Line((Color.YELLOW & 0xaaffffff), 1, Cap.BUTT);
|
||||||
ll.width = 2;
|
ll.width = 2;
|
||||||
ll = (LineLayer) mDebugLayer.getLayer(1, Layer.LINE);
|
ll = (LineLayer) dbg.getLayer(1, Layer.LINE);
|
||||||
ll.line = new Line((Color.RED & 0xaaffffff), 1, Cap.BUTT);
|
ll.line = new Line((Color.RED & 0xaaffffff), 1, Cap.BUTT);
|
||||||
ll.width = 2;
|
ll.width = 2;
|
||||||
ll = (LineLayer) mDebugLayer.getLayer(2, Layer.LINE);
|
ll = (LineLayer) dbg.getLayer(2, Layer.LINE);
|
||||||
ll.line = new Line((Color.GREEN & 0xaaffffff), 1, Cap.BUTT);
|
ll.line = new Line((Color.GREEN & 0xaaffffff), 1, Cap.BUTT);
|
||||||
ll.width = 2;
|
ll.width = 2;
|
||||||
}
|
}
|
||||||
@ -299,27 +315,21 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
|
|
||||||
if (ti.text.caption) {
|
if (ti.text.caption) {
|
||||||
ti2.move(ti, dx, dy, scale);
|
ti2.move(ti, dx, dy, scale);
|
||||||
int tx = (int) (ti2.x);
|
ti2.setAxisAlignedBBox();
|
||||||
int ty = (int) (ti2.y);
|
ti2.bbox = new OBB2D(ti2.x, ti2.y, cos, -sin, ti2.width + 6,
|
||||||
int tw = (int) (ti2.width / 2);
|
ti2.text.fontHeight + 6, true);
|
||||||
int th = (int) (ti2.text.fontHeight / 2);
|
|
||||||
|
|
||||||
boolean overlaps = false;
|
boolean overlaps = false;
|
||||||
for (TextItem lp = tl.labels; lp != null;) {
|
for (TextItem lp = tl.labels; lp != null; lp = lp.next) {
|
||||||
int px = (int) (lp.x);
|
if (!lp.text.caption)
|
||||||
int py = (int) (lp.y);
|
continue;
|
||||||
int ph = (int) (lp.text.fontHeight / 2);
|
|
||||||
int pw = (int) (lp.width / 2);
|
|
||||||
|
|
||||||
if ((tx - tw) < (px + pw)
|
|
||||||
&& (px - pw) < (tx + tw)
|
|
||||||
&& (ty - th) < (py + ph)
|
|
||||||
&& (py - ph) < (ty + th)) {
|
|
||||||
|
|
||||||
|
if (ti2.bbox.overlaps(lp.bbox)) {
|
||||||
|
Log.d(TAG, "overlap > " + ti2.string + " " + lp.string);
|
||||||
|
//if (TextItem.bboxOverlaps(ti2, lp, 4)) {
|
||||||
overlaps = true;
|
overlaps = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lp = lp.next;
|
|
||||||
}
|
}
|
||||||
if (!overlaps) {
|
if (!overlaps) {
|
||||||
tl.addText(ti2);
|
tl.addText(ti2);
|
||||||
@ -332,13 +342,14 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
/* text is way label */
|
/* text is way label */
|
||||||
|
|
||||||
// check if path at current scale is long enough for text
|
// check if path at current scale is long enough for text
|
||||||
if (mDebugLayer == null && ti.width > ti.length * scale)
|
if (dbg == null && ti.width > ti.length * scale)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// set line endpoints relative to view to be able to
|
// set line endpoints relative to view to be able to
|
||||||
// check intersections with label from other tiles
|
// check intersections with label from other tiles
|
||||||
float width = (ti.x2 - ti.x1) / 2f;
|
float width = (ti.x2 - ti.x1) / 2f;
|
||||||
float height = (ti.y2 - ti.y1) / 2f;
|
float height = (ti.y2 - ti.y1) / 2f;
|
||||||
|
ti2.bbox = null;
|
||||||
|
|
||||||
ti2.move(ti, dx, dy, scale);
|
ti2.move(ti, dx, dy, scale);
|
||||||
ti2.x2 = (ti2.x + width);
|
ti2.x2 = (ti2.x + width);
|
||||||
@ -348,30 +359,44 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
|
|
||||||
byte overlaps = -1;
|
byte overlaps = -1;
|
||||||
|
|
||||||
if (mDebugLayer == null || ti.width < ti.length * scale)
|
if (dbg == null || ti.width < ti.length * scale)
|
||||||
overlaps = checkOverlap(tl, ti2);
|
overlaps = checkOverlap(tl, ti2);
|
||||||
|
|
||||||
if (mDebugLayer != null) {
|
if (dbg != null) {
|
||||||
|
|
||||||
LineLayer ll;
|
LineLayer ll;
|
||||||
if (ti.width > ti.length * scale) {
|
if (ti.width > ti.length * scale) {
|
||||||
ll = (LineLayer) mDebugLayer.getLayer(1, Layer.LINE);
|
ll = (LineLayer) dbg.getLayer(1, Layer.LINE);
|
||||||
overlaps = 3;
|
overlaps = 3;
|
||||||
}
|
}
|
||||||
else if (overlaps == 1)
|
else if (overlaps == 1)
|
||||||
ll = (LineLayer) mDebugLayer.getLayer(0, Layer.LINE);
|
ll = (LineLayer) dbg.getLayer(0, Layer.LINE);
|
||||||
else if (overlaps == 2)
|
else if (overlaps == 2)
|
||||||
ll = (LineLayer) mDebugLayer.getLayer(3, Layer.LINE);
|
ll = (LineLayer) dbg.getLayer(3, Layer.LINE);
|
||||||
else
|
else
|
||||||
ll = (LineLayer) mDebugLayer.getLayer(2, Layer.LINE);
|
ll = (LineLayer) dbg.getLayer(2, Layer.LINE);
|
||||||
|
|
||||||
float[] points = new float[4];
|
// if (ti2.bbox == null)
|
||||||
short[] indices = { 4 };
|
// ti2.bbox = new OBB2D(ti2.x, ti2.y, ti2.x1, ti2.y1, ti.width + 10,
|
||||||
points[0] = ti2.x1 / scale;
|
// ti.text.fontHeight + 10);
|
||||||
points[1] = ti2.y1 / scale;
|
|
||||||
points[2] = ti2.x2 / scale;
|
{
|
||||||
points[3] = ti2.y2 / scale;
|
float[] points = new float[4];
|
||||||
ll.addLine(points, indices, false);
|
short[] indices = { 4 };
|
||||||
|
points[0] = (ti2.x - width * scale) / scale;
|
||||||
|
points[1] = (ti2.y - height * scale) / scale;
|
||||||
|
points[2] = (ti2.x + width * scale) / scale;
|
||||||
|
points[3] = (ti2.y + height * scale) / scale;
|
||||||
|
ll.addLine(points, indices, false);
|
||||||
|
}
|
||||||
|
if (ti2.bbox != null) {
|
||||||
|
short[] indices = { 8 };
|
||||||
|
float[] points = new float[8];
|
||||||
|
for (int p = 0; p < 8; p++)
|
||||||
|
points[p] = ti2.bbox.corner[p] / scale;
|
||||||
|
|
||||||
|
ll.addLine(points, indices, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (overlaps == 0) {
|
if (overlaps == 0) {
|
||||||
ti.active++;
|
ti.active++;
|
||||||
@ -424,6 +449,7 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
// pass new labels for rendering
|
// pass new labels for rendering
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
mNextLayer = tl;
|
mNextLayer = tl;
|
||||||
|
mDebugLayer = dbg;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -441,7 +467,7 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
|
|
||||||
if (mDebugLayer != null) {
|
if (mDebugLayer != null) {
|
||||||
layers.layers = mDebugLayer.layers;
|
layers.layers = mDebugLayer.layers;
|
||||||
mDebugLayer.layers = null;
|
mDebugLayer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set new TextLayer to be uploaded and rendered
|
// set new TextLayer to be uploaded and rendered
|
||||||
@ -511,9 +537,9 @@ public class TextOverlayExp extends BasicOverlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Layer l = layers.textureLayers; l != null;) {
|
for (Layer l = layers.textureLayers; l != null;) {
|
||||||
l = TextureRenderer.draw(l, (mMapPosition.scale / pos.scale) * div
|
l = TextureRenderer.draw(l, (mMapPosition.scale / pos.scale) * div, proj, mv);
|
||||||
, proj, mv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user