View on
Toby Thurston > Geo-Coordinates-OSGB > Geo::Coordinates::OSGB::Grid



Annotate this POD


Open  0
View/Report Bugs
Module Version: 2.18   Source  


Geo::Coordinates::OSGB::Grid - Format and parse British National Grid references




  use Geo::Coordinates::OSGB::Grid qw/parse_grid format_grid/;

  my ($e,$n) = parse_grid('TQ 23451 09893');
  my $gr     = format_grid($e, $n); # "TQ 234 098"


This module provides useful functions for parsing and formatting OSGB grid references. Some detailed background is given in background.pod and on the OS web site.


format_grid(e, n)

Formats an (easting, northing) pair into traditional `full national grid reference' with two letters and two sets of three numbers, like this `SU 387 147'.

    $gridref = format_grid(438710.908, 114792.248); # SU 387 147

If you want the individual components call it in a list context.

    ($sq, $e, $n) = format_grid(438710.908, 114792.248); # ('SU', 387, 147)

Note that rather than being rounded, the easting and northing are truncated to hectometres (as the OS system demands), so the grid reference refers to the lower left corner of the relevant 100m square. The system is described below the legend on all OS Landranger maps.

The format grid routine takes an optional third argument to control the form of grid reference returned. This should be a hash reference with one or more of the keys shown below (with the default values).

    format_grid(e, n, {form => 'SS EEE NNN', maps => 0, series => 'ABCHJ'})

Options for format_grid


Controls the format of the grid reference. With $e, $n set as above:

    Format          produces        Format            produces
    'SS'            SU
    'SSEN'          SU31            'SS E N'          SU 3 1
    'SSEENN'        SU3814          'SS EE NN'        SU 38 14
    'SSEEENNN'      SU387147        'SS EEE NNN'      SU 387 147
    'SSEEEENNNN'    SU38711479      'SS EEEE NNNN'    SU 3871 1479
    'SSEEEEENNNNN'  SU3871014792    'SS EEEEE NNNNN'  SU 38710 14792

You can't leave out the SS, you can't have N before E, and there must be the same number of Es and Ns.

There are two other special formats:

     form => 'TRAD' is equivalent to form => 'SS EEE NNN'
     form => 'GPS'  is equivalent to form => 'SS EEEEE NNNNN'

In a list context, this option means that the individual components are returned appropriately truncated as shown. So with SS EEE NNN you get back ('SU', 387, 147) and not ('SU', 387.10908, 147.92248). The format can be given as upper case or lower case or a mixture. If you want just the local easting and northing without the grid square, get the individual parts in a list context and format them yourself:

    my $gr = sprintf('Grid ref %2$s %3$s on Sheet %4$s', format_grid_landranger($e, $n))
    # returns: Grid ref 387 147 on Sheet 196

Controls whether to include a list of map sheets after the grid reference. Set it to 1 (or any true value) to include the list, and to 0 (or any false value) to leave it out. The default is maps => 0.

In a scalar context you get back a string like this:

    SU 387 147 on A:196, B:OL22E, C:180

In a list context you get back a list like this:

    ('SU', 387, 147, A:196, B:OL22E, C:180)

This option is only used when maps is true. It controls which series of maps to include in the list of sheets. Currently the series included are:

A : OS Landranger 1:50000 maps

