我已经编写了这个查询并且它有效,虽然它有点慢:
SELECT name,
(ST_Distance( ST_Transform( way,900913 ),ST_Transform( ST_GeomFromText('POINT (-6.2222 53.307)',4326),900913 )))
FROM ga_osm_latlong_polygon
WHERE
( (ST_Distance( ST_Transform( way,900913 ),ST_Transform( ST_GeomFromText('POINT (-6.2222 53.307)',4326),900913 )))
<= 1000 )
ORDER BY
(ST_Distance( ST_Transform( way,900913 ),ST_Transform( ST_GeomFromText('POINT (-6.2222 53.307)',4326),900913 ))),
name
我正试图以更优雅的方式重写它,使用'as':
SELECT name,
(ST_Distance( ST_Transform( way,900913 ),ST_Transform( ST_GeomFromText('POINT (-6.2222 53.307)',4326),900913 ))) AS d
FROM ga_osm_latlong_polygon
WHERE ( d <= 1000 )
ORDER BY d, name
不幸的是,我得到: 错误:列“d”不存在
我对这里的错误有所了解吗?
谢谢!
答案 0 :(得分:2)
关于你的别名问题,路德是对的。
关于查询缓慢有两个原因。
首先,你正在改变每一点,这需要时间
第二个也许更重要的是,你应该使用ST_Dwithin和空间索引,而不是在where子句中使用distance。
ST_Dwithin使用空间索引对很多计算进行排序。
但是,将数据投射到那些计算中会给出非常不准确的答案。为什么不使用地理功能呢。
尝试:
SELECT d, name
(
SELECT ST_Distance(a.way,b.geom) as d, a.name from
(SELECT way::geography, name from ga_osm_latlong_polygon) a,
(SELECT 'POINT(-6.2222 53.307)'::geography as geom) b
where ST_DWithin(a.way, b.geom, 1000)
) c
order by d, name;
但我想我会更简单地写它:
SELECT ST_Distance(a.way,b.geom) as d, a.name from
(SELECT way::geography, name from ga_osm_latlong_polygon) a,
(SELECT 'POINT(-6.2222 53.307)'::geography as geom) b
where ST_DWithin(a.way, b.geom, 1000)
order by ST_Distance(a.way,b.geom), name;
但是第一个版本可能会更快,因为避免ST_Distance运行两次。
但是为了让这个工作顺利,你需要空间索引 现在,当我写它时,我意识到对地理的投射可能是指数的一个显示。如果是这样,我建议您改为创建一个地理专栏,并在其上建立一个合适的索引。工作指数在这里有所不同,如夜晚和白天。
<强>更新强> 或者您可以直接使用地理类型创建索引。我没有尝试,但可能值得尝试:像这样:
Create index idx_polygon_geog
on ga_osm_latlong_polygon
using gist(way::geography);
HTH
尼克拉斯
答案 1 :(得分:0)
在WHERE子句中看不到列别名。您可以像这样重写查询:
SELECT * FROM
(
SELECT name,
(ST_Distance(
ST_Transform( way,900913 ),
ST_Transform( ST_GeomFromText('POINT (-6.2222 53.307)',4326),900913 )))
AS d
FROM ga_osm_latlong_polygon
)
AS tmp
WHERE ( d <= 1000 )
ORDER BY d, name
另外,我不确定PostGIS是否可以利用ST_Distance()谓词中的空间索引。根据目前的文档:
http://postgis.refractions.net/documentation/manual-1.5/ch04.html#id2638955
ST_Distance()包括从版本1.3开始的隐式边界框检查(可以对索引完成),但是在ST_Transform之后检查way
,这意味着查询必须扫描所有行。可以尝试重写查询,将way
保留在原始SRID中吗?像ST_Distance(way,ST_Transform(...,<srid of way>))
一样?