How to convert from UTM to LatLng in python or Javascript
Asked Answered
A

14

31

I have a bunch of files with coordinates in UTM form. For each coordinate I have easting, northing and zone. I need to convert this to LatLng for use with Google Map API to show the information in a map.

I have found some online calculators that does this, but no actual code or libraries. http://trac.osgeo.org/proj4js/ is a projection library for Javascript, but looking at the demo it doesn't include UTM projection.

I am still pretty fresh to the entire GIS domain, so what I want is something ala:

(lat,lng) = transform(easting, northing, zone)
Argot answered 5/12, 2008 at 13:42 Comment(0)
A
46

I ended up finding java code from IBM that solved it: http://www.ibm.com/developerworks/java/library/j-coordconvert/index.html

Just for reference, here is my python implementation of the method I needed:

import math

def utmToLatLng(zone, easting, northing, northernHemisphere=True):
    if not northernHemisphere:
        northing = 10000000 - northing

    a = 6378137
    e = 0.081819191
    e1sq = 0.006739497
    k0 = 0.9996

    arc = northing / k0
    mu = arc / (a * (1 - math.pow(e, 2) / 4.0 - 3 * math.pow(e, 4) / 64.0 - 5 * math.pow(e, 6) / 256.0))

    ei = (1 - math.pow((1 - e * e), (1 / 2.0))) / (1 + math.pow((1 - e * e), (1 / 2.0)))

    ca = 3 * ei / 2 - 27 * math.pow(ei, 3) / 32.0

    cb = 21 * math.pow(ei, 2) / 16 - 55 * math.pow(ei, 4) / 32
    cc = 151 * math.pow(ei, 3) / 96
    cd = 1097 * math.pow(ei, 4) / 512
    phi1 = mu + ca * math.sin(2 * mu) + cb * math.sin(4 * mu) + cc * math.sin(6 * mu) + cd * math.sin(8 * mu)

    n0 = a / math.pow((1 - math.pow((e * math.sin(phi1)), 2)), (1 / 2.0))

    r0 = a * (1 - e * e) / math.pow((1 - math.pow((e * math.sin(phi1)), 2)), (3 / 2.0))
    fact1 = n0 * math.tan(phi1) / r0

    _a1 = 500000 - easting
    dd0 = _a1 / (n0 * k0)
    fact2 = dd0 * dd0 / 2

    t0 = math.pow(math.tan(phi1), 2)
    Q0 = e1sq * math.pow(math.cos(phi1), 2)
    fact3 = (5 + 3 * t0 + 10 * Q0 - 4 * Q0 * Q0 - 9 * e1sq) * math.pow(dd0, 4) / 24

    fact4 = (61 + 90 * t0 + 298 * Q0 + 45 * t0 * t0 - 252 * e1sq - 3 * Q0 * Q0) * math.pow(dd0, 6) / 720

    lof1 = _a1 / (n0 * k0)
    lof2 = (1 + 2 * t0 + Q0) * math.pow(dd0, 3) / 6.0
    lof3 = (5 - 2 * Q0 + 28 * t0 - 3 * math.pow(Q0, 2) + 8 * e1sq + 24 * math.pow(t0, 2)) * math.pow(dd0, 5) / 120
    _a2 = (lof1 - lof2 + lof3) / math.cos(phi1)
    _a3 = _a2 * 180 / math.pi

    latitude = 180 * (phi1 - fact1 * (fact2 + fact3 + fact4)) / math.pi

    if not northernHemisphere:
        latitude = -latitude

    longitude = ((zone > 0) and (6 * zone - 183.0) or 3.0) - _a3

    return (latitude, longitude)

And here I thought it was something simple like easting*x+zone*y or something.

