gpt4 book ai didi

node.js - 就 mongoDb 而言,GeoJSON 和 Legacy 坐标对有什么区别?

转载 作者:可可西里 更新时间:2023-11-01 09:12:28 26 4
gpt4 key购买 nike

我正在尝试使用 mongoDb 的 $geoNear 聚合运算符以下列方式计算用户与当前位置的距离:

'$geoNear': {
near: currentLocation,
distanceField: 'distance',
spherical: true,
}

currentLocation 是这样的:

{ "type" : "Point", "coordinates" : [  -122.1575745,  37.4457966 ] }

我的收藏属于以下类型(使用 Mongoose ):

users = [{
....
location : { // GeoJSON Point or I think it is ;)
type: {
type: String
},
coordinates: []
}
....
}]

我正在使用索引(同样是 mongoose 的语法):

userSchema.index({
location: '2dsphere'
});

现在我面临的问题是,如果我如上所述使用 currentLocation 进行查询(以 GeoJSON 的形式),我会得到奇怪的距离(非常大的数字),但是如果我使用 currentLocation.coordinates,即使用旧坐标对( [-122.1575745, 37.4457966]), 我得到了正确的结果。但是mongoDb docs for geoNear明确表示我们可以使用 GeoJSON 点或旧坐标对 进行查询。

我很想知道 GeoJSON 点和传统坐标对之间到底有什么区别?

例如集合:

{ "_id" : ObjectId("5277679914c6d8f00b000003"), "location" : { "type" : "Point", "coordinates" : [  106.6202887,  -6.1293536 ] } }
{ "_id" : ObjectId("5277810148219d011c000003"), "location" : { "type" : "Point", "coordinates" : [ 106.6202887, -6.1293536 ] } }
{ "_id" : ObjectId("5281c7ba2dfd7bdc64000003"), "location" : { "type" : "Point", "coordinates" : [ -86.9248483, 33.4480108 ] } }
{ "_id" : ObjectId("5281c8b82dfd7bdc64000004"), "location" : { "type" : "Point", "coordinates" : [ -74.0087126, 40.7136487 ] } }
{ "_id" : ObjectId("5281c9782dfd7bdc64000005"), "location" : { "type" : "Point", "coordinates" : [ -122.1575745, 37.4457966 ] } }

错误的结果:

[{"location":{"type":"Point","coordinates":[-122.1575745,37.4457966]},"dis":13.69288259318155},
{"location":{"type":"Point","coordinates":[-86.9248483,33.4480108]},"dis":12697164592.388557},
{"location":{"type":"Point","coordinates":[-74.0087126,40.7136487]},"dis":16328789117.58145},
{"location":{"type":"Point","coordinates":[106.6202887,-6.1293536]},"dis":55446284682.14049},
{"location":{"type":"Point","coordinates":[106.6202887,-6.1293536]},"dis":55446284682.14049}]

最佳答案

让我们创建一些示例文档和地理空间索引:

> db.foo.insert({name: "Warsaw", location: {"type" : "Point", "coordinates" : [21.016667, 52.233333]}})
> db.foo.insert({name: "Stockholm", location: {"type" : "Point", "coordinates" : [18.068611, 59.329444]}})
> db.foo.ensureIndex({"location": "2dsphere"})

华沙 PL 和斯德哥尔摩 SE 之间的距离大约为 810 公里,所以让我们检查一下它是否按预期工作。首先我们可以获取斯德哥尔摩的文档。

> Stockholm = db.foo.findOne({name: "Stockholm"})

现在我们可以使用 geoNear 运行查询:

> db.runCommand({ geoNear: 'foo', near: Stockholm.location.coordinates,  spherical: true })
{
"ns" : "test.foo",
"results" : [
{
"dis" : 6.558558954334308e-10,
"obj" : {
"_id" : ObjectId("52876ab0b12c6fc62f5d9311"),
"name" : "Stockholm",
"location" : {
"type" : "Point",
"coordinates" : [
18.068611,
59.329444
]
}
}
},
{
"dis" : 0.12715355275490586,
"obj" : {
"_id" : ObjectId("5287697eb12c6fc62f5d9310"),
"name" : "Warsaw",
"location" : {
"type" : "Point",
"coordinates" : [
21.016667,
52.233333
]
}
}
}
],
"stats" : {
"time" : 9,
"nscanned" : 3,
"avgDistance" : 0.06357677670538088,
"maxDistance" : 0.12715355275490586
},
"ok" : 1
}

斯德哥尔摩与斯德哥尔摩之间的距离如预期接近 0。斯德哥尔摩和华沙之间的距离是0.12715355275490586。当您使用遗留坐标对运行查询时,您会得到以弧度为单位的结果,因此我们必须将该值乘以地球半径:

> 0.12715355275490586 * 6371.0
810.0952846015052

到目前为止一切顺利。让我们检查一下我们是否使用 geojson 作为查询得到了类似的结果。

> db.runCommand({ geoNear: 'foo', near: Stockholm.location,  spherical: true })
{
"ns" : "test.foo",
"results" : [
{
"dis" : 0.004183114486663965,
"obj" : {
"_id" : ObjectId("52876ab0b12c6fc62f5d9311"),
"name" : "Stockholm",
"location" : {
"type" : "Point",
"coordinates" : [
18.068611,
59.329444
]
}
}
},
{
"dis" : 810998.0748260651,
"obj" : {
"_id" : ObjectId("5287697eb12c6fc62f5d9310"),
"name" : "Warsaw",
"location" : {
"type" : "Point",
"coordinates" : [
21.016667,
52.233333
]
}
}
}
],
"stats" : {
"time" : 4,
"nscanned" : 3,
"avgDistance" : 405499.0395045898,
"maxDistance" : 810998.0748260651
},
"ok" : 1
}

斯德哥尔摩与斯德哥尔摩之间的距离再次接近 0。斯德哥尔摩和华沙之间的距离是 810998.0748260651。当您使用 GeoJSON 运行 geoNear 查询时,距离以米为单位计算。 810998.0748260651 大约等于 810 公里,所以这里没有什么奇怪的。

> 810998.0748260651 / 1000
810.9980748260651

两种解决方案之间的差异可能更小,但它只是一个 FP 算法。

> Math.abs(810.0952846015052 - 810.9980748260651)
0.902790224559908

当您将 find 命令与 $near 运算符一起使用时。当您在遗留坐标对上创建简单的 2d 索引时,可以使用 {$near: Stockholm.location.coordinates}{$near: {$ 查询它几何:Stockholm.location}。如果你有 2dsperhical 只有 {$near: {$geometry: Stockholm.location} 会起作用。

关于node.js - 就 mongoDb 而言,GeoJSON 和 Legacy 坐标对有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20016269/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com