MarkerLayer: check if touch hits within marker extents

This commit is contained in:
Hannes Janetzek 2014-02-09 17:00:31 +01:00
parent eb9194fe73
commit 99b7a5eb74
2 changed files with 44 additions and 29 deletions

View File

@ -172,8 +172,10 @@ public class ItemizedLayer<Item extends MarkerItem> extends MarkerLayer<Item>
BoundingBox bbox = mapPosition.getBBox(); BoundingBox bbox = mapPosition.getBBox();
int nearest = -1; int nearest = -1;
int inside = -1;
double insideY = -Double.MAX_VALUE;
/* squared dist: 50*50 pixel */ /* squared dist: 50*50 pixel ~ 2mm on 400dpi */
double dist = 2500; double dist = 2500;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@ -187,6 +189,19 @@ public class ItemizedLayer<Item extends MarkerItem> extends MarkerLayer<Item>
float dx = (float) (mTmpPoint.x - eventX); float dx = (float) (mTmpPoint.x - eventX);
float dy = (float) (mTmpPoint.y - eventY); float dy = (float) (mTmpPoint.y - eventY);
MarkerSymbol it = item.getMarker();
if (it == null)
it = mMarkerRenderer.mDefaultMarker;
if (it.isInside(dx, dy)) {
if (mTmpPoint.y > insideY) {
insideY = mTmpPoint.y;
inside = i;
}
}
if (inside >= 0)
continue;
double d = dx * dx + dy * dy; double d = dx * dx + dy * dy;
if (d > dist) if (d > dist)
continue; continue;
@ -195,9 +210,14 @@ public class ItemizedLayer<Item extends MarkerItem> extends MarkerLayer<Item>
nearest = i; nearest = i;
} }
if (nearest >= 0 && task.run(nearest)) if (inside >= 0)
return true; nearest = inside;
if (nearest >= 0 && task.run(nearest)) {
mMarkerRenderer.update();
mMap.render();
return true;
}
return false; return false;
} }

View File

@ -22,7 +22,7 @@ import org.oscim.layers.marker.MarkerItem.HotspotPlace;
public class MarkerSymbol { public class MarkerSymbol {
final Bitmap[] mBitmap; final Bitmap[] mBitmap;
// Hotspot offset /** Hotspot offset */
final PointF mOffset; final PointF mOffset;
public MarkerSymbol(Bitmap bitmap, float relX, float relY) { public MarkerSymbol(Bitmap bitmap, float relX, float relY) {
@ -32,52 +32,38 @@ public class MarkerSymbol {
} }
public MarkerSymbol(Bitmap bitmap, HotspotPlace hotspot) { public MarkerSymbol(Bitmap bitmap, HotspotPlace hotspot) {
float x = 0, y = 0;
switch (hotspot) { switch (hotspot) {
default:
case NONE:
break;
case CENTER:
x = 0.5f;
y = 0.5f;
break;
case BOTTOM_CENTER: case BOTTOM_CENTER:
x = 0.5f; mOffset = new PointF(0.5f, 1);
y = 1.0f;
break; break;
case TOP_CENTER: case TOP_CENTER:
x = 0.5f; mOffset = new PointF(0.5f, 0);
y = 0.0f;
break; break;
case RIGHT_CENTER: case RIGHT_CENTER:
x = 1.0f; mOffset = new PointF(1, 0.5f);
y = 0.5f;
break; break;
case LEFT_CENTER: case LEFT_CENTER:
x = 0.0f; mOffset = new PointF(0, 0.5f);
y = 0.5f;
break; break;
case UPPER_RIGHT_CORNER: case UPPER_RIGHT_CORNER:
x = 1.0f; mOffset = new PointF(1, 0);
y = 0.0f;
break; break;
case LOWER_RIGHT_CORNER: case LOWER_RIGHT_CORNER:
x = 1.0f; mOffset = new PointF(1, 1);
y = 1.0f;
break; break;
case UPPER_LEFT_CORNER: case UPPER_LEFT_CORNER:
x = 0.0f; mOffset = new PointF(0, 0);
y = 0.0f;
break; break;
case LOWER_LEFT_CORNER: case LOWER_LEFT_CORNER:
x = 0.0f; mOffset = new PointF(0, 1);
y = 1.0f;
break; break;
default:
mOffset = new PointF(0.5f, 0.5f);
} }
mBitmap = new Bitmap[1]; mBitmap = new Bitmap[1];
mBitmap[0] = bitmap; mBitmap[0] = bitmap;
mOffset = new PointF(x, y);
} }
public PointF getHotspot() { public PointF getHotspot() {
@ -88,4 +74,13 @@ public class MarkerSymbol {
return mBitmap[0]; return mBitmap[0];
} }
public boolean isInside(float dx, float dy) {
int w = mBitmap[0].getWidth();
int h = mBitmap[0].getHeight();
float ox = -w * mOffset.x;
float oy = -h * (1 - mOffset.y);
return dx >= ox && dy >= oy && dx <= ox + w && dy <= oy + h;
}
} }