How to center the camera so that marker is at the bottom of screen? (Google map api V2 Android)
I might edit this answer later to provide some code, but what I think could work is this:
- Get
LatLng
(LatLng M) of the clicked marker. - Convert LatLng M to a
Point
(Point M) using theProjection.toScreenLocation(LatLng)
method. This gives you the location of the marker on the device's display (in pixels). - Compute the location of a point (New Point) that's above Point M by half of the map's height.
- Convert the New Point back to
LatLng
and center the map on it.
Look here for my answer on how to get the map's height.
// googleMap is a GoogleMap object
// view is a View object containing the inflated map
// marker is a Marker object
Projection projection = googleMap.getProjection();
LatLng markerPosition = marker.getPosition();
Point markerPoint = projection.toScreenLocation(markerPosition);
Point targetPoint = new Point(markerPoint.x, markerPoint.y - view.getHeight() / 2);
LatLng targetPosition = projection.fromScreenLocation(targetPoint);
googleMap.animateCamera(CameraUpdateFactory.newLatLng(targetPosition), 1000, null);
I prefer Larry McKenzie's answer which it doesn't depend on screen projection (i.e. mProjection.toScreenLocation()), my guess is the projection resolution will go poor when the map zoom level is low, it made me sometimes couldn't get an accurate position. So, calculation based on google map spec will definitely solve the problem.
Below is an example code of moving the marker to 30% of the screen size from bottom.
zoom_lvl = mMap.getCameraPosition().zoom;
double dpPerdegree = 256.0*Math.pow(2, zoom_lvl)/170.0;
double screen_height = (double) mapContainer.getHeight();
double screen_height_30p = 30.0*screen_height/100.0;
double degree_30p = screen_height_30p/dpPerdegree;
LatLng centerlatlng = new LatLng( latlng.latitude + degree_30p, latlng.longitude );
mMap.animateCamera( CameraUpdateFactory.newLatLngZoom( centerlatlng, 15 ), 1000, null);
If you don't care about the map zooming in and just want the marker to be at the bottom see below, I think it's a simpler solution
double center = mMap.getCameraPosition().target.latitude;
double southMap = mMap.getProjection().getVisibleRegion().latLngBounds.southwest.latitude;
double diff = (center - southMap);
double newLat = marker.getPosition().latitude + diff;
CameraUpdate centerCam = CameraUpdateFactory.newLatLng(new LatLng(newLat, marker.getPosition().longitude));
mMap.animateCamera(centerCam);