[gdal-dev] Algorithm to clip the inner loop of a polygon
Andreas Oxenstierna
ao at t-kartor.se
Wed Apr 15 06:31:45 PDT 2020
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.jolma at gmail.com
> <mailto:ari.jolma at 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
>>>> chaoyue at ms.iswc.ac.cn <mailto:chaoyue at ms.iswc.ac.cn>
>>>> Mobile: +86 18709187546
>>>> ************************************************************************************
>>>>
>>>> _______________________________________________
>>>> gdal-dev mailing list
>>>> gdal-dev at lists.osgeo.org <mailto:gdal-dev at 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 at lists.osgeo.org <mailto:gdal-dev at 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:ao at t-kartor.se <mailto:ao at t-kartor.se>
>> http://www.t-kartor.com
>>
>> _______________________________________________
>> gdal-dev mailing list
>> gdal-dev at lists.osgeo.org <mailto:gdal-dev at lists.osgeo.org>
>> https://lists.osgeo.org/mailman/listinfo/gdal-dev
> _______________________________________________
> gdal-dev mailing list
> gdal-dev at lists.osgeo.org <mailto:gdal-dev at 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
> chaoyue at ms.iswc.ac.cn <mailto:chaoyue at 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: ao at t-kartor.se
http://www.t-kartor.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20200415/f823edf6/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: InnerLoop.png
Type: image/png
Size: 30127 bytes
Desc: not available
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20200415/f823edf6/attachment-0001.png>
More information about the gdal-dev
mailing list