Hi

I see that I forgot to create polygons from the splitted lines

Sp the syntax should be something like:
ST_ExteriorRing((ST_Dump(ST_Polygonize(ST_LineMerge(ST_Union(ST_Force2D(<your geometry>)))))).geom)

Hi Ari and Andreas,

Thanks for the information. I will check it out. Today I advanced a little by almost implementing what's been proposed in my message there.

Regards,
Chao

On Wed, Apr 15, 2020 at 3:04 PM Ari Jolma <ari.jo...@gmail.com <mailto:ari.jo...@gmail.com>> wrote:

    Andreas Oxenstierna kirjoitti 15.4.2020 klo 9.03:
    Hi

    Have you tested PostGIS?
    ST_ExteriorRing((ST_Dump(ST_LineMerge(ST_Union(ST_Force2D(<your
    geometry>))))).geom)

    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.


    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.

    Best,

    Ari




    Hi,

    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.

    Ari

    Chao YUE kirjoitti 15.4.2020 klo 6.30:
    Dear all,

    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.

    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.
    But I am wondering whether there is already some existing
    solutions or other better ones.

    Thanks a lot for the kind help for any hints on this !
    Kind regards,
    Chao

    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.

    InnerLoop.png

-- ***********************************************************************************
    Chao YUE(岳超)
    西北农林科技大学水土保持研究所 研究员
    黄土高原土壤侵蚀与旱地农业国家重点实验室
    State Key Laboratory of Soil Erosion and Dryland Farming on the
    Loess Plateau
    Institute of Soil and Water Conservation
    Northwest A&F University, Yangling, Shaanxi 712100, P.R. China
    chao...@ms.iswc.ac.cn <mailto:chao...@ms.iswc.ac.cn>
    Mobile: +86 18709187546
    
************************************************************************************

    _______________________________________________
    gdal-dev mailing list
    gdal-dev@lists.osgeo.org  <mailto:gdal-dev@lists.osgeo.org>
    https://lists.osgeo.org/mailman/listinfo/gdal-dev


    Code copyright Simosol Oy, licence MIT

    def add_point(self, p=None):
            """ Add a point to the end of points (before root)
            The first level ear (hole or in-a-point-intersecting
    polygon) is returned
            if there is such.
            p -- point to add, if None, close the ring

        self is a Polygon, which has as attributes a dict of points,
    where
        point = [index of previous point, index of next point, coords]
        no duplicates, no null indexes in points

               """
            n = self.n_points()
            if p is None and n < 3:
                raise ValueError("Can't close a polygon with less
    than three points.")
            if self.root is None:
                self.root = 0
                self.points[self.root] = [self.root, self.root, p]
                return
            i0 = self.points[self.root][0]
            if p is not None and p[0] == self.points[i0][2][0] and
    p[1] == self.points[i0][2][1]:
                # same point, skip
                return None
            index = i0 + 1
            while index in self.points:
                index += 1
            ear = None
            close = False
            if n > 2:
                # test for self-intersection,
                # current - new against (0-1, )1-2, ...
    prev(current)-current
                current_point = self.get_point(i0)
                j0 = self.root
                if p is None: # close
                    p = self.get_point(self.root)
                    j0 = self.index_of_next_point(j0)
                    close = True
                while True:
                    j1 = self.index_of_next_point(j0)
                    if j1 == i0:
                        break
                    pj0 = self.get_point(j0)
                    pj1 = self.get_point(j1)
                    x = get_line_intersection(pj0, pj1,
    current_point, p)

                    if type(x) is tuple: # Intersection
    #print('intersection',pj0,pj1,current_point,p)
                        # snip away and return eventually the closed
    part
                        ear = self.get_noose(j1, i0, first_point=x)
                        # set new j1 and delete from j1+1 ... current
                        self.set_point(j1, x)
                        j2 = self.index_of_next_point(j1)
                        self.delete_points(j2, i0)
                        i0 = j0
                        index = j1
                        break

                    elif abs(x) == 1: # Collinear
                        if point_on_line(p, pj0, pj1): # new is on
    j0 - j1
                            #print('collinear new on
    j0-j1',pj0,pj1,current_point,p)
                            # is j1 on cp - new?
                            if point_in_box(pj1, current_point, p):
                                k = j1 # ear is j1 ... cp
                            else: # j0 is on cp - new
                                k = j0 # ear is j0 ... cp
                            ear = self.get_noose(k, i0)
                            self.delete_points(j1, i0)
                            i0 = j0
                            index = j1
                            break
                        elif point_on_line(pj1, current_point, p): #
    j1 is on cp - new
                            #print('collinear j1 on
    cp-new',pj0,pj1,current_point,p)
                            # ear is j1 ... cp
                            ear = self.get_noose(j1, i0)
                            self.delete_points(j1, i0)
                            i0 = j0
                            index = j1
                            break
                    j0 = j1

            if not close:
                self.points[index] = [i0, self.root, p]
                self.points[i0][1] = index
                self.points[self.root][0] = index
            return ear


    _______________________________________________
    gdal-dev mailing list
    gdal-dev@lists.osgeo.org  <mailto:gdal-dev@lists.osgeo.org>
    https://lists.osgeo.org/mailman/listinfo/gdal-dev


-- Hälsningar

    Andreas Oxenstierna
    T-Kartor Geospatial AB
    Olof Mohlins väg 12 Kristianstad
    mobile: +46 733 206831
    mailto:a...@t-kartor.se  <mailto:a...@t-kartor.se>
    http://www.t-kartor.com

    _______________________________________________
    gdal-dev mailing list
    gdal-dev@lists.osgeo.org  <mailto:gdal-dev@lists.osgeo.org>
    https://lists.osgeo.org/mailman/listinfo/gdal-dev
    _______________________________________________
    gdal-dev mailing list
    gdal-dev@lists.osgeo.org <mailto:gdal-dev@lists.osgeo.org>
    https://lists.osgeo.org/mailman/listinfo/gdal-dev



--
***********************************************************************************
Chao YUE(岳超)
西北农林科技大学水土保持研究所 研究员
黄土高原土壤侵蚀与旱地农业国家重点实验室
State Key Laboratory of Soil Erosion and Dryland Farming on the Loess Plateau
Institute of Soil and Water Conservation
Northwest A&F University, Yangling, Shaanxi 712100, P.R. China
chao...@ms.iswc.ac.cn <mailto:chao...@ms.iswc.ac.cn>
Mobile: +86 18709187546
************************************************************************************


--
Best Regards

Andreas Oxenstierna
T-Kartor Geospatial AB
Olof Mohlins väg 12 Kristianstad
mobile: +46 733 206831
mailto: a...@t-kartor.se
http://www.t-kartor.com

_______________________________________________
gdal-dev mailing list
gdal-dev@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/gdal-dev

Reply via email to