Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Convert lat/long to UTM (zone 27)

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))
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading