implement continous vector rendering (to see image faster)

git-svn-id: https://osmand.googlecode.com/svn/trunk@725 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-11-29 22:44:39 +00:00
parent 940c542da6
commit 833ab7e60e
6 changed files with 80 additions and 21 deletions

View file

@ -26,6 +26,7 @@
<ListPreference android:title="@string/voice_provider" android:key="voice_provider" android:summary="@string/voice_provider_descr"></ListPreference>
<ListPreference android:key="renderer" android:title="@string/renderers" android:summary="@string/renderers_descr"></ListPreference>
<CheckBoxPreference android:summary="Use this flag to check rendering performance" android:title="Trace rendering" android:key="debug_rendering"></CheckBoxPreference>
<CheckBoxPreference android:summary="Choose show continuous rendering or whole image" android:title="Continuous rendering" android:key="use_step_by_step_rendering"/>
</PreferenceScreen>
<PreferenceScreen android:title="@string/routing_settings" android:summary="@string/routing_settings_descr">

View file

@ -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$

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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<BinaryMapDataObject> 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<IMapDownloaderCallback> 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$

View file

@ -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<BinaryMapDataObject> objects, boolean useEnglishNames) {
public Bitmap generateNewBitmap(RenderingContext rc, List<BinaryMapDataObject> objects, Bitmap bmp, boolean useEnglishNames, List<IMapDownloaderCallback> 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<IMapDownloaderCallback> 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) {