Some people have asked me about converting between latitude/longitude & Ordnance Survey grid
references. The maths is extraordinarily complex (and way beyond me!), but the Ordnance Survey
explain the resulting formulae very clearly in Annex C of their
*Guide
to coordinate systems in Great Britain*.

OS Grid References are based on 100km grid squares identified by letter-pairs, followed by digits
which identify a sub-square within the grid square, as explained on the OS
*Interactive
Guide to the National Grid*. 6-digit references identify 100m grid squares; 8 digits
identify 10m grid squares, and 10 digits identify 1m squares. TG51401317 represents a 10m box
with its (south-west) origin 51.40km across, 13.17km up within the TG square.

Before going further, I have to mention that, at a fine level of accuracy, there are different ways of measuring latitude & longitude. The Ordnance Survey uses ‘OSGB-36’, based on an ellipsoidal model of the earth’s surface which is a good fit to the UK. GPS systems generally use the world-wide ‘WGS-84’, based on an ellipsoidal model which is a best approximation to the entire earth. At Greenwich, these differ by about 126m (they coincide somewhere in the Atlantic ocean; there’s more on Wikipedia).

A source of possible confusion to be aware of is that a grid reference identifies a square (with the size of the square determined by the number of digits), whereas a latitude/longitude coordinate identifies a point (with precision implied by the number of digits).

Note also that an alternative way of expressing OS Grid References is as all-numeric eastings and northings. As square TG is six squares across, three squares up within the grid, grid reference TG 5140 1317 can also be expressed as 65140,31317.

Beware that eastings and northings can be used either as a grid reference (identifying a grid square), or as a coordinate (identifying a point). In this example, the coordinate representing the centre of grid reference TG 5140 1317 would be 651405,313175. It is often ambiguous whether eastings and northings are being used as grid references or as coordinates.

The Ordnance Survey grid is a Transverse Mercator projection (with origin at 49°N, 2°W) based on the Airy 1830 ellipsoid using the OSGB36 datum. GPS is based on WGS84/GRS80, which as mentioned can vary from OSGB36 by as much as 120m or 6" of arc (OSGB36/Airy is a better fit to the UK geoid than the geocentric WGS84 which covers the entire world). I have written some separate notes on converting between OSGB-36 & WGS-84.

The JavaScript implementation should be quite simple to translate to other languages, if required. Since JavaScript lacks a power operator, I opted to keep the script easier to read by using temporary variables and multiplication rather than the Math.pow method. Since JavaScript is untyped, expressions such as ‘5/4’ give floating-point results – typed languages may need explicit casts to give floating-point results. Also to keep the scripts simple, I have included minimal error checking, and no user options for specifying precision.

As this script is for converting OS grid references, I have ‘hard-wired’ in the Airy 1830 axes and the National Grid projection origin & scale factor; if you want to convert to other transverse mercator projections, you will need to change these constants. UTM (Universal Transverse Mercator projection) uses a scale factor of 0.9996 and origins at 6° intervals of longitude, based on the WGS84 ellipse (though previously UTM projections were based on International 1924 and Clark 1866 ellipses, among others).

Aside from the transformation maths, the other tricky bit of the script is converting grid letter-pairs to/from numeric eastings & northings. To follow what’s going on, it is worth noting that the letter-pairs define a 5x5 grid of 5x5 sub-grids; the eastings & northings work from a ‘false origin’ at grid square SV, which is displaced from grid square AA by 10 squares E, 19 squares N, with the northing axis inverted; and letter ‘I’ is skipped. OS Grid References apply to the UK only.

For other scripts for calculating distances, bearings, etc between latitude/longitude points, see my Lat/Long page. I have also written a script for calculating distances between OS grid reference points.

See below for the source code of the JavaScript implementation,
also available on GitHub.
These functions should be simple to translate into other languages if required. *April 2012*:
I have revised the scripts to be encapsulated in an *OsGridRef* object (the previous version is
still available for comparison).

I offer these formulæ & scripts for free use and adaptation as my contribution to the open-source info-sphere from which I have received so much. You are welcome to re-use these scripts [under a simple attribution license, without any warranty express or implied] provided solely that you retain my copyright notice and a link to this page.

If you would like to show your appreciation, I would most gratefully accept donations.

If you have any queries or find any problems, contact me at ku.oc.epyt-elbavom@oeg-stpircs.

*© 2005-2014 Chris Veness*