如何查找指定位置附近的位置

时间:2015-08-07 09:10:02

标签: python mongodb geolocation mongodb-query

我正在尝试使用Python3为给定的纬度和经度创建一个具有一定距离(或半径)的边界框(或圆)。

我已经解决了此问题的先前解决方案,但我对它是如何工作有疑问。有一些变量,例如halfsideinKm和一些degree to radianradian to degree转换,我无法理解这些转换是什么以及它是如何工作的。

Given lat and long finding binding box

Geocoding calculate bounding box

我有一个数据库集合Locations(在MongoDB中),它包含lat和long。

我的要求是,如果我输入一个纬度很长,我想要有一个位于边界框区域内的位置列表(来自我的mongodb)(距离为20公里)。

任何人都可以为我提供这个问题的解决方案,或者解释这些代码的工作方式吗?

是否可以使用geopy来实现?(因为它说的是关于大圆距离计算的内容)

数据库值

{
  "place_id":"151142295",
  "osm_type":"relation",
  "osm_id":"65606",
  "lat":"51.5073219",
  "lon":"-0.1276474",
  "display_name":"London, Greater London, England, United Kingdom",
  "class":"place",
  "type":"city",
  "importance":0.9754895765402
},
{
  "place_id":"4566287",
  "osm_type":"node",
  "osm_id":"485248691",
  "lat":"42.988097",
  "lon":"-81.2460295",
  "display_name":"London, Ontario, Canada",
  "class":"place",
  "type":"city",
  "importance":0.6515723047601
}

(只是数据如何存储在我的数据库中的样本)

1 个答案:

答案 0 :(得分:1)

如果您打算在MongoDB中使用地理空间查询,那么您必须做的第一件事就是更改存储数据的方式。您可以选择传统坐标对或GeoJSON格式。但是你当前在单独字段中使用“lat”和“long”以及“字符串”的存储将无效。

这是针对mongo shell编写的集合的架构修复,因为这应该是一次性操作。我正在为GeoJSON提供建议,因为它通常与很多库兼容,并且所有返回的距离都以公里为单位而不是弧度。

var bulk = db.collection.initializeUnorderedBulkOp(),
    count = 0;

db.collection.find().forEach(function(doc) {
   bulk.find({ "_id": doc._id }).updateOne({
       "$set": {
           "location": {
               "type": "Point",
               "coordinates": [parseFloat(doc.lon),parseFloat(doc.lat)]
           }        
       },
       "$unset": { "lat": "", "lon": "" }
   });
   count++;

   if ( count % 1000 == 0 ) {
       bulk.execute();
       bulk = db.collection.initializeUnorderedBulkOp();
   }
});

if ( count % 1000 !=0 )
   bulk.execute();

现在数据已修复并与索引兼容,创建索引。这里使用GeoJSON数据有意义的是"2sphere"索引:

db.collection.createIndex({ "location": "2dsphere" })

现在您已准备好进行查询。坚持使用shell作为python语法是相同的,我不知道你的库调用:

db.collection.find({
    "location": {
        "$nearSphere": {
            "$geometry": {
                "type": "Point",
                "coordinates": [lon,lat]
            },
            "$maxDistance": distance
        }
    }
})

此查询使用$nearSphere,它将根据地球曲率正确计算距离,非常适合实际位置数据。您的三个变量是坐标数组中的“经度”,“纬度”(按此顺序)和$maxDistance下要在该半径内查找事物的“距离”。

一旦您的数据合适且必需地理空间索引到位,这是一个非常简单的查询过程。

无需在客户端进行混乱的计算,因为服务器可以完成所有工作。

所有相关文档部分的链接都包含在内供您参考。阅读它们并了解有关使用MongoDB的地理空间查询的更多信息。