- 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.layer.SymbolLayer;
import org.oscim.renderer.overlays.BasicOverlay;
import org.oscim.utils.FastMath;
import org.oscim.utils.GeometryUtils;
import org.oscim.view.MapView;
import android.content.res.Resources;
@ -54,6 +54,8 @@ import android.graphics.drawable.Drawable;
public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay implements
Overlay.Snappable {
//private final static String TAG = ItemizedOverlay.class.getName();
protected final Drawable mDefaultMarker;
protected boolean mDrawFocusedItem = true;
@ -74,14 +76,10 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
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 {
private final SymbolLayer mSymbolLayer;
private final float[] mVec = new float[3];
private final float[] mBox = new float[8];
public ItemOverlay(MapView mapView) {
super(mapView);
@ -99,22 +97,16 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
mUpdate = false;
int zoom = curPos.zoomLevel;
float div = FastMath.pow(zoom - MAX_ZOOM);
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);
double mx = curPos.x;
double my = curPos.y;
double scale = Tile.SIZE * curPos.scale;
int changesInvisible = 0;
int changedVisible = 0;
int numVisible = 0;
mMapView.getMapViewPosition().getMapViewProjection(mBox);
synchronized (lock) {
if (mItems == null) {
if (layers.textureLayers != null) {
@ -124,45 +116,29 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
return;
}
// check changes
// check visibility
for (InternalItem it = mItems; it != null; it = it.next) {
it.x = (float)((it.px * div) - mx);
it.y = (float)((it.py * div) - my);
it.x = (float) ((it.px - mx) * scale);
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) {
it.changes = true;
changesInvisible++;
}
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) {
it.visible = true;
changedVisible++;
}
it.changes = false;
numVisible++;
if (!it.visible) {
it.visible = true;
changedVisible++;
}
numVisible++;
}
//Log.d(TAG, numVisible + " " + changedVisible + " " + changesInvisible);
// only update when zoomlevel changed, new items are visible
// or more than 10 of the current items became invisible
if ((numVisible == 0) && (changedVisible == 0 && changesInvisible < 10))
@ -172,9 +148,6 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
// updateMapPosition();
mMapPosition.copy(curPos);
// items are placed relative to zoomLevel
mMapPosition.scale = 1 << zoom;
layers.clear();
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;
mLayer = new ItemOverlay(mapView);
MAX_SCALE = (1 << MAX_ZOOM) * Tile.SIZE;
}
private final PointD mMapPoint = new PointD();
@ -276,8 +247,8 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
// pre-project points
MercatorProjection.project(it.item.mGeoPoint, mMapPoint);
it.px = (mMapPoint.x * MAX_SCALE);
it.py = (mMapPoint.y * MAX_SCALE);
it.px = mMapPoint.x;
it.py = mMapPoint.y;
}
mUpdate = true;
}