Reputation: 23
I'm trying to convert vectors that contain northing and easting data into decimal degrees using R. So far I have been able to the package rgdal to perform a projection, but I am running into a problem. The argument for the UTM zone must be a single character string, but I have multiple UTM zones in my data. Is there a way to use the rgdal::SpatialPoints() function to set multiple UTM zones? I tried inputting set character strings and using a vector in the CRS() function, but I received a warning message that only the first zone was used.
df<- data.frame(X = c(774869, 771437, 1051883, 524468),
Y = c(414498, 403790, 184967, 779682),
WGS.1984.UTM.Zone = c("57N", "57N", "54N", "59N"))
library(rgdal)
sputm <- SpatialPoints(df[c("X", "Y")], proj4string=CRS("+proj=utm +zone=57N +datum=WGS84"))
spgeo <- spTransform(sputm, CRS("+proj=longlat +datum=WGS84"))
#resultant coordinates are all transformed relative to UTM zone 57N
df$projargs<- paste("+proj=utm +zone=", df$WGS.1984.UTM.Zone, " +datum=WGS84", sep = "")
#trying again with set projargs character strings
spUTM<- SpatialPoints(df[c("X", "Y")], proj4string=CRS(df$projargs))
Warning messages:
1: In if (!is.na(projargs)) { : the condition has length > 1 and only the first element will be used
2: In if (!is.na(projargs)) { : the condition has length > 1 and only the first element will be used
3: In if (is.na(projargs)) uprojargs <- projargs else uprojargs <- paste(unique(unlist(strsplit(projargs, : the condition has length > 1 and only the first element will be used
Upvotes: 0
Views: 1312
Reputation: 1741
Here's another solution with the sf
package.
Make the sf object with st_as_sf()
. Note the new geometry
column.
library(sf)
library(dplyr)
df_sf <- st_as_sf(df,
coords = c("X", "Y"),
remove = FALSE,
crs = projargs)
df_sf
Simple feature collection with 4 features and 4 fields
geometry type: POINT
dimension: XY
bbox: xmin: 524468 ymin: 184967 xmax: 1051883 ymax: 779682
epsg (SRID): 32657
proj4string: +proj=utm +zone=57 +datum=WGS84 +units=m +no_defs
X Y WGS.1984.UTM.Zone projargs geometry
1 774869 414498 57N +proj=utm +zone=57N +datum=WGS84 POINT (774869 414498)
2 771437 403790 57N +proj=utm +zone=57N +datum=WGS84 POINT (771437 403790)
3 1051883 184967 54N +proj=utm +zone=54N +datum=WGS84 POINT (1051883 184967)
4 524468 779682 59N +proj=utm +zone=59N +datum=WGS84 POINT (524468 779682)
Re-project by using st_transform()
which updates the geometry column. We can pull those out into new columns with st_coordinates()
, which returns a two-column matrix for every line.
df_sf_longLat <- st_transform(df_sf, crs = "+proj=longlat +datum=WGS84") %>%
mutate(long_degrees = st_coordinates(.)[,1],
lat_degrees = st_coordinates(.)[,2])
df_sf_longLat
Simple feature collection with 4 features and 6 fields
geometry type: POINT
dimension: XY
bbox: xmin: 159.2216 ymin: 1.667156 xmax: 163.9555 ymax: 7.053618
epsg (SRID): 4326
proj4string: +proj=longlat +datum=WGS84 +no_defs
X Y WGS.1984.UTM.Zone projargs geometry long_degrees lat_degrees
1 774869 414498 57N +proj=utm +zone=57N +datum=WGS84 POINT (161.4747 3.746529) 161.4747 3.746529
2 771437 403790 57N +proj=utm +zone=57N +datum=WGS84 POINT (161.4435 3.64983) 161.4435 3.649830
3 1051883 184967 54N +proj=utm +zone=54N +datum=WGS84 POINT (163.9555 1.667156) 163.9555 1.667156
4 524468 779682 59N +proj=utm +zone=59N +datum=WGS84 POINT (159.2216 7.053618) 159.2216 7.053618
Upvotes: 1
Reputation: 887901
The function is not vectorized. So we need to loop
library(rgdal)
spUTM <- lapply(df$projargs, function(x)
SpatialPoints(df[c("X", "Y")], proj4string=CRS(x)))
str(spUTM)
#List of 4
# $ :Formal class 'SpatialPoints' [package "sp"] with 3 slots
# .. ..@ coords : num [1:4, 1:2] 774869 771437 1051883 524468 414498 ...
# .. .. ..- attr(*, "dimnames")=List of 2
# .. .. .. ..$ : NULL
# .. .. .. ..$ : chr [1:2] "X" "Y"
# .. ..@ bbox : num [1:2, 1:2] 524468 184967 1051883 779682
# .. .. ..- attr(*, "dimnames")=List of 2
# .. .. .. ..$ : chr [1:2] "X" "Y"
# ...
Or use map
from purrr
library(dplyr)
library(purrr)
df %>%
mutate(spUTM = map(projargs, ~
SpatialPoints(df[c('X', 'Y')], proj4string = CRS(.x))))
Upvotes: 0