change max zoom-level to 24
- fix bug in ScanBox where tiles where not visible when map rotation had a steep angle - refactor ScanBox, add transScale utility
This commit is contained in:
parent
8a808265a5
commit
24438c1e68
@ -310,24 +310,19 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
|
|
||||||
// lock tiles while updating isVisible state
|
// lock tiles while updating isVisible state
|
||||||
synchronized (GLRenderer.tilelock) {
|
synchronized (GLRenderer.tilelock) {
|
||||||
|
int tileZoom = tiles[0].zoomLevel;
|
||||||
|
|
||||||
for (int i = 0; i < mDrawTiles.cnt; i++)
|
for (int i = 0; i < mDrawTiles.cnt; i++)
|
||||||
tiles[i].isVisible = false;
|
tiles[i].isVisible = false;
|
||||||
|
|
||||||
int z = tiles[0].zoomLevel;
|
// scale and translate projection to tile coordinates
|
||||||
|
ScanBox.transScale(pos.x, pos.y, pos.scale, tileZoom, coords);
|
||||||
double curScale = Tile.SIZE * pos.scale;
|
|
||||||
double tileScale = Tile.SIZE * (pos.scale / (1 << z));
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; i += 2) {
|
|
||||||
coords[i + 0] = (float) ((pos.x * curScale + coords[i + 0]) / tileScale);
|
|
||||||
coords[i + 1] = (float) ((pos.y * curScale + coords[i + 1]) / tileScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
// count placeholder tiles
|
// count placeholder tiles
|
||||||
mNumTileHolder = 0;
|
mNumTileHolder = 0;
|
||||||
|
|
||||||
// check visibile tiles
|
// check visibile tiles
|
||||||
mScanBox.scan(coords, z);
|
mScanBox.scan(coords, tileZoom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,8 +15,37 @@
|
|||||||
|
|
||||||
package org.oscim.renderer;
|
package org.oscim.renderer;
|
||||||
|
|
||||||
|
import org.oscim.core.Tile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ScanBox is used to calculate tile coordinates that intersect
|
||||||
|
* the box (or trapezoid) which is usually the projection of
|
||||||
|
* screen bounds to the map at a given zoom-level.
|
||||||
|
*
|
||||||
|
* use:
|
||||||
|
* MapViewPosition.getMapViewProjection(coords)
|
||||||
|
* ScanBox.transScale(pos.x, pos.y, pos.scale, zoomLevel, coords)
|
||||||
|
* yourScanBox.scan(coords, zoomLevel);
|
||||||
|
*
|
||||||
|
* where zoomLevel is the zoom-level for which tile coordinates
|
||||||
|
* should be calculated.
|
||||||
|
* */
|
||||||
public abstract class ScanBox {
|
public abstract class ScanBox {
|
||||||
|
|
||||||
|
public static void transScale(double x, double y, double scale, int zoom, float[] box){
|
||||||
|
scale *= Tile.SIZE;
|
||||||
|
|
||||||
|
//double curScale = Tile.SIZE * scale;
|
||||||
|
double div = scale / (1 << zoom);
|
||||||
|
|
||||||
|
x *= scale;
|
||||||
|
y *= scale;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i += 2) {
|
||||||
|
box[i + 0] = (float) ((x + box[i + 0]) / div);
|
||||||
|
box[i + 1] = (float) ((y + box[i + 1]) / div);
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* ported from Polymaps: Layer.js
|
* ported from Polymaps: Layer.js
|
||||||
*/
|
*/
|
||||||
@ -44,7 +73,7 @@ public abstract class ScanBox {
|
|||||||
private Edge ab = new Edge();
|
private Edge ab = new Edge();
|
||||||
private Edge bc = new Edge();
|
private Edge bc = new Edge();
|
||||||
private Edge ca = new Edge();
|
private Edge ca = new Edge();
|
||||||
private float minX, maxX;
|
private int minX, maxX;
|
||||||
|
|
||||||
protected int mZoom;
|
protected int mZoom;
|
||||||
|
|
||||||
@ -53,18 +82,27 @@ public abstract class ScanBox {
|
|||||||
public void scan(float[] coords, int zoom) {
|
public void scan(float[] coords, int zoom) {
|
||||||
mZoom = zoom;
|
mZoom = zoom;
|
||||||
|
|
||||||
maxX = Float.MIN_VALUE;
|
|
||||||
minX = Float.MAX_VALUE;
|
// clip result to min/max as steep angles
|
||||||
|
// cause overshooting in x direction.
|
||||||
|
float max = Float.MIN_VALUE;
|
||||||
|
float min = Float.MAX_VALUE;
|
||||||
|
|
||||||
for(int i = 0; i < 8; i += 2){
|
for(int i = 0; i < 8; i += 2){
|
||||||
float x = coords[i];
|
float x = coords[i];
|
||||||
if (x > maxX)
|
if (x > max)
|
||||||
maxX = x;
|
max = x;
|
||||||
if (x < minX)
|
if (x < min)
|
||||||
minX = x;
|
min = x;
|
||||||
}
|
}
|
||||||
maxX = (float)Math.ceil(maxX);
|
|
||||||
minX = (float)Math.floor(minX);
|
max = (float)Math.ceil(max);
|
||||||
|
min = (float)Math.floor(min);
|
||||||
|
if (min == max)
|
||||||
|
max++;
|
||||||
|
|
||||||
|
minX = (int) min;
|
||||||
|
maxX = (int) max;
|
||||||
|
|
||||||
// top-left -> top-right
|
// top-left -> top-right
|
||||||
ab.set(coords[0], coords[1], coords[2], coords[3]);
|
ab.set(coords[0], coords[1], coords[2], coords[3]);
|
||||||
@ -108,10 +146,10 @@ public abstract class ScanBox {
|
|||||||
if (ca.dy == 0)
|
if (ca.dy == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ab.dy > 0.1)
|
if (ab.dy > 0.0)
|
||||||
scanSpans(ca, ab);
|
scanSpans(ca, ab);
|
||||||
|
|
||||||
if (bc.dy > 0.1)
|
if (bc.dy > 0.0)
|
||||||
scanSpans(ca, bc);
|
scanSpans(ca, bc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,13 +190,13 @@ public abstract class ScanBox {
|
|||||||
if (dy > e0.dy)
|
if (dy > e0.dy)
|
||||||
dy = e0.dy;
|
dy = e0.dy;
|
||||||
|
|
||||||
float x0 = (float)Math.ceil(e0.x0 + m0 * dy);
|
int x0 = (int)Math.ceil(e0.x0 + m0 * dy);
|
||||||
|
|
||||||
dy = d1 + y - e1.y0;
|
dy = d1 + y - e1.y0;
|
||||||
if (dy > e1.dy)
|
if (dy > e1.dy)
|
||||||
dy = e1.dy;
|
dy = e1.dy;
|
||||||
|
|
||||||
float x1 = (float)Math.floor(e1.x0 + m1 * dy);
|
int x1 = (int)Math.floor(e1.x0 + m1 * dy);
|
||||||
|
|
||||||
if (x1 < minX)
|
if (x1 < minX)
|
||||||
x1 = minX;
|
x1 = minX;
|
||||||
@ -167,7 +205,7 @@ public abstract class ScanBox {
|
|||||||
x0 = maxX;
|
x0 = maxX;
|
||||||
|
|
||||||
if (x1 < x0)
|
if (x1 < x0)
|
||||||
setVisible(y, (int) x1, (int) x0);
|
setVisible(y, x1, x0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,8 +113,8 @@ public class TileManager {
|
|||||||
clearTile(mTiles[i]);
|
clearTile(mTiles[i]);
|
||||||
}
|
}
|
||||||
//else {
|
//else {
|
||||||
// mInitialized is set when surface changed
|
// mInitialized is set when surface changed
|
||||||
// and VBOs might be lost
|
// and VBOs might be lost
|
||||||
// VertexPool.init();
|
// VertexPool.init();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
@ -162,26 +162,21 @@ public class TileManager {
|
|||||||
// jobs come in.
|
// jobs come in.
|
||||||
mMapView.addJobs(null);
|
mMapView.addJobs(null);
|
||||||
|
|
||||||
// scale and translate projection to tile coordinates
|
|
||||||
// load some tiles more than currently visible (* 0.75)
|
// load some tiles more than currently visible (* 0.75)
|
||||||
double scale = pos.scale * 0.9f;
|
double scale = pos.scale * 0.9f;
|
||||||
double curScale = Tile.SIZE * scale;
|
|
||||||
int zoomLevel = FastMath.clamp(pos.zoomLevel, MIN_ZOOMLEVEL, MAX_ZOOMLEVEL);
|
|
||||||
|
|
||||||
double tileScale = Tile.SIZE * (scale / (1 << zoomLevel));
|
int tileZoom = FastMath.clamp(pos.zoomLevel, MIN_ZOOMLEVEL, MAX_ZOOMLEVEL);
|
||||||
|
|
||||||
float[] coords = mTileCoords;
|
float[] coords = mTileCoords;
|
||||||
mMapViewPosition.getMapViewProjection(coords);
|
mMapViewPosition.getMapViewProjection(coords);
|
||||||
|
|
||||||
for (int i = 0; i < 8; i += 2) {
|
// scale and translate projection to tile coordinates
|
||||||
coords[i + 0] = (float) ((pos.x * curScale + coords[i + 0]) / tileScale);
|
ScanBox.transScale(pos.x, pos.y, scale, tileZoom, coords);
|
||||||
coords[i + 1] = (float) ((pos.y * curScale + coords[i + 1]) / tileScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
// scan visible tiles. callback function calls 'addTile'
|
// scan visible tiles. callback function calls 'addTile'
|
||||||
// which sets mNewTiles
|
// which sets mNewTiles
|
||||||
mNewTiles.cnt = 0;
|
mNewTiles.cnt = 0;
|
||||||
mScanBox.scan(coords, zoomLevel);
|
mScanBox.scan(coords, tileZoom);
|
||||||
|
|
||||||
MapTile[] newTiles = mNewTiles.tiles;
|
MapTile[] newTiles = mNewTiles.tiles;
|
||||||
MapTile[] curTiles = mCurrentTiles.tiles;
|
MapTile[] curTiles = mCurrentTiles.tiles;
|
||||||
@ -562,22 +557,22 @@ public class TileManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final ScanBox mScanBox = new ScanBox() {
|
private final ScanBox mScanBox = new ScanBox() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVisible(int y, int x1, int x2) {
|
public void setVisible(int y, int x1, int x2) {
|
||||||
MapTile[] tiles = mNewTiles.tiles;
|
MapTile[] tiles = mNewTiles.tiles;
|
||||||
int cnt = mNewTiles.cnt;
|
int cnt = mNewTiles.cnt;
|
||||||
int max = tiles.length;
|
int maxTiles = tiles.length;
|
||||||
|
|
||||||
int xmax = 1 << mZoom;
|
int xmax = 1 << mZoom;
|
||||||
|
|
||||||
for (int x = x1; x < x2; x++) {
|
for (int x = x1; x < x2; x++) {
|
||||||
MapTile tile = null;
|
MapTile tile = null;
|
||||||
|
|
||||||
if (cnt == max) {
|
if (cnt == maxTiles) {
|
||||||
Log.d(TAG, "reached maximum tiles " + max);
|
Log.d(TAG, "reached maximum tiles " + maxTiles);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE to myself: do not modify x!
|
|
||||||
int xx = x;
|
int xx = x;
|
||||||
|
|
||||||
if (x < 0 || x >= xmax) {
|
if (x < 0 || x >= xmax) {
|
||||||
|
|||||||
@ -38,13 +38,14 @@ public class MapViewPosition {
|
|||||||
private static final String TAG = MapViewPosition.class.getName();
|
private static final String TAG = MapViewPosition.class.getName();
|
||||||
|
|
||||||
// needs to fit for int: 2 * 20 * Tile.SIZE
|
// needs to fit for int: 2 * 20 * Tile.SIZE
|
||||||
public final static int MAX_ZOOMLEVEL = 20;
|
public final static int MAX_ZOOMLEVEL = 24;
|
||||||
public final static int MIN_ZOOMLEVEL = 2;
|
public final static int MIN_ZOOMLEVEL = 2;
|
||||||
|
|
||||||
public final static double MAX_SCALE = (1 << MAX_ZOOMLEVEL);
|
public final static double MAX_SCALE = (1 << MAX_ZOOMLEVEL);
|
||||||
public final static double MIN_SCALE = (1 << MIN_ZOOMLEVEL);
|
public final static double MIN_SCALE = (1 << MIN_ZOOMLEVEL);
|
||||||
|
|
||||||
public final static int ABS_ZOOMLEVEL = 20;
|
// TODO: remove. only used for animations
|
||||||
|
public final static int ABS_ZOOMLEVEL = 22;
|
||||||
|
|
||||||
private final static float MAX_ANGLE = 65;
|
private final static float MAX_ANGLE = 65;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user