studio google custom animatecamera android android-maps-v2 zooming

android - google - Establecer un nivel de zoom máximo en el constructor LatLngBounds



zoom google maps android api (10)

No he encontrado una respuesta en mi búsqueda, hay algunas respuestas en SO, pero no funcionaron para mí.

Tengo 2 marcadores en el mapa y estoy usando el generador de LatLngBounds para permitir que la cámara haga zoom al nivel de zoom correcto para incluirlos a ambos. Todo funciona como se espera, aparte de una cosa, cuando los 2 marcadores están muy cerca uno del otro, el mapa está muy muy ampliado y, bueno, no tiene ningún sentido tener este nivel de zoom.

LatLngBounds.Builder builder = new LatLngBounds.Builder(); builder.include(firstMarker.getPosition()); builder.include(secondMarker.getPosition()); LatLngBounds bounds = builder.build(); CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, markerPadding);

¿Hay alguna forma de forzar un cierto nivel de zoom, después de lo cual la cámara no hará zoom? Esto evitaría que el mapa se acercara / alejara demasiado. Básicamente estoy usando 15.0f como nivel de zoom. Si los puntos están demasiado lejos, quiero que el zoom se ajuste a ambos. Si los puntos se acercan, no quiero que el nivel de zoom vaya más allá de 15.0f.


¿Ha considerado crear un fragmento de mapa oculto y usarlo para determinar su zoom / límites? Obviamente, no es el mejor computacional, pero es probablemente la solución más fácil y precisa. Por ejemplo, es complejo hacer una solución matemática que funcione cerca de los polos y a lo largo de 0 grados (si te importa). Si usas un mapa, ya está todo integrado. Obviamente, también podría utilizar esta solución en su mapa existente, pero el usuario vería un rebote.

Así es como lo harías:

  1. Ve a los límites como lo has definido arriba
  2. Obtenga el zoom utilizando map.getCameraPosition (). Zoom.
  3. Si zoom> 15 reduce a 15 utilizando CameraUpdateFactory.zoomTo (15)

Aquí hay una versión mucho más corta basada en la answer user2808624 .

LatLngBounds bounds = builder.build(); LatLng center = bounds.getCenter(); builder.include(new LatLng(center.latitude-0.001f,center.longitude-0.001f)); builder.include(new LatLng(center.latitude+0.001f,center.longitude+0.001f)); bounds = builder.build();

Es un poco descuidado, pero puede usar 0.001 para hacer zoom no menos que una cuadra de la ciudad, 0.01 para no menos que una vista de la ciudad. La única ventaja es que solo tiene 4 líneas adicionales de código.


Es simplemente simple:

LatLngBounds.Builder latlngBuilder = new LatLngBounds.Builder(); LatLng sydney1 = new LatLng(57.149651, -2.099075); LatLng sydney2 = new LatLng(51.621441, -3.943646); latlngBuilder.include(sydney1); latlngBuilder.include(sydney2); googlemap.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBuilder.build(), 100));


Google ha agregado una api para limitar los niveles de zoom máximo / mínimo.

GoogleMap.setMaxZoomPreference() GoogleMap.setMinZoomPreference()


Implementé esta solución de acuerdo con la respuesta de user2808624, pero utilizando SphericalUtil de la biblioteca de Android Maps Utility para realizar los cálculos.

final double HEADING_NORTH_EAST = 45; final double HEADING_SOUTH_WEST = 215; LatLng center = tmpBounds.getCenter(); LatLng norhtEast = SphericalUtil.computeOffset(center, 709,HEADING_NORTH_EAST); LatLng southWest = SphericalUtil.computeOffset(center, 709,HEADING_SOUTH_WEST );


Llegué tarde pero quizás alguien tenga el mismo problema que tuve: recibí límites de un Lugar, no de un LatLngBounds.Builder:

Utilicé Location.distanceBetween (...) para averiguar si los límites eran demasiado pequeños, y luego uso un nivel de zoom mínimo con el centro de los límites:

if (areBoundsTooSmall(bounds, 300)) { mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(bounds.getCenter(), 17)); } else { mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 20)); }

El método de verificación es:

private boolean areBoundsTooSmall(LatLngBounds bounds, int minDistanceInMeter) { float[] result = new float[1]; Location.distanceBetween(bounds.southwest.latitude, bounds.southwest.longitude, bounds.northeast.latitude, bounds.northeast.longitude, result); return result[0] < minDistanceInMeter; }

