[R-sig-Geo] Cleaning small spatial polygons
Eduardo Diez
eduardodiez at gmx.com
Sat Nov 7 03:45:31 CET 2015
Roger,
Following this last approach strange things happen: the sliver polygons
that are fully inside another one get "merged" with the larger; the ones
that have no contact with the exterior but share boundaries with two or
more polygons get deleted and a hole left behind; the ones in contact with
the exterior get deleted.
This is what i tried. As the polygons were projected i used values
in squared meters for the set_RGEOS_polyThreshold function. I think values
of around 1e-2 are more appropriate for Spatial* objects in GCS.
> pol1 <- rasterToPolygons(raster1, dissolve = T)
> pol2 <- createSPComment(pol1)
> set_RGEOS_polyThreshold(3000) # for example
> set_RGEOS_warnSlivers(T)
> set_RGEOS_dropSlivers(T)
> t1 <- gBuffer(pol2, byid = T, width = 0)
There were 50 or more warnings (use warnings() to see the first 50)
> warnings()
Warning messages:
1: In gBuffer(pol2, byid = T, width = 0) : 1: Polygon object 0 area 726.084
2: In gBuffer(pol2, byid = T, width = 0) : 2: Polygon object 1 area 20.169
3: In gBuffer(pol2, byid = T, width = 0) : 3: Polygon object 2 area 20.169
4: In gBuffer(pol2, byid = T, width = 0) : 4: Polygon object 3 area 20.169
5: In gBuffer(pol2, byid = T, width = 0) : 5: Polygon object 4 area 20.169
6: In gBuffer(pol2, byid = T, width = 0) : 6: Polygon object 5 area 20.169
7: In gBuffer(pol2, byid = T, width = 0) : 7: Polygon object 6 area 80.676
8: In gBuffer(pol2, byid = T, width = 0) : 8: Polygon object 7 area 20.169
9: In gBuffer(pol2, byid = T, width = 0) : 9: Polygon object 8 area 20.169
10: In gBuffer(pol2, byid = T, width = 0) : 10: Polygon object 9 area 20.169
11: In gBuffer(pol2, byid = T, width = 0) : 11: Polygon object 10 area
2581.63
12: In gBuffer(pol2, byid = T, width = 0) : 12: Polygon object 11 area
40.338
13: In gBuffer(pol2, byid = T, width = 0) : 13: Polygon object 12 area
20.169
14: In gBuffer(pol2, byid = T, width = 0) : 14: Polygon object 14 area 1432
15: In gBuffer(pol2, byid = T, width = 0) : 15: Polygon object 15 area
40.338
16: In gBuffer(pol2, byid = T, width = 0) : 16: Polygon object 16 area
20.169
17: In gBuffer(pol2, byid = T, width = 0) : 17: Polygon object 17 area
20.169
18: In gBuffer(pol2, byid = T, width = 0) : 18: Polygon object 18 area
20.169
19: In gBuffer(pol2, byid = T, width = 0) : 19: Polygon object 19 area
80.676
20: In gBuffer(pol2, byid = T, width = 0) : 20: Polygon object 21 area
20.169
21: In gBuffer(pol2, byid = T, width = 0) : 21: Polygon object 22 area
1230.31
22: In gBuffer(pol2, byid = T, width = 0) : 22: Polygon object 23 area
20.169
23: In gBuffer(pol2, byid = T, width = 0) : 23: Polygon object 25 area
20.169
24: In gBuffer(pol2, byid = T, width = 0) : 24: Polygon object 26 area
20.169
25: In gBuffer(pol2, byid = T, width = 0) : 25: Polygon object 27 area
564.732
26: In gBuffer(pol2, byid = T, width = 0) : 26: Polygon object 28 area
40.338
27: In gBuffer(pol2, byid = T, width = 0) : 27: Polygon object 30 area
504.225
28: In gBuffer(pol2, byid = T, width = 0) : 28: Polygon object 31 area
605.07
29: In gBuffer(pol2, byid = T, width = 0) : 29: Polygon object 33 area
20.169
30: In gBuffer(pol2, byid = T, width = 0) : 30: Polygon object 34 area
20.169
31: In gBuffer(pol2, byid = T, width = 0) : 31: Polygon object 35 area
1210.14
32: In gBuffer(pol2, byid = T, width = 0) : 32: Polygon object 36 area
20.169
33: In gBuffer(pol2, byid = T, width = 0) : 33: Polygon object 37 area
685.746
34: In gBuffer(pol2, byid = T, width = 0) : 34: Polygon object 38 area
40.338
35: In gBuffer(pol2, byid = T, width = 0) : 35: Polygon object 39 area
20.169
36: In gBuffer(pol2, byid = T, width = 0) : 36: Polygon object 40 area
20.169
37: In gBuffer(pol2, byid = T, width = 0) : 37: Polygon object 41 area
80.676
38: In gBuffer(pol2, byid = T, width = 0) : 38: Polygon object 42 area
20.169
39: In gBuffer(pol2, byid = T, width = 0) : 39: Polygon object 43 area
625.239
40: In gBuffer(pol2, byid = T, width = 0) : 40: Polygon object 44 area
20.169
41: In gBuffer(pol2, byid = T, width = 0) : 41: Polygon object 46 area
262.197
42: In gBuffer(pol2, byid = T, width = 0) : 42: Polygon object 47 area
2500.96
43: In gBuffer(pol2, byid = T, width = 0) : 43: Polygon object 48 area
20.169
44: In gBuffer(pol2, byid = T, width = 0) : 44: Polygon object 49 area
40.338
45: In gBuffer(pol2, byid = T, width = 0) : 45: Polygon object 53 area
80.676
46: In gBuffer(pol2, byid = T, width = 0) : 46: Polygon object 56 area
1290.82
47: In gBuffer(pol2, byid = T, width = 0) : 47: Polygon object 57 area
2722.82
48: In gBuffer(pol2, byid = T, width = 0) : 48: Polygon object 59 area
2218.59
49: In gBuffer(pol2, byid = T, width = 0) : 49: Polygon object 60 area
40.338
50: In gBuffer(pol2, byid = T, width = 0) : 50: Polygon object 61 area
121.014
> spplot(t1)
Thanks, and sorry if i can't be of much help in making suggestions as i
don't know how could this be done
2015-11-05 8:05 GMT-03:00 Roger Bivand <Roger.Bivand at nhh.no>:
> On Wed, 4 Nov 2015, Roger Bivand wrote:
>
> On Wed, 4 Nov 2015, Eduardo Diez wrote:
>>
>> Is there any way of doing this or should i forget it and go on using
>>> GRASS
>>> through rgrass7?
>>>
>>
>> I suggest working with Emmanuel Blondel (cleangeo maintainer) to extend
>> cleangeo (also suggested in an earlier thread today, with apologies to
>> Emmanuel for picking on him!). That package already uses rgeos, and is a
>> logical place to put GRASS v.clean-like functionality (maybe even
>> encapsulating using GRASs via rgrass7 and a throwaway location).
>>
>> At the moment it is messy, though some rgeos internals do do something
>> like this, but it isn't exposed to users.
>>
>
> A possibility is to use:
>
> set_RGEOS_polyThreshold(1e-2) # for example
> set_RGEOS_warnSlivers(TRUE)
>
> shows the remaining slivers, and:
>
> set_RGEOS_dropSlivers(TRUE)
>
> drops them when using for example:
>
> t1 <- gBuffer(<your_object>, byid=TRUE, width=0)
>>
>
> A buffer of zero width should not have side-effects, but your mileage may
> vary. It will only remove slivers, not dangles. I haven't tried it when it
> also finds a Polygons object under the threshold, which was your initial
> problem.
>
> Roger
>
>
>
>> Roger
>>
>>
>>> Thanks
>>>
>>> 2015-10-19 15:03 GMT-03:00 Eduardo Diez <eduardodiez at gmx.com>:
>>>
>>> > Ok. So here's a link to a zip file that contains two shapefiles:
>>> > - pol_to_be_cleaned: the layer from which i'd like to remove small
>>> > polygons
>>> > - pol_cleaned: the layer cleaned with the function v.clean rmarea
>>> > > http://1drv.ms/1GmRWS7
>>> > > The threshold i used for cleaning was 3000 (meaning 3000 squared >
>>> meters).
>>> > > Although i do project it before sending it to GRASS, according to
>>> the
>>> > official help page it should be able to handle it:
>>> > "Threshold must always be in square meters, also for
>>> latitude-longitude
>>> > locations or locations with units other than meters"
>>> > > Thanks
>>> > > 2015-10-19 8:28 GMT-03:00 Roger Bivand <Roger.Bivand at nhh.no>:
>>> > > > On Fri, 16 Oct 2015, Eduardo Diez wrote:
>>> > > > > Dear list,
>>> > > > I'm willing to know if any knows a way of performing tha same
>>> thing > > > i'm
>>> > > > doing through rgrass7 with GRASS when I execute the function
>>> v.clean > > > with
>>> > > > "rmarea" as the tool argument. That is:
>>> > > > > > > "The rmarea tool removes all areas <= thresh. The longest
>>> boundary > > > with
>>> > > > an
>>> > > > adjacent area is removed or all boundaries if there is no
>>> adjacent > > > area.
>>> > > > Area categories are not combined when a small area is merged with
>>> a
>>> > > > larger
>>> > > > area."
>>> > > > > > > Basically i have raster of zones within a field. I convert
>>> it to
>>> > > > SpatialPolygonsDataFrame and in order to leave only the more
>>> > > > important/meaningful ones i remove the small/sliver with this
>>> tool. > > > In
>>> > > > general it works fine but having to call an external software
>>> with a
>>> > > > specific version makes the script less portable and you have to be
>>> > > > careful
>>> > > > with updates and such. Also you have to write rasters and
>>> shapefiles > > > back
>>> > > > and forth as GRASS can't work with in-memory objects.
>>> > > > > > > > Could you please provide an example of a built-in or
>>> contributed data > > set
>>> > > (URL, not attachment) with the slivers you mention, so that we know
>>> > > that we
>>> > > are addressing your problem? I don't think that:
>>> > > > > https://cran.r-project.org/web/packages/cleangeo/index.html
>>> > > > > does this, as it seems to try to repair broken geometries.
>>> > > > > Also note that you need to specify that the area threshold is
>>> in a > > square
>>> > > planar metric - dropping slivers in unprojected geometries may be
>>> more
>>> > > complicated.
>>> > > > > Roger
>>> > > > > > > > Does someone know a way of doing this in plain R?
>>> > > > > > > Thanks
>>> > > > > > > [[alternative HTML version deleted]]
>>> > > > > > > _______________________________________________
>>> > > > R-sig-Geo mailing list
>>> > > > R-sig-Geo at r-project.org
>>> > > > https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>>> > > > > > > > > --
>>> > > Roger Bivand
>>> > > Department of Economics, Norwegian School of Economics,
>>> > > Helleveien 30, N-5045 Bergen, Norway.
>>> > > voice: +47 55 95 93 55; fax +47 55 95 91 00
>>> > > e-mail: Roger.Bivand at nhh.no
>>> > > > > >
>>>
>>
>>
>>
> --
> Roger Bivand
> Department of Economics, Norwegian School of Economics,
> Helleveien 30, N-5045 Bergen, Norway.
> voice: +47 55 95 93 55; fax +47 55 95 91 00
> e-mail: Roger.Bivand at nhh.no
>
>
[[alternative HTML version deleted]]
More information about the R-sig-Geo
mailing list