Sql 如何查询坐标5英里半径内的所有行?
以下是我的PostgreSQL的CSV格式示例Sql 如何查询坐标5英里半径内的所有行?,sql,postgresql,indexing,postgis,Sql,Postgresql,Indexing,Postgis,以下是我的PostgreSQL的CSV格式示例 row,latitude,longitude 1,42.082513,-72.621498 2,42.058588,-72.633386 3,42.061118,-72.631541 4,42.06035,-72.634145 我在世界各地还有数千行这样的跨越坐标 我只想查询表中某个半径内的坐标。如何使用PostGIS和PostgreSQL实现这一点?您希望“坐标半径5英里内的所有行”,因此这并不是一个精确的问题。相关的,但你的情况更简单。“找到
row,latitude,longitude
1,42.082513,-72.621498
2,42.058588,-72.633386
3,42.061118,-72.631541
4,42.06035,-72.634145
我在世界各地还有数千行这样的跨越坐标
我只想查询表中某个半径内的坐标。如何使用PostGIS和PostgreSQL实现这一点?您希望“坐标半径5英里内的所有行”,因此这并不是一个精确的问题。相关的,但你的情况更简单。“找到离我的坐标最近的10行”将是KNN问题
将坐标转换为地理
值:
ST_SetSRID(ST_MakePoint(longitude, latitude),4326)::geography
或者,您可以使用更简单的几何图形类型。考虑:
然后我们有一张像这样的桌子:
CREATE TABLE tbl (
tbl_id serial PRIMARY KEY
, geog geography NOT NULL
);
您所需要的只是-和一个空间索引,以使其快速:
CREATE INDEX tbl_geog_gist ON tbl USING gist(geog);
查询:
SELECT *, ST_Distance(c.x, geog) AS distance -- distance is optional
FROM tbl t, (SELECT ST_GeographyFromText('SRID=4326;POINT(-72.63 42.06)')) AS c(x)
WHERE ST_DWithin(c.x, geog, 8045) -- distance in meter
ORDER BY distance; -- order is optional, you did not ask for that
或者您可以使用原始列并创建函数索引。。。
在dba.SE上的这个密切相关的答案中,这一点和其他细节如下:
您应该首先使用(如果PostgreSQL服务器可以访问该文件)或在psql
中(如果该文件不是服务器的本地文件)从CSV格式的文件创建一个表。如果您有任何问题,请参阅其他Q+A,以便获得示例
一旦将数据保存在表格中,您应该将经度
和纬度
列转换为PostGIS地理
类型,方法是在地理(点,4326)
类型的表格中添加一列,然后用适当的值填充该列(此处称为gps
):
UPDATE my_table SET gps = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326);
在该列上添加索引以允许高效搜索:
CREATE INDEX my_table_gps ON my_table USING gist(gps);
您现在可以在距给定位置5英里内找到行,例如(-72.657,42.0657)
,如下所示:
SELECT *
FROM my_table
WHERE ST_DWithin(gps, ST_SetSRID(ST_MakePoint(-72.657, 42.0657), 4326), 5 * 1609);
请注意,ST_DWithin()
在geography
一栏中以米为单位,所以你必须将以英里为单位的半径乘以以英里为单位的1609米。我综合了欧文和帕特里克的答案
-- Add geography column
ALTER TABLE googleplaces ADD COLUMN gps geography;
UPDATE googleplaces SET gps = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326);
CREATE INDEX googleplaces_gps ON googleplaces USING gist(gps);
SELECT *
FROM my_table
WHERE ST_DWithin(gps, ST_SetSRID(ST_MakePoint(-72.657, 42.0657), 4326), 5 * 1609);
你想用GiST或GIN索引进行K-最近邻(KNN)搜索。@CraigRinger我从来没有做过任何涉及这两者的事情。我在哪里可以了解更多信息?您的数据保存在CSV格式的文件中,或者保存在包含CSV格式文件中类似数据的表格中?您正在寻找“特定半径内的坐标”。从特定位置或您想要任何位置的解决方案(例如,带参数的函数)?