【发布时间】:2015-05-06 10:18:14
【问题描述】:
如何用 lng 和 lat 获得地球上两点之间的距离或弧度?
【问题讨论】:
标签: geolocation geometry geospatial
如何用 lng 和 lat 获得地球上两点之间的距离或弧度?
【问题讨论】:
标签: geolocation geometry geospatial
在这种情况下,您可能不想要mapReduce,但实际上是aggregation framework。除了一般的第一阶段查询外,您还可以通过$geoNear 运行,这对您的目的更有效。
db.places.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -88 , 30 ]
},
"distanceField": "dist"
}},
{ "$match": {
"loc": {
"$centerSphere": [ [ -88 , 30 ] , 0.1 ]
}
}}
])
或者坦率地说,因为最初的$geoNear 阶段会将一个附加字段“投影”到包含与查询的“原点”的“距离”的文档中,那么您可以在后续的那个元素上“过滤”阶段:
db.places.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -88 , 30 ]
},
"distanceField": "dist"
}},
{ "$match": {
"dist": { "$lte": 0.1 }
}}
])
由于这是一个可以“生成/投影”表示结果中距离的值的选项,因此满足您的第一个标准。 “聚合框架”的“链接”性质允许“附加过滤”或您在过滤初始查询后需要执行的任何其他操作。
所以$geoWithin 在$match 阶段下的聚合框架中的工作效果与在任何标准查询中一样好,因为它不“依赖”于存在的地理空间来源的“索引”。它在带有一个的初始查询中表现更好,但它不需要它。
由于您的要求是距原点的“距离”,因此最合乎逻辑的做法是执行将返回此类信息的操作。就是这样。
希望在此回复中包含所有相关链接,但作为新的回复者,我现在只允许两个链接。
另一个相关说明:
任何操作中“距离”或“半径”的测量取决于数据的存储方式。如果它是“传统”或“键/对或普通数组”格式,则该值将以“弧度”表示,否则如果数据在“位置”上以 GeoJSON 格式表示,则“距离数据”为改为以“米”表示。
考虑到 MongoDB 服务实现的库以及它如何与存储的数据交互,这是一个重要的考虑因素。如果您愿意正确查看,官方资源中当然有关于此的文档。再说一次,我现在不能添加这些链接,除非这个回复看到了一些急需的爱。
【讨论】:
$geoNear操作和另一种单独的命令形式geoNear是返回点之间投影“距离”的唯一方法,没有办法用 mapReduce 调用它。我可以注意到,除了“如何返回距离”之外,您真的不会问任何其他问题,示例当然会这样做。否则,您将需要包含必要的 JavaScript 代码才能计算距离。无论如何,聚合可能是获得您想要的结果的更好方法。它当然更快。
https://github.com/mongodb/mongo/blob/master/src/third_party/s2/s2latlng.cc#L37
GetDistance() 返回一个 S1Angle,S1Angle::radians() 将返回弧度。
这属于 s2-geometry-library(google code 将关闭,我将其导出到我的github。Java)。
【讨论】: