MKCoordinateRegionMakeWithDistance 在 Android 中等效 [英] MKCoordinateRegionMakeWithDistance equivalent in Android

查看:28
本文介绍了MKCoordinateRegionMakeWithDistance 在 Android 中等效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们可以在 iPhone 的地图上设置特定位置的周边区域,如下所示

We can set the surrounding area for particular location on map in iPhone as following

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 有什么等效的方法吗?

Is there any equivalent method for Android?

推荐答案

此代码不是生产质量.请改用此处评论中的 Chris 建议:https://issuetracker.google.com/issues/35823607#评论 4

This code is not production quality. Use Chris suggestion from comments here instead: https://issuetracker.google.com/issues/35823607#comment4

这个问题最初是针对 Maps API v1 提出的.此答案适用于 v2,但可以轻松更改为 v1,因此...

This question was originally asked for Maps API v1. This answer is for v2, but can be easily changed to v1, so...

没有简单的方法可以做到.

No easy way to do it.

您可能想要在 gmaps-api-issues 上请求此功能.

由于等待 Google 方面的实施可能需要几个月的时间,所以我会这样做:

As waiting for this to be implemented on Google side can take several months, so this is what I would do:

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));

注意事项:

  • 此代码尚未经过全面测试,可能不适用于边缘情况
  • 您可能想要调整私有常量以使其执行得更快
  • 您可以删除计算 LatLng south 的第三部分,并像计算经度一样这样做:这对于较小的 latDistance 值是准确的(猜想您不会看到 100 公里以下的差异)
  • 代码很丑,所以可以随意重构
  • this code has not been fully tested, may not work for edge cases
  • you may want to adjust private constants to have it execute faster
  • you may remove 3rd part where LatLng south is calculated and do it like for longitudes: this will be accurate for small values of latDistance (guessing you will not see a difference under 100km)
  • code is ugly, so feel free to refactor

这篇关于MKCoordinateRegionMakeWithDistance 在 Android 中等效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