2011-10-24 51 views
12

Tôi có tọa độ vị trí ở định dạng hướng đông/hướng bắc nhưng tôi cần phải chuyển đổi nó sang vị trí thích hợp để định vị nó trong bản đồ bing. Bất kỳ công thức hoặc chi tiết làm thế nào để chuyển đổi easting/northing để lat/lon?Hướng đông về kinh độ vĩ độ

EDIT: Để cụ thể hơn, tôi cần phải chuyển đổi SVY21 phối đến để WGS84

Trả lời

13

Eastings và phía bắc là khoảng cách về phía đông và phía bắc, tương ứng, của một điểm cơ sở. Điểm gốc thường là vĩ độ và kinh độ, và hướng đông và hướng bắc thường được biểu thị bằng mét hoặc feet. Tuy nhiên, hướng đông và hướng bắc thường được bù đắp một giá trị cụ thể để làm cho chúng dương và cho phép chúng diễn tả các địa điểm phía tây và nam của điểm gốc.

Nói chung, việc chuyển đổi từ một hệ tọa độ này sang hệ tọa độ khác không đơn giản, vì cả hai có thể có các elipsoids khác nhau (mô hình Trái Đất) và các khối dữ liệu. Theo tôi hiểu, các công thức để chuyển đổi từ một hệ thống tọa độ này sang hệ thống khác là khá phức tạp. Tuy nhiên,

SVY21, sử dụng cùng một mức dữ liệu và ellipsoid giống như WGS84, làm cho tác vụ trở nên đơn giản hơn. Trong SVY21, điểm cơ sở cho hướng đông và hướng bắc là Base 7 at Pierce Reservoir, 1 độ. 22 phút 02.9154 giây phía bắc và 103 độ. 49 phút 31.9752 giây phía đông (nghĩa là vĩ độ khoảng 1.3674765 độ và kinh độ khoảng 103.8255487 độ; văn bản nổi tiếng, tuy nhiên, sử dụng 1.3666 ... độ và 103.8333 ... độ, tương ứng). Mức chênh lệch cho hướng đông là 28001.642 mét, và độ lệch cho hướng bắc là 38744.572 mét. Mã EPSG là 3414. Tôi sẽ giả định hướng đông và hướng bắc của bạn được biểu thị bằng mét.

