The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# Toby Thurston -- 20 Jan 2016 

# test a known location converts correctly

use Geo::Coordinates::OSGB qw/ll_to_grid grid_to_ll set_default_shape/;
use Geo::Coordinates::OSGB::Grid qw/parse_grid format_grid format_grid_GPS/;

use Test::More tests => 29;

# First a round trip using WGS84
# from the sw corner of OS Explorer sheet 161 (Cobham, Surrey)
is(sprintf("%d %d", ll_to_grid(51+20/60, -25/60)), "510399 160549", "SW corner of B:161, near Chobham");
is(sprintf("%g %g", grid_to_ll(510399,160549)), sprintf("%g %g", 51+20/60, -25/60), 'Chobham, back again');

# Now some look ups using OSGB36 through out, because the LL printed on OS maps is not based on WGS84
# This routine not documented in the main module, but it's use is hopefully obvious.
set_default_shape('OSGB36');

is(format_grid_GPS(ll_to_grid(57+55/60, -305/60)),         'NH 17379 96054',         'Hills above Loch Achall, Sheet A:20'); 
is(format_grid_GPS(ll_to_grid(51.5,0)),                    'TQ 38805 79845',         'Greenwich');                           
is(format_grid_GPS(ll_to_grid(0,51.5)),                    'TQ 38805 79845',         'Reversed arguments');                  
is(ll_to_grid(51.5,0),                                     '538805.837 179845.817',  'scalar context');                      
is(format_grid_GPS(ll_to_grid({ lon => 0, lat => 51.5})),  'TQ 38805 79845',         'keyword arguments');                   
is(format_grid_GPS(ll_to_grid(59,-3)),                     'HY 42554 12927',         'Kirkwall');                            
is(format_grid_GPS(ll_to_grid(51+40/60,1)),                'TM 07436 00745',         'Foulness Sands');                      
is(format_grid_GPS(ll_to_grid(51,1)),                      'TR 10468 26633',         'St Mary\'s Bay');                      

is(ll_to_grid(49,       -2    ), "400000.000 -100000.000", 'True origin');
is(ll_to_grid(52,       -2    ), "400000.000 233553.731",  'On central meridian');
is(ll_to_grid(56+55/60, -5.25 ), "202190.386 785279.519",  "Meall a Phubuill");

# and now a boggy path just north of Glendessary in Lochaber
# OS Sheet 40 topright corner.  A graticule intersection at
# 57N 5o20W is marked.  GR measured from the map.
is( sprintf("%g %g", grid_to_ll(197575,794790)), "57 -5.3333", "Glendessary");
is( sprintf("%g %g", grid_to_ll(269995, 68361)), "50.5 -3.83333", "Scorriton");
is( sprintf("%g %g", grid_to_ll(400000,122350)), "51 -2", "Cranbourne Chase");
is( sprintf("%g %g", grid_to_ll(323223,1004000)), "58.9168 -3.33333", "Hoy");
is( sprintf("%g %g", grid_to_ll(217380,896060)), "57.9167 -5.08333", "Glen Achcall");
is( sprintf("%g %g", grid_to_ll({e => 217380, n => 896060})), "57.9167 -5.08333", "Keyword arguments for Glen Achcall");

# switch back to WGS84
set_default_shape('WGS84');

is(ll_to_grid(51.3,  0),  "539524.823 157551.911", "Somewhere in London");
is(ll_to_grid(51.3,-10),  "-157250 186110",        "Far west");
is(ll_to_grid(61.3,  0),  "507242 1270342",        "Far north");
is(ll_to_grid(56.75,-7),  "94471 773206",          "In sea north-west of Coll");
is(ll_to_grid(51.5, -2.1), "393154.801 177900.605", 'Example from docs');

# Finally some more round trips 

sub test_me {
    return format_grid(ll_to_grid(grid_to_ll(parse_grid($_[0]))), {form => 'GPS'});
}

is( test_me('NM9750194802'), 'NM 97501 94802' ,"NM975948");
is( test_me('NH0730306004'), 'NH 07303 06004' ,"NH073060");
is( test_me('SX7000568206'), 'SX 70005 68206' ,"SX700682");
is( test_me('TQ1030760608'), 'TQ 10307 60608' ,"TQ103606");
is( test_me('HY5540930010'), 'HY 55409 30010' ,"HY554300");