ST_Distance 和“as”在Postgis中

发布于 2024-10-15 23:58:59 字数 799 浏览 4 评论 0原文

我已经编写了这个查询并且它可以工作,尽管它有点慢:

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”列不存在

知道我在这里犯了什么错误吗?

谢谢!

I've written this query and it works, although it's a bit slow:

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

I'm trying to rewrite it in a more elegant way, using '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

Unfortunately, I get:
ERROR: column "d" does not exist

Any idea about what I'm getting wrong here?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情话已封尘 2024-10-22 23:58:59

你好,穆隆

关于你的别名问题,路德是对的。

查询速度慢有两个原因。

首先,您要转换每个点,这需要时间

其次,可能更重要的是,您应该将 ST_Dwithin 与空间索引一起使用,而不是在 where 子句中使用距离。

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

Nicklas

Hallo Mulone

About your alias problem, Luther is right.

About the query being slow has two reasons.

First, you are transforming every point, that takes time

Second and probably more importand, youshould use ST_Dwithin together with a spatial index instead of using distance in the where clause.

ST_Dwithin uses the spatial indexes to sort away a lot of the calculations.

But projecting your data to do those calculations will give you very inaccurate answers. Why not use the geography functions instead.

try:

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;

But I think I would write it more simply like:

  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;

But the first version might be faster because avoiding ST_Distance to run twice.

But to get this working well of course you will need the spatial index
Now when I write it I realize that the casting to geography might be a showstopper for the index. If so, I would suggest you make a geography column instead and build a proper index on that. A working index makes a difference like night and day here.

Update:
Or maybe you can create the index with the geography type directly. I have not tried, but might be worth trying: like this:

Create index idx_polygon_geog
on ga_osm_latlong_polygon
using gist(way::geography);

HTH

Nicklas

不必你懂 2024-10-22 23:58:59

列别名在 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 开始包含隐式边界框检查(可以针对索引完成),但您要在之后检查 way ST_Transform,这意味着查询必须扫描所有行。是否可以尝试重写查询,将 way 保留在其原始 SRID 中?喜欢 ST_Distance(way,ST_Transform(...,)) 吗?

Column aliases are not visible in the WHERE clause. You can rewrite the query like this:

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

Also, I am not sure if PostGIS can take advantage of a spatial index in your ST_Distance() predicate. According to the current docs:

http://postgis.refractions.net/documentation/manual-1.5/ch04.html#id2638955

ST_Distance() includes a implicit bounding box check (which can be done against the index) from version 1.3 on, BUT you are checking way AFTER a ST_Transform, which means that the query has to scan all rows. Could try to rewrite the query leaving way in its original SRID? Like ST_Distance(way,ST_Transform(...,<srid of way>))?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文