Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Maps - Limit at 180 degrees

Can I limit the Google Maps V2 (Android) at 180° / -180° longitude (like iOS MapKit)? I don't want it to wrap around, as I'm trying to implement a clusterin algorithm, and the 180 / -180 degree split would make it difficult.

I would like the panning to be limited at the red line:

enter image description here

like image 469
D-32 Avatar asked Jan 23 '13 14:01

D-32


2 Answers

So I created a solution that should be fine. If the user panns the map across the -180 / 180 border, the map will flip to the other side. So wrapping the map is still possible, but the "dangerous" area is never displayed.

I had to create a custom MapView:

public class CustomMapView extends MapView {

    private double prevLongitude;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean retVal = correctCamera();
        prevLongitude = getMap().getCameraPosition().target.longitude;
        return retVal;
    }

    public boolean correctCamera() {    
        if (getMap().getProjection().getVisibleRegion().latLngBounds.northeast.longitude < getMap().getProjection().getVisibleRegion().latLngBounds.southwest.longitude) {
            double diff = getMap().getProjection().getVisibleRegion().latLngBounds.southwest.longitude - getMap().getProjection().getVisibleRegion().latLngBounds.northeast.longitude;
            double longitudeSW;
            double longitudeNE;

            double longitudeDiff = (360-diff) / 25; 

            // use > 0 if you want the map to jump to the other side
            // <= 0 will cause the map to flip back
            if (prevLongitude > 0) {
                longitudeSW = -180 + longitudeDiff;
                longitudeNE = -180 + longitudeDiff - diff;
            } else {
                longitudeSW = 180 - longitudeDiff + diff;
                longitudeNE = 180 - longitudeDiff;
            }
            LatLngBounds bounds = new LatLngBounds(
                                        new LatLng(getMap().getCameraPosition().target.latitude, longitudeSW), 
                                        new LatLng(getMap().getCameraPosition().target.latitude, longitudeNE)
                                  );
            getMap().animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0));

            return true;
        }

        return false;
    }
}

And the xml:

<com.ieffects.clustermap.CustomMapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

And for the GoogleMap (mapView.getMap()):

map.setOnCameraChangeListener(new OnCameraChangeListener() {
    @Override
    public void onCameraChange(CameraPosition position) {
        mapView.correctCamera();
    }
});

This is needed if the user let's the map "fly" into the dangerous region.

like image 149
D-32 Avatar answered Oct 16 '22 22:10

D-32


See this tutorial for v2: http://econym.org.uk/gmap/range.htm - basically, you add a listener for the move event, and abort the move if it goes outside the range. This should be applicable in v3 as well.

like image 2
Piskvor left the building Avatar answered Oct 16 '22 20:10

Piskvor left the building