猫鼬通过半径找到地理点

时间:2016-03-23 23:03:51

标签: node.js mongoose

我尝试通过半径找到地理点,我发现教程解释了如何做到这一点。

教程摘录:

首先我们需要创建一个架构。文档为我们提供了一些如何存储地理空间数据的示例。我们将使用遗留格式作为示例。建议将经度和纬度存储在数组中。文档警告使用值的顺序,经度是第一位的。

var LocationSchema = new Schema({  
  name: String,
  loc: {
  type: [Number],  // [<longitude>, <latitude>]
  index: '2d'      // create the geospatial index
 }
});

首先,您可以在控制器中创建一个类似于以下内容的方法:

findLocation: function(req, res, next) {  
    var limit = req.query.limit || 10;

    // get the max distance or set it to 8 kilometers
    var maxDistance = req.query.distance || 8;

    // we need to convert the distance to radians
    // the raduis of Earth is approximately 6371 kilometers
    maxDistance /= 6371;

    // get coordinates [ <longitude> , <latitude> ]
    var coords = [];
    coords[0] = req.query.longitude;
    coords[1] = req.query.latitude;

    // find a location
    Location.find({
      loc: {
        $near: coords,
        $maxDistance: maxDistance
      }
    }).limit(limit).exec(function(err, locations) {
      if (err) {
        return res.json(500, err);
      }

      res.json(200, locations);
    });
}

参考教程: How to use Geospatial Indexing in MongoDB with Express and Mongoose

从教程实施源到我的项目后,我没有通过半径从数据库中获得正确的点(点不在半径范围内)。

我的问题是我如何通过半径(公里或米不重要)接收地理位置?

谢谢,迈克尔。

2 个答案:

答案 0 :(得分:2)

我在我自己的数据库中处理过类似的问题。挖掘并找到答案很棘手,所以我将在这里分享。 Mongoose的DB包的地理空间元素没有很好的文档记录。

var locQuery = (coords, distance) => { return { loc: { $near: { $geometry: { type: "Point", coordinates: coords }, $maxDistance: parseInt(distance)}}} } 查询中,您需要使用比上面更复杂的对象。我发现以下构造工作,其中maxDistance以米为单位,而coords是[经度,纬度]的数组。

{{1}}

这消除了处理地球周长和所有混乱的需要。现在,这种查询风格在Mongoose中是原生的。我发现下面的函数有助于快速进行这些查询,因此您不必每次都处理那么多的格式。

{{1}}

答案 1 :(得分:0)

不确定这仍然是多么相关,因为它是在 2016 年发布的,但我遇到了类似的问题。 我正在使用以下配置:

  • MongoDB:4.4.5
  • 猫鼬:5.12.3
  • Node.js:15.9.0

我必须用弧度分割公里才能得到半径。所以如果我想要一公里半径内的所有东西,我必须计算 1/6371

另外,请注意 Mongo(和 mongoose)坐标必须是一个数值数组,经度 BEFORE 是纬度。这既适用于存储在数据库中的对象,也适用于查询。

const km = 1;
const radius = km / 6371;

const longitude = 25;
const latitude = 20;

const area = { center: [longitude, latitude], radius: radius, unique: true, spherical: true };
query.where('geo').within().circle(area);

请记住,您的 loc 必须是 mongoose docs 中指定的点架构 (geojson)。

例如:

const pointSchema = new mongoose.Schema({
  type: {
    type: String,
    enum: ['Point'],
    required: true
  },
  coordinates: {
    type: [Number],
    required: true
  }
});

const locationSchema = new mongoose.Schema({
  name: String,
  loc: {
    type: pointSchema,
    required: true
  }
});