如何查询给定坐标(字符串类型的经纬度)中最近的记录?
我正在使用 GeoDjango 和 PostGIS。然后我遇到了如何从 postgres 数据库表中给定坐标获取最近记录的麻烦。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我正在使用 GeoDjango 和 PostGIS。然后我遇到了如何从 postgres 数据库表中给定坐标获取最近记录的麻烦。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(6)
这是使用 GeoDjango 和 PostGIS 的答案
点坐标必须是 GEOSGeometry 对象。为了使其使用
然后,让我们假设您有一个“餐厅”模型和点的坐标。
因此,对于最近的餐厅只需使用:
This this the answer using GeoDjango with PostGIS
Point coordinates must be a GEOSGeometry object. To make it use
Then, let's imagine that you have a "Restaurant" model And coordinates of the point.
So, for the closest restaurant just use:
PostGIS 2.0及更高版本可以使用KNN最近邻搜索来获取最近的质心。例如:
PostGIS 2.0 and later can use KNN nearest-neighbour searching to get the nearest centroids. For example:
我必须同意 delawen 的回答,但单独使用 st_distance 会非常慢。因此,为了加快速度,您必须使用 GIST 索引(注意大多数 PostGIS 函数,包括 st_distance 请勿使用索引,请参阅:postgis 索引建议)。
因此,您首先要在该点周围创建一个缓冲区,然后使用“&&”检查其边界框(这利用了内置的 GIST 索引 - 所以它的性能会好得多),然后你可以通过“st_distance”检查距离。
例如,要从给定的 cood 位置(例如 X=1,Y=1)获取最近的“餐厅”,您可以这样写:
与“st_distance”相比,这会非常快,但结果可能包含距离该位置超过 100 米的餐厅。给定位置(尤其是当几何图形保持为直线或多边形格式时)。
为了获得更准确的结果,在 100 米范围内的餐厅,您可以在上面给出的查询中附加以下内容:
这仍然比使用 st_distance 更高效、更快速靠它自己。因为数据库只会对满足第一个条件的记录运行st_distance。
因此,根据经验,每当您必须执行昂贵的空间查找时,请尝试:
注意:缓冲区大小或实际距离必须位于您使用的投影系统中,即如果您使用 EPSG:4326(纬度)。 /Long) 那么你就以度为单位给出了这些距离。
现实世界中的 1 米 = 0.00000899 度.. 100 米 = 做数学计算:)
I have to agree with delawen's answer but using st_distance on its own will be very slow. So to speed up things you will have to make use of GIST indexes (note most PostGIS function incl. st_distance DO NOT make use of indexes see: postgis indexing recommendation).
So you would first create a buffer around the point and then check its bounding box using "&&" (this makes use of built in GIST index - so it would perform much much better ) and then you would check distance by "st_distance".
For example to get nearest "restaurant" from a given cood location (e.g. X=1,Y=1) you would write:
This would be very fast compared to "st_distance" but results may contain restaurants that are more than 100 meters from the given location (esp. when geometries are kept in line or polygon formats).
To get more accurate results, restaurants that are exactly with in 100 meters range, you append following to the query given above:
This will still be more efficient and faster than using st_distance on its own. Because database will only run st_distance against records that fulfil the first criteria.
So as a rule of thumb, whenever you have to perform expensive spatial lookups try to:
Note: Size of buffer or actual distance has to be in projection system you are using i.e. if you are using EPSG:4326 (Lat/Long) then you have give these distances in degrees. For example
1 meter in real world = 0.00000899 degrees .. and 100 meters = do the maths :)
我没有使用 GeoDjango 的经验,但在 PostgreSQL/PostGIS 上你有 st_distance(..) 函数。因此,您可以按
st_distance(geom_column, your_coordinates) asc
对结果进行排序,并查看最近的行。如果您有普通坐标(没有 postgis 几何图形),则可以使用 GeometryFromText 函数将坐标转换为点。
这就是您要找的吗?如果没有,请尝试更明确。
I have no experience with GeoDjango, but on PostgreSQL/PostGIS you have the st_distance(..) function. So, you can order your results by
st_distance(geom_column, your_coordinates) asc
and see what are the nearest rows.If you have plain coordinates (no postgis geometry), you can convert your coordinates to a point with the geometryFromText function.
Is that what you were looking for? If not, try to be more explicit.
PostgreSQL/PostGIS 用户应使用“<->” ORDER BY 子句中的运算符来获取“K 个最近邻居”(KNN),如 Mike T 中所述="https://stackoverflow.com/a/7947019/3018084">这个答案。
为了从 GeoDjango 中的 KNN-GiST 性能改进中获益,您可以编写如下:
PostgreSQL/PostGIS users should use "<->" operator in ORDER BY clause to get "K nearest neighbors" (KNN), as said Mike T in this answer.
To get benefit from KNN-GiST performance improvement in GeoDjango you may write as following:
使用 PostGIS 和 GeoDjango 查找最近的邻居
考虑这个模型:
在视图中获取指定经度/纬度 100 英里半径内的所有兴趣点:
在模板中显示结果:
Using PostGIS and GeoDjango to find your nearest neighbour
Consider this the model:
In a view get all the points of interest within a 100 mile radius of a specified longitude / latitude:
Show the results in a template: