Easting northing to latitude longitude

谁说我不能喝 提交于 2019-11-26 21:15:00

问题


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


回答1:


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, 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, however, uses 1.3666... degrees and 103.8333... degrees, respectively). 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 link contains the relevant formulas. (For this calculation, you can use either the spherical law of cosines, as given in the section "Destination point given distance and bearing from start point", or the more accurate Vincenty's direct formula. The first linked page, however, doesn't use the Haversine formula for this calculation.)
  • 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.



回答2:


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/)




回答3:


There is a relatively simple solution in perl:

So, first of all, make sure you have Perl installed. Then, install the following four modules:

Geo::HelmertTransform Geography::NationalGrid CAM::DBF mySociety::GeoUtil

You can do this in a number of ways. Here's how I did it:

# Geo::HelmertTransform 
wget http://search.cpan.org/CPAN/authors/id/M/MY/MYSOCIETY/Geo-HelmertTransform-1.13.tar.gz 
tar xzf Geo-HelmertTransform-1.13.tar.gz  
perl Makefile.PL 
make 
make install

# Geography::NationalGrid 
http://search.cpan.org/CPAN/authors/id/P/PK/PKENT/Geography-NationalGrid-1.6.tar.gz 
tar xzf Geography-NationalGrid-1.6.tar.gz 
perl Makefile.PL 
make 
make install

# CAM::DBF 
wget http://search.cpan.org/CPAN/authors/id/C/CL/CLOTHO/CAM-DBF-1.02.tgz 
tar xzf CAM-DBF-1.02.tgz 
perl Makefile.PL 
make 
make install

# mySociety::GeoUtil
# See: http://parlvid.mysociety.org:81/os/ -> https://github.com/mysociety/commonlib/blob/master/perllib/mySociety/GeoUtil.pm
mkdir -p mySociety 
wget -O mySociety/GeoUtil.pm 'https://raw.githubusercontent.com/mysociety/commonlib/master/perllib/mySociety/GeoUtil.pm'
  1. Get GB data.

Download the Great Britain "Code-Point® Open" dataset by clicking here and following the instructions. Once you've downloaded codepo_gb.zip you can extract it as follows:

unzip codepo_gb.zip

Presuming that the unzipped files are now in the current directory, you can then run the following perlscript in order to parse the data, extract the GB eastings/northings and convert them to latitude/longitude.

use strict;
use mySociety::GeoUtil qw/national_grid_to_wgs84/;

while (<>) {
    my @x=split(/,/); # split csv
    my ($pc, $east, $north) = ($x[0], $x[10], $x[11]);
    $pc=~s/\"//g; # remove quotes around postcode
    my ($lat, $lng) = national_grid_to_wgs84($east, $north, "G"); # "G" means Great Britain
    print "$pc,$lat,$lng\n";
}

(To call, save the last code block to a .pl file, and then call perl script.pl your.csv ... also remember, $x[0], $x[10] and $x[11] should be the column numbers of postcode, easting and northing respectively.

Full credit to http://baroque.posterous.com/uk-postcode-latitudelongitude




回答4:


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


来源:https://stackoverflow.com/questions/7872539/easting-northing-to-latitude-longitude

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!