diff --git a/src/org/mapsforge/android/MapRenderer.java b/src/org/mapsforge/android/IMapRenderer.java
similarity index 81%
rename from src/org/mapsforge/android/MapRenderer.java
rename to src/org/mapsforge/android/IMapRenderer.java
index d84e2933..b5249d32 100644
--- a/src/org/mapsforge/android/MapRenderer.java
+++ b/src/org/mapsforge/android/IMapRenderer.java
@@ -14,6 +14,7 @@
*/
package org.mapsforge.android;
+import org.mapsforge.android.mapgenerator.IMapGenerator;
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
import android.opengl.GLSurfaceView;
@@ -21,7 +22,7 @@ import android.opengl.GLSurfaceView;
/**
*
*/
-public interface MapRenderer extends GLSurfaceView.Renderer {
+public interface IMapRenderer extends GLSurfaceView.Renderer {
/**
* @param mapGeneratorJob
@@ -31,9 +32,8 @@ public interface MapRenderer extends GLSurfaceView.Renderer {
public boolean passTile(MapGeneratorJob mapGeneratorJob);
/**
- * @return true when tile passed to renderer is processed false otherwise.
- * used to lock overwriting resources passed with the tile
- * (e.g. lock until bitmap is loaded to texture)
+ * @return true when tile passed to renderer is processed false otherwise. used to lock overwriting resources passed
+ * with the tile (e.g. lock until bitmap is loaded to texture)
*/
public boolean processedTile();
@@ -44,4 +44,6 @@ public interface MapRenderer extends GLSurfaceView.Renderer {
* ...
*/
public void redrawTiles(boolean clear);
+
+ public IMapGenerator createMapGenerator();
}
diff --git a/src/org/mapsforge/android/MapView.java b/src/org/mapsforge/android/MapView.java
index 28f8a36e..8703f23b 100644
--- a/src/org/mapsforge/android/MapView.java
+++ b/src/org/mapsforge/android/MapView.java
@@ -16,25 +16,35 @@ package org.mapsforge.android;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import javax.xml.parsers.ParserConfigurationException;
import org.mapsforge.android.input.TouchHandler;
import org.mapsforge.android.mapgenerator.IMapGenerator;
import org.mapsforge.android.mapgenerator.JobParameters;
import org.mapsforge.android.mapgenerator.JobQueue;
-import org.mapsforge.android.mapgenerator.JobTheme;
import org.mapsforge.android.mapgenerator.MapDatabaseFactory;
-import org.mapsforge.android.mapgenerator.MapDatabaseInternal;
-import org.mapsforge.android.mapgenerator.MapGeneratorFactory;
-import org.mapsforge.android.mapgenerator.MapGeneratorInternal;
+import org.mapsforge.android.mapgenerator.MapDatabases;
+import org.mapsforge.android.mapgenerator.MapGeneratorJob;
+import org.mapsforge.android.mapgenerator.MapRendererFactory;
+import org.mapsforge.android.mapgenerator.MapRenderers;
import org.mapsforge.android.mapgenerator.MapWorker;
+import org.mapsforge.android.mapgenerator.Theme;
import org.mapsforge.android.rendertheme.ExternalRenderTheme;
import org.mapsforge.android.rendertheme.InternalRenderTheme;
+import org.mapsforge.android.rendertheme.RenderTheme;
+import org.mapsforge.android.rendertheme.RenderThemeHandler;
import org.mapsforge.android.utils.GlConfigChooser;
import org.mapsforge.core.GeoPoint;
import org.mapsforge.core.MapPosition;
import org.mapsforge.database.FileOpenResult;
import org.mapsforge.database.IMapDatabase;
+import org.mapsforge.database.MapFileInfo;
import org.mapsforge.database.mapfile.MapDatabase;
+import org.xml.sax.SAXException;
import android.content.Context;
import android.opengl.GLSurfaceView;
@@ -49,8 +59,7 @@ import android.view.MotionEvent;
*
* This implementation supports offline map rendering as well as downloading map images (tiles) over an Internet
* connection. The operation mode of a MapView can be set in the constructor and changed at runtime with the
- * {@link #setMapGeneratorInternal(IMapGenerator)} method. Some MapView parameters depend on the selected operation
- * mode.
+ * {@link #setMapDatabase(MapDatabases)} method. Some MapView parameters depend on the selected operation mode.
*
* In offline rendering mode a special database file is required which contains the map data. Map files can be stored in
* any folder. The current map file is set by calling {@link #setMapFile(String)}. To retrieve the current
@@ -67,12 +76,12 @@ public class MapView extends GLSurfaceView {
public static final InternalRenderTheme DEFAULT_RENDER_THEME = InternalRenderTheme.OSMARENDER;
private static final float DEFAULT_TEXT_SCALE = 1;
+ private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 16);
private final MapController mMapController;
// private final MapMover mMapMover;
// private final ZoomAnimator mZoomAnimator;
-
- private final MapScaleBar mMapScaleBar;
+ // private final MapScaleBar mMapScaleBar;
private final MapViewPosition mMapViewPosition;
private final MapZoomControls mMapZoomControls;
@@ -80,10 +89,11 @@ public class MapView extends GLSurfaceView {
private final TouchHandler mTouchEventHandler;
private IMapDatabase mMapDatabase;
- private IMapGenerator mMapGenerator;
- private MapRenderer mMapRenderer;
+ private MapDatabases mMapDatabaseType;
+ private IMapRenderer mMapRenderer;
private JobQueue mJobQueue;
- private MapWorker mMapWorker;
+ private MapWorker mMapWorkers[];
+ private int mNumMapWorkers = 6;
private JobParameters mJobParameters;
private DebugSettings mDebugSettings;
private String mMapFile;
@@ -95,9 +105,7 @@ public class MapView extends GLSurfaceView {
* if the context object is not an instance of {@link MapActivity} .
*/
public MapView(Context context) {
- this(context, null,
- MapGeneratorFactory.createMapGenerator(MapGeneratorInternal.GL_RENDERER),
- MapDatabaseFactory.createMapDatabase(MapDatabaseInternal.MAP_READER));
+ this(context, null, MapRenderers.GL_RENDERER, MapDatabases.MAP_READER);
}
/**
@@ -110,25 +118,12 @@ public class MapView extends GLSurfaceView {
*/
public MapView(Context context, AttributeSet attributeSet) {
this(context, attributeSet,
- MapGeneratorFactory.createMapGenerator(attributeSet),
- MapDatabaseFactory.createMapDatabase(attributeSet));
- }
-
- /**
- * @param context
- * the enclosing MapActivity instance.
- * @param mapGenerator
- * the MapGenerator for this MapView.
- * @throws IllegalArgumentException
- * if the context object is not an instance of {@link MapActivity} .
- */
- public MapView(Context context, IMapGenerator mapGenerator) {
- this(context, null, mapGenerator, MapDatabaseFactory
- .createMapDatabase(MapDatabaseInternal.MAP_READER));
+ MapRendererFactory.getMapGenerator(attributeSet),
+ MapDatabaseFactory.getMapDatabase(attributeSet));
}
private MapView(Context context, AttributeSet attributeSet,
- IMapGenerator mapGenerator, IMapDatabase mapDatabase) {
+ MapRenderers mapGeneratorType, MapDatabases mapDatabaseType) {
super(context, attributeSet);
@@ -147,46 +142,63 @@ public class MapView extends GLSurfaceView {
mJobParameters = new JobParameters(DEFAULT_RENDER_THEME, DEFAULT_TEXT_SCALE);
mMapController = new MapController(this);
- // mMapDatabase = MapDatabaseFactory.createMapDatabase(MapDatabaseInternal.POSTGIS_READER);
- // mMapDatabase = MapDatabaseFactory.createMapDatabase(MapDatabaseInternal.JSON_READER);
- mMapDatabase = mapDatabase;
+ mMapDatabaseType = mapDatabaseType;
mMapViewPosition = new MapViewPosition(this);
- mMapScaleBar = new MapScaleBar(this);
+ // mMapScaleBar = new MapScaleBar(this);
mMapZoomControls = new MapZoomControls(mapActivity, this);
mProjection = new MapViewProjection(this);
mTouchEventHandler = new TouchHandler(mapActivity, this);
mJobQueue = new JobQueue(this);
- mMapWorker = new MapWorker(this);
- mMapWorker.start();
+
// mMapMover = new MapMover(this);
// mMapMover.start();
// mZoomAnimator = new ZoomAnimator(this);
// mZoomAnimator.start();
- setMapGeneratorInternal(mapGenerator);
+ mMapRenderer = MapRendererFactory.createMapRenderer(this, mapGeneratorType);
+ mMapWorkers = new MapWorker[mNumMapWorkers];
- GeoPoint startPoint = mMapGenerator.getStartPoint();
- if (startPoint != null) {
- mMapViewPosition.setMapCenter(startPoint);
+ for (int i = 0; i < mNumMapWorkers; i++) {
+ IMapDatabase mapDatabase = MapDatabaseFactory
+ .createMapDatabase(mapDatabaseType);
+
+ IMapGenerator mapGenerator = mMapRenderer.createMapGenerator();
+ mapGenerator.setMapDatabase(mapDatabase);
+
+ if (i == 0) {
+ mMapDatabase = mapDatabase;
+ initMapStartPosition();
+
+ // mapGenerator.setRendertheme(DEFAULT_RENDER_THEME);
+ }
+ mMapWorkers[i] = new MapWorker(i, this, mapGenerator, mMapRenderer);
+ mMapWorkers[i].start();
}
- Byte startZoomLevel = mMapGenerator.getStartZoomLevel();
- if (startZoomLevel != null) {
- mMapViewPosition.setZoomLevel(startZoomLevel.byteValue());
- }
+ setRenderTheme(InternalRenderTheme.OSMARENDER);
mapActivity.registerMapView(this);
setEGLConfigChooser(new GlConfigChooser());
setEGLContextClientVersion(2);
- mMapRenderer = mMapGenerator.getMapRenderer(this);
setRenderer(mMapRenderer);
-
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
- mMapWorker.setMapRenderer(mMapRenderer);
+ }
+
+ private void initMapStartPosition() {
+ GeoPoint startPoint = getStartPoint();
+ if (startPoint != null) {
+ mMapViewPosition.setMapCenter(startPoint);
+ }
+
+ Byte startZoomLevel = getStartZoomLevel();
+ if (startZoomLevel != null) {
+ mMapViewPosition.setZoomLevel(startZoomLevel.byteValue());
+ }
+
}
/**
@@ -224,13 +236,6 @@ public class MapView extends GLSurfaceView {
return mMapFile;
}
- /**
- * @return the currently used MapGenerator (may be null).
- */
- public IMapGenerator getMapGenerator() {
- return mMapGenerator;
- }
-
// /**
// * @return the MapMover which is used by this MapView.
// */
@@ -245,19 +250,19 @@ public class MapView extends GLSurfaceView {
return mMapViewPosition;
}
- /**
- * @return the scale bar which is used in this MapView.
- */
- public MapScaleBar getMapScaleBar() {
- return mMapScaleBar;
- }
+ // /**
+ // * @return the scale bar which is used in this MapView.
+ // */
+ // public MapScaleBar getMapScaleBar() {
+ // return mMapScaleBar;
+ // }
- /**
- * @return the zoom controls instance which is used in this MapView.
- */
- public MapZoomControls getMapZoomControls() {
- return mMapZoomControls;
- }
+ // /**
+ // * @return the zoom controls instance which is used in this MapView.
+ // */
+ // public MapZoomControls getMapZoomControls() {
+ // return mMapZoomControls;
+ // }
/**
* @return the currently used projection of the map. Do not keep this object for a longer time.
@@ -362,37 +367,41 @@ public class MapView extends GLSurfaceView {
// mZoomAnimator.pause();
// mMapMover.pause();
- mMapWorker.pause();
// mZoomAnimator.awaitPausing();
// mMapMover.awaitPausing();
- mMapWorker.awaitPausing();
// mZoomAnimator.proceed();
// mMapMover.stopMove();
// mMapMover.proceed();
- mMapWorker.proceed();
- mMapDatabase.closeFile();
+ boolean initialized = false;
- if (mapFile != null)
- fileOpenResult = mMapDatabase.openFile(new File(mapFile));
- else
- fileOpenResult = mMapDatabase.openFile(null);
+ mJobQueue.clear();
- if (fileOpenResult != null && fileOpenResult.isSuccess()) {
- mMapFile = mapFile;
+ mapWorkersPause();
- GeoPoint startPoint = mMapGenerator.getStartPoint();
- if (startPoint != null) {
- Log.d(TAG, "mapfile got startpoint");
- mMapViewPosition.setMapCenter(startPoint);
+ for (MapWorker mapWorker : mMapWorkers) {
+
+ IMapGenerator mapGenerator = mapWorker.getMapGenerator();
+ IMapDatabase mapDatabase = mapGenerator.getMapDatabase();
+
+ mapDatabase.closeFile();
+
+ if (mapFile != null)
+ fileOpenResult = mapDatabase.openFile(new File(mapFile));
+ else
+ fileOpenResult = mapDatabase.openFile(null);
+
+ if (fileOpenResult != null && fileOpenResult.isSuccess()) {
+ mMapFile = mapFile;
+
+ if (!initialized)
+ initialized = true;
}
+ }
- Byte startZoomLevel = mMapGenerator.getStartZoomLevel();
- if (startZoomLevel != null) {
- Log.d(TAG, "mapfile got start zoomlevel");
- mMapViewPosition.setZoomLevel(startZoomLevel.byteValue());
- }
+ mapWorkersProceed();
+ if (initialized) {
clearAndRedrawMapView();
Log.d(TAG, "mapfile set");
return true;
@@ -404,76 +413,61 @@ public class MapView extends GLSurfaceView {
return false;
}
- /**
- * Sets the MapGenerator for this MapView.
- *
- * @param mapGenerator
- * the new MapGenerator.
- */
- public void setMapGenerator(IMapGenerator mapGenerator) {
-
- if (mMapGenerator != mapGenerator) {
- setMapGeneratorInternal(mapGenerator);
-
- clearAndRedrawMapView();
+ private GeoPoint getStartPoint() {
+ if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
+ MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
+ if (mapFileInfo.startPosition != null) {
+ return mapFileInfo.startPosition;
+ } else if (mapFileInfo.mapCenter != null) {
+ return mapFileInfo.mapCenter;
+ }
}
+
+ return null;
}
- private void setMapGeneratorInternal(IMapGenerator mapGenerator) {
- if (mapGenerator == null) {
- throw new IllegalArgumentException("mapGenerator must not be null");
+ private Byte getStartZoomLevel() {
+ if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
+ MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
+ if (mapFileInfo.startZoomLevel != null) {
+ return mapFileInfo.startZoomLevel;
+ }
}
- mapGenerator.setMapDatabase(mMapDatabase);
-
- mMapGenerator = mapGenerator;
- mMapWorker.setMapGenerator(mMapGenerator);
-
+ return DEFAULT_START_ZOOM_LEVEL;
}
/**
* Sets the MapDatabase for this MapView.
*
- * @param mapDatabase
+ * @param mapDatabaseType
* the new MapDatabase.
*/
- public void setMapDatabase(IMapDatabase mapDatabase) {
- Log.d(TAG, "setMapDatabase " + mapDatabase.getClass());
- if (mMapDatabase != mapDatabase) {
- if (mMapDatabase != null)
- mMapDatabase.closeFile();
+ public void setMapDatabase(MapDatabases mapDatabaseType) {
+ IMapGenerator mapGenerator;
- setMapDatabaseInternal(mapDatabase);
+ Log.d(TAG, "setMapDatabase " + mapDatabaseType.name());
- // clearAndRedrawMapView();
- }
- }
+ if (mMapDatabaseType == mapDatabaseType)
+ return;
- private void setMapDatabaseInternal(IMapDatabase mapDatabase) {
- if (mapDatabase == null) {
- throw new IllegalArgumentException("MapDatabase must not be null");
- }
+ mapWorkersPause();
- if (!mMapWorker.isPausing()) {
- mMapWorker.pause();
- mMapWorker.awaitPausing();
+ for (MapWorker mapWorker : mMapWorkers) {
+ mapGenerator = mapWorker.getMapGenerator();
+
+ mapGenerator.setMapDatabase(MapDatabaseFactory
+ .createMapDatabase(mapDatabaseType));
}
mJobQueue.clear();
- mMapDatabase = mapDatabase;
- mMapGenerator.setMapDatabase(mMapDatabase);
-
- Log.d(TAG, "setMapDatabaseInternal " + mapDatabase.getClass());
String mapFile = mMapFile;
mMapFile = null;
setMapFile(mapFile);
- mMapWorker.proceed();
-
- // mMapWorker.setMapDatabase(mMapDatabase);
-
+ mapWorkersProceed();
}
/**
@@ -489,8 +483,7 @@ public class MapView extends GLSurfaceView {
throw new IllegalArgumentException("render theme must not be null");
}
- Log.d(TAG, "set rendertheme " + internalRenderTheme);
- mJobParameters = new JobParameters(internalRenderTheme, mJobParameters.textScale);
+ setRenderTheme((Theme) internalRenderTheme);
clearAndRedrawMapView();
}
@@ -510,12 +503,40 @@ public class MapView extends GLSurfaceView {
throw new IllegalArgumentException("render theme path must not be null");
}
- JobTheme jobTheme = new ExternalRenderTheme(renderThemePath);
- mJobParameters = new JobParameters(jobTheme, mJobParameters.textScale);
+ setRenderTheme(new ExternalRenderTheme(renderThemePath));
clearAndRedrawMapView();
}
+ private boolean setRenderTheme(Theme theme) {
+
+ mapWorkersPause();
+
+ InputStream inputStream = null;
+ try {
+ inputStream = theme.getRenderThemeAsStream();
+ RenderTheme t = RenderThemeHandler.getRenderTheme(inputStream);
+ mMapWorkers[0].getMapGenerator().setRenderTheme(t);
+ return true;
+ } catch (ParserConfigurationException e) {
+ Log.e(TAG, e.getMessage());
+ } catch (SAXException e) {
+ Log.e(TAG, e.getMessage());
+ } catch (IOException e) {
+ Log.e(TAG, e.getMessage());
+ } finally {
+ mapWorkersProceed();
+ try {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ } catch (IOException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ }
+ return false;
+ }
+
/**
* Sets the text scale for the map rendering. Has no effect in downloading mode.
*
@@ -523,7 +544,7 @@ public class MapView extends GLSurfaceView {
* the new text scale for the map rendering.
*/
public void setTextScale(float textScale) {
- mJobParameters = new JobParameters(mJobParameters.jobTheme, textScale);
+ mJobParameters = new JobParameters(mJobParameters.theme, textScale);
clearAndRedrawMapView();
}
@@ -583,28 +604,33 @@ public class MapView extends GLSurfaceView {
@Override
protected synchronized void onSizeChanged(int width, int height, int oldWidth,
int oldHeight) {
- mMapWorker.pause();
- mMapWorker.awaitPausing();
- super.onSizeChanged(width, height, oldWidth, oldHeight);
- mMapWorker.proceed();
-
+ for (MapWorker mapWorker : mMapWorkers) {
+ mapWorker.pause();
+ mapWorker.awaitPausing();
+ super.onSizeChanged(width, height, oldWidth, oldHeight);
+ mapWorker.proceed();
+ }
// redrawTiles();
}
void destroy() {
// mMapMover.interrupt();
- mMapWorker.interrupt();
// mZoomAnimator.interrupt();
- try {
- mMapWorker.join();
- } catch (InterruptedException e) {
- // restore the interrupted status
- Thread.currentThread().interrupt();
+ for (MapWorker mapWorker : mMapWorkers) {
+ mapWorker.interrupt();
+
+ try {
+ mapWorker.join();
+ } catch (InterruptedException e) {
+ // restore the interrupted status
+ Thread.currentThread().interrupt();
+ }
+ IMapDatabase mapDatabase = mapWorker.getMapGenerator().getMapDatabase();
+ mapDatabase.closeFile();
}
- mMapScaleBar.destroy();
- mMapDatabase.closeFile();
+ // mMapScaleBar.destroy();
}
@@ -612,8 +638,9 @@ public class MapView extends GLSurfaceView {
* @return the maximum possible zoom level.
*/
byte getMaximumPossibleZoomLevel() {
- return (byte) Math.min(mMapZoomControls.getZoomLevelMax(),
- mMapGenerator.getZoomLevelMax());
+ return (byte) 20;
+ // FIXME Math.min(mMapZoomControls.getZoomLevelMax(),
+ // mMapGenerator.getZoomLevelMax());
}
/**
@@ -639,7 +666,9 @@ public class MapView extends GLSurfaceView {
@Override
public void onPause() {
super.onPause();
- mMapWorker.pause();
+ for (MapWorker mapWorker : mMapWorkers)
+ mapWorker.pause();
+
// mMapMover.pause();
// mZoomAnimator.pause();
}
@@ -647,7 +676,9 @@ public class MapView extends GLSurfaceView {
@Override
public void onResume() {
super.onResume();
- mMapWorker.proceed();
+ for (MapWorker mapWorker : mMapWorkers)
+ mapWorker.proceed();
+
// mMapMover.proceed();
// mZoomAnimator.proceed();
}
@@ -706,9 +737,33 @@ public class MapView extends GLSurfaceView {
}
/**
- * @return MapWorker
+ * add jobs and remember MapWorkers that stuff needs to be done
+ *
+ * @param jobs
+ * tile jobs
*/
- public MapWorker getMapWorker() {
- return mMapWorker;
+ public void addJobs(ArrayList jobs) {
+ mJobQueue.setJobs(jobs);
+
+ for (MapWorker m : mMapWorkers) {
+ synchronized (m) {
+ m.notify();
+ }
+ }
}
+
+ private void mapWorkersPause() {
+ for (MapWorker mapWorker : mMapWorkers) {
+ if (!mapWorker.isPausing()) {
+ mapWorker.pause();
+ mapWorker.awaitPausing();
+ }
+ }
+ }
+
+ private void mapWorkersProceed() {
+ for (MapWorker mapWorker : mMapWorkers)
+ mapWorker.proceed();
+ }
+
}
diff --git a/src/org/mapsforge/android/MapViewPosition.java b/src/org/mapsforge/android/MapViewPosition.java
index 0bfae24a..e3e20562 100644
--- a/src/org/mapsforge/android/MapViewPosition.java
+++ b/src/org/mapsforge/android/MapViewPosition.java
@@ -26,6 +26,7 @@ import android.util.FloatMath;
public class MapViewPosition {
private static float MAX_SCALE = 2.0f;
private static float MIN_SCALE = 1.0f;
+ private static int MAX_ZOOMLEVEL = 16;
private double mLatitude;
private double mLongitude;
@@ -162,12 +163,14 @@ public class MapViewPosition {
float s = mScale * scale;
if (s >= MAX_SCALE) {
-
- byte z = (byte) FloatMath.sqrt(s);
- if (z != 0 && mZoomLevel == 20)
+ if (s > 8)
return;
- mZoomLevel += z;
- s *= 1.0f / (1 << z);
+
+ if (mZoomLevel <= MAX_ZOOMLEVEL) {
+ byte z = (byte) FloatMath.sqrt(s);
+ mZoomLevel += z;
+ s *= 1.0f / (1 << z);
+ }
} else if (s < MIN_SCALE) {
byte z = (byte) FloatMath.sqrt(1 / s);
if (z != 0 && mZoomLevel == 1)
diff --git a/src/org/mapsforge/android/glrenderer/LayerPool.java b/src/org/mapsforge/android/glrenderer/LayerPool.java
index 9621c0ee..21215a21 100644
--- a/src/org/mapsforge/android/glrenderer/LayerPool.java
+++ b/src/org/mapsforge/android/glrenderer/LayerPool.java
@@ -18,31 +18,33 @@ package org.mapsforge.android.glrenderer;
import java.util.LinkedList;
class LayerPool {
- static private LinkedList pool;
+ static private LinkedList pool = null;
static private int count;
static void init() {
- pool = new LinkedList();
- count = 0;
+ if (pool == null) {
+ pool = new LinkedList();
+ count = 0;
+ }
}
static PoolItem get() {
- if (count == 0)
- return new PoolItem();
-
- PoolItem it;
synchronized (pool) {
- count--;
- it = pool.pop();
- it.used = 0;
- }
- return it;
+ if (count == 0)
+ return new PoolItem();
+
+ count--;
+ PoolItem it = pool.pop();
+ it.used = 0;
+ return it;
+ }
}
static void add(LinkedList items) {
- int size = items.size();
synchronized (pool) {
+ int size = items.size();
+
while (count < 4096 && size-- > 0) {
count++;
pool.add(items.pop());
diff --git a/src/org/mapsforge/android/glrenderer/LineLayers.java b/src/org/mapsforge/android/glrenderer/LineLayers.java
index d799f415..3299bb8d 100644
--- a/src/org/mapsforge/android/glrenderer/LineLayers.java
+++ b/src/org/mapsforge/android/glrenderer/LineLayers.java
@@ -61,7 +61,7 @@ class LineLayers {
ByteOrder.nativeOrder());
fbuf = bbuf.asFloatBuffer();
} else {
- fbuf.position(0);
+ fbuf.clear();
}
int pos = 0;
@@ -81,7 +81,7 @@ class LineLayers {
l.pool = null;
}
- fbuf.position(0);
+ fbuf.flip();
// not needed for drawing
layers = null;
@@ -105,7 +105,7 @@ class LineLayers {
ByteOrder.nativeOrder());
sbuf = bbuf.asShortBuffer();
} else {
- sbuf.position(0);
+ sbuf.clear();
}
int pos = 0;
@@ -129,7 +129,7 @@ class LineLayers {
l.pool = null;
}
- sbuf.position(0);
+ sbuf.flip();
// not needed for drawing
layers = null;
diff --git a/src/org/mapsforge/android/glrenderer/DatabaseRenderer.java b/src/org/mapsforge/android/glrenderer/MapGenerator.java
similarity index 73%
rename from src/org/mapsforge/android/glrenderer/DatabaseRenderer.java
rename to src/org/mapsforge/android/glrenderer/MapGenerator.java
index 1fd6c45b..64165fdb 100644
--- a/src/org/mapsforge/android/glrenderer/DatabaseRenderer.java
+++ b/src/org/mapsforge/android/glrenderer/MapGenerator.java
@@ -14,29 +14,19 @@
*/
package org.mapsforge.android.glrenderer;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.mapsforge.android.MapView;
import org.mapsforge.android.mapgenerator.IMapGenerator;
-import org.mapsforge.android.mapgenerator.JobTheme;
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
import org.mapsforge.android.rendertheme.IRenderCallback;
import org.mapsforge.android.rendertheme.RenderTheme;
-import org.mapsforge.android.rendertheme.RenderThemeHandler;
import org.mapsforge.android.rendertheme.renderinstruction.Area;
import org.mapsforge.android.rendertheme.renderinstruction.Line;
-import org.mapsforge.core.GeoPoint;
-import org.mapsforge.core.WebMercator;
+import org.mapsforge.android.rendertheme.renderinstruction.RenderInstruction;
+import org.mapsforge.core.MercatorProjection;
import org.mapsforge.core.Tag;
import org.mapsforge.core.Tile;
+import org.mapsforge.core.WebMercator;
import org.mapsforge.database.IMapDatabase;
import org.mapsforge.database.IMapDatabaseCallback;
-import org.mapsforge.database.MapFileInfo;
-import org.xml.sax.SAXException;
import android.graphics.Bitmap;
import android.graphics.Color;
@@ -46,33 +36,26 @@ import android.util.Log;
/**
*
*/
-public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
- IMapDatabaseCallback {
- private static String TAG = DatabaseRenderer.class.getName();
+public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabaseCallback {
+
+ private static String TAG = MapGenerator.class.getName();
- private static final byte ZOOM_MAX = 22;
- private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 16);
private static final double PI180 = (Math.PI / 180) / 1000000.0;
private static final double PIx4 = Math.PI * 4;
private static final double STROKE_INCREASE = Math.sqrt(2);
private static final byte STROKE_MIN_ZOOM_LEVEL = 12;
private static final byte LAYERS = 11;
+ private static final double f900913 = 20037508.342789244;
private static RenderTheme renderTheme;
private IMapDatabase mMapDatabase;
- private JobTheme mPreviousJobTheme;
- // private float mPreviousTextScale;
- private byte mPreviousZoomLevel;
-
private GLMapTile mCurrentTile;
private float[] mWayNodes;
private int[] mWays;
- private ArrayList mCurrentLines;
-
private LineLayers mLineLayers;
private PolygonLayers mPolyLayers;
private MeshLayers mMeshLayers;
@@ -81,14 +64,13 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
private int mLevels;
private boolean useSphericalMercator = false;
+ private float mStrokeScale = 1.0f;
/**
*
*/
- public DatabaseRenderer() {
+ public MapGenerator() {
Log.d(TAG, "init DatabaseRenderer");
- mCurrentLines = new ArrayList();
-
LayerPool.init();
}
@@ -107,7 +89,6 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
private boolean mProjected;
private boolean mProjectedResult;
private float mSimplify;
- private static final double f900913 = 20037508.342789244;
private boolean projectToTile(boolean area) {
if (mProjected)
@@ -136,6 +117,8 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
for (int pos = 0, outPos = 0, i = 0, m = mWays.length; i < m; i++) {
int len = mWays[i];
+ if (len == 0)
+ continue;
int cnt = 0;
float lat, lon, prevLon = 0, prevLat = 0;
@@ -197,6 +180,8 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
private boolean firstMatch;
private boolean prevClosed;
+ private RenderInstruction[] mRenderInstructions = null;
+
@Override
public void renderWay(byte layer, Tag[] tags, float[] wayNodes, int[] wayLength,
boolean changed) {
@@ -220,17 +205,20 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
mSimplify = 0;
}
- mCurrentLines.clear();
mWayNodes = wayNodes;
mWays = wayLength;
if (!firstMatch && prevClosed == closed && !changed) {
- DatabaseRenderer.renderTheme.matchWay(this, tags,
- (byte) (mCurrentTile.zoomLevel + 0),
- closed, false);
+ if (mRenderInstructions != null) {
+ for (int i = 0, n = mRenderInstructions.length; i < n; i++)
+ mRenderInstructions[i].renderWay(this, tags);
+ }
+ // MapGenerator.renderTheme.matchWay(this, tags,
+ // (byte) (mCurrentTile.zoomLevel + 0),
+ // closed, false);
} else {
prevClosed = closed;
- DatabaseRenderer.renderTheme.matchWay(this, tags,
+ mRenderInstructions = MapGenerator.renderTheme.matchWay(this, tags,
(byte) (mCurrentTile.zoomLevel + 0),
closed, true);
}
@@ -273,9 +261,6 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
@Override
public void renderWay(Line line) {
- // if (prevClosed && !mProjected)
- // return;
-
projectToTile(false);
LineLayer outlineLayer = null;
@@ -284,11 +269,12 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
float w = line.strokeWidth;
- if (!line.fixed)
- w *= mStrokeScale / 1.5f;
-
+ if (!line.fixed) {
+ w *= mStrokeScale;
+ w *= mProjectionScaleFactor;
+ }
if (line.outline != -1) {
- Line outline = DatabaseRenderer.renderTheme.getOutline(line.outline);
+ Line outline = MapGenerator.renderTheme.getOutline(line.outline);
if (outline != null) {
outlineLayer = mLineLayers.getLayer(mDrawingLayer + outline.level,
outline.color, true, false);
@@ -363,33 +349,19 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
if (mMapDatabase == null)
return false;
+ useSphericalMercator = WebMercator.NAME.equals(mMapDatabase.getMapProjection());
+
mCurrentTile = (GLMapTile) mapGeneratorJob.tile;
mDebugDrawPolygons = !mapGeneratorJob.debugSettings.mDisablePolygons;
- // FIXME still chance of concurrency with maprenderer updateVisibleList ?
if (mCurrentTile.isLoading || mCurrentTile.isDrawn)
return false;
mCurrentTile.isLoading = true;
- JobTheme jobTheme = mapGeneratorJob.jobParameters.jobTheme;
+ mLevels = MapGenerator.renderTheme.getLevels();
- if (jobTheme != mPreviousJobTheme) {
- if (!setRenderTheme(jobTheme)) {
- mPreviousJobTheme = null;
- return false;
- }
-
- mPreviousJobTheme = jobTheme;
- mPreviousZoomLevel = Byte.MIN_VALUE;
- mLevels = DatabaseRenderer.renderTheme.getLevels();
- }
-
- byte zoomLevel = mCurrentTile.zoomLevel;
- if (zoomLevel != mPreviousZoomLevel) {
- setScaleStrokeWidth(zoomLevel);
- mPreviousZoomLevel = zoomLevel;
- }
+ setScaleStrokeWidth(mCurrentTile.zoomLevel);
mLineLayers = new LineLayers();
mPolyLayers = new PolygonLayers();
@@ -399,81 +371,32 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
mCurrentTile.meshLayers = mMeshLayers;
firstMatch = true;
- mMapDatabase.executeQuery(mCurrentTile, this);
- // Log.d(TAG, "loaded " + mCurrentTile);
+ mProjectionScaleFactor = (float) (1.0 / Math.cos(MercatorProjection
+ .pixelYToLatitude(mCurrentTile.pixelY, mCurrentTile.zoomLevel)
+ * (Math.PI / 180))) / 1.5f;
+ mMapDatabase.executeQuery(mCurrentTile, this);
if (mapGeneratorJob.debugSettings.mDrawTileFrames) {
float[] coords = { 0, 0, 0, Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE,
Tile.TILE_SIZE, 0, 0, 0 };
LineLayer ll = mLineLayers.getLayer(Integer.MAX_VALUE, Color.BLACK, false,
true);
- ll.addLine(coords, 0, coords.length, 1.0f, false);
+ ll.addLine(coords, 0, coords.length, 2.0f, false);
}
mCurrentTile.newData = true;
return true;
}
- @Override
- public GeoPoint getStartPoint() {
- useSphericalMercator = false;
-
- if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
- MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
-
- if (WebMercator.NAME.equals(mapFileInfo.projectionName)) {
- Log.d(TAG, "using Spherical Mercator");
-
- useSphericalMercator = true;
- }
- if (mapFileInfo.startPosition != null) {
- return mapFileInfo.startPosition;
- } else if (mapFileInfo.mapCenter != null) {
- return mapFileInfo.mapCenter;
- }
-
- }
- return null;
- }
-
- @Override
- public Byte getStartZoomLevel() {
- return DEFAULT_START_ZOOM_LEVEL;
- }
-
- @Override
- public byte getZoomLevelMax() {
- return ZOOM_MAX;
- }
-
- private static boolean setRenderTheme(JobTheme jobTheme) {
- InputStream inputStream = null;
- try {
- inputStream = jobTheme.getRenderThemeAsStream();
- DatabaseRenderer.renderTheme = RenderThemeHandler.getRenderTheme(inputStream);
- return true;
- } catch (ParserConfigurationException e) {
- Log.e(TAG, e.getMessage());
- } catch (SAXException e) {
- Log.e(TAG, e.getMessage());
- } catch (IOException e) {
- Log.e(TAG, e.getMessage());
- } finally {
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (IOException e) {
- Log.e(TAG, e.getMessage());
- }
- }
- return false;
- }
+ private float mProjectionScaleFactor;
private static byte getValidLayer(byte layer) {
if (layer < 0) {
return 0;
+ /**
+ * return instances of MapRenderer
+ */
} else if (layer >= LAYERS) {
return LAYERS - 1;
} else {
@@ -481,9 +404,17 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
}
}
- @Override
- public MapRenderer getMapRenderer(MapView mapView) {
- return new MapRenderer(mapView);
+ /**
+ * Sets the scale stroke factor for the given zoom level.
+ *
+ * @param zoomLevel
+ * the zoom level for which the scale stroke factor should be set.
+ */
+ private void setScaleStrokeWidth(byte zoomLevel) {
+ int zoomLevelDiff = Math.max(zoomLevel - STROKE_MIN_ZOOM_LEVEL, 0);
+ mStrokeScale = (float) Math.pow(STROKE_INCREASE, zoomLevelDiff);
+ if (mStrokeScale < 1)
+ mStrokeScale = 1;
}
@Override
@@ -491,19 +422,13 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
mMapDatabase = mapDatabase;
}
- private static float mStrokeScale = 1.0f;
+ @Override
+ public IMapDatabase getMapDatabase() {
+ return mMapDatabase;
+ }
- /**
- * Sets the scale stroke factor for the given zoom level.
- *
- * @param zoomLevel
- * the zoom level for which the scale stroke factor should be set.
- */
- private static void setScaleStrokeWidth(byte zoomLevel) {
- int zoomLevelDiff = Math.max(zoomLevel - STROKE_MIN_ZOOM_LEVEL, 0);
- mStrokeScale = (float) Math.pow(STROKE_INCREASE, zoomLevelDiff);
- if (mStrokeScale < 1)
- mStrokeScale = 1;
- // DatabaseRenderer.renderTheme.scaleStrokeWidth(mStrokeScale);
+ @Override
+ public void setRenderTheme(RenderTheme theme) {
+ MapGenerator.renderTheme = theme;
}
}
diff --git a/src/org/mapsforge/android/glrenderer/MapRenderer.java b/src/org/mapsforge/android/glrenderer/MapRenderer.java
index deb118d1..047af6dd 100644
--- a/src/org/mapsforge/android/glrenderer/MapRenderer.java
+++ b/src/org/mapsforge/android/glrenderer/MapRenderer.java
@@ -14,6 +14,57 @@
*/
package org.mapsforge.android.glrenderer;
+import static android.opengl.GLES20.GL_ARRAY_BUFFER;
+import static android.opengl.GLES20.GL_BLEND;
+import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
+import static android.opengl.GLES20.GL_DEPTH_TEST;
+import static android.opengl.GLES20.GL_DITHER;
+import static android.opengl.GLES20.GL_DYNAMIC_DRAW;
+import static android.opengl.GLES20.GL_EQUAL;
+import static android.opengl.GLES20.GL_EXTENSIONS;
+import static android.opengl.GLES20.GL_FLOAT;
+import static android.opengl.GLES20.GL_INVERT;
+import static android.opengl.GLES20.GL_NEVER;
+import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
+import static android.opengl.GLES20.GL_SCISSOR_TEST;
+import static android.opengl.GLES20.GL_SRC_ALPHA;
+import static android.opengl.GLES20.GL_STENCIL_BUFFER_BIT;
+import static android.opengl.GLES20.GL_STENCIL_TEST;
+import static android.opengl.GLES20.GL_TRIANGLES;
+import static android.opengl.GLES20.GL_TRIANGLE_FAN;
+import static android.opengl.GLES20.GL_TRIANGLE_STRIP;
+import static android.opengl.GLES20.GL_ZERO;
+import static android.opengl.GLES20.glBindBuffer;
+import static android.opengl.GLES20.glBlendFunc;
+import static android.opengl.GLES20.glBufferData;
+import static android.opengl.GLES20.glClear;
+import static android.opengl.GLES20.glClearColor;
+import static android.opengl.GLES20.glClearStencil;
+import static android.opengl.GLES20.glColorMask;
+import static android.opengl.GLES20.glDepthMask;
+import static android.opengl.GLES20.glDisable;
+import static android.opengl.GLES20.glDisableVertexAttribArray;
+import static android.opengl.GLES20.glDrawArrays;
+import static android.opengl.GLES20.glEnable;
+import static android.opengl.GLES20.glEnableVertexAttribArray;
+import static android.opengl.GLES20.glFinish;
+import static android.opengl.GLES20.glGenBuffers;
+import static android.opengl.GLES20.glGetAttribLocation;
+import static android.opengl.GLES20.glGetString;
+import static android.opengl.GLES20.glGetUniformLocation;
+import static android.opengl.GLES20.glScissor;
+import static android.opengl.GLES20.glStencilFunc;
+import static android.opengl.GLES20.glStencilMask;
+import static android.opengl.GLES20.glStencilOp;
+import static android.opengl.GLES20.glUniform1f;
+import static android.opengl.GLES20.glUniform2f;
+import static android.opengl.GLES20.glUniform4f;
+import static android.opengl.GLES20.glUniform4fv;
+import static android.opengl.GLES20.glUniformMatrix4fv;
+import static android.opengl.GLES20.glUseProgram;
+import static android.opengl.GLES20.glVertexAttribPointer;
+import static android.opengl.GLES20.glViewport;
+
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
@@ -25,10 +76,9 @@ import javax.microedition.khronos.opengles.GL10;
import org.mapsforge.android.DebugSettings;
import org.mapsforge.android.MapView;
-import org.mapsforge.android.mapgenerator.JobParameters;
import org.mapsforge.android.mapgenerator.IMapGenerator;
+import org.mapsforge.android.mapgenerator.JobParameters;
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
-import org.mapsforge.android.mapgenerator.MapWorker;
import org.mapsforge.android.mapgenerator.TileCacheKey;
import org.mapsforge.android.mapgenerator.TileDistanceSort;
import org.mapsforge.android.utils.GlConfigChooser;
@@ -47,12 +97,15 @@ import android.util.Log;
* TODO - use proxy child/parent tile nearer to current tile (currently it is always parent first) - use stencil instead
* of scissor mask for rotation - draw up to two parents above current tile, maybe prefetch parent
*/
-public class MapRenderer implements org.mapsforge.android.MapRenderer {
+public class MapRenderer implements org.mapsforge.android.IMapRenderer {
private static final String TAG = "MapRenderer";
+ private static final int MB = 1024 * 1024;
+
+ private boolean mTriangulate = false;
private static int CACHE_TILES_MAX = 400;
private static int CACHE_TILES = CACHE_TILES_MAX;
- private static final int LIMIT_BUFFERS = 32 * (1024 * 1024);
+ private static int LIMIT_BUFFERS = 20 * MB;
private static final int OES_HALF_FLOAT = 0x8D61;
private static final int FLOAT_BYTES = 4;
@@ -64,8 +117,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
private static int STENCIL_BITS = 8;
private final MapView mMapView;
- private final MapWorker mMapWorker;
-
private final ArrayList mJobList;
private final ArrayList mVBOs;
private final TileCacheKey mTileCacheKey;
@@ -88,9 +139,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
// current center tile
private long mTileX, mTileY;
- private FloatBuffer floatBuffer = null;
- // private ByteBuffer byteBuffer = null;
- private ShortBuffer shortBuffer = null;
+ private FloatBuffer floatBuffer[];
+ private ShortBuffer shortBuffer[];
boolean useHalfFloat = false;
@@ -147,7 +197,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
public MapRenderer(MapView mapView) {
Log.d(TAG, "init MapRenderer");
mMapView = mapView;
- mMapWorker = mapView.getMapWorker();
mDebugSettings = mapView.getDebugSettings();
mVBOs = new ArrayList();
@@ -316,7 +365,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
mJobList.clear();
mJobParameter = mMapView.getJobParameters();
- IMapGenerator mapGenerator = mMapView.getMapGenerator();
int tiles = 0;
if (newTiles == null)
return false;
@@ -376,19 +424,19 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
newTiles.tiles[tiles++] = tile;
if (!tile.isDrawn && !tile.newData && !tile.isLoading) {
- MapGeneratorJob job = new MapGeneratorJob(tile, mapGenerator,
- mJobParameter, mDebugSettings);
+ MapGeneratorJob job = new MapGeneratorJob(tile, mJobParameter,
+ mDebugSettings);
mJobList.add(job);
}
// prefetch parent
- if (tile.parent != null && !tile.parent.isDrawn && !tile.parent.newData
- && !tile.parent.isLoading) {
- MapGeneratorJob job = new MapGeneratorJob(tile.parent, mapGenerator,
- mJobParameter, mDebugSettings);
- if (!mJobList.contains(job))
- mJobList.add(job);
- }
+ // if (tile.parent != null && !tile.parent.isDrawn && !tile.parent.newData
+ // && !tile.parent.isLoading) {
+ // MapGeneratorJob job = new MapGeneratorJob(tile.parent, mJobParameter,
+ // mDebugSettings);
+ // if (!mJobList.contains(job))
+ // mJobList.add(job);
+ // }
}
}
@@ -419,12 +467,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
limitCache(removes);
- if (mJobList.size() > 0) {
- mMapView.getJobQueue().setJobs(mJobList);
- synchronized (mMapWorker) {
- mMapWorker.notify();
- }
- }
+ if (mJobList.size() > 0)
+ mMapView.addJobs(mJobList);
return true;
}
@@ -513,7 +557,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
@Override
public boolean passTile(MapGeneratorJob mapGeneratorJob) {
- if (!timing)
+ if (!timing && mapGeneratorJob.tile.isVisible)
mMapView.requestRender();
return true;
}
@@ -524,10 +568,10 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
boolean blend = false;
// draw to framebuffer
- GLES20.glColorMask(true, true, true, true);
+ glColorMask(true, true, true, true);
// do not modify stencil buffer
- GLES20.glStencilMask(0);
+ glStencilMask(0);
for (int c = 0; c < count; c++) {
PolygonLayer l = mFillPolys[c];
@@ -541,26 +585,26 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
alpha = 1.0f;
if (!blend) {
- GLES20.glEnable(GLES20.GL_BLEND);
+ glEnable(GL_BLEND);
blend = true;
}
} else if (blend) {
- GLES20.glDisable(GLES20.GL_BLEND);
+ glDisable(GL_BLEND);
blend = false;
}
- GLES20.glUniform4f(gPolygonColorHandle,
+ glUniform4f(gPolygonColorHandle,
l.colors[0], l.colors[1], l.colors[2], alpha);
// set stencil buffer mask used to draw this layer
- GLES20.glStencilFunc(GLES20.GL_EQUAL, 0xff, 1 << c);
+ glStencilFunc(GL_EQUAL, 0xff, 1 << c);
// draw tile fill coordinates
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
if (blend)
- GLES20.glDisable(GLES20.GL_BLEND);
+ glDisable(GL_BLEND);
}
private boolean drawPolygons(GLMapTile tile, int diff) {
@@ -569,63 +613,68 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
if (tile.polygonLayers == null || tile.polygonLayers.array == null)
return true;
- GLES20.glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
+ glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
+ if (mLastBoundVBO != tile.polygonVBO.id) {
+ mLastBoundVBO = tile.polygonVBO.id;
+ glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
- if (useHalfFloat) {
- GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
- OES_HALF_FLOAT, false, 0,
- POLYGON_VERTICES_DATA_POS_OFFSET);
- } else {
- GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
- GLES20.GL_FLOAT, false, 0,
- POLYGON_VERTICES_DATA_POS_OFFSET);
+ if (useHalfFloat) {
+ glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
+ OES_HALF_FLOAT, false, 0,
+ POLYGON_VERTICES_DATA_POS_OFFSET);
+ } else {
+ glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
+ GL_FLOAT, false, 0,
+ POLYGON_VERTICES_DATA_POS_OFFSET);
+ }
+
+ // glBindBuffer(GL_ARRAY_BUFFER, 0);
}
-
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
-
setMatrix(tile, diff);
- GLES20.glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
+ glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
boolean firstPass = true;
for (int i = 0, n = tile.polygonLayers.array.length; i < n; i++) {
PolygonLayer l = tile.polygonLayers.array[i];
- if (cnt == 0) {
- // disable drawing to framebuffer
- GLES20.glColorMask(false, false, false, false);
-
- // never pass the test, i.e. always apply first stencil op (sfail)
- GLES20.glStencilFunc(GLES20.GL_NEVER, 0, 0xff);
-
- if (firstPass)
- firstPass = false;
- else {
- // clear stencilbuffer
- GLES20.glStencilMask(0xFF);
- GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);
-
- // clear stencilbuffer (tile region)
- // GLES20.glStencilOp(GLES20.GL_ZERO, GLES20.GL_ZERO, GLES20.GL_ZERO);
- // GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
- }
-
- // stencil op for stencil method polygon drawing
- GLES20.glStencilOp(GLES20.GL_INVERT, GLES20.GL_INVERT, GLES20.GL_INVERT);
- }
-
// fade out polygon layers (set in RederTheme)
if (l.fadeLevel > 0 && l.fadeLevel > mDrawZ)
continue;
+ if (cnt == 0) {
+ // disable drawing to framebuffer
+ glColorMask(false, false, false, false);
+
+ // never pass the test, i.e. always apply first stencil op (sfail)
+ glStencilFunc(GL_NEVER, 0, 0xff);
+
+ if (firstPass)
+ firstPass = false;
+ else {
+ // eeek, nexus! - cant do old-school polygons
+ // glFinish();
+
+ // clear stencilbuffer
+ glStencilMask(0xFF);
+ // glClear(GL_STENCIL_BUFFER_BIT);
+
+ // clear stencilbuffer (tile region)
+ glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ }
+
+ // stencil op for stencil method polygon drawing
+ glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
+ }
+
mFillPolys[cnt] = l;
// set stencil mask to draw to
- GLES20.glStencilMask(1 << cnt++);
+ glStencilMask(1 << cnt++);
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, l.offset, l.verticesCnt);
+ glDrawArrays(GL_TRIANGLE_FAN, l.offset, l.verticesCnt);
// draw up to 8 layers into stencil buffer
if (cnt == STENCIL_BITS) {
@@ -634,47 +683,54 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
}
- if (cnt > 0)
+ if (cnt > 0) {
fillPolygons(cnt);
-
+ // eeek, nexus! - cant do old-school polygons
+ // glFinish();
+ }
return true;
}
+ private int mLastBoundVBO;
+
private boolean drawTriangles(GLMapTile tile, int diff) {
if (tile.meshLayers == null || tile.meshLayers.array == null)
return true;
- GLES20.glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
+ glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
+ if (mLastBoundVBO != tile.polygonVBO.id) {
+ mLastBoundVBO = tile.polygonVBO.id;
+ glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
- if (useHalfFloat) {
- GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
- OES_HALF_FLOAT, false, 0,
- POLYGON_VERTICES_DATA_POS_OFFSET);
- } else {
- GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
- GLES20.GL_FLOAT, false, 0,
- POLYGON_VERTICES_DATA_POS_OFFSET);
+ if (useHalfFloat) {
+ glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
+ OES_HALF_FLOAT, false, 0,
+ POLYGON_VERTICES_DATA_POS_OFFSET);
+ } else {
+ glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
+ GL_FLOAT, false, 0,
+ POLYGON_VERTICES_DATA_POS_OFFSET);
+ }
+
+ // glBindBuffer(GL_ARRAY_BUFFER, 0);
}
-
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
-
setMatrix(tile, diff);
- GLES20.glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
+ glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
MeshLayer[] layers = tile.meshLayers.array;
for (int i = 0, n = layers.length; i < n; i++) {
MeshLayer l = layers[i];
- GLES20.glUniform4fv(gPolygonColorHandle, 1, l.colors, 0);
+ glUniform4fv(gPolygonColorHandle, 1, l.colors, 0);
- // GLES20.glUniform4f(gPolygonColorHandle, 1, 0, 0, 1);
+ // glUniform4f(gPolygonColorHandle, 1, 0, 0, 1);
// System.out.println("draw: " + l.offset + " " + l.verticesCnt);
- GLES20.glDrawArrays(GLES20.GL_TRIANGLES, l.offset, l.verticesCnt);
+ glDrawArrays(GL_TRIANGLES, l.offset, l.verticesCnt);
}
+
return true;
}
@@ -684,30 +740,32 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
if (tile.lineLayers == null || tile.lineLayers.array == null)
return false;
- GLES20.glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
+ glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.id);
+ if (mLastBoundVBO != tile.lineVBO.id) {
+ mLastBoundVBO = tile.lineVBO.id;
+ glBindBuffer(GL_ARRAY_BUFFER, tile.lineVBO.id);
- if (useHalfFloat) {
- GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, OES_HALF_FLOAT,
- false, 8, LINE_VERTICES_DATA_POS_OFFSET);
+ if (useHalfFloat) {
+ glVertexAttribPointer(gLineVertexPositionHandle, 2, OES_HALF_FLOAT,
+ false, 8, LINE_VERTICES_DATA_POS_OFFSET);
- GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, OES_HALF_FLOAT,
- false, 8, LINE_VERTICES_DATA_TEX_OFFSET >> 1);
- } else {
- GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, GLES20.GL_FLOAT,
- false, 16, LINE_VERTICES_DATA_POS_OFFSET);
+ glVertexAttribPointer(gLineTexturePositionHandle, 2, OES_HALF_FLOAT,
+ false, 8, LINE_VERTICES_DATA_TEX_OFFSET >> 1);
+ } else {
+ glVertexAttribPointer(gLineVertexPositionHandle, 2, GL_FLOAT,
+ false, 16, LINE_VERTICES_DATA_POS_OFFSET);
- GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, GLES20.GL_FLOAT,
- false, 16, LINE_VERTICES_DATA_TEX_OFFSET);
+ glVertexAttribPointer(gLineTexturePositionHandle, 2, GL_FLOAT,
+ false, 16, LINE_VERTICES_DATA_TEX_OFFSET);
+ }
+ // glBindBuffer(GL_ARRAY_BUFFER, 0);
}
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
-
if (diff != 0)
z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
setMatrix(tile, diff);
- GLES20.glUniformMatrix4fv(gLineMatrixHandle, 1, false, mMVPMatrix, 0);
+ glUniformMatrix4fv(gLineMatrixHandle, 1, false, mMVPMatrix, 0);
LineLayer[] layers = tile.lineLayers.array;
@@ -729,42 +787,37 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
drawFixed = l.isFixed;
if (drawOutlines) {
- GLES20.glUniform2f(gLineModeHandle, 0, wdiv);
+ glUniform2f(gLineModeHandle, 0, wdiv);
} else if (!drawFixed) {
- GLES20.glUniform2f(gLineModeHandle, 0, wdiv * 0.98f);
+ glUniform2f(gLineModeHandle, 0, wdiv * 0.98f);
}
}
if (drawFixed) {
if (l.width < 1.0)
- GLES20.glUniform2f(gLineModeHandle, 0.4f, fdiv);
+ glUniform2f(gLineModeHandle, 0.4f, fdiv);
else
- GLES20.glUniform2f(gLineModeHandle, 0, fdiv);
+ glUniform2f(gLineModeHandle, 0, fdiv);
}
- GLES20.glUniform4fv(gLineColorHandle, 1, l.colors, 0);
+ glUniform4fv(gLineColorHandle, 1, l.colors, 0);
if (drawOutlines) {
for (int j = 0, m = l.outlines.size(); j < m; j++) {
LineLayer o = l.outlines.get(j);
if (mSimpleLines)
- GLES20.glUniform1f(gLineWidthHandle, o.width);
+ glUniform1f(gLineWidthHandle, o.width);
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, o.offset, o.verticesCnt);
+ glDrawArrays(GL_TRIANGLE_STRIP, o.offset, o.verticesCnt);
}
}
else {
if (mSimpleLines)
- GLES20.glUniform1f(gLineWidthHandle, l.width);
+ glUniform1f(gLineWidthHandle, l.width);
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
+ glDrawArrays(GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
}
- // cnt += l.verticesCnt;
}
- // GLES20.glUniform2f(gLineModeHandle, 0, wdiv);
- // float[] c = { 1, 0, 0, 1 };
- // GLES20.glUniform4fv(gLineColorHandle, 1, c, 0);
- // GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, cnt);
return true;
}
@@ -940,47 +993,53 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
}
- private boolean mTriangulate = false;
-
private int uploadCnt = 0;
private boolean uploadTileData(GLMapTile tile) {
- // not sure about this, but seems it fixes some flickering when
- // multiple tiles are uploaded in one go. but if this is really
- // the issue tiles should stay corrupted..
- if (uploadCnt++ > 0)
- GLES20.glFinish();
+ // double start = SystemClock.uptimeMillis();
+ // use multiple buffers to avoid overwriting buffer while current data is uploaded
+ // (or rather the blocking which is required to avoid this)
+ if (uploadCnt >= 10) {
+ // mMapView.requestRender();
+ // return false;
+ uploadCnt = 0;
+ glFinish();
+ }
+
+ // Upload line data to vertex buffer object
if (tile.lineVBO == null) {
- // Upload line data to vertex buffer object
synchronized (mVBOs) {
- if (mVBOs.size() < 2)
+ if (mVBOs.size() < 2) {
+ Log.d(TAG, "uploadTileData, no VBOs left");
return false;
-
+ }
tile.lineVBO = mVBOs.remove(mVBOs.size() - 1);
tile.polygonVBO = mVBOs.remove(mVBOs.size() - 1);
}
}
if (useHalfFloat)
- shortBuffer = tile.lineLayers.compileLayerData(shortBuffer);
+ shortBuffer[uploadCnt * 2] = tile.lineLayers
+ .compileLayerData(shortBuffer[uploadCnt * 2]);
else
- floatBuffer = tile.lineLayers.compileLayerData(floatBuffer);
+ floatBuffer[uploadCnt * 2] = tile.lineLayers
+ .compileLayerData(floatBuffer[uploadCnt * 2]);
if (tile.lineLayers.size > 0) {
mBufferMemoryUsage -= tile.lineVBO.size;
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.id);
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null, GLES20.GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, tile.lineVBO.id);
+ // glBufferData(GL_ARRAY_BUFFER, 0, null, GL_DYNAMIC_DRAW);
if (useHalfFloat) {
tile.lineVBO.size = tile.lineLayers.size * SHORT_BYTES;
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size,
- shortBuffer, GLES20.GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, tile.lineVBO.size,
+ shortBuffer[uploadCnt * 2], GL_DYNAMIC_DRAW);
} else {
tile.lineVBO.size = tile.lineLayers.size * FLOAT_BYTES;
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size,
- floatBuffer, GLES20.GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, tile.lineVBO.size,
+ floatBuffer[uploadCnt * 2], GL_DYNAMIC_DRAW);
}
mBufferMemoryUsage += tile.lineVBO.size;
@@ -991,26 +1050,28 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
if (!mTriangulate) {
if (useHalfFloat)
- shortBuffer = tile.polygonLayers.compileLayerData(shortBuffer);
+ shortBuffer[uploadCnt * 2 + 1] = tile.polygonLayers
+ .compileLayerData(shortBuffer[uploadCnt * 2 + 1]);
else
- floatBuffer = tile.polygonLayers.compileLayerData(floatBuffer);
+ floatBuffer[uploadCnt * 2 + 1] = tile.polygonLayers
+ .compileLayerData(floatBuffer[uploadCnt * 2 + 1]);
// Upload polygon data to vertex buffer object
if (tile.polygonLayers.size > 0) {
mBufferMemoryUsage -= tile.polygonVBO.size;
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null,
- GLES20.GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
+ // glBufferData(GL_ARRAY_BUFFER, 0, null,
+ // GL_DYNAMIC_DRAW);
if (useHalfFloat) {
tile.polygonVBO.size = tile.polygonLayers.size * SHORT_BYTES;
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
- shortBuffer, GLES20.GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
+ shortBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
} else {
tile.polygonVBO.size = tile.polygonLayers.size * FLOAT_BYTES;
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
- floatBuffer, GLES20.GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
+ floatBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
}
mBufferMemoryUsage += tile.polygonVBO.size;
@@ -1020,26 +1081,28 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
else {
if (useHalfFloat)
- shortBuffer = tile.meshLayers.compileLayerData(shortBuffer);
+ shortBuffer[uploadCnt * 2 + 1] = tile.meshLayers
+ .compileLayerData(shortBuffer[uploadCnt * 2 + 1]);
else
- floatBuffer = tile.meshLayers.compileLayerData(floatBuffer);
+ floatBuffer[uploadCnt * 2 + 1] = tile.meshLayers
+ .compileLayerData(floatBuffer[uploadCnt * 2 + 1]);
// Upload triangle data to vertex buffer object
if (tile.meshLayers.size > 0) {
mBufferMemoryUsage -= tile.polygonVBO.size;
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null,
- GLES20.GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
+ // glBufferData(GL_ARRAY_BUFFER, 0, null,
+ // GL_DYNAMIC_DRAW);
if (useHalfFloat) {
tile.polygonVBO.size = tile.meshLayers.size * SHORT_BYTES;
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
- shortBuffer, GLES20.GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
+ shortBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
} else {
tile.polygonVBO.size = tile.meshLayers.size * FLOAT_BYTES;
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
- floatBuffer, GLES20.GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
+ floatBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
}
mBufferMemoryUsage += tile.polygonVBO.size;
@@ -1050,6 +1113,13 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
tile.newData = false;
tile.isDrawn = true;
tile.isLoading = false;
+ // double compile = SystemClock.uptimeMillis();
+ // glFinish();
+ // double now = SystemClock.uptimeMillis();
+ // Log.d(TAG, tile + " - upload took: " + (now - start) + " "
+ // + (mBufferMemoryUsage / 1024) + "kb");
+
+ uploadCnt++;
return true;
}
@@ -1066,10 +1136,9 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
if (timing)
start = SystemClock.uptimeMillis();
- GLES20.glStencilMask(0xFF);
- GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
- GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);
- // GLES20.glFlush();
+ glStencilMask(0xFF);
+ glDisable(GL_SCISSOR_TEST);
+ glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// long endTime = SystemClock.uptimeMillis();
// long dt = endTime - startTime;
@@ -1100,22 +1169,21 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
GLMapTile[] tiles = curTiles.tiles;
if (mBufferMemoryUsage > LIMIT_BUFFERS) {
- Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / (1024 * 1024)
- + "MB");
+ Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / MB + "MB");
synchronized (mVBOs) {
for (VertexBufferObject vbo : mVBOs) {
if (vbo.size == 0)
continue;
mBufferMemoryUsage -= vbo.size;
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo.id);
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null,
- GLES20.GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo.id);
+ glBufferData(GL_ARRAY_BUFFER, 0, null,
+ GL_DYNAMIC_DRAW);
vbo.size = 0;
}
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
}
- Log.d(TAG, " > " + mBufferMemoryUsage / (1024 * 1024) + "MB");
+ Log.d(TAG, " > " + mBufferMemoryUsage / MB + "MB");
if (CACHE_TILES > 50)
CACHE_TILES -= 50;
@@ -1124,6 +1192,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
uploadCnt = 0;
+ mLastBoundVBO = -1;
// check visible tiles, set tile clip scissors, upload new vertex data
for (int i = 0; i < tileCnt; i++) {
@@ -1134,11 +1203,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
if (tile.newData) {
uploadTileData(tile);
-
- if (timing)
- Log.d(TAG, "buffer upload took: "
- + (SystemClock.uptimeMillis() - start));
-
continue;
}
@@ -1158,23 +1222,25 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
}
}
- // GLES20.glFinish();
- GlUtils.checkGlError("upload");
+
+ if (GlUtils.checkGlOutOfMemory("upload: " + mBufferMemoryUsage)
+ && LIMIT_BUFFERS > MB)
+ LIMIT_BUFFERS -= MB;
if (timing)
clear_time = (SystemClock.uptimeMillis() - start);
- GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
+ glEnable(GL_SCISSOR_TEST);
- GLES20.glUseProgram(gPolygonProgram);
- // GLES20.glEnableVertexAttribArray(gPolygonVertexPositionHandle);
+ glUseProgram(gPolygonProgram);
+ glEnableVertexAttribArray(gPolygonVertexPositionHandle);
if (!mTriangulate) {
- GLES20.glDisable(GLES20.GL_BLEND);
+ glDisable(GL_BLEND);
// Draw Polygons
- GLES20.glEnable(GLES20.GL_STENCIL_TEST);
+ glEnable(GL_STENCIL_TEST);
- // GLES20.glEnableVertexAttribArray(gPolygonVertexPositionHandle);
+ // glEnableVertexAttribArray(gPolygonVertexPositionHandle);
for (int i = 0; i < tileCnt; i++) {
if (tiles[i].isVisible) {
@@ -1186,8 +1252,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
drawProxyPolygons(tile);
}
}
- GlUtils.checkGlError("polygons");
- GLES20.glDisable(GLES20.GL_STENCIL_TEST);
+ // GlUtils.checkGlError("polygons");
+ glDisable(GL_STENCIL_TEST);
} else {
// Draw Triangles
for (int i = 0; i < tileCnt; i++) {
@@ -1200,23 +1266,22 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
drawProxyTriangles(tile);
}
}
- GlUtils.checkGlError("triangles");
+ // GlUtils.checkGlError("triangles");
}
- // required on GalaxyII, Android 2.3.3
- // GLES20.glDisableVertexAttribArray(gPolygonVertexPositionHandle);
+ // required on GalaxyII, Android 2.3.3 (cant just VAA enable once...)
+ glDisableVertexAttribArray(gPolygonVertexPositionHandle);
if (timing) {
- GLES20.glFinish();
+ glFinish();
poly_time = (SystemClock.uptimeMillis() - start);
}
- GLES20.glFlush();
// Draw lines
- GLES20.glEnable(GLES20.GL_BLEND);
- GLES20.glUseProgram(gLineProgram);
+ glEnable(GL_BLEND);
+ glUseProgram(gLineProgram);
- // GLES20.glEnableVertexAttribArray(gLineVertexPositionHandle);
- // GLES20.glEnableVertexAttribArray(gLineTexturePositionHandle);
+ glEnableVertexAttribArray(gLineVertexPositionHandle);
+ glEnableVertexAttribArray(gLineTexturePositionHandle);
for (int i = 0; i < tileCnt; i++) {
if (tiles[i].isVisible) {
@@ -1230,14 +1295,13 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
if (timing) {
- GLES20.glFinish();
+ glFinish();
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start) + " "
+ clear_time + " " + poly_time);
}
- // GLES20.glDisableVertexAttribArray(gLineVertexPositionHandle);
- // GLES20.glDisableVertexAttribArray(gLineTexturePositionHandle);
- GlUtils.checkGlError("lines");
- GLES20.glFinish();
+ glDisableVertexAttribArray(gLineVertexPositionHandle);
+ glDisableVertexAttribArray(gLineTexturePositionHandle);
+ // GlUtils.checkGlError("lines");
}
private int[] mVboIds;
@@ -1261,7 +1325,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
mHeight = height;
mAspect = (float) height / width;
- GLES20.glViewport(0, 0, width, height);
+ glViewport(0, 0, width, height);
int tiles = (mWidth / Tile.TILE_SIZE + 4) * (mHeight / Tile.TILE_SIZE + 4);
curTiles = new TilesData(tiles);
@@ -1271,7 +1335,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
// Set up vertex buffer objects
int numVBO = (CACHE_TILES + tiles) * 2;
mVboIds = new int[numVBO];
- GLES20.glGenBuffers(numVBO, mVboIds, 0);
+ glGenBuffers(numVBO, mVboIds, 0);
for (int i = 0; i < numVBO; i++)
mVBOs.add(new VertexBufferObject(mVboIds[i]));
@@ -1302,21 +1366,25 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
}
- String ext = GLES20.glGetString(GLES20.GL_EXTENSIONS);
+ String ext = glGetString(GL_EXTENSIONS);
- if (ext.indexOf("GL_OES_vertex_half_float") >= 0)
+ if (ext.indexOf("GL_OES_vertex_half_float") >= 0) {
useHalfFloat = true;
-
+ shortBuffer = new ShortBuffer[20];
+ }
+ else {
+ floatBuffer = new FloatBuffer[20];
+ }
Log.d(TAG, "Extensions: " + ext);
- gLineMatrixHandle = GLES20.glGetUniformLocation(gLineProgram, "u_center");
- gLineModeHandle = GLES20.glGetUniformLocation(gLineProgram, "u_mode");
- gLineColorHandle = GLES20.glGetUniformLocation(gLineProgram, "u_color");
+ gLineMatrixHandle = glGetUniformLocation(gLineProgram, "u_center");
+ gLineModeHandle = glGetUniformLocation(gLineProgram, "u_mode");
+ gLineColorHandle = glGetUniformLocation(gLineProgram, "u_color");
gLineVertexPositionHandle = GLES20
.glGetAttribLocation(gLineProgram, "a_position");
- gLineTexturePositionHandle = GLES20.glGetAttribLocation(gLineProgram, "a_st");
+ gLineTexturePositionHandle = glGetAttribLocation(gLineProgram, "a_st");
if (mSimpleLines)
- gLineWidthHandle = GLES20.glGetUniformLocation(gLineProgram, "u_width");
+ gLineWidthHandle = glGetUniformLocation(gLineProgram, "u_width");
// Set up the program for rendering polygons
gPolygonProgram = GlUtils.createProgram(Shaders.gPolygonVertexShader,
@@ -1325,31 +1393,39 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
Log.e(TAG, "Could not create polygon program.");
return;
}
- gPolygonMatrixHandle = GLES20.glGetUniformLocation(gPolygonProgram, "u_center");
- gPolygonVertexPositionHandle = GLES20.glGetAttribLocation(gPolygonProgram,
+ gPolygonMatrixHandle = glGetUniformLocation(gPolygonProgram, "u_center");
+ gPolygonVertexPositionHandle = glGetAttribLocation(gPolygonProgram,
"a_position");
- gPolygonColorHandle = GLES20.glGetUniformLocation(gPolygonProgram, "u_color");
+ gPolygonColorHandle = glGetUniformLocation(gPolygonProgram, "u_color");
- GLES20.glUseProgram(gPolygonProgram);
- GLES20.glEnableVertexAttribArray(gPolygonVertexPositionHandle);
+ // glUseProgram(gPolygonProgram);
+ // glEnableVertexAttribArray(gPolygonVertexPositionHandle);
+ //
+ // glUseProgram(gLineProgram);
+ // glEnableVertexAttribArray(gLineVertexPositionHandle);
+ // glEnableVertexAttribArray(gLineTexturePositionHandle);
- GLES20.glUseProgram(gLineProgram);
- GLES20.glEnableVertexAttribArray(gLineVertexPositionHandle);
- GLES20.glEnableVertexAttribArray(gLineTexturePositionHandle);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
-
- GLES20.glDisable(GLES20.GL_DEPTH_TEST);
- GLES20.glDepthMask(false);
- GLES20.glDisable(GLES20.GL_DITHER);
- GLES20.glClearColor(0.98f, 0.98f, 0.97f, 1.0f);
- GLES20.glClearStencil(0);
-
- // GLES20.glFrontFace(GLES20.GL_CCW);
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(false);
+ glDisable(GL_DITHER);
+ glClearColor(0.98f, 0.98f, 0.97f, 1.0f);
+ glClearStencil(0);
}
@Override
public boolean processedTile() {
return true;
}
+
+ public IMapGenerator getMapGenerator() {
+ return new MapGenerator();
+ }
+
+ @Override
+ public IMapGenerator createMapGenerator() {
+ return new MapGenerator();
+
+ }
}
diff --git a/src/org/mapsforge/android/glrenderer/PolygonLayers.java b/src/org/mapsforge/android/glrenderer/PolygonLayers.java
index 66ae641c..ebb35401 100644
--- a/src/org/mapsforge/android/glrenderer/PolygonLayers.java
+++ b/src/org/mapsforge/android/glrenderer/PolygonLayers.java
@@ -75,7 +75,7 @@ class PolygonLayers {
// Log.d("GLMap", "allocate buffer " + size);
fbuf = bbuf.asFloatBuffer();
} else {
- fbuf.position(0);
+ fbuf.clear();
}
fbuf.put(mFillCoords, 0, 8);
@@ -95,7 +95,7 @@ class PolygonLayers {
l.pool = null;
}
- fbuf.position(0);
+ fbuf.flip();
// not needed for drawing
layers = null;
@@ -121,7 +121,7 @@ class PolygonLayers {
ByteOrder.nativeOrder());
sbuf = bbuf.asShortBuffer();
} else {
- sbuf.position(0);
+ sbuf.clear();
}
short[] data = new short[PoolItem.SIZE];
@@ -157,7 +157,7 @@ class PolygonLayers {
l.pool = null;
}
- sbuf.position(0);
+ sbuf.flip();
// not needed for drawing
layers = null;
diff --git a/src/org/mapsforge/android/mapgenerator/IMapGenerator.java b/src/org/mapsforge/android/mapgenerator/IMapGenerator.java
index 9134e312..344c1d11 100644
--- a/src/org/mapsforge/android/mapgenerator/IMapGenerator.java
+++ b/src/org/mapsforge/android/mapgenerator/IMapGenerator.java
@@ -14,9 +14,7 @@
*/
package org.mapsforge.android.mapgenerator;
-import org.mapsforge.android.MapRenderer;
-import org.mapsforge.android.MapView;
-import org.mapsforge.core.GeoPoint;
+import org.mapsforge.android.rendertheme.RenderTheme;
import org.mapsforge.database.IMapDatabase;
/**
@@ -37,31 +35,13 @@ public interface IMapGenerator {
*/
boolean executeJob(MapGeneratorJob mapGeneratorJob);
- /**
- * @return the start point of this MapGenerator (may be null).
- */
- GeoPoint getStartPoint();
-
- /**
- * @return the start zoom level of this MapGenerator (may be null).
- */
- Byte getStartZoomLevel();
-
- /**
- * @return the maximum zoom level that this MapGenerator supports.
- */
- byte getZoomLevelMax();
-
- /**
- * @param mapView
- * the MapView
- * @return GLSurfaceView Renderer
- */
- MapRenderer getMapRenderer(MapView mapView);
-
/**
* @param mapDatabase
* the MapDatabase from which the map data will be read.
*/
void setMapDatabase(IMapDatabase mapDatabase);
+
+ IMapDatabase getMapDatabase();
+
+ void setRenderTheme(RenderTheme theme);
}
diff --git a/src/org/mapsforge/android/mapgenerator/JobParameters.java b/src/org/mapsforge/android/mapgenerator/JobParameters.java
index 3e95b469..b9be2257 100644
--- a/src/org/mapsforge/android/mapgenerator/JobParameters.java
+++ b/src/org/mapsforge/android/mapgenerator/JobParameters.java
@@ -22,7 +22,7 @@ public class JobParameters {
/**
* The render theme which should be used.
*/
- public final JobTheme jobTheme;
+ public final Theme theme;
/**
* The text scale factor which should applied to the render theme.
@@ -32,13 +32,13 @@ public class JobParameters {
private final int mHashCodeValue;
/**
- * @param jobTheme
+ * @param theme
* render theme which should be used.
* @param textScale
* the text scale factor which should applied to the render theme.
*/
- public JobParameters(JobTheme jobTheme, float textScale) {
- this.jobTheme = jobTheme;
+ public JobParameters(Theme theme, float textScale) {
+ this.theme = theme;
this.textScale = textScale;
mHashCodeValue = calculateHashCode();
}
@@ -52,11 +52,11 @@ public class JobParameters {
return false;
}
JobParameters other = (JobParameters) obj;
- if (jobTheme == null) {
- if (other.jobTheme != null) {
+ if (theme == null) {
+ if (other.theme != null) {
return false;
}
- } else if (!jobTheme.equals(other.jobTheme)) {
+ } else if (!theme.equals(other.theme)) {
return false;
}
if (Float.floatToIntBits(textScale) != Float.floatToIntBits(other.textScale)) {
@@ -75,7 +75,7 @@ public class JobParameters {
*/
private int calculateHashCode() {
int result = 7;
- result = 31 * result + ((jobTheme == null) ? 0 : jobTheme.hashCode());
+ result = 31 * result + ((theme == null) ? 0 : theme.hashCode());
result = 31 * result + Float.floatToIntBits(textScale);
return result;
}
diff --git a/src/org/mapsforge/android/mapgenerator/JobQueue.java b/src/org/mapsforge/android/mapgenerator/JobQueue.java
index 9b4db9d8..a2445204 100644
--- a/src/org/mapsforge/android/mapgenerator/JobQueue.java
+++ b/src/org/mapsforge/android/mapgenerator/JobQueue.java
@@ -103,7 +103,8 @@ public class JobQueue {
* Schedules all jobs in this queue.
*/
private void schedule() {
- PriorityQueue tempJobQueue = new PriorityQueue(INITIAL_CAPACITY);
+ PriorityQueue tempJobQueue = new PriorityQueue(
+ INITIAL_CAPACITY);
TileScheduler.time = SystemClock.uptimeMillis();
TileScheduler.mapPosition = mMapView.getMapPosition().getMapPosition();
diff --git a/src/org/mapsforge/android/mapgenerator/MapDatabaseFactory.java b/src/org/mapsforge/android/mapgenerator/MapDatabaseFactory.java
index 41f581d6..12bed3b1 100644
--- a/src/org/mapsforge/android/mapgenerator/MapDatabaseFactory.java
+++ b/src/org/mapsforge/android/mapgenerator/MapDatabaseFactory.java
@@ -37,29 +37,40 @@ public final class MapDatabaseFactory {
return new org.mapsforge.database.postgis.MapDatabase();
}
- MapDatabaseInternal mapDatabaseInternal = MapDatabaseInternal
- .valueOf(mapDatabaseName);
+ MapDatabases mapDatabaseInternal = MapDatabases.valueOf(mapDatabaseName);
return MapDatabaseFactory.createMapDatabase(mapDatabaseInternal);
}
+ public static MapDatabases getMapDatabase(AttributeSet attributeSet) {
+ String mapDatabaseName = attributeSet.getAttributeValue(null,
+ MAP_DATABASE_ATTRIBUTE_NAME);
+ if (mapDatabaseName == null) {
+ return MapDatabases.POSTGIS_READER;
+ }
+
+ return MapDatabases.valueOf(mapDatabaseName);
+ }
+
/**
- * @param mapDatabaseInternal
+ * @param mapDatabase
* the internal MapDatabase implementation.
* @return a new MapGenerator instance.
*/
- public static IMapDatabase createMapDatabase(MapDatabaseInternal mapDatabaseInternal) {
- switch (mapDatabaseInternal) {
+ public static IMapDatabase createMapDatabase(MapDatabases mapDatabase) {
+ switch (mapDatabase) {
case MAP_READER:
return new org.mapsforge.database.mapfile.MapDatabase();
case JSON_READER:
return new org.mapsforge.database.json.MapDatabase();
case POSTGIS_READER:
return new org.mapsforge.database.postgis.MapDatabase();
+ case PBMAP_READER:
+ return new org.mapsforge.database.pbmap.MapDatabase();
}
- throw new IllegalArgumentException("unknown enum value: " + mapDatabaseInternal);
+ throw new IllegalArgumentException("unknown enum value: " + mapDatabase);
}
private MapDatabaseFactory() {
diff --git a/src/org/mapsforge/android/mapgenerator/MapDatabaseInternal.java b/src/org/mapsforge/android/mapgenerator/MapDatabases.java
similarity index 93%
rename from src/org/mapsforge/android/mapgenerator/MapDatabaseInternal.java
rename to src/org/mapsforge/android/mapgenerator/MapDatabases.java
index da134d68..370f0347 100644
--- a/src/org/mapsforge/android/mapgenerator/MapDatabaseInternal.java
+++ b/src/org/mapsforge/android/mapgenerator/MapDatabases.java
@@ -17,7 +17,7 @@ package org.mapsforge.android.mapgenerator;
/**
* MapDatabase Implementations
*/
-public enum MapDatabaseInternal {
+public enum MapDatabases {
/**
* ...
*/
@@ -33,4 +33,8 @@ public enum MapDatabaseInternal {
*/
POSTGIS_READER,
+ /**
+ * ...
+ */
+ PBMAP_READER,
}
diff --git a/src/org/mapsforge/android/mapgenerator/MapGeneratorJob.java b/src/org/mapsforge/android/mapgenerator/MapGeneratorJob.java
index 476d3b1d..bab438b9 100644
--- a/src/org/mapsforge/android/mapgenerator/MapGeneratorJob.java
+++ b/src/org/mapsforge/android/mapgenerator/MapGeneratorJob.java
@@ -37,7 +37,7 @@ public class MapGeneratorJob implements Comparable, Serializabl
/**
* The rendering parameters for this job.
*/
- public final JobParameters jobParameters;
+ // public final JobParameters jobParameters;
/**
* The tile which should be generated.
@@ -45,7 +45,6 @@ public class MapGeneratorJob implements Comparable, Serializabl
public final MapTile tile;
private transient int mHashCodeValue;
- private final IMapGenerator mMapGenerator;
private transient double mPriority;
/**
@@ -90,18 +89,15 @@ public class MapGeneratorJob implements Comparable, Serializabl
*
* @param _tile
* the tile which should be generated.
- * @param mapGenerator
- * the MapGenerator for this job.
* @param _jobParameters
* the rendering parameters for this job.
* @param _debugSettings
* the debug settings for this job.
*/
- public MapGeneratorJob(MapTile _tile, IMapGenerator mapGenerator,
- JobParameters _jobParameters, DebugSettings _debugSettings) {
+ public MapGeneratorJob(MapTile _tile, JobParameters _jobParameters,
+ DebugSettings _debugSettings) {
tile = _tile;
- mMapGenerator = mapGenerator;
- jobParameters = _jobParameters;
+ // jobParameters = _jobParameters;
debugSettings = _debugSettings;
calculateTransientValues();
}
@@ -133,16 +129,14 @@ public class MapGeneratorJob implements Comparable, Serializabl
} else if (!debugSettings.equals(other.debugSettings)) {
return false;
}
- if (jobParameters == null) {
- if (other.jobParameters != null) {
- return false;
- }
- } else if (!jobParameters.equals(other.jobParameters)) {
- return false;
- }
- if (mMapGenerator != other.mMapGenerator) {
- return false;
- }
+ // if (jobParameters == null) {
+ // if (other.jobParameters != null) {
+ // return false;
+ // }
+ // } else if (!jobParameters.equals(other.jobParameters)) {
+ // return false;
+ // }
+
if (tile == null) {
if (other.tile != null) {
return false;
@@ -164,8 +158,7 @@ public class MapGeneratorJob implements Comparable, Serializabl
private int calculateHashCode() {
int result = 1;
result = 31 * result + ((debugSettings == null) ? 0 : debugSettings.hashCode());
- result = 31 * result + ((jobParameters == null) ? 0 : jobParameters.hashCode());
- result = 31 * result + ((mMapGenerator == null) ? 0 : mMapGenerator.hashCode());
+ // result = 31 * result + ((jobParameters == null) ? 0 : jobParameters.hashCode());
result = 31 * result + ((tile == null) ? 0 : tile.hashCode());
return result;
}
@@ -177,7 +170,8 @@ public class MapGeneratorJob implements Comparable, Serializabl
mHashCodeValue = calculateHashCode();
}
- private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
+ private void readObject(ObjectInputStream objectInputStream) throws IOException,
+ ClassNotFoundException {
objectInputStream.defaultReadObject();
calculateTransientValues();
}
diff --git a/src/org/mapsforge/android/mapgenerator/MapGeneratorFactory.java b/src/org/mapsforge/android/mapgenerator/MapRendererFactory.java
similarity index 57%
rename from src/org/mapsforge/android/mapgenerator/MapGeneratorFactory.java
rename to src/org/mapsforge/android/mapgenerator/MapRendererFactory.java
index a80d9465..5b20ca60 100644
--- a/src/org/mapsforge/android/mapgenerator/MapGeneratorFactory.java
+++ b/src/org/mapsforge/android/mapgenerator/MapRendererFactory.java
@@ -14,46 +14,66 @@
*/
package org.mapsforge.android.mapgenerator;
+import org.mapsforge.android.IMapRenderer;
+import org.mapsforge.android.MapView;
+
import android.util.AttributeSet;
/**
* A factory for the internal MapGenerator implementations.
*/
-public final class MapGeneratorFactory {
+public final class MapRendererFactory {
private static final String MAP_GENERATOR_ATTRIBUTE_NAME = "mapGenerator";
/**
+ * @param mapView
+ * ...
* @param attributeSet
* A collection of attributes which includes the desired MapGenerator.
* @return a new MapGenerator instance.
*/
- public static IMapGenerator createMapGenerator(AttributeSet attributeSet) {
- String mapGeneratorName = attributeSet.getAttributeValue(null, MAP_GENERATOR_ATTRIBUTE_NAME);
+ public static IMapRenderer createMapRenderer(MapView mapView,
+ AttributeSet attributeSet) {
+ String mapGeneratorName = attributeSet.getAttributeValue(null,
+ MAP_GENERATOR_ATTRIBUTE_NAME);
if (mapGeneratorName == null) {
- return new org.mapsforge.android.glrenderer.DatabaseRenderer();
+ return new org.mapsforge.android.glrenderer.MapRenderer(mapView);
}
- MapGeneratorInternal mapGeneratorInternal = MapGeneratorInternal.valueOf(mapGeneratorName);
- return MapGeneratorFactory.createMapGenerator(mapGeneratorInternal);
+ MapRenderers mapGeneratorInternal = MapRenderers.valueOf(mapGeneratorName);
+ return MapRendererFactory.createMapRenderer(mapView, mapGeneratorInternal);
+ }
+
+ public static MapRenderers getMapGenerator(AttributeSet attributeSet) {
+ String mapGeneratorName = attributeSet.getAttributeValue(null,
+ MAP_GENERATOR_ATTRIBUTE_NAME);
+ if (mapGeneratorName == null) {
+ return MapRenderers.GL_RENDERER;
+ }
+
+ return MapRenderers.valueOf(mapGeneratorName);
}
/**
+ * @param mapView
+ * ...
* @param mapGeneratorInternal
* the internal MapGenerator implementation.
* @return a new MapGenerator instance.
*/
- public static IMapGenerator createMapGenerator(MapGeneratorInternal mapGeneratorInternal) {
+ public static IMapRenderer createMapRenderer(MapView mapView,
+ MapRenderers mapGeneratorInternal) {
switch (mapGeneratorInternal) {
case SW_RENDERER:
- return new org.mapsforge.android.swrenderer.DatabaseRenderer();
+ return new org.mapsforge.android.swrenderer.MapRenderer(mapView);
case GL_RENDERER:
- return new org.mapsforge.android.glrenderer.DatabaseRenderer();
+ return new org.mapsforge.android.glrenderer.MapRenderer(mapView);
}
throw new IllegalArgumentException("unknown enum value: " + mapGeneratorInternal);
}
- private MapGeneratorFactory() {
+ private MapRendererFactory() {
throw new IllegalStateException();
}
}
diff --git a/src/org/mapsforge/android/mapgenerator/MapGeneratorInternal.java b/src/org/mapsforge/android/mapgenerator/MapRenderers.java
similarity index 96%
rename from src/org/mapsforge/android/mapgenerator/MapGeneratorInternal.java
rename to src/org/mapsforge/android/mapgenerator/MapRenderers.java
index cab28c0e..fcf36dc2 100644
--- a/src/org/mapsforge/android/mapgenerator/MapGeneratorInternal.java
+++ b/src/org/mapsforge/android/mapgenerator/MapRenderers.java
@@ -17,7 +17,7 @@ package org.mapsforge.android.mapgenerator;
/**
* Enumeration of all internal MapGenerator implementations.
*/
-public enum MapGeneratorInternal {
+public enum MapRenderers {
/**
* texture renderer.
*/
diff --git a/src/org/mapsforge/android/mapgenerator/MapWorker.java b/src/org/mapsforge/android/mapgenerator/MapWorker.java
index 1e9cdb77..dcf1409b 100644
--- a/src/org/mapsforge/android/mapgenerator/MapWorker.java
+++ b/src/org/mapsforge/android/mapgenerator/MapWorker.java
@@ -14,7 +14,7 @@
*/
package org.mapsforge.android.mapgenerator;
-import org.mapsforge.android.MapRenderer;
+import org.mapsforge.android.IMapRenderer;
import org.mapsforge.android.MapView;
import org.mapsforge.android.utils.PausableThread;
@@ -23,35 +23,33 @@ import org.mapsforge.android.utils.PausableThread;
* thread.
*/
public class MapWorker extends PausableThread {
- private static final String THREAD_NAME = "MapWorker";
-
+ private final String THREAD_NAME;
private final JobQueue mJobQueue;
- private IMapGenerator mMapGenerator;
- private MapRenderer mMapRenderer;
+ private final IMapGenerator mMapGenerator;
+ private final IMapRenderer mMapRenderer;
/**
+ * @param id
+ * thread id
* @param mapView
* the MapView for which this MapWorker generates map tiles.
+ * @param mapGenerator
+ * ...
+ * @param mapRenderer
+ * ...
*/
- public MapWorker(MapView mapView) {
+ public MapWorker(int id, MapView mapView, IMapGenerator mapGenerator,
+ IMapRenderer mapRenderer) {
super();
mJobQueue = mapView.getJobQueue();
- }
-
- /**
- * @param mapGenerator
- * the MapGenerator which this MapWorker should use.
- */
- public void setMapGenerator(IMapGenerator mapGenerator) {
mMapGenerator = mapGenerator;
+ mMapRenderer = mapRenderer;
+
+ THREAD_NAME = "MapWorker" + id;
}
- /**
- * @param mapRenderer
- * the MapRenderer
- */
- public void setMapRenderer(MapRenderer mapRenderer) {
- mMapRenderer = mapRenderer;
+ public IMapGenerator getMapGenerator() {
+ return mMapGenerator;
}
@Override
@@ -65,6 +63,7 @@ public class MapWorker extends PausableThread {
if (mMapGenerator == null || mapGeneratorJob == null)
return;
+ // Log.d(THREAD_NAME, "processing: " + mapGeneratorJob.tile);
boolean success = mMapGenerator.executeJob(mapGeneratorJob);
@@ -80,7 +79,8 @@ public class MapWorker extends PausableThread {
@Override
protected int getThreadPriority() {
- return (Thread.NORM_PRIORITY + Thread.MIN_PRIORITY) / 2;
+ // return (Thread.NORM_PRIORITY + Thread.MIN_PRIORITY) / 2;
+ return Thread.MIN_PRIORITY;
}
@Override
diff --git a/src/org/mapsforge/android/mapgenerator/JobTheme.java b/src/org/mapsforge/android/mapgenerator/Theme.java
similarity index 96%
rename from src/org/mapsforge/android/mapgenerator/JobTheme.java
rename to src/org/mapsforge/android/mapgenerator/Theme.java
index b1913c54..41eb4816 100644
--- a/src/org/mapsforge/android/mapgenerator/JobTheme.java
+++ b/src/org/mapsforge/android/mapgenerator/Theme.java
@@ -21,7 +21,7 @@ import java.io.Serializable;
/**
* A JobTheme defines the render theme which is used for a {@link MapGeneratorJob}.
*/
-public interface JobTheme extends Serializable {
+public interface Theme extends Serializable {
/**
* @return an InputStream to read the render theme data from.
* @throws FileNotFoundException
diff --git a/src/org/mapsforge/android/rendertheme/ExternalRenderTheme.java b/src/org/mapsforge/android/rendertheme/ExternalRenderTheme.java
index 0b2aab15..6fee1a04 100644
--- a/src/org/mapsforge/android/rendertheme/ExternalRenderTheme.java
+++ b/src/org/mapsforge/android/rendertheme/ExternalRenderTheme.java
@@ -21,12 +21,12 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
-import org.mapsforge.android.mapgenerator.JobTheme;
+import org.mapsforge.android.mapgenerator.Theme;
/**
* An ExternalRenderTheme allows for customizing the rendering style of the map via an XML file.
*/
-public class ExternalRenderTheme implements JobTheme {
+public class ExternalRenderTheme implements Theme {
private static final long serialVersionUID = 1L;
private final long mFileModificationDate;
diff --git a/src/org/mapsforge/android/rendertheme/InternalRenderTheme.java b/src/org/mapsforge/android/rendertheme/InternalRenderTheme.java
index 23b523d5..af245c0f 100644
--- a/src/org/mapsforge/android/rendertheme/InternalRenderTheme.java
+++ b/src/org/mapsforge/android/rendertheme/InternalRenderTheme.java
@@ -16,12 +16,12 @@ package org.mapsforge.android.rendertheme;
import java.io.InputStream;
-import org.mapsforge.android.mapgenerator.JobTheme;
+import org.mapsforge.android.mapgenerator.Theme;
/**
* Enumeration of all internal rendering themes.
*/
-public enum InternalRenderTheme implements JobTheme {
+public enum InternalRenderTheme implements Theme {
/**
* A rendering theme similar to the OpenStreetMap Osmarender style.
*
@@ -37,6 +37,9 @@ public enum InternalRenderTheme implements JobTheme {
@Override
public InputStream getRenderThemeAsStream() {
- return Thread.currentThread().getClass().getResourceAsStream(mPath);
+ // getResourceAsStream(mPath);
+ return InternalRenderTheme.class.getResourceAsStream(mPath);
+ // return Thread.currentThread().getClass().getResourceAsStream(mPath);
+
}
}
diff --git a/src/org/mapsforge/android/rendertheme/RenderTheme.java b/src/org/mapsforge/android/rendertheme/RenderTheme.java
index c8d9b7fe..74b7b39d 100644
--- a/src/org/mapsforge/android/rendertheme/RenderTheme.java
+++ b/src/org/mapsforge/android/rendertheme/RenderTheme.java
@@ -87,10 +87,6 @@ public class RenderTheme {
private final LRUCache mMatchingCacheWay;
private final LRUCache mMatchingCacheArea;
- // private List mMatchingListWay;
- // private List mMatchingListArea;
- // private List mMatchingListNode;
-
RenderTheme(int mapBackground, float baseStrokeWidth, float baseTextSize) {
mMapBackground = mapBackground;
mBaseStrokeWidth = baseStrokeWidth;
@@ -198,7 +194,7 @@ public class RenderTheme {
}
}
- private RenderInstruction[] mRenderInstructions = null;
+ // private RenderInstruction[] mRenderInstructions = null;
/**
* Matches a way with the given parameters against this RenderTheme.
@@ -213,23 +209,26 @@ public class RenderTheme {
* way is Closed
* @param changed
* ...
+ * @return currently processed render instructions
*/
- public void matchWay(IRenderCallback renderCallback, Tag[] tags, byte zoomLevel,
+ public synchronized RenderInstruction[] matchWay(IRenderCallback renderCallback,
+ Tag[] tags,
+ byte zoomLevel,
boolean closed, boolean changed) {
RenderInstruction[] renderInstructions = null;
LRUCache matchingCache;
MatchingCacheKey matchingCacheKey;
- if (!changed) {
- renderInstructions = mRenderInstructions;
-
- if (renderInstructions != null) {
- for (int i = 0, n = renderInstructions.length; i < n; i++)
- renderInstructions[i].renderWay(renderCallback, tags);
- }
- return;
- }
+ // if (!changed) {
+ // renderInstructions = mRenderInstructions;
+ //
+ // if (renderInstructions != null) {
+ // for (int i = 0, n = renderInstructions.length; i < n; i++)
+ // renderInstructions[i].renderWay(renderCallback, tags);
+ // }
+ // return;
+ // }
if (closed) {
matchingCache = mMatchingCacheArea;
@@ -267,90 +266,8 @@ public class RenderTheme {
matchingCache.put(matchingCacheKey, renderInstructions);
}
- mRenderInstructions = renderInstructions;
-
- // if (matchingList != null) {
- // for (int i = 0, n = matchingList.size(); i < n; ++i) {
- // matchingList.get(i).renderWay(renderCallback, tags);
- // }
- // }
- // return renderInstructions;
-
- // if (closed) {
- // mMatchingListArea = matchingList;
- // } else {
- // mMatchingListWay = matchingList;
- // }
-
- // if (mCompareKey.set(tags, zoomLevel, closed)) {
- // // Log.d("mapsforge", "SAME AS BAFORE!!!" + tags);
- // for (int i = 0, n = mInstructionList.length; i < n; ++i) {
- // mInstructionList[i].renderWay(renderCallback, tags);
- // }
- // return;
- // }
- //
- // SparseArray matchingList = mMatchingCache.get(mCompareKey);
- //
- // if (matchingList != null) {
- // mInstructionList = matchingList.get(zoomLevel);
- // if (mInstructionList != null) {
- // // cache hit
- // // Log.d("mapsforge", "CCACHE HIT !!!" + tags);
- // for (int i = 0, n = mInstructionList.length; i < n; ++i) {
- // mInstructionList[i].renderWay(renderCallback, tags);
- // }
- //
- // return;
- // }
- // }
- // // Log.d("mapsforge", "CACHE MISS !!!" + tags);
- // // cache miss
- // ArrayList instructionList = new ArrayList();
- //
- // for (int i = 0, n = mRulesList.size(); i < n; ++i) {
- // mRulesList.get(i).matchWay(renderCallback, mCompareKey.getTags(), zoomLevel, closed, instructionList);
- // }
- //
- // boolean found = false;
- // int size = instructionList.size();
- //
- // if (matchingList == null) {
- // matchingList = new SparseArray(25);
- // MatchingCacheKey matchingCacheKey = new MatchingCacheKey(mCompareKey);
- // mMatchingCache.put(matchingCacheKey, matchingList);
- // } else {
- // // check if another zoomLevel uses the same instructionList
- // for (int i = 0, n = matchingList.size(); i < n; i++) {
- // int key = matchingList.keyAt(i);
- //
- // RenderInstruction[] list2 = matchingList.get(key);
- // if (list2.length != size)
- // continue;
- //
- // int j = 0;
- // while (j < size && (list2[j] == instructionList.get(j)))
- // j++;
- //
- // if (j == size) {
- // instructionList.clear();
- // mInstructionList = list2;
- // found = true;
- // break;
- // }
- // }
- // }
- //
- // if (!found) {
- // mInstructionList = new RenderInstruction[size];
- // for (int i = 0; i < size; i++)
- // mInstructionList[i] = instructionList.get(i);
- // }
- //
- // for (int i = 0, n = mInstructionList.length; i < n; ++i)
- // mInstructionList[i].renderWay(renderCallback, tags);
- //
- // matchingList.put(zoomLevel, mInstructionList);
+ // mRenderInstructions = renderInstructions;
+ return renderInstructions;
}
void addRule(Rule rule) {
diff --git a/src/org/mapsforge/android/rendertheme/osmarender/osmarender.xml b/src/org/mapsforge/android/rendertheme/osmarender/osmarender.xml
index 0b0a5f4f..12c70405 100644
--- a/src/org/mapsforge/android/rendertheme/osmarender/osmarender.xml
+++ b/src/org/mapsforge/android/rendertheme/osmarender/osmarender.xml
@@ -1,700 +1,700 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://mapsforge.org/renderTheme ../renderTheme.xsd"
+ version="1" map-background="#f0f0f0">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/org/mapsforge/android/swrenderer/DatabaseRenderer.java b/src/org/mapsforge/android/swrenderer/MapGenerator.java
similarity index 81%
rename from src/org/mapsforge/android/swrenderer/DatabaseRenderer.java
rename to src/org/mapsforge/android/swrenderer/MapGenerator.java
index bcf5bb46..8c7f2568 100644
--- a/src/org/mapsforge/android/swrenderer/DatabaseRenderer.java
+++ b/src/org/mapsforge/android/swrenderer/MapGenerator.java
@@ -14,77 +14,39 @@
*/
package org.mapsforge.android.swrenderer;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.mapsforge.android.MapView;
import org.mapsforge.android.mapgenerator.IMapGenerator;
-import org.mapsforge.android.mapgenerator.JobTheme;
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
+import org.mapsforge.android.mapgenerator.Theme;
import org.mapsforge.android.rendertheme.IRenderCallback;
import org.mapsforge.android.rendertheme.RenderTheme;
-import org.mapsforge.android.rendertheme.RenderThemeHandler;
import org.mapsforge.android.rendertheme.renderinstruction.Area;
import org.mapsforge.android.rendertheme.renderinstruction.Line;
-import org.mapsforge.core.GeoPoint;
import org.mapsforge.core.Tag;
import org.mapsforge.core.Tile;
import org.mapsforge.database.IMapDatabase;
import org.mapsforge.database.IMapDatabaseCallback;
-import org.mapsforge.database.MapFileInfo;
import org.mapsforge.database.mapfile.MapDatabase;
-import org.xml.sax.SAXException;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.FloatMath;
-import android.util.Log;
/**
* A DatabaseRenderer renders map tiles by reading from a {@link MapDatabase}.
*/
-public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
+public class MapGenerator implements IMapGenerator, IRenderCallback,
IMapDatabaseCallback {
- private static String TAG = DatabaseRenderer.class.getName();
- private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 12);
+ // private static String TAG = MapGenerator.class.getName();
private static final byte LAYERS = 11;
private static final Paint PAINT_WATER_TILE_HIGHTLIGHT = new Paint(
Paint.ANTI_ALIAS_FLAG);
private static final double STROKE_INCREASE = 1.5;
private static final byte STROKE_MIN_ZOOM_LEVEL = 12;
- private static final byte ZOOM_MAX = 22;
-
- // private static MapRenderer mMapRenderer;
-
- private static RenderTheme getRenderTheme(JobTheme jobTheme) {
- InputStream inputStream = null;
- try {
- inputStream = jobTheme.getRenderThemeAsStream();
- return RenderThemeHandler.getRenderTheme(inputStream);
- } catch (ParserConfigurationException e) {
- Log.e(TAG, e.getMessage());
- } catch (SAXException e) {
- Log.e(TAG, e.getMessage());
- } catch (IOException e) {
- Log.e(TAG, e.getMessage());
- } finally {
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (IOException e) {
- Log.e(TAG, e.getMessage());
- }
- }
- return null;
- }
-
private static byte getValidLayer(byte layer) {
if (layer < 0) {
return 0;
@@ -103,7 +65,7 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
private List mNodes;
private float mPoiX;
private float mPoiY;
- private JobTheme mPreviousJobTheme;
+ private Theme mPreviousJobTheme;
private float mPreviousTextScale;
private byte mPreviousZoomLevel;
private static RenderTheme renderTheme;
@@ -138,7 +100,7 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
/**
* Constructs a new DatabaseRenderer.
*/
- public DatabaseRenderer() {
+ public MapGenerator() {
mCanvasRasterer = new CanvasRasterer();
mLabelPlacement = new LabelPlacement();
@@ -161,8 +123,8 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
@Override
public void cleanup() {
mTileBitmap.recycle();
- if (DatabaseRenderer.renderTheme != null) {
- DatabaseRenderer.renderTheme.destroy();
+ if (MapGenerator.renderTheme != null) {
+ MapGenerator.renderTheme.destroy();
}
}
@@ -189,30 +151,30 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
// mTileHeight = mLat1 - mLat2;
mScale = mapGeneratorJob.getScale();
- JobTheme jobTheme = mapGeneratorJob.jobParameters.jobTheme;
- if (!jobTheme.equals(mPreviousJobTheme)) {
- if (DatabaseRenderer.renderTheme == null)
- DatabaseRenderer.renderTheme = getRenderTheme(jobTheme);
- if (DatabaseRenderer.renderTheme == null) {
- mPreviousJobTheme = null;
- return false;
- }
- createWayLists();
- mPreviousJobTheme = jobTheme;
- mPreviousZoomLevel = Byte.MIN_VALUE;
- }
-
- byte zoomLevel = mCurrentTile.zoomLevel;
- if (zoomLevel != mPreviousZoomLevel) {
- setScaleStrokeWidth(zoomLevel);
- mPreviousZoomLevel = zoomLevel;
- }
-
- float textScale = mapGeneratorJob.jobParameters.textScale;
- if (textScale != mPreviousTextScale) {
- DatabaseRenderer.renderTheme.scaleTextSize(textScale);
- mPreviousTextScale = textScale;
- }
+ // Theme theme = mapGeneratorJob.jobParameters.theme;
+ // if (!theme.equals(mPreviousJobTheme)) {
+ // // if (MapGenerator.renderTheme == null)
+ // // MapGenerator.renderTheme = getRenderTheme(theme);
+ // // if (MapGenerator.renderTheme == null) {
+ // // mPreviousJobTheme = null;
+ // // return false;
+ // // }
+ // createWayLists();
+ // mPreviousJobTheme = theme;
+ // mPreviousZoomLevel = Byte.MIN_VALUE;
+ // }
+ //
+ // byte zoomLevel = mCurrentTile.zoomLevel;
+ // if (zoomLevel != mPreviousZoomLevel) {
+ // setScaleStrokeWidth(zoomLevel);
+ // mPreviousZoomLevel = zoomLevel;
+ // }
+ //
+ // float textScale = mapGeneratorJob.jobParameters.textScale;
+ // if (textScale != mPreviousTextScale) {
+ // MapGenerator.renderTheme.scaleTextSize(textScale);
+ // mPreviousTextScale = textScale;
+ // }
if (mMapDatabase != null) {
mMapDatabase.executeQuery(mCurrentTile, this);
@@ -230,7 +192,7 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
// FIXME mCoords = mMapDatabase.getCoordinates();
mCanvasRasterer.setCanvasBitmap(mTileBitmap, mScale);
- mCanvasRasterer.fill(DatabaseRenderer.renderTheme.getMapBackground());
+ mCanvasRasterer.fill(MapGenerator.renderTheme.getMapBackground());
mCanvasRasterer.drawWays(mCoords, mWays);
mCanvasRasterer.drawSymbols(mWaySymbols);
mCanvasRasterer.drawSymbols(mPointSymbols);
@@ -255,37 +217,6 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
return true;
}
- @Override
- public GeoPoint getStartPoint() {
- if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
- MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
- if (mapFileInfo.startPosition != null) {
- return mapFileInfo.startPosition;
- } else if (mapFileInfo.mapCenter != null) {
- return mapFileInfo.mapCenter;
- }
- }
-
- return null;
- }
-
- @Override
- public Byte getStartZoomLevel() {
- if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
- MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
- if (mapFileInfo.startZoomLevel != null) {
- return mapFileInfo.startZoomLevel;
- }
- }
-
- return DEFAULT_START_ZOOM_LEVEL;
- }
-
- @Override
- public byte getZoomLevelMax() {
- return ZOOM_MAX;
- }
-
@Override
public void renderAreaCaption(String textKey, float verticalOffset, Paint paint,
Paint stroke) {
@@ -314,7 +245,7 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
mDrawingLayer = mWays[getValidLayer(layer)];
mPoiX = scaleLongitude(longitude);
mPoiY = scaleLatitude(latitude);
- DatabaseRenderer.renderTheme.matchNode(this, tags, mCurrentTile.zoomLevel);
+ MapGenerator.renderTheme.matchNode(this, tags, mCurrentTile.zoomLevel);
}
@Override
@@ -539,7 +470,7 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
}
private void createWayLists() {
- int levels = DatabaseRenderer.renderTheme.getLevels();
+ int levels = MapGenerator.renderTheme.getLevels();
for (byte i = LAYERS - 1; i >= 0; --i) {
mWays[i] = new LayerContainer(levels);
}
@@ -581,12 +512,18 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
*/
private static void setScaleStrokeWidth(byte zoomLevel) {
int zoomLevelDiff = Math.max(zoomLevel - STROKE_MIN_ZOOM_LEVEL, 0);
- DatabaseRenderer.renderTheme.scaleStrokeWidth((float) Math.pow(STROKE_INCREASE,
+ MapGenerator.renderTheme.scaleStrokeWidth((float) Math.pow(STROKE_INCREASE,
zoomLevelDiff));
}
@Override
- public MapRenderer getMapRenderer(MapView mapView) {
- return new MapRenderer(mapView);
+ public IMapDatabase getMapDatabase() {
+ return mMapDatabase;
+ }
+
+ @Override
+ public void setRenderTheme(RenderTheme theme) {
+ // TODO Auto-generated method stub
+
}
}
diff --git a/src/org/mapsforge/android/swrenderer/MapRenderer.java b/src/org/mapsforge/android/swrenderer/MapRenderer.java
index 92b84d8d..0a9e4890 100644
--- a/src/org/mapsforge/android/swrenderer/MapRenderer.java
+++ b/src/org/mapsforge/android/swrenderer/MapRenderer.java
@@ -28,10 +28,9 @@ import javax.microedition.khronos.opengles.GL10;
import org.mapsforge.android.DebugSettings;
import org.mapsforge.android.MapView;
-import org.mapsforge.android.mapgenerator.JobParameters;
import org.mapsforge.android.mapgenerator.IMapGenerator;
+import org.mapsforge.android.mapgenerator.JobParameters;
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
-import org.mapsforge.android.mapgenerator.MapWorker;
import org.mapsforge.android.mapgenerator.TileCacheKey;
import org.mapsforge.android.mapgenerator.TileDistanceSort;
import org.mapsforge.android.utils.GlUtils;
@@ -46,7 +45,7 @@ import android.opengl.Matrix;
/**
*
*/
-public class MapRenderer implements org.mapsforge.android.MapRenderer {
+public class MapRenderer implements org.mapsforge.android.IMapRenderer {
// private static String TAG = "MapRenderer";
private static final int FLOAT_SIZE_BYTES = 4;
@@ -72,7 +71,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
private ArrayList mJobList;
ArrayList mTextures;
- MapWorker mMapWorker;
MapView mMapView;
GLMapTile[] currentTiles;
@@ -97,7 +95,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
*/
public MapRenderer(MapView mapView) {
mMapView = mapView;
- mMapWorker = mapView.getMapWorker();
mDebugSettings = mapView.getDebugSettings();
mMapScale = 1;
@@ -133,7 +130,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
if (diff != 0)
{
float z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
- t.distance = (long) (Math.abs((t.tileX) * z - x) + Math.abs((t.tileY) * z - y));
+ t.distance = (long) (Math.abs((t.tileX) * z - x) + Math.abs((t.tileY) * z
+ - y));
t.distance *= 2 * diff * diff;
} else {
t.distance = (Math.abs(t.tileX - x) + Math.abs(t.tileY - y));
@@ -160,7 +158,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
if (t.hasTexture()) {
synchronized (mTextures) {
- mTextures.add(new Integer(t.getTexture()));
+ mTextures.add(Integer.valueOf(t.getTexture()));
}
}
}
@@ -184,7 +182,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
mJobList.clear();
- IMapGenerator mapGenerator = mMapView.getMapGenerator();
+ // IMapGenerator mapGenerator = mMapView.getMapGenerator();
+
int tiles = 0;
for (long tileY = tileTop - 1; tileY <= tileBottom + 1; tileY++) {
for (long tileX = tileLeft - 1; tileX <= tileRight + 1; tileX++) {
@@ -216,13 +215,14 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
if (!tile.isDrawn || (tile.getScale() != scale)) {
tile.isLoading = true;
// approximation for TileScheduler
- if (tileY < tileTop || tileY > tileBottom || tileX < tileLeft || tileX > tileRight)
+ if (tileY < tileTop || tileY > tileBottom || tileX < tileLeft
+ || tileX > tileRight)
tile.isVisible = false;
else
tile.isVisible = true;
- MapGeneratorJob job = new MapGeneratorJob(tile, mapGenerator,
- mJobParameter, mDebugSettings);
+ MapGeneratorJob job = new MapGeneratorJob(tile, mJobParameter,
+ mDebugSettings);
job.setScale(scale);
mJobList.add(job);
}
@@ -243,10 +243,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
if (mJobList.size() > 0) {
- mMapView.getJobQueue().setJobs(mJobList);
- synchronized (mMapWorker) {
- mMapWorker.notify();
- }
+ mMapView.addJobs(mJobList);
}
return true;
@@ -262,10 +259,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
mMapPosition = mMapView.getMapPosition().getMapPosition();
- long x = (long) MercatorProjection.longitudeToPixelX(mMapPosition.geoPoint.getLongitude(),
+ long x = (long) MercatorProjection.longitudeToPixelX(
+ mMapPosition.geoPoint.getLongitude(),
mMapPosition.zoomLevel);
long y = (long) MercatorProjection
- .latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), mMapPosition.zoomLevel);
+ .latitudeToPixelY(mMapPosition.geoPoint.getLatitude(),
+ mMapPosition.zoomLevel);
long tileX = MercatorProjection.pixelXToTileX(x, mMapPosition.zoomLevel);
long tileY = MercatorProjection.pixelYToTileY(y, mMapPosition.zoomLevel);
@@ -345,7 +344,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
z = 1.0f / (1 << -diff);
}
drawX = MercatorProjection
- .longitudeToPixelX(mMapPosition.geoPoint.getLongitude(), tile.zoomLevel);
+ .longitudeToPixelX(mMapPosition.geoPoint.getLongitude(),
+ tile.zoomLevel);
drawY = MercatorProjection
.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), tile.zoomLevel);
@@ -377,7 +377,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
Matrix.setIdentityM(mMatrix, 0);
// map tile GL coordinates to screen coordinates
- Matrix.scaleM(mMatrix, 0, 2.0f * (tileSize * z) / mWidth, 2.0f * (tileSize * z) / mHeight, 1);
+ Matrix.scaleM(mMatrix, 0, 2.0f * (tileSize * z) / mWidth, 2.0f * (tileSize * z)
+ / mHeight, 1);
// scale tile
Matrix.scaleM(mMatrix, 0, mapScale / z, mapScale / z, 1);
@@ -396,7 +397,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
@Override
public void onDrawFrame(GL10 glUnused) {
- boolean loadedTexture = false;
+ // boolean loadedTexture = false;
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
GLES20.glClearColor(0.95f, 0.95f, 0.94f, 1.0f);
// GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
@@ -437,14 +438,16 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
if (tile.getTexture() >= 0) {
// reuse tile texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tile.getTexture());
- GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mMapGeneratorJob.getBitmap());
+ GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
+ mMapGeneratorJob.getBitmap());
} else if (mTextures.size() > 0) {
// reuse texture from previous tiles
Integer texture;
texture = mTextures.remove(mTextures.size() - 1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture.intValue());
- GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mMapGeneratorJob.getBitmap());
+ GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
+ mMapGeneratorJob.getBitmap());
tile.setTexture(texture.intValue());
} else {
// create texture
@@ -457,7 +460,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
mMapGeneratorJob = null;
processedTile = true;
- loadedTexture = true;
+ // loadedTexture = true;
}
int tileSize = (int) (Tile.TILE_SIZE * mMapScale);
int hWidth = mWidth >> 1;
@@ -491,11 +494,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
}
}
- if (loadedTexture) {
- synchronized (mMapWorker) {
- mMapWorker.notify();
- }
- }
+ // FIXME
+ // if (loadedTexture) {
+ // synchronized (mMapWorker) {
+ // mMapWorker.notify();
+ // }
+ // }
}
@Override
@@ -579,65 +583,9 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
public boolean processedTile() {
return processedTile;
}
+
+ @Override
+ public IMapGenerator createMapGenerator() {
+ return new MapGenerator();
+ }
}
-
-// private void limitCache(long top, long bottom, long left, long right, byte zoom, int remove) {
-// int cnt = 0;
-// TileCacheKey[] keys = new TileCacheKey[remove];
-//
-// for (Entry e : mTiles.entrySet()) {
-// GLMapTile t = e.getValue();
-// if (t.zoomLevel == zoom && t.tileX >= left && t.tileX <= right &&
-// t.tileY >= top && t.tileY <= bottom)
-// continue;
-//
-// if (t.zoomLevel + 1 == zoom) {
-// boolean found = false;
-// for (int i = 0; i < 4; i++) {
-// GLMapTile c = t.child[i];
-// if (c != null && !c.hasTexture() && c.tileX >= left && c.tileX <= right &&
-// c.tileY >= top && c.tileY <= bottom) {
-// found = true;
-// break;
-// }
-// }
-// if (found)
-// continue;
-// }
-// if (t.zoomLevel - 1 == zoom) {
-// GLMapTile p = t.parent;
-// if (p != null && !p.hasTexture() && p.tileX >= left && p.tileX <= right &&
-// p.tileY >= top && p.tileY <= bottom) {
-// continue;
-// }
-// }
-//
-// keys[cnt++] = e.getKey();
-//
-// if (cnt == remove)
-// break;
-// }
-//
-// for (TileCacheKey key : keys) {
-// GLMapTile t = mTiles.remove(key);
-// if (t == null)
-// continue;
-//
-// for (int i = 0; i < 4; i++) {
-// if (t.child[i] != null)
-// t.child[i].parent = null;
-// }
-// if (t.parent != null) {
-// for (int i = 0; i < 4; i++) {
-// if (t.parent.child[i] == t)
-// t.parent.child[i] = null;
-// }
-// }
-// if (t.hasTexture()) {
-// synchronized (mTextures) {
-// mTextures.add(new Integer(t.getTexture()));
-// }
-// }
-// }
-// }
-
diff --git a/src/org/mapsforge/android/swrenderer/WayDecorator.java b/src/org/mapsforge/android/swrenderer/WayDecorator.java
index 1fe0cb8d..875c195e 100644
--- a/src/org/mapsforge/android/swrenderer/WayDecorator.java
+++ b/src/org/mapsforge/android/swrenderer/WayDecorator.java
@@ -99,7 +99,7 @@ final class WayDecorator {
}
}
- static void renderText(DatabaseRenderer databaseRenderer, Paint paint, Paint outline,
+ static void renderText(MapGenerator mapGenerator, Paint paint, Paint outline,
float[] coordinates, WayDataContainer wayDataContainer,
List wayNames) {
@@ -185,7 +185,7 @@ final class WayDecorator {
if (wayNameWidth < 0) {
if (text == null) {
- text = databaseRenderer.getWayName();
+ text = mapGenerator.getWayName();
if (text == null)
text = "blub";
}
diff --git a/src/org/mapsforge/android/utils/GlUtils.java b/src/org/mapsforge/android/utils/GlUtils.java
index 45e8d50b..4bccfeb0 100644
--- a/src/org/mapsforge/android/utils/GlUtils.java
+++ b/src/org/mapsforge/android/utils/GlUtils.java
@@ -40,13 +40,17 @@ public class GlUtils {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
+ GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
+ GLES20.GL_LINEAR);
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
+ GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
+ GLES20.GL_LINEAR);
- GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
+ GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
+ GLES20.GL_CLAMP_TO_EDGE);
- GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
+ GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
+ GLES20.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
@@ -125,4 +129,16 @@ public class GlUtils {
// throw new RuntimeException(op + ": glError " + error);
}
}
+
+ public static boolean checkGlOutOfMemory(String op) {
+ int error;
+ boolean oom = false;
+ while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+ Log.e(TAG, op + ": glError " + error);
+ // throw new RuntimeException(op + ": glError " + error);
+ if (error == 1285)
+ oom = true;
+ }
+ return oom;
+ }
}
diff --git a/src/org/mapsforge/android/utils/PausableThread.java b/src/org/mapsforge/android/utils/PausableThread.java
index 780bde36..b1d7e0e8 100644
--- a/src/org/mapsforge/android/utils/PausableThread.java
+++ b/src/org/mapsforge/android/utils/PausableThread.java
@@ -37,6 +37,14 @@ public abstract class PausableThread extends Thread {
}
}
+ @Override
+ public void interrupt() {
+ // first acquire the monitor which is used to call wait()
+ synchronized (this) {
+ super.interrupt();
+ }
+ }
+
/**
* @return true if this thread is currently pausing, false otherwise.
*/
diff --git a/src/org/mapsforge/app/TileMap.java b/src/org/mapsforge/app/TileMap.java
index c4cf3853..c4a6e400 100755
--- a/src/org/mapsforge/app/TileMap.java
+++ b/src/org/mapsforge/app/TileMap.java
@@ -9,8 +9,7 @@ import org.mapsforge.android.DebugSettings;
import org.mapsforge.android.MapActivity;
import org.mapsforge.android.MapController;
import org.mapsforge.android.MapView;
-import org.mapsforge.android.mapgenerator.MapDatabaseFactory;
-import org.mapsforge.android.mapgenerator.MapDatabaseInternal;
+import org.mapsforge.android.mapgenerator.MapDatabases;
import org.mapsforge.android.rendertheme.InternalRenderTheme;
import org.mapsforge.android.utils.AndroidUtils;
import org.mapsforge.app.filefilter.FilterByFileExtension;
@@ -20,7 +19,6 @@ import org.mapsforge.app.filepicker.FilePicker;
import org.mapsforge.app.preferences.EditPreferences;
import org.mapsforge.core.BoundingBox;
import org.mapsforge.core.GeoPoint;
-import org.mapsforge.database.IMapDatabase;
import org.mapsforge.database.MapFileInfo;
import android.annotation.TargetApi;
@@ -74,7 +72,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
private static final int SELECT_MAP_FILE = 0;
private static final int SELECT_RENDER_THEME_FILE = 1;
private LocationManager mLocationManager;
- private MapDatabaseInternal mMapDatabaseInternal;
+ private MapDatabases mMapDatabase;
private MyLocationListener mMyLocationListener;
private boolean mShowMyLocation;
private boolean mSnapToLocation;
@@ -88,8 +86,11 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
@Override
public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.options_menu, menu);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+ getMenuInflater().inflate(R.menu.options_menu, menu);
+ else
+ getMenuInflater().inflate(R.menu.options_menu_pre_honeycomb, menu);
mMenu = menu;
return true;
}
@@ -434,7 +435,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
editText.setText(Double.toString(mapCenter.getLongitude()));
SeekBar zoomlevel = (SeekBar) dialog.findViewById(R.id.zoomLevel);
- zoomlevel.setMax(mMapView.getMapGenerator().getZoomLevelMax());
+ zoomlevel.setMax(20); // FIXME mMapView.getMapGenerator().getZoomLevelMax());
zoomlevel.setProgress(mMapView.getMapPosition().getZoomLevel());
final TextView textView = (TextView) dialog.findViewById(R.id.zoomlevelValue);
@@ -532,25 +533,31 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
if (preferences.contains("mapDatabase")) {
String name = preferences.getString("mapDatabase",
- MapDatabaseInternal.POSTGIS_READER.name());
+ MapDatabases.POSTGIS_READER.name());
- MapDatabaseInternal mapDatabaseInternalNew;
+ MapDatabases mapDatabaseNew;
try {
- mapDatabaseInternalNew = MapDatabaseInternal.valueOf(name);
+ mapDatabaseNew = MapDatabases.valueOf(name);
} catch (IllegalArgumentException e) {
- mapDatabaseInternalNew = MapDatabaseInternal.POSTGIS_READER;
+ mapDatabaseNew = MapDatabases.POSTGIS_READER;
}
- // mapDatabaseInternalNew = MapDatabaseInternal.JSON_READER;
- Log.d("VectorTileMap", "set map database " + mapDatabaseInternalNew);
+ // mapDatabaseInternalNew = MapDatabaseInternal.PBMAP_READER;
+ Log.d("VectorTileMap", "set map database " + mapDatabaseNew);
- if (mapDatabaseInternalNew != mMapDatabaseInternal) {
- IMapDatabase mapDatabase = MapDatabaseFactory
- .createMapDatabase(mapDatabaseInternalNew);
- mMapView.setMapDatabase(mapDatabase);
- mMapDatabaseInternal = mapDatabaseInternalNew;
+ if (mapDatabaseNew != mMapDatabase) {
+ mMapView.setMapDatabase(mapDatabaseNew);
+ mMapDatabase = mapDatabaseNew;
}
+
+ // if (mapDatabaseNew != mMapDatabase) {
+ // IMapDatabase mapDatabase = MapDatabaseFactory
+ // .createMapDatabase(mapDatabaseNew);
+ //
+ // mMapView.setMapDatabase(mapDatabase);
+ // mMapDatabase = mapDatabaseNew;
+ // }
}
try {
@@ -586,7 +593,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
mMapView.setDebugSettings(debugSettings);
- if (mMapDatabaseInternal == MapDatabaseInternal.MAP_READER) {
+ if (mMapDatabase == MapDatabases.MAP_READER) {
if (mMapView.getMapFile() == null)
startMapFilePicker();
} else {
diff --git a/src/org/mapsforge/app/filepicker/FilePicker.java b/src/org/mapsforge/app/filepicker/FilePicker.java
index bb556fd0..7c997da5 100755
--- a/src/org/mapsforge/app/filepicker/FilePicker.java
+++ b/src/org/mapsforge/app/filepicker/FilePicker.java
@@ -226,7 +226,8 @@ public class FilePicker extends Activity implements AdapterView.OnItemClickListe
@Override
protected void onResume() {
super.onResume();
- getActionBar().hide();
+ // getActionBar().hide();
+
// check if the full screen mode should be activated
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen", false)) {
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
diff --git a/src/org/mapsforge/app/preferences/EditPreferences.java b/src/org/mapsforge/app/preferences/EditPreferences.java
index a1dbdabc..4b919aa8 100644
--- a/src/org/mapsforge/app/preferences/EditPreferences.java
+++ b/src/org/mapsforge/app/preferences/EditPreferences.java
@@ -18,8 +18,6 @@ import org.mapsforge.app.R;
import android.os.Bundle;
import android.preference.PreferenceActivity;
-import android.preference.PreferenceManager;
-import android.view.WindowManager;
/**
* Activity to edit the application preferences.
@@ -34,16 +32,16 @@ public class EditPreferences extends PreferenceActivity {
@Override
protected void onResume() {
super.onResume();
- getActionBar().hide();
+ // getActionBar().hide();
// check if the full screen mode should be activated
- if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
- false)) {
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
- getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
- } else {
- getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
- }
+ // if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
+ // false)) {
+ // getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ // getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+ // } else {
+ // getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ // getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+ // }
}
}
diff --git a/src/org/mapsforge/database/IMapDatabase.java b/src/org/mapsforge/database/IMapDatabase.java
index 91dd43d9..be92c261 100644
--- a/src/org/mapsforge/database/IMapDatabase.java
+++ b/src/org/mapsforge/database/IMapDatabase.java
@@ -62,6 +62,8 @@ public interface IMapDatabase {
*/
public abstract FileOpenResult openFile(File mapFile);
+ public abstract String getMapProjection();
+
/**
* @param position
* ....
@@ -69,4 +71,4 @@ public interface IMapDatabase {
*/
public abstract String readString(int position);
-}
\ No newline at end of file
+}
diff --git a/src/org/mapsforge/database/json/MapDatabase.java b/src/org/mapsforge/database/json/MapDatabase.java
index ec93b2e9..054ea32c 100644
--- a/src/org/mapsforge/database/json/MapDatabase.java
+++ b/src/org/mapsforge/database/json/MapDatabase.java
@@ -31,13 +31,14 @@ import org.mapsforge.database.MapFileInfo;
*/
public class MapDatabase implements IMapDatabase {
+ private final static String PROJECTION = "Mercator";
private float[] mCoords = new float[20];
- private int[] mIndex = new int[1];
+ private int[] mIndex = new int[2];
// private Tag[] mTags = { new Tag("boundary", "administrative"), new Tag("admin_level", "2") };
- private Tag[] mTags = { new Tag("building", "yes") };
+ private Tag[] mTags = { new Tag("natural", "water") };
private final MapFileInfo mMapInfo =
new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
- new Byte((byte) 0), null, "Mercator", 0, 0, 0, "de", "yo!", "by me");
+ new Byte((byte) 0), null, PROJECTION, 0, 0, 0, "de", "yo!", "by me");
private boolean mOpenFile = false;
@@ -95,10 +96,10 @@ public class MapDatabase implements IMapDatabase {
//
// mIndex[0] = 10;
- lon1 = (float) MercatorProjection.pixelXToLongitude(cx - 80, tile.zoomLevel) * 1000000;
- lon2 = (float) MercatorProjection.pixelXToLongitude(cx + 80, tile.zoomLevel) * 1000000;
- lat1 = (float) MercatorProjection.pixelYToLatitude(cy - 80, tile.zoomLevel) * 1000000;
- lat2 = (float) MercatorProjection.pixelYToLatitude(cy + 80, tile.zoomLevel) * 1000000;
+ lon1 = (float) MercatorProjection.pixelXToLongitude(cx - 139, tile.zoomLevel) * 1000000;
+ lon2 = (float) MercatorProjection.pixelXToLongitude(cx + 139, tile.zoomLevel) * 1000000;
+ lat1 = (float) MercatorProjection.pixelYToLatitude(cy - 139, tile.zoomLevel) * 1000000;
+ lat2 = (float) MercatorProjection.pixelYToLatitude(cy + 139, tile.zoomLevel) * 1000000;
mCoords[0] = lon1;
mCoords[1] = lat1;
@@ -117,9 +118,35 @@ public class MapDatabase implements IMapDatabase {
mIndex[0] = 10;
+ lon1 = (float) MercatorProjection.pixelXToLongitude(cx - 119, tile.zoomLevel) * 1000000;
+ lon2 = (float) MercatorProjection.pixelXToLongitude(cx + 119, tile.zoomLevel) * 1000000;
+ lat1 = (float) MercatorProjection.pixelYToLatitude(cy - 119, tile.zoomLevel) * 1000000;
+ lat2 = (float) MercatorProjection.pixelYToLatitude(cy + 119, tile.zoomLevel) * 1000000;
+
+ mCoords[10] = lon1;
+ mCoords[11] = lat1;
+
+ mCoords[12] = lon2;
+ mCoords[13] = lat1;
+
+ mCoords[14] = lon2;
+ mCoords[15] = lat2;
+
+ mCoords[16] = lon1;
+ mCoords[17] = lat2;
+
+ mCoords[18] = lon1;
+ mCoords[19] = lat1;
+
+ mIndex[1] = 10;
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, mIndex, true);
}
+ @Override
+ public String getMapProjection() {
+ return PROJECTION;
+ }
+
@Override
public MapFileInfo getMapFileInfo() {
return mMapInfo;
diff --git a/src/org/mapsforge/database/mapfile/MapDatabase.java b/src/org/mapsforge/database/mapfile/MapDatabase.java
index 0c39d473..fd3ca7a7 100644
--- a/src/org/mapsforge/database/mapfile/MapDatabase.java
+++ b/src/org/mapsforge/database/mapfile/MapDatabase.java
@@ -177,11 +177,13 @@ public class MapDatabase implements IMapDatabase {
*/
private static final int WAY_NUMBER_OF_TAGS_BITMASK = 0x0f;
- private IndexCache mDatabaseIndexCache;
+ private static IndexCache sDatabaseIndexCache;
+ private static MapFileHeader sMapFileHeader;
+ private static int instances = 0;
+
private long mFileSize;
private boolean mDebugFile;
private RandomAccessFile mInputFile;
- private MapFileHeader mMapFileHeader;
private ReadBuffer mReadBuffer;
private String mSignatureBlock;
private String mSignaturePoi;
@@ -193,31 +195,6 @@ public class MapDatabase implements IMapDatabase {
private float[] mWayNodes = new float[100000];
private int mWayNodePosition;
- /*
- * (non-Javadoc)
- * @see org.mapsforge.map.reader.IMapDatabase#closeFile()
- */
- @Override
- public void closeFile() {
- try {
- mMapFileHeader = null;
-
- if (mDatabaseIndexCache != null) {
- mDatabaseIndexCache.destroy();
- mDatabaseIndexCache = null;
- }
-
- if (mInputFile != null) {
- mInputFile.close();
- mInputFile = null;
- }
-
- mReadBuffer = null;
- } catch (IOException e) {
- LOG.log(Level.SEVERE, null, e);
- }
- }
-
private int minLat, minLon;
/*
@@ -227,7 +204,7 @@ public class MapDatabase implements IMapDatabase {
*/
@Override
public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
- if (mMapFileHeader == null)
+ if (sMapFileHeader == null)
return;
if (mIntBuffer == null)
@@ -235,29 +212,13 @@ public class MapDatabase implements IMapDatabase {
mWayNodePosition = 0;
- // if (tile.zoomLevel < 10) {
- // // reduce small nodes with distance smaller min pixel
- // int min = 1;
- // long cx = tile.getPixelX() + (Tile.TILE_SIZE >> 1);
- // long cy = tile.getPixelY() + (Tile.TILE_SIZE >> 1);
- // double l1 = MercatorProjection.pixelXToLongitude(cx, tile.zoomLevel);
- // double l2 = MercatorProjection.pixelXToLongitude(cx + min, tile.zoomLevel);
- // minLon = (int) Math.abs((l1 * 1000000.0) - (l2 * 1000000.0));
- // l1 = MercatorProjection.pixelYToLatitude(cy, tile.zoomLevel);
- // l2 = MercatorProjection.pixelYToLatitude(cy + min, tile.zoomLevel);
- // minLat = (int) Math.abs((l1 * 1000000.0) - (l2 * 1000000.0));
- // } else {
- minLat = 0;
- minLon = 0;
- // }
-
try {
- prepareExecution();
+ // prepareExecution();
QueryParameters queryParameters = new QueryParameters();
- queryParameters.queryZoomLevel = mMapFileHeader
+ queryParameters.queryZoomLevel = sMapFileHeader
.getQueryZoomLevel(tile.zoomLevel);
// get and check the sub-file for the query zoom level
- SubFileParameter subFileParameter = mMapFileHeader
+ SubFileParameter subFileParameter = sMapFileHeader
.getSubFileParameter(queryParameters.queryZoomLevel);
if (subFileParameter == null) {
LOG.warning("no sub-file for zoom level: "
@@ -279,10 +240,15 @@ public class MapDatabase implements IMapDatabase {
*/
@Override
public MapFileInfo getMapFileInfo() {
- if (mMapFileHeader == null) {
+ if (sMapFileHeader == null) {
throw new IllegalStateException("no map file is currently opened");
}
- return mMapFileHeader.getMapFileInfo();
+ return sMapFileHeader.getMapFileInfo();
+ }
+
+ @Override
+ public String getMapProjection() {
+ return getMapFileInfo().projectionName;
}
/*
@@ -300,6 +266,7 @@ public class MapDatabase implements IMapDatabase {
*/
@Override
public FileOpenResult openFile(File mapFile) {
+
try {
if (mapFile == null) {
// throw new IllegalArgumentException("mapFile must not be null");
@@ -323,14 +290,23 @@ public class MapDatabase implements IMapDatabase {
mFileSize = mInputFile.length();
mReadBuffer = new ReadBuffer(mInputFile);
- mMapFileHeader = new MapFileHeader();
- FileOpenResult fileOpenResult = mMapFileHeader.readHeader(mReadBuffer,
+ if (instances > 0) {
+ instances++;
+ return FileOpenResult.SUCCESS;
+ }
+
+ sMapFileHeader = new MapFileHeader();
+ FileOpenResult fileOpenResult = sMapFileHeader.readHeader(mReadBuffer,
mFileSize);
if (!fileOpenResult.isSuccess()) {
closeFile();
return fileOpenResult;
}
+ prepareExecution();
+
+ instances++;
+
return FileOpenResult.SUCCESS;
} catch (IOException e) {
LOG.log(Level.SEVERE, null, e);
@@ -340,6 +316,37 @@ public class MapDatabase implements IMapDatabase {
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.mapsforge.map.reader.IMapDatabase#closeFile()
+ */
+ @Override
+ public void closeFile() {
+ instances--;
+ if (instances > 0) {
+ mReadBuffer = null;
+ return;
+ }
+
+ try {
+ sMapFileHeader = null;
+
+ if (sDatabaseIndexCache != null) {
+ sDatabaseIndexCache.destroy();
+ sDatabaseIndexCache = null;
+ }
+
+ if (mInputFile != null) {
+ mInputFile.close();
+ mInputFile = null;
+ }
+
+ mReadBuffer = null;
+ } catch (IOException e) {
+ LOG.log(Level.SEVERE, null, e);
+ }
+ }
+
/**
* Logs the debug signatures of the current way and block.
*/
@@ -351,8 +358,8 @@ public class MapDatabase implements IMapDatabase {
}
private void prepareExecution() {
- if (mDatabaseIndexCache == null) {
- mDatabaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
+ if (sDatabaseIndexCache == null) {
+ sDatabaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
}
}
@@ -436,7 +443,7 @@ public class MapDatabase implements IMapDatabase {
long blockNumber = row * subFileParameter.blocksWidth + column;
// get the current index entry
- long currentBlockIndexEntry = mDatabaseIndexCache.getIndexEntry(
+ long currentBlockIndexEntry = sDatabaseIndexCache.getIndexEntry(
subFileParameter, blockNumber);
// check if the current query would still return a water tile
@@ -462,7 +469,7 @@ public class MapDatabase implements IMapDatabase {
nextBlockPointer = subFileParameter.subFileSize;
} else {
// get and check the next block pointer
- nextBlockPointer = mDatabaseIndexCache.getIndexEntry(
+ nextBlockPointer = sDatabaseIndexCache.getIndexEntry(
subFileParameter, blockNumber + 1)
& BITMASK_INDEX_OFFSET;
if (nextBlockPointer < 1
@@ -559,7 +566,7 @@ public class MapDatabase implements IMapDatabase {
* @return true if the POIs could be processed successfully, false otherwise.
*/
private boolean processPOIs(IMapDatabaseCallback mapDatabaseCallback, int numberOfPois) {
- Tag[] poiTags = mMapFileHeader.getMapFileInfo().poiTags;
+ Tag[] poiTags = sMapFileHeader.getMapFileInfo().poiTags;
Tag[] tags = null;
for (int elementCounter = numberOfPois; elementCounter != 0; --elementCounter) {
@@ -778,7 +785,7 @@ public class MapDatabase implements IMapDatabase {
int numberOfWays) {
Tag[] tags = null;
- Tag[] wayTags = mMapFileHeader.getMapFileInfo().wayTags;
+ Tag[] wayTags = sMapFileHeader.getMapFileInfo().wayTags;
int[] textPos = new int[3];
// float[] labelPosition;
boolean skippedWays = false;
@@ -957,7 +964,7 @@ public class MapDatabase implements IMapDatabase {
|| cumulatedNumberOfWays > MAXIMUM_ZOOM_TABLE_OBJECTS) {
LOG.warning("invalid cumulated number of ways in row " + row + ' '
+ cumulatedNumberOfWays);
- if (mMapFileHeader.getMapFileInfo().debugFile) {
+ if (sMapFileHeader.getMapFileInfo().debugFile) {
LOG.warning(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
}
return null;
diff --git a/src/org/mapsforge/database/pbmap/MapDatabase.java b/src/org/mapsforge/database/pbmap/MapDatabase.java
new file mode 100644
index 00000000..4f594b26
--- /dev/null
+++ b/src/org/mapsforge/database/pbmap/MapDatabase.java
@@ -0,0 +1,513 @@
+/*
+ * 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 .
+ */
+package org.mapsforge.database.pbmap;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.zip.GZIPInputStream;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.message.BasicHeader;
+import org.mapsforge.core.BoundingBox;
+import org.mapsforge.core.GeoPoint;
+import org.mapsforge.core.Tag;
+import org.mapsforge.core.Tile;
+import org.mapsforge.core.WebMercator;
+import org.mapsforge.database.FileOpenResult;
+import org.mapsforge.database.IMapDatabase;
+import org.mapsforge.database.IMapDatabaseCallback;
+import org.mapsforge.database.MapFileInfo;
+
+import android.net.http.AndroidHttpClient;
+import android.util.Log;
+
+/**
+ *
+ *
+ */
+public class MapDatabase implements IMapDatabase {
+ private static final String TAG = "MapDatabase";
+
+ private static final MapFileInfo mMapInfo =
+ new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
+ new Byte((byte) 14), new GeoPoint(53.11, 8.85),
+ WebMercator.NAME, 0, 0, 0, "de", "comment", "author");
+
+ private boolean mOpenFile = false;
+
+ // private static final String URL = "http://city.informatik.uni-bremen.de:8020/test/%d/%d/%d.osmtile";
+ private static final String URL = "http://city.informatik.uni-bremen.de/osmstache/test/%d/%d/%d.osmtile";
+ private static final Header encodingHeader =
+ new BasicHeader("Accept-Encoding", "gzip");
+
+ private static volatile HashMap tagHash = new HashMap(100);
+
+ private Tag[] curTags = new Tag[1000];
+ private int mCurTagCnt;
+
+ private AndroidHttpClient mClient;
+ private IMapDatabaseCallback mMapGenerator;
+ private float mScaleFactor;
+
+ @Override
+ public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
+
+ String url = String.format(URL, Integer.valueOf(tile.zoomLevel),
+ Long.valueOf(tile.tileX), Long.valueOf(tile.tileY));
+
+ HttpGet getRequest = new HttpGet(url);
+ getRequest.addHeader(encodingHeader);
+ mMapGenerator = mapDatabaseCallback;
+ mCurTagCnt = 0;
+ // using variable coordinate scalefactor to take advantage of
+ // variable byte encoded integers
+ mScaleFactor = 1 / 100f;
+ if (tile.zoomLevel < 12)
+ mScaleFactor = (float) Math.pow(2, (12 - tile.zoomLevel)) / 100f;
+
+ try {
+ HttpResponse response = mClient.execute(getRequest);
+ final int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != HttpStatus.SC_OK) {
+ Log.d(TAG, "Http response " + statusCode);
+ return;
+ }
+
+ final HttpEntity entity = response.getEntity();
+ if (entity == null) {
+ Log.d(TAG, "Somethings wrong? - no entity " + statusCode);
+ return;
+ }
+
+ InputStream is = null;
+ GZIPInputStream zis = null;
+ try {
+
+ is = entity.getContent();
+ zis = new GZIPInputStream(is);
+
+ decode(zis);
+
+ } finally {
+ if (zis != null)
+ zis.close();
+ if (is != null)
+ is.close();
+ entity.consumeContent();
+ }
+ } catch (Exception ex) {
+ getRequest.abort();
+ ex.printStackTrace();
+ }
+ }
+
+ @Override
+ public String getMapProjection() {
+ return WebMercator.NAME;
+ }
+
+ @Override
+ public MapFileInfo getMapFileInfo() {
+ return mMapInfo;
+ }
+
+ @Override
+ public boolean hasOpenFile() {
+ return mOpenFile;
+ }
+
+ @Override
+ public FileOpenResult openFile(File mapFile) {
+ mOpenFile = true;
+ mClient = AndroidHttpClient.newInstance("Android");
+ return new FileOpenResult();
+ }
+
+ @Override
+ public void closeFile() {
+ mOpenFile = false;
+ if (mClient != null)
+ mClient.close();
+ }
+
+ @Override
+ public String readString(int position) {
+ return null;
+ }
+
+ private static final int BUFFER_SIZE = 32768;
+ private final byte[] buffer = new byte[BUFFER_SIZE];
+ private int bufferPos;
+ private int bufferSize;
+ private InputStream inputStream;
+
+ private static final int TAG_TILE_TAGS = 1;
+ private static final int TAG_TILE_WAYS = 2;
+ private static final int TAG_TILE_NODES = 3;
+ private static final int TAG_WAY_TAGS = 1;
+ private static final int TAG_WAY_INDEX = 2;
+ private static final int TAG_WAY_COORDS = 3;
+ // private static final int TAG_NODE_TAGS = 1;
+ // private static final int TAG_NODE_COORDS = 2;
+
+ private int bytesRead;
+
+ private boolean decode(InputStream is) throws IOException {
+ inputStream = is;
+ bytesRead = 0;
+ bufferSize = 0;
+ bufferPos = 0;
+ while (true) {
+ // read tag and wire type
+ int val = decodeVarint32();
+ if (val == 0) {
+ // Log.d(TAG, "EOF, all good");
+ return true;
+ }
+ int tag = (val >> 3);
+ // int wireType = (val & 7);
+ // Log.d(TAG, "tile " + tag + " " + wireType);
+
+ switch (tag) {
+ case TAG_TILE_TAGS:
+ decodeTileTags();
+ break;
+
+ case TAG_TILE_WAYS:
+ decodeTileWays();
+ break;
+
+ case TAG_TILE_NODES:
+ decodeTileNodes();
+ break;
+
+ default:
+ Log.d(TAG, "invalid type for tile: " + tag);
+ return false;
+ }
+ }
+ }
+
+ private boolean decodeTileTags() throws IOException {
+ String tagString = decodeString();
+
+ Tag tag = tagHash.get(tagString);
+ if (tag == null) {
+ tag = new Tag(tagString);
+ tagHash.put(tagString, tag);
+ }
+ curTags[mCurTagCnt++] = tag;
+
+ // Log.d(TAG, "tag:" + tag);
+ return true;
+ }
+
+ private boolean decodeTileWays() throws IOException {
+ int bytes = decodeVarint32();
+
+ int end = bytesRead + bytes;
+ int indexCnt = 0;
+ int tagCnt = 0;
+ int coordCnt = 0;
+ while (bytesRead < end) {
+ // read tag and wire type
+
+ int val = decodeVarint32();
+ if (val == 0)
+ break;
+
+ int tag = (val >> 3);
+ // int wireType = val & 7;
+
+ // Log.d(TAG, "way " + tag + " " + wireType + " bytes:" + bytes);
+
+ switch (tag) {
+ case TAG_WAY_TAGS:
+ tagCnt = decodeWayTags();
+ break;
+
+ case TAG_WAY_INDEX:
+ indexCnt = decodeWayIndices();
+ break;
+
+ case TAG_WAY_COORDS:
+ coordCnt = decodeWayCoordinates();
+ break;
+
+ default:
+ Log.d(TAG, "invalid type for way: " + tag);
+ }
+ }
+
+ if (indexCnt == 0 || tagCnt == 0)
+ return false;
+
+ int[] index = new int[indexCnt];
+
+ int sum = 0;
+ for (int i = 0; i < indexCnt; i++) {
+ index[i] = tmpIndices[i] * 2;
+ sum += index[i];
+ }
+
+ Tag[] tags = new Tag[tagCnt];
+ for (int i = 0; i < tagCnt; i++)
+ tags[i] = curTags[tmpTags[i]];
+
+ float[] coords = tmpCoords;
+ int pos = 0;
+
+ if (coordCnt != sum) {
+ Log.d(TAG, "way length is wrong " + coordCnt + " " + sum);
+ return false;
+ }
+
+ float z = mScaleFactor;
+ for (int j = 0, m = indexCnt; j < m; j++) {
+ float lastX = 0;
+ float lastY = 0;
+
+ for (int n = index[j] + pos; pos < n; pos += 2) {
+ lastX = coords[pos] = (coords[pos] * z) + lastX;
+ lastY = coords[pos + 1] = (coords[pos + 1] * z) + lastY;
+ }
+
+ }
+
+ mMapGenerator.renderWay((byte) 0, tags, coords, index, true);
+ return true;
+ }
+
+ private boolean decodeTileNodes() throws IOException {
+ int bytes = decodeVarint32();
+ Log.d(TAG, "way nodes " + bytes);
+ return true;
+ }
+
+ private int MAX_WAY_COORDS = 32768;
+ private int MAX_WAY_INDICES = 1000;
+ private int[] tmpTags = new int[32];
+ private int[] tmpIndices = new int[MAX_WAY_INDICES];
+ private float[] tmpCoords = new float[MAX_WAY_COORDS];
+
+ // private boolean ensureBufferSize(int size) throws IOException {
+ // if (size > (bufferSize - bufferPos))
+ // readBuffer(size - (bufferSize - bufferPos));
+ //
+ // return true;
+ // }
+
+ private int decodeWayTags() throws IOException {
+ int bytes = decodeVarint32();
+ // Log.d(TAG, "way tags: " + bytes);
+
+ int cnt = 0;
+ int end = bytesRead + bytes;
+
+ while (bytesRead < end)
+ tmpTags[cnt++] = decodeVarint32();
+
+ return cnt;
+ }
+
+ private int decodeWayIndices() throws IOException {
+ int bytes = decodeVarint32();
+ // Log.d(TAG, "way indices: " + bytes);
+
+ int cnt = 0;
+ int end = bytesRead + bytes;
+
+ while (bytesRead < end) {
+ int val = decodeVarint32();
+ if (cnt >= MAX_WAY_INDICES) {
+
+ MAX_WAY_INDICES += 128;
+ Log.d(TAG, "increase indices array " + MAX_WAY_INDICES);
+ int[] tmp = new int[MAX_WAY_INDICES];
+ System.arraycopy(tmpIndices, 0, tmp, 0, cnt);
+ tmpIndices = tmp;
+ }
+
+ tmpIndices[cnt++] = val;
+
+ }
+ return cnt;
+ }
+
+ private int decodeWayCoordinates() throws IOException {
+ int bytes = decodeVarint32();
+
+ int cnt = 0;
+ int end = bytesRead + bytes;
+
+ while (bytesRead < end) {
+ int val = decodeZigZag32(decodeVarint32());
+ if (cnt >= MAX_WAY_COORDS) {
+ MAX_WAY_COORDS += 128;
+ Log.d(TAG, "increase coords array " + MAX_WAY_COORDS);
+ float[] tmp = new float[MAX_WAY_COORDS];
+ System.arraycopy(tmpCoords, 0, tmp, 0, cnt);
+ tmpCoords = tmp;
+ }
+ tmpCoords[cnt++] = val;
+ }
+ return cnt;
+ }
+
+ private void readBuffer() throws IOException {
+
+ int len = inputStream.read(buffer, 0, BUFFER_SIZE);
+ if (len < 0) {
+ buffer[bufferPos] = 0;
+ // Log.d(TAG, " nothing to read... pos " + bufferPos + ", size "
+ // + bufferSize + ", read " + bytesRead);
+ return;
+ }
+ bufferSize = len;
+ bufferPos = 0;
+
+ // Log.d(TAG, "pos " + bufferPos + ", size " + bufferSize + ", read "
+ // + bytesRead);
+ }
+
+ private void readBuffer(int size) throws IOException {
+ if (size < (bufferSize - bufferPos))
+ return;
+
+ if (size > BUFFER_SIZE) {
+ Log.d(TAG, "EEEK too large");
+ // FIXME throw exception, but frankly better sanitize tile data on compilation
+ // this only happen with Strings larger than 32kb
+ return;
+ }
+
+ if ((size - bufferSize) + bufferPos > BUFFER_SIZE) {
+ // copy bytes left to read from buffer to the beginning of buffer
+ System.arraycopy(buffer, bufferPos, buffer, 0, bufferSize - bufferPos);
+ bufferPos = 0;
+ }
+
+ while ((bufferSize - bufferPos) < size) {
+ // read until requested size is available in buffer
+ int len = inputStream.read(buffer, bufferSize, BUFFER_SIZE - bufferSize);
+ if (len < 0) {
+ buffer[bufferSize - 1] = 0; // FIXME is this needed?
+ break;
+ }
+ bufferSize += len;
+ }
+
+ // Log.d(TAG, "needed " + size + " pos " + bufferPos + ", size "
+ // + bufferSize
+ // + ", read " + bytesRead);
+ }
+
+ /* All code below is taken from or based on Google's Protocol Buffers implementation: */
+
+ // Protocol Buffers - Google's data interchange format
+ // Copyright 2008 Google Inc. All rights reserved.
+ // http://code.google.com/p/protobuf/
+ //
+ // Redistribution and use in source and binary forms, with or without
+ // modification, are permitted provided that the following conditions are
+ // met:
+ //
+ // * Redistributions of source code must retain the above copyright
+ // notice, this list of conditions and the following disclaimer.
+ // * Redistributions in binary form must reproduce the above
+ // copyright notice, this list of conditions and the following disclaimer
+ // in the documentation and/or other materials provided with the
+ // distribution.
+ // * Neither the name of Google Inc. nor the names of its
+ // contributors may be used to endorse or promote products derived from
+ // this software without specific prior written permission.
+ //
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ private byte readRawByte() throws IOException {
+ if (bufferPos == bufferSize) {
+ readBuffer();
+ }
+ bytesRead++;
+ return buffer[bufferPos++];
+ }
+
+ private int decodeVarint32() throws IOException {
+ byte tmp = readRawByte();
+ if (tmp >= 0) {
+ return tmp;
+ }
+ int result = tmp & 0x7f;
+ if ((tmp = readRawByte()) >= 0) {
+ return result | tmp << 7;
+ }
+ result |= (tmp & 0x7f) << 7;
+ if ((tmp = readRawByte()) >= 0) {
+ return result | tmp << 14;
+ }
+ result |= (tmp & 0x7f) << 14;
+ if ((tmp = readRawByte()) >= 0) {
+ return result | tmp << 21;
+ }
+ result |= (tmp & 0x7f) << 21;
+ result |= (tmp = readRawByte()) << 28;
+
+ if (tmp < 0) {
+ // Discard upper 32 bits.
+ for (int i = 0; i < 5; i++) {
+ if (readRawByte() >= 0) {
+ return result;
+ }
+ }
+ Log.d(TAG, "EEK malformedVarint");
+ // FIXME throw some poo
+ }
+
+ return result;
+ }
+
+ private String decodeString() throws IOException {
+ final int size = decodeVarint32();
+
+ readBuffer(size);
+
+ final String result = new String(buffer, bufferPos, size, "UTF-8");
+ bufferPos += size;
+ bytesRead += size;
+ return result;
+
+ }
+
+ public static int decodeZigZag32(final int n) {
+ return (n >>> 1) ^ -(n & 1);
+ }
+
+}
diff --git a/src/org/mapsforge/database/postgis/MapDatabase.java b/src/org/mapsforge/database/postgis/MapDatabase.java
index 1f0c2f25..7444167c 100644
--- a/src/org/mapsforge/database/postgis/MapDatabase.java
+++ b/src/org/mapsforge/database/postgis/MapDatabase.java
@@ -26,9 +26,9 @@ import java.util.Properties;
import org.mapsforge.core.BoundingBox;
import org.mapsforge.core.GeoPoint;
-import org.mapsforge.core.WebMercator;
import org.mapsforge.core.Tag;
import org.mapsforge.core.Tile;
+import org.mapsforge.core.WebMercator;
import org.mapsforge.database.FileOpenResult;
import org.mapsforge.database.IMapDatabase;
import org.mapsforge.database.IMapDatabaseCallback;
@@ -40,7 +40,7 @@ import org.postgresql.PGConnection;
*
*/
public class MapDatabase implements IMapDatabase {
- private static final String QUERY = "SELECT * FROM __get_tile(?,?,?)";
+ private static final String QUERY = "SELECT tags, geom FROM __get_tile(?,?,?)";
private final float mScale = 1; // 1000000.0f;
@@ -55,16 +55,13 @@ public class MapDatabase implements IMapDatabase {
new MapFileInfo(new BoundingBox(-180, -85, 180, 85),
new Byte((byte) 14), new GeoPoint(53.11, 8.85),
WebMercator.NAME,
- 0, 0, 0, "de", "yo!", "hannes");
- // new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
- // new Byte((byte) 0), null, "Mercator",
- // 0, 0, 0, "de", "yo!", "by me");
+ 0, 0, 0, "de", "comment", "author");
private boolean mOpenFile = false;
private Connection connection = null;
- private static HashMap, Tag> tagHash = new HashMap, Tag>(
- 100);
+ private static volatile HashMap, Tag> tagHash =
+ new HashMap, Tag>(100);
private PreparedStatement prepQuery = null;
private boolean connect() {
@@ -123,7 +120,6 @@ public class MapDatabase implements IMapDatabase {
byte[] b = null;
PGHStore h = null;
- // long id;
try {
while (r != null && r.next()) {
@@ -131,9 +127,7 @@ public class MapDatabase implements IMapDatabase {
mCoordPos = 0;
try {
- // id = r.getLong(1);
-
- Object obj = r.getObject(2);
+ Object obj = r.getObject(1);
h = null;
if (obj instanceof PGHStore)
@@ -141,7 +135,7 @@ public class MapDatabase implements IMapDatabase {
else
continue;
- b = r.getBytes(3);
+ b = r.getBytes(2);
} catch (SQLException e) {
e.printStackTrace();
@@ -184,6 +178,11 @@ public class MapDatabase implements IMapDatabase {
}
}
+ @Override
+ public String getMapProjection() {
+ return WebMercator.NAME;
+ }
+
@Override
public MapFileInfo getMapFileInfo() {
return mMapInfo;