Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easting northing to latitude longitude

Tags:

gps

bing-maps

I've got coordinates of location in easting/northing format but I need to convert it to proper lat long to center it in bing maps. Any formula or details how to convert easting/northing to lat/lon?

EDIT: To be more specific, I need to convert SVY21 coordinates to the to WGS84

like image 412
Bahamut Avatar asked Oct 24 '11 07:10

Bahamut


3 Answers

Eastings and northings are distances east and north, respectively, of a base point. The base point is usually a latitude and longitude, and eastings and northings are normally expressed in meters or feet. The easting and northing, however, is usually offset a particular value to make them positive and allow them to express places west and south of the base point.

In general, converting from one coordinate system to another is not simple, since both may have different ellipsoids (Earth models) and datums. As I understand, the formulas for converting from one coordinate system to another are rather complex.

SVY21, however, uses the exact same datum and ellipsoid as WGS84, making the task simpler. In SVY21, the base point for eastings and northings is Base 7 at Pierce Reservoir. According to the geodetic version of SVY21, this base point is 1 deg. 22 min. 02.9154 sec. North and 103 deg. 49 min 31.9752 sec. East (that is, a latitude of about 1.3674765 degrees and a longitude of about 103.8255487 degrees; the well known text for the projected version, however, uses a slightly different latitude and longitude). The offset for the easting is 28001.642 meters, and the offset for the northing is 38744.572 meters. The EPSG code is 3414. I will assume your eastings and northings are expressed in meters.

Since SVY21 uses the same system as WGS84, all you have to do is:

  • Subtract the easting and northing by their respective offset values. (The values will be in meters.)
  • Find the longitude of the given point by finding the destination point given the base point, the absolute value of the easting, and the bearing of 90 degrees if the easting is positive, or 270 degrees if it's negative. This calculation is called solving the "direct geodesic problem", and this is discussed in C.F.F. Karney's article "Algorithms for geodesics, 2012.
  • Find the latitude of the given point by finding the destination point given the base point, the absolute value of the northing, and the bearing of 0 degrees if the northing is positive, or 180 degrees if it's negative.
like image 79
Peter O. Avatar answered Nov 04 '22 13:11

Peter O.


I've converted a Javascript implementation into T-SQL functions for the WGS84 to Latitude/Longitude values. Feel free to use as you see fit. If you need a different coordinate system, check out the University of Wisconsin - Green Bay web page that I used as a source and get the updated constants.

    drop function UF_utm_to_lat
