- 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 SERVER_ADDR = "city.informatik.uni-bremen.de";
private static final String URL = "/osci/map-live/";
// private static final String URL = "/osci/oscim/";
// private static final String URL = "/osci/map-live/";
private static final String URL = "/osci/oscim/";
private final static float REF_TILE_SIZE = 4096.0f;

View File

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

View File

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

View File

@ -33,9 +33,10 @@ import javax.microedition.khronos.opengles.GL10;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.renderer.MapRenderer.TilesData;
import org.oscim.renderer.layer.Layer;
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.utils.GlUtils;
import org.oscim.view.MapView;
@ -98,7 +99,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
// happens rarely, unless you live on Fidschi
/* package */static int mHolderCount;
/* package */static TilesData mDrawTiles;
/* package */static Tiles mDrawTiles;
static boolean[] vertexArray = { false, false };
@ -418,7 +419,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
serial = mDrawTiles.serial;
// get current tiles to draw
mDrawTiles = MapRenderer.getActiveTiles(mDrawTiles);
mDrawTiles = TileManager.getActiveTiles(mDrawTiles);
if (mDrawTiles == null || mDrawTiles.cnt == 0) {
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.Log;
class LineRenderer {
public final class LineRenderer {
private final static String TAG = "LineRenderer";
// private static int NUM_VERTEX_SHORTS = 4;
@ -79,7 +79,7 @@ class LineRenderer {
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 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.TextItem;
class MapTile extends JobTile {
public final class MapTile extends JobTile {
/**
* VBO layout: - 16 bytes fill coordinates, n bytes polygon vertices, m
@ -31,7 +31,7 @@ class MapTile extends JobTile {
/**
* Tile data set by TileGenerator:
*/
TextItem labels;
public TextItem labels;
Layers layers;
/**
@ -47,7 +47,7 @@ class MapTile extends JobTile {
/**
* tile is in view region.
*/
boolean isVisible;
public boolean isVisible;
/**
* pointer to access relatives in QuadTree

View File

@ -46,7 +46,7 @@ import org.oscim.utils.GlUtils;
import android.opengl.GLES20;
class PolygonRenderer {
public final class PolygonRenderer {
// private static final String TAG = "PolygonRenderer";
// private static final int NUM_VERTEX_SHORTS = 2;
@ -160,7 +160,7 @@ class PolygonRenderer {
// stencil buffer index to start fill
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) {
int zoom = pos.zoomLevel;

View File

@ -25,7 +25,7 @@ import org.oscim.utils.GlUtils;
import android.opengl.GLES20;
public class TextureRenderer {
public final class TextureRenderer {
private static int mTextureProgram;
private static int hTextureMVMatrix;
private static int hTextureProjMatrix;
@ -87,7 +87,7 @@ public class TextureRenderer {
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) {
GlUtils.checkGlError("draw texture0");
GLES20.glUseProgram(mTextureProgram);

View File

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

View File

@ -23,19 +23,16 @@ import org.oscim.core.Tile;
import org.oscim.generator.JobTile;
import org.oscim.renderer.layer.TextItem;
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.MapViewPosition;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.FloatMath;
import android.util.Log;
// FIXME to many 'Renderer', this one needs a better name.. TileLoader?
public class MapRenderer extends GLSurfaceView {
private final static String TAG = "MapRenderer";
private GLRenderer mRenderer;
// FIXME move GLSurfaceView in separate class
public class TileManager { // extends GLSurfaceView {
private final static String TAG = "TileManager";
private static final int MAX_TILES_IN_QUEUE = 40;
private static final int CACHE_THRESHOLD = 10;
@ -72,25 +69,10 @@ public class MapRenderer extends GLSurfaceView {
// 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 ReentrantLock tilelock = new ReentrantLock();
static TilesData mCurrentTiles;
/* package */static TilesData mNewTiles;
static Tiles mCurrentTiles;
/* package */static Tiles mNewTiles;
static int tileCounter;
@ -145,13 +127,13 @@ public class MapRenderer extends GLSurfaceView {
// but should do the same for GLRenderer.
// findbugs found that volatile thingy, though this class
// 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)
throw new IllegalStateException();
return SINGLETON = new MapRenderer(context, mapView);
return SINGLETON = new TileManager(mapView);
}
public void destroy() {
@ -164,22 +146,22 @@ public class MapRenderer extends GLSurfaceView {
// ... free pools
}
private MapRenderer(Context context, MapView mapView) {
super(context);
private TileManager(MapView mapView) {
// super(context);
mMapView = mapView;
mMapViewPosition = mapView.getMapViewPosition();
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 (!debugFrameTime)
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
// 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 (!debugFrameTime)
// setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mJobList = new ArrayList<JobTile>();
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
* loading by TileGenerator class
*
@ -241,8 +223,8 @@ public class MapRenderer extends GLSurfaceView {
int numTiles = (num * num) / (size * size) * 4;
// mRenderer.clearTiles(numTiles);
mNewTiles = new TilesData(numTiles);
mCurrentTiles = new TilesData(numTiles);
mNewTiles = new Tiles(numTiles);
mCurrentTiles = new Tiles(numTiles);
// MapInfo mapInfo = mMapView.getMapDatabase().getMapInfo();
// if (mapInfo != null)
// mZoomLevels = mapInfo.zoomLevel;
@ -259,7 +241,7 @@ public class MapRenderer extends GLSurfaceView {
changedPos = mMapViewPosition.getMapPosition(mapPosition, coords);
if (!changedPos) {
requestRender();
mMapView.render();
return;
}
@ -281,8 +263,7 @@ public class MapRenderer extends GLSurfaceView {
boolean changed = updateVisibleList(mapPosition, zdir);
if (!MapView.debugFrameTime)
requestRender();
mMapView.render();
if (changed) {
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)
return td;
// dont flip new/currentTiles while copying
MapRenderer.tilelock.lock();
TileManager.tilelock.lock();
try {
MapTile[] newTiles = mCurrentTiles.tiles;
int cnt = mCurrentTiles.cnt;
@ -312,7 +293,7 @@ public class MapRenderer extends GLSurfaceView {
MapTile[] nextTiles;
if (td == null)
td = new TilesData(newTiles.length);
td = new Tiles(newTiles.length);
nextTiles = td.tiles;
@ -326,13 +307,13 @@ public class MapRenderer extends GLSurfaceView {
td.serial = mUpdateCnt;
td.cnt = cnt;
} finally {
MapRenderer.tilelock.unlock();
TileManager.tilelock.unlock();
}
return td;
}
// public void releaseTiles(TilesData tiles) {
// public void releaseTiles(Tiles tiles) {
//
// }
@ -378,7 +359,7 @@ public class MapRenderer extends GLSurfaceView {
}
if (changed) {
MapRenderer.tilelock.lock();
TileManager.tilelock.lock();
try {
for (int i = 0, n = mNewTiles.cnt; i < n; i++)
newTiles[i].lock();
@ -386,13 +367,13 @@ public class MapRenderer extends GLSurfaceView {
for (int i = 0, n = mCurrentTiles.cnt; i < n; i++)
curTiles[i].unlock();
TilesData tmp = mCurrentTiles;
Tiles tmp = mCurrentTiles;
mCurrentTiles = mNewTiles;
mNewTiles = tmp;
mUpdateCnt++;
} finally {
MapRenderer.tilelock.unlock();
TileManager.tilelock.unlock();
}
// Log.d(TAG, "tiles: " + tileCounter + " " + BufferObject.counter
@ -685,8 +666,7 @@ public class MapRenderer extends GLSurfaceView {
tile.isLoading = false;
// }
if (!MapView.debugFrameTime)
requestRender();
mMapView.render();
synchronized (mTilesLoaded) {
if (!mTilesLoaded.contains(tile))
@ -696,22 +676,32 @@ public class MapRenderer extends GLSurfaceView {
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) {
// if (mRenderer != null)
// mRenderer.setRenderTheme(t);
//
// }
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.d(TAG, "onSizeChanged" + w + " " + h);
mWidth = w;
mHeight = h;
if (mWidth > 0 && mHeight > 0)
mInitial = true;
super.onSizeChanged(w, h, oldw, oldh);
}
// @Override
// protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//
// Log.d(TAG, "onSizeChanged" + w + " " + h);
// mWidth = w;
// mHeight = h;
//
// if (mWidth > 0 && mHeight > 0)
// mInitial = true;
//
// 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
public void compile(ShortBuffer sbuf) {
int numLabel = 0;
int numTextures = 0;
// int numTextures = 0;
short numIndices = 0;
short offsetIndices = 0;
@ -116,7 +116,7 @@ public final class TextLayer extends TextureLayer {
// clear bitmap, TODO rotate two canvas to reduce the chance
// of having upload lock draing to the canvas?
canvas = TextureObject.getCanvas();
numTextures++;
// numTextures++;
}
}
@ -225,7 +225,7 @@ public final class TextLayer extends TextureLayer {
sbuf.put(buf, 0, pos);
Log.d(TAG, "added labels " + numTextures + " " + numLabel);
// Log.d(TAG, "added labels " + numTextures + " " + numLabel);
}
@Override

View File

@ -12,10 +12,15 @@
* 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;
package org.oscim.renderer.overlays;
import org.oscim.core.MapPosition;
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.Layers;
import org.oscim.utils.FastMath;
@ -29,17 +34,17 @@ public abstract class Overlay {
protected final MapView mMapView;
protected MapPosition mMapPosition;
protected final Layers layers;
public final Layers layers;
// flag to set when data is ready for (re)compilation.
protected boolean newData;
public boolean newData;
// 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;
mMapPosition = new MapPosition();
layers = new Layers();
@ -68,7 +73,7 @@ public abstract class Overlay {
* @param tilesChanged
* 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)
// mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);
//
@ -85,7 +90,7 @@ public abstract class Overlay {
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);
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
* 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.renderer.layer.Layer;
@ -107,7 +107,7 @@ public class OverlayGrid extends Overlay {
}
@Override
synchronized void update(boolean positionChanged, boolean tilesChanged) {
public synchronized void update(boolean positionChanged, boolean tilesChanged) {
updateMapPosition();

View File

@ -12,7 +12,7 @@
* 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;
package org.oscim.renderer.overlays;
import org.oscim.renderer.layer.Layer;
import org.oscim.renderer.layer.LineLayer;
@ -92,7 +92,7 @@ public class OverlayTest extends Overlay {
}
@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)
mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);

View File

@ -13,11 +13,13 @@
* 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.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.TextLayer;
import org.oscim.utils.FastMath;
@ -29,7 +31,7 @@ import android.util.FloatMath;
public class OverlayText extends Overlay {
private TilesData tiles;
private Tiles tiles;
private LabelThread mThread;
/* package */boolean mRun;
/* package */boolean mRerun;
@ -57,7 +59,7 @@ public class OverlayText extends Overlay {
}
}
OverlayText(MapView mapView) {
public OverlayText(MapView mapView) {
super(mapView);
mWorkPos = new MapPosition();
@ -66,7 +68,7 @@ public class OverlayText extends Overlay {
}
void updateLabels() {
tiles = MapRenderer.getActiveTiles(tiles);
tiles = TileManager.getActiveTiles(tiles);
if (tiles.cnt == 0)
return;
@ -134,7 +136,7 @@ public class OverlayText extends Overlay {
}
@Override
synchronized void update(boolean positionChanged, boolean tilesChanged) {
public synchronized void update(boolean positionChanged, boolean tilesChanged) {
// Log.d("...", "update " + tilesChanged + " " + positionChanged);
if (mWorkLayer != null) {

View File

@ -497,7 +497,7 @@
<!-- highway -->
<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="*" v="secondary|primary_link" zoom-min="9">
<line stroke="#f2df6d" width="1.3" cap="butt" fixed="true" fade="9"/>
@ -516,7 +516,7 @@
</rule>
<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>
@ -853,7 +853,9 @@
<!-- <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"
/> -->
<rule e="way" k="boundary" v="national_park">
<area fill="#d7e6b0"/>
</rule>
<!--<rule e="way" k="boundary" v="administrative"> -->
<rule e="way" k="admin_level" v="*">
<!-- <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"
fixed="true" cap="butt" /> </rule> -->
<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 e="way" k="admin_level" v="3">
<line stroke="#0000ff" width="0.95" fixed="true" cap="butt" />
</rule>
<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 e="way" k="admin_level" v="1">
<line stroke="#ff0000" width="0.95" fixed="true" cap="butt" />
@ -947,11 +949,11 @@
stroke="#ffffff" stroke-width="2.0" />
</rule>
<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" />
</rule>
<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" />
</rule>
</rule>

View File

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

View File

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