Настройка максимального уровня масштабирования в google maps android api v2

В настоящее время я работаю над разработкой приложений с помощью Google maps android API v2. Мой код выглядит следующим образом. Предположим, что карта имеет несколько маркеров и масштабирование, чтобы показать все маркеры на дисплее.

LatLngBuilder.Builder builder = LatLngBounds.builder(); for(Marker m : markers){ builder.include(m.getPosition()); } LatLngBounds bounds = builder.build(); map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10); 

Этот код работает нормально, но я хочу прекратить анимацию, когда уровень масштабирования достигнет 17.0f; Кажется, у карты API нет такого метода для управления уровнем масштабирования. Кто-нибудь знает какую-либо идею для решения этой проблемы?

Solutions Collecting From Web of "Настройка максимального уровня масштабирования в google maps android api v2"

Я не нашел прямого решения в API Карт Google. Потенциальное решение этой проблемы заключается в прослушивании события OnCameraChange : всякий раз, когда это событие срабатывает, а уровень масштабирования выше максимального уровня масштабирования, можно вызвать animateCamera () . В результате код будет выглядеть следующим образом:

 @Override public void onCameraChange(CameraPosition position) { float maxZoom = 17.0f; if (position.zoom > maxZoom) map_.animateCamera(CameraUpdateFactory.zoomTo(maxZoom)); } 

Недавнее обновление API Карт Google вводит требуемые функции:

 GoogleMap.setMaxZoomPreference() GoogleMap.setMinZoomPreference() 

Тем не менее, это все равно не мешает анимации.

