英文:
Converting WSG84 to UTM, rgdal alternatives
问题
我有许多现有的脚本,其中我使用rgdal
包中的project()
函数来将WSG84纬度/经度坐标转换为UTM。rgdal
包在更新后间歇性地给我带来麻烦,经常在更新后停止工作,我通常可以通过将旧版本复制到我的包文件夹中来解决,而不是从CRAN安装新版本。但现在这个方法也不起作用了,因为rgdal
将在2023年退休,所以我正在尝试使用不同的包来进行投影。这就是我遇到问题的地方,因为我不太了解如何将它适应其他包,比如terra
或sf
。
somelocations<-data.frame(id=c('X', 'Y', 'Z'),
Long=c(-156.6274,-156.6457,-156.6676),
Lat=c(20.8081,20.8292,20.8512))
require(rgdal)
rgdal::project(as.matrix(somelocations[,c('Long', 'Lat')]), "+proj=utm +zone=4N ellps=WGS84 +units=m"))
Error in rgdal::project(as.matrix(DASARs[, c("Long", "Lat")]), "+proj=utm +zone=4N ellps=WGS84 +units=m") :
target crs creation failed: Invalid value for an argument
In addition: Warning message:
PROJ support is provided by the sf and terra packages among others
英文:
I have numerous existing scripts in which I used project()
from the rgdal
package to convert WSG84 Latitude/Longitude coordinates into UTM. rgdal
has intermittently been giving me headaches by randomly stopping to work after updates, which I was always able to fix by copying an older version into my package folder instead of installing newer versions from CRAN. This also has stopped working, now, and since rgdal
is going to be retired during 2023, I'm trying to convert my code using a different package for the projection. This is where I'm stuck as I don't quite understand how to adapt it for other packages like terra
or sf
.
somelocations<-data.frame(id=c('X', "Y", "Z"),
Long=c(-156.6274,-156.6457,-156.6676),
Lat=c(20.8081,20.8292,20.8512))
require(rgdal)
rgdal::project(as.matrix(somelocations[,c('Long', 'Lat')]), "+proj=utm +zone=4N ellps=WGS84 +units=m"))
Error in rgdal::project(as.matrix(DASARs[, c("Long", "Lat")]), "+proj=utm +zone=4N ellps=WGS84 +units=m") :
target crs creation failed: Invalid value for an argument
In addition: Warning message:
PROJ support is provided by the sf and terra packages among others
答案1
得分: 3
以下是翻译好的部分:
Here is how you can do that with "terra".
Your example data
somelocations <- data.frame(id=c('X', 'Y', 'Z'),
Long=c(-156.6274,-156.6457,-156.6676),
Lat=c(20.8081,20.8292,20.8512))
The "raw" approach, which is most similar to the one with rgdal:
library(terra)
project(as.matrix(somelocations[,c('Long', 'Lat')]),
"+proj=longlat", "+proj=utm +zone=4 +units=m")
# [,1] [,2]
#[1,] 746948.4 2302727
#[2,] 745008.7 2305036
#[3,] 742693.4 2307439
Or via a SpatVector (which could be useful for other reasons such as data analysis and mapping).
v <- vect(somelocations, geom=c("Long", "Lat"), crs="+proj=longlat")
p <- project(v, "+proj=utm +zone=4 +units=m")
crds(p)
# [,1] [,2]
#[1,] 746948.4 2302727
#[2,] 745008.7 2305036
#[3,] 742693.4 2307439
The reason why you get an error is that your PROJ4 string "+proj=utm +zone=4N") is not valid. You could use "+proj=utm +zone=4 +north"), but adding "+north" is redundant, just like adding "unit=m" as these are the defaults. I would also leave out +ellps=WGS84 or replace it with (the default) +datum=WGS84. (see the documentation)
英文:
Here is how you can do that with "terra".
Your example data
somelocations <- data.frame(id=c('X', "Y", "Z"),
Long=c(-156.6274,-156.6457,-156.6676),
Lat=c(20.8081,20.8292,20.8512))
The "raw" approach, which is most similar to the one with rgdal:
library(terra)
project(as.matrix(somelocations[,c('Long', 'Lat')]),
"+proj=longlat", "+proj=utm +zone=4 +units=m")
# [,1] [,2]
#[1,] 746948.4 2302727
#[2,] 745008.7 2305036
#[3,] 742693.4 2307439
Or via a SpatVector (which could be useful for other reasons such as data analysis and mapping).
v <- vect(somelocations, geom=c("Long", "Lat"), crs="+proj=longlat")
p <- project(v, "+proj=utm +zone=4 +units=m")
crds(p)
# [,1] [,2]
#[1,] 746948.4 2302727
#[2,] 745008.7 2305036
#[3,] 742693.4 2307439
The reason why you get an error is that your PROJ4 string "+proj=utm +zone=4N")
is not valid. You could use "+proj=utm +zone=4 +north")
, but adding "+north" is redundant, just like adding "unit=m" as these are the defaults. I would also leave out +ellps=WGS84
or replace it with (the default) +datum=WGS84
. (see the documentation)
答案2
得分: 2
{rgdal}包目前已经过时,包维护者(后来已经退休)积极推动包的用户考虑其他替代方案。因此,这里提供了一个转换经纬度数据为UTM 4N坐标的代码。
关键部分包括:
- 将常规数据框转换为{sf}数据框;这将为您提供投影的基线(从哪里进行投影?您的原始坐标是以十进制度、米还是英尺为单位的?)
- 对您的sf对象应用
sf::st_transform()
,将其从已知的坐标系转换为所需的格式
我发现使用EPSG代码来指定坐标参考系统最容易,例如4326和32604,而不是像您的代码中使用proj4字符串。
library(sf)
library(dplyr)
somelocations<-data.frame(id=c('X', 'Y', 'Z'),
Long=c(-156.6274,-156.6457,-156.6676),
Lat=c(20.8081,20.8292,20.8512))
# 这是基线 - WGS84中的位置
locations_sf <- somelocations %>%
st_as_sf(coords = c("Long", "Lat"), crs = 4326)
# 可视检查 - 位置是否正确?
mapview::mapview(locations_sf)
# 这就是行动!
locations_projected <- locations_sf %>%
st_transform(crs = "EPSG:32604") # 请参考 https://epsg.io/32604 了解更多信息...
# 坐标是否如预期?
locations_projected
# Simple feature collection with 3 features and 1 field
# Geometry type: POINT
# Dimension: XY
# Bounding box: xmin: 742693.4 ymin: 2302727 xmax: 746948.4 ymax: 2307439
# Projected CRS: WGS 84 / UTM zone 4N
# id geometry
# 1 X POINT (746948.4 2302727)
# 2 Y POINT (745008.7 2305036)
# 3 Z POINT (742693.4 2307439)
英文:
The {rgdal} package is by now superseded, and the package maintainer (who has since retired) is actively pushing the package users to consider other alternatives. Hence the big fat warning & pointer to {sf} and {terra}.
For converting Long Lat data to UTM zone 4N coordinates I suggest the following code.
The key parts are:
- converting from a regular data frame to {sf} data frame; this will give you the baseline for projection (where are you projecting from? are your original coordinates in decimal degrees, or meters? survey feet even?)
- apply
sf::st_transform()
to your sf object, converting from a known start to desired format
I have found it the easiest to specify Coordinate Reference Systems using EPSG codes, such as 4326 and 32604, rather than proj4strings as used in your code.
library(sf)
library(dplyr)
somelocations<-data.frame(id=c('X', "Y", "Z"),
Long=c(-156.6274,-156.6457,-156.6676),
Lat=c(20.8081,20.8292,20.8512))
# this is the baseline - locations in WGS84
locations_sf <- somelocations %>%
st_as_sf(coords = c("Long", "Lat"), crs = 4326)
# a visual check - do the locations look correct?
mapview::mapview(locations_sf)
# this is the action!
locations_projected <- locations_sf %>%
st_transform(crs = "EPSG:32604") # see https://epsg.io/32604 for more info...
# do the coordinates look as expected?
locations_projected
# Simple feature collection with 3 features and 1 field
# Geometry type: POINT
# Dimension: XY
# Bounding box: xmin: 742693.4 ymin: 2302727 xmax: 746948.4 ymax: 2307439
# Projected CRS: WGS 84 / UTM zone 4N
# id geometry
# 1 X POINT (746948.4 2302727)
# 2 Y POINT (745008.7 2305036)
# 3 Z POINT (742693.4 2307439)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论