从指定坐标获取 5 英里范围内的所有建筑物
Getting all Buildings in range of 5 miles from specified coordinates
我的数据库 table Building
包含以下列:name
、lat
、lng
如何获取距指定坐标 5 英里范围内的所有 Buildings
,例如这些:
-84.38653999999998
33.72024
我试过了,但没有用:
SELECT ST_CONTAINS(
SELECT ST_BUFFER(ST_Point(-84.38653999999998,33.72024), 5),
SELECT ST_POINT(lat,lng) FROM "my_db"."Building" LIMIT 50
);
https://docs.aws.amazon.com/athena/latest/ug/geospatial-functions-list.html
为什么要将 x,y 存储在不同的列中?我强烈建议您将它们存储为 geometry
或 geography
以避免查询时不必要的转换开销。
也就是说,您可以使用 ST_DWithin
或 ST_Distance
:
计算和检查以英里为单位的距离
(测试数据)
CREATE TABLE building (name text, long numeric, lat numeric);
INSERT INTO building VALUES ('Kirk Michael',-4.5896,54.2835);
INSERT INTO building VALUES ('Baldrine',-4.4077,54.2011);
INSERT INTO building VALUES ('Isle of Man Airport',-4.6283,54.0804);
ST_DWithin
ST_DWithin
return 如果给定的几何形状与另一个几何形状在指定的距离内,则为真。以下查询搜索距 POINT(-4.6314 54.0887)
:
5 英里半径范围内的几何图形
SELECT name,long,lat,
ST_Distance('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat)) * 0.000621371 AS distance
FROM building
WHERE
ST_DWithin('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat),8046.72); -- 8046.72 metres = 5 miles;
name | long | lat | distance
---------------------+---------+---------+-------------------
Isle of Man Airport | -4.6283 | 54.0804 | 0.587728347062174
(1 row)
ST_Distance
函数 ST_Distance
(使用 geography
类型参数)将 return 距离 米 。使用这个功能你所要做的就是最后把米换算成英里。
注意:使用ST_Distance
的查询中的距离是实时计算的,因此不要使用空间索引。所以,不建议在WHERE
子句中使用该函数!在 SELECT
子句中使用它。尽管如此,下面的示例显示了如何完成:
SELECT name,long,lat,
ST_Distance('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat)) * 0.000621371 AS distance
FROM building
WHERE
ST_Distance('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat)) * 0.000621371 <= 5;
name | long | lat | distance
---------------------+---------+---------+-------------------
Isle of Man Airport | -4.6283 | 54.0804 | 0.587728347062174
(1 row)
- 注意参数顺序
ST_MakePoint
:是经度,纬度..不是相反。
演示:db<>fiddle
Amazon Athena 等效项(以度为单位的距离):
SELECT *, ST_DISTANCE(ST_GEOMETRY_FROM_TEXT('POINT(-84.386330 33.753746)'),
ST_POINT(long,lat)) AS distance
FROM building
WHERE
ST_Distance(ST_GEOMETRY_FROM_TEXT('POINT(-84.386330 33.753746)'),
ST_POINT(long,lat)) <= 5;
第一件事。如果可能,请使用 Postgis 而不是 amazon-athena。看文档 athena 看起来像是一个空间工具的阉割版。
首先 - 安装 postgis。
CREATE EXTENSION postgis SCHEMA public;
现在为数据创建几何(如果你想使用像 3857 这样的公制 SRID)或地理(如果你想使用像 4326 这样的度数 SRID)列。
alter table building add column geog geography;
然后将您的点数据 (lat,long) 数据转换为 geometry/geography:
update building
set geog=(ST_SetSRID(ST_MakePoint(lat,long),4326)::geography)
接下来在其上创建空间索引
create index on buildings using gist(geog);
现在您可以开始行动了
select *,
st_distance(geog, ST_makePoint(-84.386,33.72024))/1609.34 dist_miles
from building
where st_dwithin(geog, ST_makePoint(-84.38653999999998,33.72024),5*1609.34);
几句解释:
如果您的 table 中有很多记录,索引很有用。
ST_Dwithin 在 st_distance 不使用索引时使用索引,因此 ST_dwithin 将使您在大数据集上的查询速度更快。
我的数据库 table Building
包含以下列:name
、lat
、lng
如何获取距指定坐标 5 英里范围内的所有 Buildings
,例如这些:
-84.38653999999998
33.72024
我试过了,但没有用:
SELECT ST_CONTAINS(
SELECT ST_BUFFER(ST_Point(-84.38653999999998,33.72024), 5),
SELECT ST_POINT(lat,lng) FROM "my_db"."Building" LIMIT 50
);
https://docs.aws.amazon.com/athena/latest/ug/geospatial-functions-list.html
为什么要将 x,y 存储在不同的列中?我强烈建议您将它们存储为 geometry
或 geography
以避免查询时不必要的转换开销。
也就是说,您可以使用 ST_DWithin
或 ST_Distance
:
(测试数据)
CREATE TABLE building (name text, long numeric, lat numeric);
INSERT INTO building VALUES ('Kirk Michael',-4.5896,54.2835);
INSERT INTO building VALUES ('Baldrine',-4.4077,54.2011);
INSERT INTO building VALUES ('Isle of Man Airport',-4.6283,54.0804);
ST_DWithin
ST_DWithin
return 如果给定的几何形状与另一个几何形状在指定的距离内,则为真。以下查询搜索距 POINT(-4.6314 54.0887)
:
SELECT name,long,lat,
ST_Distance('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat)) * 0.000621371 AS distance
FROM building
WHERE
ST_DWithin('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat),8046.72); -- 8046.72 metres = 5 miles;
name | long | lat | distance
---------------------+---------+---------+-------------------
Isle of Man Airport | -4.6283 | 54.0804 | 0.587728347062174
(1 row)
ST_Distance
函数 ST_Distance
(使用 geography
类型参数)将 return 距离 米 。使用这个功能你所要做的就是最后把米换算成英里。
注意:使用ST_Distance
的查询中的距离是实时计算的,因此不要使用空间索引。所以,不建议在WHERE
子句中使用该函数!在 SELECT
子句中使用它。尽管如此,下面的示例显示了如何完成:
SELECT name,long,lat,
ST_Distance('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat)) * 0.000621371 AS distance
FROM building
WHERE
ST_Distance('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat)) * 0.000621371 <= 5;
name | long | lat | distance
---------------------+---------+---------+-------------------
Isle of Man Airport | -4.6283 | 54.0804 | 0.587728347062174
(1 row)
- 注意参数顺序
ST_MakePoint
:是经度,纬度..不是相反。
演示:db<>fiddle
Amazon Athena 等效项(以度为单位的距离):
SELECT *, ST_DISTANCE(ST_GEOMETRY_FROM_TEXT('POINT(-84.386330 33.753746)'),
ST_POINT(long,lat)) AS distance
FROM building
WHERE
ST_Distance(ST_GEOMETRY_FROM_TEXT('POINT(-84.386330 33.753746)'),
ST_POINT(long,lat)) <= 5;
第一件事。如果可能,请使用 Postgis 而不是 amazon-athena。看文档 athena 看起来像是一个空间工具的阉割版。
首先 - 安装 postgis。
CREATE EXTENSION postgis SCHEMA public;
现在为数据创建几何(如果你想使用像 3857 这样的公制 SRID)或地理(如果你想使用像 4326 这样的度数 SRID)列。
alter table building add column geog geography;
然后将您的点数据 (lat,long) 数据转换为 geometry/geography:
update building
set geog=(ST_SetSRID(ST_MakePoint(lat,long),4326)::geography)
接下来在其上创建空间索引
create index on buildings using gist(geog);
现在您可以开始行动了
select *,
st_distance(geog, ST_makePoint(-84.386,33.72024))/1609.34 dist_miles
from building
where st_dwithin(geog, ST_makePoint(-84.38653999999998,33.72024),5*1609.34);
几句解释: 如果您的 table 中有很多记录,索引很有用。 ST_Dwithin 在 st_distance 不使用索引时使用索引,因此 ST_dwithin 将使您在大数据集上的查询速度更快。