创建双嵌套循环以更新postgresql中的表几何

时间:2017-08-14 09:18:51

标签: sql postgresql gis postgis

我正在尝试更新表格几何图形以删除重叠。它与此问题有关:Split polygons exactly in the middle。我设法创建工作查询,当2个多边形重叠时创建完美的新形状,但是当有2个以上的重叠时不起作用。我认为可以解决这个问题的方法是创建一个双循环,它只会在函数内部放置2个多边形,仅为第一个更新几何/行,或者将更新的行添加到新表中,并且当循环完成时返回具有更新行的新表。

里面的updateGeom函数应该只有2个多边形。如果是为了多边形1,2和3相交。拳头多边形1,2应该进入内部,当它完成1的geom应该更新然后进行下一次调用里面应该更新1 poly和3 poly。所以每次a_table的记录都要在从b_table转到下一条记录之前进行更新。此外,如果a_table中的记录与任何内容不相交,则保留此记录而不进行任何更改。

我的双循环功能:

CREATE OR REPLACE FUNCTION first_loop(some_table VARCHAR)
  RETURNS TABLE(id int, geom geometry)
  --RETURNS VOID
  AS
  $$
  DECLARE
    a_table text;
    b_table text;
    c_table text;
  BEGIN
    FOR a_table in select * from some_f(some_table)
    LOOP
      FOR b_table IN
      (select * from a_table a
  LEFT JOIN (select b1.id id, b1.geom geom from some_f(some_table) b1 WHERE b.id <> a.id) b
    ON (st_intersects(a.geom, b.geom)))
        LOOP
        RETURN QUERY
          --my second method
          --update tablename
          --SET geom = polygon.geom
          --FROM (SELECT * FROM updateGeom(b_table)) as polygon
          --WHERE id = polygon.id;
          INSERT into c_table SELECT * FROM updategeom(b_table) tu WHERE tu.id = a_table.id;
        END LOOP;
    END LOOP;

  END;
  $$
  LANGUAGE plpgsql;

我的问题是我不知道如何为我的updategeom功能设置输入。目前我的b_table返回a_table多边形行和与该行相交的所有多边形行。

这是我的意见:

