4

Background

I'm interested in simplifying polygons with use of the gSimplify function available through the rgeos package.

Reproducible example

A reproducible example can be generated with use of the code below:

# Data sourcing -----------------------------------------------------------

# Download an read US state shapefiles
tmp_shps <- tempfile()
tmp_dir <- tempdir()
download.file(
    "http://www2.census.gov/geo/tiger/GENZ2014/shp/cb_2014_us_state_20m.zip",
    tmp_shps
)
unzip(tmp_shps, exdir = tmp_dir)

# Libs
require(rgdal)
require(rgeos)

# Read
us_shps <- readOGR(dsn = tmp_dir, layer = "cb_2014_us_state_20m")

# Simplified --------------------------------------------------------------

# Simplifiy
us_shps_smpl <- gSimplify(spgeom = us_shps,
                          tol = 200,
                          topologyPreserve = TRUE)

Preview

par(mfrow = c(2,1))
plot(us_shps_smpl, main = "Simplified")
plot(us_shps, main = "Original")

Simplified and original polygons

Problem

In addittion to simplifying polygons the gSimplify function changed classes of the resulting object:

>> class(us_shps)
[1] "SpatialPolygonsDataFrame"
attr(,"package")
[1] "sp"
>> class(us_shps_smpl)
[1] "SpatialPolygons"
attr(,"package")
[1] "sp"

>> names(us_shps)
[1] "STATEFP"  "STATENS"  "AFFGEOID" "GEOID"    "STUSPS"   "NAME"     "LSAD"     "ALAND"    "AWATER"  
>> names(us_shps_smpl)
 [1] "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15" "16" "17" "18" "19"
[21] "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" "31" "32" "33" "34" "35" "36" "37" "38" "39"
[41] "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" "50" "51"

Questions

  • How can I safely reattached the data that was initially available in the original object and transform the resulting SpatialPolygons object to a SpatialPolygonsDataFrame

  • I reckon that one approach would simply involve attaching data frame;but this depends on the order of elements not changing. Are there any other better approaches (ideally preserving initial object class)?

Konrad
  • 17,740
  • 16
  • 106
  • 167
  • https://gis.stackexchange.com/ they can help you for surely – Andre Elrico Sep 05 '17 at 14:24
  • @AndreElrico I post on [gis](https://gis.stackexchange.com/) periodically but to my mind this question is more concerned with how the the `gSimplify` handles `SpatialPolygonDataFrame` class, less with quantitative geography aspect of the problem. I reckon it's not a clear cut but I presume that a lot of people who follow [tag:rgeos] and [tag:gis] look at both boards. – Konrad Sep 05 '17 at 14:27
  • 1
    just wanted to make sure you're aware of that site :-) – Andre Elrico Sep 05 '17 at 14:28
  • Yes, you can reattach the data using `SpatialPolygonsDataFrame(us_shps_smpl, us_shps@data)`. Do you have any example where the order of elements changed after `gSimplify`? – Z.Lin Sep 05 '17 at 14:34
  • 1
    Answere [here](https://stackoverflow.com/a/34827535/8449629) may be of relevance. – Z.Lin Sep 05 '17 at 14:34
  • @Z.Lin No, I don't and I didn't presume that it changes. I was hoping that someone here will confirm that it does not change, which seems to be the case. – Konrad Sep 05 '17 at 14:35
  • @Z.Lin Worth adding, in my production code the should have `SpatialPolygonsDataFrame` `match.ID = FALSE` argument to avoid failing on mismatched IDs. – Konrad Sep 05 '17 at 15:07
  • 1
    Are you wedded to `rgeos`? Otherwise, I believe `sf::st_simplify()` could help you out here. – coletl Oct 09 '17 at 08:55
  • @coletl Thanks, happy to consider other packages. Feel free to make it an answer. – Konrad Oct 09 '17 at 08:57

1 Answers1

4

The sf package is based entirely on data frames, so its geometry manipulations always preserve the data attached to each feature. The package hasn't caught up with all the standard spatial packages in R yet, but it's fairly easy to go back and forth between sf and sp objects when you need more functionality.

Here, st_simplify() does the work, but you'll need to project your polygons first:

library(sf)

# Download and read example data
tmp_shps <- tempfile()
tmp_dir <- tempdir()
download.file(
  "http://www2.census.gov/geo/tiger/GENZ2014/shp/cb_2014_us_state_20m.zip",
  tmp_shps
)
unzip(tmp_shps, exdir = tmp_dir)

us_shps <- st_read(paste(tmp_dir, "cb_2014_us_state_20m.shp", sep = "/"))

# st_simplify needs a projected CRS
us_shps_merc <- st_transform(us_shps, 3857)
simple_us_merc <- st_simplify(us_shps_merc)

# Change back to original CRS
simple_us <- st_transform(simple_us_merc, st_crs(us_shps))

# Change to sp object, if you like
simple_us_sp <- as(st_zm(simple_us), "Spatial")
coletl
  • 803
  • 5
  • 17
  • i found that if st_simplify drops some polygons, the geometry column will become an empty list in those rows ("list()"). those "empty geometry" rows will have to be removed before as(.,"Spatial") is applied or an error appears – Richard DiSalvo Mar 27 '19 at 02:41