Sf: st_overlaps output differs from sp::over() and not sure why

Created on 23 Jan 2019  路  5Comments  路  Source: r-spatial/sf

Hello, I'm wondering if there is something I am not understanding about the usage of st_overlaps()

I have two Polygons, one which lies within another (in my case a building lying on a property)
image

My expectation is that when I do st_overlaps(building, property) that it would return the index of the property where this overlap occurs, however it returns (empty) in the returned sparse matrix.

However if I use sp::over(as_Spatial(building), as_Spatial(property), returnList = T), it indeed returns the index of the property as I would expect.

Is there something I'm missing in the usage of st_overlaps()? Any help is much appreciated!

Most helpful comment

No problem @tblazina - It is just easier to help somebody when there is an reproducible example.
I think that st_overlaps() is not the function you are looking for. Read its description at https://postgis.net/docs/ST_Overlaps.html:

Returns TRUE if the Geometries "spatially overlap". By that we mean they intersect, but one does not completely contain another.

In your case one polygon is completely inside another one.
You probably should use a different function, e.g., st_contains(), st_covers(), st_within()...

library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.3.2, PROJ 4.9.3
pol  <- st_polygon(list(cbind(c(9.058248,9.058251,9.058294,9.058291,9.058248),c(47.05717,47.05719,47.05719,47.05717,47.05717))))
pol2 <- st_polygon(list(cbind(c(9.058247,9.058234,9.058269,9.058509,9.058518, 9.058527, 9.058536, 9.058544, 9.058534, 9.058247),c(47.05716,47.05716,47.05738,47.05736,47.05736, 47.05736, 47.05735, 47.05735, 47.05714,  47.05716))))
plot(pol2, col = "green")
plot(pol, col = "red", add = TRUE)

st_overlaps(pol, pol2)
#> Sparse geometry binary predicate list of length 1, where the predicate was `overlaps'
#>  1: (empty)

st_contains(pol2, pol)
#> Sparse geometry binary predicate list of length 1, where the predicate was `contains'
#>  1: 1
st_covers(pol2, pol)
#> Sparse geometry binary predicate list of length 1, where the predicate was `covers'
#>  1: 1
st_within(pol, pol2)
#> Sparse geometry binary predicate list of length 1, where the predicate was `within'
#>  1: 1

Created on 2019-01-24 by the reprex package (v0.2.1)

All 5 comments

@tblazina Could you prepare a reproducible example?

Note that overlaps is asymmetric, you may want to try reverse arguments.

@Nowosad Sorry about that!

pol  <- st_polygon(list(cbind(c(9.058248,9.058251,9.058294,9.058291,9.058248),c(47.05717,47.05719,47.05719,47.05717,47.05717))))
pol2 <- st_polygon(list(cbind(c(9.058247,9.058234,9.058269,9.058509,9.058518, 9.058527, 9.058536, 9.058544, 9.058534, 9.058247),c(47.05716,47.05716,47.05738,47.05736,47.05736, 47.05736, 47.05735, 47.05735, 47.05714,  47.05716))))
st_overlaps(pol, pol2)

Reversing the arguments as @edzer suggested does not seem to change anything. Also if I set a CRS
st_overlaps(st_sfc(pol, crs="+proj=longlat +datum=WGS84 +no_defs"), st_sfc(pol2, crs="+proj=longlat +datum=WGS84 +no_defs")) it does have any effect, but then does throw the warning about the assumption of being planar.

No problem @tblazina - It is just easier to help somebody when there is an reproducible example.
I think that st_overlaps() is not the function you are looking for. Read its description at https://postgis.net/docs/ST_Overlaps.html:

Returns TRUE if the Geometries "spatially overlap". By that we mean they intersect, but one does not completely contain another.

In your case one polygon is completely inside another one.
You probably should use a different function, e.g., st_contains(), st_covers(), st_within()...

library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.3.2, PROJ 4.9.3
pol  <- st_polygon(list(cbind(c(9.058248,9.058251,9.058294,9.058291,9.058248),c(47.05717,47.05719,47.05719,47.05717,47.05717))))
pol2 <- st_polygon(list(cbind(c(9.058247,9.058234,9.058269,9.058509,9.058518, 9.058527, 9.058536, 9.058544, 9.058534, 9.058247),c(47.05716,47.05716,47.05738,47.05736,47.05736, 47.05736, 47.05735, 47.05735, 47.05714,  47.05716))))
plot(pol2, col = "green")
plot(pol, col = "red", add = TRUE)

st_overlaps(pol, pol2)
#> Sparse geometry binary predicate list of length 1, where the predicate was `overlaps'
#>  1: (empty)

st_contains(pol2, pol)
#> Sparse geometry binary predicate list of length 1, where the predicate was `contains'
#>  1: 1
st_covers(pol2, pol)
#> Sparse geometry binary predicate list of length 1, where the predicate was `covers'
#>  1: 1
st_within(pol, pol2)
#> Sparse geometry binary predicate list of length 1, where the predicate was `within'
#>  1: 1

Created on 2019-01-24 by the reprex package (v0.2.1)

Thanks @Nowosad! You are correct, I was incorrectly assuming a similar functionality of sp::over and sf::st_overlaps. Thanks much for the help and I'll be sure to look at the PostGIS documentation to find the function that fits what I need.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

faridcher picture faridcher  路  4Comments

jmsigner picture jmsigner  路  4Comments

kendonB picture kendonB  路  4Comments

kendonB picture kendonB  路  4Comments

kendonB picture kendonB  路  3Comments