我写了这个查询并且它有效,虽然它有点慢:
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”不存在
关于我在这里遇到什么问题的任何想法?
谢谢!
最佳答案 你好Mulone
关于你的别名问题,路德是对的.
关于查询缓慢有两个原因.
首先,你正在改变每一点,这需要时间
其次,可能更重要的是,你应该将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
尼克拉斯