16

I have such object:

> p_mb
Simple feature collection with 52 features and 0 fields (with 9 geometries empty)
geometry type:  GEOMETRY
dimension:      XY
bbox:           xmin: 585001.4 ymin: 211001.9 xmax: 609998.1 ymax: 236998.6
epsg (SRID):    NA
proj4string:    NA
First 10 features:
                         geometry
1  POLYGON ((591051.4 211855, ...
2                   POLYGON EMPTY
3  POLYGON ((588206.4 212570, ...
4  MULTIPOLYGON (((585004.6 21...
5  POLYGON ((600614.5 216112.9...
6  POLYGON ((603033.8 215125.2...
7  MULTIPOLYGON (((608168.4 21...
8  POLYGON ((600009.4 212984, ...
9  POLYGON ((603203.4 217336, ...
10 POLYGON ((585519.4 217546, ...

obtained from negative buffering other sf object. My question is simple, how to delete those empty slots to not get error and warnings:

> p_pol <- sf::st_cast(p_mb0, "POLYGON")
There were 23 warnings (use warnings() to see them)
> warnings()
1: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
2: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
3: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
4: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
5: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
6: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
7: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
8: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
9: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
10: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
11: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
12: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
13: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
14: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
15: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
16: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
17: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
18: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
19: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
20: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
21: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
22: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
23: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only

> spl_mbuf <- as(p_pol, "Spatial")
Error: length(srl) > 0 is not TRUE

I think I can skip those warnings.


Found workaround: just used p_uni <- sf::st_union(p_mb) after buffer, but this is only emergency exit.

3 Answers 3

20

Building off of the answer by @Spacedman, you can filter out empty geometries using st_is_empty with a tidyverse approach

dne <- d %>% filter(!st_is_empty(.))
19

My first guess was to use st_area and select for those with area greater than zero. But I looked at the docs and found st_is_empty. For example here's some constructed test data:

> p = st_point(c(1,1))
> pv = st_sfc(p,p,p,p,p)
> bv = st_buffer(pv, c(1,1,0,-1,2))
> d = st_sf(bv)
> d$ID=1:5

Which has two empty polygons:

> d
Simple feature collection with 5 features and 1 field (with 2 geometries empty)
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -1 ymin: -1 xmax: 3 ymax: 3
epsg (SRID):    NA
proj4string:    NA
                              bv ID
1 POLYGON ((2 1, 1.99863 0.94...  1
2 POLYGON ((2 1, 1.99863 0.94...  2
3                  POLYGON EMPTY  3
4                  POLYGON EMPTY  4
5 POLYGON ((3 1, 2.997259 0.8...  5

Get only the non-empty with:

> dne = d[!st_is_empty(d),,drop=FALSE]
> dne
Simple feature collection with 3 features and 1 field
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -1 ymin: -1 xmax: 3 ymax: 3
epsg (SRID):    NA
proj4string:    NA
                              bv ID
1 POLYGON ((2 1, 1.99863 0.94...  1
2 POLYGON ((2 1, 1.99863 0.94...  2
5 POLYGON ((3 1, 2.997259 0.8...  5
> 
4

In the event that st_is_empty() gives you an error of:

Error in CPL_geos_is_empty(st_geometry(x)) : Evaluation error: IllegalArgumentException: point array must contain 0 or >1 elements.

You can use:

dne <- d %>% filter( is.na(st_dimension(.)) == FALSE )

Information on checking for empty geometries can be found here: https://r-spatial.org/r/2017/03/19/invalid.html#empty-geometries

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.