Search code examples
androidandroid-mapviewosmdroidtouch-eventpanning

Overriding osmdroid MapView’s Default Pan/move


I have mapView and I programatically handle the touch events.

The problem is: if the mapview is ZoomOut to its maximum, the panning is quite small and slow, and conforming the mapView is ZoomIn, the panning is bigger and faster. In another words: bigger the zoomIN bigger the panning movements.

How can I make panning moves not accordingly to zoom , so every time I move the map, it moves the same distance no matter the zoom level? or is there another way to override panning in mapview?

Here is my android Client

private double savedTouchedX = -1;
private double savedTouchedY = -1;
....

mapView.setOnTouchListener(new MapView.OnTouchListener() {

        @Override
        public boolean onTouch(View arg0, MotionEvent event) {
            int action = event.getAction();
            final Projection pj = mapView.getProjection();
            GeoPoint eventPosition = (GeoPoint) pj.fromPixels((int)event.getX(), (int)event.getY());

             switch(action)
             {
                case MotionEvent.ACTION_DOWN:
                    savedTouchedX = eventPosition.getLongitude();
                    savedTouchedY = eventPosition.getLatitude();
                    break;
                case MotionEvent.ACTION_MOVE:
                    doPanning(eventPosition, mapView);
                    break;
                case MotionEvent.ACTION_UP:
                    doPanning(eventPosition, mapView);
                    savedTouchedX = -1;
                    savedTouchedY = -1;
                    break;
                default:
                    break;
             }
             return true;
        }
    });

//move mapView
private boolean doPanning(GeoPoint e, MapView mapView)
 {
        GeoPoint mapCenter = (GeoPoint) mapView.getMapCenter();
        GeoPoint panToCenter = new GeoPoint((int)(mapCenter.getLatitudeE6() + (e.getLatitude() - savedTouchedY) * 1E5),
        (int)(mapCenter.getLongitudeE6() - (e.getLongitude() - savedTouchedX) * 1E5));
        mapView.getController().setCenter(panToCenter);
    savedTouchedX = e.getLongitude();
    savedTouchedY = e.getLatitude();
    return true;
 }

Solution

  • You MUST transform your MotionEvent position (which is in screen coords) in a Map position. This is not the same coordinates system at all!

    final Projection pj = mapView.getProjection();
    GeoPoint eventPosition = (GeoPoint) pj.fromPixels((int)event.getX(), (int)event.getY());