2

I am trying to prevent the user from moving outside a certain area in a google map. However there does not seem to be an easy way to do this. First time asking here so have mercy.

I have tried the below in an effort to poll as the user scrolls, but the problem is that OnCameraChange doesn't fire often enough, so it works jerkily and inaccurately. I know there must be some way to do this as it seems like a simple and essential feature.

private static final LatLng NEBOUND = new LatLng(47.670606, -117.393344);
private static final LatLng SWBOUND = new LatLng(47.661283, -117.411052);
private static final LatLngBounds MAPBOUNDARY = new LatLngBounds(SWBOUND, NEBOUND);
private LatLng lastCenter = new LatLng(47.667454, -117.402309);

  private final OnCameraChangeListener mOnCameraChangeListener = 
            new OnCameraChangeListener() {
        @Override
        public void onCameraChange(CameraPosition cameraPosition) {
            LatLngBounds visibleBounds = guMap.getProjection().getVisibleRegion().latLngBounds;
            if(!MAPBOUNDARY.contains(visibleBounds.northeast) || !MAPBOUNDARY.contains(visibleBounds.southwest)){
                guMap.moveCamera(CameraUpdateFactory.newLatLng(lastCenter));
            }
            else
                lastCenter = guMap.getCameraPosition().target;
            centerLoc.setText(lastCenter.toString());
        }
    };
kag0
  • 5,624
  • 7
  • 34
  • 67
  • Duplicate of : http://stackoverflow.com/questions/14977078/limit-scrolling-and-zooming-google-maps-android-api-v2/14977861#14977861 – Thibault D. Apr 29 '13 at 06:46
  • @thibaultd that's what I'm trying, but OnCameraChange doesn't fire often enough. there was a comment above yours that looked like it would work, but it was for APIv1 and seems like overkill, there must be a better way. – kag0 Apr 29 '13 at 18:11

2 Answers2

2

My implementation of the solution thanks to MaciejGórski Polling even at 5ms is rather jerky, but it works Note that depending on the shape of your boundary and the shape of the users screen, they may not be able to zoom out far enough to view the whole area.

private static final LatLng NEBOUND = new LatLng(47.671781, -117.393352);
private static final LatLng SWBOUND = new LatLng(47.661283, -117.411052);
private static final LatLngBounds MAPBOUNDARY = new LatLngBounds(SWBOUND, NEBOUND);
private LatLng lastCenter = new LatLng(47.667454, -117.402309);
GoogleMap guMap;
private Handler mHandler;

private void checkBoundaries(){
    LatLng tempCenter = guMap.getCameraPosition().target;
    LatLngBounds visibleBounds = guMap.getProjection().getVisibleRegion().latLngBounds;
    if(!MAPBOUNDARY.contains(visibleBounds.northeast) || !MAPBOUNDARY.contains(visibleBounds.southwest)){
        guMap.moveCamera(CameraUpdateFactory.newLatLng(lastCenter));
    }
    else
        lastCenter = tempCenter;
}

private void setUpHandler(){
    mHandler = new Handler(){
            public void handleMessage(Message msg){
                checkBoundaries();
                sendEmptyMessageDelayed(0, 5);
            }
        };
}
kag0
  • 5,624
  • 7
  • 34
  • 67
0

Instead of using new and shiny push technology which is onCameraChange, you may try to use old poll technology: map.getCameraPosition().

Basically you need a Handler, which will get the value of camera position in handleMessage and you send messages to this handler every 10ms or so. Inside handleMessage do sendEmptyMessageDelayed.

You can also use Runnable instead of Message (but that's a matter of taste).

MaciejGórski
  • 22,187
  • 7
  • 70
  • 94
  • not familiar with Handlers, so let me check if I have this right. I create a Handler, send it an empty message, when it receives a message it updates lastCenter (my code above) and then sends itself another empty message after a delay? – kag0 Apr 30 '13 at 01:54
  • also, just to confirm, if I use Message then everything should be happening in one thread right? – kag0 Apr 30 '13 at 02:33
  • Yes (use your code inside handleMessage) and yes (everything is happening on the thread Handler was created in). – MaciejGórski Apr 30 '13 at 09:33