r-spatial/sf

TopologyException: side location conflict with st_overlaps

mem48 opened this issue · 4 comments

Describe the bug
I am getting an error with the attached data
example.zip

I think this is due to bad data, but I wanted to raise it as an issue because it it a little odd. The error message suggests that something is wrong with the data, but st_is_valid returns TRUE. It also only affects some of the binary predicates but not all.

I think the error is related to a polygon having duplicated coordinates, but I have not been able to recreate the error except with my real data.

This is a plot of the two polygons with the red dot showing the location of the error

image

To Reproduce

polys = st_read("example.geojson")
st_overlaps(polys)
Error in scan(text = lst[[length(lst)]], quiet = TRUE) : 
  scan() expected 'a real', got '554110.83121316193.'
Error in (function (msg)  : 
  TopologyException: side location conflict at 210668.20566749386 554110.83121316193. This can occur if the input geometry is invalid.

The only fix I could find is to use st_simplify(polys, dTolerance = 0.0001) It also seems to be sensitive to rounding as converting to text and back again also fixes the error.

> sessionInfo() R version 4.3.3 (2024-02-29 ucrt) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 19045)

Matrix products: default

locale:
[1] LC_COLLATE=English_United Kingdom.utf8 LC_CTYPE=English_United Kingdom.utf8 LC_MONETARY=English_United Kingdom.utf8
[4] LC_NUMERIC=C LC_TIME=English_United Kingdom.utf8

time zone: Europe/London
tzcode source: internal

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] targets_1.6.0 sf_1.0-16

loaded via a namespace (and not attached):
[1] utf8_1.2.4 future_1.33.2 generics_0.1.3 class_7.3-22 KernSmooth_2.23-22 lattice_0.22-5
[7] listenv_0.9.1 digest_0.6.35 magrittr_2.0.3 grid_4.3.3 processx_3.8.4 e1071_1.7-14
[13] backports_1.4.1 secretbase_0.4.0 DBI_1.2.2 ps_1.7.6 purrr_1.0.2 fansi_1.0.6
[19] codetools_0.2-19 cli_3.6.2 rlang_1.1.3 units_0.8-5 parallelly_1.37.1 withr_3.0.0
[25] yaml_2.3.8 tools_4.3.3 raster_3.6-26 parallel_4.3.3 dplyr_1.1.4 base64url_1.4
[31] nngeo_0.4.7 globals_0.16.3 exactextractr_0.10.0 vctrs_0.6.5 R6_2.5.1 proxy_0.4-27
[37] lifecycle_1.0.4 classInt_0.4-10 furrr_0.3.1 pkgconfig_2.0.3 callr_3.7.6 terra_1.7-71
[43] pillar_1.9.0 data.table_1.15.4 glue_1.7.0 Rcpp_1.0.12 xfun_0.43 tibble_3.2.1
[49] tidyselect_1.2.1 rstudioapi_0.16.0 knitr_1.46 igraph_2.0.3 compiler_4.3.3 sp_2.1-3

sf::sf_extSoftVersion()
GEOS GDAL proj.4 GDAL_with_GEOS USE_PROJ_H PROJ
"3.11.2" "3.8.2" "9.3.1" "true" "true" "9.3.1"

This is rather issue with input data or GEOS than sf.

library("geos")
polys = sf::read_sf("example.geojson")
v = as_geos_geometry(polys)
geos_is_valid(v)
#> [1] TRUE TRUE
geos_overlaps(v[1], v[2])
#> Error in geos_overlaps(v[1], v[2]) : 
#>   [1] TopologyException: side location conflict at 210668.20566749386 554110.83121316193.
#>   This can occur if the input geometry is invalid.

It seems that if we use buffer with a very small value, it also works ok.

Setting precision helps in such cases:

library(sf)
# Linking to GEOS 3.12.1, GDAL 3.8.4, PROJ 9.3.1; sf_use_s2() is TRUE
polys = st_read("example.geojson") |> st_set_precision(1e8)
# Reading layer `example' from data source `/home/edzer/Downloads/example.geojson' using driver `GeoJSON'
# Simple feature collection with 2 features and 0 fields
# Geometry type: POLYGON
# Dimension:     XY
# Bounding box:  xmin: 210659 ymin: 554065.2 xmax: 210747.8 ymax: 554155.8
# Projected CRS: OSGB36 / British National Grid
st_overlaps(polys)
# Sparse geometry binary predicate list of length 2, where the predicate
# was `overlaps'
#  1: (empty)
#  2: (empty)

@edzer, do you think it would be reasonable to modify the error message in GEOS to suggest setting the precision? Currently the message indicates that the data may be invalid, even though, as Malcolm pointed out, st_is_valid() returns that it is correct.

@kadyb I don't know - I don't see where exactly the problem is, or occurs, and whether setting precision will always help.