go
create function UF_utm_to_lat(@utmz float, @x float, @y float) returns float
as
begin
    --Based on code from this page: http://www.uwgb.edu/dutchs/usefuldata/ConvertUTMNoOZ.HTM
    declare @latitude float;
    declare @longitude float;
    set @latitude = 0.00;
    set @longitude = 0.00;

    --Declarations
    declare @a float;
    declare @f float;
    declare @drad float;
    declare @k0 float;
    declare @b float;
    declare @e float;
    declare @e0 float;
    declare @esq float;
    declare @e0sq float;
    declare @zcm float;
    declare @e1 float;
    declare @M float;
    declare @mu float;
    declare @phi1 float;
    declare @C1 float;
    declare @T1 float;
    declare @N1 float;
    declare @R1 float;
    declare @D float;
    declare @phi float;
    declare @lng float;
    declare @lngd float;

    --Datum Info here: Name, a, b, f, 1/f
    --WGS 84    6,378,137.0 6356752.314 0.003352811 298.2572236

    set @a = 6378137.0;
    set @b = 6356752.314;
    set @f = 0.003352811;
    set @drad = PI()/180.0;
    set @k0 = 0.9996; --scale on central meridian

    set @e = SQRT(1.0 - (@b/@a)*(@b/@a)); --Eccentricity
    --e = Math.sqrt(1 - (b/a)*(b/a));//eccentricity
    set @e0 = @e/SQRT(1.0 - @e*@e); --Called e prime in reference
    --e0 = e/Math.sqrt(1 - e*e);//Called e prime in reference
    set @esq = (1.0 - (@b/@a)*(@b/@a)); --e squared for use in expansions
    --esq = (1 - (b/a)*(b/a));//e squared for use in expansions
    set @e0sq = @e*@e/(1.0-@e*@e); --e0 squared - always even powers
    --e0sq = e*e/(1-e*e);// e0 squared - always even powers
    set @zcm = 3.0 + 6.0*(@utmz-1.0) - 180.0; --Central meridian of zone
    --zcm = 3 + 6*(utmz-1) - 180;//Central meridian of zone
    set @e1 = (1.0 - SQRT(1.0 - @e*@e))/(1.0 + SQRT(1.0 - @e*@e)); --Called e1 in USGS PP 1395 also
    --e1 = (1 - Math.sqrt(1 - e*e))/(1 + Math.sqrt(1 - e*e));//Called e1 in USGS PP 1395 also
    set @M = 0.0 + @y / @k0; --Arc length along standard meridian
    --M = M0 + y/k0;//Arc length along standard meridian. 
    set @mu = @M/(@a*(1.0 - @esq*(1.0/4.0 + @esq*(3.0/64.0 + 5.0*@esq/256.0))));
    --mu = M/(a*(1 - esq*(1/4 + esq*(3/64 + 5*esq/256))));
    set @phi1 = @mu + @e1*(3.0/2.0 - 27.0*@e1*@e1/32.0)*SIN(2.0*@mu) + @e1*@e1*(21.0/16.0 - 55.0*@e1*@e1/32.0)*SIN(4.0*@mu); --Footprint Latitude
    --phi1 = mu + e1*(3/2 - 27*e1*e1/32)*Math.sin(2*mu) + e1*e1*(21/16 -55*e1*e1/32)*Math.sin(4*mu);//Footprint Latitude
    set @phi1 = @phi1 + @e1*@e1*@e1*(SIN(6.0*@mu)*151.0/96.0 + @e1*SIN(8.0*@mu)*1097.0/512.0);
    --phi1 = phi1 + e1*e1*e1*(Math.sin(6*mu)*151/96 + e1*Math.sin(8*mu)*1097/512);
    set @C1 = @e0sq*POWER(COS(@phi1),2.0);
    --C1 = e0sq*Math.pow(Math.cos(phi1),2);
    set @T1 = POWER(TAN(@phi1),2.0);
    --T1 = Math.pow(Math.tan(phi1),2);
    set @N1 = @a/SQRT(1.0-POWER(@e*SIN(@phi1),2.0));
    --N1 = a/Math.sqrt(1-Math.pow(e*Math.sin(phi1),2));
    set @R1 = @N1*(1.0-@e*@e)/(1.0-POWER(@e*SIN(@phi1),2.0));
    --R1 = N1*(1-e*e)/(1-Math.pow(e*Math.sin(phi1),2));
    set @D = (@x-500000.0)/(@N1*@k0);
    --D = (x-500000)/(N1*k0);
    set @phi = (@D*@D)*(1.0/2.0 - @D*@D*(5.0 + 3.0*@T1 + 10.0*@C1 - 4.0*@C1*@C1 - 9.0*@e0sq)/24.0);
    --phi = (D*D)*(1/2 - D*D*(5 + 3*T1 + 10*C1 - 4*C1*C1 - 9*e0sq)/24);
    set @phi = @phi + POWER(@D,6.0)*(61.0 + 90.0*@T1 + 298.0*@C1 + 45.0*@T1*@T1 - 252.0*@e0sq - 3.0*@C1*@C1)/720.0;
    --phi = phi + Math.pow(D,6)*(61 + 90*T1 + 298*C1 + 45*T1*T1 -252*e0sq - 3*C1*C1)/720;
    set @phi = @phi1 - (@N1*TAN(@phi1)/@R1)*@phi;
    --phi = phi1 - (N1*Math.tan(phi1)/R1)*phi;


    set @latitude = FLOOR(1000000.0*@phi/@drad)/1000000.0;

    set @lng = @D*(1.0 + @D*@D*((-1.0 - 2.0*@T1 - @C1)/6.0 + @D*@D*(5.0 - 2.0*@C1 + 28.0*@T1 - 3.0*@C1*@C1 + 8.0*@e0sq + 24.0*@T1*@T1)/120))/COS(@phi1);
    set @lngd = @zcm+@lng/@drad;
    set @longitude = FLOOR(1000000.0*@lngd)/1000000.0;


    return @latitude;
