add MapView.clearMap() -> clear all previous map state in Layers on next onUpate
- now labels are cleared properly when the or mapdb changes. - getTileSet now requires a TileSet instance as input
This commit is contained in:
parent
6bb5cd3f68
commit
82a3a880ac
@ -18,7 +18,7 @@ import org.oscim.core.MapPosition;
|
|||||||
import org.oscim.renderer.RenderLayer;
|
import org.oscim.renderer.RenderLayer;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
public class Layer {
|
public abstract class Layer {
|
||||||
public Layer(MapView mapView) {
|
public Layer(MapView mapView) {
|
||||||
mMapView = mapView;
|
mMapView = mapView;
|
||||||
}
|
}
|
||||||
@ -45,7 +45,6 @@ public class Layer {
|
|||||||
return mEnabled;
|
return mEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before each frame render request (on main thread).
|
* Called before each frame render request (on main thread).
|
||||||
*
|
*
|
||||||
@ -53,12 +52,15 @@ public class Layer {
|
|||||||
* current MapPosition
|
* current MapPosition
|
||||||
* @param changed
|
* @param changed
|
||||||
* true when MapPosition has changed since last call
|
* true when MapPosition has changed since last call
|
||||||
|
* @param clear
|
||||||
|
* Clear all resources that depend on previous map state. Most
|
||||||
|
* importantly all resources from previous GL context (hold by
|
||||||
|
* RenderLayer)
|
||||||
*/
|
*/
|
||||||
public void onUpdate(MapPosition mapPosition, boolean changed) {
|
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override to perform clean up of resources before shutdown. By default
|
* Override to perform clean up of resources before shutdown. By default
|
||||||
* does nothing.
|
* does nothing.
|
||||||
@ -69,6 +71,5 @@ public class Layer {
|
|||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,7 +70,7 @@ public class BuildingOverlay extends Overlay {
|
|||||||
private boolean mActive = false;
|
private boolean mActive = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(MapPosition mapPosition, boolean changed) {
|
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
boolean show = mapPosition.scale >= (1 << MIN_ZOOM);
|
boolean show = mapPosition.scale >= (1 << MIN_ZOOM);
|
||||||
|
|
||||||
if (show && mActive)
|
if (show && mActive)
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.layers.overlay;
|
package org.oscim.layers.overlay;
|
||||||
|
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.layers.tile.TileRenderLayer;
|
import org.oscim.layers.tile.TileRenderLayer;
|
||||||
import org.oscim.renderer.layers.TextRenderLayer;
|
import org.oscim.renderer.layers.TextRenderLayer;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
@ -34,6 +35,12 @@ public class LabelingOverlay extends Overlay {
|
|||||||
mLayer = mTextLayer;
|
mLayer = mTextLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
|
if (clear)
|
||||||
|
mTextLayer.clearLabels();
|
||||||
|
}
|
||||||
|
|
||||||
private int multi;
|
private int multi;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -95,7 +95,7 @@ public class MapScaleBar extends Layer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(MapPosition mapPosition, boolean changed) {
|
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
double latitude = MercatorProjection.toLatitude(mapPosition.y);
|
double latitude = MercatorProjection.toLatitude(mapPosition.y);
|
||||||
|
|
||||||
if (!mRedrawNeeded) {
|
if (!mRedrawNeeded) {
|
||||||
|
|||||||
@ -24,9 +24,8 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
|
|||||||
//private final static String TAG = TileLayer.class.getName();
|
//private final static String TAG = TileLayer.class.getName();
|
||||||
private final static int MAX_ZOOMLEVEL = 17;
|
private final static int MAX_ZOOMLEVEL = 17;
|
||||||
|
|
||||||
private boolean mClearMap = true;
|
|
||||||
|
|
||||||
protected final TileManager mTileManager;
|
protected final TileManager mTileManager;
|
||||||
|
protected final TileRenderLayer mRenderLayer;
|
||||||
|
|
||||||
protected final int mNumTileLoader = 4;
|
protected final int mNumTileLoader = 4;
|
||||||
protected final ArrayList<T> mTileLoader;
|
protected final ArrayList<T> mTileLoader;
|
||||||
@ -52,7 +51,7 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
|
|||||||
|
|
||||||
// RenderLayer is working in GL Thread and actually
|
// RenderLayer is working in GL Thread and actually
|
||||||
// drawing loaded tiles to screen.
|
// drawing loaded tiles to screen.
|
||||||
mLayer = new TileRenderLayer(mapView, mTileManager);
|
mLayer = mRenderLayer = new TileRenderLayer(mapView, mTileManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected T createLoader(TileManager tm);
|
abstract protected T createLoader(TileManager tm);
|
||||||
@ -62,11 +61,11 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(MapPosition mapPosition, boolean changed) {
|
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
|
|
||||||
if (mClearMap) {
|
if (clear) {
|
||||||
|
mRenderLayer.clearTiles();
|
||||||
mTileManager.init(mMapView.getWidth(), mMapView.getHeight());
|
mTileManager.init(mMapView.getWidth(), mMapView.getHeight());
|
||||||
mClearMap = false;
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (changed)
|
if (changed)
|
||||||
@ -75,11 +74,7 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
|
|
||||||
mTileManager.destroy();
|
|
||||||
|
|
||||||
for (T tileWorker : mTileLoader) {
|
for (T tileWorker : mTileLoader) {
|
||||||
|
|
||||||
tileWorker.pause();
|
tileWorker.pause();
|
||||||
tileWorker.interrupt();
|
tileWorker.interrupt();
|
||||||
tileWorker.cleanup();
|
tileWorker.cleanup();
|
||||||
@ -91,11 +86,7 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
|
|||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
mTileManager.destroy();
|
||||||
|
|
||||||
protected void clearMap() {
|
|
||||||
// clear tile and overlay data before next draw
|
|
||||||
mClearMap = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void notifyLoaders() {
|
void notifyLoaders() {
|
||||||
|
|||||||
@ -68,7 +68,8 @@ public class TileManager {
|
|||||||
// current end position in mTiles
|
// current end position in mTiles
|
||||||
private int mTilesSize;
|
private int mTilesSize;
|
||||||
|
|
||||||
// counter for tiles with new data not uploaded to GL
|
// counter for tiles with new data not
|
||||||
|
// yet uploaded to GL
|
||||||
private volatile int mTilesForUpload;
|
private volatile int mTilesForUpload;
|
||||||
|
|
||||||
// new tile jobs for MapWorkers
|
// new tile jobs for MapWorkers
|
||||||
@ -80,12 +81,13 @@ public class TileManager {
|
|||||||
// lock for TileSets while updating MapTile locks
|
// lock for TileSets while updating MapTile locks
|
||||||
private final Object mTilelock = new Object();
|
private final Object mTilelock = new Object();
|
||||||
|
|
||||||
// need to keep track of TileSets to clear on reset...
|
// need to keep track of TileSets to clear on reset.
|
||||||
private final ArrayList<TileSet> mTileSets = new ArrayList<TileSet>(4);
|
//private final ArrayList<TileSet> mTileSets = new ArrayList<TileSet>(4);
|
||||||
|
|
||||||
private TileSet mCurrentTiles;
|
private TileSet mCurrentTiles;
|
||||||
/* package */TileSet mNewTiles;
|
/* package */TileSet mNewTiles;
|
||||||
|
|
||||||
|
// job queue filled in TileManager and polled by TileLoaders
|
||||||
final JobQueue jobQueue;
|
final JobQueue jobQueue;
|
||||||
|
|
||||||
private final QuadTreeIndex<MapTile> mIndex = new QuadTreeIndex<MapTile>() {
|
private final QuadTreeIndex<MapTile> mIndex = new QuadTreeIndex<MapTile>() {
|
||||||
@ -139,7 +141,7 @@ public class TileManager {
|
|||||||
// ... free static pools
|
// ... free static pools
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void init(int width, int height) {
|
public void init(int width, int height) {
|
||||||
|
|
||||||
// sync with GLRender thread
|
// sync with GLRender thread
|
||||||
// ... and labeling thread?
|
// ... and labeling thread?
|
||||||
@ -150,11 +152,11 @@ public class TileManager {
|
|||||||
for (int i = 0; i < mTilesSize; i++)
|
for (int i = 0; i < mTilesSize; i++)
|
||||||
clearTile(mTiles[i]);
|
clearTile(mTiles[i]);
|
||||||
}
|
}
|
||||||
//else {
|
|
||||||
|
// FIXME any of this still needed?
|
||||||
// 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();
|
||||||
//}
|
|
||||||
// clear cache index
|
// clear cache index
|
||||||
// QuadTree.init();
|
// QuadTree.init();
|
||||||
|
|
||||||
@ -163,16 +165,11 @@ public class TileManager {
|
|||||||
mTilesSize = 0;
|
mTilesSize = 0;
|
||||||
mTilesCount = 0;
|
mTilesCount = 0;
|
||||||
|
|
||||||
// clear all references to previous tiles
|
|
||||||
for (TileSet td : mTileSets) {
|
|
||||||
Arrays.fill(td.tiles, null);
|
|
||||||
td.cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set up TileSet large enough to hold current tiles
|
// set up TileSet large enough to hold current tiles
|
||||||
int num = Math.max(width, height);
|
int num = Math.max(width, height);
|
||||||
int size = Tile.SIZE >> 1;
|
int size = Tile.SIZE >> 1;
|
||||||
int numTiles = (num * num) / (size * size) * 4;
|
int numTiles = (num * num) / (size * size) * 4;
|
||||||
|
|
||||||
mNewTiles = new TileSet(numTiles);
|
mNewTiles = new TileSet(numTiles);
|
||||||
mCurrentTiles = new TileSet(numTiles);
|
mCurrentTiles = new TileSet(numTiles);
|
||||||
Log.d(TAG, "max tiles: " + numTiles);
|
Log.d(TAG, "max tiles: " + numTiles);
|
||||||
@ -288,13 +285,19 @@ public class TileManager {
|
|||||||
* Tiles remain locked in cache until the set is unlocked by either passing
|
* Tiles remain locked in cache until the set is unlocked by either passing
|
||||||
* it again to this function or to releaseTiles. If passed TileSet is null
|
* it again to this function or to releaseTiles. If passed TileSet is null
|
||||||
* it will be allocated.
|
* it will be allocated.
|
||||||
|
*
|
||||||
|
* @param tileSet to be updated
|
||||||
|
* @return true if TileSet has changed
|
||||||
*/
|
*/
|
||||||
public TileSet getActiveTiles(TileSet td) {
|
public boolean getActiveTiles(TileSet tileSet) {
|
||||||
if (mCurrentTiles == null)
|
if (mCurrentTiles == null)
|
||||||
return td;
|
return false;
|
||||||
|
|
||||||
if (td != null && td.serial == mUpdateSerial)
|
if (tileSet == null)
|
||||||
return td;
|
return false;
|
||||||
|
|
||||||
|
if (tileSet.serial == mUpdateSerial)
|
||||||
|
return false;
|
||||||
|
|
||||||
// dont flip new/currentTiles while copying
|
// dont flip new/currentTiles while copying
|
||||||
synchronized (mTilelock) {
|
synchronized (mTilelock) {
|
||||||
@ -306,26 +309,24 @@ public class TileManager {
|
|||||||
newTiles[i].lock();
|
newTiles[i].lock();
|
||||||
|
|
||||||
MapTile[] nextTiles;
|
MapTile[] nextTiles;
|
||||||
|
nextTiles = tileSet.tiles;
|
||||||
if (td == null) {
|
|
||||||
td = new TileSet(newTiles.length);
|
|
||||||
mTileSets.add(td);
|
|
||||||
}
|
|
||||||
|
|
||||||
nextTiles = td.tiles;
|
|
||||||
|
|
||||||
// unlock previously active tiles
|
// unlock previously active tiles
|
||||||
for (int i = 0, n = td.cnt; i < n; i++)
|
for (int i = 0, n = tileSet.cnt; i < n; i++)
|
||||||
nextTiles[i].unlock();
|
nextTiles[i].unlock();
|
||||||
|
|
||||||
|
if (nextTiles.length != mCurrentTiles.tiles.length) {
|
||||||
|
tileSet.tiles = nextTiles = new MapTile[mCurrentTiles.tiles.length];
|
||||||
|
}
|
||||||
|
|
||||||
// copy newTiles to nextTiles
|
// copy newTiles to nextTiles
|
||||||
System.arraycopy(newTiles, 0, nextTiles, 0, cnt);
|
System.arraycopy(newTiles, 0, nextTiles, 0, cnt);
|
||||||
|
|
||||||
td.serial = mUpdateSerial;
|
tileSet.serial = mUpdateSerial;
|
||||||
td.cnt = cnt;
|
tileSet.cnt = cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return td;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
@ -392,8 +393,9 @@ public class TileManager {
|
|||||||
|
|
||||||
if (mTilesSize == mTiles.length) {
|
if (mTilesSize == mTiles.length) {
|
||||||
if (mTilesSize > mTilesCount) {
|
if (mTilesSize > mTilesCount) {
|
||||||
//Log.d(TAG, "repack: " + mTiles.length + " / " + mTilesCount);
|
|
||||||
TileDistanceSort.sort(mTiles, 0, mTilesSize);
|
TileDistanceSort.sort(mTiles, 0, mTilesSize);
|
||||||
|
// sorting also repacks the 'sparse' filled array
|
||||||
|
// so end of mTiles is at mTilesCount now
|
||||||
mTilesSize = mTilesCount;
|
mTilesSize = mTilesCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,10 +553,10 @@ public class TileManager {
|
|||||||
* called from MapWorker Thread when tile is loaded by MapTileLoader
|
* called from MapWorker Thread when tile is loaded by MapTileLoader
|
||||||
*
|
*
|
||||||
* @param tile
|
* @param tile
|
||||||
* Tile ready for upload to GL
|
* Tile ready for upload in TileRenderLayer
|
||||||
* @return ... caller does not care
|
* @return caller does not care
|
||||||
*/
|
*/
|
||||||
public synchronized boolean passTile(MapTile tile) {
|
public boolean passTile(MapTile tile) {
|
||||||
|
|
||||||
if (tile.state != STATE_LOADING) {
|
if (tile.state != STATE_LOADING) {
|
||||||
// - should rather be STATE_FAILED
|
// - should rather be STATE_FAILED
|
||||||
@ -565,6 +567,8 @@ public class TileManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tile.state = STATE_NEW_DATA;
|
tile.state = STATE_NEW_DATA;
|
||||||
|
|
||||||
|
// is volatile
|
||||||
mTilesForUpload++;
|
mTilesForUpload++;
|
||||||
|
|
||||||
// locked means the tile is visible or referenced by
|
// locked means the tile is visible or referenced by
|
||||||
|
|||||||
@ -48,24 +48,15 @@ public class TileRenderLayer extends RenderLayer {
|
|||||||
|
|
||||||
mMapPosition.copy(pos);
|
mMapPosition.copy(pos);
|
||||||
|
|
||||||
int serial = 0;
|
boolean tilesChanged;
|
||||||
if (mDrawTiles != null)
|
|
||||||
serial = mDrawTiles.getSerial();
|
|
||||||
|
|
||||||
synchronized (tilelock) {
|
synchronized (tilelock) {
|
||||||
// get current tiles to draw
|
// get current tiles to draw
|
||||||
mDrawTiles = mTileManager.getActiveTiles(mDrawTiles);
|
tilesChanged = mTileManager.getActiveTiles(mDrawTiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDrawTiles == null || mDrawTiles.cnt == 0)
|
if (mDrawTiles.cnt == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
boolean tilesChanged = false;
|
|
||||||
|
|
||||||
// check if tiles have changed.
|
|
||||||
if (serial != mDrawTiles.getSerial())
|
|
||||||
tilesChanged = true;
|
|
||||||
|
|
||||||
int tileCnt = mDrawTiles.cnt;
|
int tileCnt = mDrawTiles.cnt;
|
||||||
MapTile[] tiles = mDrawTiles.tiles;
|
MapTile[] tiles = mDrawTiles.tiles;
|
||||||
|
|
||||||
@ -90,6 +81,14 @@ public class TileRenderLayer extends RenderLayer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearTiles() {
|
||||||
|
// Clear all references to MapTiles as all current
|
||||||
|
// tiles will also be removed from TileManager.
|
||||||
|
GLRenderer.drawlock.lock();
|
||||||
|
mDrawTiles = new TileSet();
|
||||||
|
GLRenderer.drawlock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/** compile tile layer data and upload to VBOs */
|
/** compile tile layer data and upload to VBOs */
|
||||||
private static int compileTileLayers(MapTile[] tiles, int tileCnt) {
|
private static int compileTileLayers(MapTile[] tiles, int tileCnt) {
|
||||||
int uploadCnt = 0;
|
int uploadCnt = 0;
|
||||||
@ -189,10 +188,22 @@ public class TileRenderLayer extends RenderLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a TileSet of currently visible tiles
|
/**
|
||||||
public TileSet getVisibleTiles(TileSet td) {
|
* Update tileSet with currently visible tiles
|
||||||
if (mDrawTiles == null)
|
* get a TileSet of currently visible tiles
|
||||||
return td;
|
*/
|
||||||
|
public boolean getVisibleTiles(TileSet tileSet) {
|
||||||
|
if (tileSet == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mDrawTiles == null) {
|
||||||
|
releaseTiles(tileSet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// same tiles as before
|
||||||
|
if (tileSet.serial == mDrawTiles.serial)
|
||||||
|
return false;
|
||||||
|
|
||||||
// ensure tiles keep visible state
|
// ensure tiles keep visible state
|
||||||
synchronized (tilelock) {
|
synchronized (tilelock) {
|
||||||
@ -200,24 +211,26 @@ public class TileRenderLayer extends RenderLayer {
|
|||||||
MapTile[] newTiles = mDrawTiles.tiles;
|
MapTile[] newTiles = mDrawTiles.tiles;
|
||||||
int cnt = mDrawTiles.cnt;
|
int cnt = mDrawTiles.cnt;
|
||||||
|
|
||||||
if (td == null)
|
|
||||||
td = new TileSet(newTiles.length);
|
|
||||||
|
|
||||||
// unlock previous tiles
|
// unlock previous tiles
|
||||||
for (int i = 0; i < td.cnt; i++)
|
for (int i = 0; i < tileSet.cnt; i++)
|
||||||
td.tiles[i].unlock();
|
tileSet.tiles[i].unlock();
|
||||||
|
|
||||||
|
// ensure same size
|
||||||
|
if (tileSet.tiles.length != mDrawTiles.tiles.length) {
|
||||||
|
tileSet.tiles = new MapTile[mDrawTiles.tiles.length];
|
||||||
|
}
|
||||||
|
|
||||||
// lock tiles to not be removed from cache
|
// lock tiles to not be removed from cache
|
||||||
td.cnt = 0;
|
tileSet.cnt = 0;
|
||||||
for (int i = 0; i < cnt; i++) {
|
for (int i = 0; i < cnt; i++) {
|
||||||
MapTile t = newTiles[i];
|
MapTile t = newTiles[i];
|
||||||
if (t.isVisible && t.state == STATE_READY) {
|
if (t.isVisible && t.state == STATE_READY) {
|
||||||
t.lock();
|
t.lock();
|
||||||
td.tiles[td.cnt++] = t;
|
tileSet.tiles[tileSet.cnt++] = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return td;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void releaseTiles(TileSet td) {
|
public void releaseTiles(TileSet td) {
|
||||||
@ -236,7 +249,7 @@ public class TileRenderLayer extends RenderLayer {
|
|||||||
// happens rarely, unless you live on Fidschi
|
// happens rarely, unless you live on Fidschi
|
||||||
|
|
||||||
/* package */int mNumTileHolder;
|
/* package */int mNumTileHolder;
|
||||||
/* package */TileSet mDrawTiles;
|
/* package */TileSet mDrawTiles = new TileSet();
|
||||||
|
|
||||||
// scanline fill class used to check tile visibility
|
// scanline fill class used to check tile visibility
|
||||||
private final ScanBox mScanBox = new ScanBox() {
|
private final ScanBox mScanBox = new ScanBox() {
|
||||||
@ -301,4 +314,5 @@ public class TileRenderLayer extends RenderLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,9 +14,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* use with TileManager.getActiveTiles(TileSet) to get the current tiles. tiles
|
* use with TileManager.getActiveTiles(TileSet) to get the current tiles. tiles
|
||||||
* are locked to not be modifed until getActiveTiles passes them back on a
|
* are locked to not be modifed until getActiveTiles passes them back on a
|
||||||
@ -32,7 +32,8 @@ public final class TileSet {
|
|||||||
return serial;
|
return serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
TileSet() {
|
public TileSet() {
|
||||||
|
tiles = new MapTile[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileSet(int numTiles) {
|
public TileSet(int numTiles) {
|
||||||
@ -47,6 +48,11 @@ public final class TileSet {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
Arrays.fill(tiles, null);
|
||||||
|
cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static Comparator<MapTile> coordComparator = new CoordComparator();
|
public static Comparator<MapTile> coordComparator = new CoordComparator();
|
||||||
|
|
||||||
public static class CoordComparator implements Comparator<MapTile> {
|
public static class CoordComparator implements Comparator<MapTile> {
|
||||||
|
|||||||
@ -104,7 +104,7 @@ public class MapTileLayer extends TileLayer<MapTileLoader> {
|
|||||||
else
|
else
|
||||||
MapView.enableClosePolygons = false;
|
MapView.enableClosePolygons = false;
|
||||||
|
|
||||||
clearMap();
|
mMapView.clearMap();
|
||||||
|
|
||||||
resumeLoaders();
|
resumeLoaders();
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ public class MapTileLayer extends TileLayer<MapTileLoader> {
|
|||||||
mRenderTheme = internalRenderTheme.name();
|
mRenderTheme = internalRenderTheme.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
clearMap();
|
mMapView.clearMap();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -194,7 +194,7 @@ public class MapTileLayer extends TileLayer<MapTileLoader> {
|
|||||||
mRenderTheme = renderThemePath;
|
mRenderTheme = renderThemePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearMap();
|
mMapView.clearMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean setRenderTheme(Theme theme) {
|
private boolean setRenderTheme(Theme theme) {
|
||||||
|
|||||||
@ -41,6 +41,7 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
public ExtrusionRenderLayer(MapView mapView, org.oscim.layers.tile.TileRenderLayer tileRenderLayer) {
|
public ExtrusionRenderLayer(MapView mapView, org.oscim.layers.tile.TileRenderLayer tileRenderLayer) {
|
||||||
super(mapView);
|
super(mapView);
|
||||||
mTileLayer = tileRenderLayer;
|
mTileLayer = tileRenderLayer;
|
||||||
|
mTileSet = new TileSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] shaderProgram = new int[2];
|
private static int[] shaderProgram = new int[2];
|
||||||
@ -56,7 +57,7 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
// FIXME sum up size used while filling layer only up to:
|
// FIXME sum up size used while filling layer only up to:
|
||||||
//public int mBufferSize = 65536;
|
//public int mBufferSize = 65536;
|
||||||
|
|
||||||
private TileSet mTileSet;
|
private final TileSet mTileSet;
|
||||||
private MapTile[] mTiles;
|
private MapTile[] mTiles;
|
||||||
private int mTileCnt;
|
private int mTileCnt;
|
||||||
|
|
||||||
@ -85,18 +86,15 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ready = 0;
|
|
||||||
mTileSet = mTileLayer.getVisibleTiles(mTileSet);
|
|
||||||
if (mTileSet == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MapTile[] tiles = mTileSet.tiles;
|
|
||||||
// FIXME just release tiles in this case
|
|
||||||
if (mAlpha == 0 || pos.zoomLevel < 16) {
|
if (mAlpha == 0 || pos.zoomLevel < 16) {
|
||||||
isReady = false;
|
isReady = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ready = 0;
|
||||||
|
mTileLayer.getVisibleTiles(mTileSet);
|
||||||
|
MapTile[] tiles = mTileSet.tiles;
|
||||||
|
|
||||||
// keep a list of tiles available for rendering
|
// keep a list of tiles available for rendering
|
||||||
if (mTiles == null || mTiles.length < mTileSet.cnt * 4)
|
if (mTiles == null || mTiles.length < mTileSet.cnt * 4)
|
||||||
mTiles = new MapTile[mTileSet.cnt * 4];
|
mTiles = new MapTile[mTileSet.cnt * 4];
|
||||||
@ -104,9 +102,6 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
ExtrusionLayer el;
|
ExtrusionLayer el;
|
||||||
if (pos.zoomLevel >= 17) {
|
if (pos.zoomLevel >= 17) {
|
||||||
for (int i = 0; i < mTileSet.cnt; i++) {
|
for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
if (!tiles[i].isVisible)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
el = getLayer(tiles[i]);
|
el = getLayer(tiles[i]);
|
||||||
if (el == null)
|
if (el == null)
|
||||||
continue;
|
continue;
|
||||||
@ -123,12 +118,9 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
mTiles[ready++] = tiles[i];
|
mTiles[ready++] = tiles[i];
|
||||||
}
|
}
|
||||||
} else if (pos.zoomLevel == 16) {
|
} else if (pos.zoomLevel == 16) {
|
||||||
|
// check if proxy children are ready
|
||||||
for (int i = 0; i < mTileSet.cnt; i++) {
|
for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
if (!tiles[i].isVisible)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
|
|
||||||
for (byte j = 0; j < 4; j++) {
|
for (byte j = 0; j < 4; j++) {
|
||||||
if ((t.proxies & (1 << j)) != 0) {
|
if ((t.proxies & (1 << j)) != 0) {
|
||||||
MapTile c = t.rel.get(j);
|
MapTile c = t.rel.get(j);
|
||||||
|
|||||||
@ -57,6 +57,7 @@ import org.oscim.view.MapViewPosition;
|
|||||||
|
|
||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
public class TextRenderLayer extends BasicRenderLayer {
|
public class TextRenderLayer extends BasicRenderLayer {
|
||||||
private final static String TAG = TextRenderLayer.class.getName();
|
private final static String TAG = TextRenderLayer.class.getName();
|
||||||
@ -64,7 +65,7 @@ public class TextRenderLayer extends BasicRenderLayer {
|
|||||||
private final static float MIN_WAY_DIST = 3;
|
private final static float MIN_WAY_DIST = 3;
|
||||||
|
|
||||||
private final MapViewPosition mMapViewPosition;
|
private final MapViewPosition mMapViewPosition;
|
||||||
private TileSet mTileSet;
|
private final TileSet mTileSet;
|
||||||
private final LabelThread mThread;
|
private final LabelThread mThread;
|
||||||
|
|
||||||
private MapPosition mTmpPos;
|
private MapPosition mTmpPos;
|
||||||
@ -170,17 +171,20 @@ public class TextRenderLayer extends BasicRenderLayer {
|
|||||||
@Override
|
@Override
|
||||||
protected void doWork() {
|
protected void doWork() {
|
||||||
SystemClock.sleep(250);
|
SystemClock.sleep(250);
|
||||||
|
|
||||||
if (!mRun)
|
if (!mRun)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mRun = false;
|
synchronized (this) {
|
||||||
|
|
||||||
if (updateLabels()) {
|
if (updateLabels()) {
|
||||||
|
mRun = false;
|
||||||
mMapView.render();
|
mMapView.render();
|
||||||
} else {
|
} else {
|
||||||
mRun = true;
|
mRun = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getThreadName() {
|
protected String getThreadName() {
|
||||||
@ -202,8 +206,10 @@ public class TextRenderLayer extends BasicRenderLayer {
|
|||||||
|
|
||||||
mMapViewPosition = mapView.getMapViewPosition();
|
mMapViewPosition = mapView.getMapViewPosition();
|
||||||
mTileLayer = baseLayer;
|
mTileLayer = baseLayer;
|
||||||
|
mTileSet = new TileSet();
|
||||||
layers.textureLayers = new TextLayer();
|
layers.textureLayers = new TextLayer();
|
||||||
mTmpLayer = new TextLayer();
|
mTmpLayer = new TextLayer();
|
||||||
|
|
||||||
//mActiveTiles = new HashMap<MapTile, LabelTile>();
|
//mActiveTiles = new HashMap<MapTile, LabelTile>();
|
||||||
mTmpPos = new MapPosition();
|
mTmpPos = new MapPosition();
|
||||||
mThread = new LabelThread();
|
mThread = new LabelThread();
|
||||||
@ -348,9 +354,7 @@ public class TextRenderLayer extends BasicRenderLayer {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// get current tiles
|
// get current tiles
|
||||||
mTileSet = mTileLayer.getVisibleTiles(mTileSet);
|
mTileLayer.getVisibleTiles(mTileSet);
|
||||||
if (mTileSet == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (mTileSet.cnt == 0)
|
if (mTileSet.cnt == 0)
|
||||||
return false;
|
return false;
|
||||||
@ -613,10 +617,10 @@ public class TextRenderLayer extends BasicRenderLayer {
|
|||||||
mTileLayer.releaseTiles(mTileSet);
|
mTileLayer.releaseTiles(mTileSet);
|
||||||
|
|
||||||
// pass new labels for rendering
|
// pass new labels for rendering
|
||||||
synchronized (this) {
|
//synchronized (this) {
|
||||||
mNextLayer = tl;
|
mNextLayer = tl;
|
||||||
mDebugLayer = dbg;
|
mDebugLayer = dbg;
|
||||||
}
|
//}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -774,4 +778,14 @@ public class TextRenderLayer extends BasicRenderLayer {
|
|||||||
// mRun = false;
|
// mRun = false;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearLabels() {
|
||||||
|
Log.d(TAG, "clearLabels");
|
||||||
|
synchronized (mThread) {
|
||||||
|
mRun = false;
|
||||||
|
mPool.releaseAll(mPrevLabels);
|
||||||
|
mPrevLabels = null;
|
||||||
|
mTileSet.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,22 @@ public abstract class Pool<T extends Inlist<T>> {
|
|||||||
pool = item;
|
pool = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void releaseAll(T item) {
|
||||||
|
if (item == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (item != null) {
|
||||||
|
T next = item.next;
|
||||||
|
|
||||||
|
clearItem(item);
|
||||||
|
|
||||||
|
item.next = pool;
|
||||||
|
pool = item;
|
||||||
|
|
||||||
|
item = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// remove 'item' from 'list' and add back to pool
|
// remove 'item' from 'list' and add back to pool
|
||||||
public T release(T list, T item) {
|
public T release(T list, T item) {
|
||||||
if (item == null)
|
if (item == null)
|
||||||
@ -44,7 +60,6 @@ public abstract class Pool<T extends Inlist<T>> {
|
|||||||
|
|
||||||
clearItem(item);
|
clearItem(item);
|
||||||
|
|
||||||
|
|
||||||
if (item == list) {
|
if (item == list) {
|
||||||
T ret = item.next;
|
T ret = item.next;
|
||||||
|
|
||||||
|
|||||||
@ -95,6 +95,24 @@ public class LayerManager extends AbstractList<Layer> implements OnGestureListen
|
|||||||
o.onDetach();
|
o.onDetach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
|
if (mDirtyLayers)
|
||||||
|
updateLayers();
|
||||||
|
|
||||||
|
for (Layer l : mLayers)
|
||||||
|
l.onUpdate(mapPosition, changed, clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
if (mDirtyLayers)
|
||||||
|
updateLayers();
|
||||||
|
|
||||||
|
for (Layer l : mLayers) {
|
||||||
|
l.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Layer[] mLayers;
|
Layer[] mLayers;
|
||||||
InputLayer[] mInputLayer;
|
InputLayer[] mInputLayer;
|
||||||
|
|
||||||
@ -371,22 +389,7 @@ public class LayerManager extends AbstractList<Layer> implements OnGestureListen
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUpdate(MapPosition mapPosition, boolean changed) {
|
|
||||||
if (mDirtyLayers)
|
|
||||||
updateLayers();
|
|
||||||
|
|
||||||
for (Layer l : mLayers)
|
|
||||||
l.onUpdate(mapPosition, changed);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
if (mDirtyLayers)
|
|
||||||
updateLayers();
|
|
||||||
|
|
||||||
for (Layer l : mLayers) {
|
|
||||||
l.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Gets the optional TilesLayer class.
|
// * Gets the optional TilesLayer class.
|
||||||
|
|||||||
@ -66,6 +66,7 @@ public class MapView extends RelativeLayout {
|
|||||||
|
|
||||||
private int mWidth;
|
private int mWidth;
|
||||||
private int mHeight;
|
private int mHeight;
|
||||||
|
private boolean mInitialized;
|
||||||
|
|
||||||
// FIXME: keep until old pbmap reader is removed
|
// FIXME: keep until old pbmap reader is removed
|
||||||
public static boolean enableClosePolygons = false;
|
public static boolean enableClosePolygons = false;
|
||||||
@ -133,6 +134,7 @@ public class MapView extends RelativeLayout {
|
|||||||
|
|
||||||
addView(mGLView, params);
|
addView(mGLView, params);
|
||||||
|
|
||||||
|
clearMap();
|
||||||
redrawMap(false);
|
redrawMap(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +149,7 @@ public class MapView extends RelativeLayout {
|
|||||||
|
|
||||||
mRotationEnabled = true;
|
mRotationEnabled = true;
|
||||||
|
|
||||||
//mLayerManager.add(new GenericOverlay(this, new GridOverlay(this)));
|
//mLayerManager.add(new GenericOverlay(this, new GridRenderLayer(this)));
|
||||||
mLayerManager.add(new BuildingOverlay(this, baseLayer.getTileLayer()));
|
mLayerManager.add(new BuildingOverlay(this, baseLayer.getTileLayer()));
|
||||||
mLayerManager.add(new LabelingOverlay(this, baseLayer.getTileLayer()));
|
mLayerManager.add(new LabelingOverlay(this, baseLayer.getTileLayer()));
|
||||||
|
|
||||||
@ -161,8 +163,6 @@ public class MapView extends RelativeLayout {
|
|||||||
public MapTileLayer setBaseMap(BitmapTileLayer tileLayer) {
|
public MapTileLayer setBaseMap(BitmapTileLayer tileLayer) {
|
||||||
mLayerManager.add(0, new MapEventLayer(this));
|
mLayerManager.add(0, new MapEventLayer(this));
|
||||||
mLayerManager.add(1, tileLayer);
|
mLayerManager.add(1, tileLayer);
|
||||||
|
|
||||||
//mRotationEnabled = true;
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +170,11 @@ public class MapView extends RelativeLayout {
|
|||||||
mLayerManager.destroy();
|
mLayerManager.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onStop() {
|
||||||
|
Log.d(TAG, "onStop");
|
||||||
|
//mLayerManager.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean mPausing = false;
|
private boolean mPausing = false;
|
||||||
|
|
||||||
void onPause() {
|
void onPause() {
|
||||||
@ -181,18 +186,12 @@ public class MapView extends RelativeLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onResume() {
|
void onResume() {
|
||||||
|
|
||||||
if (this.mCompassEnabled)
|
if (this.mCompassEnabled)
|
||||||
mCompass.enable();
|
mCompass.enable();
|
||||||
|
|
||||||
mPausing = false;
|
mPausing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onStop() {
|
|
||||||
Log.d(TAG, "onStop");
|
|
||||||
//mLayerManager.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent motionEvent) {
|
public boolean onTouchEvent(MotionEvent motionEvent) {
|
||||||
|
|
||||||
@ -212,11 +211,13 @@ public class MapView extends RelativeLayout {
|
|||||||
mWidth = width;
|
mWidth = width;
|
||||||
mHeight = height;
|
mHeight = height;
|
||||||
|
|
||||||
if (width != 0 && height != 0)
|
mInitialized = (mWidth > 0 && mWidth > 0);
|
||||||
|
|
||||||
|
if (mInitialized)
|
||||||
mMapViewPosition.setViewport(width, height);
|
mMapViewPosition.setViewport(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean mWaitRedraw;
|
/* private */boolean mWaitRedraw;
|
||||||
|
|
||||||
private final Runnable mRedrawRequest = new Runnable() {
|
private final Runnable mRedrawRequest = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@ -229,49 +230,62 @@ public class MapView extends RelativeLayout {
|
|||||||
/**
|
/**
|
||||||
* Request to redraw the map when a global state like position,
|
* Request to redraw the map when a global state like position,
|
||||||
* datasource or theme has changed. This will trigger a call
|
* datasource or theme has changed. This will trigger a call
|
||||||
* to onUpdate() to all Layers.
|
* to onUpdate() for all Layers.
|
||||||
*
|
*
|
||||||
* @param requestRender
|
* @param requestRender
|
||||||
* also request to draw a frame
|
* also request to draw a frame
|
||||||
*/
|
*/
|
||||||
public void redrawMap(boolean requestRender) {
|
public void redrawMap(boolean requestRender) {
|
||||||
if (requestRender) {
|
if (requestRender && !mClearMap && !mPausing && mInitialized)
|
||||||
if (!(mPausing || mWidth == 0 || mHeight == 0))
|
|
||||||
mGLView.requestRender();
|
mGLView.requestRender();
|
||||||
}
|
|
||||||
if (!mWaitRedraw) {
|
if (!mWaitRedraw) {
|
||||||
mWaitRedraw = true;
|
mWaitRedraw = true;
|
||||||
post(mRedrawRequest);
|
post(mRedrawRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private boolean mClearMap;
|
||||||
|
|
||||||
|
public void clearMap(){
|
||||||
|
mClearMap = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to render a frame. Use this for animations.
|
* Request to render a frame. Use this for animations.
|
||||||
*/
|
*/
|
||||||
public void render() {
|
public void render() {
|
||||||
|
if (mClearMap)
|
||||||
|
redrawMap(false);
|
||||||
|
else
|
||||||
mGLView.requestRender();
|
mGLView.requestRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates all necessary tiles and adds jobs accordingly.
|
* Update all Layers on Main thread.
|
||||||
*
|
*
|
||||||
* @param forceRedraw TODO
|
* @param forceRedraw also render frame
|
||||||
|
* FIXME (does nothing atm)
|
||||||
*/
|
*/
|
||||||
void redrawMapInternal(boolean forceRedraw) {
|
void redrawMapInternal(boolean forceRedraw) {
|
||||||
boolean changed = false;
|
boolean changed = forceRedraw;
|
||||||
|
|
||||||
if (mPausing || mWidth == 0 || mHeight == 0)
|
if (mPausing || !mInitialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (forceRedraw) {
|
if (forceRedraw && !mClearMap)
|
||||||
mGLView.requestRender();
|
mGLView.requestRender();
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the current MapPosition
|
// get the current MapPosition
|
||||||
changed |= mMapViewPosition.getMapPosition(mMapPosition);
|
changed |= mMapViewPosition.getMapPosition(mMapPosition);
|
||||||
|
|
||||||
mLayerManager.onUpdate(mMapPosition, changed);
|
mLayerManager.onUpdate(mMapPosition, changed, mClearMap);
|
||||||
|
|
||||||
|
// delay redraw until all layers had the chance to clear
|
||||||
|
// their state.
|
||||||
|
if (mClearMap){
|
||||||
|
mGLView.requestRender();
|
||||||
|
mClearMap =false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user