Modify rendering
This commit is contained in:
parent
2f29b642fa
commit
4b93b76341
7 changed files with 231 additions and 321 deletions
|
@ -13,7 +13,6 @@ public class ToDoConstants {
|
||||||
// Map Refactoring
|
// Map Refactoring
|
||||||
// || 124 || Animated transition using only raster images (?) - skip animations (!) - don not render vectoring for animations (Issue 238) ||
|
// || 124 || Animated transition using only raster images (?) - skip animations (!) - don not render vectoring for animations (Issue 238) ||
|
||||||
// Fix issue with min/max zoom
|
// Fix issue with min/max zoom
|
||||||
// Refactoring animation (no need source tile size?)
|
|
||||||
// Empty screen replace (?)
|
// Empty screen replace (?)
|
||||||
// Remove notification from OsmAndMapTileView (?)
|
// Remove notification from OsmAndMapTileView (?)
|
||||||
// Refactoring ResourceManager with cached images (tiles density)
|
// Refactoring ResourceManager with cached images (tiles density)
|
||||||
|
|
|
@ -358,18 +358,12 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeZoom(int newZoom){
|
public void changeZoom(int newZoom){
|
||||||
mapView.getAnimatedDraggingThread().stopAnimatingSync();
|
boolean changeLocation = settings.AUTO_ZOOM_MAP.get();
|
||||||
mapView.getAnimatedDraggingThread().startZooming(mapView.getZoom(), newZoom);
|
mapView.getAnimatedDraggingThread().startZooming(newZoom, changeLocation);
|
||||||
showAndHideMapPosition();
|
showAndHideMapPosition();
|
||||||
// user can preview map manually switch off auto zoom while user don't press back to location
|
|
||||||
if(settings.AUTO_ZOOM_MAP.get()){
|
|
||||||
locationChanged(mapView.getLatitude(), mapView.getLongitude(), null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -437,8 +431,17 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
||||||
dlg.dismiss();
|
dlg.dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
view.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
dlg.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
dlg.show();
|
dlg.show();
|
||||||
|
|
||||||
|
|
||||||
// Intent newIntent = new Intent(MapActivity.this, MainMenuActivity.class);
|
// Intent newIntent = new Intent(MapActivity.this, MainMenuActivity.class);
|
||||||
//newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
//newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
// startActivity(newIntent);
|
// startActivity(newIntent);
|
||||||
|
@ -530,9 +533,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
||||||
Location lastKnownLocation = locationLayer.getLastKnownLocation();
|
Location lastKnownLocation = locationLayer.getLastKnownLocation();
|
||||||
AnimateDraggingMapThread thread = mapView.getAnimatedDraggingThread();
|
AnimateDraggingMapThread thread = mapView.getAnimatedDraggingThread();
|
||||||
int fZoom = mapView.getZoom() < 15 ? 15 : mapView.getZoom();
|
int fZoom = mapView.getZoom() < 15 ? 15 : mapView.getZoom();
|
||||||
thread.startMoving(mapView.getLatitude(), mapView.getLongitude(),
|
thread.startMoving( lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), fZoom, false);
|
||||||
lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), mapView.getZoom(), fZoom,
|
|
||||||
mapView.getSourceTileSize(), mapView.getRotate(), false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(locationLayer.getLastKnownLocation() == null){
|
if(locationLayer.getLastKnownLocation() == null){
|
||||||
|
@ -928,9 +929,8 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
||||||
LatLon cur = new LatLon(mapView.getLatitude(), mapView.getLongitude());
|
LatLon cur = new LatLon(mapView.getLatitude(), mapView.getLongitude());
|
||||||
LatLon latLon = settings.getAndClearMapLocationToShow();
|
LatLon latLon = settings.getAndClearMapLocationToShow();
|
||||||
if (latLon != null && !latLon.equals(cur)) {
|
if (latLon != null && !latLon.equals(cur)) {
|
||||||
mapView.getAnimatedDraggingThread().startMoving(cur.getLatitude(), cur.getLongitude(), latLon.getLatitude(),
|
mapView.getAnimatedDraggingThread().startMoving(latLon.getLatitude(),
|
||||||
latLon.getLongitude(), mapView.getZoom(), settings.getMapZoomToShow(), mapView.getSourceTileSize(),
|
latLon.getLongitude(), settings.getMapZoomToShow(), true);
|
||||||
mapView.getRotate(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -134,8 +134,7 @@ public class NavigatePointActivity extends Activity {
|
||||||
// in case when it is dialog
|
// in case when it is dialog
|
||||||
if(activity != null) {
|
if(activity != null) {
|
||||||
OsmandMapTileView v = activity.getMapView();
|
OsmandMapTileView v = activity.getMapView();
|
||||||
activity.getMapView().getAnimatedDraggingThread().startMoving(v.getLatitude(), v.getLongitude(),
|
v.getAnimatedDraggingThread().startMoving(lat, lon, v.getZoom(), true);
|
||||||
lat, lon, v.getZoom(), v.getZoom(), v.getSourceTileSize(), v.getRotate(), true);
|
|
||||||
} else {
|
} else {
|
||||||
OsmandSettings.getOsmandSettings(this).setMapLocationToShow(lat, lon, MessageFormat.format(getString(R.string.search_history_navigate_to), lat, lon));
|
OsmandSettings.getOsmandSettings(this).setMapLocationToShow(lat, lon, MessageFormat.format(getString(R.string.search_history_navigate_to), lat, lon));
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,173 +16,37 @@ import android.view.animation.LinearInterpolator;
|
||||||
* Thread for animated dragging.
|
* Thread for animated dragging.
|
||||||
* Defines accelerator to stop dragging screen.
|
* Defines accelerator to stop dragging screen.
|
||||||
*/
|
*/
|
||||||
public class AnimateDraggingMapThread implements Runnable {
|
public class AnimateDraggingMapThread {
|
||||||
|
|
||||||
protected static final Log log = LogUtil.getLog(AnimateDraggingMapThread.class);
|
protected static final Log log = LogUtil.getLog(AnimateDraggingMapThread.class);
|
||||||
|
|
||||||
public interface AnimateDraggingCallback {
|
|
||||||
|
|
||||||
public void dragTo(float curX, float curY, float newX, float newY, boolean notify);
|
|
||||||
|
|
||||||
public void setLatLon(double latitude, double longitude, boolean notify);
|
|
||||||
|
|
||||||
public void zoomTo(float zoom, boolean notify);
|
|
||||||
|
|
||||||
public void rotateTo(float rotate);
|
|
||||||
|
|
||||||
public float getRotate();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static float DRAGGING_ANIMATION_TIME = 1900f;
|
private final static float DRAGGING_ANIMATION_TIME = 1900f;
|
||||||
private final static float ZOOM_ANIMATION_TIME = 800f;
|
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 = 1300f;
|
||||||
private final static int DEFAULT_SLEEP_TO_REDRAW = 55;
|
private final static int DEFAULT_SLEEP_TO_REDRAW = 55;
|
||||||
|
|
||||||
private volatile boolean stopped;
|
private volatile boolean stopped;
|
||||||
private volatile Thread currentThread = null;
|
private volatile Thread currentThread = null;
|
||||||
private AnimateDraggingCallback callback = null;
|
private final OsmandMapTileView tileView;
|
||||||
private boolean notifyListener;
|
|
||||||
|
|
||||||
private float targetRotate = 0;
|
private float targetRotate = 0;
|
||||||
|
|
||||||
|
|
||||||
private boolean animateDrag = true;
|
|
||||||
private float curX;
|
|
||||||
private float curY;
|
|
||||||
private float vx;
|
|
||||||
private float vy;
|
|
||||||
private float ax;
|
|
||||||
private float ay;
|
|
||||||
private byte dirX;
|
|
||||||
private byte dirY;
|
|
||||||
private final float a = 0.0014f;
|
|
||||||
|
|
||||||
private long time;
|
|
||||||
|
|
||||||
|
|
||||||
// 0 - zoom out, 1 - moving, 2 - zoom in
|
|
||||||
private byte phaseOfMoving ;
|
|
||||||
private int endZ;
|
|
||||||
private byte dirZ;
|
|
||||||
private int intZ;
|
|
||||||
private byte dirIntZ;
|
|
||||||
private float curZ;
|
|
||||||
private int timeZEnd;
|
|
||||||
private int timeZInt;
|
|
||||||
private int timeMove;
|
|
||||||
private float moveX;
|
|
||||||
private float moveY;
|
|
||||||
private double moveLat;
|
|
||||||
private double moveLon;
|
|
||||||
|
|
||||||
|
|
||||||
private double targetLatitude = 0;
|
private double targetLatitude = 0;
|
||||||
private double targetLongitude = 0;
|
private double targetLongitude = 0;
|
||||||
private int targetZoom = 0;
|
private int targetZoom = 0;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
currentThread = Thread.currentThread();
|
|
||||||
AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator();
|
|
||||||
try {
|
|
||||||
|
|
||||||
boolean conditionToCountinue = true;
|
public AnimateDraggingMapThread(OsmandMapTileView tileView){
|
||||||
while (!stopped && conditionToCountinue) {
|
this.tileView = tileView;
|
||||||
// calculate sleep
|
|
||||||
long sleep = 0;
|
|
||||||
if(animateDrag){
|
|
||||||
// sleep = (long) (40d / (Math.max(vx, vy) + 0.45));
|
|
||||||
sleep = 80;
|
|
||||||
} else {
|
|
||||||
sleep = 80;
|
|
||||||
}
|
|
||||||
Thread.sleep(sleep);
|
|
||||||
long curT = System.currentTimeMillis();
|
|
||||||
int dt = (int) (curT - time);
|
|
||||||
float newX = animateDrag && vx > 0 ? curX + dirX * vx * dt : curX;
|
|
||||||
float newY = animateDrag && vy > 0 ? curY + dirY * vy * dt : curY;
|
|
||||||
|
|
||||||
float newZ = curZ;
|
|
||||||
if(!animateDrag){
|
|
||||||
if (phaseOfMoving == 0 || phaseOfMoving == 2) {
|
|
||||||
byte dir = phaseOfMoving == 2 ? dirZ : dirIntZ;
|
|
||||||
int time = phaseOfMoving == 2 ? timeZEnd : timeZInt;
|
|
||||||
float end = phaseOfMoving == 2 ? endZ : intZ;
|
|
||||||
if (time > 0) {
|
|
||||||
newZ = newZ + dir * (float) dt / time;
|
|
||||||
}
|
|
||||||
if (dir > 0 == newZ > end) {
|
|
||||||
newZ = end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(timeMove > 0){
|
|
||||||
newX = newX + moveX * (float) dt / timeMove;
|
|
||||||
newY = newY + moveY * (float) dt / timeMove;
|
|
||||||
|
|
||||||
if(moveX > 0 == newX > moveX){
|
|
||||||
newX = moveX;
|
|
||||||
}
|
|
||||||
if(moveY > 0 == newY > moveY){
|
|
||||||
newY = moveY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!stopped && callback != null) {
|
|
||||||
if (animateDrag || phaseOfMoving == 1) {
|
|
||||||
callback.dragTo(curX, curY, newX, newY, notifyListener);
|
|
||||||
} else {
|
|
||||||
callback.zoomTo(newZ, notifyListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
time = curT;
|
|
||||||
if(animateDrag){
|
|
||||||
vx -= ax * dt;
|
|
||||||
vy -= ay * dt;
|
|
||||||
curX = newX;
|
|
||||||
curY = newY;
|
|
||||||
conditionToCountinue = vx > 0.5 || vy > 0.5;
|
|
||||||
} else {
|
|
||||||
if(phaseOfMoving == 0){
|
|
||||||
curZ = newZ;
|
|
||||||
if(curZ == intZ){
|
|
||||||
curX = 0;
|
|
||||||
curY = 0;
|
|
||||||
phaseOfMoving ++;
|
|
||||||
}
|
|
||||||
} else if(phaseOfMoving == 2){
|
|
||||||
curZ = newZ;
|
|
||||||
conditionToCountinue = curZ != endZ;
|
|
||||||
} else {
|
|
||||||
curX = newX;
|
|
||||||
curY = newY;
|
|
||||||
if(curX == moveX && curY == moveY){
|
|
||||||
phaseOfMoving ++;
|
|
||||||
callback.setLatLon(moveLat, moveLon, notifyListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(curZ != ((int) Math.round(curZ))){
|
|
||||||
if(Math.abs(curZ - endZ) > 3){
|
|
||||||
callback.zoomTo(Math.round(curZ), notifyListener);
|
|
||||||
} else {
|
|
||||||
callback.zoomTo(endZ, notifyListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//rotate after animation
|
|
||||||
pendingRotateAnimation();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
}
|
|
||||||
currentThread = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void pendingRotateAnimation() throws InterruptedException{
|
|
||||||
|
private void pendingRotateAnimation() throws InterruptedException {
|
||||||
boolean conditionToCountinue = true;
|
boolean conditionToCountinue = true;
|
||||||
while (conditionToCountinue && callback != null) {
|
while (conditionToCountinue && !stopped) {
|
||||||
conditionToCountinue = false;
|
conditionToCountinue = false;
|
||||||
float rotationDiff = targetRotate - callback.getRotate();
|
float rotationDiff = targetRotate - tileView.getRotate();
|
||||||
if (Math.abs((rotationDiff + 360) % 360) < Math.abs((rotationDiff - 360) % 360)) {
|
if (Math.abs((rotationDiff + 360) % 360) < Math.abs((rotationDiff - 360) % 360)) {
|
||||||
rotationDiff = (rotationDiff + 360) % 360;
|
rotationDiff = (rotationDiff + 360) % 360;
|
||||||
} else {
|
} else {
|
||||||
|
@ -192,10 +56,10 @@ public class AnimateDraggingMapThread implements Runnable {
|
||||||
if (absDiff > 0) {
|
if (absDiff > 0) {
|
||||||
Thread.sleep(DEFAULT_SLEEP_TO_REDRAW);
|
Thread.sleep(DEFAULT_SLEEP_TO_REDRAW);
|
||||||
if (absDiff < 1) {
|
if (absDiff < 1) {
|
||||||
callback.rotateTo(targetRotate);
|
tileView.rotateToAnimate(targetRotate);
|
||||||
} else {
|
} else {
|
||||||
conditionToCountinue = true;
|
conditionToCountinue = true;
|
||||||
callback.rotateTo(((absDiff / 10) * Math.signum(rotationDiff) + callback.getRotate()) % 360);
|
tileView.rotateToAnimate(((absDiff / 10) * Math.signum(rotationDiff) + tileView.getRotate()) % 360);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,7 +74,7 @@ public class AnimateDraggingMapThread implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAnimating(){
|
public boolean isAnimating(){
|
||||||
return currentThread != null;
|
return currentThread != null && !stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -227,132 +91,179 @@ public class AnimateDraggingMapThread implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startMoving(double curLat, double curLon, double finalLat, double finalLon, int curZoom, int endZoom, int tileSize, float rotate, boolean notifyListener){
|
public void startThreadAnimating(final Runnable runnable){
|
||||||
stopAnimatingSync();
|
stopAnimatingSync();
|
||||||
targetLatitude = finalLat;
|
|
||||||
targetLongitude = finalLon;
|
|
||||||
targetZoom = endZoom;
|
|
||||||
|
|
||||||
this.notifyListener = notifyListener;
|
|
||||||
curZ = curZoom;
|
|
||||||
intZ = curZoom;
|
|
||||||
float mX = (float) ((MapUtils.getTileNumberX(intZ, curLon) - MapUtils.getTileNumberX(intZ, finalLon)) * tileSize);
|
|
||||||
float mY = (float) ((MapUtils.getTileNumberY(intZ, curLat) - MapUtils.getTileNumberY(intZ, finalLat)) * tileSize);
|
|
||||||
while (Math.abs(mX) + Math.abs(mY) > 1200 && intZ > 4) {
|
|
||||||
intZ--;
|
|
||||||
mX = (float) ((MapUtils.getTileNumberX(intZ, curLon) - MapUtils.getTileNumberX(intZ, finalLon)) * tileSize);
|
|
||||||
mY = (float) ((MapUtils.getTileNumberY(intZ, curLat) - MapUtils.getTileNumberY(intZ, finalLat)) * tileSize);
|
|
||||||
}
|
|
||||||
float rad = (float) Math.toRadians(rotate);
|
|
||||||
moveX = FloatMath.cos(rad) * mX - FloatMath.sin(rad) * mY;
|
|
||||||
moveY = FloatMath.sin(rad) * mX + FloatMath.cos(rad) * mY;
|
|
||||||
moveLat = finalLat;
|
|
||||||
moveLon = finalLon;
|
|
||||||
if(curZoom < intZ){
|
|
||||||
dirIntZ = 1;
|
|
||||||
} else {
|
|
||||||
dirIntZ = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(intZ < endZoom){
|
|
||||||
dirZ = 1;
|
|
||||||
} else {
|
|
||||||
dirZ = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
endZ = endZoom;
|
|
||||||
|
|
||||||
// timeZInt = Math.abs(curZoom - intZ) * 300;
|
|
||||||
// if (timeZInt > 900) {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
timeZInt = 600;
|
|
||||||
timeZEnd = 500;
|
|
||||||
timeMove = (int) (Math.abs(moveX) + Math.abs(moveY) * 3);
|
|
||||||
if(timeMove > 2200){
|
|
||||||
timeMove = 2200;
|
|
||||||
}
|
|
||||||
animateDrag = false;
|
|
||||||
phaseOfMoving = (byte) (intZ == curZoom ? 1 : 0);
|
|
||||||
curX = 0;
|
|
||||||
curY = 0;
|
|
||||||
|
|
||||||
|
|
||||||
time = System.currentTimeMillis();
|
|
||||||
stopped = false;
|
stopped = false;
|
||||||
Thread thread = new Thread(this,"Animatable dragging"); //$NON-NLS-1$
|
currentThread = new Thread(new Runnable() {
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void startZooming(final int zoomStart, final int zoomEnd){
|
|
||||||
stopAnimatingSync();
|
|
||||||
|
|
||||||
stopped = false;
|
|
||||||
final boolean notifyListener = true;
|
|
||||||
final float animationTime = ZOOM_ANIMATION_TIME;
|
|
||||||
|
|
||||||
Thread thread = new Thread(new Runnable(){
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
currentThread = Thread.currentThread();
|
try {
|
||||||
float curZoom = zoomStart;
|
runnable.run();
|
||||||
AccelerateInterpolator interpolator = new AccelerateInterpolator(1);
|
} finally {
|
||||||
|
currentThread = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "Animating Thread");
|
||||||
|
currentThread.start();
|
||||||
|
|
||||||
long timeMillis = SystemClock.uptimeMillis();
|
}
|
||||||
float normalizedTime = 0f;
|
|
||||||
while(!stopped){
|
public void startMoving(final double finalLat, final double finalLon, final int endZoom, final boolean notifyListener){
|
||||||
normalizedTime = (SystemClock.uptimeMillis() - timeMillis) / animationTime;
|
stopAnimatingSync();
|
||||||
if(normalizedTime > 1f){
|
|
||||||
break;
|
double startLat = tileView.getLatitude();
|
||||||
}
|
double startLon = tileView.getLongitude();
|
||||||
float interpolation = interpolator.getInterpolation(normalizedTime);
|
float rotate = tileView.getRotate();
|
||||||
curZoom = interpolation * (zoomEnd - zoomStart) + zoomStart;
|
final int startZoom = tileView.getZoom();
|
||||||
callback.zoomTo(curZoom, notifyListener);
|
int tileSize = tileView.getSourceTileSize();
|
||||||
try {
|
|
||||||
Thread.sleep(DEFAULT_SLEEP_TO_REDRAW);
|
|
||||||
} catch (InterruptedException e) {
|
int mZoom = startZoom;
|
||||||
stopped = true;
|
boolean skipAnimation = false;
|
||||||
}
|
float mStX = (float) ((MapUtils.getTileNumberX(mZoom, startLon) - MapUtils.getTileNumberX(mZoom, finalLon)) * tileSize);
|
||||||
|
float mStY = (float) ((MapUtils.getTileNumberY(mZoom, startLat) - MapUtils.getTileNumberY(mZoom, finalLat)) * tileSize);
|
||||||
|
while (Math.abs(mStX) + Math.abs(mStY) > 1200) {
|
||||||
|
mZoom--;
|
||||||
|
if(mZoom <= 4){
|
||||||
|
skipAnimation = true;
|
||||||
|
}
|
||||||
|
mStX = (float) ((MapUtils.getTileNumberX(mZoom, startLon) - MapUtils.getTileNumberX(mZoom, finalLon)) * tileSize);
|
||||||
|
mStY = (float) ((MapUtils.getTileNumberY(mZoom, startLat) - MapUtils.getTileNumberY(mZoom, finalLat)) * tileSize);
|
||||||
|
}
|
||||||
|
final int moveZoom = mZoom;
|
||||||
|
// check if animation needed
|
||||||
|
skipAnimation = skipAnimation || (Math.abs(moveZoom - startZoom) >= 3 || Math.abs(endZoom - moveZoom) > 3);
|
||||||
|
if (skipAnimation) {
|
||||||
|
tileView.setLatLonAnimate(finalLat, finalLon, notifyListener);
|
||||||
|
tileView.zoomToAnimate(endZoom, notifyListener);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float rad = (float) Math.toRadians(rotate);
|
||||||
|
final float mMoveX = FloatMath.cos(rad) * mStX - FloatMath.sin(rad) * mStY;
|
||||||
|
final float mMoveY = FloatMath.sin(rad) * mStX + FloatMath.cos(rad) * mStY;
|
||||||
|
|
||||||
|
startThreadAnimating(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
setTargetValues(endZoom, finalLat, finalLon);
|
||||||
|
if(moveZoom != startZoom){
|
||||||
|
animatingZoomInThread(startZoom, moveZoom, ZOOM_MOVE_ANIMATION_TIME, notifyListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(curZoom != ((int) Math.round(curZoom))){
|
if(!stopped){
|
||||||
if(Math.abs(curZoom - zoomEnd) > 2){
|
animatingMoveInThread(mMoveX, mMoveY, MOVE_MOVE_ANIMATION_TIME, notifyListener);
|
||||||
if(zoomStart > zoomEnd){
|
|
||||||
curZoom = (float) Math.floor(curZoom);
|
|
||||||
} else {
|
|
||||||
curZoom = (float) Math.ceil(curZoom);
|
|
||||||
}
|
|
||||||
callback.zoomTo(curZoom, notifyListener);
|
|
||||||
} else {
|
|
||||||
callback.zoomTo(zoomEnd, notifyListener);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if(!stopped){
|
||||||
|
tileView.setLatLonAnimate(finalLat, finalLon, notifyListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stopped && moveZoom != endZoom) {
|
||||||
|
animatingZoomInThread(moveZoom, endZoom, ZOOM_MOVE_ANIMATION_TIME, notifyListener);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pendingRotateAnimation();
|
pendingRotateAnimation();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
}
|
}
|
||||||
currentThread = null;
|
|
||||||
}
|
}
|
||||||
},"Animatable zooming"); //$NON-NLS-1$
|
});
|
||||||
thread.start();
|
}
|
||||||
|
|
||||||
|
private void animatingMoveInThread(float moveX, float moveY, float animationTime,
|
||||||
|
boolean notify){
|
||||||
|
AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator();
|
||||||
|
|
||||||
|
float cX = 0;
|
||||||
|
float cY = 0;
|
||||||
|
long timeMillis = SystemClock.uptimeMillis();
|
||||||
|
float normalizedTime = 0f;
|
||||||
|
while(!stopped){
|
||||||
|
normalizedTime = (SystemClock.uptimeMillis() - timeMillis) / animationTime;
|
||||||
|
if(normalizedTime > 1f){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
float interpolation = interpolator.getInterpolation(normalizedTime);
|
||||||
|
float nX = interpolation * moveX;
|
||||||
|
float nY = interpolation * moveY;
|
||||||
|
tileView.dragToAnimate(cX, cY, nX, nY, notify);
|
||||||
|
cX = nX;
|
||||||
|
cY = nY;
|
||||||
|
try {
|
||||||
|
Thread.sleep(DEFAULT_SLEEP_TO_REDRAW);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
stopped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void animatingZoomInThread(int zoomStart, int zoomEnd, float animationTime, boolean notifyListener){
|
||||||
|
float curZoom = zoomStart;
|
||||||
|
// AccelerateInterpolator interpolator = new AccelerateInterpolator(1);
|
||||||
|
LinearInterpolator interpolator = new LinearInterpolator();
|
||||||
|
|
||||||
|
long timeMillis = SystemClock.uptimeMillis();
|
||||||
|
float normalizedTime = 0f;
|
||||||
|
while(!stopped){
|
||||||
|
normalizedTime = (SystemClock.uptimeMillis() - timeMillis) / animationTime;
|
||||||
|
if(normalizedTime > 1f){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
float interpolation = interpolator.getInterpolation(normalizedTime);
|
||||||
|
curZoom = interpolation * (zoomEnd - zoomStart) + zoomStart;
|
||||||
|
tileView.zoomToAnimate(curZoom, notifyListener);
|
||||||
|
try {
|
||||||
|
Thread.sleep(DEFAULT_SLEEP_TO_REDRAW);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
stopped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(curZoom != ((int) Math.round(curZoom))){
|
||||||
|
if(Math.abs(curZoom - zoomEnd) > 2){
|
||||||
|
if(zoomStart > zoomEnd){
|
||||||
|
curZoom = (float) Math.floor(curZoom);
|
||||||
|
} else {
|
||||||
|
curZoom = (float) Math.ceil(curZoom);
|
||||||
|
}
|
||||||
|
tileView.zoomToAnimate(curZoom, notifyListener);
|
||||||
|
} else {
|
||||||
|
tileView.zoomToAnimate(zoomEnd, notifyListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void startZooming(final int zoomEnd, final boolean notifyListener){
|
||||||
|
final float animationTime = ZOOM_ANIMATION_TIME;
|
||||||
|
final int zoomStart = tileView.getZoom();
|
||||||
|
|
||||||
|
startThreadAnimating(new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
setTargetValues(zoomEnd, tileView.getLatitude(), tileView.getLongitude());
|
||||||
|
animatingZoomInThread(zoomStart, zoomEnd, animationTime, notifyListener);
|
||||||
|
try {
|
||||||
|
pendingRotateAnimation();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void startDragging(final float velocityX, final float velocityY, float startX, float startY,
|
public void startDragging(final float velocityX, final float velocityY, float startX, float startY,
|
||||||
final float endX, final float endY){
|
final float endX, final float endY, final boolean notifyListener){
|
||||||
stopAnimatingSync();
|
|
||||||
this.notifyListener = true;
|
|
||||||
stopped = false;
|
|
||||||
final float animationTime = DRAGGING_ANIMATION_TIME;
|
final float animationTime = DRAGGING_ANIMATION_TIME;
|
||||||
|
clearTargetValues();
|
||||||
Thread thread = new Thread(new Runnable(){
|
startThreadAnimating(new Runnable(){
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
currentThread = Thread.currentThread();
|
|
||||||
float curX = endX;
|
float curX = endX;
|
||||||
float curY = endY;
|
float curY = endY;
|
||||||
|
|
||||||
DecelerateInterpolator interpolator = new DecelerateInterpolator(1);
|
DecelerateInterpolator interpolator = new DecelerateInterpolator(1);
|
||||||
|
|
||||||
long timeMillis = SystemClock.uptimeMillis();
|
long timeMillis = SystemClock.uptimeMillis();
|
||||||
|
@ -368,7 +279,7 @@ public class AnimateDraggingMapThread implements Runnable {
|
||||||
float newX = velocityX * (1 - interpolation) * (normalizedTime - prevNormalizedTime) + curX;
|
float newX = velocityX * (1 - interpolation) * (normalizedTime - prevNormalizedTime) + curX;
|
||||||
float newY = velocityY * (1 - interpolation) * (normalizedTime - prevNormalizedTime) + curY;
|
float newY = velocityY * (1 - interpolation) * (normalizedTime - prevNormalizedTime) + curY;
|
||||||
|
|
||||||
callback.dragTo(curX, curY, newX, newY, notifyListener);
|
tileView.dragToAnimate(curX, curY, newX, newY, notifyListener);
|
||||||
curX = newX;
|
curX = newX;
|
||||||
curY = newY;
|
curY = newY;
|
||||||
prevNormalizedTime = normalizedTime;
|
prevNormalizedTime = normalizedTime;
|
||||||
|
@ -382,20 +293,38 @@ public class AnimateDraggingMapThread implements Runnable {
|
||||||
pendingRotateAnimation();
|
pendingRotateAnimation();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
}
|
}
|
||||||
currentThread = null;
|
|
||||||
}
|
}
|
||||||
},"Animatable dragging"); //$NON-NLS-1$
|
}); //$NON-NLS-1$
|
||||||
thread.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startRotate(float rotate) {
|
private void clearTargetValues(){
|
||||||
this.targetRotate = rotate;
|
targetZoom = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTargetValues(int zoom, double lat, double lon){
|
||||||
|
targetZoom = zoom;
|
||||||
|
targetLatitude = lat;
|
||||||
|
targetLongitude = lon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startRotate(final float rotate) {
|
||||||
if (!isAnimating()) {
|
if (!isAnimating()) {
|
||||||
|
clearTargetValues();
|
||||||
// stopped = false;
|
// stopped = false;
|
||||||
// do we need to kill and recreate the thread? wait would be enough as now it
|
// do we need to kill and recreate the thread? wait would be enough as now it
|
||||||
// also handles the rotation?
|
// also handles the rotation?
|
||||||
Thread thread = new Thread(this, "Animatable dragging"); //$NON-NLS-1$
|
startThreadAnimating(new Runnable() {
|
||||||
thread.start();
|
@Override
|
||||||
|
public void run() {
|
||||||
|
targetRotate = rotate;
|
||||||
|
try {
|
||||||
|
pendingRotateAnimation();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.targetRotate = rotate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,12 +340,5 @@ public class AnimateDraggingMapThread implements Runnable {
|
||||||
return targetLongitude;
|
return targetLongitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnimateDraggingCallback getCallback() {
|
|
||||||
return callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCallback(AnimateDraggingCallback callback) {
|
|
||||||
this.callback = callback;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -439,8 +439,8 @@ public class MapInfoLayer implements OsmandMapLayer {
|
||||||
LatLon pointToNavigate = view.getSettings().getPointToNavigate();
|
LatLon pointToNavigate = view.getSettings().getPointToNavigate();
|
||||||
if(pointToNavigate != null){
|
if(pointToNavigate != null){
|
||||||
int fZoom = view.getZoom() < 15 ? 15 : view.getZoom();
|
int fZoom = view.getZoom() < 15 ? 15 : view.getZoom();
|
||||||
thread.startMoving(view.getLatitude(), view.getLongitude(), pointToNavigate.getLatitude(), pointToNavigate.getLongitude(),
|
thread.startMoving(pointToNavigate.getLatitude(), pointToNavigate.getLongitude(),
|
||||||
view.getZoom(), fZoom, view.getSourceTileSize(), view.getRotate(), true);
|
fZoom, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -15,7 +15,6 @@ import net.osmand.osm.LatLon;
|
||||||
import net.osmand.osm.MapUtils;
|
import net.osmand.osm.MapUtils;
|
||||||
import net.osmand.plus.OsmandSettings;
|
import net.osmand.plus.OsmandSettings;
|
||||||
import net.osmand.plus.activities.OsmandApplication;
|
import net.osmand.plus.activities.OsmandApplication;
|
||||||
import net.osmand.plus.views.AnimateDraggingMapThread.AnimateDraggingCallback;
|
|
||||||
import net.osmand.plus.views.MultiTouchSupport.MultiTouchZoomListener;
|
import net.osmand.plus.views.MultiTouchSupport.MultiTouchZoomListener;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@ -42,7 +41,7 @@ import android.view.GestureDetector.OnDoubleTapListener;
|
||||||
import android.view.GestureDetector.OnGestureListener;
|
import android.view.GestureDetector.OnGestureListener;
|
||||||
import android.view.SurfaceHolder.Callback;
|
import android.view.SurfaceHolder.Callback;
|
||||||
|
|
||||||
public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCallback, Callback, AnimateDraggingCallback {
|
public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCallback, Callback {
|
||||||
|
|
||||||
|
|
||||||
protected final int emptyTileDivisor = 16;
|
protected final int emptyTileDivisor = 16;
|
||||||
|
@ -157,8 +156,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
getHolder().addCallback(this);
|
getHolder().addCallback(this);
|
||||||
|
|
||||||
animatedDraggingThread = new AnimateDraggingMapThread();
|
animatedDraggingThread = new AnimateDraggingMapThread(this);
|
||||||
animatedDraggingThread.setCallback(this);
|
|
||||||
gestureDetector = new GestureDetector(getContext(), new MapTileViewOnGestureListener());
|
gestureDetector = new GestureDetector(getContext(), new MapTileViewOnGestureListener());
|
||||||
multiTouchSupport = new MultiTouchSupport(getContext(), new MapTileViewMultiTouchZoomListener());
|
multiTouchSupport = new MultiTouchSupport(getContext(), new MapTileViewMultiTouchZoomListener());
|
||||||
gestureDetector.setOnDoubleTapListener(new MapTileViewOnDoubleTapListener());
|
gestureDetector.setOnDoubleTapListener(new MapTileViewOnDoubleTapListener());
|
||||||
|
@ -257,17 +255,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for internal usage
|
|
||||||
@Override
|
|
||||||
public void zoomTo(float zoom, boolean notify) {
|
|
||||||
if (mainLayer != null && mainLayer.getMaximumShownMapZoom() >= zoom && mainLayer.getMinimumShownMapZoom() <= zoom) {
|
|
||||||
this.zoom = zoom;
|
|
||||||
refreshMap();
|
|
||||||
if (notify && locationListener != null) {
|
|
||||||
locationListener.locationChanged(latitude, longitude, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRotate(float rotate) {
|
public void setRotate(float rotate) {
|
||||||
float diff = rotate-this.rotate;
|
float diff = rotate-this.rotate;
|
||||||
|
@ -596,8 +584,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected void dragToAnimate(float fromX, float fromY, float toX, float toY, boolean notify) {
|
||||||
public void dragTo(float fromX, float fromY, float toX, float toY, boolean notify) {
|
|
||||||
float dx = (fromX - toX);
|
float dx = (fromX - toX);
|
||||||
float dy = (fromY - toY);
|
float dy = (fromY - toY);
|
||||||
moveTo(dx, dy);
|
moveTo(dx, dy);
|
||||||
|
@ -606,8 +593,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected void rotateToAnimate(float rotate) {
|
||||||
public void rotateTo(float rotate) {
|
|
||||||
this.rotate = rotate;
|
this.rotate = rotate;
|
||||||
float rotateRad = (float) Math.toRadians(rotate);
|
float rotateRad = (float) Math.toRadians(rotate);
|
||||||
this.rotateCos = FloatMath.cos(rotateRad);
|
this.rotateCos = FloatMath.cos(rotateRad);
|
||||||
|
@ -615,15 +601,24 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
refreshMap();
|
refreshMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected void setLatLonAnimate(double latitude, double longitude, boolean notify) {
|
||||||
public void setLatLon(double latitude, double longitude, boolean notify) {
|
|
||||||
this.latitude = latitude;
|
this.latitude = latitude;
|
||||||
this.longitude = longitude;
|
this.longitude = longitude;
|
||||||
refreshMap();
|
refreshMap();
|
||||||
if (locationListener != null && notify) {
|
if (locationListener != null && notify) {
|
||||||
locationListener.locationChanged(latitude, longitude, this);
|
locationListener.locationChanged(latitude, longitude, this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for internal usage
|
||||||
|
protected void zoomToAnimate(float zoom, boolean notify) {
|
||||||
|
if (mainLayer != null && mainLayer.getMaximumShownMapZoom() >= zoom && mainLayer.getMinimumShownMapZoom() <= zoom) {
|
||||||
|
this.zoom = zoom;
|
||||||
|
refreshMap();
|
||||||
|
if (notify && locationListener != null) {
|
||||||
|
locationListener.locationChanged(latitude, longitude, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveTo(float dx, float dy) {
|
public void moveTo(float dx, float dy) {
|
||||||
|
@ -744,7 +739,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||||
if (Math.abs(e1.getX() - e2.getX()) + Math.abs(e1.getX() - e2.getX()) > 50 * dm.density) {
|
if (Math.abs(e1.getX() - e2.getX()) + Math.abs(e1.getX() - e2.getX()) > 50 * dm.density) {
|
||||||
animatedDraggingThread.startDragging(velocityX, velocityY,
|
animatedDraggingThread.startDragging(velocityX, velocityY,
|
||||||
e1.getX(), e1.getY(), e2.getX(), e2.getY());
|
e1.getX(), e1.getY(), e2.getX(), e2.getY(), true);
|
||||||
} else {
|
} else {
|
||||||
onScroll(e1, e2, e1.getX() - e2.getX(), e1.getY() - e2.getY());
|
onScroll(e1, e2, e1.getX() - e2.getX(), e1.getY() - e2.getY());
|
||||||
}
|
}
|
||||||
|
@ -772,7 +767,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||||
dragTo(e2.getX() + distanceX, e2.getY() + distanceY, e2.getX(), e2.getY(), true);
|
dragToAnimate(e2.getX() + distanceX, e2.getY() + distanceY, e2.getX(), e2.getY(), true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,8 +798,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
@Override
|
@Override
|
||||||
public boolean onDoubleTap(MotionEvent e) {
|
public boolean onDoubleTap(MotionEvent e) {
|
||||||
LatLon l = getLatLonFromScreenPoint(e.getX(), e.getY());
|
LatLon l = getLatLonFromScreenPoint(e.getX(), e.getY());
|
||||||
getAnimatedDraggingThread().startMoving(getLatitude(), getLongitude(), l.getLatitude(), l.getLongitude(), getZoom(),
|
getAnimatedDraggingThread().startMoving(l.getLatitude(), l.getLongitude(), getZoom() + 1, true);
|
||||||
getZoom() + 1, getSourceTileSize(), getRotate(), true);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,9 +76,7 @@ public class RouteInfoLayer implements OsmandMapLayer, IRouteInformationListener
|
||||||
textView.setText(info.descriptionRoute);
|
textView.setText(info.descriptionRoute);
|
||||||
textView.layout(0, 0, textSize, (int) ((textView.getPaint().getTextSize()+4) * textView.getLineCount()));
|
textView.layout(0, 0, textSize, (int) ((textView.getPaint().getTextSize()+4) * textView.getLineCount()));
|
||||||
}
|
}
|
||||||
view.getAnimatedDraggingThread().startMoving(view.getLatitude(), view.getLongitude(),
|
view.getAnimatedDraggingThread().startMoving(l.getLatitude(), l.getLongitude(), view.getZoom(), true);
|
||||||
l.getLatitude(), l.getLongitude(),
|
|
||||||
view.getZoom(), view.getZoom(), view.getSourceTileSize(), view.getRotate(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -98,9 +96,7 @@ public class RouteInfoLayer implements OsmandMapLayer, IRouteInformationListener
|
||||||
textView.setText(info.descriptionRoute);
|
textView.setText(info.descriptionRoute);
|
||||||
textView.layout(0, 0, textSize, (int) ((textView.getPaint().getTextSize() + 4) * textView.getLineCount()));
|
textView.layout(0, 0, textSize, (int) ((textView.getPaint().getTextSize() + 4) * textView.getLineCount()));
|
||||||
}
|
}
|
||||||
view.getAnimatedDraggingThread().startMoving(view.getLatitude(), view.getLongitude(),
|
view.getAnimatedDraggingThread().startMoving(l.getLatitude(), l.getLongitude(), view.getZoom(), true);
|
||||||
l.getLatitude(), l.getLongitude(),
|
|
||||||
view.getZoom(), view.getZoom(), view.getSourceTileSize(), view.getRotate(), true);
|
|
||||||
}
|
}
|
||||||
view.refreshMap();
|
view.refreshMap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue