Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

st_intersection: found non-noded intersection between LINESTRING #1549

Closed
jepol77 opened this issue Dec 7, 2020 · 8 comments
Closed

st_intersection: found non-noded intersection between LINESTRING #1549

jepol77 opened this issue Dec 7, 2020 · 8 comments

Comments

@jepol77
Copy link

jepol77 commented Dec 7, 2020

There seems to be an issue with st_intersection that I can not solve with the usual methods.

download polygons from here: https://github.com/jepol77/test/blob/main/invalid_polygons.rds
bbx <- readRDS(".../invalid_polygons.rds")
bbx <- bbx %>% st_set_precision(1e5) %>% st_make_valid()
i <- st_intersection(bbx)

I get this error: Fejl i CPL_nary_intersection(x) :
Evaluation error: TopologyException: found non-noded intersection between LINESTRING (497314 6.31343e+06, 497314 6.31343e+06) and LINESTRING (497314 6.31343e+06, 497314 6.31343e+06) at 497313.60609830072 6313426.1116788359.

I know there has been some recent work on this in PostGIS; any news when that is gonna trickle down to R?

@rsbivand
Copy link
Member

rsbivand commented Dec 7, 2020

Please see #794 and the extensive discussion there. You are attempting n-ary intersection, which recurses, intersecting intersection products. The input geometries are valid, but some intersection product ceases to be valid. Using GEOS-devel with OverlayNG does not help, although different invalid intermediate outputs are found. Further, your input objects, while being valid polygons, are actually:

image

@jepol77
Copy link
Author

jepol77 commented Dec 7, 2020

Could you put it in a for loop somehow, or would that make it very slow?

@rsbivand
Copy link
Member

rsbivand commented Dec 7, 2020

Not only very slow, but also using very much memory, apparently. N-ary intersection is not provided by JTS or GEOS; sf added it as a speculation, but because it grosses up imprecision as you reach greater depths of overlaps, it is not as such covered by the available computational geometry models. rgeos does not permit it. The depth seems to be up to 14 iterations, but I maxed out 16GB on the fifth with recusing binary st_intersection()s. Slicing out the categories as separate objects might help, but the number of possible combinations of n=34 is still very large (points in the surface intersecting 0, 1, combinations of 2, ... ) and so on. Maybe sampling with a very dense grid?

@rsbivand
Copy link
Member

rsbivand commented Dec 7, 2020

This gives 215 distinct areas:

bbx <- readRDS("all.rds")
library(sf)
bbxo <- st_union(bbx)
grd <- st_sample(bbxo, size=100000, type="regular")
grd_sp <- as(grd, "Spatial")
library(sp)
gridded(grd_sp) <- TRUE
grd_SP <- as(grd_sp, "SpatialPolygons")
grd_sf_p <- st_as_sf(grd_SP)
ovs <- st_intersects(grd_sf_p, st_geometry(bbx), sparse=FALSE)
codes <- apply(ovs, 1, function(x) {paste(sapply(x, ifelse, "1", "0"), collapse="")})
grdd_sf_p <- st_as_sf(grd_sf_p)
grdd_sf_p$codes <- codes
bbx_i <- aggregate(grdd_sf_p, list(grdd_sf_p$codes), head, 1)
bbx_i$fcodes <- factor(bbx_i$codes)
levels(bbx_i$fcodes)
dim(bbx_i) # [1] 215   4
i <- st_intersection(bbx, bbx_i[,"fcodes"])
dim(i) # [1] 417   3

Since the grid cells are about 1m^2, the intersection output less than 1 could perhaps be discarded.This is with about 100000 points, 1 million might also be feasible, but I feel that this is as good as you'll get.

edzer added a commit that referenced this issue Dec 7, 2020
this turns of the GEOS error+warning mechanisms, and drops
geometries that cause trouble.
* addresses #794
* motivated by #1549
@edzer
Copy link
Member

edzer commented Dec 7, 2020

This branch gives us

library(sf)
# Linking to GEOS 3.8.1, GDAL 3.1.3, PROJ 7.1.1
bbx <- readRDS("invalid_polygons.rds")
bbx <- bbx %>% st_set_precision(1e5) %>% st_make_valid()
(i <- st_intersection(bbx))
# Simple feature collection with 212 features and 3 fields
# geometry type:  GEOMETRY
# dimension:      XY
# bbox:           xmin: 495762 ymin: 6311742 xmax: 497599.9 ymax: 6314854
# projected CRS:  ETRS89 / UTM zone 32N
# First 10 features:
#     no_pnts n.overlaps origins                       geometry
# 1        82          1       1 POLYGON ((496433.2 6312980,...
# 2        82          1       2 MULTIPOLYGON (((497346 6314...
# 3        74          1       3 MULTIPOLYGON (((497260.1 63...
# 2.1      82          2    2, 4 POLYGON ((497297.5 6313184,...
# 4        85          1       4 MULTIPOLYGON (((497325.1 63...
# 2.2      82          3 2, 4, 5 POLYGON ((497295.3 6313180,...
# 4.1      85          2    4, 5 POLYGON ((497299.3 6313214,...
# 2.3      82          2    2, 5 MULTIPOLYGON (((497308 6313...
# 5        76          1       5 MULTIPOLYGON (((497281.9 63...
# 4.2      85          2    4, 6 MULTIPOLYGON (((497314.4 63...

basically by switching off GEOS error reporting and ignoring geometries causing trouble.

@edzer
Copy link
Member

edzer commented Dec 7, 2020

I'm still trying to count, and report, the amount of troubling geometries...

@rsbivand
Copy link
Member

rsbivand commented Dec 8, 2020

The nary branch and the grid give very similar output, with some missing combinations both ways (6.512942 [m^2] in nary intersection of 109888.1 [m^2], 28.57107 [m^2] in gridded binary intersection of 93167.42 [m^2]). I needed to aggregate my binary intersection as well, to combine separated geometries.

@edzer
Copy link
Member

edzer commented Jan 2, 2021

I merged the nary branch: better to return something than nothing with an error message.

@edzer edzer closed this as completed Jan 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants