studio - map in activity android
¿Cómo centrar la cámara para que el marcador esté en la parte inferior de la pantalla?(Google map api V2 Android) (9)
Cualquiera que todavía esté buscando centrar la cámara según las coordenadas de ubicación
CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(Lat, Lon))
.zoom(15)
.bearing(0)
.tilt(45)
.build();
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
Credits
Cuando se hace clic en un marcador, el comportamiento predeterminado de la cámara es centrarlo en la pantalla, pero como normalmente tengo una descripción de texto larga en la ventana de información, es más conveniente cambiar la posición de la cámara para que el marcador esté en la parte inferior pantalla (haciendo que la ventana de información se encuentre en el centro de la pantalla). Creo que debería poder hacerlo anulando la funciónMarkerClick como a continuación (el comportamiento predeterminado se cancela cuando esta función devuelve true)
@Override
public boolean onMarkerClick(final Marker marker) {
// Google sample code comment : We return false to indicate that we have not
// consumed the event and that we wish
// for the default behavior to occur (which is for the camera to move
// such that the
// marker is centered and for the marker''s info window to open, if it
// has one).
marker.showInfoWindow();
CameraUpdate center=
CameraUpdateFactory.newLatLng(new LatLng(XXXX,
XXXX));
mMap.moveCamera(center);//my question is how to get this center
// return false;
return true;
}
Editar:
Problema resuelto usando los pasos de la respuesta aceptada, códigos a continuación:
@Override
public boolean onMarkerClick(final Marker marker) {
//get the map container height
LinearLayout mapContainer = (LinearLayout) findViewById(R.id.map_container);
container_height = mapContainer.getHeight();
Projection projection = mMap.getProjection();
LatLng markerLatLng = new LatLng(marker.getPosition().latitude,
marker.getPosition().longitude);
Point markerScreenPosition = projection.toScreenLocation(markerLatLng);
Point pointHalfScreenAbove = new Point(markerScreenPosition.x,
markerScreenPosition.y - (container_height / 2));
LatLng aboveMarkerLatLng = projection
.fromScreenLocation(pointHalfScreenAbove);
marker.showInfoWindow();
CameraUpdate center = CameraUpdateFactory.newLatLng(aboveMarkerLatLng);
mMap.moveCamera(center);
return true;
}
Gracias por ayudar ^ ^
Después de algunas experiencias, he implementado la solución que está bien para mí.
DisplayMetrics metrics = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getMetrics(metrics);
Point targetPoint = new Point(metrics.widthPixels / 2, metrics.heightPixels - metrics.heightPixels / 9);
LatLng targetLatlng = map.getProjection().fromScreenLocation(targetPoint);
double fromCenterToTarget = SphericalUtil.computeDistanceBetween(map.getCameraPosition().target, targetLatlng);
LatLng center = SphericalUtil.computeOffset(new LatLng(location.latitude, location.longitude), fromCenterToTarget/1.2, location.bearing);
CameraUpdate camera = CameraUpdateFactory.newLatLng(center);
map.animateCamera(camera, 1000, null);
Aquí. Primero, seleccionamos el punto físico en la pantalla donde se debe mover el marcador. Luego, conviértalo a LatLng. Siguiente paso: calcule la distancia desde la posición actual del marcador (en el centro) hasta el objetivo. Finalmente, movemos el centro del mapa directamente desde el marcador hasta la distancia calculada.
He estado probando todas las soluciones propuestas aquí, y vine con una implementación combinada de ellas. Teniendo en cuenta, la proyección del mapa, la inclinación, el zoom y la altura de la ventana de información.
En realidad, no coloca el marcador en la parte inferior de la "vista de cámara", pero creo que se adapta bastante bien a la ventana de información y al centro de marcadores en la mayoría de los casos.
@Override
public boolean onMarkerClick(Marker marker) {
mIsMarkerClick = true;
mHandler.removeCallbacks(mUpdateTimeTask);
mLoadTask.cancel(true);
getActivity().setProgressBarIndeterminateVisibility(false);
marker.showInfoWindow();
Projection projection = getMap().getProjection();
Point marketCenter = projection.toScreenLocation(marker.getPosition());
float tiltFactor = (90 - getMap().getCameraPosition().tilt) / 90;
marketCenter.y -= mInfoWindowAdapter.getInfoWindowHeight() / 2 * tiltFactor;
LatLng fixLatLng = projection.fromScreenLocation(marketCenter);
mMap.animateCamera(CameraUpdateFactory.newLatLng(fixLatLng), null);
return true;
}
Y luego, su adaptador personalizado tendría que mantener una instancia de la vista inflada de la ventana de información, para poder recuperar su altura.
public int getInfoWindowHeight(){
if (mLastInfoWindoView != null){
return mLastInfoWindoView.getMeasuredHeight();
}
return 0;
}
Investigué un poco y, de acuerdo con la documentación, el mapa es cuadrado y con un nivel de zoom cero, el ancho y la altura son 256dp y +/- 85 grados N / S. El ancho del mapa aumenta con el nivel de zoom para que el ancho y la altura sean 256 * 2N dp. Donde N es el nivel de zoom. En teoría, puede determinar la nueva ubicación obteniendo la altura del mapa y dividiéndola en 170 grados totales para obtener dp por grado. Luego, obtenga la altura de la pantalla (o la altura de la vista de mapa) en dp, divídalo por dos y convierta el tamaño de la vista en grados de latitud. Luego configure su nuevo punto de Cámara en muchos grados de latitud sur. Puedo agregar el código si lo necesita pero estoy en un teléfono en este momento.
Podría editar esta respuesta más tarde para proporcionar algún código, pero lo que creo que podría funcionar es esto:
- Obtenga
LatLng
( LatLng M ) del marcador cliqueado . - Convierta LatLng M a un
Point
( Punto M ) usando el métodoProjection.toScreenLocation(LatLng)
. Esto le da la ubicación del marcador en la pantalla del dispositivo (en píxeles). - Calcule la ubicación de un punto ( Nuevo punto ) que está por encima del Punto M a la mitad de la altura del mapa.
- Convierte el Nuevo Punto de nuevo a
LatLng
y centra el mapa en él.
Mire here mi respuesta sobre cómo obtener la altura del mapa.
// 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);
Prefiero la respuesta de Larry McKenzie, que no depende de la proyección en pantalla (es decir, mProjection.toScreenLocation ()), supongo que la resolución de proyección no será buena cuando el nivel de zoom del mapa sea bajo, a veces no pude obtener una precisión posición. Por lo tanto, el cálculo basado en la especificación del mapa de Google definitivamente resolverá el problema.
A continuación se muestra un código de ejemplo para mover el marcador al 30% del tamaño de la pantalla desde la parte inferior.
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);
Sí, usa la clase de Proyección. Más específicamente:
Obtener proyección del mapa:
Projection projection = map.getProjection();
Obtener la ubicación de tu marcador:
LatLng markerLocation = marker.getPosition();
Pasar ubicación al método Projection.toScreenLocation ():
Point screenPosition = projection.toScreenLocation(markerLocation);
De esta manera puedes mover tu marcador relativo al centro o alrededor de la pantalla
Point mappoint = googleMap.getProjection().toScreenLocation(new LatLng(latitude, longitude));
mappoint.set(mappoint.x, mappoint.y-30);
googleMap.animateCamera(CameraUpdateFactory.newLatLng(googleMap.getProjection().fromScreenLocation(mappoint)));
Si no te importa que el mapa se acerque y solo quieres que el marcador esté en la parte inferior, mira a continuación, creo que es una solución más simple
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);
Tuve el mismo problema, probé la siguiente solución perfectamente funcional
mMap.setOnMarkerClickListener(new OnMarkerClickListener()
{
@Override
public boolean onMarkerClick(Marker marker)
{
int yMatrix = 200, xMatrix =40;
DisplayMetrics metrics1 = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics1);
switch(metrics1.densityDpi)
{
case DisplayMetrics.DENSITY_LOW:
yMatrix = 80;
xMatrix = 20;
break;
case DisplayMetrics.DENSITY_MEDIUM:
yMatrix = 100;
xMatrix = 25;
break;
case DisplayMetrics.DENSITY_HIGH:
yMatrix = 150;
xMatrix = 30;
break;
case DisplayMetrics.DENSITY_XHIGH:
yMatrix = 200;
xMatrix = 40;
break;
case DisplayMetrics.DENSITY_XXHIGH:
yMatrix = 200;
xMatrix = 50;
break;
}
Projection projection = mMap.getProjection();
LatLng latLng = marker.getPosition();
Point point = projection.toScreenLocation(latLng);
Point point2 = new Point(point.x+xMatrix,point.y-yMatrix);
LatLng point3 = projection.fromScreenLocation(point2);
CameraUpdate zoom1 = CameraUpdateFactory.newLatLng(point3);
mMap.animateCamera(zoom1);
marker.showInfoWindow();
return true;
}
});