Эквивалент MKCoordinateRegionMakeWithDistance в Android - PullRequest
10 голосов
/ 03 июня 2011

Мы можем установить окрестности для определенного местоположения на карте в iPhone следующим образом

CLLocationCoordinate2D coord = {latitude:37.09024, longitude:-95.712891};
CLLocationDistance latitudinalMeters;
latitudinalMeters =NoOfMiles * 1609.344;
CLLocationDistance longitudinalMeters;
longitudinalMeters = NoOfMiles * 1609.344;
mapViewHome.region = MKCoordinateRegionMakeWithDistance(coord, latitudinalMeters, longitudinalMeters); 

Существует ли какой-либо эквивалентный метод для Android?

Ответы [ 2 ]

15 голосов
/ 07 мая 2013

Этот код не качество продукции.Вместо этого используйте предложение Криса из комментариев: https://issuetracker.google.com/issues/35823607#comment4


Этот вопрос изначально задавался для Maps API v1.Этот ответ предназначен для v2, но его можно легко изменить на v1, поэтому ...

Нет простого способа сделать это.

Возможно, вы захотите запросить эту функцию на gmaps-api-questions .

Поскольку ожидание того, чтобы это было реализовано на стороне Google, может занять несколько месяцев, вот что я бы сделал:

private static final double ASSUMED_INIT_LATLNG_DIFF = 1.0;
private static final float ACCURACY = 0.01f;

public static LatLngBounds boundsWithCenterAndLatLngDistance(LatLng center, float latDistanceInMeters, float lngDistanceInMeters) {
    latDistanceInMeters /= 2;
    lngDistanceInMeters /= 2;
    LatLngBounds.Builder builder = LatLngBounds.builder();
    float[] distance = new float[1];
    {
        boolean foundMax = false;
        double foundMinLngDiff = 0;
        double assumedLngDiff = ASSUMED_INIT_LATLNG_DIFF;
        do {
            Location.distanceBetween(center.latitude, center.longitude, center.latitude, center.longitude + assumedLngDiff, distance);
            float distanceDiff = distance[0] - lngDistanceInMeters;
            if (distanceDiff < 0) {
                if (!foundMax) {
                    foundMinLngDiff = assumedLngDiff;
                    assumedLngDiff *= 2;
                } else {
                    double tmp = assumedLngDiff;
                    assumedLngDiff += (assumedLngDiff - foundMinLngDiff) / 2;
                    foundMinLngDiff = tmp;
                }
            } else {
                assumedLngDiff -= (assumedLngDiff - foundMinLngDiff) / 2;
                foundMax = true;
            }
        } while (Math.abs(distance[0] - lngDistanceInMeters) > lngDistanceInMeters * ACCURACY);
        LatLng east = new LatLng(center.latitude, center.longitude + assumedLngDiff);
        builder.include(east);
        LatLng west = new LatLng(center.latitude, center.longitude - assumedLngDiff);
        builder.include(west);
    }
    {
        boolean foundMax = false;
        double foundMinLatDiff = 0;
        double assumedLatDiffNorth = ASSUMED_INIT_LATLNG_DIFF;
        do {
            Location.distanceBetween(center.latitude, center.longitude, center.latitude + assumedLatDiffNorth, center.longitude, distance);
            float distanceDiff = distance[0] - latDistanceInMeters;
            if (distanceDiff < 0) {
                if (!foundMax) {
                    foundMinLatDiff = assumedLatDiffNorth;
                    assumedLatDiffNorth *= 2;
                } else {
                    double tmp = assumedLatDiffNorth;
                    assumedLatDiffNorth += (assumedLatDiffNorth - foundMinLatDiff) / 2;
                    foundMinLatDiff = tmp;
                }
            } else {
                assumedLatDiffNorth -= (assumedLatDiffNorth - foundMinLatDiff) / 2;
                foundMax = true;
            }
        } while (Math.abs(distance[0] - latDistanceInMeters) > latDistanceInMeters * ACCURACY);
        LatLng north = new LatLng(center.latitude + assumedLatDiffNorth, center.longitude);
        builder.include(north);
    }
    {
        boolean foundMax = false;
        double foundMinLatDiff = 0;
        double assumedLatDiffSouth = ASSUMED_INIT_LATLNG_DIFF;
        do {
            Location.distanceBetween(center.latitude, center.longitude, center.latitude - assumedLatDiffSouth, center.longitude, distance);
            float distanceDiff = distance[0] - latDistanceInMeters;
            if (distanceDiff < 0) {
                if (!foundMax) {
                    foundMinLatDiff = assumedLatDiffSouth;
                    assumedLatDiffSouth *= 2;
                } else {
                    double tmp = assumedLatDiffSouth;
                    assumedLatDiffSouth += (assumedLatDiffSouth - foundMinLatDiff) / 2;
                    foundMinLatDiff = tmp;
                }
            } else {
                assumedLatDiffSouth -= (assumedLatDiffSouth - foundMinLatDiff) / 2;
                foundMax = true;
            }
        } while (Math.abs(distance[0] - latDistanceInMeters) > latDistanceInMeters * ACCURACY);
        LatLng south = new LatLng(center.latitude - assumedLatDiffSouth, center.longitude);
        builder.include(south);
    }
    return builder.build();
}

Использование:

LatLngBounds bounds = AndroidMapsExtensionsUtils.boundsWithCenterAndLatLngDistance(new LatLng(51.0, 19.0), 1000, 2000);
map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0));

Примечания:

  • этот код не был полностью протестирован, может не работать для крайних случаев
  • вы можете настроить частные константы, чтобы он выполнялся быстрее
  • вы можете удалить 3-ю часть, где вычисляется LatLng south, и сделать это, как для долгот: это будет точно для малых значений latDistance (предполагаю, что вы не увидите разницу ниже 100 км)некрасиво, так что не стесняйтесь рефакторинг
3 голосов
/ 17 июля 2013

Хотя приведенный выше ответ может сработать, на самом деле он не выглядит прямым, как уже упоминал автор. Вот код, который работает для меня. Обратите внимание, что в коде предполагается, что Земля является идеальной сферой.

double latspan = (latMeters/111325);
double longspan = (longMeters/111325)*(1/ Math.cos(Math.toRadians(location.latitude))); 

LatLngBounds bounds = new LatLngBounds(
    new LatLng(location.latitude-latspan, location.longitude-longspan),
    new LatLng(location.latitude+latspan, location.longitude+longspan));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...