Search code examples
rextractpolygonareashapefile

Counting polygons in shapefile


So I have multiple species ranges which look like the following (colored blue for example) This one runs east to west across Africa:

Example species range

I can get the total area by using gArea in the rgeos package. What I want to know is how many individual polygons make up this file - i.e. how many distinct regions are there to the total range (this could be islands, or just separated populations) and what the ranges of those polygons are. I have been using the following code:

#Load example shapefile
shp <- readShapeSpatial("species1.shp")

#How many polygon slots are there?
length(shp@polygons)

>2

#How many polygons are in each slot
length(shp@polygons[[1]]@Polygons
length(shp@polygons[[2]]@Polygons

and to get the area of a particular one:

shp@polygons[[1]]@Polygons[[1]]@area

Is this correct? I'm worried that a lake in the middle of the range might constitute a polygon on its own? I want to end up with a list that is roughly like:

           Species A    Species B
Polygon 1      12          11
Polygon 2      13          10
Polygon 2      14          NA

If I wanted to compile a list for every species of how many polygons and their individual ranges would be pretty straightforward to pass to a loop if the above code is correct.

Thanks


Solution

  • This is a very un-glamorous solution, but it gets the job done at the moment.

    for(i in 1:length(shpfiles)){
    
    shp <- shpfiles[[i]]
    
    #1) Create master list of all polygon files within a shapefile
    
    #How many lists of polygons are there within the shpfile
    num.polygon.lists <- length(shp@polygons)
    
    
    #Get all polygon files
    master <- vector(mode="list")
    for(i in 1:num.polygon.lists){
    m <- shp@polygons[[i]]@Polygons
    
    master[[i]] <- m
    }
    
    #Combine polygon files into a single list
    len <- length(master)
    
    if(len > 1) {
    
    root <- master[[1]]
    for(i in 2:length(master)){
    root <- c(master[[i]], root)}
    
    } else {root <- master[[1]]}
    
    #Rename
    polygon.files <- root
    
    #2) Count number of polygon files that are not holes
    
    #Create a matrix for the total number of polygon slots that are going to be counted
    res <- matrix(NA,ncol=1 , nrow=length(polygon.files))
    
    #Loop through polygons returning whether slot "hole" is TRUE/FALSE
    for(i in 1:length(polygon.files)){
    
    r <- isTRUE(polygon.files[[i]]@hole)
    
    res[[i,1]] <- r
    }
    
    #Count number times "FALSE" appears - means polygon is not a hole
    p.count <- table(res)["FALSE"]
    p.count <- as.numeric(p.count)
    
    print(p.count)
    
    }
    

    It's a start