File Exchange

image thumbnail


version 1.7 (6.27 KB) by

Latitude/longitude to and from UTM coordinates precise and vectorized conversion.



View License

UTM2LL converts Universal Transverse Mercator (UTM) East/North coordinates to latitude/longitude.
LL2UTM converts latitude/longitude coordinates to UTM.
Both functions are using precise formula (millimeter precision), possible user-defined datum (WGS84 is the default), and are all vectorized (no loop in the code). It means that huge matrix of points, like an entire DEM grid, can be converted very fast.
Example (needs readhgt.m author's function):
X = readhgt(36:38,12:15,'merge','crop',[36.5,38.5,12.2,16],'plot');
[lon,lat] = meshgrid(X.lon,;
[x,y,zone] = ll2utm(lat,lon); % do the job!
z = double(X.z); z(z==-32768 | z<0) = NaN;
pcolor(x,y,z); shading flat; hold on
hold off; axis equal; axis tight
xlabel('East (m)'); ylabel('North (m)')
title(sprintf('Sicily - UTM zone %d WGS84',zone))
loads SRTM full resolution DEM of Sicily in lat/lon (a 2400x4500 grid), converts it to UTM and plots the result with pcolor and contour. To make a regular UTM grid, you may interpolate x and y with griddata function.

See "doc ll2utm" and "doc utm2ll" for syntax and help.

Comments and Ratings (15)

Again, for those who might find it interesting, although I am not in the field of GIS, I tweaked line 115 of utm2ll from:
L0 = (6*abs(f) - 183)/D0;
L0 = (6*f - 183)/D0;
and it worked perfectly. Here's an example:
utm2ll( 463385.25 ,3095579.99 , 28) % Yes, I am using utm28
ans =
27.9848503065749 -15.3723407898456

Confirmed the result with:

Hi Francois

Used your scripts for plotting pedestrian path recorded in Latitude and Longitude. Used it for converting to local Cartesian coordinates. worked very good. Thanks a lot!


JoeB (view profile)

Thanks for this. It will be very useful. ll2utm works fine, however utm2ll works for scalars and vectors but fails for matrices in the version I am using: (R2016a)

Operands to the || and && operators must be convertible to logical scalar values.

Error in utm2ll (line 135)
while any(isnan(p0) | abs(p - p0) > eps) && n < maxiter


Ben (view profile)

Could you please add GDA94?

Hello and thank you for your work.

I tried to use ll2utm with Mars latitude, longitude. I've seen that there is the possibility to create "DATUM" as a 2-element vector.

For Mars the vector is this one: [3396.9, 0.00589].

Using this vector I have this error: "Error using complex
Real input A must be numeric, real, and full.
Error in ll2utm (line 160)
z = complex(atan(sinh(L)./cos(l1 - L0)),log(tan(pi/4 + asin(sin(l1 - L0)./cosh(L))/2)));"

How can I use this code for Mars lat, lon?


Hello and thank you for your work,

In order for this to be true in the south Hemisphere:


I modified ll2utm so its zone input (z) is a positive value. (around line 147)

% UTM zone automatic setting
if isempty(zone)
F0 = round((l1*D0 + 183)/6);
F0 = abs(zone); %MB add abs

instead of

if isempty(zone)
F0 = round((l1*D0 + 183)/6);
F0 = zone; %MB add abs

Merci encore...


Hi, Frederic,
I tried to use ll2utm.m, and found that the output doesn't change even though I use different datum. See below:


a = 6.007219987931314e+05
b = 3.519881013316354e+06
c = 13


a = 6.007241362545381e+05
b = 3.519694086015768e+06
c = 13

a = 6.007241362545381e+05
b = 3.519694086015768e+06
c = 13

Any idea? Thanks,


Seb Biass

Hi, thanks a lot for these codes. FYI, when I use utm2ll with easting and northing matrices, I get these errors - whether I input the zone as a scalar, a vector or a matrix:

Operands to the || and && operators must be convertible to logical scalar values.

Error in utm2ll (line 135)
while any(isnan(p0) | abs(p - p0) > eps) && n < maxiter

Operands to the || and && operators must be convertible to logical scalar values.

Error in utm2ll (line 80)
if ~isnumeric(f) || any(f ~= round(f)) || (~isscalar(f) && any(size(f) ~= size(x)))

Best regards,

Regarding utm2ll.m:
Why has the ZONE to be a scalar when X and Y can be scalars, vectors or a matrix?

Hi. In the vectorized version of ll2utm.m, I don't get negative zones for coordinates in the southern hemisphere. Should the code in line #172 be:
f = F0.*sign(lat);
instead of
f = F0;

Best regards

Sorry, my comment relates to ll2utm.m (not utm2ll.m).

Fred Massin


Hi Francois, thanks a lot for these functions, very useful and very fast. I was wondering if there could be a way to force the UTM zone. I am using many datasets that are in UTM 22 N for example, and I would like to be able to do:
[x,y] = ll2utm(lat,lon,22);

Because otherwise my x and y are potentially different zones. Thanks !

This vectorized version of lat/lon vs UTM coordinates conversion may help users to deal with huge grids like digital elevation models, where others functions fail or take infinite time.



packaging problem.


Following the comment of Frederic Christen (thanks!), ZONE input argument can be scalar, vector or matrix in both ll2utm and utm2ll. Bug corrected for negative ZONE multiple outputs in southern hemisphere.


LL2UTM: adds possibility to force the UTM zone (thanks to Mathieu's suggestion).


- adds single output argument (ll2utm and utm2ll)
- adds single input argument (ll2utm)


minor update.


adds an example of ll2utm use.


minor update of description.

MATLAB Release
MATLAB 8.2 (R2013b)

MATLAB Online Live Editor Challenge

Win cash prizes and have your live script featured on our website

Learn more

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video