Настройка максимального уровня масштабирования в 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 нет такого метода контроля уровня масштабирования.
Кто-нибудь знает какую-либо идею для решения этой проблемы?
Ответы
Ответ 1
Я не нашел прямого решения в API Карт Google. Потенциальное решение этой проблемы заключается в прослушивании события OnCameraChange: всякий раз, когда это событие срабатывает и уровень масштабирования выше максимального уровня масштабирования, можно вызвать animateCamera(). Итоговый код будет выглядеть следующим образом:
@Override
public void onCameraChange(CameraPosition position) {
float maxZoom = 17.0f;
if (position.zoom > maxZoom)
map_.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
Ответ 2
В недавнем обновлении API Карт Google вводит требуемые функции:
GoogleMap.setMaxZoomPreference()
GoogleMap.setMinZoomPreference()
Это все равно не мешает анимации играть.
Ответ 3
Вот соответствующий 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;
}
Ответ 4
От 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 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);
Ответ 5
То же, что и решение Arvis, но используя Location
[distanceBetween()
] (http://developer.android.com/reference/android/location/Location.html#distanceBetween(double, double, double, double, 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);
}
}
Ответ 6
Перед анимацией камеры вы можете проверить, не слишком ли близки точки обзора 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);
пс. Мой пример - в С# для Xamarin, но вы можете легко отрегулировать его для java
Ответ 7
Это из ссылка на 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
Ответ 8
Подход @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;
}
Ответ 9
Я не уверен, что это сработает, но вы можете попробовать это
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
Надеюсь, что это поможет
Ответ 10
То, что я закончил, - это создать свои собственные кнопки и отключить стандартные, поэтому я бы получил полный контроль.
Что-то вроде этого в макете для размещения кнопок:
<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");
}
}
});
Ответ 11
С помощью com.google.android.gms:play-services-maps:9.4.0
вы можете легко установить минимальное/максимальное масштабирование. С помощью GoogleMap.setMinZoomPreference()
и GoogleMap.setMaxZoomPreference()
вы можете установить предпочтительный минимальный и/или максимальный уровень масштабирования. Подробнее см. здесь.
Ответ 12
Мы не можем напрямую ограничивать функцию масштабирования карты, но мы можем попытаться получить такую же функцию, как это.
добавить map.setOnCameraChangeListener
final float maxZoom = 10.0f;
@Override
public void onCameraChange(CameraPosition position) {
if (position.zoom > maxZoom)
map.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
Ответ 13
На новом 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);
}
});
Ответ 14
map.setMinZoomPreference(floatValue);
Ответ 15
Вы можете получить максимальный уровень масштабирования, вызвав его getMaxZoomLevel()
, а затем установите это значение:
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(fromPosition, getMaxZoomLevel()));
Ответ 16
Карта имеет свойство maxZoom. Просто установите это значение, когда вы создаете карту.