J'ai des coordonnées de localisation au format est/nord mais je dois le convertir en lat approprié pour le centrer dans les cartes bing. Une formule ou des détails sur la conversion de l'abscisse/ordonnée en lat/lon?
EDIT: Pour être plus précis, j'ai besoin de convertir les coordonnées SVY21 en WGS84
Les abscisses et les ordonnées sont les distances à l'est et au nord, respectivement, d'un point de base. Le point de base est généralement une latitude et une longitude, et les abscisses et les ordonnées sont normalement exprimées en mètres ou en pieds. L'abscisse et l'ordonnée, cependant, sont généralement compensées par une valeur particulière pour les rendre positives et leur permettre d'exprimer des endroits à l'ouest et au sud du point de base.
En général, la conversion d'un système de coordonnées à un autre n'est pas simple, car les deux peuvent avoir des ellipsoïdes (modèles terrestres) et des datums différents. Si je comprends bien, les formules de conversion d'un système de coordonnées à un autre sont assez complexes.
SVY21 , cependant, utilise exactement le même datum et ellipsoïde que WGS84, ce qui rend la tâche plus simple. Dans SVY21, le point de base pour les abscisses et les ordonnées est Base 7 au réservoir Pierce , 1 deg. 22 min. 02.9154 sec. nord et 103 deg. 49 min 31.9752 sec. est (c'est-à-dire une latitude d'environ 1,3674765 degrés et une longitude d'environ 103,8255487 degrés; le texte bien connu, cependant, utilise 1,3666 ... degrés et 103,8333 ... degrés, respectivement). Le décalage pour l'abscisse est de 28001,642 mètres et le décalage pour l'ordonnée est de 38744,572 mètres. Le code EPSG est 3414. Je suppose que vos abscisses et ordonnées sont exprimées en mètres.
Étant donné que SVY21 utilise le même système que WGS84, tout ce que vous avez à faire est de:
Il existe des centaines de systèmes de coordonnées différents - Est/Nord et Lat/Long sont types de coordonnées, mais ils ne sont pas suffisants pour identifier de manière unique le système à partir duquel ces coordonnées sont obtenues.
Vous devez avoir un code EPSG (par exemple 4326, 4269, 27700, 32701) ou, alternativement, les détails du système de référence spatiale (le datum, la projection, le méridien principal et l'unité de mesure) pour votre source et le format de destination choisi . Vous mentionnez "GPS" dans le titre de votre question, je suppose donc que le lat/lon dont vous avez besoin est défini par rapport au datum WGS84 utilisé par les systèmes de positionnement global, mais il existe encore de nombreuses projections de ce datum qui pourraient conduire à des abaissements différents./Valeurs d'ordonnée.
Une fois que vous avez les détails de la projection utilisée, vous pouvez effectuer la transformation en code en utilisant quelque chose comme la bibliothèque Proj.4 (http://trac.osgeo.org/proj/)
J'ai converti une implémentation Javascript en fonctions T-SQL pour le WGS84 en valeurs Latitude/Longitude. N'hésitez pas à l'utiliser comme bon vous semble. Si vous avez besoin d'un système de coordonnées différent, consultez la page Web de l'Université du Wisconsin - Green Bay que j'ai utilisée comme source et obtenez les constantes mises à jour.
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
Il existe une solution relativement simple en Perl:
Donc, tout d'abord, assurez-vous que Perl est installé. Ensuite, installez les quatre modules suivants:
Géo :: HelmertTransform Geography :: NationalGrid CAM :: DBF mySociety :: GeoUtil
Vous pouvez le faire de plusieurs manières. Voici comment je l'ai fait:
# 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'
- Obtenez des données GB.
Téléchargez l'ensemble de données "Code-Point® Open" de Grande-Bretagne en cliquant ici et en suivant les instructions. Une fois que vous avez téléchargé codepo_gb.Zip, vous pouvez l'extraire comme suit:
décompressez codepo_gb.Zip
En supposant que les fichiers décompressés se trouvent maintenant dans le répertoire en cours, vous pouvez ensuite exécuter le perlscript suivant afin d'analyser les données, d'extraire les abscisses/ordonnées du Go et de les convertir en 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";
}
(Pour appeler, enregistrez le dernier bloc de code dans un fichier .pl, puis appelez Perl script.pl your.csv
... rappelez-vous également que $ x [0], $ x [10] et $ x [11] doivent être les numéros de colonne du code postal, de l'abscisse et de l'ordonnée respectivement.
Crédit complet à http://baroque.posterous.com/uk-postcode-latitudelongitude