Converting UTM (wsg84) coordinates to Latitude and Longitude
Asked Answered
T

6

18

I've been searching for a while now (here and on google obviously) for a neat way to convert a set of UTM coordinates to Latitude and Longitude. I've got the coordinates and I know in what zone they are, but how do I convert this to Latitude and Longitude? I Was hoping there would be some kind of class that could do at least some of the magic for me, but it doesn't seem so :(

Any suggestions on this?

I know it can be done, as this converter seems to work just fine Geographic/UTM Coordinate Converter.

Any input is greatly appreciated! :)

Thanks!

Trefoil answered 22/4, 2010 at 10:6 Comment(1)
Both good answers! :) Thanks a lot. I fixed it a bit different by finding the Lat and Lon from a given address. Not the most neat way of programming, but it does the work. I'm going to explore the ProjNet library though. Thanks again :)Trefoil
C
13

Take a look at this .NET library http://projnet.codeplex.com/ . This should help in your case

Checkered answered 22/4, 2010 at 10:13 Comment(2)
can u say which class the converter is??plz help meBullace
ProjNet moved from Codeplex to GitHub: github.com/dotMorten/ProjNET maybe github.com/NetTopologySuite/ProjNet4GeoAPI is of additional interest.Bestraddle
L
22

Here is:

 public static void ToLatLon(double utmX, double utmY, string utmZone, out double latitude, out double longitude)
    {
        bool isNorthHemisphere = utmZone.Last() >= 'N';

        var diflat = -0.00066286966871111111111111111111111111;
        var diflon = -0.0003868060578;

        var zone = int.Parse(utmZone.Remove(utmZone.Length - 1));
        var c_sa = 6378137.000000;
        var c_sb = 6356752.314245;
        var e2 = Math.Pow((Math.Pow(c_sa,2) - Math.Pow(c_sb,2)),0.5)/c_sb;
        var e2cuadrada = Math.Pow(e2,2);
        var c = Math.Pow(c_sa,2) / c_sb;
        var x = utmX - 500000;
        var y = isNorthHemisphere ? utmY : utmY - 10000000;

        var s = ((zone * 6.0) - 183.0);
        var lat = y / (c_sa * 0.9996);
        var v = (c / Math.Pow(1 + (e2cuadrada * Math.Pow(Math.Cos(lat), 2)), 0.5)) * 0.9996;
        var a = x / v;
        var a1 = Math.Sin(2 * lat);
        var a2 = a1 * Math.Pow((Math.Cos(lat)), 2);
        var j2 = lat + (a1 / 2.0);
        var j4 = ((3 * j2) + a2) / 4.0;
        var j6 = ((5 * j4) + Math.Pow(a2 * (Math.Cos(lat)), 2)) / 3.0;
        var alfa = (3.0 / 4.0) * e2cuadrada;
        var beta = (5.0 / 3.0) * Math.Pow(alfa, 2);
        var gama = (35.0 / 27.0) * Math.Pow(alfa, 3);
        var bm = 0.9996 * c * (lat - alfa * j2 + beta * j4 - gama * j6);
        var b = (y - bm) / v;
        var epsi = ((e2cuadrada * Math.Pow(a, 2)) / 2.0) * Math.Pow((Math.Cos(lat)), 2);
        var eps = a * (1 - (epsi / 3.0));
        var nab = (b * (1 - epsi)) + lat;
        var senoheps = (Math.Exp(eps) - Math.Exp(-eps)) / 2.0;
        var delt  = Math.Atan(senoheps/(Math.Cos(nab) ) );
        var tao = Math.Atan(Math.Cos(delt) * Math.Tan(nab));

        longitude = ((delt * (180.0 / Math.PI)) + s) + diflon;
        latitude = ((lat + (1 + e2cuadrada * Math.Pow(Math.Cos(lat), 2) - (3.0 / 2.0) * e2cuadrada * Math.Sin(lat) * Math.Cos(lat) * (tao - lat)) * (tao - lat)) * (180.0 / Math.PI)) + diflat;
    }
Louque answered 21/5, 2013 at 1:39 Comment(2)
Thanks Playful! I just change this lines for me, because i am udng in Brazil. bool isNorthHemisphere = utmZone.Last() == 'N' ? true : false; var diflat = 0.00006286966871111111111111111111111111; //-0.00066286966871111111111111111111111111; var diflon = -0.0003868060578;Escudo
i am having diff of 1.6+ in long. can you explain variables such as s, v, a, a1, a2, j2, j4 etc? i might have different values for my location as following: Angular unit: Degree (0.017453292519943299) Central_Meridian: 55.333333 Inverse Flattening: 298.257223563Sew
C
13

Take a look at this .NET library http://projnet.codeplex.com/ . This should help in your case

