Tôi đã quản lý để giải quyết vấn đề này mà không cần sử dụng các công cụ GRASS hoặc các chức năng tô pô đã đề cập.
Về cơ bản, tôi lấy tất cả các nút bắt đầu và kết thúc, đặt chúng vào một bảng mới, tạm thời, đặt một bộ đệm xung quanh chúng, hợp nhất các đối tượng bộ đệm và di chuyển tất cả các nút tìm thấy trong mỗi bộ đệm đến trung tâm của bộ đệm.
Khi xong, tôi di chuyển điểm bắt đầu và điểm kết thúc ban đầu đến vị trí mới.
Dễ dàng hơn dự kiến và vẫn nhanh, nhưng tôi hy vọng PostGIS sẽ có một số chức năng tích hợp sẵn cho việc này - điều đó sẽ còn nhanh hơn nữa.
Chỉnh sửa: vì lợi ích của việc trả lại cho cộng đồng, đây là mã (khá nhảm nhí) của tôi bây giờ.
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;