Установите максимальный уровень масштабирования в построителе LatLngBounds

Я не нашел ответа в своем поиске, есть несколько ответов на SO, но они не работали для меня.

У меня есть 2 маркера на карте, и я использую построитель LatLngBounds, чтобы позволить камере приближаться к правильному уровню масштабирования, чтобы включить их обоих. Все работает так, как ожидалось, в стороне от одной вещи, когда 2 маркера действительно близки друг к другу, карта очень сильно масштабируется и хорошо, нет никакого смысла, чтобы этот уровень масштабирования.

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

Есть ли способ заставить определенный уровень масштабирования, после чего камера не будет масштабироваться? Это позволит избежать слишком большого увеличения карты. В основном я использую 15.0f как уровень масштабирования. Если точки слишком далеко, я хочу, чтобы зум соответствовал им. Если очки приближаются, я не хочу, чтобы уровень масштабирования превышал 15.0f.

У меня есть аналогичный случай, где я хочу, по крайней мере, диагональ карты в 2 километра. Поэтому я просто добавляю два дополнительных объекта в строитель: первый 1 км к северо-западу от центра исходных границ и второй 1 км к юго-востоку от центра. Если они находятся внутри границ, они ничего не меняют. Если они находятся за пределами исходных границ, они увеличивают границы до значимого размера.

Вот полный пример кода:

 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); } - 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); } - 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); } 

Я реализовал это решение в соответствии с ответом user2808624, но с помощью SphericalUtil из библиотеки Android Maps Utility для выполнения вычислений.

 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 ); 

Google добавил api для ограничения уровней масштабирования max / min.

 GoogleMap.setMaxZoomPreference() GoogleMap.setMinZoomPreference() 

Вот гораздо более короткая версия, основанная на ответе 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(); 

Его немного неряшливо, но вы можете использовать 0.001 для увеличения не менее городского блока, 0,01 для не менее городского вида. Единственным преимуществом является только 4 дополнительных строки кода.

Считаете ли вы, что фрагмент карты скрыт, и используя это, чтобы определить масштаб / границы? Это, очевидно, не самое лучшее вычислительное, но это, вероятно, самое простое / наиболее точное решение. Например, сложно сделать математическое решение, которое работает вблизи полюсов и через 0 градусов долготы (если вам интересно). Если вы используете карту, все это уже встроено. Вы также можете использовать это решение на своей существующей карте, но пользователь увидит отскок.

Вот как вы это сделаете:

  1. Перейдите к границам, как вы определили выше
  2. Получите масштаб с помощью map.getCameraPosition (). Zoom.
  3. Если масштабирование> 15 уменьшит масштаб до 15, используя CameraUpdateFactory.zoomTo (15)

Невозможно ограничить уровни масштабирования с 4.0.30, но вы можете отслеживать эту проблему .

Легким способом было бы увеличить масштаб, как на этом видео: http://www.youtube.com/watch?v=-nCZ37HdheY
В основном они вызывают animateCamera при animateCamera определенного уровня масштабирования.

Это выглядело бы немного странно, потому что у вас тогда есть 2 анимации, которые не запускаются пользователем.

Трудный путь будет делать сама математика. Попытайтесь работать с CameraUpdateFactory.newLatLngZoom с LatLng как центром между этими точками и максимальным увеличением при обнаружении точек близко друг к другу.

Поздно, но, возможно, у кого-то такая же проблема: я получил баллы с места, а не из LatLngBounds.Builder:

Я использовал Location.distanceBetween (…), чтобы узнать, были ли границы слишком маленькими, а затем используйте минимальный уровень масштабирования с центром границ:

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

Метод проверки:

 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; } 

Я использовал минимальный уровень масштабирования 17 и прокладку 20 для слишком маленьких границ, слишком мал, здесь здесь останавливается минимальное расстояние в метрах 300. Вы можете отрегулировать числа по мере необходимости.

Быстрое исправление:

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

Помните, что он может остановить масштабирование, пока карта не будет полностью перезагружена. Но в качестве быстрого решения это работает.

Это просто:

 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)); 
Intereting Posts
Создание многоадресного сервера на основе кодеков OPUS (android / linux) Значок значка в верхней части нижней панели навигационной панели Почему не доступна библиотека поддержки Android версии 22? Android-эмулятор не запускается Установить максимальное количество видимых строк для списка Android: ошибка анализа при анализе манифеста. Прекращение установки IabResult: услуга выставления счетов недоступна на устройстве. (Ответ: 3: выставление счетов недоступно) Преобразование макета кадра в изображение и сохранение его Вызов основного компонента пользовательского интерфейса Android из React native Js code Что именно происходит, когда я устанавливаю приложение для Android? Как узнать, сколько приложений работает в фоновом режиме в Android? Jenkins email артефакт для каждой сборки Как преобразовать HttpEntity в JSON? Получение изображения из рисунка и добавление в PDF с помощью iText Обфускация нескольких модулей с помощью студии android