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

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 > 
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(.)) 
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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.