Reputation: 551
I have a relatively simple task to accomplish in R: I have two polygon layers, a "patches" layer containing 39 focal polygons and a "landcover" layer containing one multipolygon of the focal landcover type. I need to clip those two layers so that I keep only the extent of the focal landcover type within the focal polygons. Sometimes, this works fine with sf::st_intersection
, sometimes this works fine using sf::st_difference
and a "negative" landcover layer (containing the extent of all non-focal landcover types) and sometimes none of both approaches work. At first, I thought that these different behaviors depend on the resulting topography complexitiy, but this does not seem to be the case.
The errors I get are of the form
Error in CPL_geos_op2(op, st_geometry(x), st_geometry(y)) : Evaluation error: TopologyException: Input geom 1 is invalid: Ring Self-intersection at or near point 4372482.6526834015 5297568.4303682083 at 4372482.6526834015 5297568.4303682083.
so I checked for the land cover polygon and each of the focal polygons using sf:: st_is_simple ('patch')
which in all cases yielded TRUE
.
Consider these three cases:
The "simple" case, where sf::st_intersection
works. An example (the
patch in blue, the land cover in green):
The "intermediate" case, where sf::st_intersection
does not work
but sf::st_difference
can be used as a workaround when the focal
landcover is replaced by the non-focal land-cover. An example (the
patch in blue, the non-focal land cover in red:
The "difficult" case where neither keeping the focal land cover (green) type using sf::st_intersection
nor excluding the non-focal land cover type (red) using sf::st_difference
work - I get similar errors for both approaches:
I was unable to make a reproducible example, so I hope that it is possible to figure out what happens here from the example images. I could not see any pattern in there so perhaps only someone with deep insights into st_intersection
and st_difference
can indiciate a solution to this...
Upvotes: 3
Views: 1659
Reputation: 8699
The error you are describing is not random; ring self intersection means invalid geometry. You should be able to test for it via sf::st_is_valid()
.
This error is known to happen when using spatial objects originated in the realm of ESRI products, which use slightly different criteria for validity than OGC realm.
To overcome the issue you have several options:
sf::st_is_valid()
= leaving only valid geometries in place)sf::st_make_valid()
- note that this may result in altered geometry, and may require installation of {lwgeom}
packagesf::st_buffer(your_ object, 0)
. This hack will force creation of a new geometry, possibly overcoming the errors in the original one.For more information consider the sf package documentation: https://r-spatial.github.io/sf/reference/valid.html
Upvotes: 5