[GIS] Unique SpatialPolygons object with multiple polygons slots in R

holespolygonr

I'm trying to create an interactive Shiny application based off of this example provided by user G. Cocca. In this example, you click on a polygon and a second window zooms you into that polygon with additional administrative units. The example, however, utilizes cleaned and "perfect" polygons from the maptools package, and I am having trouble trying to finagle with my imperfect data to fit the example.

Without getting too bogged down in the details, I am having problems applying the Shiny example to my own data because of the structure of my shapefiles/polygons. It is imperative that I utilize a specific set of shapefiles, so unfortunately I can't dig around for already-cleaned data. Here is one of my example shapefiles, for reproducability. I read this into R via readOGR() from rgdal.

Here is a snippet of code from the example and an image of the resultant mapStates_sp object:

library(maptools)
mapStates <- map("state", fill = TRUE, plot = FALSE)
mapStates_sp <- map2SpatialPolygons(mapStates, IDs = mapStates$names)

enter image description here

In the linked Shiny example, the polygons are loaded in and converted as a Formal class SpatialPolygons. The first @polygons slot states that there are 63 objects with @ polygons:List of 63. Each of those 63 polygons has its own @ Polygons:List of 1 denotation. This makes perfect sense to me. The SpatialPolygon layer has 63 objects, each of which has one single polygon with its own ID, etc.

When I load in my own shapefile, which has already been cleaned and dissolved, I get the following:

library(rgdal)
countries <- readOGR("D:/LandScan", layer = "cleaned", 
                stringsAsFactors = F)
countries_sp <- SpatialPolygons(countries@polygons)

enter image description here

As you can see, the first @ polygons slot is structured the same way: @ polygons :List of 24. 24 polygons for 24 different attributes, this is correct. What's confusing to me are the following @ Polygons slots, the first of which is picture above with @ Polygons :List of 9. (Each @polygons has its own @Polygons: List of x denotation.)

What is creating all of these extra polygons? I've already dissolved my features and attempted to clean them. I see that some of the slots state @ hole : logi TRUE. My polygons are country boundaries, so some of them include islands, archipelagos, lakes, etc. That's just part of their geometries. Is there any way that I can restructure my polygons so that each of my 24 features has only one @Polygons slot? This question/answer seems to be the same issue, but this person created their own DF, whereas mine is already housed in a shapefile, so I'm not sure that it applies.

Best Answer

You have a SpatialPolygonsDataFrame with 24 features. Note carefully the use of upper case Polygons and lower case polygons in the following, as well as the use of what are slots and what are classes:

The geometries are stored in the @polygons slot, which is a list of length 24, one for each feature, each containing one object of class Polygons.

An object of class Polygons has a slot, @Polygons that stores a list of the rings and islands and holes that make up the geometry.

> str(countries@polygons[[1]]@Polygons,2)
List of 9
 $ :Formal class 'Polygon' [package "sp"] with 5 slots
 [8 more]

Your first feature has 9 Polygon objects in its @Polygons slot because it is made up of 9 rings. There's no way you can make this into 1 ring without losing geometry, and if your feature is made up of two similar sized land masses, you are going to lose one of them. You can't have two disconnected rings in a single Polygon object, which means if your feature has two disconnected land masses then you have to have 2 Polygon objects in your @Polygons list for that feature.