Update zoom animation and add zoom fraction for autozoom (don't change density in autozoom). Add limit autozoom for different drive options

This commit is contained in:
Victor Shcherb 2015-01-13 00:04:08 +01:00
parent 4eb799499d
commit eaa25f3daa
10 changed files with 122 additions and 92 deletions

View file

@ -64,7 +64,7 @@ public class BinaryInspector {
"-vmap", "-vmapobjects", "-vmap", "-vmapobjects",
// "-vrouting", // "-vrouting",
// "-vaddress", "-vcities", "-vstreets", "-vstreetgroups","-vbuildings", // "-vaddress", "-vcities", "-vstreets", "-vstreetgroups","-vbuildings",
//"-zoom=16", // "-zoom=16",
// "-bbox=1.74,51.17,1.75,51.16", // "-bbox=1.74,51.17,1.75,51.16",
"/home/victor/projects/osmand/osm-gen/Map.obf" "/home/victor/projects/osmand/osm-gen/Map.obf"
}); });

View file

@ -11,6 +11,7 @@ public class RotatedTileBox {
private int zoom; private int zoom;
private double mapDensity = 1; private double mapDensity = 1;
private double zoomAnimation; private double zoomAnimation;
private double zoomFloatPart;
private int cx; private int cx;
private int cy; private int cy;
private int pixWidth; private int pixWidth;
@ -42,6 +43,7 @@ public class RotatedTileBox {
this.lon = r.lon; this.lon = r.lon;
this.zoom = r.zoom; this.zoom = r.zoom;
this.mapDensity = r.mapDensity; this.mapDensity = r.mapDensity;
this.zoomFloatPart = r.zoomFloatPart;
this.zoomAnimation = r.zoomAnimation; this.zoomAnimation = r.zoomAnimation;
this.rotate = r.rotate; this.rotate = r.rotate;
this.density = r.density; this.density = r.density;
@ -67,7 +69,7 @@ public class RotatedTileBox {
} }
public void calculateDerivedFields() { public void calculateDerivedFields() {
zoomFactor = Math.pow(2, zoomAnimation ) * 256 * mapDensity; zoomFactor = Math.pow(2, zoomAnimation + zoomFloatPart) * 256 * mapDensity;
double rad = Math.toRadians(this.rotate); double rad = Math.toRadians(this.rotate);
rotateCos = Math.cos(rad); rotateCos = Math.cos(rad);
rotateSin = Math.sin(rad); rotateSin = Math.sin(rad);
@ -341,12 +343,18 @@ public class RotatedTileBox {
public double getZoomAnimation() { public double getZoomAnimation() {
return zoomAnimation; return zoomAnimation;
} }
public void setZoomAnimation(double z) { public double getZoomFloatPart() {
this.zoomAnimation = z; return zoomFloatPart;
calculateDerivedFields();
} }
public void setZoomAndAnimation(int zoom, double zoomAnimation, double zoomFloatPart) {
this.zoomAnimation = zoomAnimation;
this.zoomFloatPart = zoomFloatPart;
this.zoom = zoom;
calculateDerivedFields();
}
public void setZoomAndAnimation(int zoom, double zoomAnimation) { public void setZoomAndAnimation(int zoom, double zoomAnimation) {
this.zoomAnimation = zoomAnimation; this.zoomAnimation = zoomAnimation;
this.zoom = zoom; this.zoom = zoom;
@ -406,12 +414,6 @@ public class RotatedTileBox {
calculateDerivedFields(); calculateDerivedFields();
} }
public void setZoomWithAnimate(int zoom,double zoomToAnimate) {
this.zoom = zoom;
this.zoomAnimation = zoomToAnimate;
calculateDerivedFields();
}
public float getRotate() { public float getRotate() {
return rotate; return rotate;
} }

View file

@ -107,12 +107,10 @@ public class RenderingRulesStorage {
if (renderingAttributes.containsKey(e.getKey())) { if (renderingAttributes.containsKey(e.getKey())) {
RenderingRule root = renderingAttributes.get(e.getKey()); RenderingRule root = renderingAttributes.get(e.getKey());
List<RenderingRule> list = e.getValue().getIfElseChildren(); List<RenderingRule> list = e.getValue().getIfElseChildren();
e.getValue().addToBeginIfElseChildren(root);
for (RenderingRule every : list) { for (RenderingRule every : list) {
if(every != root) { root.addIfElseChildren(every);
root.addIfElseChildren(every);
}
} }
e.getValue().addToBeginIfElseChildren(root);
} else { } else {
renderingAttributes.put(e.getKey(), e.getValue()); renderingAttributes.put(e.getKey(), e.getValue());
} }

View file

@ -773,7 +773,7 @@ public class OsmandSettings {
new EnumIntPreference<AutoZoomMap>("auto_zoom_map_new", AutoZoomMap.NONE, new EnumIntPreference<AutoZoomMap>("auto_zoom_map_new", AutoZoomMap.NONE,
AutoZoomMap.values()).makeProfile().cache(); AutoZoomMap.values()).makeProfile().cache();
{ {
AUTO_ZOOM_MAP.setModeDefaultValue(ApplicationMode.CAR, AutoZoomMap.FARTHEST); AUTO_ZOOM_MAP.setModeDefaultValue(ApplicationMode.CAR, AutoZoomMap.FAR);
AUTO_ZOOM_MAP.setModeDefaultValue(ApplicationMode.BICYCLE, AutoZoomMap.NONE); AUTO_ZOOM_MAP.setModeDefaultValue(ApplicationMode.BICYCLE, AutoZoomMap.NONE);
AUTO_ZOOM_MAP.setModeDefaultValue(ApplicationMode.PEDESTRIAN, AutoZoomMap.NONE); AUTO_ZOOM_MAP.setModeDefaultValue(ApplicationMode.PEDESTRIAN, AutoZoomMap.NONE);
} }
@ -1869,16 +1869,18 @@ public class OsmandSettings {
} }
public enum AutoZoomMap { public enum AutoZoomMap {
NONE(R.string.auto_zoom_none, 0f), NONE(R.string.auto_zoom_none, 0f, 18),
FARTHEST(R.string.auto_zoom_farthest, 1f), FARTHEST(R.string.auto_zoom_farthest, 1f, 17f),
FAR(R.string.auto_zoom_far, 1.4f), FAR(R.string.auto_zoom_far, 1.4f, 18f),
CLOSE(R.string.auto_zoom_close, 2f) CLOSE(R.string.auto_zoom_close, 2f, 19f)
; ;
public final float coefficient; public final float coefficient;
public final int name; public final int name;
AutoZoomMap(int name, float coefficient) { public final float maxZoom;
AutoZoomMap(int name, float coefficient, float maxZoom) {
this.name = name; this.name = name;
this.coefficient = coefficient; this.coefficient = coefficient;
this.maxZoom = maxZoom;
} }
} }

View file

@ -23,7 +23,6 @@ import net.osmand.map.MapTileDownloader.DownloadRequest;
import net.osmand.map.MapTileDownloader.IMapDownloaderCallback; import net.osmand.map.MapTileDownloader.IMapDownloaderCallback;
import net.osmand.plus.ApplicationMode; import net.osmand.plus.ApplicationMode;
import net.osmand.plus.BusyIndicator; import net.osmand.plus.BusyIndicator;
import net.osmand.plus.DeviceAdminRecv;
import net.osmand.plus.OsmAndConstants; import net.osmand.plus.OsmAndConstants;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
@ -42,7 +41,6 @@ import net.osmand.plus.render.RendererRegistry;
import net.osmand.plus.resources.ResourceManager; import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.routing.RoutingHelper.RouteCalculationProgressCallback; import net.osmand.plus.routing.RoutingHelper.RouteCalculationProgressCallback;
import net.osmand.plus.routing.VoiceRouter;
import net.osmand.plus.views.AnimateDraggingMapThread; import net.osmand.plus.views.AnimateDraggingMapThread;
import net.osmand.plus.views.OsmAndMapLayersView; import net.osmand.plus.views.OsmAndMapLayersView;
import net.osmand.plus.views.OsmAndMapSurfaceView; import net.osmand.plus.views.OsmAndMapSurfaceView;
@ -56,19 +54,15 @@ import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.media.AudioManager; import android.media.AudioManager;
import android.net.Uri; import android.net.Uri;
import android.opengl.GLSurfaceView;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.PowerManager;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.Gravity; import android.view.Gravity;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -488,12 +482,18 @@ public class MapActivity extends AccessibleActivity {
// if (settings.AUTO_ZOOM_MAP.get() == AutoZoomMap.NONE) { // if (settings.AUTO_ZOOM_MAP.get() == AutoZoomMap.NONE) {
// changeLocation = false; // changeLocation = false;
// } // }
// double curZoom = mapView.getZoom() + mapView.getZoomFractionalPart() + stp * 0.3;
// int newZoom = (int) Math.round(curZoom);
// double zoomFrac = curZoom - newZoom;
final int newZoom = mapView.getZoom() + stp; final int newZoom = mapView.getZoom() + stp;
final double zoomFrac = mapView.getZoomFractionalPart();
if (newZoom > 22) { if (newZoom > 22) {
AccessibleToast.makeText(this, R.string.edit_tilesource_maxzoom, Toast.LENGTH_SHORT).show(); //$NON-NLS-1$ AccessibleToast.makeText(this, R.string.edit_tilesource_maxzoom, Toast.LENGTH_SHORT).show(); //$NON-NLS-1$
return; return;
} }
mapView.getAnimatedDraggingThread().startZooming(newZoom, changeLocation); mapView.getAnimatedDraggingThread().startZooming(newZoom, zoomFrac, changeLocation);
if (app.accessibilityEnabled()) if (app.accessibilityEnabled())
AccessibleToast.makeText(this, getString(R.string.zoomIs) + " " + newZoom, Toast.LENGTH_SHORT).show(); //$NON-NLS-1$ AccessibleToast.makeText(this, getString(R.string.zoomIs) + " " + newZoom, Toast.LENGTH_SHORT).show(); //$NON-NLS-1$
showAndHideMapPosition(); showAndHideMapPosition();

View file

@ -197,19 +197,19 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc
// decrease a bit // decrease a bit
zdelta += 1; zdelta += 1;
} }
double targetZoom = Math.max(tb.getZoom() + tb.getZoomFloatPart() + zdelta, settings.AUTO_ZOOM_MAP.get().maxZoom);
int threshold = settings.AUTO_FOLLOW_ROUTE.get(); int threshold = settings.AUTO_FOLLOW_ROUTE.get();
if (now - lastTimeAutoZooming > 4500 && (now - lastTimeAutoZooming > threshold || !isUserZoomed)) { if (now - lastTimeAutoZooming > 4500 && (now - lastTimeAutoZooming > threshold || !isUserZoomed)) {
isUserZoomed = false; isUserZoomed = false;
lastTimeAutoZooming = now; lastTimeAutoZooming = now;
double settingsZoomScale = Math.log(mapView.getSettingsMapDensity()) / Math.log(2.0f); // double settingsZoomScale = Math.log(mapView.getSettingsMapDensity()) / Math.log(2.0f);
double zoomScale = Math.log(tb.getMapDensity()) / Math.log(2.0f); // double zoomScale = Math.log(tb.getMapDensity()) / Math.log(2.0f);
double complexZoom = tb.getZoom() + zoomScale + zdelta; // double complexZoom = tb.getZoom() + zoomScale + zdelta;
// round to 0.33 // round to 0.33
double newZoom = Math.round((complexZoom - settingsZoomScale) * 3) / 3f; targetZoom = Math.round(targetZoom * 3) / 3f;
int newIntegerZoom = (int)Math.round(newZoom); int newIntegerZoom = (int)Math.round(targetZoom);
double nzscale = newZoom - newIntegerZoom + settingsZoomScale; double zPart = targetZoom - newIntegerZoom;
mapView.setComplexZoom(newIntegerZoom, Math.pow(2, nzscale)); mapView.getAnimatedDraggingThread().startZooming(newIntegerZoom, zPart, false);
// mapView.getAnimatedDraggingThread().startZooming(mapView.getFloatZoom() + zdelta, false);
} }
} }
} }

View file

@ -71,6 +71,11 @@ public class DashFavoritesFragment extends DashBaseFragment {
}); });
return view; return view;
} }
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override @Override
public void onResume() { public void onResume() {

View file

@ -4,7 +4,7 @@ import net.osmand.core.android.MapRendererView;
import net.osmand.core.android.TileSourceProxyProvider; import net.osmand.core.android.TileSourceProxyProvider;
import net.osmand.core.jni.MapLayerConfiguration; import net.osmand.core.jni.MapLayerConfiguration;
import net.osmand.core.jni.PointI; import net.osmand.core.jni.PointI;
import net.osmand.data.QuadPointDouble; import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.map.ITileSource; import net.osmand.map.ITileSource;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
@ -138,8 +138,8 @@ public class MapVectorLayer extends BaseMapLayer {
// opengl renderer // opengl renderer
mapRenderer.setTarget(new PointI(tilesRect.getCenter31X(), tilesRect.getCenter31Y())); mapRenderer.setTarget(new PointI(tilesRect.getCenter31X(), tilesRect.getCenter31Y()));
mapRenderer.setAzimuth(-tilesRect.getRotate()); mapRenderer.setAzimuth(-tilesRect.getRotate());
mapRenderer.setZoom((float) (tilesRect.getZoom() /* + tilesRect.getZoomScale() */+ tilesRect mapRenderer.setZoom((float) (tilesRect.getZoom() + tilesRect
.getZoomAnimation())); .getZoomAnimation() + tilesRect.getZoomFloatPart()));
} else { } else {
if (!view.isZooming()) { if (!view.isZooming()) {
if (resourceManager.updateRenderedMapNeeded(tilesRect, drawSettings)) { if (resourceManager.updateRenderedMapNeeded(tilesRect, drawSettings)) {
@ -163,16 +163,22 @@ public class MapVectorLayer extends BaseMapLayer {
boolean shown = false; boolean shown = false;
if (bmp != null && bmpLoc != null) { if (bmp != null && bmpLoc != null) {
float rot = -bmpLoc.getRotate(); float rot = -bmpLoc.getRotate();
int cz = currentViewport.getZoom();
canvas.rotate(rot, currentViewport.getCenterPixelX(), currentViewport.getCenterPixelY()); canvas.rotate(rot, currentViewport.getCenterPixelX(), currentViewport.getCenterPixelY());
final RotatedTileBox calc = currentViewport.copy(); final RotatedTileBox calc = currentViewport.copy();
calc.setRotate(bmpLoc.getRotate()); calc.setRotate(bmpLoc.getRotate());
QuadPointDouble lt = bmpLoc.getLeftTopTile(cz); // int cz = currentViewport.getZoom();
QuadPointDouble rb = bmpLoc.getRightBottomTile(cz); // QuadPointDouble lt = bmpLoc.getLeftTopTile(cz);
final float x1 = calc.getPixXFromTile(lt.x, lt.y, cz); // QuadPointDouble rb = bmpLoc.getRightBottomTile(cz);
final float x2 = calc.getPixXFromTile(rb.x, rb.y, cz); // final float x1 = calc.getPixXFromTile(lt.x, lt.y, cz);
final float y1 = calc.getPixYFromTile(lt.x, lt.y, cz); // final float x2 = calc.getPixXFromTile(rb.x, rb.y, cz);
final float y2 = calc.getPixYFromTile(rb.x, rb.y, cz); // final float y1 = calc.getPixYFromTile(lt.x, lt.y, cz);
// final float y2 = calc.getPixYFromTile(rb.x, rb.y, cz);
LatLon lt = bmpLoc.getLeftTopLatLon();
LatLon rb = bmpLoc.getRightBottomLatLon();
final float x1 = calc.getPixXFromLatLon(lt.getLatitude(), lt.getLongitude());
final float x2 = calc.getPixXFromLatLon(rb.getLatitude(), rb.getLongitude());
final float y1 = calc.getPixYFromLatLon(lt.getLatitude(), lt.getLongitude());
final float y2 = calc.getPixYFromLatLon(rb.getLatitude(), rb.getLongitude());
destImage.set(x1, y1, x2, y2); destImage.set(x1, y1, x2, y2);
if (!bmp.isRecycled()) { if (!bmp.isRecycled()) {
canvas.drawBitmap(bmp, null, destImage, paintImg); canvas.drawBitmap(bmp, null, destImage, paintImg);

View file

@ -8,8 +8,6 @@ import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator; import android.view.animation.LinearInterpolator;
@ -23,10 +21,10 @@ public class AnimateDraggingMapThread {
protected static final Log log = PlatformUtil.getLog(AnimateDraggingMapThread.class); protected static final Log log = PlatformUtil.getLog(AnimateDraggingMapThread.class);
private final static float DRAGGING_ANIMATION_TIME = 1200f; private final static float DRAGGING_ANIMATION_TIME = 1200f;
private final static float ZOOM_ANIMATION_TIME = 800f; private final static float ZOOM_ANIMATION_TIME = 500f;
private final static float ZOOM_MOVE_ANIMATION_TIME = 650f; private final static float ZOOM_MOVE_ANIMATION_TIME = 450f;
private final static float MOVE_MOVE_ANIMATION_TIME = 2000f; private final static float MOVE_MOVE_ANIMATION_TIME = 1300f;
private final static int DEFAULT_SLEEP_TO_REDRAW = 55; private final static int DEFAULT_SLEEP_TO_REDRAW = 15;
private volatile boolean stopped; private volatile boolean stopped;
private volatile Thread currentThread = null; private volatile Thread currentThread = null;
@ -36,6 +34,7 @@ public class AnimateDraggingMapThread {
private double targetLatitude = 0; private double targetLatitude = 0;
private double targetLongitude = 0; private double targetLongitude = 0;
private int targetIntZoom = 0; private int targetIntZoom = 0;
private int targetFloatZoom = 0;
private boolean isAnimatingZoom; private boolean isAnimatingZoom;
@ -120,11 +119,13 @@ public class AnimateDraggingMapThread {
public void startMoving(final double finalLat, final double finalLon, final int endZoom, final boolean notifyListener){ public void startMoving(final double finalLat, final double finalLon, final int endZoom, final boolean notifyListener){
stopAnimatingSync(); stopAnimatingSync();
double startLat = tileView.getLatitude();
double startLon = tileView.getLongitude();
float rotate = tileView.getRotate();
final int startZoom = tileView.getZoom();
final RotatedTileBox rb = tileView.getCurrentRotatedTileBox().copy(); final RotatedTileBox rb = tileView.getCurrentRotatedTileBox().copy();
double startLat = rb.getLatitude();
double startLon = rb.getLongitude();
float rotate = rb.getRotate();
final int startZoom = rb.getZoom();
final double startZoomFP = rb.getZoomFloatPart();
boolean skipAnimation = false; boolean skipAnimation = false;
float mStX = rb.getPixXFromLatLon(startLat, startLon) - rb.getPixXFromLatLon(finalLat, finalLon); float mStX = rb.getPixXFromLatLon(startLat, startLon) - rb.getPixXFromLatLon(finalLat, finalLon);
float mStY = rb.getPixYFromLatLon(startLat, startLon) - rb.getPixYFromLatLon(finalLat, finalLon); float mStY = rb.getPixYFromLatLon(startLat, startLon) - rb.getPixYFromLatLon(finalLat, finalLon);
@ -141,7 +142,7 @@ public class AnimateDraggingMapThread {
skipAnimation = skipAnimation || (Math.abs(moveZoom - startZoom) >= 3 || Math.abs(endZoom - moveZoom) > 3); skipAnimation = skipAnimation || (Math.abs(moveZoom - startZoom) >= 3 || Math.abs(endZoom - moveZoom) > 3);
if (skipAnimation) { if (skipAnimation) {
tileView.setLatLonAnimate(finalLat, finalLon, notifyListener); tileView.setLatLonAnimate(finalLat, finalLon, notifyListener);
tileView.setZoomAnimate(endZoom, notifyListener); tileView.setFractionalZoom(endZoom, 0, notifyListener);
return; return;
} }
final float mMoveX = rb.getPixXFromLatLon(startLat, startLon) - rb.getPixXFromLatLon(finalLat, finalLon); final float mMoveX = rb.getPixXFromLatLon(startLat, startLon) - rb.getPixXFromLatLon(finalLat, finalLon);
@ -155,7 +156,7 @@ public class AnimateDraggingMapThread {
public void run() { public void run() {
setTargetValues(endZoom, finalLat, finalLon); setTargetValues(endZoom, finalLat, finalLon);
if(moveZoom != startZoom){ if(moveZoom != startZoom){
animatingZoomInThread(startZoom, moveZoom, ZOOM_MOVE_ANIMATION_TIME, notifyListener); animatingZoomInThread(startZoom, startZoomFP, moveZoom, startZoomFP,ZOOM_MOVE_ANIMATION_TIME, notifyListener);
} }
if(!stopped){ if(!stopped){
@ -165,10 +166,10 @@ public class AnimateDraggingMapThread {
tileView.setLatLonAnimate(finalLat, finalLon, notifyListener); tileView.setLatLonAnimate(finalLat, finalLon, notifyListener);
} }
if (!stopped && moveZoom != endZoom) { if (!stopped && (moveZoom != endZoom || startZoomFP != 0)) {
animatingZoomInThread(moveZoom, endZoom, ZOOM_MOVE_ANIMATION_TIME, notifyListener); animatingZoomInThread(moveZoom, startZoomFP, endZoom, 0, ZOOM_MOVE_ANIMATION_TIME, notifyListener);
} }
tileView.setZoomAnimate(endZoom, notifyListener); tileView.setFractionalZoom(endZoom, 0, notifyListener);
pendingRotateAnimation(); pendingRotateAnimation();
} }
@ -203,12 +204,17 @@ public class AnimateDraggingMapThread {
} }
private void animatingZoomInThread(double zoomStart, int zoom, float animationTime, boolean notifyListener){ private void animatingZoomInThread(int zoomStart, double zoomFloatStart,
int zoomEnd, double zoomFloatEnd, float animationTime, boolean notifyListener){
try { try {
isAnimatingZoom = true; isAnimatingZoom = true;
double curZoom = zoomStart; // could be 0 ]-0.5,0.5], -1 ]-1,0], 1 ]0, 1]
double zoomEnd = (zoom /*+ zoomScale*/); int threshold = ((int)(zoomFloatEnd * 2));
animationTime *= Math.abs(zoomEnd - zoomStart); double beginZoom = zoomStart + zoomFloatStart;
double endZoom = zoomEnd + zoomFloatEnd;
double curZoom = beginZoom;
animationTime *= Math.abs(endZoom - beginZoom);
// AccelerateInterpolator interpolator = new AccelerateInterpolator(1); // AccelerateInterpolator interpolator = new AccelerateInterpolator(1);
LinearInterpolator interpolator = new LinearInterpolator(); LinearInterpolator interpolator = new LinearInterpolator();
@ -220,15 +226,17 @@ public class AnimateDraggingMapThread {
break; break;
} }
float interpolation = interpolator.getInterpolation(normalizedTime); float interpolation = interpolator.getInterpolation(normalizedTime);
curZoom = interpolation * (zoomEnd - zoomStart) + zoomStart; curZoom = interpolation * (endZoom - beginZoom) + beginZoom;
tileView.zoomToAnimate(curZoom, notifyListener); int baseZoom = (int) Math.round(curZoom - 0.5 * threshold);
double zaAnimate = curZoom - baseZoom;
tileView.zoomToAnimate(baseZoom, zaAnimate, notifyListener);
try { try {
Thread.sleep(DEFAULT_SLEEP_TO_REDRAW); Thread.sleep(DEFAULT_SLEEP_TO_REDRAW);
} catch (InterruptedException e) { } catch (InterruptedException e) {
stopped = true; stopped = true;
} }
} }
tileView.setZoomAnimate(zoom, notifyListener); tileView.setFractionalZoom(zoomEnd, zoomFloatEnd, notifyListener);
} finally { } finally {
isAnimatingZoom = false; isAnimatingZoom = false;
} }
@ -238,14 +246,14 @@ public class AnimateDraggingMapThread {
return isAnimatingZoom; return isAnimatingZoom;
} }
public void startZooming(final int zoomEnd, final boolean notifyListener){ public void startZooming(final int zoomEnd, final double zoomPart, final boolean notifyListener){
final float animationTime = ZOOM_ANIMATION_TIME; final float animationTime = ZOOM_ANIMATION_TIME;
startThreadAnimating(new Runnable(){ startThreadAnimating(new Runnable(){
@Override @Override
public void run() { public void run() {
final double zoomStart = tileView.getZoom() ; RotatedTileBox tb = tileView.getCurrentRotatedTileBox();
setTargetValues(zoomEnd, tileView.getLatitude(), tileView.getLongitude()); setTargetValues(zoomEnd, tileView.getLatitude(), tileView.getLongitude());
animatingZoomInThread(zoomStart, zoomEnd, animationTime, notifyListener); animatingZoomInThread(tb.getZoom(), tb.getZoomFloatPart(), zoomEnd, zoomPart, animationTime, notifyListener);
pendingRotateAnimation(); pendingRotateAnimation();
} }
}); //$NON-NLS-1$ }); //$NON-NLS-1$

View file

@ -164,7 +164,7 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
@Override @Override
public void onTwoFingerTap() { public void onTwoFingerTap() {
afterTwoFingerTap = true; afterTwoFingerTap = true;
getAnimatedDraggingThread().startZooming(getZoom()-1,true); getAnimatedDraggingThread().startZooming(getZoom() - 1, currentViewport.getZoomFloatPart(), true);
} }
}; };
@ -290,7 +290,7 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
public void setIntZoom(int zoom) { public void setIntZoom(int zoom) {
if (mainLayer != null && zoom <= mainLayer.getMaximumShownMapZoom() && zoom >= mainLayer.getMinimumShownMapZoom()) { if (mainLayer != null && zoom <= mainLayer.getMaximumShownMapZoom() && zoom >= mainLayer.getMinimumShownMapZoom()) {
animatedDraggingThread.stopAnimating(); animatedDraggingThread.stopAnimating();
currentViewport.setZoomAndAnimation(zoom, 0); currentViewport.setZoomAndAnimation(zoom, 0, 0);
currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0); currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0);
refreshMap(); refreshMap();
} }
@ -299,7 +299,7 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
public void setComplexZoom(int zoom, double mapDensity) { public void setComplexZoom(int zoom, double mapDensity) {
if (mainLayer != null && zoom <= mainLayer.getMaximumShownMapZoom() && zoom >= mainLayer.getMinimumShownMapZoom()) { if (mainLayer != null && zoom <= mainLayer.getMaximumShownMapZoom() && zoom >= mainLayer.getMinimumShownMapZoom()) {
animatedDraggingThread.stopAnimating(); animatedDraggingThread.stopAnimating();
currentViewport.setZoomWithAnimate(zoom, 0); currentViewport.setZoomAndAnimation(zoom, 0);
currentViewport.setMapDensity(mapDensity); currentViewport.setMapDensity(mapDensity);
currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0); currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0);
refreshMap(); refreshMap();
@ -350,6 +350,10 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
public int getZoom() { public int getZoom() {
return currentViewport.getZoom(); return currentViewport.getZoom();
} }
public double getZoomFractionalPart() {
return currentViewport.getZoomFloatPart();
}
public double getSettingsMapDensity() { public double getSettingsMapDensity() {
return (getSettings().MAP_DENSITY.get()) * Math.max(1, getDensity()); return (getSettings().MAP_DENSITY.get()) * Math.max(1, getDensity());
@ -385,7 +389,7 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
if (mainLayer.getMinimumShownMapZoom() > zoom) { if (mainLayer.getMinimumShownMapZoom() > zoom) {
zoom = mainLayer.getMinimumShownMapZoom(); zoom = mainLayer.getMinimumShownMapZoom();
} }
currentViewport.setZoomAndAnimation(zoom, 0); currentViewport.setZoomAndAnimation(zoom, 0, 0);
refreshMap(); refreshMap();
} }
@ -414,6 +418,12 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
final float x2 = calc.getPixXFromTile(rb.x, rb.y, cz); final float x2 = calc.getPixXFromTile(rb.x, rb.y, cz);
final float y1 = calc.getPixYFromTile(lt.x, lt.y, cz); final float y1 = calc.getPixYFromTile(lt.x, lt.y, cz);
final float y2 = calc.getPixYFromTile(rb.x, rb.y, cz); final float y2 = calc.getPixYFromTile(rb.x, rb.y, cz);
// LatLon lt = bufferImgLoc.getLeftTopLatLon();
// LatLon rb = bufferImgLoc.getRightBottomLatLon();
// final float x1 = calc.getPixXFromLatLon(lt.getLatitude(), lt.getLongitude());
// final float x2 = calc.getPixXFromLatLon(rb.getLatitude(), rb.getLongitude());
// final float y1 = calc.getPixYFromLatLon(lt.getLatitude(), lt.getLongitude());
// final float y2 = calc.getPixYFromLatLon(rb.getLatitude(), rb.getLongitude());
if (!bufferBitmap.isRecycled()) { if (!bufferBitmap.isRecycled()) {
RectF rct = new RectF(x1, y1, x2, y2); RectF rct = new RectF(x1, y1, x2, y2);
canvas.drawBitmap(bufferBitmap, null, rct, paintImg); canvas.drawBitmap(bufferBitmap, null, rct, paintImg);
@ -678,8 +688,8 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
} }
} }
protected void setZoomAnimate(int zoom, boolean notify) { protected void setFractionalZoom(int zoom, double zoomPart, boolean notify) {
currentViewport.setZoomWithAnimate(zoom, 0); currentViewport.setZoomAndAnimation(zoom, 0, zoomPart);
refreshMap(); refreshMap();
if (locationListener != null && notify) { if (locationListener != null && notify) {
locationListener.locationChanged(getLatitude(), getLongitude(), this); locationListener.locationChanged(getLatitude(), getLongitude(), this);
@ -687,17 +697,7 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
} }
// for internal usage // for internal usage
protected void zoomToAnimate(double tzoom, boolean notify) { protected void zoomToAnimate(int zoom, double zoomToAnimate, boolean notify) {
int zoom = getZoom();
double zoomToAnimate = tzoom - zoom;
if (zoomToAnimate >= 1) {
zoom += (int) zoomToAnimate;
zoomToAnimate -= (int) zoomToAnimate;
}
while (zoomToAnimate < 0) {
zoom--;
zoomToAnimate += 1;
}
if (mainLayer != null && mainLayer.getMaximumShownMapZoom() >= zoom && mainLayer.getMinimumShownMapZoom() <= zoom) { if (mainLayer != null && mainLayer.getMaximumShownMapZoom() >= zoom && mainLayer.getMinimumShownMapZoom() <= zoom) {
currentViewport.setZoomAndAnimation(zoom, zoomToAnimate); currentViewport.setZoomAndAnimation(zoom, zoomToAnimate);
currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0); currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0);
@ -866,13 +866,22 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
final RotatedTileBox calc = initialViewport.copy(); final RotatedTileBox calc = initialViewport.copy();
calc.setLatLonCenter(initialCenterLatLon.getLatitude(), initialCenterLatLon.getLongitude()); calc.setLatLonCenter(initialCenterLatLon.getLatitude(), initialCenterLatLon.getLongitude());
double calcZoom = initialViewport.getZoom() + dz ;
float calcRotate = calc.getRotate() + angle; float calcRotate = calc.getRotate() + angle;
calc.setRotate(calcRotate); calc.setRotate(calcRotate);
calc.setZoomAnimation(dz); calc.setZoomAndAnimation(initialViewport.getZoom(),
dz, initialViewport.getZoomFloatPart());
final LatLon r = calc.getLatLonFromPixel(cp.x + dx, cp.y + dy); final LatLon r = calc.getLatLonFromPixel(cp.x + dx, cp.y + dy);
setLatLon(r.getLatitude(), r.getLongitude()); setLatLon(r.getLatitude(), r.getLongitude());
zoomToAnimate((float) calcZoom, true); int baseZoom = initialViewport.getZoom();
while(initialViewport.getZoomFloatPart() + dz > 1) {
dz --;
baseZoom ++;
}
while(initialViewport.getZoomFloatPart() + dz < 0) {
dz ++;
baseZoom --;
}
zoomToAnimate(baseZoom, dz, true);
rotateToAnimate(calcRotate); rotateToAnimate(calcRotate);
} }