【问题标题】:Mongoose $maxDistance not preciseMongoose $maxDistance 不精确
【发布时间】:2015-07-25 23:12:58
【问题描述】:

我将地点存储在 Mongoose 模型中(名称 + 坐标为 [lng, lat]),并且上面有一个 2d 索引。

我想从以公里为单位的半径内的点(lng,lat)获取最近的位置。

为此,我使用猫鼬的 $near 和 $maxDistance 参数。 我面临的问题是半径似乎并不精确,因此我得到了错误的结果。

这是我的地理搜索代码:

LocationModel.find({
        loc: {
            $near: coords,
            $maxDistance: max_distance
        }
    }).exec(function(err, locations)
    {
        if(err)
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });

        res.json(locations);
    });

我有两个测试地点:

地点 1:6.614090000000033, 45.4203

地点 2:6.905578500000047, 45.4683226

总距离:23.36km

$maxDistance 的 max_distance 是这样计算的:

var max_distance = req.params.max_distance / 111.12;

当我提供作为地点 A 的参考点时,我只会在我将 max_distance 设置为 33 公里及以上而不是 24 公里时获得结果。

有人可以解释一下这里出了什么问题吗?可能是 111.12(我在整个 Internet 上找到的),还是别的什么?

谢谢

【问题讨论】:

    标签: node.js mongodb mongoose geolocation


    【解决方案1】:

    1 度在赤道处大约 111 公里,您的 111.12 来自该处。但是当我们远离赤道时,由于当我们接近极点时子午线(经度)的会聚,它变得更少。

    Degree  Lat         Lng
    0°      110.574 km  111.320 km
    15°     110.649 km  107.551 km
    30°     110.852 km  96.486 km
    45°     111.132 km  78.847 km
    60°     111.412 km  55.800 km
    75°     111.618 km  28.902 km
    90°     111.694 km  0.000 km
    

    您可以为此使用equirectangular approximation

    x = Δlat * cos (Δlng/2)
    y = ΔLng
    d = R ⋅ √x² + y²
    where Δlat & Δlng in radians & R = radius of earth
    Δlat is the difference between the 2 lats  & Δlng that of lats 
    

    【讨论】:

    • 当我使用这个表时(即:将我的 max_distance 除以计算的 Lng),我找到了正确的值。但我找不到如何计算这个值。你能帮我解决这个问题并给我公式吗?我去的每个网站都提出了两个 lat / long 的公式(就像你的公式对 Δlat 和 Δlng 所做的那样),但我只有一个。
    • Δlat 是 2 个 lats 和 Δlng 之间的差异,对于 2 个 lngs 来说是相同的。
    【解决方案2】:

    由于您在谈论地理位置,我建议进行以下更改:

    1. 使用2dsphere 索引而不是2d。这将确保搜索考虑到地球不是二维平面。
    2. 更改您的模型以以 GeoJSON 格式表示坐标。

    所以你的架构应该是这样的:

        var LocationSchema = new mongoose.Schema({
          name: String,
          location: {
            type: {
               type: String,
               default: "Point"
            },
            coordinates: {
                type: [Number]
            }
          }
        });
        LocationSchema.index({ location: '2dsphere' });
    

    现在您可以使用Model.geoNear 来执行您的查询。要获得以公里为单位的距离,您需要使用distanceMultiplier 选项,并将地球半径(以公里为单位)作为值。不要忘记{ spherical: true } 标志。

    注意:我已将它用作聚合的一部分,它非常准确。在上述情况下它也应该同样工作。 Mongoose 文档没有谈论它。使用this from MongoDB docs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-08
      • 2018-02-08
      • 1970-01-01
      相关资源
      最近更新 更多