#! perl -w
# Toby Thurston --- 16 Apr 2009
use strict;
# This test data is taken directly from the OS publications about OSTN02
# StationName Eeg°in'9_Lat_Sec EDeg°in'_Long_Sec ETRS89_Height ETRS89_East ETRS89_North OSGB36_East OSGB36_North ODN_Height
my %test_input = (
Scilly => [ 49.922263943333, -6.299777527222, 100.000, 91400.000, 11400.000, 91492.135, 11318.801, 46.882 ],
Liz1 => [ 49.960061383056, -5.203046100278, 124.269, 170277.189, 11652.895, 170370.706, 11572.404, 71.222 ],
Plym => [ 50.438858254722, -4.108645639722, 215.251, 250265.789, 62095.883, 250359.798, 62016.567, 163.081 ],
Scp1 => [ 50.575636651667, -1.297822771389, 94.688, 449719.403, 75415.594, 449816.359, 75335.859, 48.571 ],
OSHQ => [ 50.931279377500, -1.450514340556, 100.405, 438614.045, 114871.192, 438710.908, 114792.248, 54.029 ],
Nfo1 => [ 51.374470259167, 1.444547306944, 99.439, 639720.224, 169645.824, 639821.823, 169565.856, 55.110 ],
Nas1 => [ 51.400782203889, -3.551283487222, 112.371, 292090.289, 168081.281, 292184.858, 168003.462, 60.615 ],
Bris => [ 51.427547433611, -2.544076186111, 104.018, 362174.408, 170056.500, 362269.979, 169978.688, 54.467 ],
Lond => [ 51.489365646111, -0.119925564167, 66.057, 530526.413, 178467.043, 530624.963, 178388.461, 20.518 ],
Carm => [ 51.858908967500, -4.308524766111, 81.351, 241030.731, 220409.858, 241124.573, 220332.638, 27.590 ],
Colc => [ 51.894366375278, 0.897243275000, 75.273, 599345.196, 225801.485, 599445.578, 225722.824, 30.192 ],
Nort => [ 52.251609509167, -0.912489570000, 131.594, 474237.874, 262125.333, 474335.957, 262047.752, 83.961 ],
Droi => [ 52.255293816389, -2.154586149444, 101.526, 389448.042, 261989.271, 389544.178, 261912.151, 51.977 ],
King => [ 52.751366874444, 0.401535476944, 66.431, 562079.805, 319862.042, 562180.535, 319784.993, 20.890 ],
Nott => [ 52.962191095000, -1.197476561667, 93.825, 453904.269, 340910.743, 454002.822, 340834.941, 45.253 ],
Dare => [ 53.344802806667, -2.640493207222, 88.411, 357359.683, 383364.152, 357455.831, 383290.434, 36.750 ],
Lyn1 => [ 53.416285157778, -4.289180693056, 100.776, 247865.448, 393566.264, 247958.959, 393492.906, 46.314 ],
Lyn2 => [ 53.416309251667, -4.289177926389, 100.854, 247865.718, 393568.938, 247959.229, 393495.580, 46.393 ],
Blac => [ 53.779110256944, -3.040454906944, 64.940, 331439.160, 431992.943, 331534.552, 431920.792, 12.636 ],
Leed => [ 53.800215199167, -1.663791675833, 215.609, 422143.679, 433891.207, 422242.174, 433818.699, 165.891 ],
IoMS => [ 54.086663180833, -4.634521685000, 84.366, 227685.882, 468918.331, 227778.318, 468847.386, 29.335 ],
Fla1 => [ 54.116851443333, -0.077731326667, 86.778, 525643.491, 470775.610, 525745.658, 470703.211, 41.217 ],
IoMN => [ 54.329195410556, -4.388491180000, 94.503, 244687.517, 495324.611, 244780.625, 495254.884, 39.891 ],
Carl => [ 54.895423405278, -2.938277414722, 93.541, 339824.598, 556102.504, 339921.133, 556034.759, 41.077 ],
Newc => [ 54.979122740000, -1.616576845556, 125.878, 424539.719, 565080.533, 424639.343, 565012.700, 76.551 ],
Glas => [ 55.853999529722, -4.296490155556, 71.617, 256247.486, 664760.292, 256340.914, 664697.266, 17.414 ],
Edin => [ 55.924782652500, -3.294792187778, 119.032, 319092.329, 671010.630, 319188.423, 670947.532, 66.362 ],
Mala => [ 57.006066965278, -5.828366926389, 68.494, 167542.805, 797124.153, 167634.190, 797067.142, 13.190 ],
Gir1 => [ 57.139025193056, -2.048560316111, 108.610, 397061.069, 805408.146, 397160.479, 805349.734, 58.902 ],
Inve => [ 57.486250003333, -4.219263989444, 66.178, 266961.481, 846233.646, 267056.756, 846176.969, 13.230 ],
Stkilda => [ 57.813518421667, -8.578544610278, 100.000, 9500.003, 899499.996, 9587.897, 899448.993, 43.424 ],
Flannan => [ 58.212622481389, -7.592555631111, 140.404, 71622.450, 938567.303, 71713.120, 938516.401, 83.594 ],
But1 => [ 58.515603618056, -6.260914556389, 115.026, 151874.984, 966535.331, 151968.641, 966483.777, 58.836 ],
Thur => [ 58.581204614444, -3.726310213056, 98.634, 299624.627, 967256.596, 299721.879, 967202.990, 46.011 ],
Ork_Main_Ork => [ 58.718937183056, -3.073926035278, 100.000, 337800.000, 981800.000, 337898.195, 981746.359, 48.631 ],
Ork_Main_Main => [ 58.721082864444, -3.137882873056, 100.000, 334100.000, 982100.000, 334198.101, 982046.419, 48.439 ],
Orkney => [ 59.037438710000, -3.214540010556, 100.000, 330300.000, 1017400.000, 330398.311, 1017347.013, 47.978 ],
SuleSkerry => [ 59.093350350833, -4.417576741667, 100.000, 261500.000, 1025500.000, 261596.767, 1025447.599, 46.347 ],
NorthRona => [ 59.096716177778, -5.827993408889, 140.716, 180766.824, 1029654.640, 180862.449, 1029604.111, 85.197 ],
FairIsle => [ 59.534707943333, -1.625169658333, 100.000, 421200.000, 1072200.000, 421300.513, 1072147.236, 50.951 ],
Sum1 => [ 59.854099142500, -1.274869112222, 149.890, 440623.592, 1107930.781, 440725.061, 1107878.445, 100.991 ],
Foula => [ 60.133080920833, -2.073828223611, 140.716, 395898.578, 1138780.346, 395999.656, 1138728.948, 89.901 ],
);
use Geo::Coordinates::OSTN02 qw/ETRS89_to_OSGB36 OSGB36_to_ETRS89/;
use Geo::Coordinates::OSGB qw/grid_to_ll ll_to_grid/;
use Test::Simple tests => 168;
for my $k (sort keys %test_input ) {
my ($lat,$lon, $z) = @{$test_input{$k}}[0,1,2];
my ($x,$y) = @{$test_input{$k}}[3,4];
my ($gotx, $goty) = ll_to_grid($lat,$lon,'ETRS89');
ok( $gotx == $x && $goty == $y , "Create X Y: $k: $x:$gotx $y:$goty" );
}
my $eps = 0.001000001; # within 1mm (near as dammit)
for my $k (sort keys %test_input ) {
my ($lat,$lon, $z) = @{$test_input{$k}}[0,1,2];
my ($x,$y) = @{$test_input{$k}}[3,4];
my ($e,$n,$h) = @{$test_input{$k}}[5,6,7];
my ($gote, $gotn, $goth) = ETRS89_to_OSGB36($x, $y, $z);
my $de = abs($gote-$e);
my $dn = abs($gotn-$n);
my $dh = abs($goth-$h);
ok( $de<$eps && $dn<$eps && $dh<$eps, "ETRS89_to_OSGB36: $k : $de $dn :: $dh" );
}
for my $k (sort keys %test_input ) {
my ($lat,$lon, $z) = @{$test_input{$k}}[0,1,2];
my ($x,$y) = @{$test_input{$k}}[3,4];
my ($e,$n,$h) = @{$test_input{$k}}[5,6,7];
my ($gotX, $gotY, $gotZ) = OSGB36_to_ETRS89($e, $n, $h);
my $dx = abs($gotX-$x);
my $dy = abs($gotY-$y);
my $dz = abs($gotZ-$z);
ok( $dx<$eps && $dx<$eps && $dx<$eps, "OSGB36_to_ETRS89: $k : $dx $dy :: $dz" );
}
$eps = 1.1e-6; # decimal degrees, which is about 20cm latitude, 10cm longitude
for my $k (sort keys %test_input ) {
my ($lat,$lon, $z) = @{$test_input{$k}}[0,1,2];
my ($x,$y) = @{$test_input{$k}}[3,4];
my ($e,$n,$h) = @{$test_input{$k}}[5,6,7];
my ($gotlat, $gotlon) = grid_to_ll($x,$y,'ETRS89');
ok( abs($lat-$gotlat)<$eps && abs($lon-$gotlon)<$eps, "back to LL: $k");
}