<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <div class="moz-cite-prefix">Hi</div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">Have you tested PostGIS?</div>
    <div class="moz-cite-prefix">ST_ExteriorRing((ST_Dump(ST_LineMerge(ST_Union(ST_Force2D(<your
      geometry>))))).geom)</div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">should extract the points you want to
      keep by splitting at intersections - but it may fail in very
      complex cases. Then I would start with a ST_SnapToGrid with a
      quite high tolerance to lower the coordinate resolution.<br>
      <br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <blockquote type="cite"
      cite="mid:aeff7777-d05b-415c-e2d6-cb7ff62bac83@gmail.com">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <p>Hi,</p>
      <p>I wrote a method to a Polygon class (in Python) that solves
        that problem because the ones in GEOS via Shapely did not seem
        good enough. My method was based on no published algorithm but
        just my own reasoning, it is probably not optimal speed-wise. I
        did not perform formal testing on it but it worked on my data,
        which was quite large. The basic idea was to build the polygon
        by adding points and when adding test for self intersections /
        collinearity against existing segments. The method returns the
        loops while points are added. The code is not in a public repo
        but I'll add the method below. It needs some basic methods and
        function which should be simple to add.<br>
      </p>
      <p>Ari<br>
      </p>
      <div class="moz-cite-prefix">Chao YUE kirjoitti 15.4.2020 klo
        6.30:<br>
      </div>
      <blockquote type="cite"
cite="mid:CAAN-aRFQsyoVTBceU0QhGcoPr-obmeVhUujAccYroaJwBBPUCw@mail.gmail.com">
        <meta http-equiv="content-type" content="text/html;
          charset=UTF-8">
        <div dir="ltr">
          <div class="gmail_default" style="font-size:small">
            <div>Dear all,</div>
            <div><br>
            </div>
            <div>Does anyone have some experience or is aware of some
              algorithm that can find and clip the inner loop formed in
              a polygon ? I attach one example here. In this case I
              would only keep the outer points and drop the ones that
              make an inner loop. I am developing some algorithm to
              simulate wildland fire propagation. The algorithm is based
              on Richards 1990.</div>
            <div><br>
            </div>
            <div>In the paper he described an algorithm based on two
              steps: (1) find the points where a concave curvature is
              made. (2) search for both sides of this point to see where
              any two line segments cross over each other. </div>
            <div>But I am wondering whether there is already some
              existing solutions or other better ones. </div>
            <div><br>
            </div>
            <div>Thanks a lot for the kind help for any hints on this !</div>
            <div>Kind regards,</div>
            <div>Chao</div>
            <div><br>
            </div>
            <div>Gwynfor Richards, 1990. An elliptical growth model of
              forest fire fronts and its numerical solution.
              International journal for Numerical Methods in
              Engineering, Vol. 30, 1163-1179.</div>
            <div><br>
            </div>
            <div><img src="cid:part1.8C18B390.16925307@t-kartor.se"
                alt="InnerLoop.png" class="" width="562" height="415"><br>
            </div>
          </div>
          <div><br>
          </div>
          -- <br>
          <div dir="ltr" class="gmail_signature"
            data-smartmail="gmail_signature">
            <div dir="ltr">
              <div>
                <div dir="ltr">
                  <div>
                    <div dir="ltr">
                      <div dir="ltr">
                        <div dir="ltr">
                          <div><span style="font-size:12.8px">***********************************************************************************</span><br>
                          </div>
                          <div><font color="#000000">Chao YUE(岳超)</font></div>
                          <font color="#000000">西北农林科技大学水土保持研究所 研究员</font></div>
                        <div dir="ltr"><font color="#000000">黄土高原土壤侵蚀与旱地农业国家重点实验室</font></div>
                        <div dir="ltr"><span
                            style="font-family:Helvetica;font-size:12px"><font
                              color="#000000">State Key Laboratory of
                              Soil Erosion and Dryland Farming on the
                              Loess Plateau</font></span></div>
                        <div dir="ltr"><span
                            style="font-family:Helvetica;font-size:12px"><font
                              color="#000000">Institute of Soil and
                              Water Conservation</font></span></div>
                        <div dir="ltr"><font color="#000000"><span
                              style="font-family:Helvetica;font-size:12px">Northwest
                              A&F University, Yangling, Shaanxi
                              712100, P.R. China</span><br>
                          </font></div>
                        <div dir="ltr">
                          <div><font color="#000000"><a
                                href="mailto:chaoyue@ms.iswc.ac.cn"
                                style="font-family:Helvetica;font-size:12px"
                                target="_blank" moz-do-not-send="true">chaoyue@ms.iswc.ac.cn</a><br>
                            </font></div>
                          <div><font color="#000000">Mobile: +86
                              18709187546</font></div>
                          <div>************************************************************************************<br>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <br>
        <fieldset class="mimeAttachmentHeader"></fieldset>
        <pre class="moz-quote-pre" wrap="">_______________________________________________