Checkered answered 22/4, 2010 at 10:13 Comment(2)
can u say which class the converter is??plz help meBullace
ProjNet moved from Codeplex to GitHub: github.com/dotMorten/ProjNET maybe github.com/NetTopologySuite/ProjNet4GeoAPI is of additional interest.Bestraddle
H
4

There is c++ code available on this website: http://www.gpsy.com/gpsinfo/geotoutm/

Go down the page a bit to the "Source Code" heading, and look for these files at the bottom:

Chuck Gantz

Enclosures: LatLong-UTMconversion.cpp (view online as text file) LatLong-UTMconversion.h (view online as text file) UTMConversions.cpp (view online as text file) SwissGrid.cpp (view online as text file) constants.h (view online as text file)

e.g. the first file links to: www.gpsy.com/gpsinfo/geotoutm/gantz/LatLong-UTMconversion.cpp etc

There are functions here for going both ways: UTM to Lat Long, and vice versa. If you look elsewhere, there are python versions of this code. e.g. at code.google.com/p/pys60gps/source/browse/trunk/lib/LatLongUTMconversion.py?r=246

There are also c# versions of some of it: at mediakey.dk/~cc/convert-northing-and-easting-utm-to-longitude-and-latitude/

Good luck.

Hedgehog answered 30/8, 2010 at 23:36 Comment(0)
I
4

I made a port from a javascript library to C#, I have tested it and works perfectly, you can take a look at it here.

Immigrant answered 27/6, 2017 at 14:27 Comment(2)
Warning: There are errors in your port; I've tested against different online converters.Cogwheel
sorry, I have not had time to correct it, as far as i know, the latlng to utm works fine, can you help to make it work correctly?Immigrant
S
1

Checkout CoordinateSharp on NuGet. It's really easy to do this with it.

 //Example
 UniversalTransverseMercator utm = new UniversalTransverseMercator("Q", 14, 581943.5, 2111989.8);
 Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm);
Samella answered 8/7, 2018 at 22:51 Comment(2)
FYI this is paid for commercial use.Meridional
Only if the commercial software is closed source. If not it’s a small one time fee for lifetime use and unlimited distributions.Samella
N
0

