pau*_*aul 2 sql gis postgis presto amazon-athena
我有数据库表Building与这些列:name,lat,lng
如何Buildings在指定坐标的5英里范围内获取全部范围,例如:
-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
);
Run Code Online (Sandbox Code Playgroud)
https://docs.aws.amazon.com/athena/latest/ug/geospatial-functions-list.html
为什么要将x,y存储在分隔的列中?我真诚地建议您将它们存储为geometry或geography避免查询时间中的投射开销.
话虽这么说,您可以使用以下内容计算距离(以英里为单位):
(测试数据)
CREATE TEMPORARY TABLE building (name text, lat numeric, long numeric);
INSERT INTO building VALUES ('foo',7.52,51.96);
INSERT INTO building VALUES ('bar',7.62,51.94);
INSERT INTO building VALUES ('far away ... ',10.62,59.94);
Run Code Online (Sandbox Code Playgroud)
该函数ST_Distance(带有geography类型参数)将返回以米为单位的距离.您所要做的就是最后将米转换为英里.就像是:
SELECT *, ST_Distance(ST_GeographyFromText('POINT(7.62 51.93)'),
ST_MakePoint(lat,long)) * 0.000621371 AS distance
FROM building
WHERE
ST_Distance(ST_GeographyFromText('POINT(7.62 51.93)'),
ST_MakePoint(lat,long)) * 0.000621371 > 5
name | lat | long | distance
---------------+-------+-------+------------------
far away ... | 10.62 | 59.94 | 566.123267141404
(1 Zeile)
Run Code Online (Sandbox Code Playgroud)
编辑 - 相当于亚马逊雅典娜(距离度):
SELECT *, ST_DISTANCE(ST_GEOMETRY_FROM_TEXT('POINT(-84.386330 33.753746)'),
ST_POINT(lat,long)) AS distance
FROM building
WHERE
ST_Distance(ST_GEOMETRY_FROM_TEXT('POINT(-84.386330 33.753746)'),
ST_POINT(lat,long)) > 5;
Run Code Online (Sandbox Code Playgroud)
先说第一件事。如果可能,请使用 Postgis 而不是 amazon-athena。看文档 athena 看起来像是空间工具的阉割版。
首先 - 安装 postgis。
CREATE EXTENSION postgis SCHEMA public;
Run Code Online (Sandbox Code Playgroud)
现在为您的数据创建几何(如果你想使用像 3857 这样的度量 SRID)或地理(如果你想使用像 4326 这样的度数 SRID)列。
alter table building add column geog geography;
Run Code Online (Sandbox Code Playgroud)
然后将您的点数据(经纬度)数据转换为几何/地理:
update building
set geog=(ST_SetSRID(ST_MakePoint(lat,long),4326)::geography)
Run Code Online (Sandbox Code Playgroud)
接下来在其上创建空间索引
create index on buildings using gist(geog);
Run Code Online (Sandbox Code Playgroud)
现在您已准备好采取行动
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);
Run Code Online (Sandbox Code Playgroud)
几句解释:如果表中有很多记录,索引很有用。ST_Dwithin 在 st_distance 不使用索引时使用索引,因此 ST_dwithin 将使您在大数据集上的查询速度更快。