gdal-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:gdal-dev@lists.osgeo.org" moz-do-not-send="true">gdal-dev@lists.osgeo.org</a>
<a class="moz-txt-link-freetext" href="https://lists.osgeo.org/mailman/listinfo/gdal-dev" moz-do-not-send="true">https://lists.osgeo.org/mailman/listinfo/gdal-dev</a></pre>
      </blockquote>
      <p><br>
      </p>
      <p>Code copyright Simosol Oy, licence MIT<br>
      </p>
      <p>def add_point(self, p=None):<br>
                """ Add a point to the end of points (before root)<br>
                The first level ear (hole or in-a-point-intersecting
        polygon) is returned<br>
                if there is such.<br>
                p -- point to add, if None, close the ring</p>
      <p>    self is a Polygon, which has as attributes a dict of
        points, where<br>
            point = [index of previous point, index of next point,
        coords]<br>
            no duplicates, no null indexes in points<br>
      </p>
      <p>           """<br>
                n = self.n_points()<br>
                if p is None and n < 3:<br>
                    raise ValueError("Can't close a polygon with less
        than three points.")<br>
                if self.root is None:<br>
                    self.root = 0<br>
                    self.points[self.root] = [self.root, self.root, p]<br>
                    return<br>
                i0 = self.points[self.root][0]<br>
                if p is not None and p[0] == self.points[i0][2][0] and
        p[1] == self.points[i0][2][1]:<br>
                    # same point, skip<br>
                    return None<br>
                index = i0 + 1<br>
                while index in self.points:<br>
                    index += 1<br>
                ear = None<br>
                close = False<br>
                if n > 2:<br>
                    # test for self-intersection,<br>
                    # current - new against (0-1, )1-2, ...
        prev(current)-current<br>
                    current_point = self.get_point(i0)<br>
                    j0 = self.root<br>
                    if p is None: # close<br>
                        p = self.get_point(self.root)<br>
                        j0 = self.index_of_next_point(j0)<br>
                        close = True<br>
                    while True:<br>
                        j1 = self.index_of_next_point(j0)<br>
                        if j1 == i0:<br>
                            break<br>
                        pj0 = self.get_point(j0)<br>
                        pj1 = self.get_point(j1)<br>
                        x = get_line_intersection(pj0, pj1,
        current_point, p)<br>
        <br>
                        if type(x) is tuple: # Intersection<br>
                           
        #print('intersection',pj0,pj1,current_point,p)<br>
                            # snip away and return eventually the closed
        part<br>
                            ear = self.get_noose(j1, i0, first_point=x)<br>
                            # set new j1 and delete from j1+1 ...
        current<br>
                            self.set_point(j1, x)<br>
                            j2 = self.index_of_next_point(j1)<br>
                            self.delete_points(j2, i0)<br>
                            i0 = j0<br>
                            index = j1<br>
                            break<br>
        <br>
                        elif abs(x) == 1: # Collinear<br>
                            if point_on_line(p, pj0, pj1): # new is on
        j0 - j1<br>
                                #print('collinear new on
        j0-j1',pj0,pj1,current_point,p)<br>
                                # is j1 on cp - new?<br>
                                if point_in_box(pj1, current_point, p):<br>
                                    k = j1 # ear is j1 ... cp<br>
                                else: # j0 is on cp - new<br>
                                    k = j0 # ear is j0 ... cp<br>
                                ear = self.get_noose(k, i0)<br>
                                self.delete_points(j1, i0)<br>
                                i0 = j0<br>
                                index = j1<br>
                                break<br>
                            elif point_on_line(pj1, current_point, p): #
        j1 is on cp - new<br>
                                #print('collinear j1 on
        cp-new',pj0,pj1,current_point,p)<br>
                                # ear is j1 ... cp<br>
                                ear = self.get_noose(j1, i0)<br>
                                self.delete_points(j1, i0)<br>
                                i0 = j0<br>
                                index = j1<br>
                                break<br>
                        j0 = j1<br>
        <br>
                if not close:<br>
                    self.points[index] = [i0, self.root, p]<br>
                    self.points[i0][1] = index<br>
                    self.points[self.root][0] = index<br>
                return ear<br>
      </p>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
gdal-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:gdal-dev@lists.osgeo.org">gdal-dev@lists.osgeo.org</a>
<a class="moz-txt-link-freetext" href="https://lists.osgeo.org/mailman/listinfo/gdal-dev">https://lists.osgeo.org/mailman/listinfo/gdal-dev</a></pre>
    </blockquote>
    <p><br>
    </p>
    <pre class="moz-signature" cols="72">-- 
Hälsningar

Andreas Oxenstierna
T-Kartor Geospatial AB
Olof Mohlins väg 12 Kristianstad
mobile: +46 733 206831
mailto: <a class="moz-txt-link-abbreviated" href="mailto:ao@t-kartor.se">ao@t-kartor.se</a>
<a class="moz-txt-link-freetext" href="http://www.t-kartor.com">http://www.t-kartor.com</a></pre>
  </body>
</html>