yenats
yenats

Reputation: 551

sf::st_intersection: virtually random error action

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_differenceand 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:

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

Answers (1)

Jindra Lacko
Jindra Lacko

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:

  • filter the offending geometry out (via subsetting of your spatial object based on the result of sf::st_is_valid() = leaving only valid geometries in place)
  • try to correct the geometries via sf::st_make_valid() - note that this may result in altered geometry, and may require installation of {lwgeom} package
  • apply "magic dust" of a buffer of zero width on your invalid spatial object via sf::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

Related Questions