Вот соответствующий Java-код для решения Arvis, который хорошо работал для меня:

 private LatLngBounds adjustBoundsForMaxZoomLevel(LatLngBounds bounds) { LatLng sw = bounds.southwest; LatLng ne = bounds.northeast; double deltaLat = Math.abs(sw.latitude - ne.latitude); double deltaLon = Math.abs(sw.longitude - ne.longitude); final double zoomN = 0.005; // minimum zoom coefficient if (deltaLat < zoomN) { sw = new LatLng(sw.latitude - (zoomN - deltaLat / 2), sw.longitude); ne = new LatLng(ne.latitude + (zoomN - deltaLat / 2), ne.longitude); bounds = new LatLngBounds(sw, ne); } else if (deltaLon < zoomN) { sw = new LatLng(sw.latitude, sw.longitude - (zoomN - deltaLon / 2)); ne = new LatLng(ne.latitude, ne.longitude + (zoomN - deltaLon / 2)); bounds = new LatLngBounds(sw, ne); } return bounds; } 

Из документа Android doc: https://developers.google.com/maps/documentation/android-api/views

You may find it useful to set a prefered minimum and/or maximum zoom level. For example, this is useful to control the user's experience if your app shows a defined area around a point of interest, or if you're using a custom tile overlay with a limited set of zoom levels.

  private GoogleMap mMap; // Set a preference for minimum and maximum zoom. mMap.setMinZoomPreference(6.0f); mMap.setMaxZoomPreference(14.0f); 

То же, что и решение Arvis, но с использованием Location [s] [ distanceBetween() ] ( http://developer.android.com/reference/android/location/Location.html#distanceBetween (двойной, двойной, двойной, двойной, float [])) Метод вычисления расстояния между точками:

 @Override public void zoomToMarkers(Set<Marker> markers) { LatLngBounds.Builder builder = new LatLngBounds.Builder(); for (Marker marker : markers) { builder.include(marker.getPosition()); } LatLngBounds bounds = builder.build(); // Calculate distance between northeast and southwest float[] results = new float[1]; android.location.Location.distanceBetween(bounds.northeast.latitude, bounds.northeast.longitude, bounds.southwest.latitude, bounds.southwest.longitude, results); CameraUpdate cu = null; if (results[0] < 1000) { // distance is less than 1 km -> set to zoom level 15 cu = CameraUpdateFactory.newLatLngZoom(bounds.getCenter(), 15); } else { int padding = 50; // offset from edges of the map in pixels cu = CameraUpdateFactory.newLatLngBounds(bounds, padding); } if (cu != null) { mMap.moveCamera(cu); } } 

Перед анимационной камерой вы можете проверить, не слишком ли близки точки обзора SW и NE, и, если необходимо, настроить границы:

  ... LatLngBounds bounds = builder.Build(); var sw = bounds.Southwest; var ne = bounds.Northeast; var deltaLat = Math.Abs(sw.Latitude - ne.Latitude); var deltaLon = Math.Abs(sw.Longitude - ne.Longitude); const double zoomN = 0.005; // set whatever zoom coefficient you need!!! if (deltaLat < zoomN) { sw.Latitude = sw.Latitude - (zoomN - deltaLat / 2); ne.Latitude = ne.Latitude + (zoomN - deltaLat / 2); bounds = new LatLngBounds(sw, ne); } else if (deltaLon < zoomN) { sw.Longitude = sw.Longitude - (zoomN - deltaLon / 2); ne.Longitude = ne.Longitude + (zoomN - deltaLon / 2); bounds = new LatLngBounds(sw, ne); } map.animateCamera(CameraUpdateFactory.NewLatLngBounds(bounds, 10); 

пс. Мой пример – в c # для Xamarin, но вы можете легко настроить его для java

Это ссылка на API для используемой вами include(position) :

«Включает этот момент для построения границ. Оценки будут расширены как минимум, чтобы включить эту точку. Точнее, она рассмотрит возможность расширения границ как в направлении на восток, так и на запад (один из которых может обернуться вокруг мира) И выберите меньшее из двух. В случае, когда оба направления приводят к LatLngBounds того же размера, это расширит его в направлении на восток ».

Карта уменьшит масштаб, пока не появится все маркеры, которые вы добавляете в цикл for.

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

 @Override public void onCameraChange(CameraPosition camPos) { if (camPos.zoom < 17 && mCurrentLoc != null) { // set zoom 17 and disable zoom gestures so map can't be zoomed out // all the way mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(position,17)); mMap.getUiSettings().setZoomGesturesEnabled(false); } if (camPos.zoom >= 17) { mMap.getUiSettings().setZoomGesturesEnabled(true); } LatLngBounds visibleBounds = mMap.getProjection().getVisibleRegion().latLngBounds; //add the markers 

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

 private LatLngBounds adjustBoundsForMinimumLatitudeDegrees(LatLngBounds bounds, double minLatitudeDegrees) { LatLng sw = bounds.southwest; LatLng ne = bounds.northeast; double visibleLatitudeDegrees = Math.abs(sw.latitude - ne.latitude); if (visibleLatitudeDegrees < minLatitudeDegrees) { LatLng center = bounds.getCenter(); sw = new LatLng(center.latitude - (minLatitudeDegrees / 2), sw.longitude); ne = new LatLng(center.latitude + (minLatitudeDegrees / 2), ne.longitude); bounds = new LatLngBounds(sw, ne); } return bounds; } 

Я не уверен, что это сработает, но вы можете попробовать это

 map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); 

Надеюсь, поможет

То, что я закончил, – это создать собственные кнопки и отключить стандартные, поэтому я бы получил полный контроль.

Что-то вроде этого в макете, чтобы поместить кнопки:

 <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_gravity="bottom" android:layout_alignParentRight="true" android:layout_alignParentBottom="true"> <Button android:id="@+id/bzoomin" android:layout_width="55dp" android:layout_height="55dp" android:gravity="center" android:textSize="28sp" android:text="+" /> <Button android:id="@+id/bzoomout" android:layout_width="55dp" android:layout_height="55dp" android:gravity="center" android:textSize="23sp" android:text="—" /> </LinearLayout> 

Затем это в коде, чтобы отключить кнопки по умолчанию и настроить наши новые:

 map.getUiSettings().setZoomControlsEnabled(false); // setup zoom control buttons Button zoomout = (Button) findViewById(R.id.bzoomout); zoomout.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { if(map.getCameraPosition().zoom >= 8.0f){ // Zoom like normal map.animateCamera(CameraUpdateFactory.zoomOut()); }else{ // Do whatever you want if user went too far Messages.toast_short(MapsActivity.this, "Maximum zoom out level reached"); } } }); Button zoomin = (Button) findViewById(R.id.bzoomin); zoomin.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (map.getCameraPosition().zoom <= 14.0f) { // Zoom like normal map.animateCamera(CameraUpdateFactory.zoomIn()); } else { // Do whatever you want if user went too far Messages.toast_short(MapsActivity.this, "Maximum zoom in level reached"); } } }); 

С com.google.android.gms:play-services-maps:9.4.0 вы можете легко установить min / max zoom. С помощью GoogleMap.setMinZoomPreference() и GoogleMap.setMaxZoomPreference() вы можете установить предпочтительный минимальный и / или максимальный уровень масштабирования. Подробнее см. Здесь .

Мы не можем ограничить функцию масштабирования карты напрямую, но мы можем попытаться получить такую ​​же функцию, как эта.

Добавить map.setOnCameraChangeListener

 final float maxZoom = 10.0f; @Override public void onCameraChange(CameraPosition position) { if (position.zoom > maxZoom) map.animateCamera(CameraUpdateFactory.zoomTo(maxZoom)); } 

На новом Google Maps 9.8

com.google.android.gms:play-services-maps:9.8.0

Вот как я это сделал и работал

  googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() { @Override public void onCameraMove() { Log.d(App.TAG, "onCameraMove"); CameraPosition position = googleMap.getCameraPosition(); float maxZoom = 9.0f; if (position.zoom > maxZoom) { googleMap.setMinZoomPreference(maxZoom); } Log.d(App.TAG, "position.zoom = " + position.zoom); } }); 

Вы можете получить максимальный уровень масштабирования, вызвав его getMaxZoomLevel() а затем установите это значение:

 mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(fromPosition, getMaxZoomLevel())); 

Карта имеет свойство maxZoom. Просто установите это значение, когда вы создаете свою карту