refactor and document Map
- merge Layers into Map - change UpdateEvent to Map.UpdateListener - make updateLayers protected
This commit is contained in:
parent
9a82c24a89
commit
4f1b3f262b
@ -19,8 +19,6 @@ import java.net.URL;
|
||||
import org.oscim.backend.canvas.Bitmap;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.event.MapEvent;
|
||||
import org.oscim.event.UpdateEvent;
|
||||
import org.oscim.gdx.client.GwtBitmap;
|
||||
import org.oscim.layers.tile.TileLayer;
|
||||
import org.oscim.layers.tile.bitmap.TileSource.FadeStep;
|
||||
@ -50,66 +48,33 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
|
||||
mFade = mTileSource.getFadeSteps();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void onUpdate(MapPosition pos, boolean changed, boolean clear) {
|
||||
// super.onUpdate(pos, changed, clear);
|
||||
//
|
||||
// if (mFade == null) {
|
||||
// mRenderLayer.setBitmapAlpha(1);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float alpha = 0;
|
||||
// for (FadeStep f : mFade) {
|
||||
// if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
|
||||
// continue;
|
||||
//
|
||||
// if (f.alphaStart == f.alphaEnd) {
|
||||
// alpha = f.alphaStart;
|
||||
// break;
|
||||
// }
|
||||
// double range = f.scaleEnd / f.scaleStart;
|
||||
// float a = (float)((range - (pos.scale / f.scaleStart)) / range);
|
||||
// a = FastMath.clamp(a, 0, 1);
|
||||
// // interpolate alpha between start and end
|
||||
// alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// mRenderLayer.setBitmapAlpha(alpha);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void handleEvent(MapEvent event) {
|
||||
super.handleEvent(event);
|
||||
public void onMapUpdate(MapPosition pos, boolean changed, boolean clear) {
|
||||
super.onMapUpdate(pos, changed, clear);
|
||||
|
||||
if (event instanceof UpdateEvent) {
|
||||
if (mFade == null) {
|
||||
mRenderLayer.setBitmapAlpha(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFade == null) {
|
||||
mRenderLayer.setBitmapAlpha(1);
|
||||
return;
|
||||
}
|
||||
MapPosition pos = mMap.getMapPosition();
|
||||
float alpha = 0;
|
||||
for (FadeStep f : mFade) {
|
||||
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
|
||||
continue;
|
||||
|
||||
float alpha = 0;
|
||||
for (FadeStep f : mFade) {
|
||||
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
|
||||
continue;
|
||||
|
||||
if (f.alphaStart == f.alphaEnd) {
|
||||
alpha = f.alphaStart;
|
||||
break;
|
||||
}
|
||||
double range = f.scaleEnd / f.scaleStart;
|
||||
float a = (float) ((range - (pos.scale / f.scaleStart)) / range);
|
||||
a = FastMath.clamp(a, 0, 1);
|
||||
// interpolate alpha between start and end
|
||||
alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
|
||||
if (f.alphaStart == f.alphaEnd) {
|
||||
alpha = f.alphaStart;
|
||||
break;
|
||||
}
|
||||
|
||||
mRenderLayer.setBitmapAlpha(alpha);
|
||||
double range = f.scaleEnd / f.scaleStart;
|
||||
float a = (float) ((range - (pos.scale / f.scaleStart)) / range);
|
||||
a = FastMath.clamp(a, 0, 1);
|
||||
// interpolate alpha between start and end
|
||||
alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
mRenderLayer.setBitmapAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,6 +82,33 @@ public abstract class GdxMap implements ApplicationListener {
|
||||
}, delay / 1000f);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all Layers on Main thread.
|
||||
*
|
||||
* @param forceRedraw
|
||||
* also render frame FIXME (does nothing atm)
|
||||
*/
|
||||
private void redrawMapInternal(boolean forceRedraw) {
|
||||
// FIXME needed?
|
||||
GLState.blend(false);
|
||||
GLState.test(false, false);
|
||||
|
||||
updateLayers();
|
||||
|
||||
mRenderRequest = true;
|
||||
Gdx.graphics.requestRendering();
|
||||
}
|
||||
|
||||
/* private */boolean mWaitRedraw;
|
||||
private final Runnable mRedrawRequest = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mWaitRedraw = false;
|
||||
redrawMapInternal(false);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
mMapRenderer = new MapRenderer(mMap);
|
||||
@ -200,30 +227,6 @@ public abstract class GdxMap implements ApplicationListener {
|
||||
public void resume() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all Layers on Main thread.
|
||||
*
|
||||
* @param forceRedraw
|
||||
* also render frame FIXME (does nothing atm)
|
||||
*/
|
||||
void redrawMapInternal(boolean forceRedraw) {
|
||||
GLState.blend(false);
|
||||
GLState.test(false, false);
|
||||
|
||||
mMap.updateLayers();
|
||||
|
||||
mRenderRequest = true;
|
||||
Gdx.graphics.requestRendering();
|
||||
}
|
||||
|
||||
/* private */boolean mWaitRedraw;
|
||||
private final Runnable mRedrawRequest = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mWaitRedraw = false;
|
||||
redrawMapInternal(false);
|
||||
}
|
||||
};
|
||||
|
||||
class TouchHandler implements InputProcessor {
|
||||
|
||||
|
19
vtm/src/org/oscim/event/Dispatcher.java
Normal file
19
vtm/src/org/oscim/event/Dispatcher.java
Normal file
@ -0,0 +1,19 @@
|
||||
package org.oscim.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Dispatcher<T> {
|
||||
protected List<T> listeners = new ArrayList<T>();
|
||||
|
||||
public void addListener(T l) {
|
||||
if (!listeners.contains(l))
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public void removeListener(T l) {
|
||||
listeners.remove(l);
|
||||
}
|
||||
|
||||
public abstract void dispatch();
|
||||
}
|
5
vtm/src/org/oscim/event/IListener.java
Normal file
5
vtm/src/org/oscim/event/IListener.java
Normal file
@ -0,0 +1,5 @@
|
||||
package org.oscim.event;
|
||||
|
||||
public interface IListener {
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package org.oscim.event;
|
||||
|
||||
|
||||
public class UpdateEvent extends MapEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
public static final String TYPE = "UpdateEvent";
|
||||
|
||||
public UpdateEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
public boolean positionChanged;
|
||||
public boolean clearMap;
|
||||
|
||||
}
|
@ -16,16 +16,14 @@ package org.oscim.layers.tile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.oscim.event.EventListener;
|
||||
import org.oscim.event.MapEvent;
|
||||
import org.oscim.event.UpdateEvent;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.layers.Layer;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.tiling.TileLoader;
|
||||
import org.oscim.tiling.TileManager;
|
||||
import org.oscim.tiling.TileRenderer;
|
||||
|
||||
public abstract class TileLayer<T extends TileLoader> extends Layer implements EventListener {
|
||||
public abstract class TileLayer<T extends TileLoader> extends Layer implements Map.UpdateListener {
|
||||
//private final static String TAG = TileLayer.class.getName();
|
||||
private final static int MAX_ZOOMLEVEL = 17;
|
||||
private final static int MIN_ZOOMLEVEL = 2;
|
||||
@ -61,8 +59,6 @@ public abstract class TileLayer<T extends TileLoader> extends Layer implements E
|
||||
// RenderLayer is working in GL Thread and actually
|
||||
// drawing loaded tiles to screen.
|
||||
mRenderer = mRenderLayer = new TileRenderer(mTileManager);
|
||||
|
||||
map.addListener(UpdateEvent.TYPE, this);
|
||||
}
|
||||
|
||||
abstract protected T createLoader(TileManager tm);
|
||||
@ -71,55 +67,32 @@ public abstract class TileLayer<T extends TileLoader> extends Layer implements E
|
||||
return (TileRenderer) mRenderer;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||
//
|
||||
// if (clear || mInitial) {
|
||||
// mRenderLayer.clearTiles();
|
||||
// mTileManager.init(mInitial);
|
||||
// mInitial = false;
|
||||
// changed = true;
|
||||
// }
|
||||
//
|
||||
// if (changed && mTileManager.update(mapPosition))
|
||||
// notifyLoaders();
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void handleEvent(MapEvent event) {
|
||||
if (event instanceof UpdateEvent) {
|
||||
|
||||
UpdateEvent e = (UpdateEvent) event;
|
||||
|
||||
boolean changed = e.positionChanged;
|
||||
|
||||
if (e.clearMap || mInitial) {
|
||||
mRenderLayer.clearTiles();
|
||||
mTileManager.init(mInitial);
|
||||
mInitial = false;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed && mTileManager.update(mMap.getMapPosition()))
|
||||
notifyLoaders();
|
||||
public void onMapUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||
if (clear || mInitial) {
|
||||
mRenderLayer.clearTiles();
|
||||
mTileManager.init(mInitial);
|
||||
mInitial = false;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed && mTileManager.update(mapPosition))
|
||||
notifyLoaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
mMap.removeListener(UpdateEvent.TYPE, this);
|
||||
|
||||
for (T loader : mTileLoader) {
|
||||
loader.pause();
|
||||
loader.interrupt();
|
||||
loader.cleanup();
|
||||
|
||||
// try {
|
||||
// tileWorker.join(10000);
|
||||
// } catch (InterruptedException e) {
|
||||
// // restore the interrupted status
|
||||
// Thread.currentThread().interrupt();
|
||||
// }
|
||||
//try {
|
||||
// tileWorker.join(10000);
|
||||
//} catch (InterruptedException e) {
|
||||
// // restore the interrupted status
|
||||
// Thread.currentThread().interrupt();
|
||||
//}
|
||||
}
|
||||
mTileManager.destroy();
|
||||
}
|
||||
|
@ -24,8 +24,6 @@ import org.oscim.backend.CanvasAdapter;
|
||||
import org.oscim.backend.canvas.Bitmap;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.event.MapEvent;
|
||||
import org.oscim.event.UpdateEvent;
|
||||
import org.oscim.layers.tile.TileLayer;
|
||||
import org.oscim.layers.tile.bitmap.TileSource.FadeStep;
|
||||
import org.oscim.map.Map;
|
||||
@ -53,66 +51,33 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
|
||||
}
|
||||
|
||||
|
||||
// @Override
|
||||
// public void onUpdate(MapPosition pos, boolean changed, boolean clear) {
|
||||
// super.onUpdate(pos, changed, clear);
|
||||
//
|
||||
// if (mFade == null) {
|
||||
// mRenderLayer.setBitmapAlpha(1);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float alpha = 0;
|
||||
// for (FadeStep f : mFade) {
|
||||
// if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
|
||||
// continue;
|
||||
//
|
||||
// if (f.alphaStart == f.alphaEnd) {
|
||||
// alpha = f.alphaStart;
|
||||
// break;
|
||||
// }
|
||||
// double range = f.scaleEnd / f.scaleStart;
|
||||
// float a = (float)((range - (pos.scale / f.scaleStart)) / range);
|
||||
// a = FastMath.clamp(a, 0, 1);
|
||||
// // interpolate alpha between start and end
|
||||
// alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// mRenderLayer.setBitmapAlpha(alpha);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void handleEvent(MapEvent event) {
|
||||
super.handleEvent(event);
|
||||
public void onMapUpdate(MapPosition pos, boolean changed, boolean clear) {
|
||||
super.onMapUpdate(pos, changed, clear);
|
||||
|
||||
if (event instanceof UpdateEvent){
|
||||
if (mFade == null) {
|
||||
mRenderLayer.setBitmapAlpha(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFade == null) {
|
||||
mRenderLayer.setBitmapAlpha(1);
|
||||
return;
|
||||
}
|
||||
MapPosition pos = mMap.getMapPosition();
|
||||
float alpha = 0;
|
||||
for (FadeStep f : mFade) {
|
||||
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
|
||||
continue;
|
||||
|
||||
float alpha = 0;
|
||||
for (FadeStep f : mFade) {
|
||||
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
|
||||
continue;
|
||||
|
||||
if (f.alphaStart == f.alphaEnd) {
|
||||
alpha = f.alphaStart;
|
||||
break;
|
||||
}
|
||||
double range = f.scaleEnd / f.scaleStart;
|
||||
float a = (float)((range - (pos.scale / f.scaleStart)) / range);
|
||||
a = FastMath.clamp(a, 0, 1);
|
||||
// interpolate alpha between start and end
|
||||
alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
|
||||
if (f.alphaStart == f.alphaEnd) {
|
||||
alpha = f.alphaStart;
|
||||
break;
|
||||
}
|
||||
|
||||
mRenderLayer.setBitmapAlpha(alpha);
|
||||
double range = f.scaleEnd / f.scaleStart;
|
||||
float a = (float)((range - (pos.scale / f.scaleStart)) / range);
|
||||
a = FastMath.clamp(a, 0, 1);
|
||||
// interpolate alpha between start and end
|
||||
alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
mRenderLayer.setBitmapAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,15 +15,15 @@
|
||||
package org.oscim.layers.tile.vector.labeling;
|
||||
|
||||
import org.oscim.backend.Log;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.event.EventListener;
|
||||
import org.oscim.event.MapEvent;
|
||||
import org.oscim.event.MotionEvent;
|
||||
import org.oscim.event.UpdateEvent;
|
||||
import org.oscim.layers.Layer;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.tiling.TileRenderer;
|
||||
|
||||
public class LabelLayer extends Layer implements EventListener {
|
||||
public class LabelLayer extends Layer implements EventListener, Map.UpdateListener {
|
||||
private final static String TAG = LabelLayer.class.getName();
|
||||
private final TextRenderer mTextRenderer;
|
||||
|
||||
@ -31,7 +31,7 @@ public class LabelLayer extends Layer implements EventListener {
|
||||
|
||||
public LabelLayer(Map map, TileRenderer tileRenderLayer) {
|
||||
super(map);
|
||||
map.addListener(UpdateEvent.TYPE, this);
|
||||
|
||||
map.addListener(MotionEvent.TYPE, this);
|
||||
|
||||
//mTextLayer = new org.oscim.renderer.layers.TextRenderLayer(map, tileRenderLayer);
|
||||
@ -41,7 +41,6 @@ public class LabelLayer extends Layer implements EventListener {
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
mMap.removeListener(UpdateEvent.TYPE, this);
|
||||
mMap.removeListener(MotionEvent.TYPE, this);
|
||||
|
||||
// TODO stop and clear labeling thread
|
||||
@ -50,13 +49,7 @@ public class LabelLayer extends Layer implements EventListener {
|
||||
|
||||
@Override
|
||||
public void handleEvent(MapEvent event) {
|
||||
if (event instanceof UpdateEvent) {
|
||||
|
||||
UpdateEvent e = (UpdateEvent) event;
|
||||
if (e.clearMap)
|
||||
mTextRenderer.clearLabels();
|
||||
|
||||
} else if (event instanceof MotionEvent) {
|
||||
if (event instanceof MotionEvent) {
|
||||
MotionEvent e = (MotionEvent) event;
|
||||
|
||||
int action = e.getAction() & MotionEvent.ACTION_MASK;
|
||||
@ -75,11 +68,11 @@ public class LabelLayer extends Layer implements EventListener {
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||
// if (clear)
|
||||
// mTextRenderer.clearLabels();
|
||||
// }
|
||||
@Override
|
||||
public void onMapUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||
if (clear)
|
||||
mTextRenderer.clearLabels();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean onTouchEvent(MotionEvent e) {
|
||||
|
@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 osmdroid authors
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oscim.map;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.oscim.layers.Layer;
|
||||
import org.oscim.renderer.LayerRenderer;
|
||||
|
||||
public class Layers extends AbstractList<Layer> {
|
||||
//private final static String TAG = Layers.class.getName();
|
||||
|
||||
private final CopyOnWriteArrayList<Layer> mLayerList;
|
||||
|
||||
Layers() {
|
||||
mLayerList = new CopyOnWriteArrayList<Layer>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Layer get(int index) {
|
||||
return mLayerList.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int size() {
|
||||
return mLayerList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(int index, Layer element) {
|
||||
mLayerList.add(index, element);
|
||||
mDirtyLayers = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Layer remove(int index) {
|
||||
mDirtyLayers = true;
|
||||
return mLayerList.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Layer set(int index, Layer element) {
|
||||
mDirtyLayers = true;
|
||||
return mLayerList.set(index, element);
|
||||
}
|
||||
|
||||
private boolean mDirtyLayers;
|
||||
private LayerRenderer[] mLayerRenderer;
|
||||
|
||||
public LayerRenderer[] getLayerRenderer() {
|
||||
if (mDirtyLayers)
|
||||
updateLayers();
|
||||
|
||||
return mLayerRenderer;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (mDirtyLayers)
|
||||
updateLayers();
|
||||
|
||||
for (Layer o : mLayers)
|
||||
o.onDetach();
|
||||
}
|
||||
|
||||
Layer[] mLayers;
|
||||
|
||||
private synchronized void updateLayers() {
|
||||
if (!mDirtyLayers)
|
||||
return;
|
||||
|
||||
mLayers = new Layer[mLayerList.size()];
|
||||
|
||||
int numRenderLayers = 0;
|
||||
|
||||
for (int i = 0, n = mLayerList.size(); i < n; i++) {
|
||||
Layer o = mLayerList.get(i);
|
||||
|
||||
if (o.getRenderer() != null)
|
||||
numRenderLayers++;
|
||||
mLayers[i] = o;
|
||||
}
|
||||
|
||||
mLayerRenderer = new LayerRenderer[numRenderLayers];
|
||||
|
||||
for (int i = 0, cntR = 0, n = mLayerList.size(); i < n; i++) {
|
||||
Layer o = mLayerList.get(i);
|
||||
LayerRenderer l = o.getRenderer();
|
||||
if (l != null)
|
||||
mLayerRenderer[cntR++] = l;
|
||||
}
|
||||
|
||||
mDirtyLayers = false;
|
||||
}
|
||||
}
|
@ -14,20 +14,24 @@
|
||||
*/
|
||||
package org.oscim.map;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.oscim.backend.Log;
|
||||
import org.oscim.core.BoundingBox;
|
||||
import org.oscim.core.GeoPoint;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.MercatorProjection;
|
||||
import org.oscim.event.Dispatcher;
|
||||
import org.oscim.event.EventDispatcher;
|
||||
import org.oscim.event.EventListener;
|
||||
import org.oscim.event.IListener;
|
||||
import org.oscim.event.MotionEvent;
|
||||
import org.oscim.event.UpdateEvent;
|
||||
import org.oscim.layers.Layer;
|
||||
import org.oscim.layers.MapEventLayer;
|
||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||
import org.oscim.layers.tile.vector.VectorTileLoader;
|
||||
import org.oscim.renderer.LayerRenderer;
|
||||
import org.oscim.renderer.MapRenderer;
|
||||
import org.oscim.theme.IRenderTheme;
|
||||
import org.oscim.theme.InternalRenderTheme;
|
||||
@ -94,16 +98,21 @@ public abstract class Map implements EventDispatcher {
|
||||
|
||||
private InternalRenderTheme mCurrentTheme;
|
||||
|
||||
/**
|
||||
* Utility function to set theme of base vector-layer and
|
||||
* use map background color from theme.
|
||||
*/
|
||||
public void setTheme(InternalRenderTheme theme) {
|
||||
if (mBaseLayer == null) {
|
||||
Log.e(TAG, "No base layer set");
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
if (mCurrentTheme == theme){
|
||||
if (mCurrentTheme == theme) {
|
||||
Log.d(TAG, "same theme: " + theme);
|
||||
return;
|
||||
}
|
||||
|
||||
IRenderTheme t = ThemeLoader.load(theme);
|
||||
if (t == null) {
|
||||
Log.e(TAG, "Invalid theme");
|
||||
@ -126,7 +135,7 @@ public abstract class Map implements EventDispatcher {
|
||||
* Request call to onUpdate for all layers. This function can
|
||||
* be called from any thread. Request will be handled on main
|
||||
* thread.
|
||||
*
|
||||
*
|
||||
* @param forceRedraw pass true to render next frame
|
||||
*/
|
||||
public abstract void updateMap(boolean forceRedraw);
|
||||
@ -151,16 +160,21 @@ public abstract class Map implements EventDispatcher {
|
||||
/**
|
||||
* Post a task to run on a shared worker-thread. Only use for
|
||||
* tasks running less than a second!
|
||||
* */
|
||||
public void addTask(Runnable task){
|
||||
*/
|
||||
public void addTask(Runnable task) {
|
||||
mAsyncExecutor.post(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return screen width in pixel.
|
||||
*/
|
||||
public abstract int getWidth();
|
||||
|
||||
/**
|
||||
* Return screen height in pixel.
|
||||
*/
|
||||
public abstract int getHeight();
|
||||
|
||||
|
||||
/**
|
||||
* Request to clear all layers before rendering next frame
|
||||
*/
|
||||
@ -169,27 +183,9 @@ public abstract class Map implements EventDispatcher {
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not call directly! This function is run on main-loop
|
||||
* before rendering a frame.
|
||||
* This function is run on main-loop before rendering a frame.
|
||||
* Caution: Do not call directly!
|
||||
*/
|
||||
public void updateLayers() {
|
||||
boolean changed = false;
|
||||
|
||||
// get the current MapPosition
|
||||
changed |= mViewport.getMapPosition(mMapPosition);
|
||||
|
||||
//mLayers.onUpdate(mMapPosition, changed, mClearMap);
|
||||
|
||||
UpdateEvent e = new UpdateEvent(this);
|
||||
e.clearMap = mClearMap;
|
||||
e.positionChanged = changed;
|
||||
|
||||
for (EventListener l : mUpdateListeners)
|
||||
l.handleEvent(e);
|
||||
|
||||
mClearMap = false;
|
||||
}
|
||||
|
||||
public void setDebugSettings(DebugSettings debugSettings) {
|
||||
mDebugSettings = debugSettings;
|
||||
//MapTileLoader.setDebugSettings(debugSettings);
|
||||
@ -197,6 +193,9 @@ public abstract class Map implements EventDispatcher {
|
||||
|
||||
public DebugSettings getDebugSettings() {
|
||||
return mDebugSettings;
|
||||
|
||||
protected void updateLayers() {
|
||||
mUpdateDispatcher.dispatch();
|
||||
}
|
||||
|
||||
public void setMapPosition(MapPosition mapPosition) {
|
||||
@ -242,32 +241,169 @@ public abstract class Map implements EventDispatcher {
|
||||
return mAnimator;
|
||||
}
|
||||
|
||||
|
||||
ArrayList<EventListener> mUpdateListeners = new ArrayList<EventListener>();
|
||||
ArrayList<EventListener> mMotionListeners = new ArrayList<EventListener>();
|
||||
|
||||
@Override
|
||||
public void addListener(String type, EventListener listener) {
|
||||
if (type == UpdateEvent.TYPE)
|
||||
mUpdateListeners.add(listener);
|
||||
else if (type == MotionEvent.TYPE)
|
||||
if (type == MotionEvent.TYPE)
|
||||
mMotionListeners.add(listener);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(String type, EventListener listener) {
|
||||
if (type == UpdateEvent.TYPE)
|
||||
mUpdateListeners.remove(listener);
|
||||
else if (type == MotionEvent.TYPE)
|
||||
if (type == MotionEvent.TYPE)
|
||||
mMotionListeners.remove(listener);
|
||||
}
|
||||
|
||||
public MapPosition getMapPosition() {
|
||||
return mMapPosition;
|
||||
}
|
||||
|
||||
public void handleMotionEvent(MotionEvent e) {
|
||||
for (EventListener l : mMotionListeners)
|
||||
l.handleEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener interface for map update notifications.
|
||||
*
|
||||
* NOTE: Layers implementing this interface they will be automatically
|
||||
* registered when the layer is added to the map and unresitered when
|
||||
* the layer is removed.
|
||||
*/
|
||||
public interface UpdateListener extends IListener {
|
||||
void onMapUpdate(MapPosition mapPosition, boolean positionChanged, boolean clear);
|
||||
}
|
||||
|
||||
private class UpdateDispatcher extends Dispatcher<UpdateListener> {
|
||||
@Override
|
||||
public void dispatch() {
|
||||
boolean changed = false;
|
||||
|
||||
// get the current MapPosition
|
||||
changed |= mViewport.getMapPosition(mMapPosition);
|
||||
|
||||
for (UpdateListener l : listeners)
|
||||
l.onMapUpdate(mMapPosition, changed, mClearMap);
|
||||
|
||||
mClearMap = false;
|
||||
}
|
||||
}
|
||||
|
||||
private final UpdateDispatcher mUpdateDispatcher = new UpdateDispatcher();
|
||||
|
||||
/**
|
||||
* Register UpdateListener
|
||||
*/
|
||||
public void addUpdateListener(UpdateListener l) {
|
||||
mUpdateDispatcher.addListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister UpdateListener
|
||||
*/
|
||||
public void removeUpdateListener(UpdateListener l) {
|
||||
mUpdateDispatcher.removeListener(l);
|
||||
}
|
||||
|
||||
public final class Layers extends AbstractList<Layer> {
|
||||
|
||||
private final CopyOnWriteArrayList<Layer> mLayerList;
|
||||
|
||||
Layers() {
|
||||
mLayerList = new CopyOnWriteArrayList<Layer>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Layer get(int index) {
|
||||
return mLayerList.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int size() {
|
||||
return mLayerList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(int index, Layer layer) {
|
||||
if (mLayerList.contains(layer))
|
||||
throw new IllegalArgumentException("layer added twice");
|
||||
|
||||
if (layer instanceof UpdateListener)
|
||||
addUpdateListener((UpdateListener) layer);
|
||||
|
||||
mLayerList.add(index, layer);
|
||||
mDirtyLayers = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Layer remove(int index) {
|
||||
mDirtyLayers = true;
|
||||
|
||||
Layer remove = mLayerList.remove(index);
|
||||
|
||||
if (remove instanceof UpdateListener)
|
||||
removeUpdateListener((UpdateListener) remove);
|
||||
|
||||
return remove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Layer set(int index, Layer layer) {
|
||||
if (mLayerList.contains(layer))
|
||||
throw new IllegalArgumentException("layer added twice");
|
||||
|
||||
mDirtyLayers = true;
|
||||
Layer remove = mLayerList.set(index, layer);
|
||||
|
||||
if (remove instanceof UpdateListener)
|
||||
removeUpdateListener((UpdateListener) remove);
|
||||
|
||||
return remove;
|
||||
}
|
||||
|
||||
private boolean mDirtyLayers;
|
||||
private LayerRenderer[] mLayerRenderer;
|
||||
|
||||
public LayerRenderer[] getLayerRenderer() {
|
||||
if (mDirtyLayers)
|
||||
updateLayers();
|
||||
|
||||
return mLayerRenderer;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (mDirtyLayers)
|
||||
updateLayers();
|
||||
|
||||
for (Layer o : mLayers)
|
||||
o.onDetach();
|
||||
}
|
||||
|
||||
Layer[] mLayers;
|
||||
|
||||
private synchronized void updateLayers() {
|
||||
if (!mDirtyLayers)
|
||||
return;
|
||||
|
||||
mLayers = new Layer[mLayerList.size()];
|
||||
|
||||
int numRenderLayers = 0;
|
||||
|
||||
for (int i = 0, n = mLayerList.size(); i < n; i++) {
|
||||
Layer o = mLayerList.get(i);
|
||||
|
||||
if (o.getRenderer() != null)
|
||||
numRenderLayers++;
|
||||
mLayers[i] = o;
|
||||
}
|
||||
|
||||
mLayerRenderer = new LayerRenderer[numRenderLayers];
|
||||
|
||||
for (int i = 0, cntR = 0, n = mLayerList.size(); i < n; i++) {
|
||||
Layer o = mLayerList.get(i);
|
||||
LayerRenderer l = o.getRenderer();
|
||||
if (l != null)
|
||||
mLayerRenderer[cntR++] = l;
|
||||
}
|
||||
|
||||
mDirtyLayers = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user