# Calculating UTM Zones using ArcGIS Pro?

The Calculate UTM Zone tool is listed amongst the Tools that are not available in ArcGIS Pro at version 1.4.

A workaround when needing UTM zones to be calculated would be to use the Calculate UTM Zone tool from ArcGIS Desktop but is anyone aware of a workaround for calculating UTM zones on a machine when only ArcGIS Pro (with its ArcPy) is installed? 

• `(longitude + 172) / 6` – Vince Jan 17 '17 at 0:35
• @Vince 180 not 172! (then floor it) – mkennedy Jan 17 '17 at 0:54
• @mkennedy and Vince - I should have remembered that because I used it in an answer to an earlier question. I'll try to write up an answer if neither of you or anyone else does. – PolyGeo Jan 17 '17 at 1:12
• Oopsie 174, not 172 (The "+ 1" is associative through the "/ 6"). It depends on the language, and if the longitude is integer (if it's double, then the `floor` and an `int` cast is needed). In Python `zone = str((int(Math.floor(longitude)) + 174) / 6) + if (latitude < 0) 'S' else 'N'` – Vince Jan 17 '17 at 1:52
• Ahhh. This just proves one should test code at a PC, not just type it from a phone: Wrong sign on the hack, and wrong ternary syntax and missing parens on the ternary: `zone = str((int(longitude + 174.0) / 6) + ( 'S' if (latitude < 0) else 'N')` – Vince Jan 18 '17 at 17:26

UTM zone is one of sixty 6 degree wide bands numbered from west to east (1-60). It requires only a longitude value. Either of these Python expressions will work (the second slightly faster, but more obscure):

``````zone = int(longitude + 180.0) / 6 + 1

zone = int(longitude + 186.0) / 6
``````

UTM Zone can also refer to one of 120 band segments (north and south), which would then require a longitude value and be represented as a string:

``````zone = str(int(longitude + 186.0) / 6) + ('S' if (latitude < 0) else 'N')
``````

Even though it is not strictly part of a UTM zone designations, many also use the military grid reference system (MGRS) band designators to slice the 164 degrees of UTM-addressed meridians (from 80S to 84N) into mostly 8 degree tall bands, lettered 'C' through 'X' (skipping 'I' and 'O') -- the 'X' band is 12 degrees tall. MGRS uses 'A' and 'B' for south of 80S (west and east of the Prime Meridian, respectively) and 'Y' and 'Z' for north of 84N (similarly).

The following Python function takes a `geometry` parameter and generates a three character formatted string suitable as a rough spatial index hash based on MGRS (fixed-width, so 1X would be rendered `01X`, and lexographic sorting is possible):

``````def calcMGRS(geom):
bandVals = "CDEFGHJKLMNPQRSTUVWXX"

if (not geom):
return '61B'

ddLon = geom.extent.XMin
ddLat = geom.extent.YMax

zone = int(ddLon + 186.0) / 6

if (ddLat >= 84.0):
band = 'Y' if (ddLon < 0.0) else 'Z'
elif (ddLat <= -80.0):
band = 'A' if (ddLon < 0.0) else 'B'
else:
band = bandVals[int(ddLat + 80.0) / 8]

return '{:02d}{:s}'.format(zone,band)
``````

Note that this is different from the Esri utility, since it uses the upper-left corner of the geometry, not the centroid to identify the zone and band.

Generating a UTM spatial reference string would be simple enough, given the second code block (with direction). The trickiest part would be to extract GeogCS from the current map canvas.

• I was about to bring up luomus.fi/en/utm-mgrs-atlas-florae-europaeae but it looks like you may have already taken account of it. I'm planning to test using points rather than lines or polygons, and was thinking that I would use GCS WGS 1984 - I have some playing to do. – PolyGeo Jan 19 '17 at 6:46
• You fliped latitude and longitude names :) – Dims May 25 '17 at 19:38
• @Dims Your meaning is unclear – Vince May 25 '17 at 20:30
• @Vince sorry this was me who confused them :) – Dims May 27 '17 at 11:00
• With python 3, you'd want to use the // (integer division operator) or your answer may result in fractional zones. `zone = str(int(longitude + 186.0) // 6) + ('S' if (latitude < 0) else 'N')` should work in python 2.x and 3.x. – svohara Jun 8 '17 at 18:26