Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何查询坐标5英里半径内的所有行?_Sql_Postgresql_Indexing_Postgis - Fatal编程技术网

Sql 如何查询坐标5英里半径内的所有行?

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英里内的所有行”,因此这并不是一个精确的问题。相关的,但你的情况更简单。“找到

以下是我的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英里内的所有行”,因此这并不是一个精确的问题。相关的,但你的情况更简单。“找到离我的坐标最近的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格式文件中类似数据的表格中?您正在寻找“特定半径内的坐标”。从特定位置或您想要任何位置的解决方案(例如,带参数的函数)?