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",
// "-vrouting",
// "-vaddress", "-vcities", "-vstreets", "-vstreetgroups","-vbuildings",
//"-zoom=16",
// "-zoom=16",
// "-bbox=1.74,51.17,1.75,51.16",
"/home/victor/projects/osmand/osm-gen/Map.obf"
});

View file

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

View file

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

View file

@ -773,7 +773,7 @@ public class OsmandSettings {
new EnumIntPreference<AutoZoomMap>("auto_zoom_map_new", AutoZoomMap.NONE,
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.PEDESTRIAN, AutoZoomMap.NONE);
}
@ -1869,16 +1869,18 @@ public class OsmandSettings {
}
public enum AutoZoomMap {
NONE(R.string.auto_zoom_none, 0f),
FARTHEST(R.string.auto_zoom_farthest, 1f),
FAR(R.string.auto_zoom_far, 1.4f),
CLOSE(R.string.auto_zoom_close, 2f)
NONE(R.string.auto_zoom_none, 0f, 18),
FARTHEST(R.string.auto_zoom_farthest, 1f, 17f),
FAR(R.string.auto_zoom_far, 1.4f, 18f),
CLOSE(R.string.auto_zoom_close, 2f, 19f)
;
public final float coefficient;
public final int name;
AutoZoomMap(int name, float coefficient) {
public final float maxZoom;
AutoZoomMap(int name, float coefficient, float maxZoom) {
this.name = name;
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.plus.ApplicationMode;
import net.osmand.plus.BusyIndicator;
import net.osmand.plus.DeviceAdminRecv;
import net.osmand.plus.OsmAndConstants;
import net.osmand.plus.OsmandApplication;
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.routing.RoutingHelper;
import net.osmand.plus.routing.RoutingHelper.RouteCalculationProgressCallback;
import net.osmand.plus.routing.VoiceRouter;
import net.osmand.plus.views.AnimateDraggingMapThread;
import net.osmand.plus.views.OsmAndMapLayersView;
import net.osmand.plus.views.OsmAndMapSurfaceView;
@ -56,19 +54,15 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioManager;
import android.net.Uri;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.KeyEvent;
@ -488,12 +482,18 @@ public class MapActivity extends AccessibleActivity {
// if (settings.AUTO_ZOOM_MAP.get() == AutoZoomMap.NONE) {
// 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 double zoomFrac = mapView.getZoomFractionalPart();
if (newZoom > 22) {
AccessibleToast.makeText(this, R.string.edit_tilesource_maxzoom, Toast.LENGTH_SHORT).show(); //$NON-NLS-1$
return;
}
mapView.getAnimatedDraggingThread().startZooming(newZoom, changeLocation);
mapView.getAnimatedDraggingThread().startZooming(newZoom, zoomFrac, changeLocation);
if (app.accessibilityEnabled())
AccessibleToast.makeText(this, getString(R.string.zoomIs) + " " + newZoom, Toast.LENGTH_SHORT).show(); //$NON-NLS-1$
showAndHideMapPosition();

View file

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

View file

@ -71,6 +71,11 @@ public class DashFavoritesFragment extends DashBaseFragment {
});
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
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.jni.MapLayerConfiguration;
import net.osmand.core.jni.PointI;
import net.osmand.data.QuadPointDouble;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
import net.osmand.map.ITileSource;
import net.osmand.plus.OsmandSettings;
@ -138,8 +138,8 @@ public class MapVectorLayer extends BaseMapLayer {
// opengl renderer
mapRenderer.setTarget(new PointI(tilesRect.getCenter31X(), tilesRect.getCenter31Y()));
mapRenderer.setAzimuth(-tilesRect.getRotate());
mapRenderer.setZoom((float) (tilesRect.getZoom() /* + tilesRect.getZoomScale() */+ tilesRect
.getZoomAnimation()));
mapRenderer.setZoom((float) (tilesRect.getZoom() + tilesRect
.getZoomAnimation() + tilesRect.getZoomFloatPart()));
} else {
if (!view.isZooming()) {
if (resourceManager.updateRenderedMapNeeded(tilesRect, drawSettings)) {
@ -163,16 +163,22 @@ public class MapVectorLayer extends BaseMapLayer {
boolean shown = false;
if (bmp != null && bmpLoc != null) {
float rot = -bmpLoc.getRotate();
int cz = currentViewport.getZoom();
canvas.rotate(rot, currentViewport.getCenterPixelX(), currentViewport.getCenterPixelY());
final RotatedTileBox calc = currentViewport.copy();
calc.setRotate(bmpLoc.getRotate());
QuadPointDouble lt = bmpLoc.getLeftTopTile(cz);
QuadPointDouble rb = bmpLoc.getRightBottomTile(cz);
final float x1 = calc.getPixXFromTile(lt.x, lt.y, cz);
final float x2 = calc.getPixXFromTile(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);
// int cz = currentViewport.getZoom();
// QuadPointDouble lt = bmpLoc.getLeftTopTile(cz);
// QuadPointDouble rb = bmpLoc.getRightBottomTile(cz);
// final float x1 = calc.getPixXFromTile(lt.x, lt.y, cz);
// final float x2 = calc.getPixXFromTile(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);
if (!bmp.isRecycled()) {
canvas.drawBitmap(bmp, null, destImage, paintImg);

View file

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

View file

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