12

I am trying to convert a latitude/longitude point to UTM.

To define UTM projection, I need to calculate zone for the point.

I am trying to figure out the best way to do this.

One way to do this would be use longitude values to find the proper zone.

This would require lot of coding.

I am curious if there is a better way of doing this?

2
  • 1
    You could always do a Select By Location function and select the polygon UTM Zone that the point is located inside of.
    – MLowry
    Aug 9, 2011 at 15:44
  • 1
    Do you need to consider all possible UTM zones (such as polar zones, etc.) or do you just want the mid-latitude zones? The latter are a simple calculation because they are evenly spaced every six degrees from -180 to +180.
    – whuber
    Aug 9, 2011 at 15:52

2 Answers 2

21

It's not that difficult, even if you handle the zones around Svalbard and Norway. Here's an example:

ZoneNumber = floor((LongTemp + 180)/6) + 1;

if( Lat >= 56.0 && Lat < 64.0 && LongTemp >= 3.0 && LongTemp < 12.0 )
    ZoneNumber = 32;
endif
// Special zones for Svalbard
if( Lat >= 72.0 && Lat < 84.0 ) 
  if  ( LongTemp >= 0.0  && LongTemp <  9.0 ) 
    ZoneNumber = 31;
  elseif( LongTemp >= 9.0  && LongTemp < 21.0 )
    ZoneNumber = 33;
  elseif(LongTemp >= 21.0 && LongTemp < 33.0 )
    ZoneNumber = 35;
  elseif(LongTemp >= 33.0 && LongTemp < 42.0 ) 
    ZoneNumber = 37;
  endif
 endif

Convert Latitude/Longitude to UTM (attributed to Chuck Gantz).

I haven't tried this specific code, but the algorithm looks correct.

0
0

So I had this problem today, that I needed to find the UTM zone from lat/long. I needed to do it in R, but this was one of the top google hits. So here's my R script, with tests at the end for some of the curly edge cases like Svalbard, Norway, and the poles:

require(tidyverse)
require(purrr)
require(testthat)

find_one_utm_zone <- function(longitude, latitude) {

  # Special zones for Svalbard
  if (latitude >= 72.0 && latitude <= 84.0 ) {
    if (longitude >= 0.0  && longitude <  9.0)
      return("31X");
    if (longitude >= 9.0  && longitude < 21.0)
      return("33X")
    if (longitude >= 21.0 && longitude < 33.0)
      return("35X")
    if (longitude >= 33.0 && longitude < 42.0)
      return("37X")
  }
  # Special zones for Norway
  if (latitude >= 56.0 && latitude < 64.0 ) {
    if (longitude >= 0.0  && longitude <  3.0)
      return("31V");
    if (longitude >= 3.0  && longitude < 12.0)
      return("32V")
  }

  # North + South Poles

  if (latitude > 84.0){
    if ((longitude+180)%%360-180 < 0) {return("Y")}
    if ((longitude+180)%%360-180 > 0) {return("Z")}
  } else if (latitude < -80.0){
    if ((longitude+180)%%360-180 < 0) {return("A")}
    if ((longitude+180)%%360-180 > 0) {return("B")}
  }

  # Everything in the middle

  if ( (latitude>-80.0) && (latitude<=84.0) ){

    mid_zones <- LETTERS[c(3:8,10:14,16:24)] # C to X, skip I and O
    utm_letter <- mid_zones[ min(floor( (latitude + 80) / 8 )+1 , 20) ]
    utm_number <- (floor( (longitude + 180) / 6 ) %% 60) + 1 # modulo in case longitude is 0 to 360 instead of -180 to 180
    utm_zone <- paste0(utm_number, utm_letter)
    return(utm_zone)

  } else {
      stop("lat long not valid (or something else broke)")
    }
}
find_utm_zone <- function(lon, lat){
  purrr::map2_chr(.x = lon, .y = lat, .f = find_one_utm_zone)
}

Example of use

locs <-
  tibble(lon = c(-100,30,150, 4, 7, 22, 0, 12, -34),
         lat = c(-45, 85, 12, 57, 81, 83, 5, -81, 85),
         desired_utm_zone = c("14G","Z","56P", "32V" ,"31X","35X","31N", "B","Y"))

locs2 <-
  locs %>%
  mutate(utm_zone = find_utm_zone(lon = lon,lat = lat))

Test that it worked:

testthat::expect_equal(locs2$utm_zone, locs2$desired_utm_zone)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.