From 76e1dcae7ce3fb4a3aaaaa638b695cd8643d81ca Mon Sep 17 00:00:00 2001
From: Hannes Janetzek <hannes.janetzek@gmail.com>
Date: Mon, 4 Feb 2013 14:50:11 +0100
Subject: [PATCH] - fix issue with hanging ui on clse when network is down -
 add getters for rotation/compass enabled - cleanups

---
 src/org/oscim/database/IMapDatabase.java   |   4 +-
 src/org/oscim/generator/TileGenerator.java | 103 ++++++++-------------
 src/org/oscim/view/MapView.java            |  70 ++++++--------
 src/org/oscim/view/MapViewPosition.java    |   2 +-
 4 files changed, 68 insertions(+), 111 deletions(-)

diff --git a/src/org/oscim/database/IMapDatabase.java b/src/org/oscim/database/IMapDatabase.java
index 960b69ee..5d03248a 100644
--- a/src/org/oscim/database/IMapDatabase.java
+++ b/src/org/oscim/database/IMapDatabase.java
@@ -15,7 +15,6 @@
  */
 package org.oscim.database;
 
-
 import org.oscim.generator.JobTile;
 
 /**
@@ -57,7 +56,8 @@ public interface IMapDatabase {
 
 	/**
 	 * Closes the map file and destroys all internal caches. Has no effect if no
-	 * map file is currently opened.
+	 * map file is currently opened. Should also force to close Socket so that
+	 * thread cannot hang in socket.read
 	 */
 	public abstract void close();
 
