我将地方存储在Mongoose模型中(名称+ coords为[lng,lat])并且在其上有一个2d索引。
我想从半径(km)内的点(lng,lat)获得最近的位置。
为此,我使用mongoose的$ 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设置为33km及以上时才会得到结果,而不是应该是24km。
有人可以解释我这里有什么问题吗?也许是111.12(我在互联网上找到的),还是其他的东西?
由于
答案 0 :(得分:4)
既然你在谈论地理定位,我会建议这些改变:
2dsphere
索引代替2d
。这将确保搜索考虑到地球不是二维平面。所以你的架构应该是这样的:
var LocationSchema = new mongoose.Schema({
name: String,
location: {
type: {
type: String,
default: "Point"
},
coordinates: {
type: [Number]
}
}
});
LocationSchema.index({ location: '2dsphere' });
现在,您可以使用here来执行查询。要以公里为单位,您需要使用distanceMultiplier
选项,以地球半径(公里)为单位。不要忘记{ spherical: true }
标志。
注意:我已将它用作聚合的一部分,而且非常准确。它也应该在上述情况下也一样。 Mongoose文档没有谈论它。使用Model.geoNear
答案 1 :(得分: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