admin管理员组

文章数量:1122846

I'm working with spatial data in R using the sf package, and I need to identify geometries that are completely within a larger geometry (not just intersecting or touching boundaries).

In other words, I need the red square (which has a hollow center) to merge with the purple, while leaving the blue unaffected.

Does anyone know how to do this?

Here is an data example:


# Geometry 1 (geom1) is a polygon with a hole (an outer boundary and an inner "empty" ring).
# Geometry 2 (geom2) is a simple polygon that aligns perfectly with the inner boundary of geom1 (it is completely inside the "hole").
# Geometry 3 (geom3) is a separate polygon that intersects the boundary of geom1 but is not fully contained by it.

library(sf)

# Create geometry 1 as a polygon with a hole
geom1 <- st_polygon(list(
  rbind(c(0, 0), c(0, 5), c(5, 5), c(5, 0), c(0, 0)),           # Outer boundary
  rbind(c(1, 1), c(1, 4), c(4, 4), c(4, 1), c(1, 1))            # Inner "hole"
))

# Create geometry 2 as a simple polygon
geom2 <- st_polygon(list(
  rbind(c(1, 1), c(1, 4), c(4, 4), c(4, 1), c(1, 1))            # Polygon inside the hole
))

# Create geometry 3 as a separate polygon
geom3 <- st_polygon(list(
  rbind(c(5, 5), c(5, 9), c(9, 9), c(9, 5), c(5, 5))            # Polygon outside geom1
))

# Combine geometries into a simple feature collection
sf_data <- st_sf(geometry = st_sfc(geom1, geom2, geom3))

Note that st_intersects returns both geometry 2 (internal) and geometry 3. In this case, it would be necessary to return only geometry 2. st_contains also not work since geometry 1 has a blank space.

I was expecting to find a method to identify geometries that are fully within the outer boundary of another geometry.

I'm working with spatial data in R using the sf package, and I need to identify geometries that are completely within a larger geometry (not just intersecting or touching boundaries).

In other words, I need the red square (which has a hollow center) to merge with the purple, while leaving the blue unaffected.

Does anyone know how to do this?

Here is an data example:


# Geometry 1 (geom1) is a polygon with a hole (an outer boundary and an inner "empty" ring).
# Geometry 2 (geom2) is a simple polygon that aligns perfectly with the inner boundary of geom1 (it is completely inside the "hole").
# Geometry 3 (geom3) is a separate polygon that intersects the boundary of geom1 but is not fully contained by it.

library(sf)

# Create geometry 1 as a polygon with a hole
geom1 <- st_polygon(list(
  rbind(c(0, 0), c(0, 5), c(5, 5), c(5, 0), c(0, 0)),           # Outer boundary
  rbind(c(1, 1), c(1, 4), c(4, 4), c(4, 1), c(1, 1))            # Inner "hole"
))

# Create geometry 2 as a simple polygon
geom2 <- st_polygon(list(
  rbind(c(1, 1), c(1, 4), c(4, 4), c(4, 1), c(1, 1))            # Polygon inside the hole
))

# Create geometry 3 as a separate polygon
geom3 <- st_polygon(list(
  rbind(c(5, 5), c(5, 9), c(9, 9), c(9, 5), c(5, 5))            # Polygon outside geom1
))

# Combine geometries into a simple feature collection
sf_data <- st_sf(geometry = st_sfc(geom1, geom2, geom3))

Note that st_intersects returns both geometry 2 (internal) and geometry 3. In this case, it would be necessary to return only geometry 2. st_contains also not work since geometry 1 has a blank space.

I was expecting to find a method to identify geometries that are fully within the outer boundary of another geometry.

Share Improve this question asked yesterday Pedro AlvesPedro Alves 31 silver badge1 bronze badge New contributor Pedro Alves is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 1
  • 1 What do you mean by excluding those touching boundaries? If the top right corner of the purple square was the same as the top right corner of the red square but the others were unchanged would you want to merge them? – SamR Commented yesterday
Add a comment  | 

1 Answer 1

Reset to default 2

Included example suggests that you could drop holes and operate with exterior rings to check what gets covered (by what).
With sfheaders::sf_remove_holes():

library(sf)

(exterior_rings <- sfheaders::sf_remove_holes(sf_data))
#> Simple feature collection with 3 features and 0 fields
#> Geometry type: POLYGON
#> Dimension:     XY
#> Bounding box:  xmin: 0 ymin: 0 xmax: 9 ymax: 9
#> CRS:           NA
#>                         geometry
#> 1 POLYGON ((0 0, 0 5, 5 5, 5 ...
#> 2 POLYGON ((1 1, 1 4, 4 4, 4 ...
#> 3 POLYGON ((5 5, 5 9, 9 9, 9 ...

st_covered_by(exterior_rings)
#> Sparse geometry binary predicate list of length 3, where the predicate
#> was `covered_by'
#>  1: 1
#>  2: 1, 2
#>  3: 3

which(lengths(st_covered_by(exterior_rings)) > 1)
#> [1] 2

本文标签: rHow to identify intersections of hollow geometries while ignoring othersStack Overflow