【问题标题】:how to perform a selective ST_Split?如何执行选择性 ST_Split?
【发布时间】:2021-11-04 15:25:41
【问题描述】:

我需要用一组点切割具有相同几何形状但不同属性(例如颜色)的不同线。这些点也具有属性颜色。 我的刀点应该只切割具有相同颜色值的线条。红点应该只剪红线,绿点应该只剪绿线等等......
我尝试了以下方法:

with knife as(
    select st_union(geom) as geom, colour
    from points
    group by colour)
select lines.colour,(st_dump(st_split(lines.geom,knife.geom))).geom as geom
from lines, knife
where lines.colour=knife.colour

可悲的是,我的“选择性刀”不是那么有选择性,可以切割所有线条,无论线条的颜色如何。 有人可以帮忙吗?

编辑:
@JimJones 我找不到支持 PostGIS 扩展的 SQL 小提琴。但是对于我的数据样本,这把刀以某种方式完美地工作。
我不知道为什么我的真实数据有问题。真正的数据线实际上是多线串,这可能是个问题吗? (我不知何故在用插入语句创建多行字符串)
编辑2:
用 PostGIS 找到了一个小提琴
dbfiddle here

create table points(
id serial,
colour varchar,
geom geometry(point,4326)
);

create table lines(
id serial,
colour varchar,
geom geometry(linestring,4326)
);

insert into lines(colour, geom)
VALUES
('red','linestring(1 1,10 1)'),
('green','linestring(1 1,10 1)'),
('blue','linestring(1 1,10 1)');

insert into points(colour, geom)
VALUES
('red',(st_makepoint(2,1))),
('red',(st_makepoint(4,1))), 
('red',(st_makepoint(6,1))), 
('red',(st_makepoint(8,1))), 
('green',(st_makepoint(2.5,1))), 
('green',(st_makepoint(5,1))),
('green',(st_makepoint(7.5,1))),
('blue',(st_makepoint(3,1))),
('blue',(st_makepoint(6,1))),
('blue',(st_makepoint(9,1)));

with knife as(
    select st_union(geom) as geom, colour
    from points
    group by colour)
select lines.colour,(st_dump(st_split(lines.geom,knife.geom))).geom as geom
from lines, knife
where lines.colour=knife.colour
´´´


  [1]: https://dbfiddle.uk/?rdbms=postgres_12&fiddle=8642640bb690dfee7d31006a673e2dcf

【问题讨论】:

  • 您能提供一个数据样本和确切的预期结果吗?最好在小提琴中添加创建表和插入语句。
  • 嗨!小提琴+1 :) 我很难理解您的查询中可能有什么问题.. 看起来很好。 MultiLinestrings 不是 ST_Split 的问题(根据文档)。也许是因为这个函数总是返回一个集合,并且由于你的几何图形是一个多线串,它可能会在剪切后产生一个线串的集合。
  • 我想我现在明白我的问题了。这就是我的线首先变成多线串的方式。我曾经有很多小线条,所以我在它们上使用了 ST_Union(或 ST_Collect)。不知何故,Postgis 仍然记得,这些行曾经分开一次,当 st_dump 发生时,它们又变成了锯齿状。如果我在 QGIS 中使用默认的“溶解”工具并将图层上传到数据库中,那么刀就可以正常工作。这带来了一个新问题:PostGIS 中是否有相当于 QGIS 中的“溶解”的功能?切换到 QGIS 进行此操作会严重减慢我的速度......
  • 我猜 ST_Dump 是唯一的方法。您可以选择在剪切后再次重新组合线条吗?
  • 我现在... ...没有改善。但我试图在 ST_Split 前面挤压一个 ST_Linemerge,令人惊讶的是它似乎起到了作用。我仍然需要在星期一验证这一点,但至少我得到了与 QGIS Dissolve 相同的结果。所以转储现在看起来像这样: (St_Dump(St_Split(ST_Linemerge(lines.geom),knife.geom))).geom

标签: postgresql postgis


【解决方案1】:

免责声明:我是 postgres 初学者。即使我很确定我找到了解决问题的方法,但也可能有问题。因此,如有必要,请随时纠正我
如果您想对之前使用 ST_Union 合并的行进行 ST_Split,则应在 ST_Split 和 ST_Dump 之前使用 ST_Linemerge。
即使在 ST_Union 之后,PostGIS 似乎也“记得”这些线路以前为不同的球队效力。因此,当您使用新刀 ST_Slit 并 ST_Dump GeometryCollection 时,线串也会在“旧焊接点”处被切割。 如果您在 ST_Union 之后进行 ST_Linemerge,PostGIS 似乎可以消除这些连接点,您可以安全地使用刀。

在这个fiddle 中,我创建了2 个线型和一些刀点。有一条实线(蓝色)和一些黄色线段,它们部分重叠,但都具有与蓝色线相同的空间范围。 我分别使用 ST_Union 和 ST_Collect(按颜色分组)将黄色线段合并为一条线(显然对蓝线没有影响)。 在第二步中,我用刀点再次拆分和倾倒线,一次使用 st_linemerge,一次不使用 st_linemerge,分别用于“联合”和“收集”线。
结果(我计算了新段的数量和每种颜色的累积线长度)显示,只有 linemerged st_union 之后的拆分才能给出正确的结果。仅使用 St_Union 会产生正确的长度,但线段的数量是错误的。 ST_Collect 将保留以前重叠的部分,因此长度和段数根本没有用(出于我的目的)。

【讨论】:

    猜你喜欢
    • 2018-11-19
    • 2021-03-29
    • 2023-02-09
    • 2023-03-19
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多