¿Cómo centrarse en la ubicación en Google Maps, teniendo en cuenta una vista es en la parte superior de la misma?

Fondo

Supongamos que tengo una vista de mapas de Google, y otra vista encima de ella, que cubre una parte de ella, ocultando algún contenido del mapa.

El problema

Necesito hacer la "cámara" del mapa, enfocar y tener un marcador en una coordenada, pero dejar que todo esté en el centro de la parte visible del mapa.

Algo como esto:

Introduzca aquí la descripción de la imagen

El código original se estaba centrando en (alrededor) el centro de toda la pantalla, haciendo el marcador casi invisible (como la vista inferior lo cubre).

La cosa es, no puedo encontrar la manera correcta de establecer el valor correcto a la coordenada Y del mapa en sí (latitud significado).

Lo que he intentado

He intentado, dada la altura de la vista inferior, y la coordenada que he puesto el marcador, para calcular el delta (sin embargo, por supuesto no cambiar el marcador en sí):

final float neededZoom = 6.5f; int bottomViewHeight = bottomView.getHeight(); LatLng posToFocusOn = ...; final Point point = mMap.getProjection().toScreenLocation(posToFocusOn); final float curZoom = mMap.getCameraPosition().zoom; point.y += bottomViewHeight * curZoom / neededZoom; posToFocusOn = mMap.getProjection().fromScreenLocation(point); final CameraUpdate cameraPosition = CameraUpdateFactory.newCameraPosition(new Builder().target(posToFocusOn).zoom(neededZoom).build()); 

Lamentablemente, esto se centra mucho más allá del marcador.

La pregunta

¿Qué tiene de malo lo que escribí? ¿Que puedo hacer para arreglarlo?

Ok, he encontrado una solución, que creo que funciona en todos los dispositivos (probado en 3, cada uno con una resolución de pantalla diferente y el tamaño):

He medido cuántos píxeles (y luego convertido a DP) un cambio de un grado tiene en el propio marcador.

A partir de esto, medí la altura de cada vista, y calculé el delta necesario para mover la cámara.

En mi caso, es de esta manera (suponiendo que el zoom es 6.5f):

  //measured as 223 pixels on Nexus 5, which has xxhdpi, so divide by 3 final float oneDegreeInPixels = convertDpToPixels( 223.0f / 3.0f); final float mapViewCenter = mapViewHeight / 2.0f; final float bottomViewHeight = ...; final float posToFocusInPixelsFromTop = (mapViewHeight - bottomViewHeight) / 2.0f ;// can optionally add the height of the view on the top area final float deltaLatDegreesToMove = (mapViewCenter - posToFocusInPixelsFromTop) / oneDegreeInPixels; LatLng posToFocusOn = new LatLng(latitude - deltaLatDegreesToMove, longitude); final CameraUpdate cameraPosition = CameraUpdateFactory.newCameraPosition(new Builder().target(posToFocusOn).zoom(neededZoom).build()); 

Y funcionó.

Me pregunto si se puede ajustar para soportar cualquier valor de zoom.

Su código es casi correcto, pero va por encima del marcador porque está teniendo en cuenta bottomViewHeight al calcular point.y lugar de bottomViewHeight/2 (cuando el tamaño de su vista es 200px, sólo necesita desplazar el mapa 100px para actualizarlo):

 point.y += (bottomViewHeight / 2) * curZoom / neededZoom; 

Actualizar:

Este es un enfoque más general que toma en cuenta los límites del mapa y calcula un nuevo mapa de límites de acuerdo con la altura de su bottomView . Esto es independiente del zoom.

 public void recenter() { LatLngBounds mapBounds = mMap.getProjection().getVisibleRegion().latLngBounds; Point nothEastPoint = mMap.getProjection().toScreenLocation(mapBounds.northeast); Point souhWestPoint = mMap.getProjection().toScreenLocation(mapBounds.southwest); Point newNorthEast = new Point(nothEastPoint.x, nothEastPoint.y + bottomView.getHeight() / 2); Point newSouhWestPoint = new Point(souhWestPoint.x, souhWestPoint.y + bottomView.getHeight() / 2); LatLngBounds newBounds = LatLngBounds.builder() .include(mMap.getProjection().fromScreenLocation(newNorthEast)) .include(mMap.getProjection().fromScreenLocation(newSouhWestPoint)) .build(); mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(newBounds, 0)); } 

Tenga en cuenta que cada vez que llame a recenter() el mapa se moverá.

  • MyLocation botón oculto tras la barra de acción transparente, cómo reposicionar?
  • Influenciar el tamaño de mosaico en Android Maps TileProvider?
  • Botón My-Location de GoogleMaps v2 Android, no se muestra
  • Android Google Maps API v2: obtener mi ubicación de rodamiento
  • Android Google Maps API v2 ruta de visualización
  • Abrir Google Maps desde hipervínculo
  • Utilidad de mapas de Android: imágenes de la URL
  • Mover marcador con gps en google map android
  • Grupo de mapas de Google con dirección
  • Google Maps API V2 'Error al cargar mapa. No se pudo contactar con Google Servers, ni siquiera comprobar permiso y keystore
  • Error de constructores no predeterminados en fragmentos
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.