gpt4 book ai didi

r - 海洋纬度经度点距海岸的距离

转载 作者:行者123 更新时间:2023-12-04 11:51:10 25 4
gpt4 key购买 nike

我开始了一个“免费”的开源项目,为地球海洋的 pH 值创建一个新的数据集。

我从 NOAA 的开放数据集开始,用这些列创建了一个 245 万行的数据集:

colnames(NOAA_NODC_OSD_SUR_pH_7to9)
[1] "Year" "Month" "Day" "Hour" "Lat" "Long" "Depth" "pH"

方法文档 HERE .

数据集 HERE .

我现在的目标是“限定”每一行(2.45m)......为此,我需要计算从纬度/经度的每个点到最近海岸的距离。

所以我正在寻找一种方法
在:纬度/经度
出:距离(离岸公里)

有了这个,我可以确定数据点是否会受到海岸污染的影响,例如附近的城市污水。

我已经在寻找一种方法来做到这一点,但似乎所有人都需要我没有的包/软件。

如果有人愿意提供帮助,我将不胜感激。
或者,如果您知道一种简单(免费)的方法来完成此操作,请告诉我...

我可以从事 R 编程、Shell 脚本方面的工作,但不是这些方面的专家......

最佳答案

所以这里发生了几件事。首先,您的数据集似乎具有 pH 值与深度的关系。因此,虽然有 ~ 2.5MM 行,但只有 ~200,000 行深度 = 0 - 仍然很多。

其次,要获得到最近海岸的距离,您需要一个海岸线的 shapefile。幸运的是,这是可用的 here , 在优秀 Natural Earth website .

第三,你的数据是长/纬度(所以,单位=度),但你想要以公里为单位的距离,所以你需要转换你的数据(上面的海岸线数据也是长/纬度,也需要转换)。转换的一个问题是您的数据显然是全局的,并且任何全局转换都必然是非平面的。所以精度将取决于实际位置。正确的方法是对您的数据进行网格化,然后使用一组适合于您的点所在网格的平面变换。不过,这超出了本问题的范围,因此我们将使用全局变换 (mollweide)只是为了让您了解它是如何在 R 中完成的。

library(rgdal)   # for readOGR(...); loads package sp as well
library(rgeos) # for gDistance(...)

setwd(" < directory with all your files > ")
# WGS84 long/lat
wgs.84 <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
# ESRI:54009 world mollweide projection, units = meters
# see http://www.spatialreference.org/ref/esri/54009/
mollweide <- "+proj=moll +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
df <- read.csv("OSD_All.csv")
sp.points <- SpatialPoints(df[df$Depth==0,c("Long","Lat")], proj4string=CRS(wgs.84))

coast <- readOGR(dsn=".",layer="ne_10m_coastline",p4s=wgs.84)
coast.moll <- spTransform(coast,CRS(mollweide))
point.moll <- spTransform(sp.points,CRS(mollweide))

set.seed(1) # for reproducible example
test <- sample(1:length(sp.points),10) # random sample of ten points
result <- sapply(test,function(i)gDistance(point.moll[i],coast.moll))
result/1000 # distance in km
# [1] 0.2185196 5.7132447 0.5302977 28.3381043 243.5410571 169.8712255 0.4182755 57.1516195 266.0498881 360.6789699

plot(coast)
points(sp.points[test],pch=20,col="red")



所以这会读取您的数据集,提取行 Depth==0 ,并将其转换为 SpatialPoints 对象。然后我们将从上面的链接下载的海岸线数据库读取到 SpatialLines 对象中。然后我们使用 spTransform(...) 将两者都转换为 Mollweide 投影。 ,然后我们使用 gDistance(...)rgeos包来计算每个点和最近海岸之间的最小距离。

同样,重要的是要记住,尽管有小数位,但这些距离只是近似值。

一个非常大的问题是速度:1000 个距离(在我的系统上)这个过程需要大约 2 分钟,所以运行所有 200,000 个距离大约需要 6.7 小时。理论上,一种选择是找到分辨率较低的海岸线数据库。

下面的代码将计算所有 201,000 个距离。
## not run
## estimated run time ~ 7 hours
result <- sapply(1:length(sp.points), function(i)gDistance(sp.points[i],coast))

编辑 :OP 关于内核的评论让我想到这可能是一个例子,其中并行化的改进可能值得付出努力。所以这里是你将如何使用并行处理运行它(在 Windows 上)。
library(foreach)   # for foreach(...)
library(snow) # for makeCluster(...)
library(doSNOW) # for resisterDoSNOW(...)

cl <- makeCluster(4,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)
}
get.dist.seq <- function(n) sapply(1:n,function(i)gDistance(point.moll[i],coast.moll))

identical(get.dist.seq(10),get.dist.parallel(10)) # same result?
# [1] TRUE
library(microbenchmark) # run "benchmark"
microbenchmark(get.dist.seq(1000),get.dist.parallel(1000),times=1)
# Unit: seconds
# expr min lq mean median uq max neval
# get.dist.seq(1000) 140.19895 140.19895 140.19895 140.19895 140.19895 140.19895 1
# get.dist.parallel(1000) 50.71218 50.71218 50.71218 50.71218 50.71218 50.71218 1

使用 4 个内核可将处理速度提高约 3 倍。因此,由于 1000 次距离大约需要一分钟,因此 100,000 次距离应该不到 2 小时。

请注意,使用 times=1是对 microbenchmark(...)的滥用真的,因为重点是多次运行该过程并平均结果,但我只是没有耐心。

关于r - 海洋纬度经度点距海岸的距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27697504/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com