From 2785a7a089263bd2cf89be8e75c3befa160e7689 Mon Sep 17 00:00:00 2001 From: Alexander Sytnyk Date: Mon, 12 Jun 2017 18:52:15 +0300 Subject: [PATCH] Add a measurement of the distance between the fingers --- .../osmand/plus/views/MultiTouchSupport.java | 8 +++ .../osmand/plus/views/OsmandMapTileView.java | 42 ++++++++++++ .../osmand/plus/views/RulerControlLayer.java | 21 ++++-- .../mapwidgets/MapInfoWidgetsFactory.java | 64 ++++++++++++------- 4 files changed, 108 insertions(+), 27 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/MultiTouchSupport.java b/OsmAnd/src/net/osmand/plus/views/MultiTouchSupport.java index e024eac2e4..dd95ca231b 100644 --- a/OsmAnd/src/net/osmand/plus/views/MultiTouchSupport.java +++ b/OsmAnd/src/net/osmand/plus/views/MultiTouchSupport.java @@ -33,6 +33,9 @@ public class MultiTouchSupport { public void onGestureInit(float x1, float y1, float x2, float y2); + public void onActionPointerDownOrMove(PointF first, PointF second); + + public void onActionPointerUp(); } private boolean multiTouchAPISupported = false; @@ -103,6 +106,11 @@ public class MultiTouchSupport { angleDefined = true; angle = (float) (Math.atan2(y2 - y1, x2 -x1) * 180 / Math.PI); } + if (actionCode == MotionEvent.ACTION_DOWN || actionCode == MotionEvent.ACTION_MOVE) { + listener.onActionPointerDownOrMove(new PointF(x1, y1), new PointF(x2, y2)); + } else if (actionCode == MotionEvent.ACTION_UP || actionCode == MotionEvent.ACTION_POINTER_UP) { + listener.onActionPointerUp(); + } if (actionCode == ACTION_POINTER_DOWN) { centerPoint = new PointF((x1 + x2) / 2, (y1 + y2) / 2); listener.onGestureInit(x1, y1, x2, y2); diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index e11149d17b..18603214bc 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -161,6 +161,11 @@ public class OsmandMapTileView implements IMapDownloaderCallback { private boolean afterDoubleTap = false; private boolean wasMapLinkedBeforeGesture = false; + private PointF firstPointer; + private PointF secondPointer; + private LatLon firstPointerLatLon; + private LatLon secondPointerLatLon; + public OsmandMapTileView(MapActivity activity, int w, int h) { this.activity = activity; init(activity, w, h); @@ -171,6 +176,11 @@ public class OsmandMapTileView implements IMapDownloaderCallback { application = (OsmandApplication) ctx.getApplicationContext(); settings = application.getSettings(); + firstPointer = new PointF(-1, -1); + secondPointer = new PointF(-1, -1); + firstPointerLatLon = new LatLon(-1, -1); + secondPointerLatLon = new LatLon(-1, -1); + paintGrayFill = new Paint(); paintGrayFill.setColor(Color.GRAY); paintGrayFill.setStyle(Style.FILL); @@ -305,6 +315,22 @@ public class OsmandMapTileView implements IMapDownloaderCallback { } // ///////////////////////// NON UI PART (could be extracted in common) ///////////////////////////// + public PointF getFirstPointer() { + return firstPointer; + } + + public PointF getSecondPointer() { + return secondPointer; + } + + public LatLon getFirstPointerLatLon() { + return firstPointerLatLon; + } + + public LatLon getSecondPointerLatLon() { + return secondPointerLatLon; + } + public void setIntZoom(int zoom) { zoom = zoom > getMaxZoom() ? getMaxZoom() : zoom; zoom = zoom < getMinZoom() ? getMinZoom() : zoom; @@ -1007,6 +1033,22 @@ public class OsmandMapTileView implements IMapDownloaderCallback { this.y1 = y1; this.x2 = x2; this.y2 = y2; + firstPointerLatLon = currentViewport.getLatLonFromPixel(x1, y1); + secondPointerLatLon = currentViewport.getLatLonFromPixel(x2, y2); + } + + @Override + public void onActionPointerDownOrMove(PointF first, PointF second) { + firstPointer.set(first); + secondPointer.set(second); + } + + @Override + public void onActionPointerUp() { + firstPointer.set(-1, -1); + secondPointer.set(-1, -1); + firstPointerLatLon = new LatLon(-1, -1); + secondPointerLatLon = new LatLon(-1, -1); } @Override diff --git a/OsmAnd/src/net/osmand/plus/views/RulerControlLayer.java b/OsmAnd/src/net/osmand/plus/views/RulerControlLayer.java index fab9def742..3f695833e5 100644 --- a/OsmAnd/src/net/osmand/plus/views/RulerControlLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/RulerControlLayer.java @@ -7,6 +7,7 @@ import android.graphics.Color; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.graphics.Paint.Style; +import android.graphics.PointF; import android.graphics.Rect; import net.osmand.Location; @@ -86,10 +87,16 @@ public class RulerControlLayer extends OsmandMapLayer { final RulerMode mode = app.getSettings().RULER_MODE.get(); if (mode == RulerMode.FIRST) { - drawCenterIcon(canvas, tb, center); - Location currentLoc = app.getLocationProvider().getLastKnownLocation(); - if (currentLoc != null) { - drawDistance(canvas, tb, center, currentLoc); + PointF firstFinger = view.getFirstPointer(); + PointF secondFinger = view.getSecondPointer(); + if (firstFinger.x != -1 && firstFinger.y != -1 && secondFinger.x != -1 && secondFinger.y != -1) { + drawFingerDistance(canvas, tb, center, firstFinger, secondFinger); + } else { + drawCenterIcon(canvas, tb, center); + Location currentLoc = app.getLocationProvider().getLastKnownLocation(); + if (currentLoc != null) { + drawDistance(canvas, tb, center, currentLoc); + } } } else if (mode == RulerMode.SECOND) { drawCenterIcon(canvas, tb, center); @@ -101,6 +108,12 @@ public class RulerControlLayer extends OsmandMapLayer { } } + private void drawFingerDistance(Canvas canvas, RotatedTileBox tb, QuadPoint center, PointF first, PointF second) { + canvas.rotate(-tb.getRotate(), center.x, center.y); + canvas.drawLine(first.x, first.y, second.x, second.y, distancePaint); + canvas.rotate(tb.getRotate(), center.x, center.y); + } + private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, QuadPoint center) { canvas.rotate(-tb.getRotate(), center.x, center.y); canvas.drawBitmap(centerIcon, center.x - centerIcon.getWidth() / 2, diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java index 2f394cb6f2..c0edf859bb 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java @@ -112,25 +112,43 @@ public class MapInfoWidgetsFactory { public TextInfoWidget createRulerControl(final MapActivity map) { final String title = map.getResources().getString(R.string.map_widget_show_ruler); - final TextInfoWidget rulerControl = new TextInfoWidget(map) { - @Override - public boolean updateInfo(DrawSettings drawSettings) { - if (map.getMyApplication().getSettings().RULER_MODE.get() == RulerMode.FIRST) { - Location currentLoc = map.getMyApplication().getLocationProvider().getLastKnownLocation(); - LatLon centerLoc = map.getMapLocation(); - if (currentLoc != null && centerLoc != null) { - float dist = (float) MapUtils.getDistance(currentLoc.getLatitude(), currentLoc.getLongitude(), - centerLoc.getLatitude(), centerLoc.getLongitude()); - String distance = OsmAndFormatter.getFormattedDistance(dist, map.getMyApplication()); - int ls = distance.lastIndexOf(' '); - setText(distance.substring(0, ls), distance.substring(ls + 1)); - } else { - setText(title, null); - } - } - return true; - } - }; + final TextInfoWidget rulerControl = new TextInfoWidget(map) { + LatLon cacheFirstFinger; + LatLon cacheSecondFinger; + + @Override + public boolean updateInfo(DrawSettings drawSettings) { + if (map.getMyApplication().getSettings().RULER_MODE.get() == RulerMode.FIRST) { + Location currentLoc = map.getMyApplication().getLocationProvider().getLastKnownLocation(); + LatLon centerLoc = map.getMapLocation(); + LatLon firstFinger = map.getMapView().getFirstPointerLatLon(); + LatLon secondFinger = map.getMapView().getSecondPointerLatLon(); + + if (firstFinger.getLatitude() != -1 && firstFinger.getLongitude() != -1 && + secondFinger.getLatitude() != -1 && secondFinger.getLongitude() != -1) { + if (cacheFirstFinger != firstFinger || cacheSecondFinger != secondFinger) { + cacheFirstFinger = firstFinger; + cacheSecondFinger = secondFinger; + setDistanceText(firstFinger.getLatitude(), firstFinger.getLongitude(), + secondFinger.getLatitude(), secondFinger.getLongitude()); + } + } else if (currentLoc != null && centerLoc != null) { + setDistanceText(currentLoc.getLatitude(), currentLoc.getLongitude(), + centerLoc.getLatitude(), centerLoc.getLongitude()); + } else { + setText(title, null); + } + } + return true; + } + + private void setDistanceText(double firstLat, double firstLon, double secondLat, double secondLon) { + float dist = (float) MapUtils.getDistance(firstLat, firstLon, secondLat, secondLon); + String distance = OsmAndFormatter.getFormattedDistance(dist, map.getMyApplication()); + int ls = distance.lastIndexOf(' '); + setText(distance.substring(0, ls), distance.substring(ls + 1)); + } + }; rulerControl.setText(title, null); rulerControl.setIcons(R.drawable.widget_distance_day, R.drawable.widget_distance_night); @@ -663,16 +681,16 @@ public class MapInfoWidgetsFactory { RouteDataObject rt = locationProvider.getLastKnownRouteSegment(); if (rt != null) { text = RoutingHelper.formatStreetName( - rt.getName(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get()), + rt.getName(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get()), rt.getRef(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get(), rt.bearingVsRouteDirection(locationProvider.getLastKnownLocation())), - rt.getDestinationName(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get(), rt.bearingVsRouteDirection(locationProvider.getLastKnownLocation())), + rt.getDestinationName(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get(), rt.bearingVsRouteDirection(locationProvider.getLastKnownLocation())), "ยป"); - } + } if (text == null) { text = ""; } else { if(!Algorithms.isEmpty(text) && locationProvider.getLastKnownLocation() != null) { - double dist = + double dist = CurrentPositionHelper.getOrthogonalDistance(rt, locationProvider.getLastKnownLocation()); if(dist < 50) { showMarker = true;