如何将夏威夷和阿拉斯加添加到R中的空间多边形?

时间:2015-02-09 23:18:26

标签: r maps gis maptools sp

如何将夏威夷和阿拉斯加添加到以下代码中(取自Josh O'Brien的回答:Latitude Longitude Coordinates to State Code in R)?

library(sp)
library(maps)
library(maptools)

# The single argument to this function, pointsDF, is a data.frame in which:
#   - column 1 contains the longitude in degrees (negative in the US)
#   - column 2 contains the latitude in degrees

latlong2state <- function(pointsDF) {
    # Prepare SpatialPolygons object with one SpatialPolygon
    # per state (plus DC, minus HI & AK)
    states <- map('state', fill=TRUE, col="transparent", plot=FALSE)
    IDs <- sapply(strsplit(states$names, ":"), function(x) x[1])
    states_sp <- map2SpatialPolygons(states, IDs=IDs,
                     proj4string=CRS("+proj=longlat +datum=wgs84"))

    # Convert pointsDF to a SpatialPoints object 
    pointsSP <- SpatialPoints(pointsDF, 
                    proj4string=CRS("+proj=longlat +datum=wgs84"))

    # Use 'over' to get _indices_ of the Polygons object containing each point 
    indices <- over(pointsSP, states_sp)

    # Return the state names of the Polygons object containing each point
    stateNames <- sapply(states_sp@polygons, function(x) x@ID)
    stateNames[indices]
}

# Test the function using points in Alaska (ak) and Hawaii (hi)

ak <- data.frame(lon = c(-151.0074), lat = c(63.0694))
hi <- data.frame(lon = c(-157.8583), lat = c(21.30694))
nc <- data.frame(lon = c(-77.335), lat = c(34.671))


latlong2state(ak)
latlong2state(hi)
latlong2state(nc)

latlong2state(ak)latlong2state(hi)代码返回NA,但如果代码修改正确,则会返回Alaska和Hawaii作为结果。

感谢任何帮助!

2 个答案:

答案 0 :(得分:4)

您需要使用具有50个状态的地图,使用states <- map('state', fill=TRUE, col="transparent", plot=FALSE)加载的地图没有夏威夷和阿拉斯加。

例如,您可以从here下载20米美国地图,并将其解压缩到当前目录中。然后,您应该在R当前目录中有一个名为cb_2013_us_state_5m的文件夹。

我已经调整了一些您发布的代码,为夏威夷和Alsaka工作,还没有尝试过其他的代码。

library(sp)
library(rgeos)
library(rgdal)

# The single argument to this function, pointsDF, is a data.frame in which:
#   - column 1 contains the longitude in degrees (negative in the US)
#   - column 2 contains the latitude in degrees

latlong2state <- function(pointsDF) {
  states <-readOGR(dsn='cb_2013_us_state_5m',layer='cb_2013_us_state_5m')
  states <- spTransform(states, CRS("+proj=longlat"))

  pointsSP <- SpatialPoints(pointsDF,proj4string=CRS("+proj=longlat"))

  # Use 'over' to get _indices_ of the Polygons object containing each point 
  indices <- over(pointsSP, states)
  indices$NAME
}

# Test the function using points in Alaska (ak) and Hawaii (hi)

ak <- data.frame(lon = c(-151.0074), lat = c(63.0694))
hi <- data.frame(lon = c(-157.8583), lat = c(21.30694))

latlong2state(ak)
latlong2state(hi)

答案 1 :(得分:2)

这是基于包maps中的数据集,其中只包含较低的48个。对于您的任务,它需要一个包含所有状态的shapefile。 Census.gov网站总是找到这些的好地方。我对你发布的函数进行了一些更改,以便它可以使用这个新的shapefile。

#download a shapefile with ALL states
tmp_dl <- tempfile()
download.file("http://www2.census.gov/geo/tiger/GENZ2013/cb_2013_us_state_20m.zip", tmp_dl)
unzip(tmp_dl, exdir=tempdir())
ST <- readOGR(tempdir(), "cb_2013_us_state_20m")

latlong2state <- function(pointsDF) {
    # Just copied the earlier code with some key changes
    states <- ST

    # Convert pointsDF to a SpatialPoints object 
    # USING THE CRS THAT MATCHES THE SHAPEFILE
    pointsCRS <- "+proj=longlat +datum=NAD83 +no_defs +ellps=GRS80 +towgs84=0,0,0"
    pointsSP <- SpatialPoints(pointsDF, proj4string=CRS(pointsCRS))

    # Use 'over' to get _indices_ of the Polygons object containing each point 
    indices <- over(pointsSP, states)

    # Return the state names of the Polygons object containing each point
    as.vector(indices$NAME)
}

我们来试试吧!

ak <- data.frame(lon = c(-151.0074), lat = c(63.0694))
hi <- data.frame(lon = c(-157.8583), lat = c(21.30694))
nc <- data.frame(lon = c(-77.335), lat = c(34.671))

latlong2state(ak)
[1] "Alaska"

latlong2state(hi)
[1] "Hawaii"

latlong2state(nc)
[1] "North Carolina"