Карты Google получают радиус видимой области для уровня масштабирования

Я создаю приложение, в которое я загружаю данные из API в onCameraIdle. Запросу нужны целевое местоположение и радиус, в котором я могу получить результаты.

Код, который я использую для получения радиуса от текущей камеры:

/**
 * @param map The Map on which to compute the radius.
 * @return The circle radius of the area visible on map, in meters.
 */
public float getRadiusVisibleOnMap(GoogleMap map) {
    VisibleRegion visibleRegion = map.getProjection().getVisibleRegion();

    LatLng farRight = visibleRegion.farRight;
    LatLng farLeft = visibleRegion.farLeft;
    LatLng nearRight = visibleRegion.nearRight;
    LatLng nearLeft = visibleRegion.nearLeft;

    float[] distanceWidth = new float[1];
    Location.distanceBetween(
            (farRight.latitude + nearRight.latitude) / 2,
            (farRight.longitude + nearRight.longitude) / 2,
            (farLeft.latitude + nearLeft.latitude) / 2,
            (farLeft.longitude + nearLeft.longitude) / 2,
            distanceWidth
    );


    float[] distanceHeight = new float[1];
    Location.distanceBetween(
            (farRight.latitude + nearRight.latitude) / 2,
            (farRight.longitude + nearRight.longitude) / 2,
            (farLeft.latitude + nearLeft.latitude) / 2,
            (farLeft.longitude + nearLeft.longitude) / 2,
            distanceHeight
    );

    float radius;

    if (distanceWidth[0] > distanceHeight[0]) {
        radius = distanceWidth[0];
    } else {
        radius = distanceHeight[0];
    }

    return radius;
}

Я получил его из здесь

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

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

public int getZoomLevel(Circle circle) {
    if (circle != null) {
        double radius = circle.getRadius();
        double scale = radius / 500;
        zoomLevel = (int) (16 - Math.log(scale) / Math.log(2));
    }
    return zoomLevel;
}

Я получил формулу: формула

Формула неверна. Он не выводит правильные размеры. Для уровня масштабирования 14 я получаю размер радиуса 2,697331 км, используя VisibleRegion камеры. Если я вычислю радиус по формуле, результат будет 0,008 км.


person Vlad    schedule 10.05.2017    source источник
comment
С какой проблемой вы здесь столкнулись?   -  person Sreehari    schedule 10.05.2017
comment
Формула, которую я получил для расчета радиуса, неверна. Он не выводит правильные размеры. Для уровня масштабирования 14 я получаю размер радиуса 2,697331 км, используя VisibleRegion камеры. Если я вычислю радиус по формуле, результат будет 0,008 км.   -  person Vlad    schedule 10.05.2017
comment
У вас есть более одной широты и долготы на визуальной базе? Если тогда я могу дать вам логику для расчета радиуса из этого. Я имею в виду масштабирование, основанное на более чем одной широте/долготе.   -  person Sreehari    schedule 10.05.2017
comment
Я не уверен, что ты имеешь в виду. Мне нужен радиус, прежде чем я инициирую следующую команду: map.animateCamera(CameraUpdateFactory.newLatLngZoom(location, zoomLevel), callback); У меня есть местоположение: LatLng и zoomLevel: float   -  person Vlad    schedule 10.05.2017
comment
Я имею в виду, если у вас есть широта/долгота для местоположения 1 и широта/долгота для местоположения 2 и широта/долгота для местоположения 3, тогда я могу дать вам формулу для расчета масштабирования на основе всех этих местоположений.   -  person Sreehari    schedule 10.05.2017
comment
Нет, у меня нет нескольких мест. Я не хочу настраивать камеру так, чтобы одновременно показывались 3 локации. Для этого я бы использовал LatLngBounds для хранения координат и CameraUpdateFactory.newLatLngBounds. Мне нужно знать VisibleRegion камеры, прежде чем анимация масштабирования будет завершена. Спасибо, в любом случае.   -  person Vlad    schedule 10.05.2017


Ответы (1)


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

Вы почти у цели, используйте приведенную ниже модифицированную функцию, которая использует теорему Пифагора, чтобы найти минимальный радиус, необходимый для размещения «прямоугольника» карты.


введите здесь описание изображения


@Override
public void onMapReady(GoogleMap googleMap) {
    this.googleMap = googleMap;
    googleMap.setOnMarkerClickListener(this);

    googleMap.setOnCameraIdleListener(() -> {
        CameraPosition cameraPosition = googleMap.getCameraPosition();
        double radiusInMeters = getMapVisibleRadius();
        double radiusInKilometers = radiusInMeters / 1000;
        double latitude = cameraPosition.target.latitude;
        double longitude = cameraPosition.target.longitude;

        // TODO you take it from here, 
        // I use firebase to get relevant markers based on the lat,long,radius

    });
}


private double getMapVisibleRadius() {
    VisibleRegion visibleRegion = googleMap.getProjection().getVisibleRegion();

    float[] distanceWidth = new float[1];
    float[] distanceHeight = new float[1];

    LatLng farRight = visibleRegion.farRight;
    LatLng farLeft = visibleRegion.farLeft;
    LatLng nearRight = visibleRegion.nearRight;
    LatLng nearLeft = visibleRegion.nearLeft;

    Location.distanceBetween(
            (farLeft.latitude + nearLeft.latitude) / 2,
            farLeft.longitude,
            (farRight.latitude + nearRight.latitude) / 2,
            farRight.longitude,
            distanceWidth
    );

    Location.distanceBetween(
            farRight.latitude,
            (farRight.longitude + farLeft.longitude) / 2,
            nearRight.latitude,
            (nearRight.longitude + nearLeft.longitude) / 2,
            distanceHeight
    );

    double radiusInMeters = Math.sqrt(Math.pow(distanceWidth[0], 2) + Math.pow(distanceHeight[0], 2)) / 2;
    return radiusInMeters;
}
person Jossef Harush    schedule 31.05.2018