2011-10-24 18 views
12

Mam współrzędne położenia w formacie wschód/północ, ale muszę go przekonwertować na odpowiedni długi czas, aby wyśrodkować go na mapach bing. Jakąkolwiek formułę lub szczegóły dotyczące konwersji wschód/północ do lat/lon?Wschodnia północ do szerokości geograficznej

EDIT: Aby być bardziej szczegółowe, muszę konwertować SVY21 współrzędne do WGS84

Odpowiedz

13

Eastings a północy to odpowiednio odległości na wschód i na północ od punktu bazowego. Punktem bazowym jest zwykle szerokość i długość geograficzna, a wschody i północy są zwykle wyrażane w metrach lub stopach. Wschodnia i północna jest jednak zwykle kompensowana określoną wartością, aby uczynić je dodatnimi i pozwolić im wyrazić miejsca na zachód i południe od punktu bazowego.

Generalnie, konwersja z jednego układu współrzędnych na inny nie jest prosta, ponieważ obie mogą mieć różne elipsoidy (modele Ziemi) i odniesienia. Jak rozumiem, formuły do ​​konwersji z jednego układu współrzędnych na inny są dość złożone.

SVY21, jednak używa dokładnie tego samego punktu odniesienia i elipsoidy jak WGS84, dzięki czemu zadanie jest prostsze. W SVY21 punktem bazowym dla wschodów i północów jest Base 7 at Pierce Reservoir, 1 °. 22 min. 02.9154 sek. północ i 103 stopni. 49 min 31,9752 sek. na wschód (to jest szerokość geograficzna około 1,3674765 stopni i długość geograficzna około 103,8255487 stopni, jednak dobrze znany tekst wykorzystuje odpowiednio 1,3666 ... stopni i 103.8333 ... stopni). Przesunięcie na wschód wynosi 28001.642 metrów, a przesunięcie na północ to 38744.572 metrów. Kod EPSG to 3414. Przyjmę, że wasze wschody i północy wyrażone są w metrach.

Od SVY21 wykorzystuje ten sam system jak WGS84, wszystko co musisz zrobić, to:

  • Odejmij X i Y od ich wartości offsetu. (Wartości będą podane w metrach.)
  • Znajdź długość geograficzną podanego punktu, znajdując punkt docelowy, biorąc pod uwagę punkt bazowy, bezwzględną wartość wschodu i namiar o 90 stopni, jeśli wschód jest dodatni lub 270 stopnie, jeśli są ujemne. This link zawiera odpowiednie formuły. (Do tego obliczenia można użyć albo sferycznego prawa cosinusów, jak podano w sekcji "Punkt docelowy podana odległość i namiar od punktu początkowego", albo dokładniejszej Vincenty's direct formula. Pierwsza strona linkowana jednak nie używa Formuła Haversine dla tego obliczenia.)
  • Znajdź szerokość geograficzną podanego punktu, znajdując punkt docelowy, biorąc pod uwagę punkt bazowy, bezwzględną wartość północy i namiar 0 stopni, jeśli północ jest dodatnia lub 180 stopni, jeśli to jest negatywne.
+0

Czy odnosisz się do formuły Haversine'a? A może ze wschodu na północ do lat/lon? – Bahamut

+0

Nie, mam na myśli sferyczne prawo cosinusów, choć może również działać z bezpośrednią formułą Vincenty'ego. –

+0

dzięki, spróbuję. – Bahamut

3

Istnieją setki różnych układów współrzędnych - wsch/Północne a Lat/Długi są rodzaje współrzędnych, ale oni nie są wystarczające do jednoznacznej identyfikacji systemu, z którego uzyskuje się te współrzędne.

Musisz mieć kod EPSG (np. 4326, 4269, 27700, 32701) lub, alternatywnie, dane przestrzennego układu odniesienia (punkt odniesienia, rzut, południk główny i jednostka miary) dla źródła i wybrany format docelowy. W tytule pytania wspominasz "GPS", więc zakładam, że wymagane wyrażenie/dług jest zdefiniowane w odniesieniu do układu odniesienia WGS84 używanego przez globalne systemy pozycjonowania, ale wciąż istnieje wiele prognoz tego punktu odniesienia, które mogą prowadzić do różnych Wartości wschodnie/północne.

Gdy masz szczegóły projekcji używany, można przeprowadzić transformację w kodzie za pomocą czegoś jak biblioteki Proj.4 (http://trac.osgeo.org/proj/)

+0

wyniki, które otrzymuję są w formacie SVY21 i muszę je przekonwertować na WGS84 i narysować na mapach bing. Czy to możliwe przy użyciu biblioteki? – Bahamut

2

Jest to stosunkowo proste rozwiązanie w Perl:

Tak, przede wszystkim, upewnij się, że masz zainstalowane Perl. Następnie zainstalować cztery następujące moduły:

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

Można to zrobić na kilka sposobów. Oto jak to zrobiłem:

# 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. Pobierz dane GB.

Pobierz zestaw danych "Code-Point® Open" Wielkiej Brytanii, klikając tutaj i postępując zgodnie z instrukcjami. Po pobraniu codepo_gb.zip można wyodrębnić je w następujący sposób:

rozpakuj codepo_gb.zip

Zakładając, że rozpakowane pliki są teraz w bieżącym katalogu, można następnie uruchom następujące perlscript w celu do przeanalizowania danych, wyodrębnij GB eastings/northings i przekonwertuj je na szerokość/długość geograficzną.

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

(Aby zadzwonić, zapisz ostatni blok kodu do .pl pliku, a następnie zadzwonić perl script.pl your.csv ... również pamiętać, $ x [0], $ x [10] i [11 $ x ] powinny być numery kolumn kod pocztowy, X i Y odpowiednio.

pełny kredyt http://baroque.posterous.com/uk-postcode-latitudelongitude

+0

byłby dobry, ale ja wolę obliczenia i/lub formuły konwersji na przenośność. po drugie, svy21 jest singapurem, więc brytyjska konwersja SVY na WGS84 nie ma zastosowania. – Bahamut

+0

Moja zła, mam nadzieję, że może pomóc komuś, bo natknąłem się na to pytanie, gdy w pośpiechu, aby znaleźć rozwiązanie i to była najłatwiejsza metoda brytyjskiej konwersji. – rickyduck

+1

prawda. dlatego nie odrzuciłem go, ponieważ ktoś może uznać to za przydatne. – Bahamut

2

mam przeliczone implementację JavaScript do funkcji T-SQL dla WGS84 do szerokości/wartości długości geograficznej. Zapraszam do użyj, jak chcesz, jeśli potrzebujesz innego układu współrzędnych, sprawdź University of Wisconsin - Strona internetowa Green Bay, której używałem jako źródła i otrzymuję zaktualizowane stałe.

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 
Powiązane problemy