我有一个数据框,其中有3k +个数据点分布在整个墨西哥湾北部(在这里我仅提供6个)。我正在尝试为到海岸的距离(km)创建一个新变量。我有一个要使用的形状文件(gulf.shape
),但不清楚如何使用。
这是一些数据
require(maptools)
require(sp)
library(rgdal)
library(lubridate)
df <- data.frame(Lat = c(26.84853, 28.38329, 28.00364,
29.53840, 29.32030, 26.81622, 25.28146),
Lon = c(-96.55716, -94.29307, -91.21581,
-88.42556, -84.20031, -83.89737, -82.95665))
然后我加载shapefile(提供here)。
gulf.shape <- "Shape\\stateshigh.shp"
gulf.shape <- maptools::readShapePoly(gulf.shape)
和快速绘图以可视化我所拥有的东西。
plot(df$Lon, df$Lat,
xlim = c(-97.5, -80.7), ylim = c(25, 30.5),
xlab ="Latitude", ylab = "Longitude",
pch = 20, col="red", cex=1.5)
par(new=T)
sp::plot(gulf.shape, add= T,
xlim = c(-97.5, -80.7), ylim = c(25, 30.5),
xlab ="Latitude", ylab = "Longitude",
col = "gray")
我发现了一个堆栈溢出帖子(here),使我可以使用下面的代码得到答案。他们使用的形状文件可用here。
require(rgdal) # for readOGR(...); loads package sp as well
require(rgeos) # for gDistance(...)
require(parallel) # for detect cores
require(foreach) # for foreach(...)
require(snow) # for makeCluster(...)
require(doSNOW) # for resisterDoSNOW(...)
wgs.84 <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
mollweide <- "+proj=moll +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
sp.points <- SpatialPoints(df[,c("Lon","Lat")], proj4string=CRS(wgs.84))
coast <- rgdal::readOGR(dsn=".",layer="ne_10m_coastline",p4s=wgs.84);str(coast)
coast.moll <- spTransform(coast,CRS(mollweide))
point.moll <- spTransform(sp.points,CRS(mollweide))
no_cores <- detectCores()
cl <- makeCluster(no_cores,type="SOCK") # create a 4-processor cluster
registerDoSNOW(cl) # register the cluster
get.dist.parallel <- function(n) {
foreach(i=1:n, .combine=c, .packages="rgeos", .inorder=TRUE,
.export=c("point.moll","coast.moll")) %dopar% gDistance(point.moll[i],coast.moll)
}
df$Dis.to.SHORE <- get.dist.parallel(length(sp.points))
df$Dis.to.SHORE <- df$Dis.to.SHORE/1000
df
plot(coast)
points(sp.points,pch=20,col="red")
但是,我不了解wgs.84
和mollweide
中使用的CRS代码,这使我对使用此代码生成的数据感到不安。我还想只使用gulf.shape
文件而不是整个世界,因为在前面提到的堆栈溢出帖子中有一些建议,那就是更好。
所以我的问题是:
我获得的到岸的距离的值是否相当准确(即5-10m以内)?
如何修改代码以利用gulf.shape
文件而不是整个世界?
任何人都可以解释CRS
代码或为我提供良好的参考吗?
请注意,由于我实际上有6个以上的数据点,因此我使用并行计算来加快处理速度。
答案 0 :(得分:1)
我将尽力回答您的第三个问题。 CRS(坐标参考系)在映射中非常重要,因为它定义了点的坐标系。这是一个有用的概述。 https://www.nceas.ucsb.edu/~frazier/RSpatialGuides/OverviewCoordinateReferenceSystems.pdf
对于您的特定情况,当您更改为其他shapefile时,您需要(1)找出针对shapefile(gulf.shape)的CRS。通常,它在shapefile随附的.prj文件或元数据中。 (2)选择适合您目标的CRS。您正在计算距离,因此等距投影可能对您最有帮助。 (3)在计算距离之前将原始crs转换为目标crs。 您引用的代码也正在执行此操作。世界shapefile带有wgs84 crs;选择的目标crs是mollweide;并使用spTransform()函数将wgs84转换为mollweide。
在另一个问题上,与您的第一个问题有关,计算的准确性与您使用的crs有关,但也与shapefile的大小和点的精度(经/纬度)有关。