- rename MapRenderer to TileManager and refactor

- move overlay renderer to own package
- slight TouchHandler improvements, not start rotation when scaling
This commit is contained in:
Hannes Janetzek 2012-10-20 00:50:32 +02:00
parent 98246fe50b
commit 78aac5f019
20 changed files with 243 additions and 160 deletions

View File

@ -65,8 +65,8 @@ public class MapDatabase implements IMapDatabase {
private static final String CACHE_FILE = "%d-%d-%d.tile"; private static final String CACHE_FILE = "%d-%d-%d.tile";
private static final String SERVER_ADDR = "city.informatik.uni-bremen.de"; private static final String SERVER_ADDR = "city.informatik.uni-bremen.de";
private static final String URL = "/osci/map-live/"; // private static final String URL = "/osci/map-live/";
// private static final String URL = "/osci/oscim/"; private static final String URL = "/osci/oscim/";
private final static float REF_TILE_SIZE = 4096.0f; private final static float REF_TILE_SIZE = 4096.0f;

View File

@ -14,7 +14,7 @@
*/ */
package org.oscim.generator; package org.oscim.generator;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.TileManager;
import org.oscim.renderer.TileGenerator; import org.oscim.renderer.TileGenerator;
import org.oscim.utils.PausableThread; import org.oscim.utils.PausableThread;
@ -26,7 +26,7 @@ public class MapWorker extends PausableThread {
private final String THREAD_NAME; private final String THREAD_NAME;
private final JobQueue mJobQueue; private final JobQueue mJobQueue;
private final TileGenerator mMapGenerator; private final TileGenerator mMapGenerator;
private final MapRenderer mMapRenderer; private final TileManager mTileManager;
/** /**
* @param id * @param id
@ -35,15 +35,15 @@ public class MapWorker extends PausableThread {
* ... * ...
* @param tileGenerator * @param tileGenerator
* ... * ...
* @param mapRenderer * @param tileManager
* ... * ...
*/ */
public MapWorker(int id, JobQueue jobQueue, TileGenerator tileGenerator, public MapWorker(int id, JobQueue jobQueue, TileGenerator tileGenerator,
MapRenderer mapRenderer) { TileManager tileManager) {
super(); super();
mJobQueue = jobQueue; mJobQueue = jobQueue;
mMapGenerator = tileGenerator; mMapGenerator = tileGenerator;
mMapRenderer = mapRenderer; mTileManager = tileManager;
THREAD_NAME = "MapWorker" + id; THREAD_NAME = "MapWorker" + id;
} }
@ -69,7 +69,7 @@ public class MapWorker extends PausableThread {
boolean success = mMapGenerator.executeJob(tile); boolean success = mMapGenerator.executeJob(tile);
if (!isInterrupted() && success) { if (!isInterrupted() && success) {
mMapRenderer.passTile(tile); mTileManager.passTile(tile);
} }
} }

View File

@ -17,7 +17,7 @@ package org.oscim.renderer;
import android.opengl.GLES20; import android.opengl.GLES20;
class BufferObject { public final class BufferObject {
private static BufferObject pool; private static BufferObject pool;
static int counter; static int counter;
@ -110,7 +110,7 @@ class BufferObject {
counter = num; counter = num;
} }
int id; public int id;
int size; int size;
BufferObject next; BufferObject next;

View File

@ -33,9 +33,10 @@ import javax.microedition.khronos.opengles.GL10;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.MapRenderer.TilesData;
import org.oscim.renderer.layer.Layer; import org.oscim.renderer.layer.Layer;
import org.oscim.renderer.layer.Layers; import org.oscim.renderer.layer.Layers;
import org.oscim.renderer.overlays.Overlay;
import org.oscim.renderer.overlays.OverlayText;
import org.oscim.theme.RenderTheme; import org.oscim.theme.RenderTheme;
import org.oscim.utils.GlUtils; import org.oscim.utils.GlUtils;
import org.oscim.view.MapView; import org.oscim.view.MapView;
@ -98,7 +99,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
// happens rarely, unless you live on Fidschi // happens rarely, unless you live on Fidschi
/* package */static int mHolderCount; /* package */static int mHolderCount;
/* package */static TilesData mDrawTiles; /* package */static Tiles mDrawTiles;
static boolean[] vertexArray = { false, false }; static boolean[] vertexArray = { false, false };
@ -418,7 +419,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
serial = mDrawTiles.serial; serial = mDrawTiles.serial;
// get current tiles to draw // get current tiles to draw
mDrawTiles = MapRenderer.getActiveTiles(mDrawTiles); mDrawTiles = TileManager.getActiveTiles(mDrawTiles);
if (mDrawTiles == null || mDrawTiles.cnt == 0) { if (mDrawTiles == null || mDrawTiles.cnt == 0) {
return; return;

View File

@ -0,0 +1,42 @@
/*
* Copyright 2012 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.renderer;
import org.oscim.utils.GlConfigChooser;
import org.oscim.view.MapView;
import android.content.Context;
import android.opengl.GLSurfaceView;
public class GLView extends GLSurfaceView {
MapView mMapView;
private GLRenderer mRenderer;
public GLView(Context context, MapView mapView) {
super(context);
mMapView = mapView;
// Log.d(TAG, "init GLSurfaceLayer");
setEGLConfigChooser(new GlConfigChooser());
setEGLContextClientVersion(2);
// setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
mRenderer = new GLRenderer(mMapView);
setRenderer(mRenderer);
if (!MapView.debugFrameTime)
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
}

View File

@ -25,7 +25,7 @@ import android.opengl.GLES20;
import android.util.FloatMath; import android.util.FloatMath;
import android.util.Log; import android.util.Log;
class LineRenderer { public final class LineRenderer {
private final static String TAG = "LineRenderer"; private final static String TAG = "LineRenderer";
// private static int NUM_VERTEX_SHORTS = 4; // private static int NUM_VERTEX_SHORTS = 4;
@ -79,7 +79,7 @@ class LineRenderer {
return true; return true;
} }
static Layer draw(MapPosition pos, Layer layer, float[] matrix, float div, public static Layer draw(MapPosition pos, Layer layer, float[] matrix, float div,
int mode, int bufferOffset) { int mode, int bufferOffset) {
int zoom = pos.zoomLevel; int zoom = pos.zoomLevel;

View File

@ -18,7 +18,7 @@ import org.oscim.generator.JobTile;
import org.oscim.renderer.layer.Layers; import org.oscim.renderer.layer.Layers;
import org.oscim.renderer.layer.TextItem; import org.oscim.renderer.layer.TextItem;
class MapTile extends JobTile { public final class MapTile extends JobTile {
/** /**
* VBO layout: - 16 bytes fill coordinates, n bytes polygon vertices, m * VBO layout: - 16 bytes fill coordinates, n bytes polygon vertices, m
@ -31,7 +31,7 @@ class MapTile extends JobTile {
/** /**
* Tile data set by TileGenerator: * Tile data set by TileGenerator:
*/ */
TextItem labels; public TextItem labels;
Layers layers; Layers layers;
/** /**
@ -47,7 +47,7 @@ class MapTile extends JobTile {
/** /**
* tile is in view region. * tile is in view region.
*/ */
boolean isVisible; public boolean isVisible;
/** /**
* pointer to access relatives in QuadTree * pointer to access relatives in QuadTree

View File

@ -46,7 +46,7 @@ import org.oscim.utils.GlUtils;
import android.opengl.GLES20; import android.opengl.GLES20;
class PolygonRenderer { public final class PolygonRenderer {
// private static final String TAG = "PolygonRenderer"; // private static final String TAG = "PolygonRenderer";
// private static final int NUM_VERTEX_SHORTS = 2; // private static final int NUM_VERTEX_SHORTS = 2;
@ -160,7 +160,7 @@ class PolygonRenderer {
// stencil buffer index to start fill // stencil buffer index to start fill
private static int mStart; private static int mStart;
static Layer draw(MapPosition pos, Layer layer, public static Layer draw(MapPosition pos, Layer layer,
float[] matrix, boolean first, boolean clip) { float[] matrix, boolean first, boolean clip) {
int zoom = pos.zoomLevel; int zoom = pos.zoomLevel;

View File

@ -25,7 +25,7 @@ import org.oscim.utils.GlUtils;
import android.opengl.GLES20; import android.opengl.GLES20;
public class TextureRenderer { public final class TextureRenderer {
private static int mTextureProgram; private static int mTextureProgram;
private static int hTextureMVMatrix; private static int hTextureMVMatrix;
private static int hTextureProjMatrix; private static int hTextureProjMatrix;
@ -87,7 +87,7 @@ public class TextureRenderer {
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
} }
static Layer draw(Layer layer, float scale, float[] projection, public static Layer draw(Layer layer, float scale, float[] projection,
float matrix[], int offset) { float matrix[], int offset) {
GlUtils.checkGlError("draw texture0"); GlUtils.checkGlError("draw texture0");
GLES20.glUseProgram(mTextureProgram); GLES20.glUseProgram(mTextureProgram);

View File

@ -457,9 +457,6 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
private static byte getValidLayer(byte layer) { private static byte getValidLayer(byte layer) {
if (layer < 0) { if (layer < 0) {
return 0; return 0;
/**
* return instances of MapRenderer
*/
} else if (layer >= LAYERS) { } else if (layer >= LAYERS) {
return LAYERS - 1; return LAYERS - 1;
} else { } else {

View File

@ -23,19 +23,16 @@ import org.oscim.core.Tile;
import org.oscim.generator.JobTile; import org.oscim.generator.JobTile;
import org.oscim.renderer.layer.TextItem; import org.oscim.renderer.layer.TextItem;
import org.oscim.renderer.layer.VertexPool; import org.oscim.renderer.layer.VertexPool;
import org.oscim.utils.GlConfigChooser; import org.oscim.renderer.overlays.Overlay;
import org.oscim.view.MapView; import org.oscim.view.MapView;
import org.oscim.view.MapViewPosition; import org.oscim.view.MapViewPosition;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.FloatMath; import android.util.FloatMath;
import android.util.Log; import android.util.Log;
// FIXME to many 'Renderer', this one needs a better name.. TileLoader? // FIXME move GLSurfaceView in separate class
public class MapRenderer extends GLSurfaceView { public class TileManager { // extends GLSurfaceView {
private final static String TAG = "MapRenderer"; private final static String TAG = "TileManager";
private GLRenderer mRenderer;
private static final int MAX_TILES_IN_QUEUE = 40; private static final int MAX_TILES_IN_QUEUE = 40;
private static final int CACHE_THRESHOLD = 10; private static final int CACHE_THRESHOLD = 10;
@ -72,25 +69,10 @@ public class MapRenderer extends GLSurfaceView {
// private static int[] mBoundaryTiles = new int[8]; // private static int[] mBoundaryTiles = new int[8];
// used for passing tiles to be rendered from TileLoader(Main-Thread) to
// GLThread
static final class TilesData {
int cnt = 0;
int serial;
MapTile[] tiles;
TilesData() {
}
TilesData(int numTiles) {
tiles = new MapTile[numTiles];
}
}
static int mUpdateCnt; static int mUpdateCnt;
static ReentrantLock tilelock = new ReentrantLock(); static ReentrantLock tilelock = new ReentrantLock();
static TilesData mCurrentTiles; static Tiles mCurrentTiles;
/* package */static TilesData mNewTiles; /* package */static Tiles mNewTiles;
static int tileCounter; static int tileCounter;
@ -145,13 +127,13 @@ public class MapRenderer extends GLSurfaceView {
// but should do the same for GLRenderer. // but should do the same for GLRenderer.
// findbugs found that volatile thingy, though this class // findbugs found that volatile thingy, though this class
// is created before any other thread starts // is created before any other thread starts
private static volatile MapRenderer SINGLETON; private static volatile TileManager SINGLETON;
public static MapRenderer create(Context context, MapView mapView) { public static TileManager create(MapView mapView) {
if (SINGLETON != null) if (SINGLETON != null)
throw new IllegalStateException(); throw new IllegalStateException();
return SINGLETON = new MapRenderer(context, mapView); return SINGLETON = new TileManager(mapView);
} }
public void destroy() { public void destroy() {
@ -164,22 +146,22 @@ public class MapRenderer extends GLSurfaceView {
// ... free pools // ... free pools
} }
private MapRenderer(Context context, MapView mapView) { private TileManager(MapView mapView) {
super(context); // super(context);
mMapView = mapView; mMapView = mapView;
mMapViewPosition = mapView.getMapViewPosition(); mMapViewPosition = mapView.getMapViewPosition();
Log.d(TAG, "init GLSurfaceLayer"); // Log.d(TAG, "init GLSurfaceLayer");
setEGLConfigChooser(new GlConfigChooser()); // setEGLConfigChooser(new GlConfigChooser());
setEGLContextClientVersion(2); // setEGLContextClientVersion(2);
//
// setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS); // // setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
mRenderer = new GLRenderer(mMapView); // mRenderer = new GLRenderer(mMapView);
setRenderer(mRenderer); // setRenderer(mRenderer);
//
// if (!debugFrameTime) // // if (!debugFrameTime)
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); // setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mJobList = new ArrayList<JobTile>(); mJobList = new ArrayList<JobTile>();
mTiles = new ArrayList<MapTile>(); mTiles = new ArrayList<MapTile>();
@ -196,7 +178,7 @@ public class MapRenderer extends GLSurfaceView {
} }
/** /**
* Update list of visible tiles and passes them to MapRenderer, when not * Update list of visible tiles and passes them to TileManager, when not
* available tiles are created and added to JobQueue (mapView.addJobs) for * available tiles are created and added to JobQueue (mapView.addJobs) for
* loading by TileGenerator class * loading by TileGenerator class
* *
@ -241,8 +223,8 @@ public class MapRenderer extends GLSurfaceView {
int numTiles = (num * num) / (size * size) * 4; int numTiles = (num * num) / (size * size) * 4;
// mRenderer.clearTiles(numTiles); // mRenderer.clearTiles(numTiles);
mNewTiles = new TilesData(numTiles); mNewTiles = new Tiles(numTiles);
mCurrentTiles = new TilesData(numTiles); mCurrentTiles = new Tiles(numTiles);
// MapInfo mapInfo = mMapView.getMapDatabase().getMapInfo(); // MapInfo mapInfo = mMapView.getMapDatabase().getMapInfo();
// if (mapInfo != null) // if (mapInfo != null)
// mZoomLevels = mapInfo.zoomLevel; // mZoomLevels = mapInfo.zoomLevel;
@ -259,7 +241,7 @@ public class MapRenderer extends GLSurfaceView {
changedPos = mMapViewPosition.getMapPosition(mapPosition, coords); changedPos = mMapViewPosition.getMapPosition(mapPosition, coords);
if (!changedPos) { if (!changedPos) {
requestRender(); mMapView.render();
return; return;
} }
@ -281,8 +263,7 @@ public class MapRenderer extends GLSurfaceView {
boolean changed = updateVisibleList(mapPosition, zdir); boolean changed = updateVisibleList(mapPosition, zdir);
if (!MapView.debugFrameTime) mMapView.render();
requestRender();
if (changed) { if (changed) {
int remove = mTiles.size() - GLRenderer.CACHE_TILES; int remove = mTiles.size() - GLRenderer.CACHE_TILES;
@ -294,13 +275,13 @@ public class MapRenderer extends GLSurfaceView {
} }
} }
public static TilesData getActiveTiles(TilesData td) { public static Tiles getActiveTiles(Tiles td) {
if (td != null && td.serial == mUpdateCnt) if (td != null && td.serial == mUpdateCnt)
return td; return td;
// dont flip new/currentTiles while copying // dont flip new/currentTiles while copying
MapRenderer.tilelock.lock(); TileManager.tilelock.lock();
try { try {
MapTile[] newTiles = mCurrentTiles.tiles; MapTile[] newTiles = mCurrentTiles.tiles;
int cnt = mCurrentTiles.cnt; int cnt = mCurrentTiles.cnt;
@ -312,7 +293,7 @@ public class MapRenderer extends GLSurfaceView {
MapTile[] nextTiles; MapTile[] nextTiles;
if (td == null) if (td == null)
td = new TilesData(newTiles.length); td = new Tiles(newTiles.length);
nextTiles = td.tiles; nextTiles = td.tiles;
@ -326,13 +307,13 @@ public class MapRenderer extends GLSurfaceView {
td.serial = mUpdateCnt; td.serial = mUpdateCnt;
td.cnt = cnt; td.cnt = cnt;
} finally { } finally {
MapRenderer.tilelock.unlock(); TileManager.tilelock.unlock();
} }
return td; return td;
} }
// public void releaseTiles(TilesData tiles) { // public void releaseTiles(Tiles tiles) {
// //
// } // }
@ -378,7 +359,7 @@ public class MapRenderer extends GLSurfaceView {
} }
if (changed) { if (changed) {
MapRenderer.tilelock.lock(); TileManager.tilelock.lock();
try { try {
for (int i = 0, n = mNewTiles.cnt; i < n; i++) for (int i = 0, n = mNewTiles.cnt; i < n; i++)
newTiles[i].lock(); newTiles[i].lock();
@ -386,13 +367,13 @@ public class MapRenderer extends GLSurfaceView {
for (int i = 0, n = mCurrentTiles.cnt; i < n; i++) for (int i = 0, n = mCurrentTiles.cnt; i < n; i++)
curTiles[i].unlock(); curTiles[i].unlock();
TilesData tmp = mCurrentTiles; Tiles tmp = mCurrentTiles;
mCurrentTiles = mNewTiles; mCurrentTiles = mNewTiles;
mNewTiles = tmp; mNewTiles = tmp;
mUpdateCnt++; mUpdateCnt++;
} finally { } finally {
MapRenderer.tilelock.unlock(); TileManager.tilelock.unlock();
} }
// Log.d(TAG, "tiles: " + tileCounter + " " + BufferObject.counter // Log.d(TAG, "tiles: " + tileCounter + " " + BufferObject.counter
@ -685,8 +666,7 @@ public class MapRenderer extends GLSurfaceView {
tile.isLoading = false; tile.isLoading = false;
// } // }
if (!MapView.debugFrameTime) mMapView.render();
requestRender();
synchronized (mTilesLoaded) { synchronized (mTilesLoaded) {
if (!mTilesLoaded.contains(tile)) if (!mTilesLoaded.contains(tile))
@ -696,22 +676,32 @@ public class MapRenderer extends GLSurfaceView {
return true; return true;
} }
public static void onSizeChanged(int w, int h) {
Log.d(TAG, "onSizeChanged" + w + " " + h);
mWidth = w;
mHeight = h;
if (mWidth > 0 && mHeight > 0)
mInitial = true;
}
// public void setRenderTheme(RenderTheme t) { // public void setRenderTheme(RenderTheme t) {
// if (mRenderer != null) // if (mRenderer != null)
// mRenderer.setRenderTheme(t); // mRenderer.setRenderTheme(t);
// //
// } // }
@Override // @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) { // protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//
Log.d(TAG, "onSizeChanged" + w + " " + h); // Log.d(TAG, "onSizeChanged" + w + " " + h);
mWidth = w; // mWidth = w;
mHeight = h; // mHeight = h;
//
if (mWidth > 0 && mHeight > 0) // if (mWidth > 0 && mHeight > 0)
mInitial = true; // mInitial = true;
//
super.onSizeChanged(w, h, oldw, oldh); // super.onSizeChanged(w, h, oldw, oldh);
} // }
} }

View File

@ -0,0 +1,34 @@
/*
* Copyright 2012 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.renderer;
/**
* use with TileManager.getActiveTiles(Tiles) to get the current tiles. tiles
* are locked to not be modifed until getActiveTiles passes them back on a
* second invocation or TODO: implement TileManager.releaseTiles(Tiles).
*/
public final class Tiles {
public int cnt = 0;
public MapTile[] tiles;
int serial;
Tiles() {
}
Tiles(int numTiles) {
tiles = new MapTile[numTiles];
}
}

View File

@ -66,7 +66,7 @@ public final class TextLayer extends TextureLayer {
@Override @Override
public void compile(ShortBuffer sbuf) { public void compile(ShortBuffer sbuf) {
int numLabel = 0; int numLabel = 0;
int numTextures = 0; // int numTextures = 0;
short numIndices = 0; short numIndices = 0;
short offsetIndices = 0; short offsetIndices = 0;
@ -116,7 +116,7 @@ public final class TextLayer extends TextureLayer {
// clear bitmap, TODO rotate two canvas to reduce the chance // clear bitmap, TODO rotate two canvas to reduce the chance
// of having upload lock draing to the canvas? // of having upload lock draing to the canvas?
canvas = TextureObject.getCanvas(); canvas = TextureObject.getCanvas();
numTextures++; // numTextures++;
} }
} }
@ -225,7 +225,7 @@ public final class TextLayer extends TextureLayer {
sbuf.put(buf, 0, pos); sbuf.put(buf, 0, pos);
Log.d(TAG, "added labels " + numTextures + " " + numLabel); // Log.d(TAG, "added labels " + numTextures + " " + numLabel);
} }
@Override @Override

View File

@ -12,10 +12,15 @@
* You should have received a copy of the GNU Lesser General Public License along with * 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/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.oscim.renderer; package org.oscim.renderer.overlays;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.BufferObject;
import org.oscim.renderer.GLRenderer;
import org.oscim.renderer.LineRenderer;
import org.oscim.renderer.PolygonRenderer;
import org.oscim.renderer.TextureRenderer;
import org.oscim.renderer.layer.Layer; import org.oscim.renderer.layer.Layer;
import org.oscim.renderer.layer.Layers; import org.oscim.renderer.layer.Layers;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
@ -29,17 +34,17 @@ public abstract class Overlay {
protected final MapView mMapView; protected final MapView mMapView;
protected MapPosition mMapPosition; protected MapPosition mMapPosition;
protected final Layers layers; public final Layers layers;
// flag to set when data is ready for (re)compilation. // flag to set when data is ready for (re)compilation.
protected boolean newData; public boolean newData;
// flag set by GLRenderer when data is compiled // flag set by GLRenderer when data is compiled
protected boolean isReady; public boolean isReady;
protected BufferObject vbo; public BufferObject vbo;
Overlay(MapView mapView) { public Overlay(MapView mapView) {
mMapView = mapView; mMapView = mapView;
mMapPosition = new MapPosition(); mMapPosition = new MapPosition();
layers = new Layers(); layers = new Layers();
@ -68,7 +73,7 @@ public abstract class Overlay {
* @param tilesChanged * @param tilesChanged
* true when loaded tiles changed * true when loaded tiles changed
*/ */
synchronized void update(boolean positionChanged, boolean tilesChanged) { public synchronized void update(boolean positionChanged, boolean tilesChanged) {
// // keep position constant (or update layer relative to new position) // // keep position constant (or update layer relative to new position)
// mMapView.getMapViewPosition().getMapPosition(mMapPosition, null); // mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);
// //
@ -85,7 +90,7 @@ public abstract class Overlay {
float[] mvp = new float[16]; float[] mvp = new float[16];
synchronized void render(MapPosition pos, float[] mv, float[] proj) { public synchronized void render(MapPosition pos, float[] mv, float[] proj) {
float div = setMatrix(pos, mv); float div = setMatrix(pos, mv);
Matrix.multiplyMM(mvp, 0, proj, 0, mv, 0); Matrix.multiplyMM(mvp, 0, proj, 0, mv, 0);

View File

@ -12,7 +12,7 @@
* You should have received a copy of the GNU Lesser General Public License along with * 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/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.oscim.renderer; package org.oscim.renderer.overlays;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.layer.Layer; import org.oscim.renderer.layer.Layer;
@ -107,7 +107,7 @@ public class OverlayGrid extends Overlay {
} }
@Override @Override
synchronized void update(boolean positionChanged, boolean tilesChanged) { public synchronized void update(boolean positionChanged, boolean tilesChanged) {
updateMapPosition(); updateMapPosition();

View File

@ -12,7 +12,7 @@
* You should have received a copy of the GNU Lesser General Public License along with * 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/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.oscim.renderer; package org.oscim.renderer.overlays;
import org.oscim.renderer.layer.Layer; import org.oscim.renderer.layer.Layer;
import org.oscim.renderer.layer.LineLayer; import org.oscim.renderer.layer.LineLayer;
@ -92,7 +92,7 @@ public class OverlayTest extends Overlay {
} }
@Override @Override
synchronized void update(boolean positionChanged, boolean tilesChanged) { public synchronized void update(boolean positionChanged, boolean tilesChanged) {
// keep position constant (or update layer relative to new position) // keep position constant (or update layer relative to new position)
mMapView.getMapViewPosition().getMapPosition(mMapPosition, null); mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);

View File

@ -13,11 +13,13 @@
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.oscim.renderer; package org.oscim.renderer.overlays;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.MapRenderer.TilesData; import org.oscim.renderer.TileManager;
import org.oscim.renderer.MapTile;
import org.oscim.renderer.Tiles;
import org.oscim.renderer.layer.TextItem; import org.oscim.renderer.layer.TextItem;
import org.oscim.renderer.layer.TextLayer; import org.oscim.renderer.layer.TextLayer;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
@ -29,7 +31,7 @@ import android.util.FloatMath;
public class OverlayText extends Overlay { public class OverlayText extends Overlay {
private TilesData tiles; private Tiles tiles;
private LabelThread mThread; private LabelThread mThread;
/* package */boolean mRun; /* package */boolean mRun;
/* package */boolean mRerun; /* package */boolean mRerun;
@ -57,7 +59,7 @@ public class OverlayText extends Overlay {
} }
} }
OverlayText(MapView mapView) { public OverlayText(MapView mapView) {
super(mapView); super(mapView);
mWorkPos = new MapPosition(); mWorkPos = new MapPosition();
@ -66,7 +68,7 @@ public class OverlayText extends Overlay {
} }
void updateLabels() { void updateLabels() {
tiles = MapRenderer.getActiveTiles(tiles); tiles = TileManager.getActiveTiles(tiles);
if (tiles.cnt == 0) if (tiles.cnt == 0)
return; return;
@ -134,7 +136,7 @@ public class OverlayText extends Overlay {
} }
@Override @Override
synchronized void update(boolean positionChanged, boolean tilesChanged) { public synchronized void update(boolean positionChanged, boolean tilesChanged) {
// Log.d("...", "update " + tilesChanged + " " + positionChanged); // Log.d("...", "update " + tilesChanged + " " + positionChanged);
if (mWorkLayer != null) { if (mWorkLayer != null) {

View File

@ -497,7 +497,7 @@
<!-- highway --> <!-- highway -->
<rule e="way" k="highway" v="*"> <rule e="way" k="highway" v="*">
<rule e="way" k="*" v="*" zoom-min="5" zoom-max="10"> <rule e="way" k="*" v="*" zoom-min="3" zoom-max="10">
<rule e="way" k="area" v="~|no|false"> <rule e="way" k="area" v="~|no|false">
<rule e="way" k="*" v="secondary|primary_link" zoom-min="9"> <rule e="way" k="*" v="secondary|primary_link" zoom-min="9">
<line stroke="#f2df6d" width="1.3" cap="butt" fixed="true" fade="9"/> <line stroke="#f2df6d" width="1.3" cap="butt" fixed="true" fade="9"/>
@ -516,7 +516,7 @@
</rule> </rule>
<rule e="way" k="*" v="motorway"> <rule e="way" k="*" v="motorway">
<line stroke="#eec693" width="1.5" cap="butt" fixed="true" fade="5"/> <line stroke="#eec693" width="1.5" cap="butt" fixed="true" fade="3"/>
</rule> </rule>
</rule> </rule>
</rule> </rule>
@ -853,7 +853,9 @@
<!-- <rule e="way" k="boundary" v="*"> <rule e="way" k="boundary" v="national_park"> <!-- <rule e="way" k="boundary" v="*"> <rule e="way" k="boundary" v="national_park">
<line stroke="#4ef94b" width="0.25" stroke-dasharray="15, 5, 5, 5" <line stroke="#4ef94b" width="0.25" stroke-dasharray="15, 5, 5, 5"
/> --> /> -->
<rule e="way" k="boundary" v="national_park">
<area fill="#d7e6b0"/>
</rule>
<!--<rule e="way" k="boundary" v="administrative"> --> <!--<rule e="way" k="boundary" v="administrative"> -->
<rule e="way" k="admin_level" v="*"> <rule e="way" k="admin_level" v="*">
<!-- <rule e="way" k="admin_level" v="11"> <line stroke="#f9574b" width="0.1" <!-- <rule e="way" k="admin_level" v="11"> <line stroke="#f9574b" width="0.1"
@ -868,13 +870,13 @@
/> </rule> <rule e="way" k="admin_level" v="5"> <line stroke="#f9574b" width="0.15" /> </rule> <rule e="way" k="admin_level" v="5"> <line stroke="#f9574b" width="0.15"
fixed="true" cap="butt" /> </rule> --> fixed="true" cap="butt" /> </rule> -->
<rule e="way" k="admin_level" v="4"> <rule e="way" k="admin_level" v="4">
<line stroke="#8f80dd" width="0.9" fixed="true" cap="butt" /> <line stroke="#afa0dd" width="0.9" fixed="true" cap="butt" />
</rule> </rule>
<rule e="way" k="admin_level" v="3"> <rule e="way" k="admin_level" v="3">
<line stroke="#0000ff" width="0.95" fixed="true" cap="butt" /> <line stroke="#0000ff" width="0.95" fixed="true" cap="butt" />
</rule> </rule>
<rule e="way" k="admin_level" v="2"> <rule e="way" k="admin_level" v="2">
<line stroke="#a0a0a0" width="0.95" fixed="true" cap="butt" /> <line stroke="#808080" width="1.15" fixed="true" cap="butt" />
</rule> </rule>
<rule e="way" k="admin_level" v="1"> <rule e="way" k="admin_level" v="1">
<line stroke="#ff0000" width="0.95" fixed="true" cap="butt" /> <line stroke="#ff0000" width="0.95" fixed="true" cap="butt" />
@ -947,11 +949,11 @@
stroke="#ffffff" stroke-width="2.0" /> stroke="#ffffff" stroke-width="2.0" />
</rule> </rule>
<rule e="node" k="*" v="city"> <rule e="node" k="*" v="city">
<caption k="name" font-style="bold" font-size="20" fill="#000000" <caption k="name" font-size="19" fill="#000000"
stroke="#ffffff" stroke-width="2.0" /> stroke="#ffffff" stroke-width="2.0" />
</rule> </rule>
<rule e="node" k="*" v="country"> <rule e="node" k="*" v="country">
<caption k="name" font-size="20" fill="#000000" <caption k="name" font-style="bold" font-size="20" fill="#000000"
stroke="#ffffff" stroke-width="2.0" /> stroke="#ffffff" stroke-width="2.0" />
</rule> </rule>
</rule> </rule>

View File

@ -35,8 +35,9 @@ import org.oscim.generator.JobQueue;
import org.oscim.generator.JobTile; import org.oscim.generator.JobTile;
import org.oscim.generator.MapWorker; import org.oscim.generator.MapWorker;
import org.oscim.renderer.GLRenderer; import org.oscim.renderer.GLRenderer;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.GLView;
import org.oscim.renderer.TileGenerator; import org.oscim.renderer.TileGenerator;
import org.oscim.renderer.TileManager;
import org.oscim.theme.ExternalRenderTheme; import org.oscim.theme.ExternalRenderTheme;
import org.oscim.theme.InternalRenderTheme; import org.oscim.theme.InternalRenderTheme;
import org.oscim.theme.RenderTheme; import org.oscim.theme.RenderTheme;
@ -79,7 +80,8 @@ public class MapView extends FrameLayout {
private IMapDatabase mMapDatabase; private IMapDatabase mMapDatabase;
private MapDatabases mMapDatabaseType; private MapDatabases mMapDatabaseType;
private MapRenderer mMapRenderer; private TileManager mTileManager;
private GLView mGLView;
private JobQueue mJobQueue; private JobQueue mJobQueue;
private MapWorker mMapWorkers[]; private MapWorker mMapWorkers[];
private int mNumMapWorkers = 4; private int mNumMapWorkers = 4;
@ -142,7 +144,8 @@ public class MapView extends FrameLayout {
mJobQueue = new JobQueue(); mJobQueue = new JobQueue();
mMapRenderer = MapRenderer.create(context, this); mTileManager = TileManager.create(this);
mGLView = new GLView(context, this);
mMapWorkers = new MapWorker[mNumMapWorkers]; mMapWorkers = new MapWorker[mNumMapWorkers];
@ -164,7 +167,7 @@ public class MapView extends FrameLayout {
if (i == 0) if (i == 0)
mMapDatabase = mapDatabase; mMapDatabase = mapDatabase;
mMapWorkers[i] = new MapWorker(i, mJobQueue, tileGenerator, mMapRenderer); mMapWorkers[i] = new MapWorker(i, mJobQueue, tileGenerator, mTileManager);
} }
mapActivity.registerMapView(this); mapActivity.registerMapView(this);
@ -182,7 +185,7 @@ public class MapView extends FrameLayout {
android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.MATCH_PARENT,
android.view.ViewGroup.LayoutParams.MATCH_PARENT); android.view.ViewGroup.LayoutParams.MATCH_PARENT);
addView(mMapRenderer, params); addView(mGLView, params);
if (testRegionZoom) if (testRegionZoom)
mRegionLookup = new RegionLookup(this); mRegionLookup = new RegionLookup(this);
@ -194,7 +197,11 @@ public class MapView extends FrameLayout {
for (MapWorker worker : mMapWorkers) for (MapWorker worker : mMapWorkers)
worker.start(); worker.start();
}
public void render() {
if (!MapView.debugFrameTime)
mGLView.requestRender();
} }
/** /**
@ -252,14 +259,14 @@ public class MapView extends FrameLayout {
if (mPausing || this.getWidth() == 0 || this.getHeight() == 0) if (mPausing || this.getWidth() == 0 || this.getHeight() == 0)
return; return;
mMapRenderer.updateMap(false); mTileManager.updateMap(false);
} }
public void clearAndRedrawMap() { public void clearAndRedrawMap() {
if (mPausing || this.getWidth() == 0 || this.getHeight() == 0) if (mPausing || this.getWidth() == 0 || this.getHeight() == 0)
return; return;
mMapRenderer.updateMap(true); mTileManager.updateMap(true);
} }
/** /**
@ -476,6 +483,8 @@ public class MapView extends FrameLayout {
if (width != 0 && height != 0) if (width != 0 && height != 0)
mMapViewPosition.setViewport(width, height); mMapViewPosition.setViewport(width, height);
TileManager.onSizeChanged(width, height);
mapWorkersProceed(); mapWorkersProceed();
} }
@ -527,7 +536,7 @@ public class MapView extends FrameLayout {
public void onStop() { public void onStop() {
Log.d(TAG, "onStop"); Log.d(TAG, "onStop");
mMapRenderer.destroy(); mTileManager.destroy();
} }
/** /**

View File

@ -43,6 +43,8 @@ final class TouchHandler
implements ScaleGestureDetector.OnScaleGestureListener { implements ScaleGestureDetector.OnScaleGestureListener {
private static final float SCALE_DURATION = 450; private static final float SCALE_DURATION = 450;
private static final float ROTATION_DELAY = 200; // ms
private static final int INVALID_POINTER_ID = -1; private static final int INVALID_POINTER_ID = -1;
private final MapView mMapView; private final MapView mMapView;
@ -56,7 +58,7 @@ final class TouchHandler
private boolean mBeginRotate; private boolean mBeginRotate;
private boolean mBeginTilt; private boolean mBeginTilt;
private boolean mLongPress; private boolean mLongPress;
private long mLongPressTime; // private long mLongPressTime;
private float mPosX; private float mPosX;
private float mPosY; private float mPosY;
@ -161,14 +163,12 @@ final class TouchHandler
boolean scaling = mScaleGestureDetector.isInProgress(); boolean scaling = mScaleGestureDetector.isInProgress();
if (!mScaling) { if (!mScaling)
mScaling = scaling; mScaling = scaling;
}
if (!scaling && !mMoveStart) { if (!scaling && !mMoveStart) {
if (Math.abs(moveX) > 3 * mMapMoveDelta if (Math.abs(moveX) > mMapMoveDelta || Math.abs(moveY) > mMapMoveDelta) {
|| Math.abs(moveY) > 3 * mMapMoveDelta) {
// the map movement threshold has been reached // the map movement threshold has been reached
// longPressDetector.pressStop(); // longPressDetector.pressStop();
mMoveStart = true; mMoveStart = true;
@ -186,13 +186,13 @@ final class TouchHandler
return true; return true;
} }
if (!scaling) { if (multi == 0) {
mMapPosition.moveMap(moveX, moveY); mMapPosition.moveMap(moveX, moveY);
mMapView.redrawMap(); mMapView.redrawMap();
return true; return true;
} }
if (!mMapView.enableRotation || multi < 1) if (event.getEventTime() - mMultiTouchDownTime < ROTATION_DELAY)
return true; return true;
double x1 = event.getX(0); double x1 = event.getX(0);
@ -206,26 +206,21 @@ final class TouchHandler
double rad = Math.atan2(dy, dx); double rad = Math.atan2(dy, dx);
double r = rad - mAngle; double r = rad - mAngle;
if (!mBeginRotate && Math.abs(rad) < 0.25 || Math.abs(rad) > Math.PI - 0.25) { if (!mBeginRotate) {
// if (Math.abs(moveX) > 3 * mMapMoveDelta) { if (Math.abs(rad) < 0.25 || Math.abs(rad) > Math.PI - 0.25) {
mBeginTilt = true; mBeginTilt = true;
if (mMapPosition.tilt(moveY / 4)) { if (mMapPosition.tilt(moveY / 4)) {
mMapView.redrawMap(); mMapView.redrawMap();
} }
// }
return true; return true;
} }
if (!mBeginRotate && !mBeginScale && !mBeginTilt) { if (!mBeginScale && !mBeginTilt) {
if (Math.abs(r) > 0.03) if (Math.abs(r) > 0.05) {
Log.d("...", "begin rotate");
mBeginRotate = true; mBeginRotate = true;
} }
}
// quick way to prevent flipping...
// Log.d("", "rotation " + rad + " " + r);
if (Math.abs(r) > 0.1) {
rad = mAngle;
r = 0;
} }
if (mBeginRotate) { if (mBeginRotate) {
@ -248,16 +243,20 @@ final class TouchHandler
} }
private int multi = 0; private int multi = 0;
private long mMultiTouchDownTime;
private boolean onActionPointerDown(MotionEvent event) { private boolean onActionPointerDown(MotionEvent event) {
// longPressDetector.pressStop(); // longPressDetector.pressStop();
// multiTouchDownTime = motionEvent.getEventTime(); mMultiTouchDownTime = event.getEventTime();
multi++; multi++;
if (multi == 1) { if (multi == 1) {
double dx = event.getX(0) - event.getX(1); double dx = event.getX(0) - event.getX(1);
double dy = event.getY(0) - event.getY(1); double dy = event.getY(0) - event.getY(1);
mAngle = Math.atan2(dy, dx); mAngle = Math.atan2(dy, dx);
} }
Log.d("...", "multi down " + multi);
return true; return true;
} }
@ -282,6 +281,7 @@ final class TouchHandler
multi--; multi--;
mLongPress = false; mLongPress = false;
Log.d("...", "multi up " + multi);
return true; return true;
} }
@ -429,7 +429,8 @@ final class TouchHandler
mMapPosition.getOffsetPoint(mPosX, mPosY)); mMapPosition.getOffsetPoint(mPosX, mPosY));
} else { } else {
mLongPress = true; mLongPress = true;
mLongPressTime = SystemClock.uptimeMillis();
// mLongPressTime = SystemClock.uptimeMillis();
// mScrollX = (e.getX(0) - (mMapView.getWidth() >> 1)) * 2f; // mScrollX = (e.getX(0) - (mMapView.getWidth() >> 1)) * 2f;
// mScrollY = (e.getY(0) - (mMapView.getHeight() >> 1)) * 2f; // mScrollY = (e.getY(0) - (mMapView.getHeight() >> 1)) * 2f;
// mPrevScale = 0; // mPrevScale = 0;
@ -473,14 +474,14 @@ final class TouchHandler
mTimeEnd = SystemClock.elapsedRealtime(); mTimeEnd = SystemClock.elapsedRealtime();
if (!mBeginScale) { if (!mBeginScale) {
if (mTimeEnd - mTimeStart > 200 || mSumScale > 1.1 || mSumScale < 0.9) { if (mSumScale > 1.1 || mSumScale < 0.9) {
Log.d("...", "begin scale " + mSumScale);
mBeginScale = true; mBeginScale = true;
scale = mSumScale; // scale = mSumScale;
} else }
return true;
} }
if (mMapPosition.scaleMap(scale, mFocusX, mFocusY)) if (mBeginScale && mMapPosition.scaleMap(scale, mFocusX, mFocusY))
mMapView.redrawMap(); mMapView.redrawMap();
return true; return true;