【问题标题】:MKCoordinateRegionMakeWithDistance equivalent in AndroidMKCoordinateRegionMakeWithDistance 在 Android 中的等效项
【发布时间】:2011-09-07 15:43:50
【问题描述】:

我们可以在 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 有没有等效的方法?

【问题讨论】:

    标签: android google-maps area


    【解决方案1】:

    此代码不是生产质量。在这里使用来自 cmets 的 Chris 建议:https://issuetracker.google.com/issues/35823607#comment4


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

    没有简单的方法。

    您可能想request this feature on gmaps-api-issues

    由于等待在 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));
    

    注意事项:

    • 此代码尚未经过全面测试,可能不适用于边缘情况
    • 您可能需要调整私有常量以使其执行得更快
    • 您可以删除计算 LatLng south 的第 3 部分,并像处理经度一样:这对于较小的 latDistance 值是准确的(假设您在 100 公里以下看不到差异)
    • 代码很丑,请随意重构

    【讨论】:

    【解决方案2】:

    虽然上述答案可能有效,但正如作者已经提到的那样,它并没有真正向前看。这是一些对我有用的代码。请注意,代码假设地球是一个完美的球体。

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

    【讨论】:

    • 简单、简洁且足以满足大多数应用程序的需要。谢谢
    • 111325 的数字是什么?
    • 如果这能解释什么是 111325 会更好。
    猜你喜欢
    • 1970-01-01
    • 2012-07-17
    • 2012-08-03
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多