end
go
drop function UF_utm_to_long
go
create function UF_utm_to_long(@utmz float, @x float, @y float) returns float
as
begin
    --Based on code from this page: http://www.uwgb.edu/dutchs/usefuldata/ConvertUTMNoOZ.HTM
    declare @latitude float;
    declare @longitude float;
    set @latitude = 0.00;
    set @longitude = 0.00;

    --Declarations
    declare @a float;
    declare @f float;
    declare @drad float;
    declare @k0 float;
    declare @b float;
    declare @e float;
    declare @e0 float;
    declare @esq float;
    declare @e0sq float;
    declare @zcm float;
    declare @e1 float;
    declare @M float;
    declare @mu float;
    declare @phi1 float;
    declare @C1 float;
    declare @T1 float;
    declare @N1 float;
    declare @R1 float;
    declare @D float;
    declare @phi float;
    declare @lng float;
    declare @lngd float;

    --Datum Info here: Name, a, b, f, 1/f
    --WGS 84    6,378,137.0 6356752.314 0.003352811 298.2572236

    set @a = 6378137.0;
    set @b = 6356752.314;
    set @f = 0.003352811;
    set @drad = PI()/180.0;
    set @k0 = 0.9996; --scale on central meridian

    set @e = SQRT(1.0 - (@b/@a)*(@b/@a)); --Eccentricity
    --e = Math.sqrt(1 - (b/a)*(b/a));//eccentricity
    set @e0 = @e/SQRT(1.0 - @e*@e); --Called e prime in reference
    --e0 = e/Math.sqrt(1 - e*e);//Called e prime in reference
    set @esq = (1.0 - (@b/@a)*(@b/@a)); --e squared for use in expansions
    --esq = (1 - (b/a)*(b/a));//e squared for use in expansions
    set @e0sq = @e*@e/(1.0-@e*@e); --e0 squared - always even powers
    --e0sq = e*e/(1-e*e);// e0 squared - always even powers
    set @zcm = 3.0 + 6.0*(@utmz-1.0) - 180.0; --Central meridian of zone
    --zcm = 3 + 6*(utmz-1) - 180;//Central meridian of zone
    set @e1 = (1.0 - SQRT(1.0 - @e*@e))/(1.0 + SQRT(1.0 - @e*@e)); --Called e1 in USGS PP 1395 also
    --e1 = (1 - Math.sqrt(1 - e*e))/(1 + Math.sqrt(1 - e*e));//Called e1 in USGS PP 1395 also
    set @M = 0.0 + @y / @k0; --Arc length along standard meridian
    --M = M0 + y/k0;//Arc length along standard meridian. 
    set @mu = @M/(@a*(1.0 - @esq*(1.0/4.0 + @esq*(3.0/64.0 + 5.0*@esq/256.0))));
    --mu = M/(a*(1 - esq*(1/4 + esq*(3/64 + 5*esq/256))));
    set @phi1 = @mu + @e1*(3.0/2.0 - 27.0*@e1*@e1/32.0)*SIN(2.0*@mu) + @e1*@e1*(21.0/16.0 - 55.0*@e1*@e1/32.0)*SIN(4.0*@mu); --Footprint Latitude
    --phi1 = mu + e1*(3/2 - 27*e1*e1/32)*Math.sin(2*mu) + e1*e1*(21/16 -55*e1*e1/32)*Math.sin(4*mu);//Footprint Latitude
    set @phi1 = @phi1 + @e1*@e1*@e1*(SIN(6.0*@mu)*151.0/96.0 + @e1*SIN(8.0*@mu)*1097.0/512.0);
    --phi1 = phi1 + e1*e1*e1*(Math.sin(6*mu)*151/96 + e1*Math.sin(8*mu)*1097/512);
    set @C1 = @e0sq*POWER(COS(@phi1),2.0);
    --C1 = e0sq*Math.pow(Math.cos(phi1),2);
    set @T1 = POWER(TAN(@phi1),2.0);
    --T1 = Math.pow(Math.tan(phi1),2);
    set @N1 = @a/SQRT(1.0-POWER(@e*SIN(@phi1),2.0));
    --N1 = a/Math.sqrt(1-Math.pow(e*Math.sin(phi1),2));
    set @R1 = @N1*(1.0-@e*@e)/(1.0-POWER(@e*SIN(@phi1),2.0));
    --R1 = N1*(1-e*e)/(1-Math.pow(e*Math.sin(phi1),2));
    set @D = (@x-500000.0)/(@N1*@k0);
    --D = (x-500000)/(N1*k0);
    set @phi = (@D*@D)*(1.0/2.0 - @D*@D*(5.0 + 3.0*@T1 + 10.0*@C1 - 4.0*@C1*@C1 - 9.0*@e0sq)/24.0);
    --phi = (D*D)*(1/2 - D*D*(5 + 3*T1 + 10*C1 - 4*C1*C1 - 9*e0sq)/24);
    set @phi = @phi + POWER(@D,6.0)*(61.0 + 90.0*@T1 + 298.0*@C1 + 45.0*@T1*@T1 - 252.0*@e0sq - 3.0*@C1*@C1)/720.0;
    --phi = phi + Math.pow(D,6)*(61 + 90*T1 + 298*C1 + 45*T1*T1 -252*e0sq - 3*C1*C1)/720;
    set @phi = @phi1 - (@N1*TAN(@phi1)/@R1)*@phi;
    --phi = phi1 - (N1*Math.tan(phi1)/R1)*phi;

    set @latitude = FLOOR(1000000.0*@phi/@drad)/1000000.0;

    set @lng = @D*(1.0 + @D*@D*((-1.0 - 2.0*@T1 - @C1)/6.0 + @D*@D*(5.0 - 2.0*@C1 + 28.0*@T1 - 3.0*@C1*@C1 + 8.0*@e0sq + 24.0*@T1*@T1)/120))/COS(@phi1);
    set @lngd = @zcm+@lng/@drad;
    set @longitude = FLOOR(1000000.0*@lngd)/1000000.0;


    return @longitude;
end
like image 42
SQLGuru Avatar answered Nov 04 '22 12:11

SQLGuru


There are hundreds of different coordinate systems - Easting/Northing and Lat/Long are types of coordinates, but they're not enough to uniquely identify the system from which those coordinates are obtained.

You need to either have an EPSG code (e.g. 4326, 4269, 27700, 32701) or, alternatively, the details of the spatial reference system (the datum, projection, prime meridian and unit of measure) for both your source and chosen destination format. You mention "GPS" in your question title, so I'm assuming that the lat/lon you require is defined relative to the WGS84 datum used by global positioning systems, but there are still many projections of that datum that could lead to different Easting/Northing values.

Once you've got the details of the projection used, you can perform the transformation in code using something like the Proj.4 library (http://trac.osgeo.org/proj/)

like image 31
Alastair Aitchison Avatar answered Nov 04 '22 13:11

Alastair Aitchison