ID   geom
1    POLYGON((1.46446609406726 9.53553390593274,2.222148834902 10.1573480615127,3.08658283817456 10.6193976625564,4.02454838991936 10.9039264020162,5 11,5.97545161008065 10.9039264020162,6.91341716182545 10.6193976625564,7.77785116509801 10.1573480615127,8.53553390593274 9.53553390593274,9.15734806151272 8.77785116509801,9.61939766255643 7.91341716182545,9.90392640201615 6.97545161008064,10 6,9.90392640201615 5.02454838991936,9.61939766255644 4.08658283817456,9.15734806151273 3.222148834902,8.53553390593274 2.46446609406726,4.53553390593274 -1.53553390593274,3.77785116509801 -2.15734806151273,2.91341716182544 -2.61939766255644,1.97545161008064 -2.90392640201615,0.999999999999997 -3,0.0245483899193568 -2.90392640201615,-0.913417161825449 -2.61939766255643,-1.77785116509801 -2.15734806151273,-2.53553390593274 -1.53553390593274,-3.15734806151272 -0.777851165098014,-3.61939766255643 0.0865828381745486,-3.90392640201615 1.02454838991935,-4 1.99999999999999,-3.90392640201615 2.97545161008063,-3.61939766255644 3.91341716182544,-3.15734806151273 4.777851165098,-2.53553390593274 5.53553390593274,1.46446609406726 9.53553390593274))
2    POLYGON((-1.98298112825965 -1.98298112825965,-2.33787015556454 -1.72271712927421,-3 -1,-3.50841208766131 -0.161994553145181,-3.84356842714042 0.759095131926497,-3.99258914826899 1.72787209517077,-3.94974746830583 2.70710678118654,-3.71668976898605 3.65916775015137,-3.30237232699422 4.54746783294987,-2.72271712927421 5.33787015556453,-2 6,2 9,2.8117599230287 9.49573190543394,3.70270825387629 9.8287714923611,4.64060320129179 9.98706666699757,5.59150406179902 9.96488901637038,6.52099947170454 9.76304110911028,7.39545269143852 9.38882745196026,8.18321885766463 8.85579015303067,8.85579015303067 8.18321885766463,9.38882745196026 7.39545269143852,9.76304110911028 6.52099947170454,9.96488901637038 5.59150406179902,9.98706666699757 4.64060320129179,9.8287714923611 3.70270825387629,9.49573190543394 2.8117599230287,9 2,6 -2,5.33787015556453 -2.72271712927421,4.54746783294987 -3.30237232699422,3.65916775015137 -3.71668976898605,2.70710678118655 -3.94974746830583,1.72787209517077 -3.99258914826899,0.759095131926498 -3.84356842714042,-0.161994553145176 -3.50841208766131,-0.999999999999999 -3,-1.7227171292742 -2.33787015556454,-1.98298112825965 -1.98298112825965))
3    POLYGON((-0.786796564403575 7.2842712474619,2 11,2.66212984443547 11.7227171292742,3.45253216705013 12.3023723269942,4.34083224984863 12.716689768986,5.29289321881346 12.9497474683058,6.27212790482923 12.992589148269,7.2409048680735 12.8435684271404,8.16199455314518 12.5084120876613,9 12,9.72271712927421 11.3378701555645,10.3023723269942 10.5474678329499,10.716689768986 9.65916775015138,10.9497474683058 8.70710678118655,10.992589148269 7.72787209517078,10.8435684271404 6.7590951319265,10.5084120876613 5.83800544685483,10 5,7 1,6.53553390593274 0.464466094067263,5.53553390593274 -0.535533905932737,4.77785116509801 -1.15734806151273,3.91341716182544 -1.61939766255644,2.97545161008064 -1.90392640201615,2 -2,1.02454838991936 -1.90392640201615,0.0865828381745506 -1.61939766255643,-0.77785116509801 -1.15734806151273,-1.53553390593274 -0.535533905932738,-2.15734806151272 0.222148834901986,-2.61939766255643 1.08658283817455,-2.90392640201615 2.02454838991935,-3 3,-2.90392640201615 3.97545161008063,-2.61939766255644 4.91341716182544,-2.15734806151273 5.777851165098,-1.53553390593274 6.53553390593274,-0.786796564403575 7.2842712474619))
4    POLYGON((0.464466094067263 6.53553390593274,1.222148834902 7.15734806151273,2.08658283817456 7.61939766255644,3.02454838991936 7.90392640201615,4 8,4.97545161008065 7.90392640201615,5.91341716182545 7.61939766255643,6.77785116509801 7.15734806151273,7.53553390593274 6.53553390593274,8.15734806151272 5.77785116509801,8.61939766255643 4.91341716182545,8.90392640201615 3.97545161008064,9 3,8.90392640201615 2.02454838991936,8.61939766255644 1.08658283817456,8.15734806151273 0.222148834901995,7.53553390593274 -0.535533905932737,5.53553390593274 -2.53553390593274,4.77785116509801 -3.15734806151273,3.91341716182544 -3.61939766255644,2.97545161008064 -3.90392640201615,2 -4,1.02454838991936 -3.90392640201615,0.0865828381745506 -3.61939766255643,-0.77785116509801 -3.15734806151273,-1.53553390593274 -2.53553390593274,-2.15734806151272 -1.77785116509801,-2.61939766255643 -0.913417161825451,-2.90392640201615 0.0245483899193526,-3 0.999999999999995,-2.90392640201615 1.97545161008063,-2.61939766255644 2.91341716182544,-2.15734806151273 3.777851165098,-1.53553390593274 4.53553390593274,0.464466094067263 6.53553390593274))

设置代码:

CREATE table polygons (id SERIAL, geom geometry);