B : OS Explorer 1:25000 maps (some of these are designated as `Outdoor Leisure' maps)

C : OS Seventh Series One-Inch 1:63360 maps

H : Harvey British Mountain maps - mainly at 1:40000

J : Harvey Super Walker maps - mainly at 1:25000

so if you only want Explorer maps use: series => 'B', and if you want only Explorers and Landrangers use: series => 'AB', and so on.

Note that the numbers returned for the Harvey maps have been invented for the purposes of this module. They do not appear on the maps themselves; instead the maps have titles. You can use the numbers returned as an index to the data in Geo::Coordinates::OSGB::Maps to find the appropriate title.


Equivalent to format_grid(e,n, { form => 'trad' }).


Equivalent to format_grid(e,n, { form => 'gps' }).


Equivalent to format_grid(e,n, { maps => 1 }).


Equivalent to

   format_grid(e,n,{ form => 'ss eee nnn', maps => 1, series => 'A' })

except that the leading "A:" will be stripped from any sheet names returned, and you get a slightly fancier set of phrases in a scalar context depending on how many map numbers are in the list of sheets.


The parse_grid routine extracts a (easting, northing) pair from a string, or a list of arguments, representing a grid reference. The pair returned are in units of metres from the false origin of the grid, so that you can pass them to format_grid or grid_to_ll.

The arguments should be in one of the following forms


This is included only for backward compatibility. It is now just a synonym for parse_grid.


This is included only for backward compatibility. It is now just a synonym for parse_grid.

parse_landranger_grid(sheet, e, n)

This is included only for backward compatibility. It is now just a synonym for parse_grid.

parse_map_grid(sheet, e, n)

This is included only for backward compatibility. It is now just a synonym for parse_grid.

random_grid([sheet1, sheet2, ...])

Takes an optional list of map sheet identifiers, and returns a random easting and northing for some place covered by one of the maps. There's no guarantee that the point will not be in the sea, but it will be within the bounding box of one of the maps and it should be within one of the areas covered by the OSTN02 data set.


  use Geo::Coordinates::OSGB::Grid

  # Get full coordinates in metres from GR
  my ($e,$n) = parse_grid('TQ 23451 09893');

  # Reading and writing grid references
  # Format full easting and northing into traditional formats
  my $gr1 = format_grid($e, $n);                              # "TQ 234 098"
  my $gr2 = format_grid($e, $n, { form => 'SSEEENNN' } );     # "TQ234098"
  my $gr3 = format_grid($e, $n, { form => 'SSEEEEENNNNN'} );  # "TQ 23451 09893"
  my $gr4 = format_grid($e, $n, { form => 'gps'} );           # "TQ 23451 09893"
  my $gr5 = format_grid_landranger($e, $n);# "TQ 234 098 on Landranger sheet 198"

  # or call in list context to get the individual parts
  my ($sq, $ee, $nn) = format_grid($e, $n); # ('TQ', 234, 98)

  # parse routines to convert from these formats to full e,n
  ($e,$n) = parse_grid('TQ 234 098');
  ($e,$n) = parse_grid('TQ234098'); # spaces optional
  ($e,$n) = parse_grid('TQ',234,98); # or even as a list
  ($e,$n) = parse_grid('TQ 23451 09893'); # as above..

  # You can also get grid refs from individual maps.
  # Sheet between 1..204; gre & grn must be 3 or 5 digits long
  ($e,$n) = parse_grid(176,123,994);
  # put leading zeros in quotes
  ($e,$n) = parse_grid(196,636,'024');

For more examples of parsing and formatting look at the test files.


The useful area of these routines is confined to the British Isles, not including Ireland or the Channel Islands. But very little range checking is done, so you can generate pseudo grid references for points that are some way outside this useful area. For example we have St Peter Port in Guernsey at XD 611 506 and Rockall at MC 035 165. The working area runs from square AA in the far north west to ZZ in the far south east. In WGS84 terms the corners run from 64.75N 32.33W (Iceland) to 65.8N 22.65E (Norway) to 44.5N 11.8E (Venice) to 44N 19.5W (the Western Approaches). This is something of a geodesy toy rather than a useful function.


Messages from format_grid

In case of error format_grid will die with a message. Possible messages are:

Messages from parse_grid

In case of error parse_grid will die with one of the following messages:

If you get an unexpected result from any of these subroutines, please generate a test case to reproduce your result and get in touch to ask me about it.


There is no configuration required either of these modules or your environment. It should work on any recent version of Perl better than 5.8, on any platform.


Perl 5.08 or better.


None known.


Copyright (C) 2002-2016 Toby Thurston

OSTN02 transformation data included in this module is freely available from the Ordnance Survey but remains Crown Copyright (C) 2002

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


Toby Thurston -- 12 Jun 2017


See Geo::Coordinates::OSGB.

syntax highlighting: