Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I detect if an Android MapView has been panned or zoomed?

I'm creating an Android app that searches for items based on the visible area of the MapView. Is there a way to set up a listener on my MapView to detect when a map has been panned or zoomed?

like image 515
dl. Avatar asked Feb 24 '10 18:02

dl.


2 Answers

try mapview-overlay-manager, it is a extension for overlayer for android maps,

it has some simplified OnGestureListener, few example:

onSingleTap(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem)

onDoubleTap(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem)

onLongPress(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem)

onZoom(ZoomEvent, ManagedOverlay)

onScrolled(...)

link:http://code.google.com/p/mapview-overlay-manager/ hope it helps

like image 76
liding Avatar answered Oct 05 '22 23:10

liding


You can create a SimpleMapView that extends MapView.

public class SimpleMapView extends MapView {

    private int currentZoomLevel = -1;
    private GeoPoint currentCenter;
    private List<ZoomChangeListener> zoomEvents = new ArrayList<ZoomChangeListener>();
    private List<PanChangeListener> panEvents = new ArrayList<PanChangeListener>();

    public SimpleMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public SimpleMapView(Context context, String apiKey) {
        super(context, apiKey);
    }

    public SimpleMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    /**
     * 
     * @return
     */
    public int[][] getBounds() {

        GeoPoint center = getMapCenter();
        int latitudeSpan = getLatitudeSpan();
        int longtitudeSpan = getLongitudeSpan();
        int[][] bounds = new int[2][2];

        bounds[0][0] = center.getLatitudeE6() - (latitudeSpan / 2);
        bounds[0][1] = center.getLongitudeE6() - (longtitudeSpan / 2);

        bounds[1][0] = center.getLatitudeE6() + (latitudeSpan / 2);
        bounds[1][1] = center.getLongitudeE6() + (longtitudeSpan / 2);
        return bounds;
    }

    public boolean onTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_UP) {
            GeoPoint centerGeoPoint = this.getMapCenter();
            if (currentCenter == null || 
                    (currentCenter.getLatitudeE6() != centerGeoPoint.getLatitudeE6()) ||
                    (currentCenter.getLongitudeE6() != centerGeoPoint.getLongitudeE6()) ) {
                firePanEvent(currentCenter, this.getMapCenter());
            }
            currentCenter = this.getMapCenter();
        }
        return super.onTouchEvent(ev);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        if(getZoomLevel() != currentZoomLevel){
            fireZoomLevel(currentZoomLevel, getZoomLevel());
            currentZoomLevel = getZoomLevel();
        }
    }

    @Override
    public void setSatellite(boolean on){
        super.setSatellite(on);
    }

    @Override
    public MapController getController(){
        return super.getController();
    }

    private void fireZoomLevel(int old, int current){
        for(ZoomChangeListener event : zoomEvents){
            event.onZoom(old, current);
        }
    }

    private void firePanEvent(GeoPoint old, GeoPoint current){
        for(PanChangeListener event : panEvents){
            event.onPan(old, current);
        }
    }

    public void addZoomChangeListener(ZoomChangeListener listener){
        this.zoomEvents.add(listener);
    }

    public void addPanChangeListener(PanChangeListener listener){
        this.panEvents.add(listener);
    }
}

You have the Listeners you can put the code for pan or zoom. Then in your xml:

 <com.androidnatic.maps.SimpleMapView android:clickable="true" 
                    android:layout_height="match_parent" android:id="@+id/mapView" 
                    android:layout_width="match_parent"
                     android:apiKey="xxx">
 </com.androidnatic.maps.SimpleMapView>

And then in your code you can specify the Pan Listener:

mapView.addPanChangeListener(new PanChangeListener() {

            @Override
            public void onPan(GeoPoint old, GeoPoint current) {
                          //TODO
                        }
        });
like image 26
chemalarrea Avatar answered Oct 06 '22 00:10

chemalarrea