it-swarm.com.ru

Настройка максимального уровня масштабирования в картах Google 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 карты не имеет такого метода для управления уровнем масштабирования . Кто-нибудь знает какие-либо идеи для решения этой проблемы?

35
user2223820

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

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

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

GoogleMap.setMaxZoomPreference()

GoogleMap.setMinZoomPreference()

Это все еще не мешает воспроизвести анимацию.

24
Dmitry Serov

Вот соответствующий 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;
}
12
kasimir

Из документа Android: 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);
11
ChrisUser2627250

То же, что и решение Arvis, но с использованием Location 's [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
Jens

Перед анимацией камеры вы можете проверить, не слишком ли близки точки 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

3
Arvis

Это из справочника 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
2
Vishal Disawar

Подход @ 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;
}
1
Christopher Pickslay

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

0
wwang

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

добавить map.setOnCameraChangeListener

final float maxZoom = 10.0f;

@Override
public void onCameraChange(CameraPosition position) {

    if (position.zoom > maxZoom)
        map.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
0
Ravi
map.setMinZoomPreference(floatValue);
0
Karim Elshaweish

На новых Google Картах 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);

        }
    });
0
user2373653

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

Как-то так в макете для размещения кнопок:

<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");
        }
    }
});
0
William W

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

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

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

0
Benil Mathew