Usé el nivel de zoom mínimo 17 y el relleno 20 para los límites que son demasiado pequeños, demasiado pequeños se definen aquí por la distancia mínima en el medidor 300. Puede ajustar los números según sea necesario.


No hay forma de limitar los niveles de zoom a partir de 4.0.30, pero puede hacer un seguimiento de este problema .

La forma más fácil sería forzar el nivel de zoom como en este video: http://www.youtube.com/watch?v=-nCZ37HdheY
Básicamente, están llamando a animateCamera cuando se animateCamera cierto nivel de zoom.

Eso parecería un poco extraño, porque entonces tienes 2 animaciones que no son iniciadas por el usuario.

La manera difícil sería hacer las matemáticas a ti mismo. Intente trabajar con CameraUpdateFactory.newLatLngZoom con LatLng como centro entre estos puntos y su zoom máximo cuando detecte puntos que están cerca uno del otro.


Siguiendo las respuestas de user2808624 y dvdrlee, escribí una extensión en Kotlin:

fun LatLngBounds.Builder.createBoundsWithZoomMaintained(bounds: LatLngBounds) : LatLngBounds { val HEADING_NORTH_EAST = 45.0 //NorthEast angle val HEADING_SOUTH_WEST = 215.0 //SouthWest angle val center = bounds.center val northEast = SphericalUtil.computeOffset(center, 709.0, HEADING_NORTH_EAST) //1000 metres on the diagonal translates to 709 metres on either side. val southWest = SphericalUtil.computeOffset(center, 709.0, HEADING_SOUTH_WEST) this.include(northEast).include(southWest) return this.build() }

Por lo general, esto se encuentra en su archivo de Utilidades o Extensiones, y luego puede usarlo desde cualquier lugar simplemente así:

var bounds = builder.build() //To include all your existing points. bounds = builder.createBoundsWithZoomMaintained(bounds) //Updated bounds. mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10))


Solución rápida es:

gMap.setOnMapLoadedCallback(this); CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding); gMap.setMaxZoomPreference(10); gMap.animateCamera(cu); @Override public void onMapLoaded() { gMap.resetMinMaxZoomPreference(); }

Tenga en cuenta que podría detener el zoom hasta que el mapa esté completamente recargado. Pero como una solución rápida funciona.


Tengo un caso similar, donde quiero al menos un mapa en diagonal de 2 kilómetros. Por lo tanto, solo agrego dos puntos adicionales al constructor: el primer 1 km al noroeste del centro de los límites originales y el segundo 1 km al sureste del centro. Si están dentro de los límites, no cambian nada. Si están fuera de los límites originales, aumentan los límites a un tamaño significativo.

Aquí hay un ejemplo de código completo:

public LatLngBounds createBoundsWithMinDiagonal(MarkerOptions firstMarker, MarkerOptions secondMarker) { LatLngBounds.Builder builder = new LatLngBounds.Builder(); builder.include(firstMarker.getPosition()); builder.include(secondMarker.getPosition()); LatLngBounds tmpBounds = builder.build(); /** Add 2 points 1000m northEast and southWest of the center. * They increase the bounds only, if they are not already larger * than this. * 1000m on the diagonal translates into about 709m to each direction. */ LatLng center = tmpBounds.getCenter(); LatLng northEast = move(center, 709, 709); LatLng southWest = move(center, -709, -709); builder.include(southWest); builder.include(northEast); return builder.build(); } private static final double EARTHRADIUS = 6366198; /** * Create a new LatLng which lies toNorth meters north and toEast meters * east of startLL */ private static LatLng move(LatLng startLL, double toNorth, double toEast) { double lonDiff = meterToLongitude(toEast, startLL.latitude); double latDiff = meterToLatitude(toNorth); return new LatLng(startLL.latitude + latDiff, startLL.longitude + lonDiff); } private static double meterToLongitude(double meterToEast, double latitude) { double latArc = Math.toRadians(latitude); double radius = Math.cos(latArc) * EARTHRADIUS; double rad = meterToEast / radius; return Math.toDegrees(rad); } private static double meterToLatitude(double meterToNorth) { double rad = meterToNorth / EARTHRADIUS; return Math.toDegrees(rad); }