Use this code:

     public static void UTMToLatLon(double Easting, double Northing, double Zone, double Hemi, out double latitude, out double longitude)
    {
        double DtoR = Math.PI / 180, RtoD = 180 / Math.PI;
        double a = 6378137, f = 0.00335281066474748071984552861852, northernN0 = 0, southernN0 = 10000000, E0 = 500000, 
            n = f / (2 - f), k0 = 0.9996,
            A = a * (1 + (1 / 4) * Math.Pow(n, 2) + (1 / 64) * Math.Pow(n, 4) + (1 / 256) * Math.Pow(n, 6) + (25 / 16384) * Math.Pow(n, 8) + (49 / 65536) * Math.Pow(n, 10)) / (1 + n),             
            beta1 = n / 2 - (2 / 3) * Math.Pow(n, 2) + (37 / 96) * Math.Pow(n, 3) - (1 / 360) * Math.Pow(n, 4) - (81 / 512) * Math.Pow(n, 5) + (96199 / 604800) * Math.Pow(n, 6) - (5406467 / 38707200) * Math.Pow(n, 7) + (7944359 / 67737600) * Math.Pow(n, 8) - (7378753979 / 97542144000) * Math.Pow(n, 9) + (25123531261 / 804722688000) * Math.Pow(n, 10), 
            beta2 = (1 / 48) * Math.Pow(n, 2) + (1 / 15) * Math.Pow(n, 3) - (437 / 1440) * Math.Pow(n, 4) + (46 / 105) * Math.Pow(n, 5) - (1118711 / 3870720) * Math.Pow(n, 6) + (51841 / 1209600) * Math.Pow(n, 7) + (24749483 / 348364800) * Math.Pow(n, 8) - (115295683 / 1397088000) * Math.Pow(n, 9) + (5487737251099 / 51502252032000) * Math.Pow(n, 10), 
            beta3 = (17 / 480) * Math.Pow(n, 3) - (37 / 840) * Math.Pow(n, 4) - (209 / 4480) * Math.Pow(n, 5) + (5569 / 90720) * Math.Pow(n, 6) + (9261899 / 58060800) * Math.Pow(n, 7) - (6457463 / 17740800) * Math.Pow(n, 8) + (2473691167 / 9289728000) * Math.Pow(n, 9) - (852549456029 / 20922789888000) * Math.Pow(n, 10), 
            beta4 = (4397 / 161280) * Math.Pow(n, 4) - (11 / 504) * Math.Pow(n, 5) - (830251 / 7257600) * Math.Pow(n, 6) + (466511 / 2494800) * Math.Pow(n, 7) + (324154477 / 7664025600) * Math.Pow(n, 8) - (937932223 / 3891888000) * Math.Pow(n, 9) - (89112264211 / 5230697472000) * Math.Pow(n, 10),
            beta5 = (4583 / 161280) * Math.Pow(n, 5) - (108847 / 3991680) * Math.Pow(n, 6) - (8005831 / 63866880) * Math.Pow(n, 7) + (22894433 / 124540416) * Math.Pow(n, 8) + (112731569449 / 557941063680) * Math.Pow(n, 9) - (5391039814733 / 10461394944000) * Math.Pow(n, 10),
            beta6 = (20648693 / 638668800) * Math.Pow(n, 6) - (16363163 / 518918400) * Math.Pow(n, 7) - (2204645983 / 12915302400) * Math.Pow(n, 8) + (4543317553 / 18162144000) * Math.Pow(n, 9) + (54894890298749 / 167382319104000) * Math.Pow(n, 10),
            beta7 = (219941297 / 5535129600) * Math.Pow(n, 7) - (497323811 / 12454041600) * Math.Pow(n, 8) - (79431132943 / 332107776000) * Math.Pow(n, 9) + (4346429528407 / 12703122432000) * Math.Pow(n, 10),
            beta8 = (191773887257 / 3719607091200) * Math.Pow(n, 8) - (17822319343 / 336825216000) * Math.Pow(n, 9) - (497155444501631 / 1422749712384000) * Math.Pow(n, 10),
            beta9 = (11025641854267 / 158083301376000) * Math.Pow(n, 9) - (492293158444691 / 6758061133824000) * Math.Pow(n, 10),
            beta10 = (7028504530429621 / 72085985427456000) * Math.Pow(n, 10),
            delta1 = 2 * n - (2 / 3) * Math.Pow(n, 2) - 2 * Math.Pow(n, 3), 
            delta2 = (7 / 3) * Math.Pow(n, 2) - (8 / 5) * Math.Pow(n, 3), 
            delta3 = (56 / 15) * Math.Pow(n, 3),
            ksi = (Northing / 100 - northernN0) / (k0 * A), eta = (Easting / 100 - E0) / (k0 * A),
            ksi_prime = ksi - (beta1 * Math.Sin(2 * ksi) * Math.Cosh(2 * eta) + beta2 * Math.Sin(4 * ksi) * Math.Cosh(4 * eta) + beta3 * Math.Sin(6 * ksi) * Math.Cosh(6 * eta) + beta4 * Math.Sin(8 * ksi) * Math.Cosh(8 * eta) + beta5 * Math.Sin(10 * ksi) * Math.Cosh(10 * eta) + 
                        beta6 * Math.Sin(12 * ksi) * Math.Cosh(12 * eta) + beta7 * Math.Sin(14 * ksi) * Math.Cosh(14 * eta) + beta8 * Math.Sin(16 * ksi) * Math.Cosh(16 * eta) + beta9 * Math.Sin(18 * ksi) * Math.Cosh(18 * eta) + beta10 * Math.Sin(20 * ksi) * Math.Cosh(20 * eta)),
            eta_prime = eta - (beta1 * Math.Cos(2 * ksi) * Math.Sinh(2 * eta) + beta2 * Math.Cos(4 * ksi) * Math.Sinh(4 * eta) + beta3 * Math.Cos(6 * ksi) * Math.Sinh(6 * eta)),
            sigma_prime = 1 - (2 * beta1 * Math.Cos(2 * ksi) * Math.Cosh(2 * eta) + 2 * beta2 * Math.Cos(4 * ksi) * Math.Cosh(4 * eta) + 2 * beta3 * Math.Cos(6 * ksi) * Math.Cosh(6 * eta)),
            taw_prime = 2 * beta1 * Math.Sin(2 * ksi) * Math.Sinh(2 * eta) + 2 * beta2 * Math.Sin(4 * ksi) * Math.Sinh(4 * eta) + 2 * beta3 * Math.Sin(6 * ksi) * Math.Sinh(6 * eta),
            ki = Math.Asin(Math.Sin(ksi_prime) / Math.Cosh(eta_prime));

        latitude = (ki + delta1 * Math.Sin(2 * ki) + delta2 * Math.Sin(4 * ki) + delta3 * Math.Sin(6 * ki)) * RtoD;
        double longitude0 = Zone * 6 * DtoR  - 183 * DtoR ;
        longitude = (longitude0 + Math.Atan(Math.Sinh(eta_prime) / Math.Cos(ksi_prime))) * RtoD;
    }

This code is far more Accurate than others.

Nahamas answered 28/3, 2017 at 15:16 Comment(3)
You would need to explain the code and may be the source. At least justify the "far more Accurate" than others part of your answer.Soinski
sources that I use to obtain these equations are: link link I compared this code with some headers which are prepared for C#, and I found that these are more accurately. I also compared it with other answers in the page.Nahamas
Re "I also compared it with other answers in the page." Compared how? Do you have any specific test results that demonstrate this is more accurate?Cheerleader

© 2022 - 2024 — McMap. All rights reserved.