INSERT  INTO polygons (geom) VALUES
 (ST_Buffer(st_addpoint(ST_MakeLine(ST_MakePoint(1, 2), ST_MakePoint(3, 4)), st_makepoint(5, 6)), 5)),
 ( ST_Buffer((ST_MakeLine(ST_MakePoint(2, 1), ST_MakePoint(4, 3))), 5)),
 ( ST_Buffer(ST_MakePoint(7.5,7.5), 5))
 ( ST_Buffer(ST_MakePoint(5,5), 5));

CREATE OR REPLACE FUNCTION updateGeom(tablename varchar) RETURNS table(id int, geom geometry)
--RETURNS VOID AS $func$ BEGIN   EXECUTE format('   with union_poly AS (
    SELECT
      b.id,
      b.geom geom2,
      (SELECT st_makepolygon(st_exteriorring(st_union(t2.geom)))
       FROM %s t2
       WHERE t2.id <> b.id
      ) AS geom
    FROM %s b )   , clip_union_poly AS (
    SELECT
      a.id,
      ST_LineMerge(st_difference(ST_ExteriorRing(a.geom2), b.geom)) cut,
      a.geom                                                        poly
    FROM union_poly a
      LEFT JOIN union_poly b ON (ST_Intersects(a.geom2, b.geom) AND a.id = b.id) )   , centre AS (
    SELECT
      a.id,
      st_linemerge(st_approximatemedialaxis(st_intersection(a.geom2, b.geom))) centre
    FROM union_poly a
      LEFT JOIN union_poly b ON (ST_Intersects(a.geom2, b.geom) AND a.id = b.id) )

  , distance AS (
    SELECT
      b.id,
      b.cut                                              cut,
      a.centre                                           centre,
      b.poly                                             poly,
      st_startpoint(b.cut)                               stCut,
      st_endpoint(b.cut)                                 endCut,
      (st_startpoint(a.centre) <-> st_startpoint(b.cut)) cStpSt,
      (st_startpoint(a.centre) <-> st_endpoint(b.cut))   cStpEnd,
      (st_endpoint(a.centre) <-> st_startpoint(b.cut))   cEndpSt,
      (st_endpoint(a.centre) <-> st_endpoint(b.cut))     cEndpEnd
    FROM centre a, clip_union_poly b
    WHERE b.id = a.id )

  , casing AS (
    SELECT
      b.id                                             id,
      cut                                              cut,
      st_astext(stCut)                                 stCut,
      st_astext(endCut)                                endCut,
      b.poly                                             poly,

      (CASE WHEN b.cEndpSt < b.cEndpEnd
        THEN st_addpoint(stExt.centrStart, stCut)
       ELSE st_addpoint(stExt.centrStart, endCut) END) endExt

    FROM distance b LEFT JOIN (SELECT
                                 b.id,
                                 (CASE WHEN b.cStpSt < b.cStpEnd
                                   THEN st_addpoint(centre, stCut, 0)
                                  ELSE st_addpoint(centre, endCut, 0) END) centrStart
                               FROM distance b) stExt ON b.id = stExt.id )

  , polygon AS (
    SELECT
      a.poly                                             poly2,
      a.id,
      st_astext(cut)                      cut,
      st_astext(endExt)                   ext,
      st_astext(st_reverse(endExt))       rev,
      st_astext(st_makeline(cut, endExt)) line,
      st_makepolygon(ST_AddPoint(st_makeline(cut, cl.center), st_startpoint(st_makeline(cut, cl.center)))) poly
    FROM casing a LEFT JOIN (SELECT
                               b.id,
                               (CASE WHEN (st_startpoint(b.cut) <-> st_startpoint(b.endExt)) > 0
                                 THEN b.endExt
                                ELSE st_reverse(b.endExt) END) center
                             FROM casing b) cl ON cl.id = a.id )

  , tool AS (
    SELECT
             b.*,
             (SELECT a.poly
              FROM polygon a
              WHERE a.id = b.id)
           FROM %s b ) 

SELECT * from tool
--update "%s"
--SET geom = polygon.poly
--FROM polygon
--WHERE %s.id = polygon.id ', tablename, tablename, tablename, tablename, tablename); END; $func$ LANGUAGE plpgsql;

0 个答案:

没有答案