将线的起点和终点与PostGIS中的其他线对齐


9

有很多示例显示了如何将线捕捉到点,但是我找不到任何(快速!)将线串的起点和终点节点捕捉到其他线节点的方法。

本质上,我想在postgis(2.0)中“清理”我的图层,将几乎相似的点移动到一起,并在线串之间缝制微小的开口。

是否添加另一个节点,移动任一条线的第一个/最后一个节点或将两个点都移动到中心都没关系。

我找到了两个选项,但是我不确定如何从两个选项开始:

第二个选项听起来可行,但是对于如何遵循此方法的任何帮助将不胜感激。

Answers:


6

我设法解决了这个问题,而没有使用提到的GRASS工具或拓扑功能。

基本上,我将所有开始节点和结束节点放入新的临时表中,在它们周围放置一个缓冲区,合并缓冲区对象,然后将每个缓冲区中找到的所有节点移到缓冲区的质心。

完成后,我将原始的起点和终点移动到新位置。

比预期的要容易,并且仍然很快,但是我希望PostGIS为此提供一些内置功能-这样会更快。

编辑:为了回馈社区,这是我的代码(现在很糟糕)。

drop table if exists nodes;
drop table if exists nodes2;
drop table if exists buffers;

-- Get Start and End nodes
select ST_StartPoint(wkb_geometry) startnode,  ST_EndPoint(wkb_geometry) endnode,    ogc_fid into nodes  from sourceTable;
-- Combine all nodes into one table for easier queries
select startnode node, ogc_fid into nodes2 from nodes;
insert into nodes2 select endnode node, ogc_fid from nodes;

-- Some indexes to speed everything up
CREATE INDEX nodesstart_idx ON nodes USING gist  (startnode);
CREATE INDEX nodesend_idx ON nodes USING gist  (endnode);
CREATE INDEX nodes2_idx ON nodes2 USING gist  (node);
CREATE INDEX nodes_ogcfid_idx ON nodes USING btree (ogc_fid ASC NULLS LAST);

-- Create buffers, combine them, split combined objects again
select (ST_Dump(ST_Union(ST_Buffer(node, 1)))).geom geom into buffers from nodes2;
CREATE INDEX buffers_idx ON buffers USING gist  (geom);

-- Update start/end nodes table
UPDATE nodes SET startnode = ST_Centroid((select geom from buffers WHERE geom && startnode));
UPDATE nodes SET endnode = ST_Centroid((select geom from buffers WHERE geom && endnode));
-- Update original points
update sourceTable set wkb_geometry = ST_SetPoint(
ST_SetPoint(wkb_geometry, 0, (select startnode from nodes where ogc_fid=sourceTable.ogc_fid)), 
ST_NumPoints(wkb_geometry) - 1, (select endnode from nodes where ogc_fid=sourceTable.ogc_fid));

DROP TABLE nodes;
DROP TABLE nodes2;
DROP TABLE buffers;

这个答案看起来很像我答案中的“非拓扑”建议。如果您投票赞成或选择了答案,将是一种好感。这些就是这里给社区提供的食物:)
卡塔丁

你是对的。我已对您的回答进行了投票,并将编辑我的回复以包括我的代码。
耶尔默·巴斯

4

这是三个选项。希望有人会有所帮助。

v。清洁

使用QGIS中的GRASS工具,您可以清理空间对象的拓扑。@RK用户在回答另一个问题时给出了有关如何执行此操作的很好的说明。GRASS提供的优点是,它将推断shapefile的拓扑。这种情况的缺点是数据不在shapefile中。当然,您可以使用“添加PostGIS图层”工具将数据从Postgres导出到shapefile中,但这是一个额外的步骤。

非拓扑PostGIS功能

在PostGIS中,可以使用ST_EndPointST_StartPoint函数获取线串的终点和起点。然后,结合使用ST_DWithi n和ST_Distance,可以找到附近几何图形上最近的起点或终点。如果您有很多点,那么ST_DWithin将大大加快查询速度-假设您有索引。从那里,您将需要建立一个规则,该规则定义要修改的点和固定的点。

这样做的好处是您不必将数据发送到GRASS进行清理,但是需要注意一些陷阱。

PostGIS拓扑功能

该问题引用了PostGIS拓扑功能。这些效果很好,但是,正如Wiki所述,您必须明确定义边缘,节点和面。显然,这对于您的数据集将是一个问题,因为您已经知道拓扑问题。


1

PostGIS具有捕捉功能。也许它们会有所帮助?

ST_Snap将输入几何图形的线段和顶点对齐到参考几何图形的顶点。

ST_SnapToGrid将输入几何图形的所有点对齐到常规网格。


1
谢谢,我知道这些功能。ST_Snap捕捉所有节点,我只想要开始和结束节点。ST_SnapToGrid并不是真正适合的对象,因为它修改了所有现有的几何图形,并且有机会将相距较近的节点移到更远的地方,因为它们几乎没有落入另一个段中。
耶尔默·巴斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.