以下是商业文档,其中address.location是我保存坐标的地方。
{
"_id" : ObjectId("59944c26085e1140d4575393"),
"category" : "place",
"address" : {
"streetAddress" : "19210 Clay Road",
"city" : "Katy",
"zipcode" : "77449",
"state" : "Texas",
"country" : "United States",
"countryCode" : "US",
"locality" : "Katy, TX",
"location" : {
"type" : "Point",
"coordinates" : [
-95.7043599,
29.832139
]
},
"fomattedAddress" : "19210 Clay Rd, Katy, TX 77449"
}
}
使用以下逻辑我计算了多边形
Coordinate[] coordinates = new Coordinate[] {new Coordinate(-84.529793, 33.961886), new Coordinate( -84.521698, 33.952987),
new Coordinate(-84.517242, 33.944534), new Coordinate(-84.513290, 33.937264), new Coordinate( -84.498865, 33.915202), new Coordinate(-84.529793, 33.961886)};
GeometryFactory geometryFactory = new GeometryFactory();
LinearRing linear = new GeometryFactory().createLinearRing(coordinates);
Polygon polygon = new Polygon(linear, null, geometryFactory);
Coordinate[] polyCoordinates = polygon.getCoordinates();
使用下面的mongo查询我试图让多边形内的业务,但我没有结果,我做错了,请指导我
db.business.find(
{
"address.location.coordinates": {
$geoIntersects: {
$geometry: {
type: "Polygon" ,
coordinates: [
[ [ -84.529793, 33.961886 ], [ -84.521698, 33.952987 ], [ -84.517242, 33.944534 ], [-84.51329, 33.937264] , [ -84.498865, 33.915202 ], [-84.529793, 33.961886] ]
]
}
}
}
}
)
答案 0 :(得分:0)
要查找沿路线的特定距离内的所有点,您需要在路线上建立多边 。
在下图中,我假设整个路线(绿色)是一条简洁明了的直线。您的查询是3个形状的$or
- 半径为R的蓝色起点和终点圆,以及连接两者的红色多边形:
以下javascript代码https://jsfiddle.net/961kcxr3/使用基本平面几何图形计算线段的坐标。这是您需要使用您选择的语言在应用程序级别上执行的操作:
const routeCoords [ [ -84.529793, 33.961886 ], [ -84.521698, 33.952987 ], [ -84.517242, 33.944534 ], [-84.51329, 33.937264] , [ -84.498865, 33.915202 ] ] ];
const R = 1000; // 1 km - radius to search within, adjust to your needs
const M = 1/98000; // radius to radians multiplier
const A = routeCoords[0];
const B = routeCoords[4];
const a = Math.atan2(B[0] - A[0], B[1] - A[1]) + Math.PI / 2;
var polyCoords = [
[
A[0] - Math.sin(a) * R * M,
A[1] - Math.cos(a) * R * M
], [
B[0] - Math.sin(a) * R * M,
B[1] - Math.cos(a) * R * M
], [
B[0] + Math.sin(a) * R * M,
B[1] + Math.cos(a) * R * M
], [
A[0] + Math.sin(a) * R * M,
A[1] + Math.cos(a) * R * M
]
];
其中给出了poly的坐标:
[
[-84.516182, 33.970903],
[-84.485254, 33.924219],
[-84.512476, 33.906185],
[-84.543404, 33.952869]
]
结果查询:
db.business.find(
{ $or: [
{ "address.location.coordinates": {
$geoWithin: {
$geometry: {
type: "Polygon" ,
coordinates: [ [
[-84.516182, 33.970903],
[-84.485254, 33.924219],
[-84.512476, 33.906185],
[-84.543404, 33.952869],
[-84.516182, 33.970903] // the first point to close the poly
] ]
}
},
} },
{ "address.location.coordinates": {
$geoWithin: {
$centerSphere: [ [ -84.529793, 33.961886 ], 1 / 6378.1 ]
}, // 1 km radius, adjust to your needs
} },
{ "address.location.coordinates": {
$geoWithin: {
$centerSphere: [ [ -84.498865, 33.915202 ], 1 / 6378.1 ]
}, // 1 km radius, adjust to your needs
} }
] }
)
现实代码应计算每个分段的多边形和圆形。它可以导致相当大的查询,因此在准确性和速度之间进行合理的平衡。
优化的一些案例:
R
,则可以跳过多边形,并为该段使用2或1圈。a
对于2个连续的段是相同的,则可以加入两端并将它们视为单个段,就像我在上面的示例中加入4个段一样