Search code examples
androidmapactivity

Zooming and panning to lat/lng span in map activity


Summary

I need to be able to move from my current mapview to a latitude/longitude span. I want this move to happen in an animated sort of way (similar to how animateTo works). I need to go from my current view, and zoom in or out to end up at the target latitude/longitude span. Below is the code I'm using to do this when I use zoomLevels. But I have to use spans, not zoom levels to accomplish this.

[Edit]

Here's what I'm doing for animateTo. I need the equivalent of this, but using Lat/Lng Span to end up at my final view (i need to be zoomed and centered, showing the lat/lng span provided). As you'll notice, i'm using targetZoomLevel and currentZoomLevel to determine how much zooming to do... I need to be using the lat/lng span instead.

public static void smoothZoom(final MapController controller,
        final int currentZoomLevel, final int targetZoomLevel,
        int latitude, int longitude) {

    final Handler handler = new Handler();

    controller.animateTo(new GeoPoint(latitude, longitude), new Runnable() {
        public void run() {

            int currentZoom = currentZoomLevel;
            int zoomTarget = targetZoomLevel;

            // Smooth zoom handler
            // int zoomLevel = _mapView.getZoomLevel();
            // int targetZoomLevel = targetLevel;
            long delay = 0;

            if (zoomTarget > currentZoom) {
                while (currentZoom++ < zoomTarget) {
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            controller.zoomIn();
                        }
                    }, delay);

                    delay += 150; // Change this to whatever is good on the
                                    // device
                }
            } 
        }
    });
}

[Edit]

I really need this code for my application now, there is no way around it. First person to help me get working code gets 250 rep.


Solution

  • Is this the kind of solution you're looking for?

    public static void zoomSpan(final MapView mapView, int northernLat, int southernLat, int easternLon, int westernLon) {
        final int latSpan = northernLat - southernLat;
        final int lonSpan = easternLon - westernLon;
        latCenter = southernLat + latSpan / 2;
        lonCenter = westernLon + lonSpan / 2;
    
        final MapController controller = mapView.getController();
        final Handler handler = new Handler();
    
        final Runnable zoomRunnable = new Runnable() {
            public void run() {
                int viewLatSpan = mapView.getLatitudeSpan();
                int viewLonSpan = mapView.getLongitudeSpan();
                boolean actionTaken = false;
                if (mapView.getZoomLevel() > 1 && (latSpan > viewLatSpan || lonSpan > viewLonSpan)) {
                    controller.zoomOut();
                    actionTaken = true;
                }
                if (mapView.getZoomLevel() < mapView.getMaxZoomLevel() && latSpan * 2 <= viewLatSpan && lonSpan * 2 <= viewLonSpan) {
                    controller.zoomIn();
                    actionTaken = true;
                }
                if (actionTaken)
                    handler.post(zoomRunnable);
            }
        };
    
        controller.animateTo(latCenter, lonCenter, zoomRunnable);
    
    }