<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <div class="moz-cite-prefix">Andreas Oxenstierna kirjoitti 15.4.2020
      klo 9.03:<br>
    </div>
    <blockquote type="cite"
      cite="mid:154d7069-6cd0-4b85-da02-75cdc00bf746@t-kartor.se">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <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>
      </div>
    </blockquote>
    <p><br>
    </p>
    <p>That PostGIS solution looks quite nice. Unfortunately I was not
      able to use PostGIS in my case but were restricted to Shapely,
      which uses GEOS. But then, PostGIS is mostly based on GEOS, so it
      should perhaps be doable that way too. I'm not working or using
      that solution I gave right now so won't test it.</p>
    <p>Best,<br>
    </p>
    <p>Ari<br>
    </p>
    <p><br>
    </p>
    <blockquote type="cite"
      cite="mid:154d7069-6cd0-4b85-da02-75cdc00bf746@t-kartor.se">
      <div class="moz-cite-prefix"> <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.54C15395.18E8B9C9@gmail.com"
                  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" 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>
      <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" moz-do-not-send="true">ao@t-kartor.se</a>
<a class="moz-txt-link-freetext" href="http://www.t-kartor.com" moz-do-not-send="true">http://www.t-kartor.com</a></pre>
      <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>
  </body>
</html>