Provided by: libgeo-coordinates-osgb-perl_2.20-2_all bug

NAME

       Geo::Coordinates::OSGB::Background - Background and extended description

VERSION

       2.20

DESCRIPTION

       These notes are part of Geo::Coordinates::OSGB, a Perl implementation of latitude and longitude co-
       ordinate conversion for England, Wales, and Scotland based on formulae and data published by the Ordnance
       Survey of Great Britain.

       These modules will convert accurately between an OSGB national grid reference, and coordinates given in
       latitude and longitude using the WGS84 model.  This means that you can take latitude and longitude
       readings from your GPS receiver, (or read them from Wikipedia, or Google Earth, or your car's sat-nav),
       and use this module to convert them to an accurate British National grid reference for use with one of
       the Ordnance Survey's paper maps.  And vice versa, of course.

       These notes explain some of the background and implementation details that might help you get the most
       out of them.

       The algorithms and theory for these conversion routines are all from A Guide to Coordinate Systems in
       Great Britain published by the OSGB, April 1999 (Revised December 2010) and available from the Ordnance
       Survey website <http://www.ordnancesurvey.co.uk/>.  You may also like to read some of the other
       introductory material there.  Should you be hoping to adapt this code to your own custom Mercator
       projection, you will find the paper called Surveying with the National GPS Network, especially useful.

   Upgrading from V2.09 or earlier
       These modules suffered a major overhaul in V2.10 which changed the semantics and interface.  The
       motivation for the change was to simplify the interface, to make WGS84 the default model for latitude and
       longitude, and to speed up conversions.  This section explains what you might have to change to get your
       old code to work with V2.10 and above.

       •   The  module structure changed from V2.09 to V2.10 so it would probably be a good idea to clean up any
           old installation you have and re-install a new version so that none of the  old  files  hangs  about.
           The simplest way to do this is to use the "cpanm" application.

       •   The parsing and formatting routines have been split into a separate module, so before V2.10 you could
           do this:

              use Geo::Coordinates::OSGB ':all'; # Don't do this any more

           now you need to do this:

              use Geo::Coordinates::OSGB       qw(grid_to_ll ll_to_grid);
              use Geo::Coordinates::OSGB::Grid qw(parse_grid format_grid);

       •   The  old  "OSTN02.pm"  module  has  been  removed.   The  data  and the functions it provided are now
           integrated into "OSGB.pm".  The old "OSGB36_to_ETRS89" and "ETRS89_to_OSGB36" functions are now built
           into "ll_to_grid" and "grid_to_ll"; the OSTN data is now used automatically when needed.

       •   The main conversion routines now assume the WGS84 model for lat/lon coordinates.  If you  still  want
           to  work  with  the OSGB36 model for lat/lon, then you need to add the "{ shape => 'OSGB36' }" option
           when converting.  In other words if you did this before:

              my ($e, $n) = ll_to_grid(52.5, -2);

           then to get exactly the same results, you now need to do this

              my ($e, $n) = ll_to_grid(52.5, -2, { shape => 'OSGB36' } );

           On the other hand, if you are working with the WGS84 model, then before V2.10 you had to do this:

              # Old and exact
              my ($e, $n) = ETRS89_to_OSGB36(ll_to_grid(52.5, -2));

           or this:

              # Old and approximate
              my ($e, $n) = ll_to_grid(shift_ll_from_WGS84(52.5, -2));

           now you can just do:

              my ($e, $n) = ll_to_grid(52.5, -2);

           This means that the most likely use case is the default.  In other words you can  take  lat/lon  from
           your GPS and get correct grid references by default

       •   The  functions "shift_ll_into_WGS84" and "shift_ll_from_WGS84" are no longer provided.  They were not
           very accurate, and  they  were  confusing.   "ll_to_grid"  and  "grid_to_ll"  now  do  the  necessary
           adjustments for you automatically.

       •   The  functions  to parse and format grid references are moved to "OSGB/Grid.pm".  They have also been
           radically simplified, so that there are now only two functions: "parse_grid" and "format_grid".   The
           old  names  like "parse_GPS_grid" and "format_grid_trad" are retained with their former meanings, but
           they are just synonyms for the two core functions.

       •   The functions to parse and format lat/lon have been removed.  They were not really a core function of
           this module.  There are other modules on CPAN to deal with latitude and longitude.  I  also  give  an
           example of how to format decimal degrees as degrees, minutes, and seconds in "examples/bngl.pl".

   Coordinates and ellipsoid models
       This  section  explains  the fundamental problems of mapping a spherical earth onto a flat piece of paper
       (or computer screen).  A basic understanding of this material will  help  you  use  these  routines  more
       effectively.   It  will also provide you with a good store of ammunition if you ever get into an argument
       with someone from the Flat Earth Society.

       It is a direct consequence of Newton's law of universal gravitation  (and  in  particular  the  bit  that
       states  that  the  gravitational  attraction  between  two  objects varies inversely as the square of the
       distance between them) that all planets are roughly spherical;  if they  were  any  other  shape  gravity
       would  tend  to  pull  them  into a sphere.  On the other hand, most useful surfaces for displaying large
       scale maps (such as pieces of paper or screens) are flat.  Therefore the fundamental problem in making  a
       map  of the earth is that the curved surface being mapped must be distorted at least slightly in order to
       get it to fit onto a flat map.

       This module sets out to solve the corresponding problem of converting latitude and longitude  coordinates
       (designed  for  a  spherical  surface)  to and from a rectangular grid (for a flat surface).  A spherical
       projection is a fairly simple but tedious bit of trigonometry, but the problem is complicated by the fact
       that the earth is not quite a sphere.  Because our planet spins about a vertical axis, it tends to  bulge
       out slightly in the middle, so it is more of an oblate spheroid (or ellipsoid) than a sphere.  This makes
       the  arithmetic  even  more  tedious,  but  the real problem is that the earth is not a regular ellipsoid
       either; it is an irregular lump that closely resembles an ellipsoid and which is constantly  (if  slowly)
       being  rearranged  by  plate  tectonics.  So the best we can do is to pick an imaginary regular ellipsoid
       that provides a good fit for the region of the earth that we are interested in mapping.

       An ellipsoid model is defined by a series of numbers:  the major and minor semi-axes of the solid, and  a
       ratio between them called the flattening. There are four ellipsoid models that are relevant to the UK:

       OSGB36
           The  OSGB36  ellipsoid  is a revision of work begun by George Airy the Astronomer Royal in 1830, when
           the OS first undertook to make a series of maps that covered the entire country.  It provides a  good
           fit for most of the British Isles.

       EDM50
           The  European  standard ellipsoid is a compromise to get a good fit for most of Western Europe.  This
           is not used by these modules.

       WGS84
           As part of the development of the GPS network by the American military in the 1980s a new  world-wide
           ellipsoid  called  WGS84 was defined.  This fits most populated regions of the world reasonably well.
           (Technically the ellipsoid is called GRS80, and WGS84 refers to the whole World Geodetic System  that
           is  based  on it, plus some very nerdy modifications, but for the purposes of this module it's just a
           label).

       ETRS89
           The European Terrestrial Reference System is also based on GRS80, and for our purposes  is  identical
           to  WGS84.   The technical difference is that in the ETRS89 system assumes that the Eurasian tectonic
           plate is the reference, whereas WGS84 assumes that the American plate is  the  reference.   But  this
           makes no practical difference whatsoever for the use of these modules.

       The  latitude  and  longitude  marked  on OS maps printed before 2015 are given in the OSGB36 model.  The
       latitude and longitude you read from your GPS device, or from Wikipedia, or Google Earth are in the WGS84
       model.  So the point with latitude 51.4778 and longitude 0 in the OSGB36 model is on the  prime  meridian
       line  in  the courtyard of the Royal Observatory in Greenwich, but the point with the same coordinates in
       the WGS84 model is about 120 metres away to the south-east, in the park.

       In these modules the shape used for the projection of latitude and  longitude  onto  the  grid  is  WGS84
       unless you specifically set it to use OSGB36.

   The British National Grid and OSTN02 / OSTN15
       A  Mercator  grid  projection like the British National Grid is defined by the five parameters defined as
       constants at the top of the module.

       •   True point of origin Latitude and Longitude = 49N, 2W

       •   False origin easting and northing = 400000, -100000

       •   Convergence factor = 0.9996012717

       One consequence of the True Point of Origin of the British Grid being set to 49N,  2W  is  that  all  the
       vertical  grid  lines  are  parallel to the 2W meridian; you can see this on the appropriate OS maps (for
       example Landranger sheet 184), or on the PDF picture supplied with this package in the "examples" folder.
       The effect of moving the False Point of Origin to the far south west  is  to  make  all  grid  references
       positive.

       Strictly  speaking,  grid  references are given as the distance in metres from the False Point of Origin,
       with the easting always given before the northing.  For everyday use however, the OSGB suggest that  grid
       references  need  only  to be given within the local 100km square as this makes the numbers smaller.  For
       this purpose they divide Britain into a series of 100km squares, each identified by a  pair  of  letters:
       TQ, SU, ND, etc.  The grid of the big squares actually used is something like this:

                                       HP
                                       HU
                                    HY
                           NA NB NC ND
                           NF NG NH NJ NK
                           NL NM NN NO NP
                              NR NS NT NU
                              NW NX NY NZ OV
                                 SC SD SE TA
                                 SH SJ SK TF TG
                              SM SN SO SP TL TM
                              SR SS ST SU TQ TR
                           SV SW SX SY SZ TV

       SW  covers  most  of  Cornwall,  TQ  London, HU the Shetlands, and there is one tiny corner of a beach in
       Yorkshire that is in OV.  The system has the neat feature that N and S are directly above each other,  so
       that most Sx squares are in the south and most Nx squares are in the north.  The system logically extends
       far  out  in  all  directions;  so square XA lies south of SV and ME to the west of NA and so on.  But it
       becomes less useful the further you go from the central meridian of 2W.

       Within each of the large squares, we only need five-digit coordinates --- from (0,0) to (99999,99999) ---
       to refer to a given square  metre.   But  general  use  rarely  demands  such   precision,  so  the  OSGB
       recommendation   is to use units of 100m (hectometres) so that we only need three digits for each easting
       and northing --- (000,000) to (999,999).  If we combine the easting and  northing  we  get  the  familiar
       traditional  six  figure  grid reference.  Each of these grid references is repeated in each of the large
       100km squares but this does not usually matter for local use  with  a  particular  map.   Where  it  does
       matter,  the  OS  suggest that the six figure reference is prefixed with the identifier of the large grid
       square to give a `full national grid reference', such as TQ330800.  This system is described in the notes
       in the corner of every Landranger 1:50,000 scale map.

       This system was originally devised for use on top of the OSGB36 model of latitude and longitude,  so  the
       prime  meridian  used  and  the  coordinates  of the true point of origin are all defined in that system.
       However as part of standardizing on an international GPS system, the OS have  redefined  the  grid  as  a
       rubber  sheet  transformation from WGS84.  There is no intrinsic merit to using one model or another, but
       there's an obvious need to be consistent about which one you choose, and with the growing ubiquity of GPS
       systems, it makes sense to standardize on WGS84.

       The grid remains the primary reference system for use with maps, but the OS has  always  also  printed  a
       latitude  and  longitude  `graticule'  around  the  edges of the large scale sheets.  Traditionally these
       coordinates have been given in the OSGB36 model, but since 2015 the OS has been printing revised editions
       of Explorer and Landranger sheets with WGS84 coordinates instead.  The legend of  my  recently  purchased
       copy of Explorer 311 has this paragraph under the heading `The National Grid Reference System':

       •   Base  map constructed on Transverse Mercator Projection, Airy Ellipsoid, OSGB (1936) Datum.  Vertical
           datum mean sea level. The latitude, longitude graticule  overlay  is  on  the  ETRS89  datum  and  is
           compatible with the WGS84 datum used by satellite navigation devices.

       If  your  map does not have the last sentence you can assume that it shows OSGB36 latitude and longitude.
       Of course, this change makes no difference to the grid itself.

       The differences between the OSGB36 and WGS84 models are only important if you are  working  at  a  fairly
       small  scale.  The average differences on the ground vary from about -67 metres to + 124 meters depending
       on where you are in the country.

           Square                 Easting difference           Northing difference
           --------------------   -------------------------    ------------------
                        HP                        109                          66
                     HT HU                    100 106                      59  62
               HW HX HY                73  83  93                  51  48  47
            NA NB NC ND            61  65  81  89              40  39  38  40
            NF NG NH NJ NK         57  68  79  92  99          30  29  28  26  26
            NL NM NN NO            56  66  79  91              18  17  15  15
               NR NS NT NU             66  77  92 100               3   2   1   0
               NW NX NY NZ             70  77  92 103              -9  -8 -10 -13
                  SC SD SE TA              77  93 104 112             -19 -22 -23 -24
                  SH SJ SK TF TG           79  91 103 114 124         -35 -34 -35 -38 -40
               SM SN SO SP TL TM       72  80  90 101 113 122     -49 -47 -46 -46 -46 -47
                  SS ST SU TQ TR           80  90 101 113 121         -57 -56 -57 -57 -59
               SW SX SY SZ TV          71  79  90 100 113         -67 -64 -62 -62 -62

       The chart above shows the mean difference in each grid square.  A positive easting difference  means  the
       WGS84  Lat/Lon  is  to  the  east  of  OSGB36; a positive northing difference means it is to the north of
       OSGB36.  At a scale of 1:50,000, 124 meters is 2.48 mm, and at 1:25,000 it is 4.96 mm, so the  difference
       is readily visible if you compare new and old editions of the same map sheet.

       The transformation from WGS84 to OSGB36 published in 2002 was called OSTN02 and consisted of a large data
       set  that  defined  a three dimensional shift for each square kilometre of the country.  This dataset was
       revised (apparently to give a better fit) in 2015 and the revised dataset is called OSTN15.

       To get from WGS84 latitude and longitude to the grid, you project from the WGS84 ellipsoid to  a  pseudo-
       grid  and then look up the relevant shifts from OSTN15 and adjust the easting and northing accordingly to
       get coordinates in the OSGB grid.  Going the other way is slightly more complicated as you have to use an
       iterative approach to find the latitude and longitude that would give you your grid coordinates.

       It is also possible to use a three-dimensional shift and rotation called a Helmert transformation to  get
       an  approximate  conversion.  This approach is used automatically by these modules for locations that are
       undefined in OSTN15, and, if you want to, you can explicitly use it anywhere  in  the  UK  by  using  the
       "grid_to_ll_helmert" and "ll_to_grid_helmert" routines.

       Modern GPS receivers can all display coordinates in the OS grid system.  You just need to set the display
       units  to  be  `British National Grid' or whatever similar name is used on your unit.  Most units display
       the coordinates as two groups of five digits and a grid square identifier.  The units are  metres  within
       the  grid  square.  However you should note that your consumer GPS unit will not have a copy of the whole
       of OSTN15 in it.  To show you  an  OSGB  grid  reference,  your  GPS  will  be  using  either  a  Helmert
       transformation,  or  an  even  more  approximate  Molodenksy  transformation  to translate from the WGS84
       coordinates it is getting from the satellites.

       Note that the OSGB (and therefore this module) does not cover the whole of the British  Isles,  nor  even
       the  whole  of  the  UK,  in  particular it covers neither the Channel Islands nor Northern Ireland.  The
       coverage that is included is essentially the same as the  coverage  provided  by  the  OSGB  "Landranger"
       1:50000  series  maps.   The  coverage  of  the  OSTN02  data set was slightly smaller, as the OS did not
       originally define the model for any points more than about 2km off shore.  The main difference in  OSTN15
       is  that  coverage is extended to the whole rectangle from grid point (0,0) to (700000,1250000), although
       the accuracy far off shore should not be relied on more than about +/- 5m.

   Implementation of OSTN shift data
       The OSTN15 is the definitive transformation from WGS84 coordinates to the British National Grid.   It  is
       published as a large text file giving a set of corrections for each square kilometre of the country.  The
       OS  also  publish an algorithm to use it which is described on their website.  Essentially you take WGS84
       latitude and longitude coordinates and project them into an (easting, northing) pair of  coordinates  for
       the  flat  surface  of  your  grid. You then look up the corrections for the four corners of the relevant
       kilometre square and interpolate the exact corrections needed for your spot in the square.  Adding  these
       exact corrections gives you an (easting, northing) pair in the British grid.

       The  distributed  data also includes a vertical height correction as part of the OSGM15 geoid module, but
       this is not used in this module, so it is omitted from the module in order to save space.

       The table of data supplied by the  Ordnance  Survey  contains  876951  rows  with  entries  for  each  km
       intersection  between (0,0) and (700000, 1250000).  In OSTN02, 567472 of these entries referred to square
       kms that are more than 10 km away from the British mainland (either in the sea or in Eire) and these were
       set to zero, indicating that OSTN02 is not defined at these places.  In order to save more  space,  these
       were  omitted from the beginning and end of each row in the data as stored in my original implementation.
       The last 21 rows (north of Shetland) were all zeroes, so these were omitted as well.

       My implementation of the OSTN02 data was included in the "OSGB.pm" module after the "__DATA__" line,  and
       was  read  using  the magic "<DATA>" file handle.  In tests this proved to be the fastest way to load all
       that data, by a long way.

       There were 1229 rows of data, and each row contained up to 701 pairs of shift data encoded  as  pairs  of
       integers  representing  the  shift  in  mm.   Leading  and trailing zeros were omitted, and the number of
       leading zeros omitted was stored in the first three characters of each row.  The integer pairs  were  all
       coded  in a home-grown version of base32 using the character set "0123456789:;<=>?@ABDEFGHIJKLMNO".  This
       allowed integers up to 32767 to be stored in three bytes of printable ASCII.  that could be stored inside
       "OSGB.pm".  Decoding them was very slightly slower than decoding hex strings, but using 3  bytes  integer
       instead of 4 reduced the memory and loading time by 25%.

       When the OSGB revised OSTN02 to OSTN15, they filled in all the zeros, so this complicated approach was no
       longer  justified.   In  version  2.20  and above of this module, the shift data sets are included in the
       module's `share` directory and loaded at run time.  This turns out to be faster and simpler.

   Accuracy, uncertainty, and speed
       This section explores the limits of accuracy and precision you can expect from this software.

       Accuracy of readings from GPS devices

       If you are converting readings taken from your own handheld GPS device, the readings themselves will  not
       be  very  accurate.  To convince yourself of this, try taking your GPS on the same walk on different days
       and comparing the track: you will see that the tracks do not coincide.  If you have two units  take  them
       both and compare the tracks:  you will see that they do not coincide.

       The  accuracy of the readings you get will be affected by cloud cover, tree cover, the exact positions of
       the satellites relative to you (which are constantly changing as the earth rotates), how close you are to
       sources of interference, like  buildings  or  electricity  installations,  not  to  mention  the  ambient
       temperature and the state of your rechargeable batteries.

       To  get  really  accurate  readings  you  have  to  invest in some serious professional or military grade
       surveying equipment.

       How big is 0.000001 of a degree?

       In the British Isles the distance along a meridian between two points that are  one  degree  of  latitude
       apart  is  about 110 km or just under 70 miles. This is the distance as the crow flies from, say, Swindon
       to Walsall.  So a tenth of a degree is about 11 km or 7 miles, a hundredth is just  over  1km,  0.001  is
       about  110m,  0.0001 about 11m and 0.00001 just over 1 m.  If you think in minutes, and seconds, then one
       minute is about 1840 m (and it's no coincidence that this happens to  be  approximately  the  same  as  1
       nautical mile).  One second is a bit over 30m, 0.1 seconds is about 3 m, and 0.0001 second is about 3mm.

                Degrees              Minutes             Seconds  * LATITUDE *
                      1 = 110 km         1 = 1.8 km        1 = 30 m
                    0.1 =  11 km       0.1 = 180 m       0.1 =  3 m
                   0.01 = 1.1 km      0.01 =  18 m      0.01 = 30 cm
                  0.001 = 110 m      0.001 =   2 m     0.001 =  3 cm
                 0.0001 =  11 m     0.0001 = 20 cm    0.0001 =  3 mm
                0.00001 = 1.1 m    0.00001 =  2 cm
               0.000001 = 11 cm   0.000001 =  2 mm
              0.0000001 =  1 cm

       Degrees  of  latitude  get  very  slightly  longer  as you go further north but not by much.  In contrast
       degrees of longitude, which represent the same length on the ground  as  latitude  at  the  equator,  get
       significantly  smaller  in  northern  latitudes.   In southern England one degree of longitude represents
       about 70 km or 44 miles, in northern Scotland it's less than 60 km or about 35 miles.  Scaling everything
       down means that the fifth decimal place of a degree of longitude represents about 60-70cm on the ground.

              Degrees                Minutes            Seconds * LONGITUDE *
                    1 = 60-70 km         1 = 1.0-1.2 km      1 = 17-20 m
                  0.1 = 6-7 km         0.1 = 100-120 m     0.1 = 2 m
                 0.01 = 600-700 m     0.01 = 10-12 m      0.01 = 20 cm
                0.001 = 60-70 m      0.001 = 1 m         0.001 = 2 cm
               0.0001 = 6-7 m       0.0001 = 10 cm      0.0001 = 2 mm
              0.00001 = 60-70 cm   0.00001 = 1 cm
             0.000001 = 6-7 cm

       How accurate are the conversions?

       The OS supply test data with OSTN15 that comes from various fixed stations around the  country  and  that
       form  part  of the definition of the transformation.  If you look in the test files "06-osgb-*.t" you can
       see how it is used for testing these modules.

       In all cases translating from the WGS84 coordinates to the national grid and vice versa  is  accurate  to
       the  millimetre,  so  these  modules are at least as accurate as the OSGB software that produced the test
       data.

       The main difference between the OSTN02 transformation and OSTN15 is that the model fits  the  whole  grid
       area  better.   With  OSTN02  the  conversions  were (very slightly) less accurate for places west of 7W.
       Translating from the given grid coordinates to WGS84 latitude and longitude coordinates was  accurate  to
       1mm  for  all  of  England,  Wales, Scotland and the Isle of Man, but `round trip' testing (by generating
       random grid references, converting them to WGS84 latitude and longitude and then converting them back  to
       grid  easting and northing), showed that beyond of 6W (that is in the Scilly Isles and the Hebrides), the
       error creeps up to about 4mm if you go as far as St Kilda (at about 8.57W).  The new OSTN15  numbers  are
       all  very  slightly  different, so that converting any given latitude and longitude in WGS84 gives a grid
       reference that may be a few mm different.  But OSTN15 no longer shows greater round trip  errors  in  the
       far west. The accuracy of round trip conversions is less than 1mm for all of the OSGB test points in both
       directions.

       Outside the rectangle covered by OSTN15, this module uses the small Helmert transformation recommended by
       the  OS.  The OS state that, with the parameters they provide, this transformation will be accurate up to
       about +/-5 metres, in the vicinity of the British Isles.

       You can also use this transformation within the OSTN15 rectangle by calling the "grid_to_ll_helmert"  and
       "ll_to_grid_helmert" routines.  If you compare the output from these routines to the output from the more
       accurate  routines  that  use OSTN15 you will find that the differences are between about -3.6 metres and
       +5.1 metres depending on where you are in the country.  In the South East both easting and  northing  are
       underestimated, in northern Scotland they tend to be overestimated.

       How fast are the conversions?

       In  general the answer to this question is "probably faster than you need", but if you have read this far
       you might be interested in the results of my benchmarking.  The slowest part of these routines used to be
       the loading of the OSTN15 data set but I have put considerable effort into making this faster since about
       version 2.08 of this module, so that now the accurate routines the use the OSTN15 data  are  pretty  much
       the same as the approximate routines ("ll_to_grid" is slightly faster, "grid_to_ll" is slightly slower).

       The  tests  used to be a bit generous to my code because of the caching effect.  In order to speed up the
       OSTN data lookups, the routines used to keep a cache of the data  fetched,  so  that  if  you  convert  a
       sequence of coordinates in the same square km, the second and subsequent lookups will get the data from a
       local  hash  instead  of  having  to read the table.  The benchmark test (using the standard Benchmark.pm
       approach) consists of getting Perl to run as many conversions as possible for about 5 CPU seconds, and as
       a result the cache hit  ratio  was  probably  rather  exaggerated.   Nevertheless  this  might  still  be
       reasonably  representative  if  you are converting, say, the steps in a GPX track, where successive steps
       are highly likely to be the same square km as the one before.  Moreover, since converting  to  OSTN15,  I
       have removed the cache look ups so I'm no longer getting any such boost.

       Last  year (2016) with version 2.16 of this module, a typical bench mark run on my development machine (a
       Mac Mini server from 2011) using the Apple-supplied Perl 5.16 gave:

           Subroutine          calls per sec  ms per call
           ----------------------------------------------
           ll_to_grid                  41677        0.024
           ll_to_grid_helmert          42145        0.024

           grid_to_ll                  18131        0.055
           grid_to_ll_helmert          35793        0.028

       On my newer work machine (a MBP from 2015) using the newer Perl 5.18 supplied with macOS  Sierra,  I  got
       slightly better numbers with V2.16

           Subroutine          calls per sec  ms per call
           ----------------------------------------------
           ll_to_grid                  50980        0.020
           ll_to_grid_helmert          68267        0.015

           grid_to_ll                  25831        0.039
           grid_to_ll_helmert          54371        0.018

       But  after  a  bit more work to simplify the way that the cache is implemented I get this on the same MBP
       with the version 2.19:

           Subroutine          calls per sec  ms per call
           ----------------------------------------------
           ll_to_grid                  69099       0.0145
           ll_to_grid_helmert          66158       0.0151

           grid_to_ll                  29114       0.0343
           grid_to_ll_helmert          53969       0.0185

       Now, on the same MBP, but with the new OSTN15 data set and the simpler data look up I get:

           Subroutine          calls per sec  ms per call
           ----------------------------------------------
           ll_to_grid                  70730       0.0141
           ll_to_grid_helmert          63308       0.0158

           grid_to_ll                  32238       0.0310
           grid_to_ll_helmert          55286       0.0181

       In my opinion, this justifies my decision  to  make  the  accurate  OSTN  conversion  the  default.   The
       approximate Helmert-based routine is no quicker for ll to grid conversions.

       It  is  always going to be slightly slower converting from grid to ll, due to the iterative nature of the
       algorithm that is built into OSTN15.  So the approximate routine is likely  to  remain  slightly  faster.
       Having  said  that  none  of  the  routines  is  really  slow,  since even "grid_to_ll" averages under 60
       microseconds per call on the older machine.  `Your mileage may vary', of course.

       The routines have been tested  with  various  versions  of  Perl,  including  recent  versions  with  the
       "uselongdouble"  option  enabled.  Using a locally compiled version of Perl 5.22 with ordinary doubles, I
       saw a small improvement on the Helmert routines, but the default routines are about  the  same.   On  the
       same  system,  long doubles slowed everything down by about 10%, and made no difference to the round trip
       precision of the routines. Since the formulae were specifically designed for  ordinary  double  precision
       arithmetic, Perl's default arithmetic is more than adequate.

   Maps
       Since  Version 2.09 these modules have included a set of map sheet definitions so that you can find which
       paper maps your coordinates are on.

       See Geo::Coordinates::OSGB::Maps for details of the series included.  The first three series are OS maps:

         A - OS Landranger maps at 1:50000 scale;
         B - OS Explorer maps at 1:25000;
         C - the old OS One-Inch maps at 1:63360.

       Landranger sheet 47 appears in the list of keys as "A:47", Explorer sheet 161 as "B:161", and so on.   As
       of  2015,  the  Explorer series of incorporates the Outdoor Leisure maps, so (for example) the two sheets
       that make up the map `Outdoor Leisure 1' appear as "B:OL1E" and "B:OL1W".

       Thanks to the marketing department at the OS and their  ongoing  re-branding  exercise  several  Explorer
       sheets  have  been  promoted to Outdoor Leisure status.  So (for example) Explorer sheet 364 has recently
       become `Explorer sheet Outdoor Leisure 39'.  Maps like this  are  listed  with  a  combined  name,  thus:
       "B:395/OL54".

       Many of the Explorer sheets are printed on both sides.  In these cases each side is treated as a separate
       sheet  and distinguished with suffixes.  The pair of suffixes used for a map will either be N and S, or E
       and W.  So for example there is no Explorer  sheet  "B:271",  but  you  will  find  sheets  "B:271N"  and
       "B:271S".  The suffixes are determined automatically from the layout of the sides, so in a very few cases
       it  might  not  match  what  is  printed on the sheet but it should still be obvious which side is which.
       Where the map has a combined name the suffix only appears at the  end.  For  example:  "B:386/OL49E"  and
       "B:386/OL49W".

       Several  sheets  also  have insets, for islands, like Lundy or The Scilly Isles, or for promontories like
       Selsey Bill or Spurn Head.  Like the sides, these insets are also treated as  additional  sheets  (albeit
       rather smaller).  They are named with an alphabetic suffix so Spurn Head is on an inset on Explorer sheet
       292  and  this  is labelled "B:292.a".  Where there is more than one inset on a sheet, they are sorted in
       descending order of size and labelled ".a", ".b" etc.  On some sheets the insets overlap the area of  the
       main sheet, but they are still treated as separate map sheets.

       Some  maps  have  marginal  extensions  to  include  local  features  -  these are simply included in the
       definition of the main sheets.  There are, therefore,  many  sheets  that  are  not  regular  rectangles.
       Nevertheless, the module is able to work out when a point is covered by one of these extensions.

       In  the  examples  folder  there is an extended example showing how to work with the map data as supplied
       through the "Maps.pm" interface.

       The source files for the map data are in the "maps" directory.  The script that builds "Maps.pm" from the
       source files is "build/make_maps_code".

       It's probably fair to say that currently (in early 2016) everything about the maps is still  experimental
       and may change in the future.

       For each series there are two files:

       •   "catalogue"  which  defines:  an index number for each map (unique to this project); the sheet number
           for the map - not necessarily an integer; the sheet title as a UTF8 string; the current  ISBN  number
           for maps that have them.

       •   "polygons"  which  has:  index  numbers  that match the corresponding "catalogue"; sheet numbers that
           match the corresponding "catalogue"; a flag - an integer to show the status of the entry  (no  formal
           meaning); followed by a MULTIPOLYGON in WKT format.

       There  is  one  line  in  each  of  the  files for each map in the series.  The data format for the sheet
       polygons is Well Known Text (as defined in Wikipedia).  The set of polygons for each map is defined as  a
       MULTIPOLYGON;  a list of POLYGONS.  There are no holes in any of the polygons.  A missing polygon list is
       recorded as "EMPTY" (this is part of WKT).

       The units are metres from the false point of origin (which is some miles west of the Scilly  Isles).   So
       the south west corner of Landranger sheet 204, which has traditional grid reference SW 720 140 is defined
       in this data as "172000 14000".  This is essentially what "parse_grid" returns. No leading zeros needed.

       The polygon starts at the south west corner of the sheet and is recorded anticlockwise.  WKT insists that
       the first pair is repeated at the end to close the polygon. So a simple 40km square Landranger sheet with
       no insets or extensions, such as Sheet 152, whose SW corner is at SP 530 300 is recorded as

           (((453000 230000, 493000 230000, 493000 270000, 453000 270000, 453000 230000)))

       If  the  sheet  boundary is more complicated than a square, the polygon consists of a coordinate pair for
       each corner.  Extensions - where the coloured printing spills over the neat edge - are included  as  part
       of  the  main polygon in the appropriate place, always moving anticlockwise.  Extensions don't have to be
       rectilinear but they are made up of straight lines.  Extensions consisting of  administrative  boundaries
       and labels are ignored.  If in doubt, use common sense.

       If  an inset is drawn on the map sheet with its own grid margin then it is recorded as a separate polygon
       following the WKT format, even if it overlaps the main sheet.

       On OS Landranger maps,  the first (and last) pair should always be the SW corner, if an extension affects
       the SW corner, start and end with the regular corner pair even if they are technically  redundant.   This
       allows  me  to  find  the  SW corners currently defined for the Landranger maps easily.  In other series,
       start somewhere near the SW and go anticlockwise.

perl v5.36.0                                       2022-12-06             Geo::Coordinate...SGB::Background(3pm)