在Android中获取可见地图的半径

18

有没有可能从中心点找到可见地图的半径?

Google 地图

我想从 API 中获取距离地图中心点最近的位置,该 API 要求提供纬度、经度和半径。我能够从中心点获取纬度和经度,但无法找到获取半径的方法。

谢谢。

5个回答

21

对于Google Maps Android API,您可以通过以下方式获取边界:

从地图引用中,通过getProjection()获取Projection。 然后,

投影用于在屏幕位置和地理坐标之间进行转换。

所以从投影中,我们可以使用getVisibleRegion()来获取地图的VisibleRegion,其中包含一个LatLngBounds,它是一个包含两个LatLng变量的类,一个用于边界的东北角,另一个用于西南角。

因此,代码应该如下所示:

        googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition position) {
                LatLngBounds bounds = googleMap.getProjection().getVisibleRegion().latLngBounds;
                LatLng northeast = bounds.northeast;
                LatLng southwest = bounds.southwest;

                Context context = getApplicationContext();
                CharSequence text = "ne:"+northeast+" sw:"+southwest;
                int duration = Toast.LENGTH_SHORT;

                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
            }
        });

=-=-=-=-=-= 编辑:

也许我太天真了,只给出东北和西南方向可以解决这个问题,但这仅适用于用户未旋转地图或倾斜三维地图的特殊情况。

因此,您只需要获取VisibleRegion,它提供了4个变量:farRight、farLeft、nearRight、nearLeft,分别代表区域的4个角落。

然后我们可以计算该4个点所表示区域的宽度和高度,并选择较小的一个(有时宽度可能大于高度)。

至于计算,我们只需要使用Location.distanceBetween(x1,y1,x2,y2,result)函数......

这使得代码看起来像以下内容:

                VisibleRegion visibleRegion = googleMap.getProjection().getVisibleRegion();

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

                float[] distanceWidth = new float[2];
                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[2];
                Location.distanceBetween(
                        (farRight.latitude+nearRight.latitude)/2,
                        (farRight.longitude+nearRight.longitude)/2,
                        (farLeft.latitude+nearLeft.latitude)/2,
                        (farLeft.longitude+nearLeft.longitude)/2,
                        distanceHeight
                );

                float distance;

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

1
我原本想说剩下的只是一个数学问题,但我想我太天真了。顺便提一下,这个距离以米为单位。 - kaho
你建议的第二种方法确实非常有效。谢谢@kaho。 - Anil Gorthy
@kaho,正如“三思而后行”的说法一样,这种方法很好,但我想在计算高度时,您误将纬度考虑在内,最终又得到了宽度。您应该像“三思而后行”所做的那样考虑经度。 - Apoorv Karkare

14
非常感谢您的回答@kaho,它帮了我很多(甚至您以相同的方式计算了distanceWidth和distanceHeight)。
澄清:
  • farLeft 是定义摄像机左上角的LatLng对象。

  • farRight 是定义摄像机右上角的LatLng对象。

  • nearLeft 是定义摄像机左下角的LatLng对象。

  • nearRight 是定义摄像机右下角的LatLng对象。

编辑:我不知道为什么我们把一个简单的计算变得有点复杂,可见半径只是可见对角线的一半,就是这样!

进入图像描述

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

        float[] diagonalDistance = new float[1];

        LatLng farLeft = visibleRegion.farLeft;
        LatLng nearRight = visibleRegion.nearRight;

        Location.distanceBetween(
                farLeft.latitude,
                farLeft.longitude,
                nearRight.latitude,
                nearRight.longitude,
                diagonalDistance
        );

        return diagonalDistance[0] / 2;
    }

我也记录了我的结果以与@jossef-harush的结果进行比较,大约是:

输入图片描述


在多少弧度内?我这里得到了一些非常大的数字,看起来像是米。 - franklinexpress
是的,visibleRadius 的值以米为单位。 - Phong Nguyen
如何排除不属于可见地图/区域的区域?我指的是左/右半径曲线超出可见范围的情况。 - VVB
1
@VVB 你想计算可见矩形区域的面积吗?很简单,只需从VisibleRegion的4个角点计算即可。 - Phong Nguyen
谢谢回复。我认为你现有的答案已经按照这种方式计算了。正确吗? - VVB

2

覆盖整个区域,甚至角落!

我没有看到其他答案覆盖了整个地图区域;

请参见下面的图像,为了测试它,我绘制了一个圆形叠加层来查看计算出的半径边界,它并未覆盖整个地图区域。

我的修改非常简单,我使用勾股定理找到适合包含地图“矩形”的半径。


输入图片说明


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

谢谢!我发现我的答案不正确。但是我也找到了更简单的计算可见半径的方法。我们已经有了坐标值,所以不需要应用勾股定理来分别计算宽度和高度的距离,你可以查看我的更新答案。 - Phong Nguyen
如何排除不属于可见地图/区域的区域?我指的是左/右半径曲线超出可见范围的情况。 - VVB
1
VVB 圆形的一个常见用例是使用地理经纬度和半径来从数据库中过滤出仅相关的数据。您可以根据视口的矩形边界框手动过滤掉超出视口的结果。 - Jossef Harush Kadouri

2
对于Kotlin用户,从setOnCameraIdleListener调用此函数。
    private fun getMapVisibleRadius(): Double {
    val visibleRegion: VisibleRegion = mMap.projection.visibleRegion

    val distanceWidth = FloatArray(1)
    val distanceHeight = FloatArray(1)

    val farRight: LatLng = visibleRegion.farRight
    val farLeft: LatLng = visibleRegion.farLeft
    val nearRight: LatLng = visibleRegion.nearRight
    val nearLeft: LatLng = 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)

    val radiusInMeters = Math.sqrt((Math.pow(distanceWidth.get(0).toString().toDouble(), 2.0))
            + Math.pow(distanceHeight.get(0).toString().toDouble(), 2.0)) / 2
    return radiusInMeters
}

0

编辑:以下答案适用于Google Maps JavaScript API v3
=-=-=-=-=-=-=

我认为答案是:可以。

根据文档,您可以通过computeDistanceBetween(LatLngFrom, LatLngTo)计算2点之间的距离。

此外,您还可以使用getBounds()方法获取地图的边界,该方法位于google.maps.Map类中。


谢谢回复,但这些方法和链接不是指的v3吗?目前只有JavaScript可用? - awaistoor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接