diff --git a/src/org/oscim/generator/TileGenerator.java b/src/org/oscim/generator/TileGenerator.java
index 62945530..be2ee066 100644
--- a/src/org/oscim/generator/TileGenerator.java
+++ b/src/org/oscim/generator/TileGenerator.java
@@ -46,7 +46,7 @@ import android.util.Log;
 /**
  * @author Hannes Janetzek
  * @note
- *       1. MapWorker calls TileGenerator.execute to load a tile.
+ *       1. The MapWorkers call TileGenerator.execute() to load a tile.
  *       2. The tile data will be loaded from current MapDatabase
  *       3. MapDatabase calls the IMapDatabaseCallback functions
  *       implemented by TileGenerator for WAY and POI items.
@@ -65,10 +65,14 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 	public static final byte STROKE_MAX_ZOOM_LEVEL = 17;
 
 	private static RenderTheme renderTheme;
+	private static int renderLevels;
+	private static DebugSettings debug;
 
+	// current MapDatabase used by this TileGenerator
 	private IMapDatabase mMapDatabase;
 
-	private MapTile mCurrentTile;
+	// currently processed tile
+	private MapTile mTile;
 
 	// coordinates of the currently processed way
 	private float[] mCoords;
@@ -83,15 +87,12 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 	private TextItem mLabels;
 
 	private int mDrawingLayer;
-	private int mLevels;
 
 	private float mStrokeScale = 1.0f;
 
 	private RenderInstruction[] mRenderInstructions = null;
 
-	//private final String TAG_WATER = "water".intern();
-
-	private final MapView mMapView;
+	//private final MapView mMapView;
 
 	private final Tag[] debugTagBox = { new Tag("debug", "box") };
 	private final Tag[] debugTagWay = { new Tag("debug", "way") };
@@ -105,9 +106,9 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 	private float mPoiX, mPoiY;
 	private int mPriority;
 
+	// replacement for variable value tags that should not be matched by RenderTheme
 	private final static Tag mTagEmptyName = new Tag(Tag.TAG_KEY_NAME, null, false);
 	private final static Tag mTagEmptyHouseNr = new Tag(Tag.TAG_KEY_HOUSE_NUMBER, null, false);
-
 	private Tag mTagName;
 	private Tag mTagHouseNr;
 
@@ -116,6 +117,11 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 
 	public static void setRenderTheme(RenderTheme theme) {
 		renderTheme = theme;
+		renderLevels = theme.getLevels();
+	}
+
+	public static void setDebugSettings(DebugSettings debugSettings) {
+		debug = debugSettings;
 	}
 
 	/**
@@ -123,7 +129,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 	 *            the MapView
 	 */
 	public TileGenerator(MapView mapView) {
-		mMapView = mapView;
+		//	mMapView = mapView;
 	}
 
 	public void cleanup() {
@@ -135,25 +141,18 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 		if (mMapDatabase == null)
 			return false;
 
-		tile = mCurrentTile = (MapTile) jobTile;
-		DebugSettings debugSettings = mMapView.getDebugSettings();
+		tile = mTile = (MapTile) jobTile;
 
-		mDebugDrawPolygons = !debugSettings.mDisablePolygons;
-		mDebugDrawUnmatched = debugSettings.mDrawUnmatchted;
+		mDebugDrawPolygons = !debug.mDisablePolygons;
+		mDebugDrawUnmatched = debug.mDrawUnmatchted;
 
 		if (tile.layers != null) {
 			// should be fixed now.
-			Log.d(TAG, "XXX tile already loaded " + tile + " " + tile.state);
+			Log.d(TAG, "BUG tile already loaded " + tile + " " + tile.state);
 			return false;
 		}
 
-		mLevels = TileGenerator.renderTheme.getLevels();
-
-		// limit stroke scale at z=17
-		// if (tile.zoomLevel < STROKE_MAX_ZOOM_LEVEL)
 		setScaleStrokeWidth(tile.zoomLevel);
-		// else
-		// setScaleStrokeWidth(STROKE_MAX_ZOOM_LEVEL);
 
 		// account for area changes with latitude
 		mProjectionScaleFactor = 0.5f + 0.5f * (
@@ -162,20 +161,6 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 
 		mLayers = new Layers();
 
-		//Log.d(TAG, "loading: " + tile);
-		// 180 degree angle in building
-		//if ((tile.zoomLevel != 17) || (tile.tileX == 68728 && tile.tileY == 42634))
-
-		// bad bad poly!
-		// if ((tile.zoomLevel != 17) || (tile.tileX == 69767 && tile.tileY == 47236))
-		//g: [X:69165, Y:42344, Z:17]
-		//if ((tile.zoomLevel != 17) || (tile.tileX == 69165 && tile.tileY == 42344))
-
-		// tram/service elements rendered as buildnig with vts
-		//if ((tile.zoomLevel != 17) || (tile.tileX == 68744 && tile.tileY == 42650))
-
-		//if ((tile.zoomLevel != 17) || (tile.tileX == 68736 && tile.tileY == 42653))
-
 		if (mMapDatabase.executeQuery(tile, this) != QueryResult.SUCCESS) {
 			//Log.d(TAG, "Failed loading: " + tile);
 			mLayers.clear();
@@ -188,7 +173,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 			return false;
 		}
 
-		if (debugSettings.mDrawTileFrames) {
+		if (debug.mDrawTileFrames) {
 			mTagName = new Tag("name", tile.toString(), false);
 			mPoiX = Tile.TILE_SIZE >> 1;
 			mPoiY = 10;
@@ -201,7 +186,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 				mIndices[0] = 10;
 
 			mCoords = debugBoxCoords;
-			mDrawingLayer = 10 * mLevels;
+			mDrawingLayer = 10 * renderLevels;
 			TileGenerator.renderTheme.matchWay(this, debugTagBox, (byte) 0, false, true);
 		}
 
@@ -249,6 +234,11 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 
 	private boolean mRenderBuildingModel;
 
+	// Replace tags that should not be matched by value in RenderTheme
+	// to avoid caching RenderInstructions for each way of the same type
+	// only with different name.
+	// Maybe this should be done within RenderTheme, also allowing
+	// to set these replacement rules in theme file.
 	private boolean filterTags(Tag[] tags) {
 		mRenderBuildingModel = false;
 
@@ -260,7 +250,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 			} else if (tags[i].key == Tag.TAG_KEY_HOUSE_NUMBER) {
 				mTagHouseNr = tags[i];
 				tags[i] = mTagEmptyHouseNr;
-			} else if (mCurrentTile.zoomLevel >= 17 &&
+			} else if (mTile.zoomLevel >= 17 &&
 					key == Tag.TAG_KEY_BUILDING) {
 				mRenderBuildingModel = true;
 			}
@@ -270,17 +260,17 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 
 	// ---------------- MapDatabaseCallback -----------------
 	@Override
-	public void renderPointOfInterest(byte layer, Tag[] tags, float latitude,
-			float longitude) {
+	public void renderPointOfInterest(byte layer, Tag[] tags,
+			float latitude, float longitude) {
 
 		// reset state
 		mTagName = null;
 		mTagHouseNr = null;
 
 		//if (mMapProjection != null) {
-		//	long x = mCurrentTile.pixelX;
-		//	long y = mCurrentTile.pixelY + Tile.TILE_SIZE;
-		//	long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
+		//	long x = mTile.pixelX;
+		//	long y = mTile.pixelY + Tile.TILE_SIZE;
+		//	long z = Tile.TILE_SIZE << mTile.zoomLevel;
 		//
 		//	double divx, divy;
 		//	long dx = (x - (z >> 1));
@@ -297,10 +287,6 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 		//		mPoiX = (float) (longitude / divx - dx);
 		//		double sinLat = Math.sin(latitude * PI180);
 		//		mPoiY = (float) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy);
-		//
-		//		// TODO remove this, only used for mapsforge maps
-		//		if (mPoiX < -10 || mPoiX > Tile.TILE_SIZE + 10 || mPoiY < -10
-		//				|| mPoiY > Tile.TILE_SIZE + 10)
 		//			return;
 		//	}
 		//} else {
@@ -313,7 +299,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 		// Log.d(TAG, "renderPointOfInterest: " + mTagName);
 
 		// mNodeRenderInstructions =
-		TileGenerator.renderTheme.matchNode(this, tags, mCurrentTile.zoomLevel);
+		TileGenerator.renderTheme.matchNode(this, tags, mTile.zoomLevel);
 	}
 
 	private boolean mClosed;
@@ -334,23 +320,12 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 		if (!filterTags(tags))
 			return;
 
-		//	mProjected = false;
-		//	mSimplify = 0.5f;
-		//	if (closed) {
-		//		if (mCurrentTile.zoomLevel < 14)
-		//			mSimplify = 0.5f;
-		//		else
-		//			mSimplify = 0.2f;
-		//		if (tags.length == 1 && TAG_WATER == (tags[0].value))
-		//			mSimplify = 0;
-		//	}
-
-		mDrawingLayer = getValidLayer(layer) * mLevels;
+		mDrawingLayer = getValidLayer(layer) * renderLevels;
 		mCoords = coords;
 		mIndices = indices;
 
 		mRenderInstructions = TileGenerator.renderTheme.matchWay(this, tags,
-				(byte) (mCurrentTile.zoomLevel + 0), closed, true);
+				(byte) (mTile.zoomLevel + 0), closed, true);
 
 		if (mRenderInstructions == null && mDebugDrawUnmatched)
 			debugUnmatched(closed, tags);
@@ -380,7 +355,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 	public boolean checkWay(Tag[] tags, boolean closed) {
 
 		mRenderInstructions = TileGenerator.renderTheme.matchWay(this, tags,
-				(byte) (mCurrentTile.zoomLevel + 0), closed, false);
+				(byte) (mTile.zoomLevel + 0), closed, false);
 
 		return mRenderInstructions != null;
 	}
@@ -426,7 +401,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 		int numLayer = mDrawingLayer + level;
 
 		if (mRenderBuildingModel) {
-			//Log.d(TAG, "add buildings: " + mCurrentTile + " " + mPriority);
+			//Log.d(TAG, "add buildings: " + mTile + " " + mPriority);
 			if (mLayers.extrusionLayers == null)
 				mLayers.extrusionLayers = new ExtrusionLayer(0);
 
@@ -553,9 +528,9 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
 	//
 	//		float[] coords = mCoords;
 	//
-	//		long x = mCurrentTile.pixelX;
-	//		long y = mCurrentTile.pixelY + Tile.TILE_SIZE;
-	//		long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
+	//		long x = mTile.pixelX;
+	//		long y = mTile.pixelY + Tile.TILE_SIZE;
+	//		long z = Tile.TILE_SIZE << mTile.zoomLevel;
 	//		float min = mSimplify;
 	//
 	//		double divx, divy = 0;
diff --git a/src/org/oscim/view/MapView.java b/src/org/oscim/view/MapView.java
index 582cdd4f..e9c5e2e2 100644
--- a/src/org/oscim/view/MapView.java
+++ b/src/org/oscim/view/MapView.java
@@ -70,8 +70,8 @@ public class MapView extends RelativeLayout {
 	public static final boolean testRegionZoom = false;
 	private static final boolean debugDatabase = false;
 
-	public boolean enableRotation = false;
-	public boolean enableCompass = false;
+	public boolean mRotationEnabled = false;
+	public boolean mCompassEnabled = false;
 	public boolean enablePagedFling = false;
 
 	private final MapViewPosition mMapViewPosition;
@@ -82,8 +82,6 @@ public class MapView extends RelativeLayout {
 	private final TouchHandler mTouchEventHandler;
 	private final Compass mCompass;
 
-	//private MapDatabases mMapDatabaseType;
-
 	private TileManager mTileManager;
 	private final OverlayManager mOverlayManager;
 
@@ -96,9 +94,8 @@ public class MapView extends RelativeLayout {
 
 	private MapOptions mMapOptions;
 	private IMapDatabase mMapDatabase;
-
-	private DebugSettings debugSettings;
 	private String mRenderTheme;
+	private DebugSettings mDebugSettings;
 
 	private boolean mClearTiles;
 
@@ -141,8 +138,6 @@ public class MapView extends RelativeLayout {
 
 		MapActivity mapActivity = (MapActivity) context;
 
-		debugSettings = new DebugSettings(false, false, false, false);
-
 		mMapViewPosition = new MapViewPosition(this);
 		mMapPosition = new MapPosition();
 
@@ -160,6 +155,9 @@ public class MapView extends RelativeLayout {
 
 		mMapWorkers = new MapWorker[mNumMapWorkers];
 
+		mDebugSettings = new DebugSettings(false, false, false, false);
+		TileGenerator.setDebugSettings(mDebugSettings);
+
 		for (int i = 0; i < mNumMapWorkers; i++) {
 			TileGenerator tileGenerator = new TileGenerator(this);
 			mMapWorkers[i] = new MapWorker(i, mJobQueue, tileGenerator, mTileManager);
@@ -181,7 +179,7 @@ public class MapView extends RelativeLayout {
 
 		mMapZoomControls = new MapZoomControls(mapActivity, this);
 		mMapZoomControls.setShowMapZoomControls(true);
-		enableRotation = true;
+		mRotationEnabled = true;
 
 		//mOverlayManager.add(new GenericOverlay(this, new GridOverlay(this)));
 		mOverlayManager.add(new BuildingOverlay(this));
@@ -224,13 +222,6 @@ public class MapView extends RelativeLayout {
 			mGLView.requestRender();
 	}
 
-	//	/**
-	//	 * @return the map database which is used for reading map files.
-	//	 */
-	//	public IMapDatabase getMapDatabase() {
-	//		return mMapDatabase;
-	//	}
-
 	/**
 	 * @return the current position and zoom level of this MapView.
 	 */
@@ -239,7 +230,7 @@ public class MapView extends RelativeLayout {
 	}
 
 	public void enableRotation(boolean enable) {
-		enableRotation = enable;
+		mRotationEnabled = enable;
 
 		if (enable) {
 			enableCompass(false);
@@ -247,10 +238,10 @@ public class MapView extends RelativeLayout {
 	}
 
 	public void enableCompass(boolean enable) {
-		if (enable == this.enableCompass)
+		if (enable == mCompassEnabled)
 			return;
 
-		this.enableCompass = enable;
+		mCompassEnabled = enable;
 
 		if (enable)
 			enableRotation(false);
@@ -261,6 +252,14 @@ public class MapView extends RelativeLayout {
 			mCompass.disable();
 	}
 
+	public boolean getCompassEnabled() {
+		return mCompassEnabled;
+	}
+
+	public boolean getRotationEnabled() {
+		return mRotationEnabled;
+	}
+
 	@Override
 	public boolean onTouchEvent(MotionEvent motionEvent) {
 		// mMapZoomControls.onMapViewTouchEvent(motionEvent.getAction()
@@ -305,7 +304,8 @@ public class MapView extends RelativeLayout {
 	 *            the new DebugSettings for this MapView.
 	 */
 	public void setDebugSettings(DebugSettings debugSettings) {
-		this.debugSettings = debugSettings;
+		mDebugSettings = debugSettings;
+		TileGenerator.setDebugSettings(debugSettings);
 		clearAndRedrawMap();
 	}
 
@@ -313,7 +313,7 @@ public class MapView extends RelativeLayout {
 	 * @return the debug settings which are used in this MapView.
 	 */
 	public DebugSettings getDebugSettings() {
-		return debugSettings;
+		return mDebugSettings;
 	}
 
 	public Map<String, String> getMapOptions() {
@@ -488,27 +488,20 @@ public class MapView extends RelativeLayout {
 		mapWorkersProceed();
 	}
 
-	//	@Override
-	//	protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-	//		//		super.onLayout(changed, left, top, right, bottom);
-	//		mMapZoomControls.onLayout(changed, left, top, right, bottom);
-	//	}
-
 	void destroy() {
 		for (MapWorker mapWorker : mMapWorkers) {
 			mapWorker.pause();
 			mapWorker.interrupt();
 
+			mapWorker.getTileGenerator().getMapDatabase().close();
+
 			try {
-				// FIXME this hangs badly sometimes,
-				// just let it crash...
 				mapWorker.join(10000);
 			} catch (InterruptedException e) {
 				// restore the interrupted status
 				Thread.currentThread().interrupt();
 			}
-			TileGenerator tileGenerator = mapWorker.getTileGenerator();
-			tileGenerator.getMapDatabase().close();
+
 		}
 	}
 
@@ -521,7 +514,7 @@ public class MapView extends RelativeLayout {
 		mJobQueue.clear();
 		mapWorkersPause(true);
 
-		if (this.enableCompass)
+		if (this.mCompassEnabled)
 			mCompass.disable();
 
 	}
@@ -530,7 +523,7 @@ public class MapView extends RelativeLayout {
 		Log.d(TAG, "onResume");
 		mapWorkersProceed();
 
-		if (this.enableCompass)
+		if (this.mCompassEnabled)
 			mCompass.enable();
 
 		mPausing = false;
@@ -669,17 +662,6 @@ public class MapView extends RelativeLayout {
 		return new GeoPoint(mMapPosition.lat, mMapPosition.lon);
 	}
 
-	//	@Override
-	//	protected void onLayout(boolean changed, int l, int t, int r, int b) {
-	//		// TODO Auto-generated method stub
-	//
-	//	}
-	//	
-	//	@Override
-	//	protected void onMeasure()) {
-	//		// TODO Auto-generated method stub
-	//
-	//	}
 	// /**
 	// * Sets the visibility of the zoom controls.
 	// *
diff --git a/src/org/oscim/view/MapViewPosition.java b/src/org/oscim/view/MapViewPosition.java
index f825a465..f791fbd3 100644
--- a/src/org/oscim/view/MapViewPosition.java
+++ b/src/org/oscim/view/MapViewPosition.java
@@ -475,7 +475,7 @@ public class MapViewPosition {
 		double dx = mx / mScale;
 		double dy = my / mScale;
 
-		if (mMapView.enableRotation || mMapView.enableCompass) {
+		if (mMapView.mRotationEnabled || mMapView.mCompassEnabled) {
 			double rad = Math.toRadians(mRotation);
 			double rcos = Math.cos(rad);
 			double rsin = Math.sin(rad);