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.backend.canvas.Bitmap;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.event.MapEvent;
|
|
||||||
import org.oscim.event.UpdateEvent;
|
|
||||||
import org.oscim.gdx.client.GwtBitmap;
|
import org.oscim.gdx.client.GwtBitmap;
|
||||||
import org.oscim.layers.tile.TileLayer;
|
import org.oscim.layers.tile.TileLayer;
|
||||||
import org.oscim.layers.tile.bitmap.TileSource.FadeStep;
|
import org.oscim.layers.tile.bitmap.TileSource.FadeStep;
|
||||||
@ -50,66 +48,33 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
|
|||||||
mFade = mTileSource.getFadeSteps();
|
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
|
@Override
|
||||||
public void handleEvent(MapEvent event) {
|
public void onMapUpdate(MapPosition pos, boolean changed, boolean clear) {
|
||||||
super.handleEvent(event);
|
super.onMapUpdate(pos, changed, clear);
|
||||||
|
|
||||||
if (event instanceof UpdateEvent) {
|
if (mFade == null) {
|
||||||
|
mRenderLayer.setBitmapAlpha(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mFade == null) {
|
float alpha = 0;
|
||||||
mRenderLayer.setBitmapAlpha(1);
|
for (FadeStep f : mFade) {
|
||||||
return;
|
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
|
||||||
}
|
continue;
|
||||||
MapPosition pos = mMap.getMapPosition();
|
|
||||||
|
|
||||||
float alpha = 0;
|
if (f.alphaStart == f.alphaEnd) {
|
||||||
for (FadeStep f : mFade) {
|
alpha = f.alphaStart;
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
|
double range = f.scaleEnd / f.scaleStart;
|
||||||
mRenderLayer.setBitmapAlpha(alpha);
|
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
|
@Override
|
||||||
|
@ -82,6 +82,33 @@ public abstract class GdxMap implements ApplicationListener {
|
|||||||
}, delay / 1000f);
|
}, delay / 1000f);
|
||||||
return true;
|
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);
|
mMapRenderer = new MapRenderer(mMap);
|
||||||
@ -200,30 +227,6 @@ public abstract class GdxMap implements ApplicationListener {
|
|||||||
public void resume() {
|
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 {
|
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 java.util.ArrayList;
|
||||||
|
|
||||||
import org.oscim.event.EventListener;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.event.MapEvent;
|
|
||||||
import org.oscim.event.UpdateEvent;
|
|
||||||
import org.oscim.layers.Layer;
|
import org.oscim.layers.Layer;
|
||||||
import org.oscim.map.Map;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.tiling.TileLoader;
|
import org.oscim.tiling.TileLoader;
|
||||||
import org.oscim.tiling.TileManager;
|
import org.oscim.tiling.TileManager;
|
||||||
import org.oscim.tiling.TileRenderer;
|
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 String TAG = TileLayer.class.getName();
|
||||||
private final static int MAX_ZOOMLEVEL = 17;
|
private final static int MAX_ZOOMLEVEL = 17;
|
||||||
private final static int MIN_ZOOMLEVEL = 2;
|
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
|
// RenderLayer is working in GL Thread and actually
|
||||||
// drawing loaded tiles to screen.
|
// drawing loaded tiles to screen.
|
||||||
mRenderer = mRenderLayer = new TileRenderer(mTileManager);
|
mRenderer = mRenderLayer = new TileRenderer(mTileManager);
|
||||||
|
|
||||||
map.addListener(UpdateEvent.TYPE, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected T createLoader(TileManager tm);
|
abstract protected T createLoader(TileManager tm);
|
||||||
@ -71,55 +67,32 @@ public abstract class TileLayer<T extends TileLoader> extends Layer implements E
|
|||||||
return (TileRenderer) mRenderer;
|
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
|
@Override
|
||||||
public void handleEvent(MapEvent event) {
|
public void onMapUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
if (event instanceof UpdateEvent) {
|
if (clear || mInitial) {
|
||||||
|
mRenderLayer.clearTiles();
|
||||||
UpdateEvent e = (UpdateEvent) event;
|
mTileManager.init(mInitial);
|
||||||
|
mInitial = false;
|
||||||
boolean changed = e.positionChanged;
|
changed = true;
|
||||||
|
|
||||||
if (e.clearMap || mInitial) {
|
|
||||||
mRenderLayer.clearTiles();
|
|
||||||
mTileManager.init(mInitial);
|
|
||||||
mInitial = false;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed && mTileManager.update(mMap.getMapPosition()))
|
|
||||||
notifyLoaders();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changed && mTileManager.update(mapPosition))
|
||||||
|
notifyLoaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetach() {
|
public void onDetach() {
|
||||||
mMap.removeListener(UpdateEvent.TYPE, this);
|
|
||||||
|
|
||||||
for (T loader : mTileLoader) {
|
for (T loader : mTileLoader) {
|
||||||
loader.pause();
|
loader.pause();
|
||||||
loader.interrupt();
|
loader.interrupt();
|
||||||
loader.cleanup();
|
loader.cleanup();
|
||||||
|
|
||||||
// try {
|
//try {
|
||||||
// tileWorker.join(10000);
|
// tileWorker.join(10000);
|
||||||
// } catch (InterruptedException e) {
|
//} catch (InterruptedException e) {
|
||||||
// // restore the interrupted status
|
// // restore the interrupted status
|
||||||
// Thread.currentThread().interrupt();
|
// Thread.currentThread().interrupt();
|
||||||
// }
|
//}
|
||||||
}
|
}
|
||||||
mTileManager.destroy();
|
mTileManager.destroy();
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,6 @@ import org.oscim.backend.CanvasAdapter;
|
|||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
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.TileLayer;
|
||||||
import org.oscim.layers.tile.bitmap.TileSource.FadeStep;
|
import org.oscim.layers.tile.bitmap.TileSource.FadeStep;
|
||||||
import org.oscim.map.Map;
|
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
|
@Override
|
||||||
public void handleEvent(MapEvent event) {
|
public void onMapUpdate(MapPosition pos, boolean changed, boolean clear) {
|
||||||
super.handleEvent(event);
|
super.onMapUpdate(pos, changed, clear);
|
||||||
|
|
||||||
if (event instanceof UpdateEvent){
|
if (mFade == null) {
|
||||||
|
mRenderLayer.setBitmapAlpha(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mFade == null) {
|
float alpha = 0;
|
||||||
mRenderLayer.setBitmapAlpha(1);
|
for (FadeStep f : mFade) {
|
||||||
return;
|
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
|
||||||
}
|
continue;
|
||||||
MapPosition pos = mMap.getMapPosition();
|
|
||||||
|
|
||||||
float alpha = 0;
|
if (f.alphaStart == f.alphaEnd) {
|
||||||
for (FadeStep f : mFade) {
|
alpha = f.alphaStart;
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
|
double range = f.scaleEnd / f.scaleStart;
|
||||||
mRenderLayer.setBitmapAlpha(alpha);
|
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
|
@Override
|
||||||
|
@ -15,15 +15,15 @@
|
|||||||
package org.oscim.layers.tile.vector.labeling;
|
package org.oscim.layers.tile.vector.labeling;
|
||||||
|
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.event.EventListener;
|
import org.oscim.event.EventListener;
|
||||||
import org.oscim.event.MapEvent;
|
import org.oscim.event.MapEvent;
|
||||||
import org.oscim.event.MotionEvent;
|
import org.oscim.event.MotionEvent;
|
||||||
import org.oscim.event.UpdateEvent;
|
|
||||||
import org.oscim.layers.Layer;
|
import org.oscim.layers.Layer;
|
||||||
import org.oscim.map.Map;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.tiling.TileRenderer;
|
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 static String TAG = LabelLayer.class.getName();
|
||||||
private final TextRenderer mTextRenderer;
|
private final TextRenderer mTextRenderer;
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ public class LabelLayer extends Layer implements EventListener {
|
|||||||
|
|
||||||
public LabelLayer(Map map, TileRenderer tileRenderLayer) {
|
public LabelLayer(Map map, TileRenderer tileRenderLayer) {
|
||||||
super(map);
|
super(map);
|
||||||
map.addListener(UpdateEvent.TYPE, this);
|
|
||||||
map.addListener(MotionEvent.TYPE, this);
|
map.addListener(MotionEvent.TYPE, this);
|
||||||
|
|
||||||
//mTextLayer = new org.oscim.renderer.layers.TextRenderLayer(map, tileRenderLayer);
|
//mTextLayer = new org.oscim.renderer.layers.TextRenderLayer(map, tileRenderLayer);
|
||||||
@ -41,7 +41,6 @@ public class LabelLayer extends Layer implements EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetach() {
|
public void onDetach() {
|
||||||
mMap.removeListener(UpdateEvent.TYPE, this);
|
|
||||||
mMap.removeListener(MotionEvent.TYPE, this);
|
mMap.removeListener(MotionEvent.TYPE, this);
|
||||||
|
|
||||||
// TODO stop and clear labeling thread
|
// TODO stop and clear labeling thread
|
||||||
@ -50,13 +49,7 @@ public class LabelLayer extends Layer implements EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(MapEvent event) {
|
public void handleEvent(MapEvent event) {
|
||||||
if (event instanceof UpdateEvent) {
|
if (event instanceof MotionEvent) {
|
||||||
|
|
||||||
UpdateEvent e = (UpdateEvent) event;
|
|
||||||
if (e.clearMap)
|
|
||||||
mTextRenderer.clearLabels();
|
|
||||||
|
|
||||||
} else if (event instanceof MotionEvent) {
|
|
||||||
MotionEvent e = (MotionEvent) event;
|
MotionEvent e = (MotionEvent) event;
|
||||||
|
|
||||||
int action = e.getAction() & MotionEvent.ACTION_MASK;
|
int action = e.getAction() & MotionEvent.ACTION_MASK;
|
||||||
@ -75,11 +68,11 @@ public class LabelLayer extends Layer implements EventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
// public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
public void onMapUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
// if (clear)
|
if (clear)
|
||||||
// mTextRenderer.clearLabels();
|
mTextRenderer.clearLabels();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// @Override
|
// @Override
|
||||||
// public boolean onTouchEvent(MotionEvent e) {
|
// 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;
|
package org.oscim.map;
|
||||||
|
|
||||||
|
import java.util.AbstractList;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.core.BoundingBox;
|
import org.oscim.core.BoundingBox;
|
||||||
import org.oscim.core.GeoPoint;
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.core.MercatorProjection;
|
||||||
|
import org.oscim.event.Dispatcher;
|
||||||
import org.oscim.event.EventDispatcher;
|
import org.oscim.event.EventDispatcher;
|
||||||
import org.oscim.event.EventListener;
|
import org.oscim.event.EventListener;
|
||||||
|
import org.oscim.event.IListener;
|
||||||
import org.oscim.event.MotionEvent;
|
import org.oscim.event.MotionEvent;
|
||||||
import org.oscim.event.UpdateEvent;
|
import org.oscim.layers.Layer;
|
||||||
import org.oscim.layers.MapEventLayer;
|
import org.oscim.layers.MapEventLayer;
|
||||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
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.renderer.MapRenderer;
|
||||||
import org.oscim.theme.IRenderTheme;
|
import org.oscim.theme.IRenderTheme;
|
||||||
import org.oscim.theme.InternalRenderTheme;
|
import org.oscim.theme.InternalRenderTheme;
|
||||||
@ -94,16 +98,21 @@ public abstract class Map implements EventDispatcher {
|
|||||||
|
|
||||||
private InternalRenderTheme mCurrentTheme;
|
private InternalRenderTheme mCurrentTheme;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility function to set theme of base vector-layer and
|
||||||
|
* use map background color from theme.
|
||||||
|
*/
|
||||||
public void setTheme(InternalRenderTheme theme) {
|
public void setTheme(InternalRenderTheme theme) {
|
||||||
if (mBaseLayer == null) {
|
if (mBaseLayer == null) {
|
||||||
Log.e(TAG, "No base layer set");
|
Log.e(TAG, "No base layer set");
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCurrentTheme == theme){
|
if (mCurrentTheme == theme) {
|
||||||
Log.d(TAG, "same theme: " + theme);
|
Log.d(TAG, "same theme: " + theme);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IRenderTheme t = ThemeLoader.load(theme);
|
IRenderTheme t = ThemeLoader.load(theme);
|
||||||
if (t == null) {
|
if (t == null) {
|
||||||
Log.e(TAG, "Invalid theme");
|
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
|
* Request call to onUpdate for all layers. This function can
|
||||||
* be called from any thread. Request will be handled on main
|
* be called from any thread. Request will be handled on main
|
||||||
* thread.
|
* thread.
|
||||||
*
|
*
|
||||||
* @param forceRedraw pass true to render next frame
|
* @param forceRedraw pass true to render next frame
|
||||||
*/
|
*/
|
||||||
public abstract void updateMap(boolean forceRedraw);
|
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
|
* Post a task to run on a shared worker-thread. Only use for
|
||||||
* tasks running less than a second!
|
* tasks running less than a second!
|
||||||
* */
|
*/
|
||||||
public void addTask(Runnable task){
|
public void addTask(Runnable task) {
|
||||||
mAsyncExecutor.post(task);
|
mAsyncExecutor.post(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return screen width in pixel.
|
||||||
|
*/
|
||||||
public abstract int getWidth();
|
public abstract int getWidth();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return screen height in pixel.
|
||||||
|
*/
|
||||||
public abstract int getHeight();
|
public abstract int getHeight();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to clear all layers before rendering next frame
|
* 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
|
* This function is run on main-loop before rendering a frame.
|
||||||
* 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) {
|
public void setDebugSettings(DebugSettings debugSettings) {
|
||||||
mDebugSettings = debugSettings;
|
mDebugSettings = debugSettings;
|
||||||
//MapTileLoader.setDebugSettings(debugSettings);
|
//MapTileLoader.setDebugSettings(debugSettings);
|
||||||
@ -197,6 +193,9 @@ public abstract class Map implements EventDispatcher {
|
|||||||
|
|
||||||
public DebugSettings getDebugSettings() {
|
public DebugSettings getDebugSettings() {
|
||||||
return mDebugSettings;
|
return mDebugSettings;
|
||||||
|
|
||||||
|
protected void updateLayers() {
|
||||||
|
mUpdateDispatcher.dispatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMapPosition(MapPosition mapPosition) {
|
public void setMapPosition(MapPosition mapPosition) {
|
||||||
@ -242,32 +241,169 @@ public abstract class Map implements EventDispatcher {
|
|||||||
return mAnimator;
|
return mAnimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ArrayList<EventListener> mUpdateListeners = new ArrayList<EventListener>();
|
|
||||||
ArrayList<EventListener> mMotionListeners = new ArrayList<EventListener>();
|
ArrayList<EventListener> mMotionListeners = new ArrayList<EventListener>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addListener(String type, EventListener listener) {
|
public void addListener(String type, EventListener listener) {
|
||||||
if (type == UpdateEvent.TYPE)
|
if (type == MotionEvent.TYPE)
|
||||||
mUpdateListeners.add(listener);
|
|
||||||
else if (type == MotionEvent.TYPE)
|
|
||||||
mMotionListeners.add(listener);
|
mMotionListeners.add(listener);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeListener(String type, EventListener listener) {
|
public void removeListener(String type, EventListener listener) {
|
||||||
if (type == UpdateEvent.TYPE)
|
if (type == MotionEvent.TYPE)
|
||||||
mUpdateListeners.remove(listener);
|
|
||||||
else if (type == MotionEvent.TYPE)
|
|
||||||
mMotionListeners.remove(listener);
|
mMotionListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapPosition getMapPosition() {
|
|
||||||
return mMapPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleMotionEvent(MotionEvent e) {
|
public void handleMotionEvent(MotionEvent e) {
|
||||||
for (EventListener l : mMotionListeners)
|
for (EventListener l : mMotionListeners)
|
||||||
l.handleEvent(e);
|
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