I have a data set of 3000 plots with coordinates in Lat/Long. It spans 13 UTM zones. I want to break it up into chunks corresponding with the 13 UTM zones, and convert the coordinates in each chunk to their appropriate UTMs.

How would I figure out which UTM zone each coordinate should be in? I would prefer to use R, but could use QGIS if necessary

4 Answers 4


UTM zones are 6 degree bands, see figure https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system - and then the EPSG code is 32600+x where x is the band number. e.g. New York is between 72W and 78W so that's zone 18, North, so use EPSG code 32618: https://epsg.io/32618

There are some exceptions where UTM zones get split and tweaked in various places but the outline above should suffice for most things.

  • don't south zones have a different starting number?
    – Ian Turton
    Apr 30, 2020 at 7:23
  • 1
    Oopsie. Yes, southern zones appear to be 32700+zone number. epsg.io/32718 - although the only difference is the offset, so its okay to use N zones for data in S and vice versa as long as you use the right code.
    – Spacedman
    Apr 30, 2020 at 8:40

There are also some on-line converters to do both-way transformations. This one permits batch conversion of data from a csv file:http://www.earthpoint.us/BatchConvert.aspx Though you do need a subscription for batch processing. I'm guessing there are others available that are free. One here, for example, though I haven't tried it.https://consult.hermes.com.np/batch-convert-lat-long-to-utm/ See also other question/answers like this one: Convert Lat/Long to UTM


The QGIS Custom Expressions tutorial gives a function that will return the UTM zone (for most zones) you could use that to add a new (virtual) attribute to your data and then do a reprojection based on that value.

import math
from qgis.core import *
from qgis.gui import *

@qgsfunction(args=0, group='Custom', usesgeometry=True)
def GetUtmZone(value1, feature, parent):
    """Return the UTM Zone of the feature's geometry as a String"""
    centroid = feature.geometry()
    longitude = centroid.asPoint().x()
    latitude = centroid.asPoint().y()
    zone_number = math.floor(((longitude + 180) / 6) % 60) + 1

    if latitude >= 0:
        zone_letter = 'N'
        zone_letter = 'S'

    return '%d%s' % (int(zone_number), zone_letter)

Another approach that was suggested to me on Reddit was to use a spatial join with this shapefile: https://hub.arcgis.com/datasets/esri::world-utm-grid/data

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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