From 833ab7e60e2907cb9af268f3cb9fdf3c7192930a Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 29 Nov 2010 22:44:39 +0000 Subject: [PATCH] implement continous vector rendering (to see image faster) git-svn-id: https://osmand.googlecode.com/svn/trunk@725 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8 --- OsmAnd/res/xml/settings_pref.xml | 1 + OsmAnd/src/net/osmand/OsmandSettings.java | 14 ++++++ OsmAnd/src/net/osmand/ResourceManager.java | 2 +- .../osmand/activities/SettingsActivity.java | 1 + .../osmand/render/MapRenderRepositories.java | 40 +++++++++++++---- .../src/net/osmand/render/OsmandRenderer.java | 43 +++++++++++++------ 6 files changed, 80 insertions(+), 21 deletions(-) diff --git a/OsmAnd/res/xml/settings_pref.xml b/OsmAnd/res/xml/settings_pref.xml index dd633e1089..751af0a0d4 100644 --- a/OsmAnd/res/xml/settings_pref.xml +++ b/OsmAnd/res/xml/settings_pref.xml @@ -26,6 +26,7 @@ + diff --git a/OsmAnd/src/net/osmand/OsmandSettings.java b/OsmAnd/src/net/osmand/OsmandSettings.java index ed7cf72733..1d1d7953a8 100644 --- a/OsmAnd/src/net/osmand/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/OsmandSettings.java @@ -354,6 +354,20 @@ public class OsmandSettings { SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE); return prefs.edit().putBoolean(USE_ENGLISH_NAMES, useEnglishNames).commit(); } + + // this value string is synchronized with settings_pref.xml preference name + public static final String USE_STEP_BY_STEP_RENDERING = "use_step_by_step_rendering"; //$NON-NLS-1$ + public static final boolean USE_STEP_BY_STEP_RENDERING_DEF = true; + + public static boolean isUsingStepByStepRendering(SharedPreferences prefs) { + return prefs.getBoolean(USE_STEP_BY_STEP_RENDERING, USE_STEP_BY_STEP_RENDERING_DEF); + } + + public static boolean setUsingStepByStepRendering(Context ctx, boolean rendering) { + SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE); + return prefs.edit().putBoolean(USE_STEP_BY_STEP_RENDERING, rendering).commit(); + } + // this value string is synchronized with settings_pref.xml preference name public static final String MAP_VECTOR_DATA = "map_vector_data"; //$NON-NLS-1$ diff --git a/OsmAnd/src/net/osmand/ResourceManager.java b/OsmAnd/src/net/osmand/ResourceManager.java index d0799dd9bf..f05c701b94 100644 --- a/OsmAnd/src/net/osmand/ResourceManager.java +++ b/OsmAnd/src/net/osmand/ResourceManager.java @@ -825,7 +825,7 @@ public class ResourceManager { } else if(req instanceof MapLoadRequest){ if(!mapLoaded){ MapLoadRequest r = (MapLoadRequest) req; - renderer.loadMap(r.tileBox); + renderer.loadMap(r.tileBox, downloader.getDownloaderCallbacks()); mapLoaded = true; } } diff --git a/OsmAnd/src/net/osmand/activities/SettingsActivity.java b/OsmAnd/src/net/osmand/activities/SettingsActivity.java index a377b4d588..0d7928e1f0 100644 --- a/OsmAnd/src/net/osmand/activities/SettingsActivity.java +++ b/OsmAnd/src/net/osmand/activities/SettingsActivity.java @@ -109,6 +109,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference new BooleanPreference(OsmandSettings.AUTO_ZOOM_MAP, OsmandSettings.AUTO_ZOOM_MAP_DEF), new BooleanPreference(OsmandSettings.SAVE_TRACK_TO_GPX, OsmandSettings.SAVE_TRACK_TO_GPX_DEF), new BooleanPreference(OsmandSettings.DEBUG_RENDERING_INFO, OsmandSettings.DEBUG_RENDERING_INFO_DEF), + new BooleanPreference(OsmandSettings.USE_STEP_BY_STEP_RENDERING, OsmandSettings.USE_STEP_BY_STEP_RENDERING_DEF), }; private BroadcastReceiver broadcastReceiver; diff --git a/OsmAnd/src/net/osmand/render/MapRenderRepositories.java b/OsmAnd/src/net/osmand/render/MapRenderRepositories.java index 46803794fb..a9cee43602 100644 --- a/OsmAnd/src/net/osmand/render/MapRenderRepositories.java +++ b/OsmAnd/src/net/osmand/render/MapRenderRepositories.java @@ -28,6 +28,7 @@ import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.binary.BinaryMapIndexReader.TagValuePair; import net.osmand.data.index.IndexConstants; +import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; import net.osmand.osm.MapRenderingTypes; import net.osmand.osm.MapUtils; import net.osmand.osm.MultyPolygon; @@ -36,8 +37,10 @@ import net.osmand.render.OsmandRenderer.RenderingContext; import org.apache.commons.logging.Log; import android.content.Context; +import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.RectF; +import android.graphics.Bitmap.Config; import android.os.Handler; import android.os.Looper; import android.widget.Toast; @@ -68,11 +71,13 @@ public class MapRenderRepositories { private boolean interrupted = false; private RenderingContext currentRenderingContext; private SearchRequest searchRequest; + private SharedPreferences prefs; public MapRenderRepositories(Context context){ this.context = context; this.renderer = new OsmandRenderer(context); handler = new Handler(Looper.getMainLooper()); + prefs = OsmandSettings.getPrefs(context); } public Context getContext() { @@ -287,7 +292,7 @@ public class MapRenderRepositories { } - public synchronized void loadMap(RotatedTileBox tileRect) { + public synchronized void loadMap(RotatedTileBox tileRect, List notifyList) { interrupted = false; if(currentRenderingContext != null){ currentRenderingContext = null; @@ -330,19 +335,38 @@ public class MapRenderRepositories { } now = System.currentTimeMillis(); - Bitmap bmp = renderer.generateNewBitmap(currentRenderingContext, cObjects, OsmandSettings.usingEnglishNames(OsmandSettings - .getPrefs(context))); + + + Bitmap bmp = Bitmap.createBitmap(currentRenderingContext.width, currentRenderingContext.height, Config.RGB_565); + + boolean stepByStep = OsmandSettings.isUsingStepByStepRendering(prefs); + // 1. generate image step by step + if (stepByStep) { + Bitmap oldBmp = this.bmp; + this.bmp = bmp; + this.bmpLocation = tileRect; + if (oldBmp != null) { + oldBmp.recycle(); + } + } + + renderer.generateNewBitmap(currentRenderingContext, cObjects, bmp, + OsmandSettings.usingEnglishNames(prefs), stepByStep ? notifyList : null); if (checkWhetherInterrupted()) { currentRenderingContext = null; return; } final long renderingTime = System.currentTimeMillis() - now; currentRenderingContext = null; - Bitmap oldBmp = this.bmp; - this.bmp = bmp; - this.bmpLocation = tileRect; - if (oldBmp != null) { - oldBmp.recycle(); + + // 2. replace whole image + if (!stepByStep) { + Bitmap oldBmp = this.bmp; + this.bmp = bmp; + this.bmpLocation = tileRect; + if (oldBmp != null) { + oldBmp.recycle(); + } } if(OsmandSettings.isDebugRendering(context)){ final String msg = "Search done in "+ searchTime+" ms\nRendering done in "+ renderingTime+ " ms"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ diff --git a/OsmAnd/src/net/osmand/render/OsmandRenderer.java b/OsmAnd/src/net/osmand/render/OsmandRenderer.java index 4450aea679..7ea377547d 100644 --- a/OsmAnd/src/net/osmand/render/OsmandRenderer.java +++ b/OsmAnd/src/net/osmand/render/OsmandRenderer.java @@ -15,6 +15,7 @@ import java.util.Map; import net.osmand.LogUtil; import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapIndexReader.TagValuePair; +import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; import net.osmand.osm.MapRenderingTypes; import net.osmand.osm.MultyPolygon; import net.sf.junidecode.Junidecode; @@ -35,7 +36,6 @@ import android.graphics.PointF; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.Typeface; -import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory.Options; import android.graphics.Paint.Align; import android.graphics.Paint.Cap; @@ -271,9 +271,20 @@ public class OsmandRenderer { } - public Bitmap generateNewBitmap(RenderingContext rc, List objects, boolean useEnglishNames) { + public Bitmap generateNewBitmap(RenderingContext rc, List objects, Bitmap bmp, boolean useEnglishNames, List notifyList) { long now = System.currentTimeMillis(); render = RendererRegistry.getRegistry().getCurrentSelectedRenderer(); + + // fill area + Canvas cv = new Canvas(bmp); + if(render != null){ + int dc = render.getDefaultColor(); + if(dc != 0){ + paintFillEmpty.setColor(dc); + } + } + cv.drawRect(0, 0, bmp.getWidth(), bmp.getHeight(), paintFillEmpty); + // put in order map int sz = objects.size(); int init = sz / 4; @@ -310,24 +321,16 @@ public class OsmandRenderer { } } - Bitmap bmp = null; if (objects != null && !objects.isEmpty() && rc.width > 0 && rc.height > 0) { // init rendering context rc.tileDivisor = (int) (1 << (31 - rc.zoom)); rc.cosRotateTileSize = FloatMath.cos((float) Math.toRadians(rc.rotate)) * TILE_SIZE; rc.sinRotateTileSize = FloatMath.sin((float) Math.toRadians(rc.rotate)) * TILE_SIZE; - bmp = Bitmap.createBitmap(rc.width, rc.height, Config.RGB_565); - Canvas cv = new Canvas(bmp); - if(render != null){ - int dc = render.getDefaultColor(); - if(dc != 0){ - paintFillEmpty.setColor(dc); - } - } - cv.drawRect(0, 0, bmp.getWidth(), bmp.getHeight(), paintFillEmpty); + float[] keys = orderMap.keys(); Arrays.sort(keys); + int objCount = 0; for (int k = 0; k < keys.length; k++) { TIntArrayList list = orderMap.get(keys[k]); for (int j = 0; j < list.size(); j++) { @@ -338,11 +341,18 @@ public class OsmandRenderer { // show text only for main type drawObj(obj, cv, rc, obj.getTypes()[l], l == 0); + + objCount++; + } + if(objCount > 35){ + notifyListeners(notifyList); + objCount = 0; } if(rc.interrupted){ return null; } } + notifyListeners(notifyList); int skewConstant = (int) (16 * dm.density); @@ -380,6 +390,7 @@ public class OsmandRenderer { return null; } } + notifyListeners(notifyList); drawTextOverCanvas(rc, cv, useEnglishNames); long time = System.currentTimeMillis() - now; log.info(String.format("Rendering has been done in %s ms. (%s points, %s points inside, %s visile from %s)",//$NON-NLS-1$ @@ -389,6 +400,14 @@ public class OsmandRenderer { return bmp; } + + private void notifyListeners(List notifyList) { + if (notifyList != null) { + for (IMapDownloaderCallback c : notifyList) { + c.tileDownloaded(null); + } + } + } private final static boolean findAllTextIntersections = true; public void drawTextOverCanvas(RenderingContext rc, Canvas cv, boolean useEnglishNames) {