- determine item visibility with unprojected screen coordinates

- use absolute projected position now that coordinates are double
This commit is contained in:
Hannes Janetzek 2013-04-18 20:22:19 +02:00
parent fde9109695
commit dcae12bbc3

View File

@ -29,7 +29,7 @@ import org.oscim.overlay.OverlayItem.HotspotPlace;
import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLRenderer.Matrices;
import org.oscim.renderer.layer.SymbolLayer; import org.oscim.renderer.layer.SymbolLayer;
import org.oscim.renderer.overlays.BasicOverlay; import org.oscim.renderer.overlays.BasicOverlay;
import org.oscim.utils.FastMath; import org.oscim.utils.GeometryUtils;
import org.oscim.view.MapView; import org.oscim.view.MapView;
import android.content.res.Resources; import android.content.res.Resources;
@ -54,6 +54,8 @@ import android.graphics.drawable.Drawable;
public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay implements public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay implements
Overlay.Snappable { Overlay.Snappable {
//private final static String TAG = ItemizedOverlay.class.getName();
protected final Drawable mDefaultMarker; protected final Drawable mDefaultMarker;
protected boolean mDrawFocusedItem = true; protected boolean mDrawFocusedItem = true;
@ -74,14 +76,10 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
private int mSize; private int mSize;
// pre-projected points to zoomlevel 20
private static final byte MAX_ZOOM = 22;
private final double MAX_SCALE;
class ItemOverlay extends BasicOverlay { class ItemOverlay extends BasicOverlay {
private final SymbolLayer mSymbolLayer; private final SymbolLayer mSymbolLayer;
private final float[] mVec = new float[3]; private final float[] mBox = new float[8];
public ItemOverlay(MapView mapView) { public ItemOverlay(MapView mapView) {
super(mapView); super(mapView);
@ -99,22 +97,16 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
mUpdate = false; mUpdate = false;
int zoom = curPos.zoomLevel; double mx = curPos.x;
float div = FastMath.pow(zoom - MAX_ZOOM); double my = curPos.y;
double scale = Tile.SIZE * curPos.scale;
double mx = curPos.x * (Tile.SIZE << zoom);
double my = curPos.y * (Tile.SIZE << zoom);
// limit could be 1 if we update on every position change
float limit = 1.5f;
// no need to project these
int max = (1 << 11);
int changesInvisible = 0; int changesInvisible = 0;
int changedVisible = 0; int changedVisible = 0;
int numVisible = 0; int numVisible = 0;
mMapView.getMapViewPosition().getMapViewProjection(mBox);
synchronized (lock) { synchronized (lock) {
if (mItems == null) { if (mItems == null) {
if (layers.textureLayers != null) { if (layers.textureLayers != null) {
@ -124,44 +116,28 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
return; return;
} }
// check changes // check visibility
for (InternalItem it = mItems; it != null; it = it.next) { for (InternalItem it = mItems; it != null; it = it.next) {
it.x = (float)((it.px * div) - mx); it.x = (float) ((it.px - mx) * scale);
it.y = (float)((it.py * div) - my); it.y = (float) ((it.py - my) * scale);
it.changes = false;
if (it.x > max || it.x < -max || it.y > max || it.y < -max) { if (!GeometryUtils.pointInPoly(it.x, it.y, mBox, 8, 0)) {
if (it.visible) { if (it.visible) {
it.changes = true; it.changes = true;
changesInvisible++; changesInvisible++;
} }
continue; continue;
} }
// map points to screen
mVec[0] = it.x;
mVec[1] = it.y;
mVec[2] = 0;
matrices.viewproj.prj(mVec);
float sx = mVec[0];
float sy = mVec[1];
// check if it is visible
if (sx < -limit || sx > limit || sy < -limit || sy > limit) {
// Log.d("..", "outside " + it.x + " " + it.y + " -> " + sx + " " + sy);
if (it.visible) {
it.changes = true;
changesInvisible++;
}
} else {
if (!it.visible) { if (!it.visible) {
it.visible = true; it.visible = true;
changedVisible++; changedVisible++;
} }
it.changes = false;
numVisible++; numVisible++;
} }
}
//Log.d(TAG, numVisible + " " + changedVisible + " " + changesInvisible);
// only update when zoomlevel changed, new items are visible // only update when zoomlevel changed, new items are visible
// or more than 10 of the current items became invisible // or more than 10 of the current items became invisible
@ -172,9 +148,6 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
// updateMapPosition(); // updateMapPosition();
mMapPosition.copy(curPos); mMapPosition.copy(curPos);
// items are placed relative to zoomLevel
mMapPosition.scale = 1 << zoom;
layers.clear(); layers.clear();
for (InternalItem it = mItems; it != null; it = it.next) { for (InternalItem it = mItems; it != null; it = it.next) {
@ -236,8 +209,6 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
this.mDefaultMarker = pDefaultMarker; this.mDefaultMarker = pDefaultMarker;
mLayer = new ItemOverlay(mapView); mLayer = new ItemOverlay(mapView);
MAX_SCALE = (1 << MAX_ZOOM) * Tile.SIZE;
} }
private final PointD mMapPoint = new PointD(); private final PointD mMapPoint = new PointD();
@ -276,8 +247,8 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
// pre-project points // pre-project points
MercatorProjection.project(it.item.mGeoPoint, mMapPoint); MercatorProjection.project(it.item.mGeoPoint, mMapPoint);
it.px = (mMapPoint.x * MAX_SCALE); it.px = mMapPoint.x;
it.py = (mMapPoint.y * MAX_SCALE); it.py = mMapPoint.y;
} }
mUpdate = true; mUpdate = true;
} }