将空间多边形转换为地图对象

时间:2014-06-02 00:29:32

标签: r maps gis geospatial spatial

我正在尝试将R中的空间多边形对象转换为地图对象。我已经设法使用以前回答的问题,特别是(In R, how can I convert SpatialPolygons* to map objects),但我遇到的问题与这个帖子中的人有同样的问题:我得到奇怪的多边形链接,使地图无法使用。

我已将完整的代码包含在内以供复制。

感谢您的帮助。

library(sp)
library(spdep)
library(maps)
library(rgdal)

## load a file from GADM (you just have to specify the countries "special part" of the file name, like "ARG" for Argentina. Optionally you can specify which level you want to have
loadGADM <- function (fileName, level = 0, ...) {
load(url(paste("http://gadm.org/data/rda/", fileName, "_adm", level, ".RData", sep     = "")))
gadm
}

## the maps objects get a prefix (like "ARG_" for Argentina)
changeGADMPrefix <- function (GADM, prefix) {
GADM <- spChFIDs(GADM, paste(prefix, row.names(GADM), sep = "_"))
GADM
}

## load file and change prefix
loadChangePrefix <- function (fileName, level = 0, ...) {
theFile <- loadGADM(fileName, level)
theFile <- changeGADMPrefix(theFile, fileName)
theFile
}

## this function creates a SpatialPolygonsDataFrame that contains all maps you specify in "fileNames".
## E.g.: 
## spdf <- getCountries(c("ARG","BOL","CHL"))
## plot(spdf) # should draw a map with Brasil, Argentina and Chile on it.
getCountries <- function (fileNames, level = 0, ...) {
polygon <- sapply(fileNames, loadChangePrefix, level)
polyMap <- do.call("rbind", polygon)
polyMap
}



indiamap <- getCountries("IND",level=1)

xx <- indiamap
require(reshape)
xx@data$id <- rownames(xx@data)

# Convert to dataframe
xx.df <- as.data.frame(xx)

#Fortfy automagic
require(ggplot2)
xx.fort <- fortify(xx, region="id")

# Join operation - one row per coordinate vector
require(plyr)
xx <- join(xx.fort, xx.df,by="id")

# Split by ID because we need to add NA at end of each set of polygon coordinates to 'break' the line
xxSp <- split(xx, xx$id)

# Need to insert NA at end of each polygon shape to cut off that shape
xxL <- do.call( rbind , (lapply( xxSp , function(x) { j <- x[ nrow(x) , ] ; j[1:2] <- c(NA,NA); rbind( x , j ) })) )


# Create list object with same structure as map object
xxMap <- list( x = xxL$long , y = xxL$lat , range = c( range(xxL$long) , range(xxL$lat) ) , names = as.character(unique( xxL$NAME ) ) )

# Define as a map class object
attr(xxMap , "class") <- "map"

# Plot!!
map( xxMap )

1 个答案:

答案 0 :(得分:1)

问题在于每个id个(省)由多个多边形组成,例如:岛屿。 SpatialPolygonsDataFrame有信息告诉这些单独的多边形是相同的id但不应该通过线连接。转换为map后,该信息就会丢失。在您的解决方法中,您只需在NA之间添加id,而不是在所有单独的多边形之间添加。{/ p>

技巧是为所有单独的棋子生成唯一的ID,因此可以在每个小棋子后添加NA。 xx创建的join包含一个名为piece的字段。对于单个id内的每个多边形,此字段似乎都有一个单独的数字。因此,例如具有id == 4的多边形由3个部分组成,例如3个岛屿。然后可以通过以下方式生成所有多边形的唯一ID:

xx$myid <- xx$ID_1*1000 + as.numeric(xx$piece)

每个省份的ID * 1000加上每件的ID。印度多边形内的最大碎片数为212.完整的代码为:

indiamap <- getCountries("IND",level=1)

xx <- indiamap
require(reshape)
xx@data$id <- rownames(xx@data)

# Convert to dataframe
xx.df <- as.data.frame(xx)
# xx.df$myid = xx$ID1*100 + xx$piece

#Fortfy automagic
require(ggplot2)
xx.fort <- fortify(xx, region="id")

# Join operation - one row per coordinate vector
require(plyr)
xx <- join(xx.fort, xx.df,by="id")
unique(xx$piece)

# generate unique id for each polygon piece
xx$myid <- xx$ID_1*1000 + as.numeric(xx$piece)

# Split by myid because we need to add NA at end of each set of polygon coordinates to 'break' the line
xxSp <- split(xx, xx$myid)

# Need to insert NA at end of each polygon shape to cut off that shape
# xxL <- do.call( rbind , (lapply( xxSp , function(x) { j <- x[ nrow(x) , ] ; j[1:2] <- c(NA,NA); rbind( x , j ) })) )
xxL <- do.call( rbind , (lapply( xxSp , function(x) { j <- x[nrow(x) , ] ; j[1:2] <- c(NA,NA); rbind( x , j ) })) )


# Create list object with same structure as map object
xxMap <- list( x = xxL$long , y = xxL$lat , range = c( range(xxL$long) , range(xxL$lat) ) , names = as.character(unique( xxL$NAME_1 ) ) )

# Define as a map class object
attr(xxMap , "class") <- "map"

map( xxMap , fill=T, col=2)

enter image description here