我如何知道一个 Lat,Lng 点是不是包含在一个圆圈内?
Posted
技术标签:
【中文标题】我如何知道一个 Lat,Lng 点是不是包含在一个圆圈内?【英文标题】:How do I know if a Lat,Lng point is contained within a circle?我如何知道一个 Lat,Lng 点是否包含在一个圆圈内? 【发布时间】:2011-05-26 17:18:54 【问题描述】:好的,不言自明。我正在使用谷歌地图,我试图找出一个经纬度点是否在半径为 x 的圆内(x 由用户选择)。
边界框不适用于此。我已经尝试过使用以下代码:
distlatLng = new google.maps.LatLng(dist.latlng[0],dist.latlng[1]);
var latLngBounds = circle.getBounds();
if(latLngBounds.contains(distlatLng))
dropPins(distlatLng,dist.f_addr);
这仍然会导致标记位于圆圈之外。
我猜这是一些需要计算曲率或面积的简单数学,但我不确定从哪里开始。有什么建议吗?
【问题讨论】:
This SO 帖子可能会为您提供所需的见解。 【参考方案1】:带有可拖动中心标记的工作解决方案
你试过contains
吗?看看LatLngBounds
构造函数。
我写了一篇关于它的文章,其中包含指向有效JSFiddle.net example 的链接。
Updated version.
【讨论】:
@zavidovych 这是一个已知的错误。它已经消失了一段时间,我猜是 v3.9 回来了。我已经提交了错误报告。还有一种方法,我会在有时间的时候发布。 很好的解决方案。当我需要它时不可用:) 很好的解决方案。到目前为止,包含似乎正在工作。 这个例子在demo.developerextensions.com/answers/…的修改版本,它也使用自定义函数检查距离,可以在没有google lib的情况下使用 @surindersingh 那是一个伟大的!谢谢!您可能想将其添加到答案中(请提交edit)。【参考方案2】:这很简单。您只需要计算中心和给定点之间的距离并将其与半径进行比较。您可以从 here获取帮助计算两个纬度之间的距离
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review 感谢@fasteque 的信息 :) @fasteque 他提到的解决方案很简单。最好在您的问题/建议中包含更多详细信息,说明您到底想要什么或正在寻找什么。 @NBhargav 最好包含外部链接的相关部分,或者如果无法访问,请提供代码示例。回答指南中清楚地写了:***.com/help/how-to-answer【参考方案3】:不幸的是,毕达哥拉斯对球体没有帮助。因此 Stuart Beard 的回答是不正确的;经度差异与米没有固定的比例,而是取决于纬度。
正确的方法是使用大圆距离公式。假设一个球形地球,一个很好的近似值是这样的(在 C++ 中):
/** Find the great-circle distance in metres, assuming a spherical earth, between two lat-long points in degrees. */
inline double GreatCircleDistanceInMeters(double aLong1,double aLat1,double aLong2,double aLat2)
aLong1 *= KDegreesToRadiansDouble;
aLat1 *= KDegreesToRadiansDouble;
aLong2 *= KDegreesToRadiansDouble;
aLat2 *= KDegreesToRadiansDouble;
double cos_angle = sin(aLat1) * sin(aLat2) + cos(aLat1) * cos(aLat2) * cos(aLong2 - aLong1);
/*
Inaccurate trig functions can cause cos_angle to be a tiny amount
greater than 1 if the two positions are very close. That in turn causes
acos to give a domain error and return the special floating point value
-1.#IND000000000000, meaning 'indefinite'. Observed on VS2008 on 64-bit Windows.
*/
if (cos_angle >= 1)
return 0;
double angle = acos(cos_angle);
return angle * KEquatorialRadiusInMetres;
在哪里
const double KPiDouble = 3.141592654;
const double KDegreesToRadiansDouble = KPiDouble / 180.0;
和
/**
A constant to convert radians to metres for the Mercator and other projections.
It is the semi-major axis (equatorial radius) used by the WGS 84 datum (see http://en.wikipedia.org/wiki/WGS84).
*/
const int32 KEquatorialRadiusInMetres = 6378137;
【讨论】:
完全同意这是正确的。然而,当时并不要求 100% 的准确度。 您仍然选择了一个在两极附近有危险错误的答案,@StuartBeard,我完全赞成在适当的情况下进行近似,但我认为您在非笛卡尔空间中选择笛卡尔距离因为“答案”是不负责任的。【参考方案4】:使用 Google Maps API 几何库计算圆心与标记之间的距离,然后将其与半径进行比较。
var pointIsInsideCircle = google.maps.geometry.spherical.computeDistanceBetween(circle.getCenter(), point) <= circle.getRadius();
【讨论】:
【参考方案5】:以下代码适用于我:我的标记不能拖到圆圈外,而是挂在其边缘(在任何方向)并保留最后一个有效位置。
该函数是标记“拖动”事件的事件处理程序。
_markerDragged : function()
var latLng = this.marker.getPosition();
var center = this.circle.getCenter();
var radius = this.circle.getRadius();
if (this.circleBounds.contains(latLng) &&
(google.maps.geometry.spherical.computeDistanceBetween(latLng, center) <= radius))
this.lastMarkerPos = latLng;
this._geocodePosition(latLng);
else
// Prevent dragging marker outside circle
// see (comments of) http://unserkaiser.com/code/google-maps-marker-check-if-in-circle/
// see http://www.mvjantzen.com/blog/?p=3190 and source code of http://mvjantzen.com/cabi/trips4q2012.html
this.marker.setPosition(this.lastMarkerPos);
,
感谢http://unserkaiser.com/code/google-maps-marker-check-if-in-circle/ 和http://www.mvjantzen.com/blog/?p=3190。
【讨论】:
【参考方案6】:我真的有点傻。考虑一下我们可以使用毕达哥拉斯定理。
我们与一个点的最大距离(X 英里),以及两个纬度和两个经度。如果我们使用这些形成一个三角形,那么我们可以求解到该点的距离。
假设我们知道point1
坐标为lat1,lng1
是圆的中心,point2
坐标为lat2,lng2
是我们试图确定的点是否在圆内。
我们使用由point1
和point2
确定的点形成一个直角三角形。这,point3
将有坐标lat1,lng2
或lat2,lng1
(哪个没关系)。然后我们计算差异(或者如果您愿意)距离 - latDiff = lat2-lat1
和 lngDiff = lng2-lng1
然后我们使用毕达哥拉斯计算距中心的距离 - dist=sqrt(lngDiff^2+latDiff^2)
。
我们必须将所有内容都转换为米,以便它可以在谷歌地图上正常工作,因此英里乘以 1609(大约),纬度/经度乘以 111000(大约)。这并不完全准确,但它做得很好。
希望一切都有意义。
【讨论】:
在这里聚会有点晚了,但您有没有考虑到使用的地图投影会扭曲物体的形状和距离? 这完全忽略了地图投影。纬度和经度不等间距!它在北纬或南纬根本行不通。只在赤道附近。这是错误的。 @CarlF。是的,这是对的。使用地图时有更好的解决方案。看到这个答案***.com/a/10428729/1202145 @NBhargav,您的链接非常接近正确答案!它可能仍然存在问题。我没有检查数学,但要注意将弧近似为直线。可以使澳大利亚悉尼看起来更接近美国波士顿。以上是关于我如何知道一个 Lat,Lng 点是不是包含在一个圆圈内?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 StandaloneSearchBox 获取 Lat 和 Lng?
RestKit 将包含 lat & lng 的数组映射到 CoreData