如何在 Android Google Maps API v2 中将 LatLng 和半径转换为 ​​LatLngBounds?

Posted

技术标签:

【中文标题】如何在 Android Google Maps API v2 中将 LatLng 和半径转换为 ​​LatLngBounds?【英文标题】:How to convert a LatLng and a radius to a LatLngBounds in Android Google Maps API v2? 【发布时间】:2013-02-25 11:58:26 【问题描述】:

我认为这是最近的 Google Maps API v2 的限制。他们最近添加了在地面上绘制圆圈的功能 - 但如果您想定位相机以使其显示整个圆圈,则没有办法这样做。

可以调用 CameraUpdateFactory#newLatLngBounds(bounds, padding),其中“bounds”是 LatLngBounds,“padding”是以像素为单位的距离。问题是无法在 LatLngBounds 中创建 LatLng 和半径。

LatLngBounds 的构造函数只接受 2 个 LatLng 实例并生成一个矩形,其中这些是 NW 和 SE 角。

【问题讨论】:

【参考方案1】:

就像提到的Risadinha 一样,您可以使用android-maps-utils 轻松实现这一目标。只需添加:

compile 'com.google.maps.android:android-maps-utils:0.4.4'

到你的 gradle 依赖,使用下面的代码:

public LatLngBounds toBounds(LatLng center, double radiusInMeters) 
    double distanceFromCenterToCorner = radiusInMeters * Math.sqrt(2.0);
    LatLng southwestCorner =
                SphericalUtil.computeOffset(center, distanceFromCenterToCorner, 225.0);
    LatLng northeastCorner = 
                SphericalUtil.computeOffset(center, distanceFromCenterToCorner, 45.0);
    return new LatLngBounds(southwestCorner, northeastCorner);

编辑:

我们的目标是计算两个点 (LatLngs):

southwestCorner

northeastCorner

SphericalUtil 的javadoc 中,您可以看到22545heading 值,而distanceFromCenterToCornerdistance。下图中数值的进一步解释:

【讨论】:

什么是 225 和 45 ?为什么需要 sqrt? 仅供参考,如果其他人想知道(和我一样),distance,因此radius,以米为单位。 为什么要乘以sqrt(2)。第二个参数不是以米为单位的距离吗? @RobertDolca 因为你想计算从中心到右上角(或左下角)的距离,所以它被相乘了。如果你没有将它乘以sqrt(2),你会得到从中心到顶部(或底部)edge的距离。 最新的是:compile 'com.google.maps.android:android-maps-utils:0.4.4'【参考方案2】:

使用 javascript 库,您可以绘制一个具有中心和半径的圆,然后获取它的边界。

centerSfo = new google.maps.LatLng(37.7749295, -122.41941550000001);
circle = new google.maps.Circle(radius: 5000, center: centerSfo);
bounds = circle.getBounds();

您可以使用 android api 来做同样的事情。

【讨论】:

是的,这可能是我能在这里得到的最佳答案。只是小更新: var circle = new window.google.maps.Circle(center: ,map: , radius: , //fillColor: '#FF0000' ); 其实不能,因为没有getBounds方法。 是的,there is in APIv3,效果很好! APIv2 没有,需要一种解决方法。所以既然 OP 已经很老了,它应该解决后来的 API v3。 你链接了Javascript API,Android API没有【参考方案3】:

这是完全可行的。

LatLng 是您的圆心吗?你想要做的是在LatLngBounds 内写上你的圆圈(圆圈内的正方形问题),这样整个东西就会显示在地图上。

如果您在纸上绘制此图,您会发现您拥有计算LatLngBounds 所需的一切。

还记得怎么find the lengths of the sides of a right triangle吗?

a² + b² = c²

如果你从你的圆心画一条线到西北(左上)角,再画一条直线到正方形的西墙(从中心到左边的直线)你有一个三角形。现在您可以使用上面的等式求解c,因为您知道三角形其他边的长度(圆的半径)。

所以现在你的方程变成了

r² + r² = c²

减少到

2r² = c²

进一步简化为

c = squareRoot(2) * r

现在你有距离了。这当然是过于简单化了,因为地球不是平的。如果距离不是很大,您可以使用上面相同的等式,但修改为将球形地球投影到平面上:

http://en.wikipedia.org/wiki/Geographical_distance#Flat-surface_formulae

请注意,这也使用Pythagorean theorem,与我们在上面所做的相同。

接下来,您需要根据给定方位的中心点和上面找到的距离计算端点(西北角和东南角)。

这篇文章可能会有所帮助:Calculate endpoint given distance, bearing, starting point

使用上面链接中的公式时,不要忘记将度数转换为弧度! (度数乘以pi/180

【讨论】:

@EmilAdz 目前有点不正确,因为距离方程正在计算平面值,而它应该计算测地线值。除非读者是Flat-Earther,否则应该没问题。 感谢@ChristopherPerry,但我有点希望通过现有的 Android API 找到某种方法来做到这一点。虽然您的解决方案是正确的(对于足够小的圆圈),但需要重写大量容易出错的逻辑。 好吧,对于 X 框架没有提供的东西,我不得不多次滚动自己的代码。为什么不做一些 TDD 并编写一些测试来驱动代码,然后你就会知道它的工作方式是你所期望的?它不应该是一个大函数,它可以分解为多个部分,并且每个部分都单独测试,因此如果出现错误,您将确切知道在哪里查看或改进您的算法。 嗨@ChristopherPerry,我可以从这个答案中获得一些信息以满足我的需要。我想为“X”缩放级别的半径计算设备上的像素数。基本上我在地图上覆盖了自己的圆圈来创建区域。现在我想根据缩放级别调整圆圈的宽度。你能帮我一个线索吗? 嗨@ChristopherPerry,我刚刚在这里发布了问题***.com/questions/35295605/…【参考方案4】:

Google 提供了一个实用程序库:

http://googlemaps.github.io/android-maps-utils/

由 Google 推荐用于此任务和示例代码: http://code.google.com/p/gmaps-api-issues/issues/detail?id=5704

【讨论】:

【参考方案5】:

虽然Bartek Lipinski's 的答案是正确的,如果您的 LatLngBounds 定义了一个正方形,大多数 LatLngBounds 定义了矩形,因此,东北点和西南点与中心的方位角并不总是 45 度和 255 度.

因此,如果您希望从任何四边形的中心获取半径的 LatLngBounds,请像这样使用初始 bounds.northeastbounds.southwest 的坐标(使用 SphericalUtils):

LatLng northEast = SphericalUtil.computeOffset(center, radius * Math.sqrt(2.0), SphericalUtil.computeHeading(center, bounds.northeast));
LatLng southWest = SphericalUtil.computeOffset(center, radius * Math.sqrt(2.0), (180 + (180 + SphericalUtil.computeHeading(center, bounds.southwest))));

(180 + (180 + x)) 从中心顺时针计算西南点的方位角。

【讨论】:

以上是关于如何在 Android Google Maps API v2 中将 LatLng 和半径转换为 ​​LatLngBounds?的主要内容,如果未能解决你的问题,请参考以下文章

com.google.android.maps 在 Android Studio 中不存在

用户如何通过点击 google maps android 添加标记?

如何在 Google Maps Android SDK 的折线上添加形状

如何设置 Android Google Maps API v2 地图以显示全球地图?

Google Maps Android API - 如何在拖动时移动标记的锚点

如何使用 google maps api for android 将地图限制在一个国家/地区