I am struggling to convert my lat and long columns to UTM (zone 27). I found the below function in another post but I believe I am running into an issue due to not all my sites not having spatial data. When I run the below function it does not change my lat long. When I run specific lines I get an error on the first line of the function for the coordinates().
#data
brazil_legacy_data <- structure(list(site = c("1 water", "2 water", "3 water", "4 water",
"5 water", "6 water", "7 water", "8 water", "9 water", "10 water",
"11 water", "lago angelim water", "lago anta water", "lago minutal water",
"lago sede water", "poça temporária water", "trilha water",
"1 land", "2 land", "3 land", "4 land", "5 land", "6 land", "7 land",
"8 land", "9 land", "10 land", "11 land", "lago angelim land",
"lago anta land", "lago minutal land", "lago sede land", "poça temporária land",
"trilha land"), lat = c(-23.340813, -23.342987, -23.343694, -23.340738,
-23.332042, -23.324259, -23.327646, -23.313991, NA, -23.386967,
NA, NA, NA, NA, NA, NA, NA, -23.340744, -23.343771, -23.343741,
-23.341032, -23.331908, -23.324572, -23.326528, -23.31427, NA,
-23.387007, NA, NA, NA, NA, NA, NA, NA), long = c(-45.149414,
-45.144503, -45.129222, -45.117734, -45.099698, -45.089126, -45.133222,
-45.120015, NA, -45.187918, NA, NA, NA, NA, NA, NA, NA, -45.150486,
-45.144043, -45.128388, -45.117835, -45.097041, -45.094422, -45.132481,
-45.124575, NA, -45.186547, NA, NA, NA, NA, NA, NA, NA), region = c("santa virginia",
"santa virginia", "santa virginia", "santa virginia", "santa virginia",
"santa virginia", "santa virginia", "santa virginia", "santa virginia",
"santa virginia", "santa virginia", "santa virginia", "santa virginia",
"santa virginia", "santa virginia", "santa virginia", "santa virginia",
"santa virginia", "santa virginia", "santa virginia", "santa virginia",
"santa virginia", "santa virginia", "santa virginia", "santa virginia",
"santa virginia", "santa virginia", "santa virginia", "santa virginia",
"santa virginia", "santa virginia", "santa virginia", "santa virginia",
"santa virginia"), location = c("brazil", "brazil", "brazil",
"brazil", "brazil", "brazil", "brazil", "brazil", "brazil", "brazil",
"brazil", "brazil", "brazil", "brazil", "brazil", "brazil", "brazil",
"brazil", "brazil", "brazil", "brazil", "brazil", "brazil", "brazil",
"brazil", "brazil", "brazil", "brazil", "brazil", "brazil", "brazil",
"brazil", "brazil", "brazil")), row.names = c(NA, -34L), class = c("tbl_df",
"tbl", "data.frame"))
# convert to utm
long2utm <- function(long) {
(floor((long 180)/6) %% 60) 1
}
LongLatToUTM <- function(brazil_legacy_sites){
## Args: df, data frame must have x and y columns. Should be from same UTM zone.
## Create a spatial dataframe
coordinates(brazil_legacy_sites) <- ~lat long
proj4string(brazil_legacy_sites) <- CRS(" proj=longlat datum=WGS84")
## Get zones for all the points in the data frame.
## Stop if more than one zone is present.
## You can write your own code for handling cases where your
## data comes from different UTM zones.
zone <- long2UTM(brazil_legacy_sites$lat)
if (length(unique(zone)) > 1) stop("values from different UTM zones")
zone <- unique(zone)
## Change CRS of the spatial data frame and convert to data frame
res <- spTransform(brazil_legacy_sites, CRS(paste0(" proj=utm zone=", zone, " datum=WGS84")))
return(as.data.frame(res))
}
CodePudding user response:
With these data you only need zone 23
b <- as.data.frame(brazil_legacy_data)
long2utm(b$long) |> unique()
#[1] 23 NA
So I will skip the loop
library(terra)
v <- vect(b, c("long", "lat"), crs=" proj=longlat")
u <- terra::project(v, " proj=utm zone=23")
utm <- crds(u)
head(utm)
# x y
#[1,] 484726.5 -2581256
#[2,] 485228.8 -2581497
#[3,] 486790.9 -2581573
#[4,] 487964.9 -2581245
#[5,] 489808.0 -2580281
#[6,] 490888.2 -2579419
All together
i <- which(!is.na(b$long))
b[i, c("x", "y")] <- utm
head(b)
# site lat long region location x y
#1 1 water -23.34081 -45.14941 santa virginia brazil 484726.5 -2581256
#2 2 water -23.34299 -45.14450 santa virginia brazil 485228.8 -2581497
#3 3 water -23.34369 -45.12922 santa virginia brazil 486790.9 -2581573
#4 4 water -23.34074 -45.11773 santa virginia brazil 487964.9 -2581245
#5 5 water -23.33204 -45.09970 santa virginia brazil 489808.0 -2580281
#6 6 water -23.32426 -45.08913 santa virginia brazil 490888.2 -2579419
This was not working for you because you had "rgdal" loaded after "terra" and then you get
rgdal::project(v, " proj=utm zone=23")
#Error in rgdal::project(v, " proj=utm zone=23") : xy not numeric