PostGIS 2.3按点分割

Gui*_*air 6 sql postgresql triggers loops postgis

我在gis.stackexchange上问了这个问题(但是因为我的实际问题似乎比GIS更像是一个DB问题,我在这里试试运气).以下是关于gis.stackexchange的问题:https://gis.stackexchange.com/questions/256535/postgis-2-3-splitting-multiline-by-points

我有一个触发器,当我插入一个新行来插入我的表中的分割线组时,我会循环,但由于某种原因我没有得到想要的结果,因为在示例中我只得到三行中的两行.我做错了什么?

这里是触发器功能的代码:

CREATE OR REPLACE FUNCTION public.split_cable()
      RETURNS trigger AS
    $BODY$
    DECLARE compte integer;
    DECLARE i integer := 2;
    BEGIN
    compte = (SELECT count(*) FROM boite WHERE st_intersects(boite.geom, new.geom));

    WHILE i < compte LOOP
        WITH brs AS (SELECT row_number() over(), boite.geom FROM boite, cable2
            WHERE st_intersects(boite.geom, new.geom)
    -- here the ORDER BY serve to get the "boite" objects in a specific order
            ORDER BY st_linelocatepoint(st_linemerge(new.geom),boite.geom)),
            brs2 AS (SELECT st_union(geom) AS geom FROM brs),
            cables AS (SELECT (st_dump(st_split(new.geom, brs2.geom))).geom FROM brs2)
        INSERT INTO cable2 (geom) VALUES (
        SELECT st_multi(cables.geom) FROM cables WHERE st_startpoint(geom) = (SELECT geom FROM brs WHERE brs.row_number = i));
        i = i + 1;
    END LOOP;

    new.geom = (WITH brs AS (SELECT row_number() over(), boite.geom FROM boite, cable2
            WHERE st_intersects(boite.geom, new.geom)
            ORDER BY st_linelocatepoint(st_linemerge(new.geom),boite.geom)),
            brs2 AS (SELECT st_union(geom) as geom from brs),
            cables AS (SELECT (st_dump(st_split(new.geom, brs2.geom))).geom FROM brs2)
            SELECT st_multi(cables.geom) FROM cables WHERE st_startpoint(geom) = (SELECT geom FROM brs WHERE brs.row_number = 1));
    RETURN new;
    END
    $BODY$
      LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

Fel*_*des 0

这是一个相对复杂的查询,并且有很多移动部分。我对调试查询的建议涉及多种想法:

  1. 考虑将函数拆分为更小的函数,以便更容易测试,然后从一组您知道肯定可以根据需要工作的部分组成函数。

  2. 将一组中间结果导出到中间表,您可以使用图形工具轻松可视化中间结果集,并可以更好地评估数据出错的位置。

  3. 您使用的 ST_ 函数的组合可能不会创建您认为它们创建的几何图形,排除这种情况的一种方法是可视化地理函数组合的结果,例如 st_dump(st_split(...)))或 st_dump(st_split(...)) 例如。

  4. 也许这个检查: st_startpoint(geom) = (SELECT geom FROM brs WHERE brs.row_number = i)) 可以通过检查“附近的点”而不是“精确点”来进行,也许这些点非常接近,如附近的厘米,使它们本质上是“同一点”,但实际上并不是确切的点。但这只是一个假设。

  5. 考虑与 StackOverflow 共享更多数据!就像一个小数据集或示例,这样我们就可以实际运行代码!:)