Подтвердить что ты не робот

Android maps V2 newLatLngBounds с подшипником

Я использую новые карты Android V2 с этим макетом:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  class="com.google.android.gms.maps.SupportMapFragment"
  map:cameraBearing="270"/>

Я пытаюсь использовать метод newLatLngBounds (LatLngBounds bounds, int padding) для масштабирования и просмотра всех моих маркеров на карте, однако для датчика камеры установлено значение 0.

В описании документации для разработчиков Google говорится:

public static CameraUpdate newLatLngBounds (LatLngBounds bounds, int padding) (...). Возвращенный CameraUpdate имеет значение 0 и наклон 0. (...) ".

Как изменить значение подшипника?

Я попытался установить новый подшипник программно после вызова newLatLngBounds, примерно так:

mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100));
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
.target(mMap.getCameraPosition().target)
.zoom(mMap.getCameraPosition().zoom)
.bearing(270)
.build()));

Но когда я это сделаю, некоторые маркеры не появятся.

4b9b3361

Ответ 1

У меня есть альтернатива, у меня была такая же проблема. Я покажу, как преобразовать границы в масштабирование, а затем мы просто будем использовать CameraPosition.builder(), чтобы создать правильную позицию.

private static final double LN2 = 0.6931471805599453;
    private static final int WORLD_PX_HEIGHT = 256;
    private static final int WORLD_PX_WIDTH = 256;
    private static final int ZOOM_MAX = 21;

    public int getBoundsZoomLevel(LatLngBounds bounds, int mapWidthPx, int mapHeightPx){

        LatLng ne = bounds.northeast;
        LatLng sw = bounds.southwest;

        double latFraction = (latRad(ne.latitude) - latRad(sw.latitude)) / Math.PI;

        double lngDiff = ne.longitude - sw.longitude;
        double lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360;

        double latZoom = zoom(mapHeightPx, WORLD_PX_HEIGHT, latFraction);
        double lngZoom = zoom(mapWidthPx, WORLD_PX_WIDTH, lngFraction);

        int result = Math.min((int)latZoom, (int)lngZoom);
        return Math.min(result, ZOOM_MAX);
    }

    private double latRad(double lat) {
        double sin = Math.sin(lat * Math.PI / 180);
        double radX2 = Math.log((1 + sin) / (1 - sin)) / 2;
        return Math.max(Math.min(radX2, Math.PI), -Math.PI) / 2;
    }
    private double zoom(int mapPx, int worldPx, double fraction) {
        return Math.floor(Math.log(mapPx / worldPx / fraction) / LN2);
    }

Затем вы можете использовать этот код и добавить опору/и/или наклона с границами:

            LatLngBounds bounds = LatLngBounds.builder()
                    .include(swCorner)
                    .include(neCorner).build();
            CameraPosition cp = new CameraPosition.Builder()
                    .bearing(randomBearing())
                    .tilt(randomTilt())
                    .target(latLng)
                    .zoom(getBoundsZoomLevel(bounds, findViewById(R.id.map).getMeasuredWidth(), findViewById(R.id.map).getMeasuredHeight()))
                    .build();
            CameraUpdate cu = CameraUpdateFactory.newCameraPosition(cp);
            mMap.animateCamera(cu);

Это будет работать (вам нужно будет изменить mMap на вашу фактическую картографическую переменную, а id - на ваш идентификатор карты).

Удачи! Я получил boundZoomLevel из сообщения: Как определить уровень масштабирования LatLngBounds перед использованием map.fitBounds? Идите, как этот ответ, если у вас есть время!

Ответ 2

да, вы можете! просто используйте: https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap#animateCamera(com.google.android.gms.maps.CameraUpdate, int, com.google.android.gms.maps.GoogleMap.CancelableCallback)

и реализовать CancelableCallback и поместить его в метод onFinish(): https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.CancelableCallback#onFinish()

код для изменения подшипника. Конечно, вы не получите ни одной анимации, а цепочку из двух, но она будет работать!

mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100)/*,DURATION_IN_MS_IF_NEEDED*/,new GoogleMap.CancelableCallback(){
    @Override
    public void onCancel() {
        //DO SOMETHING HERE IF YOU WANT TO REACT TO A USER TOUCH WHILE ANIMATING
    }
    @Override
    public void onFinish() {
        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
/*.target(mMap.getCameraPosition().target)
.zoom(mMap.getCameraPosition().zoom)*/
.bearing(270)
.build()));
    }
});

Я не думаю, что вам нужна цель и зум, я их прокомментировал, так как он должен управляться предыдущей анимацией

ИЗМЕНИТЬ Посмотрев лучше на API, у меня есть метод, который мог бы работать (я не могу проверить его сейчас, пожалуйста, взгляните на него: имея LatLngBounds, вы можете получить то, что является уровнем масштабирования, который лучше всего подходит для этой области (это зависит от размеров устройства, поэтому вам нужно получить размеры представления во время выполнения), а затем, когда у вас есть зум (у вас также есть центр LatLngBounds), вы можете сделать обновление камеры с помощью одной уникальной анимации: https://developers.google.com/android/reference/com/google/android/gms/maps/model/CameraPosition, конструктор допускает набор значений, или вы можете использовать построитель, как было показано ранее.

Вы можете найти в Интернете различные способы сделать это, например (просто быстрый поиск в Интернете получил версию javascript fooobar.com/questions/54981/...)

Надеюсь, это поможет вам в решении вашей проблемы!

Ответ 3

Плохая проблема в Google CameraUpdateFactory я решил это со временем, крошечный раз!

public void zoomToBounds() {
    LatLngBounds latLngBounds = getBoundsOfInput(inputPoints);
    final int PADDING = 20;

    final CameraPosition now = map.getCameraPosition();
    final float tilt = map.getCameraPosition().tilt;
    final float bearing = map.getCameraPosition().bearing;
    final LatLng[] target = new LatLng[1];
    final float[] zoom = new float[1];

    map.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, PADDING), 1, null);

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            target[0] = map.getCameraPosition().target;
            zoom[0] = map.getCameraPosition().zoom;
        }
    }, 10);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            map.animateCamera(CameraUpdateFactory.newCameraPosition(now), 1, null);
        }
    }, 30);

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            map.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(target[0], zoom[0], tilt, bearing)));
        }
    }, 60);
}

выглядит грязным, но работает

3 Обработчик выполняет задание, каждый postdelay должен быть больше, чем предыдущий