Argot answered 5/12, 2008 at 15:4 Comment(5)
I don't blame you for thinking it was something simple. I converted last week from Lat/Lon to Easting/Northing for Miller Projection and I'm still celebrating inside.Serosa
Why does your function require zone? Shouldn't you just need easting, northing, hemisphere?Betteanne
@Franki: Because UTM coordinates are relative to predefined zones. UTM on Wikipedia.Amortizement
You saved my day, I was looking for almost 2 days for something like this, and works pretty well, I did a javascript version of your script I will put as an answer if someone else find it helpull...thank you very muchLanny
I found the latitude result to be significantly different from the expected result. For example, with easting = 300000, northing = 5900040, zone = 31, and northernHemisphere = True, utmToLatLng` returns (lat, lon) = (53.21191417905066, 0.0047609197376834445). For comparison, this online UTM to lat, lon converter yields (lat, lon) = (53.211978, 0.004761), which is consistent with the expected coordinates.Designer
R
10

What I found is the following site: http://home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html It has a javascript converter, you should check the algorithm there. From the page:

Programmers: The JavaScript source code in this document may be copied and reused without restriction.

Raneeraney answered 5/12, 2008 at 14:21 Comment(3)
This is the cleanest Javascript version I have seen.Katherine
As mentioned in @monkut 's answer, python.org includes GDAL's Swig bindings from python: pypi.python.org/pypi/GDALFerdy
Link seem to be broken!Thermoelectric
R
8

According to this page, UTM is supported by proj4js.

http://trac.osgeo.org/proj4js/wiki/UserGuide#Supportedprojectionclasses

You may also want to take a look at GDAL. The gdal library has excellent python support, though it may be a bit overkill if you're only doing projection conversion.

Replenish answered 5/12, 2008 at 14:58 Comment(2)
+1 PROJ4 can do almost anything you've ever dreamed of, so if proj4js is a true port, it will be able to do it too.Quinte
+1 proj4s is the way to go. no point reinventing the wheel.. the proj4s reads from a config file which can have any projection added - type the reference into spatialreference.org to get a proj4js string e.g. spatialreference.org/ref/epsg/4326/proj4jsExcisable
L
8

A Javascript version of Staale answer

function utmToLatLng(zone, easting, northing, northernHemisphere){
        if (!northernHemisphere){
            northing = 10000000 - northing;
        }

        var a = 6378137;
        var e = 0.081819191;
        var e1sq = 0.006739497;
        var k0 = 0.9996;

        var arc = northing / k0;
        var mu = arc / (a * (1 - Math.pow(e, 2) / 4.0 - 3 * Math.pow(e, 4) / 64.0 - 5 * Math.pow(e, 6) / 256.0));

        var ei = (1 - Math.pow((1 - e * e), (1 / 2.0))) / (1 + Math.pow((1 - e * e), (1 / 2.0)));

        var ca = 3 * ei / 2 - 27 * Math.pow(ei, 3) / 32.0;

        var cb = 21 * Math.pow(ei, 2) / 16 - 55 * Math.pow(ei, 4) / 32;
        var cc = 151 * Math.pow(ei, 3) / 96;
        var cd = 1097 * Math.pow(ei, 4) / 512;
        var phi1 = mu + ca * Math.sin(2 * mu) + cb * Math.sin(4 * mu) + cc * Math.sin(6 * mu) + cd * Math.sin(8 * mu);

        var n0 = a / Math.pow((1 - Math.pow((e * Math.sin(phi1)), 2)), (1 / 2.0));

        var r0 = a * (1 - e * e) / Math.pow((1 - Math.pow((e * Math.sin(phi1)), 2)), (3 / 2.0));
        var fact1 = n0 * Math.tan(phi1) / r0;

        var _a1 = 500000 - easting;
        var dd0 = _a1 / (n0 * k0);
        var fact2 = dd0 * dd0 / 2;

        var t0 = Math.pow(Math.tan(phi1), 2);
        var Q0 = e1sq * Math.pow(Math.cos(phi1), 2);
        var fact3 = (5 + 3 * t0 + 10 * Q0 - 4 * Q0 * Q0 - 9 * e1sq) * Math.pow(dd0, 4) / 24;

        var fact4 = (61 + 90 * t0 + 298 * Q0 + 45 * t0 * t0 - 252 * e1sq - 3 * Q0 * Q0) * Math.pow(dd0, 6) / 720;

        var lof1 = _a1 / (n0 * k0);
        var lof2 = (1 + 2 * t0 + Q0) * Math.pow(dd0, 3) / 6.0;
        var lof3 = (5 - 2 * Q0 + 28 * t0 - 3 * Math.pow(Q0, 2) + 8 * e1sq + 24 * Math.pow(t0, 2)) * Math.pow(dd0, 5) / 120;
        var _a2 = (lof1 - lof2 + lof3) / Math.cos(phi1);
        var _a3 = _a2 * 180 / Math.PI;

        var latitude = 180 * (phi1 - fact1 * (fact2 + fact3 + fact4)) / Math.PI;

        if (!northernHemisphere){
          latitude = -latitude;
        }

        var longitude = ((zone > 0) && (6 * zone - 183.0) || 3.0) - _a3;

        var obj = {
              latitude : latitude,
              longitude: longitude
        };


        return obj;
      }
Lanny answered 9/12, 2014 at 21:17 Comment(0)
A
7

I'm new to this as well and have been studying up on the subject recently.

Here's a method I found using the python gdal pacakge (the osr package is included in gdal). The gdal package is pretty powerful, but the documentation could be better.

This is derived from a discussion here: http://www.mail-archive.com/[email protected]/msg12398.html

import osr

def transform_utm_to_wgs84(easting, northing, zone):
    utm_coordinate_system = osr.SpatialReference()
    utm_coordinate_system.SetWellKnownGeogCS("WGS84") # Set geographic coordinate system to handle lat/lon
    is_northern = northing > 0    
    utm_coordinate_system.SetUTM(zone, is_northern)

    wgs84_coordinate_system = utm_coordinate_system.CloneGeogCS() # Clone ONLY the geographic coordinate system 

    # create transform component
    utm_to_wgs84_transform = osr.CoordinateTransformation(utm_coordinate_system, wgs84_coordinate_system) # (<from>, <to>)
    return utm_to_wgs84_transform.TransformPoint(easting, northing, 0) # returns lon, lat, altitude

And here's the method for converting from a lat, lon in wgs84 (what most gps units report) to utm:

def transform_wgs84_to_utm(lon, lat):    
    def get_utm_zone(longitude):
        return (int(1+(longitude+180.0)/6.0))

    def is_northern(latitude):
        """
        Determines if given latitude is a northern for UTM
        """
        if (latitude < 0.0):
            return 0
        else:
            return 1

    utm_coordinate_system = osr.SpatialReference()
    utm_coordinate_system.SetWellKnownGeogCS("WGS84") # Set geographic coordinate system to handle lat/lon  
    utm_coordinate_system.SetUTM(get_utm_zone(lon), is_northern(lat))

    wgs84_coordinate_system = utm_coordinate_system.CloneGeogCS() # Clone ONLY the geographic coordinate system 

    # create transform component
    wgs84_to_utm_transform = osr.CoordinateTransformation(wgs84_coordinate_system, utm_coordinate_system) # (<from>, <to>)
    return wgs84_to_utm_transform.TransformPoint(lon, lat, 0) # returns easting, northing, altitude    

I also found that if you've already got django/gdal installed and you know the EPSG code for the UTM zone you're working on, you can just use the Point() transform() method.

from django.contrib.gis.geos import Point
utm2epsg = {"54N": 3185, ...}
p = Point(lon, lat, srid=4326) # 4326 = WGS84 epsg code
p.transform(utm2epsg["54N"])
Actino answered 20/4, 2012 at 3:1 Comment(0)
P
7

There is a library for Python (utm) "Bidirectional UTM-WGS84 converter for python" that can manage single coordinate points or series.

Convert a (latitude, longitude) tuple into an UTM coordinate:

>>> utm.from_latlon(51.2, 7.5)

resulting

(395201.3103811303, 5673135.241182375, 32, 'U')

The return has the form (EASTING, NORTHING, ZONE_NUMBER, ZONE_LETTER).

If series are used, in the result EASTING and NORTHING will have the same shape.

>>> utm.from_latlon(np.array([51.2, 49.0]), np.array([7.5, 8.4]))

resulting

(array([395201.31038113, 456114.59586214]), array([5673135.24118237, 5427629.20426126]), 32, 'U')

And for the opposite, convert an UTM coordinate into a (latitude, longitude) tuple:

>>> utm.to_latlon(340000, 5710000, 32, 'U')
(51.51852098408468, 6.693872395145327)

with the syntax utm.to_latlon(EASTING, NORTHING, ZONE_NUMBER, ZONE_LETTER). Same in this case if series are to be used. According to the documentation is faster to pass a series than multiple one point calls to the function.

Polycotyledon answered 10/12, 2021 at 19:10 Comment(0)
T
4

You could use Proj4js, as follows.

Download Proj4JS from GitHub, using this link.

The following code will convert from UTM to longitude latitude

<html>
<head>
  <script src="proj4.js"></script>

  <script>
    var utm = "+proj=utm +zone=32";
    var wgs84 = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
    console.log(proj4(utm,wgs84,[539884, 4942158]));
  </script>
</head>
<body>

</body>
</html>

In this code, the UTM zone is 32, as should be obvious. The Easting is 539884, and the Northing is 4942158. The result is:

[9.502832656648073, 44.631671014204365] 

Which is to say 44.631671014204365N, 9.502832656648073E. Which I have verified is correct.

If you need other projections, you can find their strings here.

Tuchman answered 4/9, 2013 at 18:30 Comment(1)
What about South of Equator or notQuarterphase
P
1
////////////////////////////////////////////////////////////////////////////////////////////
//
// ToLL - function to compute Latitude and Longitude given UTM Northing and Easting in meters
//
//  Description:
//    This member function converts input north and east coordinates
//    to the corresponding Northing and Easting values relative to the defined
//    UTM zone.  Refer to the reference in this file's header.
//
//  Parameters:
//    north   - (i) Northing (meters)
//    east    - (i) Easting (meters)
//    utmZone - (i) UTM Zone of the North and East parameters
//    lat     - (o) Latitude in degrees 
//    lon     - (o) Longitude in degrees
//
function ToLL(north,east,utmZone)
{ 
  // This is the lambda knot value in the reference
  var LngOrigin = DegToRad(utmZone * 6 - 183)

  // The following set of class constants define characteristics of the
  // ellipsoid, as defined my the WGS84 datum.  These values need to be
  // changed if a different dataum is used.    

  var FalseNorth = 0.  // South or North?
  //if (lat < 0.) FalseNorth = 10000000.  // South or North?
  //else          FalseNorth = 0.   

  var Ecc = 0.081819190842622       // Eccentricity
  var EccSq = Ecc * Ecc
  var Ecc2Sq = EccSq / (1. - EccSq)
  var Ecc2 = Math.sqrt(Ecc2Sq)      // Secondary eccentricity
  var E1 = ( 1 - Math.sqrt(1-EccSq) ) / ( 1 + Math.sqrt(1-EccSq) )
  var E12 = E1 * E1
  var E13 = E12 * E1
  var E14 = E13 * E1

  var SemiMajor = 6378137.0         // Ellipsoidal semi-major axis (Meters)
  var FalseEast = 500000.0          // UTM East bias (Meters)
  var ScaleFactor = 0.9996          // Scale at natural origin

  // Calculate the Cassini projection parameters

  var M1 = (north - FalseNorth) / ScaleFactor
  var Mu1 = M1 / ( SemiMajor * (1 - EccSq/4.0 - 3.0*EccSq*EccSq/64.0 -
    5.0*EccSq*EccSq*EccSq/256.0) )

  var Phi1 = Mu1 + (3.0*E1/2.0 - 27.0*E13/32.0) * Math.sin(2.0*Mu1)
    + (21.0*E12/16.0 - 55.0*E14/32.0)           * Math.sin(4.0*Mu1)
    + (151.0*E13/96.0)                          * Math.sin(6.0*Mu1)
    + (1097.0*E14/512.0)                        * Math.sin(8.0*Mu1)

  var sin2phi1 = Math.sin(Phi1) * Math.sin(Phi1)
  var Rho1 = (SemiMajor * (1.0-EccSq) ) / Math.pow(1.0-EccSq*sin2phi1,1.5)
  var Nu1 = SemiMajor / Math.sqrt(1.0-EccSq*sin2phi1)

  // Compute parameters as defined in the POSC specification.  T, C and D

  var T1 = Math.tan(Phi1) * Math.tan(Phi1)
  var T12 = T1 * T1
  var C1 = Ecc2Sq * Math.cos(Phi1) * Math.cos(Phi1)
  var C12 = C1 * C1
  var D  = (east - FalseEast) / (ScaleFactor * Nu1)
  var D2 = D * D
  var D3 = D2 * D
  var D4 = D3 * D
  var D5 = D4 * D
  var D6 = D5 * D

  // Compute the Latitude and Longitude and convert to degrees
  var lat = Phi1 - Nu1*Math.tan(Phi1)/Rho1 *
    ( D2/2.0 - (5.0 + 3.0*T1 + 10.0*C1 - 4.0*C12 - 9.0*Ecc2Sq)*D4/24.0
     + (61.0 + 90.0*T1 + 298.0*C1 + 45.0*T12 - 252.0*Ecc2Sq - 3.0*C12)*D6/720.0 )

  lat = RadToDeg(lat)

  var lon = LngOrigin + 
    ( D - (1.0 + 2.0*T1 + C1)*D3/6.0
      + (5.0 - 2.0*C1 + 28.0*T1 - 3.0*C12 + 8.0*Ecc2Sq + 24.0*T12)*D5/120.0) / Math.cos(Phi1)

  lon = RadToDeg(lon)

  // Create a object to store the calculated Latitude and Longitude values
  var sendLatLon = new PC_LatLon(lat,lon)

  // Returns a PC_LatLon object
  return sendLatLon
}

////////////////////////////////////////////////////////////////////////////////////////////
//
//  RadToDeg - function that inputs a value in radians and returns a value in degrees
//
function RadToDeg(value)
{
  return ( value * 180.0 / Math.PI )
}

////////////////////////////////////////////////////////////////////////////////////////////
//
// PC_LatLon - this psuedo class is used to store lat/lon values computed by the ToLL 
//  function.
//
function PC_LatLon(inLat,inLon)
{
  this.lat       = inLat     // Store Latitude in decimal degrees
  this.lon       = inLon     // Store Longitude in decimal degrees
}
Pentalpha answered 18/7, 2011 at 14:0 Comment(1)
DegToRad method is missingIatrics
H
1

One problem I had with using proj4js was that it needed the exact zone as @Richard points out. I found a great resource here which can convert WGS to UTM and wrote a cleaner wrapper in JavaScript:

https://github.com/urbanetic/utm-converter

Hairston answered 20/12, 2014 at 14:55 Comment(0)
D
0

There is a perl module via CPAN called Geography::NationalGrid which can convert easting/northing to lat/longs. That may help.

Alternatively there are lots of scripts on the movable-type site that let you convert lat/long and easting/northings.

Dotted answered 7/7, 2009 at 13:4 Comment(0)
R
0

The answer by Staale worked for me with a small modification - The math module cannot handle Pandas Series, so I replaced all math functions with numpy.

However, checking in QGIS, I see about 4m difference between the UTM and LAT/LON coordinates.

Code below:

import numpy as np

def utmToLatLng(zone, easting, northing, northernHemisphere=True):
    if not northernHemisphere:
        northing = 10000000 - northing

a = 6378137
e = 0.081819191
e1sq = 0.006739497
k0 = 0.9996

arc = northing / k0
mu = arc / (a * (1 - np.power(e, 2) / 4.0 - 3 * np.power(e, 4) / 64.0 - 5 * np.power(e, 6) / 256.0))

ei = (1 - np.power((1 - e * e), (1 / 2.0))) / (1 + np.power((1 - e * e), (1 / 2.0)))

ca = 3 * ei / 2 - 27 * np.power(ei, 3) / 32.0

cb = 21 * np.power(ei, 2) / 16 - 55 * np.power(ei, 4) / 32
cc = 151 * np.power(ei, 3) / 96
cd = 1097 * np.power(ei, 4) / 512
phi1 = mu + ca * np.sin(2 * mu) + cb * np.sin(4 * mu) + cc * np.sin(6 * mu) + cd * np.sin(8 * mu)

n0 = a / np.power((1 - np.power((e * np.sin(phi1)), 2)), (1 / 2.0))

r0 = a * (1 - e * e) / np.power((1 - np.power((e * np.sin(phi1)), 2)), (3 / 2.0))
fact1 = n0 * np.tan(phi1) / r0

_a1 = 500000 - easting
dd0 = _a1 / (n0 * k0)
fact2 = dd0 * dd0 / 2

t0 = np.power(np.tan(phi1), 2)
Q0 = e1sq * np.power(np.cos(phi1), 2)
fact3 = (5 + 3 * t0 + 10 * Q0 - 4 * Q0 * Q0 - 9 * e1sq) * np.power(dd0, 4) / 24

fact4 = (61 + 90 * t0 + 298 * Q0 + 45 * t0 * t0 - 252 * e1sq - 3 * Q0 * Q0) * np.power(dd0, 6) / 720

lof1 = _a1 / (n0 * k0)
lof2 = (1 + 2 * t0 + Q0) * np.power(dd0, 3) / 6.0
lof3 = (5 - 2 * Q0 + 28 * t0 - 3 * np.power(Q0, 2) + 8 * e1sq + 24 * np.power(t0, 2)) * np.power(dd0, 5) / 120
_a2 = (lof1 - lof2 + lof3) / np.cos(phi1)
_a3 = _a2 * 180 / np.pi

latitude = 180 * (phi1 - fact1 * (fact2 + fact3 + fact4)) / np.pi

if not northernHemisphere:
    latitude = -latitude

longitude = ((zone > 0) and (6 * zone - 183.0) or 3.0) - _a3

return (latitude, longitude)

That way I can do this directly:

df['LAT'], df['LON']=utmToLatLng(31, df['X'], df['Y'], northernHemisphere=True)
Reta answered 22/8, 2018 at 13:51 Comment(0)
O
0

Converted @TreyA to kotlin (some Math functions in java libraries), just for the case of it. Seems to be a bit more accurate than @Staale and @sandino


fun utmToLatLng2(
    north:Double?,
    east:Double?,
    zone:Long,
    northernHemisphere: Boolean
):LatLng?{

    if((north==null)||(east == null)) return null

    val lngOrigin = Math.toRadians(zone*6.0 - 183.0)
    val falseNorth = if(northernHemisphere) 0.toDouble() else 10000000.toDouble()

    val ecc = 0.081819190842622
    val eccSq = ecc*ecc
    val ecc2Sq = eccSq / (1.0 - eccSq)
    //var ecc2 = sqrt(ecc2Sq) //not in use ?
    val e1 = (1.0 - sqrt(1.0-eccSq))/(1.0 + sqrt(1-eccSq))
    val e12 = e1*e1
    val e13 = e12*e1
    val e14 = e13*e1

    val semiMajor = 6378137.0
    val falseEast = 500000.0
    val scaleFactor = 0.9996

    //Cassini

    val m1 = (north - falseNorth) / scaleFactor
    val mu1 = m1 / (semiMajor * (1.0 - eccSq/4.0 - 3.0*eccSq*eccSq/64.0 - 5.0*eccSq*eccSq*eccSq/256.0))

    val phi1 = mu1 +
            (3.0 * e1 / 2.0 - 27.0 * e13 / 32.0) * sin(2.0 * mu1) +
            (21.0 * e12 / 16.0 - 55.0 * e14 / 32.0) * sin(4.0 * mu1) +
            (151.0 * e13 / 96.0) * sin(6.0 * mu1) +
            (1097.0 * e14 / 512.0) * sin( 8.0 * mu1)

    val sin2phi1 = sin(phi1) * sin(phi1)
    val rho1 = (semiMajor * (1.0-eccSq)) / (1.0 - eccSq * sin2phi1).pow(1.5)
    val nu1 = semiMajor / sqrt(1.0-eccSq*sin2phi1)

    //POSC

    val t1 = tan(phi1)*tan(phi1)
    val t12 = t1*t1
    val c1 = ecc2Sq*cos(phi1)*cos(phi1)
    val c12 = c1*c1
    val d = (east - falseEast) / (scaleFactor*nu1)
    val d2 = d*d
    val d3 = d2*d
    val d4 = d3*d
    val d5 = d4*d
    val d6 = d5*d

    //Compute lat & lon convert to degree

    var lat =
        phi1 - nu1 * tan(phi1)/rho1 *
                (d2/2.0 - (5.0 + 3.0*t1 + 10*c1 - 4.0*c12 -9.0*ecc2Sq) * d4/24.0 +
                        (61.0 + 90.0*t1 +298.0*c1 + 45.0*t12 -252*ecc2Sq - 3.0*c12) * d6/720.0)

    lat = Math.toDegrees(lat)

    var lon =
        lngOrigin +
                (d - (1.0 + 2.0*t1 + c1)*d3/6.0 +
                        (5.0 - 2.0*c1 + 28.0*t1 - 3.0*c12 + 8.0*ecc2Sq + 24.0*t12)*d5/120.0) / cos(phi1)

    lon = Math.toDegrees(lon)

    return LatLng(lat,lon)


}



Opalina answered 19/11, 2021 at 15:3 Comment(0)
A
0

In Python, you can also use the pyproj package. Find the EPSG code of your UTM (e.g., here). Then:

From lat-lon to UTM:

from pyproj import Transformer, CRS
crs = CRS.from_epsg(25833)  # put your desired EPSG code here
latlon2utm = Transformer.from_crs(crs.geodetic_crs, crs)
lats = [58.969, 59.911]  # latitudes of two Norwegian cities
lons = [5.732, 10.750]  # longitudes of two Norwegian cities
eastings, northings = latlon2utm.transform(lats, lons)

From UTM to lat-lon:

utm2latlon = Transformer.from_crs(crs, crs.geodetic_crs)
latitudes, longitudes = utm2latlon.transform(eastings, northings)
Armillas answered 1/3, 2022 at 18:29 Comment(0)
D
0

In addition to the utm package, there is also the sentinelhub worth considering. They give slightly different results, but they are closer to the expected coordinates than the func utmToLatLng provided by another contributor. The sentinelhub package is better documented (probably better maintained too), and has a number of other useful geometric functions.

import utm
from sentinelhub import CRS
from sentinelhub.geo_utils import transform_point

easting = 300000
northing = 5900040
utm_zone = '31N'
zone = 31

# Using utmToLatLng:
lat, lon = utmToLatLng(zone, easting, northing, northernHemisphere=True)
# lat = 0.0047609197376834445
# lon = 53.21191417905066 (note this result is very different from the ones below)

# Using utm:
lon, lat = utm.to_latlon(easting, northing, zone, 'N')
# lat = 0.004760919759893956
# lon = 53.21197788941637

# Using sentinelhub:
lon, lat = transform_point((easting, northing), CRS.UTM_31N, CRS.WGS84)
# lat = 0.004760925082036568
# lon = 53.21197782614651
Designer answered 28/3 at 13:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.