Kể từ SVY21 sử dụng hệ thống tương tự như WGS84, tất cả các bạn phải làm là:

  • Trừ đường về hướng đông và đường đi về phía bắc do bù đắp giá trị tương ứng của họ. (Các giá trị sẽ tính bằng mét.)
  • Tìm kinh độ của điểm đã cho bằng cách tìm điểm đích cho điểm gốc, giá trị tuyệt đối của hướng đông và vòng 90 độ nếu hướng đông là dương hoặc 270 độ nếu nó âm. This link chứa các công thức có liên quan. (Đối với phép tính này, bạn có thể sử dụng hoặc là định luật hình cầu của các cosin, như được đưa ra trong phần "Điểm đích được đưa ra và mang từ điểm bắt đầu", hoặc chính xác hơn Vincenty's direct formula. Tuy nhiên, trang liên kết đầu tiên không sử dụng Công thức Haversine cho phép tính này.)
  • Tìm vĩ độ của điểm đã cho bằng cách tìm điểm đích cho điểm gốc, giá trị tuyệt đối của hướng bắc và vòng bi 0 độ nếu hướng bắc là dương hoặc 180 độ nếu nó tiêu cực.
+0

bạn đang đề cập đến công thức của Haversine? Làm thế nào về từ đông/bắc đến lat/lon? – Bahamut

+0

Không, tôi đang đề cập đến định luật hình cầu của cosin, mặc dù nó cũng có thể làm việc với công thức trực tiếp của Vincenty. –

+0

cảm ơn tôi sẽ thử. – Bahamut

3

Có hàng trăm khác nhau phối hợp hệ thống - hướng đông/Hướng về phía bắc và Lat/Long là loại tọa độ, nhưng chúng không đủ để xác định duy nhất hệ thống thu được các tọa độ đó.

Bạn cần phải có mã EPSG (ví dụ: 4326, 4269, 27700, 32701) hoặc, theo cách khác, chi tiết của hệ thống tham chiếu không gian (mốc, phép chiếu, kinh tuyến chính và đơn vị đo) cho cả nguồn của bạn và chọn định dạng đích. Bạn đề cập đến "GPS" trong tiêu đề câu hỏi của bạn, vì vậy tôi giả định rằng lat/lon bạn yêu cầu được xác định tương ứng với dữ liệu WGS84 được sử dụng bởi các hệ thống định vị toàn cầu, nhưng vẫn còn nhiều dự đoán về dữ liệu đó có thể dẫn đến khác nhau Các giá trị Easting/Northing.

Một khi bạn đã có các chi tiết của chiếu được sử dụng, bạn có thể thực hiện việc chuyển đổi trong mã sử dụng một cái gì đó như thư viện PROJ.4 (http://trac.osgeo.org/proj/)

+0

kết quả tôi nhận được ở định dạng SVY21 và tôi cần chuyển đổi nó thành WGS84 và vẽ nó trong bản đồ bing. Có thể sử dụng thư viện đó không? – Bahamut

2

Có một giải pháp tương đối đơn giản trong perl:

Vì vậy, trước hết, hãy chắc chắn bạn có Perl được cài đặt. Sau đó, cài đặt sau bốn mô-đun:

Geo :: HelmertTransform Địa lý :: NationalGrid CAM :: DBF mySociety :: GeoUtil

Bạn có thể làm điều này trong một số cách khác nhau. Đây là cách tôi đã làm nó:

# 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. Lấy dữ liệu GB.

Tải xuống bộ dữ liệu "Code-Point® Open" của Vương quốc Anh bằng cách nhấp vào đây và làm theo hướng dẫn. Một khi bạn đã tải về codepo_gb.zip bạn có thể trích xuất nó như sau:

unzip codepo_gb.zip

Giả sử rằng các tập tin đã được giải nén hiện nay có trong thư mục hiện hành, sau đó bạn có thể chạy các PerlScript sau theo thứ tự để phân tích cú pháp dữ liệu, hãy trích xuất GB phía đông/hướng bắc và chuyển đổi chúng thành vĩ độ/kinh độ.

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"; 
} 

(Để gọi, lưu các khối mã cuối cùng vào một tập tin .pl, và sau đó gọi perl script.pl your.csv ... cũng nhớ, $ x [0], $ x [10] và $ x [11 ] nên là số cột của mã bưu điện, đường về hướng đông và đường đi về hướng bắc tương ứng.

tín dụng đầy đủ để http://baroque.posterous.com/uk-postcode-latitudelongitude

+0

sẽ là tốt nhưng tôi thích tính toán và/hoặc công thức cho việc chuyển đổi cho tính di động. thứ hai, svy21 là singapore vì vậy chuyển đổi SVY sang WGS84 của Anh không áp dụng được. – Bahamut

+0

Của tôi xấu, hy vọng nó có thể giúp một ai đó mặc dù tôi vấp khi câu hỏi này trong khi vội vàng để tìm một giải pháp và đây là phương pháp dễ nhất cho chuyển đổi của Anh. – rickyduck

+1

đúng. đó là lý do tại sao tôi đã không downvote nó kể từ khi ai đó có thể tìm thấy điều này hữu ích quá. – Bahamut

2

tôi đã chuyển đổi một thực hiện chức năng Javascript vào T-SQL cho WGS84 Latitude/Longitude giá trị. Hãy sử dụng như bạn thấy phù hợp.Nếu bạn cần một hệ thống tọa độ khác nhau, hãy kiểm tra Đại học Wisconsin - Trang web Green Bay mà tôi đã sử dụng làm nguồn và nhận các hằng số được cập nhật.

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/([email protected]*@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*([email protected]*@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 = @[email protected]/@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/([email protected]*@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*([email protected]*@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 = @[email protected]/@drad; 
    set @longitude = FLOOR(1000000.0*@lngd)/1000000.0; 


    return @longitude; 
end 
Các vấn đề liên quan