ST_Intersects(LINESTRING,POLYGON)的意外结果

时间:2014-07-17 19:35:09

标签: postgresql postgis

我从包含几何数据的我的表中获得了一些难以获得的准确结果。我目前正在使用PostGIS 2.1.3,PostgreSQL 9.3.4和GEOS 3.3.8,尽管我也在早期版本中重现了这个问题。

我有一个表Track,它维护LINESTRING,总结其各个位置的时间。我需要实时构建这条线。添加新轨道时,我会从2个点创建一条线,然后在新信息可用时更新该线。为了解决这个问题,我一直在使用ST_AddPoint函数。我发现当我发出ST_Intersects查询时,我没有得到所有预期的曲目。最后,我尝试了与ST_MakeLine相同的方法,它可以正常工作。

我已经设法将问题归结为一个非常简单的测试用例,显示失败。我从一个干净的空间启用数据库开始(postgis.sql和spatial_ref_sys.sql加载)。

create table track
(
    id serial
);

select AddGeometryColumn('track', 'track_region', 0, 'LINESTRING', 2);

create index trk_rgn_idx on track using GIST ( track_region  );

insert into track (track_region) values(ST_GeomFromText('LINESTRING(600.6 129.877, 585.785 170.165 )'));

update track set track_region = ST_AddPoint( track_region, ST_GeomFromText('POINT(572.741 211.551)'));
update track set track_region = ST_AddPoint( track_region, ST_GeomFromText('POINT(558.694 251.969)'));
update track set track_region = ST_AddPoint( track_region, ST_GeomFromText('POINT(544.725 292.666)'));
update track set track_region = ST_AddPoint( track_region, ST_GeomFromText('POINT(531.029 333.661)'));
update track set track_region = ST_AddPoint( track_region, ST_GeomFromText('POINT(518.303 375.281)'));
update track set track_region = ST_AddPoint( track_region, ST_GeomFromText('POINT(506.037 416.302)'));
update track set track_region = ST_AddPoint( track_region, ST_GeomFromText('POINT(492.891 455.689)'));
update track set track_region = ST_AddPoint( track_region, ST_GeomFromText('POINT(480.456 491.382)'));
update track set track_region = ST_AddPoint( track_region, ST_GeomFromText('POINT(469.236 522.899)'));

select id from track where( ST_Intersects(track_region, 'POLYGON((100 400,500 400,500 1200,100 1200,100 400))'));

退货失败:

 id
----
(0 rows)

当我尝试下面的ST_MakeLine方法时,我得到了期望的结果。

drop table track;

create table track
(
    id serial
);

select AddGeometryColumn('track', 'track_region', 0, 'LINESTRING', 2);

create index trk_rgn_idx on track using GIST ( track_region  );

insert into track (track_region) values(ST_GeomFromText('LINESTRING(600.6 129.877, 585.785 170.165 )'));

update track set track_region = ST_MakeLine( track_region, ST_GeomFromText('POINT(572.741 211.551)'));
update track set track_region = ST_MakeLine( track_region, ST_GeomFromText('POINT(558.694 251.969)'));
update track set track_region = ST_MakeLine( track_region, ST_GeomFromText('POINT(544.725 292.666)'));
update track set track_region = ST_MakeLine( track_region, ST_GeomFromText('POINT(531.029 333.661)'));
update track set track_region = ST_MakeLine( track_region, ST_GeomFromText('POINT(518.303 375.281)'));
update track set track_region = ST_MakeLine( track_region, ST_GeomFromText('POINT(506.037 416.302)'));
update track set track_region = ST_MakeLine( track_region, ST_GeomFromText('POINT(492.891 455.689)'));
update track set track_region = ST_MakeLine( track_region, ST_GeomFromText('POINT(480.456 491.382)'));
update track set track_region = ST_MakeLine( track_region, ST_GeomFromText('POINT(469.236 522.899)'));

select id from track where( ST_Intersects(track_region, 'POLYGON((100 400,500 400,500 1200,100 1200,100 400))'));

返回预期的内容。

 id
----
  1
(1 row)

任何人都可以知道我做错了什么吗?我的猜测是,我是如何使用ST_AddPoint来创建该行的,因为如果我只是一次性插入行,一切正常。另外,如果我在添加了ST_AddPoint之后选择了该行,那么在类似的查询中使用它,它就可以工作。

select ST_Intersects('LINESTRING(600.6 129.877,585.785 170.165,572.741 211.551,558.694 251.969,544.725 292.666,531.029 333.661,518.303 375.281,506.037 416.302,492.891 455.689,480.456 491.382,469.236 522.899)', 'POLYGON((100 400,500 400,500 1200,100 1200,100 400))' );

 id
----
  1
(1 row)

谢谢!

1 个答案:

答案 0 :(得分:3)

您发现了ST_Point的错误,该错误已经简化为here as #2845

我会考虑使用一种创建LineString几何的简单方法,而不是重复更新表。 ST_MakeLine有一个使用点几何数组的例子,我认为这是一个好的开始。如果您有点几何表,也可以使用array_agg来帮助构建这些点数组。