add first multitouch suppor
git-svn-id: https://osmand.googlecode.com/svn/trunk@314 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
7089997b81
commit
03569b29cb
8 changed files with 222 additions and 152 deletions
|
@ -19,7 +19,8 @@ public class ToDoConstants {
|
||||||
// 60. Audio guidance for routing !
|
// 60. Audio guidance for routing !
|
||||||
// 68. Implement service to app work with screen offline
|
// 68. Implement service to app work with screen offline
|
||||||
// (introduce special settings how often update location to monitoring & audio guidance)
|
// (introduce special settings how often update location to monitoring & audio guidance)
|
||||||
// 69. Multitouch zoom
|
// 69. Multitouch zoom, animated zoom, animate map shift!
|
||||||
|
// check everywhere float zoom
|
||||||
// Improvement : Show stops in the transport route on the map
|
// Improvement : Show stops in the transport route on the map
|
||||||
|
|
||||||
// Not clear if it is really needed
|
// Not clear if it is really needed
|
||||||
|
|
|
@ -279,13 +279,8 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onLongPressEvent(PointF point) {
|
public boolean onLongPressEvent(PointF point) {
|
||||||
float dx = point.x - mapView.getCenterPointX();
|
LatLon l = mapView.getLatLonFromScreenPoint(point.x, point.y);
|
||||||
float dy = point.y - mapView.getCenterPointY();
|
contextMenuPoint(l.getLatitude(), l.getLongitude(), false);
|
||||||
float fy = mapView.calcDiffTileY(dx, dy);
|
|
||||||
float fx = mapView.calcDiffTileX(dx, dy);
|
|
||||||
double latitude = MapUtils.getLatitudeFromTile(mapView.getZoom(), mapView.getYTile() + fy);
|
|
||||||
double longitude = MapUtils.getLongitudeFromTile(mapView.getZoom(), mapView.getXTile() + fx);
|
|
||||||
contextMenuPoint(latitude, longitude, false);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,11 +303,8 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
||||||
if(event.getAction() == MotionEvent.ACTION_MOVE){
|
if(event.getAction() == MotionEvent.ACTION_MOVE){
|
||||||
float x = event.getX();
|
float x = event.getX();
|
||||||
float y = event.getY();
|
float y = event.getY();
|
||||||
x = (float) (MapUtils.getTileNumberX(mapView.getZoom() , mapView.getLongitude()) + x / 3);
|
LatLon l = mapView.getLatLonFromScreenPoint(mapView.getCenterPointX() + x * 15, mapView.getCenterPointY() + y * 15);
|
||||||
y = (float) (MapUtils.getTileNumberY(mapView.getZoom(), mapView.getLatitude()) + y / 3);
|
setMapLocation(l.getLatitude(), l.getLongitude());
|
||||||
double lat = MapUtils.getLatitudeFromTile(mapView.getZoom(), y);
|
|
||||||
double lon = MapUtils.getLongitudeFromTile(mapView.getZoom(), x);
|
|
||||||
setMapLocation(lat, lon);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return super.onTrackballEvent(event);
|
return super.onTrackballEvent(event);
|
||||||
|
|
|
@ -7,6 +7,7 @@ package com.osmand.views;
|
||||||
public class AnimateDraggingMapThread implements Runnable {
|
public class AnimateDraggingMapThread implements Runnable {
|
||||||
public interface AnimateDraggingCallback {
|
public interface AnimateDraggingCallback {
|
||||||
public void dragTo(float curX, float curY, float newX, float newY);
|
public void dragTo(float curX, float curY, float newX, float newY);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private float curX;
|
private float curX;
|
||||||
|
|
114
OsmAnd/src/com/osmand/views/MultiTouchSupport.java
Normal file
114
OsmAnd/src/com/osmand/views/MultiTouchSupport.java
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
package com.osmand.views;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.FloatMath;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import com.osmand.LogUtil;
|
||||||
|
|
||||||
|
public class MultiTouchSupport {
|
||||||
|
|
||||||
|
private static final Log log = LogUtil.getLog(MultiTouchSupport.class);
|
||||||
|
|
||||||
|
public static final int ACTION_MASK = 255;
|
||||||
|
public static final int ACTION_POINTER_ID_SHIFT = 8;
|
||||||
|
public static final int ACTION_POINTER_DOWN = 5;
|
||||||
|
public static final int ACTION_POINTER_UP = 6;
|
||||||
|
|
||||||
|
public interface MultiTouchZoomListener {
|
||||||
|
|
||||||
|
public void onZoomStarted(float distance);
|
||||||
|
|
||||||
|
public void onZooming(float distance, float relativeToStart);
|
||||||
|
|
||||||
|
public void onZoomEnded(float distance, float relativeToStart);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean multiTouchAPISupported = false;
|
||||||
|
private final MultiTouchZoomListener listener;
|
||||||
|
protected final Context ctx;
|
||||||
|
|
||||||
|
protected Method getPointerCount;
|
||||||
|
protected Method getX;
|
||||||
|
protected Method getY;
|
||||||
|
protected Method getPointerId;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public MultiTouchSupport(Context ctx, MultiTouchZoomListener listener){
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.listener = listener;
|
||||||
|
initMethods();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMultiTouchSupported(){
|
||||||
|
return multiTouchAPISupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInZoomMode(){
|
||||||
|
return inZoomMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initMethods(){
|
||||||
|
try {
|
||||||
|
getPointerCount = MotionEvent.class.getMethod("getPointerCount"); //$NON-NLS-1$
|
||||||
|
getPointerId = MotionEvent.class.getMethod("getPointerId", Integer.TYPE); //$NON-NLS-1$
|
||||||
|
getX = MotionEvent.class.getMethod("getX", Integer.TYPE); //$NON-NLS-1$
|
||||||
|
getY = MotionEvent.class.getMethod("getY", Integer.TYPE); //$NON-NLS-1$
|
||||||
|
multiTouchAPISupported = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
multiTouchAPISupported = false;
|
||||||
|
log.info("Multi touch not supported", e); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean inZoomMode = false;
|
||||||
|
private float zoomStartedDistance = 100;
|
||||||
|
private float previousZoom = 1;
|
||||||
|
|
||||||
|
public boolean onTouchEvent(MotionEvent event){
|
||||||
|
if(!isMultiTouchSupported()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int actionCode = event.getAction() & ACTION_MASK;
|
||||||
|
try {
|
||||||
|
Integer pointCount = (Integer) getPointerCount.invoke(event);
|
||||||
|
if(pointCount < 2){
|
||||||
|
if(inZoomMode){
|
||||||
|
listener.onZoomEnded(zoomStartedDistance * previousZoom, previousZoom);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Float x1 = (Float) getX.invoke(event, 0);
|
||||||
|
Float x2 = (Float) getX.invoke(event, 1);
|
||||||
|
Float y1 = (Float) getY.invoke(event, 0);
|
||||||
|
Float y2 = (Float) getY.invoke(event, 1);
|
||||||
|
float distance = FloatMath.sqrt((x2 - x1)*(x2 -x1) + (y2-y1)*(y2-y1));
|
||||||
|
previousZoom = distance / zoomStartedDistance;
|
||||||
|
if (actionCode == ACTION_POINTER_DOWN) {
|
||||||
|
listener.onZoomStarted(distance);
|
||||||
|
zoomStartedDistance = distance;
|
||||||
|
inZoomMode = true;
|
||||||
|
return true;
|
||||||
|
} else if(actionCode == ACTION_POINTER_UP){
|
||||||
|
if(inZoomMode){
|
||||||
|
listener.onZoomEnded(distance, previousZoom);
|
||||||
|
inZoomMode = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else if(inZoomMode && actionCode == MotionEvent.ACTION_MOVE){
|
||||||
|
listener.onZooming(distance, previousZoom);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("Multi touch exception" , e); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,8 +3,6 @@ package com.osmand.views;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
@ -38,11 +36,13 @@ import com.osmand.data.preparation.MapTileDownloader.DownloadRequest;
|
||||||
import com.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback;
|
import com.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback;
|
||||||
import com.osmand.map.IMapLocationListener;
|
import com.osmand.map.IMapLocationListener;
|
||||||
import com.osmand.map.ITileSource;
|
import com.osmand.map.ITileSource;
|
||||||
|
import com.osmand.osm.LatLon;
|
||||||
import com.osmand.osm.MapUtils;
|
import com.osmand.osm.MapUtils;
|
||||||
import com.osmand.views.AnimateDraggingMapThread.AnimateDraggingCallback;
|
import com.osmand.views.AnimateDraggingMapThread.AnimateDraggingCallback;
|
||||||
|
import com.osmand.views.MultiTouchSupport.MultiTouchZoomListener;
|
||||||
|
|
||||||
public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCallback,
|
public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCallback,
|
||||||
Callback, AnimateDraggingCallback, OnGestureListener, OnDoubleTapListener {
|
Callback, AnimateDraggingCallback, OnGestureListener, OnDoubleTapListener, MultiTouchZoomListener {
|
||||||
|
|
||||||
protected final int emptyTileDivisor = 16;
|
protected final int emptyTileDivisor = 16;
|
||||||
protected final int timeForDraggingAnimation = 300;
|
protected final int timeForDraggingAnimation = 300;
|
||||||
|
@ -63,9 +63,10 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
protected static final Log log = LogUtil.getLog(OsmandMapTileView.class);
|
protected static final Log log = LogUtil.getLog(OsmandMapTileView.class);
|
||||||
/**
|
/**
|
||||||
* zoom level
|
* zoom level - could be float to show zoomed tiles
|
||||||
*/
|
*/
|
||||||
private int zoom = 3;
|
// TODO rotated zoom calculation check where it is could be needed???
|
||||||
|
private float zoom = 3;
|
||||||
|
|
||||||
private double longitude = 0d;
|
private double longitude = 0d;
|
||||||
|
|
||||||
|
@ -96,8 +97,12 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
private AnimateDraggingMapThread animatedDraggingThread;
|
private AnimateDraggingMapThread animatedDraggingThread;
|
||||||
|
|
||||||
|
private float initialMultiTouchZoom;
|
||||||
|
|
||||||
private GestureDetector gestureDetector;
|
private GestureDetector gestureDetector;
|
||||||
|
|
||||||
|
private MultiTouchSupport multiTouchSupport;
|
||||||
|
|
||||||
Paint paintGrayFill;
|
Paint paintGrayFill;
|
||||||
Paint paintWhiteFill;
|
Paint paintWhiteFill;
|
||||||
Paint paintCenter;
|
Paint paintCenter;
|
||||||
|
@ -146,6 +151,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
animatedDraggingThread = new AnimateDraggingMapThread();
|
animatedDraggingThread = new AnimateDraggingMapThread();
|
||||||
animatedDraggingThread.setCallback(this);
|
animatedDraggingThread.setCallback(this);
|
||||||
gestureDetector = new GestureDetector(getContext(), this);
|
gestureDetector = new GestureDetector(getContext(), this);
|
||||||
|
multiTouchSupport = new MultiTouchSupport(getContext(), this);
|
||||||
gestureDetector.setOnDoubleTapListener(this);
|
gestureDetector.setOnDoubleTapListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,8 +197,13 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////// NON UI PART (could be extracted in common) /////////////////////////////
|
/////////////////////////// NON UI PART (could be extracted in common) /////////////////////////////
|
||||||
public int getTileSize() {
|
public float getTileSize() {
|
||||||
return map == null ? 256 : map.getTileSize();
|
int tileSize = map == null ? 256 : map.getTileSize();
|
||||||
|
if(zoom == (int) zoom){
|
||||||
|
return tileSize;
|
||||||
|
}
|
||||||
|
float m = (float) Math.pow(2, zoom - (int) zoom);
|
||||||
|
return m * tileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,7 +216,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setZoom(int zoom){
|
public void setZoom(float zoom){
|
||||||
if (map == null || (map.getMaximumZoomSupported() >= zoom && map.getMinimumZoomSupported() <= zoom)) {
|
if (map == null || (map.getMaximumZoomSupported() >= zoom && map.getMinimumZoomSupported() <= zoom)) {
|
||||||
animatedDraggingThread.stopDragging();
|
animatedDraggingThread.stopDragging();
|
||||||
this.zoom = zoom;
|
this.zoom = zoom;
|
||||||
|
@ -266,9 +277,14 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getZoom() {
|
public int getZoom() {
|
||||||
|
return (int) zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFloatZoom(){
|
||||||
return zoom;
|
return zoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setMapLocationListener(IMapLocationListener l){
|
public void setMapLocationListener(IMapLocationListener l){
|
||||||
locationListener = l;
|
locationListener = l;
|
||||||
}
|
}
|
||||||
|
@ -284,10 +300,10 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
//////////////////////////////// DRAWING MAP PART /////////////////////////////////////////////
|
//////////////////////////////// DRAWING MAP PART /////////////////////////////////////////////
|
||||||
|
|
||||||
protected void drawEmptyTile(Canvas cvs, float x, float y){
|
protected void drawEmptyTile(Canvas cvs, float x, float y){
|
||||||
int tileDiv = getTileSize() / emptyTileDivisor;
|
int tileDiv = (int) (getTileSize() / emptyTileDivisor);
|
||||||
for (int k1 = 0; k1 < emptyTileDivisor; k1++) {
|
for (int k1 = 0; k1 < emptyTileDivisor; k1++) {
|
||||||
for (int k2 = 0; k2 < emptyTileDivisor; k2++) {
|
for (int k2 = 0; k2 < emptyTileDivisor; k2++) {
|
||||||
float xk = x + tileDiv* k1;
|
float xk = x + tileDiv* k1 ;
|
||||||
float yk = y + tileDiv* k2;
|
float yk = y + tileDiv* k2;
|
||||||
if ((k1 + k2) % 2 == 0) {
|
if ((k1 + k2) % 2 == 0) {
|
||||||
cvs.drawRect(xk, yk, xk + tileDiv, yk + tileDiv, paintGrayFill);
|
cvs.drawRect(xk, yk, xk + tileDiv, yk + tileDiv, paintGrayFill);
|
||||||
|
@ -378,7 +394,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
if (OsmandSettings.isUsingInternetToDownloadTiles(getContext())) {
|
if (OsmandSettings.isUsingInternetToDownloadTiles(getContext())) {
|
||||||
MapTileDownloader.getInstance().refuseAllPreviousRequests();
|
MapTileDownloader.getInstance().refuseAllPreviousRequests();
|
||||||
}
|
}
|
||||||
int tileSize = getTileSize();
|
float ftileSize = getTileSize();
|
||||||
|
int tileSize = map == null ? 256 : map.getTileSize();
|
||||||
float tileX = getXTile();
|
float tileX = getXTile();
|
||||||
float tileY = getYTile();
|
float tileY = getYTile();
|
||||||
float w = getCenterPointX();
|
float w = getCenterPointX();
|
||||||
|
@ -386,6 +403,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
SurfaceHolder holder = getHolder();
|
SurfaceHolder holder = getHolder();
|
||||||
synchronized (holder) {
|
synchronized (holder) {
|
||||||
|
int nzoom = (int) zoom;
|
||||||
Canvas canvas = holder.lockCanvas();
|
Canvas canvas = holder.lockCanvas();
|
||||||
if (canvas != null) {
|
if (canvas != null) {
|
||||||
ResourceManager mgr = ResourceManager.getResourceManager();
|
ResourceManager mgr = ResourceManager.getResourceManager();
|
||||||
|
@ -402,21 +420,21 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
int height = (int) (FloatMath.ceil(tilesRect.bottom) - top);
|
int height = (int) (FloatMath.ceil(tilesRect.bottom) - top);
|
||||||
for (int i = 0; i <width; i++) {
|
for (int i = 0; i <width; i++) {
|
||||||
for (int j = 0; j< height; j++) {
|
for (int j = 0; j< height; j++) {
|
||||||
float x1 = (i + left - tileX) * tileSize + w;
|
float x1 = (i + left - tileX) * ftileSize+ w;
|
||||||
float y1 = (j + top - tileY) * tileSize + h;
|
float y1 = (j + top - tileY) * ftileSize + h;
|
||||||
String ordImgTile = mgr.calculateTileId(map, left + i, top + j, zoom);
|
String ordImgTile = mgr.calculateTileId(map, left + i, top + j, nzoom);
|
||||||
// asking tile image async
|
// asking tile image async
|
||||||
boolean imgExist = mgr.tileExistOnFileSystem(ordImgTile);
|
boolean imgExist = mgr.tileExistOnFileSystem(ordImgTile);
|
||||||
Bitmap bmp = null;
|
Bitmap bmp = null;
|
||||||
boolean originalBeLoaded = useInternet && zoom <= maxLevel;
|
boolean originalBeLoaded = useInternet && nzoom <= maxLevel;
|
||||||
if (imgExist || originalBeLoaded) {
|
if (imgExist || originalBeLoaded) {
|
||||||
bmp = mgr.getTileImageForMapAsync(ordImgTile, map, left + i, top + j, zoom, useInternet);
|
bmp = mgr.getTileImageForMapAsync(ordImgTile, map, left + i, top + j, nzoom, useInternet);
|
||||||
}
|
}
|
||||||
if (bmp == null) {
|
if (bmp == null) {
|
||||||
int div = 2;
|
int div = 2;
|
||||||
// asking if there is small version of the map (in cache)
|
// asking if there is small version of the map (in cache)
|
||||||
String imgTile2 = mgr.calculateTileId(map, (left + i) / 2, (top + j) / 2, zoom - 1);
|
String imgTile2 = mgr.calculateTileId(map, (left + i) / 2, (top + j) / 2, nzoom - 1);
|
||||||
String imgTile4 = mgr.calculateTileId(map, (left + i) / 4, (top + j) / 4, zoom - 2);
|
String imgTile4 = mgr.calculateTileId(map, (left + i) / 4, (top + j) / 4, nzoom - 2);
|
||||||
if(originalBeLoaded || imgExist){
|
if(originalBeLoaded || imgExist){
|
||||||
bmp = mgr.getTileImageFromCache(imgTile2);
|
bmp = mgr.getTileImageFromCache(imgTile2);
|
||||||
div = 2;
|
div = 2;
|
||||||
|
@ -426,11 +444,11 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!originalBeLoaded && !imgExist){
|
if(!originalBeLoaded && !imgExist){
|
||||||
if (mgr.tileExistOnFileSystem(imgTile2) || (useInternet && zoom - 1 <= maxLevel)) {
|
if (mgr.tileExistOnFileSystem(imgTile2) || (useInternet && nzoom - 1 <= maxLevel)) {
|
||||||
bmp = mgr.getTileImageForMapAsync(imgTile2, map, (left + i) / 2, (top + j) / 2, zoom - 1, useInternet);
|
bmp = mgr.getTileImageForMapAsync(imgTile2, map, (left + i) / 2, (top + j) / 2, nzoom - 1, useInternet);
|
||||||
div = 2;
|
div = 2;
|
||||||
} else if (mgr.tileExistOnFileSystem(imgTile4) || (useInternet && zoom - 2 <= maxLevel)) {
|
} else if (mgr.tileExistOnFileSystem(imgTile4) || (useInternet && nzoom - 2 <= maxLevel)) {
|
||||||
bmp = mgr.getTileImageForMapAsync(imgTile4, map, (left + i) / 4, (top + j) / 4, zoom - 2, useInternet);
|
bmp = mgr.getTileImageForMapAsync(imgTile4, map, (left + i) / 4, (top + j) / 4, nzoom - 2, useInternet);
|
||||||
div = 4;
|
div = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,14 +459,20 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
int xZoom = ((left + i) % div) * tileSize / div;
|
int xZoom = ((left + i) % div) * tileSize / div;
|
||||||
int yZoom = ((top + j) % div) * tileSize / div;;
|
int yZoom = ((top + j) % div) * tileSize / div;;
|
||||||
bitmapToZoom.set(xZoom, yZoom, xZoom + tileSize / div, yZoom + tileSize / div);
|
bitmapToZoom.set(xZoom, yZoom, xZoom + tileSize / div, yZoom + tileSize / div);
|
||||||
bitmapToDraw.set(x1, y1, x1 + tileSize, y1 + tileSize);
|
bitmapToDraw.set(x1, y1, x1 + ftileSize, y1 + ftileSize);
|
||||||
canvas.drawBitmap(bmp, bitmapToZoom, bitmapToDraw, paintBitmap);
|
canvas.drawBitmap(bmp, bitmapToZoom, bitmapToDraw, paintBitmap);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if(zoom - nzoom != 0){
|
||||||
|
bitmapToZoom.set(0, 0, map.getTileSize(), map.getTileSize());
|
||||||
|
bitmapToDraw.set(x1, y1, x1 + ftileSize, y1 + ftileSize);
|
||||||
|
canvas.drawBitmap(bmp, bitmapToZoom, bitmapToDraw, paintBitmap);
|
||||||
} else {
|
} else {
|
||||||
canvas.drawBitmap(bmp, x1, y1, paintBitmap);
|
canvas.drawBitmap(bmp, x1, y1, paintBitmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
drawOverMap(canvas);
|
drawOverMap(canvas);
|
||||||
} finally {
|
} finally {
|
||||||
holder.unlockCanvasAndPost(canvas);
|
holder.unlockCanvasAndPost(canvas);
|
||||||
|
@ -531,22 +555,22 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
/////////////////////////////////// DRAGGING PART ///////////////////////////////////////
|
/////////////////////////////////// DRAGGING PART ///////////////////////////////////////
|
||||||
public float calcDiffTileY(float dx, float dy){
|
public float calcDiffTileY(float dx, float dy){
|
||||||
float rad = (float) Math.toRadians(rotate);
|
float rad = (float) Math.toRadians(rotate);
|
||||||
return (-FloatMath.sin(rad) * dx + FloatMath.cos(rad) * dy) / getTileSize();
|
return (-FloatMath.sin(rad) * dx + FloatMath.cos(rad) * dy) / (getTileSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public float calcDiffTileX(float dx, float dy){
|
public float calcDiffTileX(float dx, float dy){
|
||||||
float rad = (float) Math.toRadians(rotate);
|
float rad = (float) Math.toRadians(rotate);
|
||||||
return (FloatMath.cos(rad) * dx + FloatMath.sin(rad) * dy) / getTileSize();
|
return (FloatMath.cos(rad) * dx + FloatMath.sin(rad) * dy) / (getTileSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public float calcDiffPixelY(float dTileX, float dTileY){
|
public float calcDiffPixelY(float dTileX, float dTileY){
|
||||||
float rad = (float) Math.toRadians(rotate);
|
float rad = (float) Math.toRadians(rotate);
|
||||||
return (FloatMath.sin(rad) * dTileX + FloatMath.cos(rad) * dTileY) * getTileSize();
|
return (FloatMath.sin(rad) * dTileX + FloatMath.cos(rad) * dTileY) * getTileSize() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float calcDiffPixelX(float dTileX, float dTileY){
|
public float calcDiffPixelX(float dTileX, float dTileY){
|
||||||
float rad = (float) Math.toRadians(rotate);
|
float rad = (float) Math.toRadians(rotate);
|
||||||
return (FloatMath.cos(rad) * dTileX - FloatMath.sin(rad) * dTileY) * getTileSize();
|
return (FloatMath.cos(rad) * dTileX - FloatMath.sin(rad) * dTileY) * getTileSize() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -554,7 +578,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
*/
|
*/
|
||||||
public int getMapXForPoint(double longitude){
|
public int getMapXForPoint(double longitude){
|
||||||
double tileX = MapUtils.getTileNumberX(zoom, longitude);
|
double tileX = MapUtils.getTileNumberX(zoom, longitude);
|
||||||
return (int) ((tileX - getXTile()) * getTileSize() + getCenterPointX());
|
return (int) ((tileX - getXTile()) * getTileSize()+ getCenterPointX());
|
||||||
}
|
}
|
||||||
public int getMapYForPoint(double latitude){
|
public int getMapYForPoint(double latitude){
|
||||||
double tileY = MapUtils.getTileNumberY(zoom, latitude);
|
double tileY = MapUtils.getTileNumberY(zoom, latitude);
|
||||||
|
@ -606,87 +630,13 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
// checkMultiTouchEvent(event);
|
if(event.getAction() == MotionEvent.ACTION_DOWN){
|
||||||
/*return */ gestureDetector.onTouchEvent(event);
|
animatedDraggingThread.stopDragging();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
if (!multiTouchSupport.onTouchEvent(event)) {
|
||||||
private static Pattern x2Pattern = Pattern.compile("x2=([0-9]+)"); //$NON-NLS-1$
|
/* return */gestureDetector.onTouchEvent(event);
|
||||||
private static Pattern y2Pattern = Pattern.compile("y2=([0-9]+)"); //$NON-NLS-1$
|
|
||||||
private int lastX2 = 0;
|
|
||||||
private int lastY2 = 0;
|
|
||||||
private PointF mtStart = null;
|
|
||||||
private PointF mtStart2 = null;
|
|
||||||
private int mtZoom = 0;
|
|
||||||
private float mtDist = 0;
|
|
||||||
private boolean checkMultiTouchEvent(MotionEvent event) {
|
|
||||||
String str = event.toString();
|
|
||||||
Matcher m = x2Pattern.matcher(str);
|
|
||||||
// log.debug(str);
|
|
||||||
if(m.find()){
|
|
||||||
int x2= Integer.parseInt(m.group(1));
|
|
||||||
m = y2Pattern.matcher(str);
|
|
||||||
if(m.find()){
|
|
||||||
int y2= Integer.parseInt(m.group(1));
|
|
||||||
if (x2 != lastX2 && y2 != lastY2) {
|
|
||||||
float dx = x2 - event.getX();
|
|
||||||
float dy = y2 - event.getY();
|
|
||||||
float dist = FloatMath.sqrt(dx*dx+dy*dy);
|
|
||||||
if (dist > 0) {
|
|
||||||
if (mtStart == null) {
|
|
||||||
mtStart = new PointF(event.getX(), event.getY());
|
|
||||||
mtStart2 = new PointF(x2, y2);
|
|
||||||
mtZoom = zoom;
|
|
||||||
mtDist = dist;
|
|
||||||
log.debug("Multitouch dist="+mtDist);
|
|
||||||
} else {
|
|
||||||
if(dist < mtDist){
|
|
||||||
dist *= 0.6f;
|
|
||||||
} else {
|
|
||||||
dist *= 1.3f;
|
|
||||||
}
|
|
||||||
int dz = (int) (Math.log(dist/mtDist) / Math.log(2));
|
|
||||||
log.debug("Mt dist=" +dist);
|
|
||||||
if (mtZoom + dz != zoom) {
|
|
||||||
setZoom(mtZoom + dz);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastX2 = x2;
|
|
||||||
lastY2 = y2;
|
|
||||||
// log.debug("Multi touch x=" + event.getX() + " y=" + event.getY() + " x2=" + x2 + " y2=" + y2 + " dist="
|
|
||||||
// + dist +" mt="+mtDist);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if(event.getAction() == MotionEvent.ACTION_UP){
|
|
||||||
log.debug("UP");
|
|
||||||
mtStart = null;
|
|
||||||
mtStart2 = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mtStart != null;
|
|
||||||
// String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" ,
|
|
||||||
// "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" };
|
|
||||||
// StringBuilder sb = new StringBuilder();
|
|
||||||
// int action = event.getAction();
|
|
||||||
// int actionCode = action & 255;
|
|
||||||
// sb.append("event ACTION_" ).append(names[actionCode]);
|
|
||||||
// if (actionCode == 5
|
|
||||||
// || actionCode == 6) {
|
|
||||||
// sb.append("(pid " ).append(action >> 8);
|
|
||||||
// sb.append(")" );
|
|
||||||
// }
|
|
||||||
// sb.append("[" );
|
|
||||||
// for (int i = 0; i < event.getPointerCount(); i++) {
|
|
||||||
// sb.append("#" ).append(i);
|
|
||||||
// sb.append("(pid " ).append(event.getPointerId(i));
|
|
||||||
// sb.append(")=" ).append((int) event.getX(i));
|
|
||||||
// sb.append("," ).append((int) event.getY(i));
|
|
||||||
// if (i + 1 < event.getPointerCount())
|
|
||||||
// sb.append(";" );
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -726,17 +676,35 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
public void onZoomEnded(float distance, float relativeToStart) {
|
||||||
if(mtStart != null){
|
float dz = (float) (Math.log(relativeToStart) / Math.log(2) * 1.5);
|
||||||
return true;
|
initialMultiTouchZoom = (float) Math.round(initialMultiTouchZoom + dz);
|
||||||
|
setZoom(initialMultiTouchZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZoomStarted(float distance) {
|
||||||
|
initialMultiTouchZoom = zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZooming(float distance, float relativeToStart) {
|
||||||
|
float dz = (float) (Math.log(relativeToStart) / Math.log(2) * 1.5);
|
||||||
|
if(Math.abs(initialMultiTouchZoom + dz - zoom) > 0.05){
|
||||||
|
setZoom(initialMultiTouchZoom + dz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||||
animatedDraggingThread.startDragging(Math.abs(velocityX/1000), Math.abs(velocityY/1000), e1.getX(), e1.getY(), e2.getX(), e2.getY());
|
animatedDraggingThread.startDragging(Math.abs(velocityX/1000), Math.abs(velocityY/1000), e1.getX(), e1.getY(), e2.getX(), e2.getY());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLongPress(MotionEvent e) {
|
public void onLongPress(MotionEvent e) {
|
||||||
if(mtStart != null){
|
if(multiTouchSupport.isInZoomMode()){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(log.isDebugEnabled()){
|
if(log.isDebugEnabled()){
|
||||||
|
@ -753,13 +721,11 @@ 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) {
|
||||||
if(mtStart != null){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
dragTo(e2.getX() + distanceX, e2.getY() + distanceY, e2.getX(), e2.getY());
|
dragTo(e2.getX() + distanceX, e2.getY() + distanceY, e2.getX(), e2.getY());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,9 +735,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onSingleTapUp(MotionEvent e) {
|
public boolean onSingleTapUp(MotionEvent e) {
|
||||||
if(mtStart != null){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
PointF point = new PointF(e.getX(), e.getY());
|
PointF point = new PointF(e.getX(), e.getY());
|
||||||
if(log.isDebugEnabled()){
|
if(log.isDebugEnabled()){
|
||||||
log.debug("On click event "+ point.x + " " + point.y); //$NON-NLS-1$ //$NON-NLS-2$
|
log.debug("On click event "+ point.x + " " + point.y); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
@ -787,15 +750,22 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onDoubleTap(MotionEvent e) {
|
|
||||||
float dx = e.getX() - getCenterPointX();
|
public LatLon getLatLonFromScreenPoint(float x, float y){
|
||||||
float dy = e.getY() - getCenterPointY();
|
float dx = x - getCenterPointX();
|
||||||
|
float dy = y - getCenterPointY();
|
||||||
float fy = calcDiffTileY(dx, dy);
|
float fy = calcDiffTileY(dx, dy);
|
||||||
float fx = calcDiffTileX(dx, dy);
|
float fx = calcDiffTileX(dx, dy);
|
||||||
double latitude = MapUtils.getLatitudeFromTile(getZoom(), getYTile() + fy);
|
double latitude = MapUtils.getLatitudeFromTile(zoom, getYTile() + fy);
|
||||||
double longitude = MapUtils.getLongitudeFromTile(getZoom(), getXTile() + fx);
|
double longitude = MapUtils.getLongitudeFromTile(zoom, getXTile() + fx);
|
||||||
setLatLon(latitude, longitude);
|
return new LatLon(latitude, longitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onDoubleTap(MotionEvent e) {
|
||||||
|
LatLon l = getLatLonFromScreenPoint(e.getX(), e.getY());
|
||||||
|
setLatLon(l.getLatitude(), l.getLongitude());
|
||||||
setZoom(zoom + 1);
|
setZoom(zoom + 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,10 +109,6 @@ public class POIMapLayer implements OsmandMapLayer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTileSize(){
|
|
||||||
return view.getTileSize();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initLayer(OsmandMapTileView view) {
|
public void initLayer(OsmandMapTileView view) {
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class PointLocationLayer implements OsmandMapLayer {
|
||||||
if (isLocationVisible(lastKnownLocation)) {
|
if (isLocationVisible(lastKnownLocation)) {
|
||||||
int locationX = view.getMapXForPoint(lastKnownLocation.getLongitude());
|
int locationX = view.getMapXForPoint(lastKnownLocation.getLongitude());
|
||||||
int locationY = view.getMapYForPoint(lastKnownLocation.getLatitude());
|
int locationY = view.getMapYForPoint(lastKnownLocation.getLatitude());
|
||||||
int radius = MapUtils.getLengthXFromMeters(view.getZoom(), view.getLatitude(), view.getLongitude(), lastKnownLocation
|
int radius = MapUtils.getLengthXFromMeters(view.getFloatZoom(), view.getLatitude(), view.getLongitude(), lastKnownLocation
|
||||||
.getAccuracy(), view.getTileSize(), view.getWidth());
|
.getAccuracy(), view.getTileSize(), view.getWidth());
|
||||||
|
|
||||||
if(appMode == ApplicationMode.CAR){
|
if(appMode == ApplicationMode.CAR){
|
||||||
|
@ -105,7 +105,7 @@ public class PointLocationLayer implements OsmandMapLayer {
|
||||||
int radiusBearing = 30;
|
int radiusBearing = 30;
|
||||||
if(lastKnownLocation.hasSpeed()){
|
if(lastKnownLocation.hasSpeed()){
|
||||||
radiusBearing =
|
radiusBearing =
|
||||||
Math.max(MapUtils.getLengthXFromMeters(view.getZoom(), view.getLatitude(), view.getLongitude(),
|
Math.max(MapUtils.getLengthXFromMeters(view.getFloatZoom(), view.getLatitude(), view.getLongitude(),
|
||||||
lastKnownLocation.getSpeed(), view.getTileSize(), view.getWidth()) * 2, radiusBearing);
|
lastKnownLocation.getSpeed(), view.getTileSize(), view.getWidth()) * 2, radiusBearing);
|
||||||
}
|
}
|
||||||
radiusBearing += RADIUS /2;
|
radiusBearing += RADIUS /2;
|
||||||
|
|
|
@ -67,10 +67,6 @@ public class TransportStopsLayer implements OsmandMapLayer {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public int getTileSize(){
|
|
||||||
return view.getTileSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(PointF point) {
|
public boolean onTouchEvent(PointF point) {
|
||||||
|
|
Loading…
Reference in a new issue