Home Blog CV Projects Patterns Notes Book Colophon Search

Converting from GPS to British National Grid

21 Dec, 2016

This seems pretty horrendously complicated to understand properly, but here I'll show you how to look up the data you need to do the transforms easily.

Here are the steps:

  1. First go to http://epsg.io and type in the term you want. The site will suggest the official standard you are looking for. For GPS it is is EPSG:4326 (aka WSG84) and for British National Grid it is EPSG:27700.
  2. Load the pages for each standard and scroll to the bottom for Export
  3. Choose the tool you want to use for the conversion and copy the settings

For this we'll use Proj.4's cs2cs tool.

The settings we need from EPSG are:

GPS:

+proj=longlat +datum=WGS84 +no_defs 

British National Grid:

+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs 

Now you can get the cs2cs program (or follow instructions at https://github.com/OSGeo/proj.4/wiki:

brew install proj

Now we can use the two setting from above with +to between them in the cs2cs tool. As an example, the coordinates of Ordnance Survey's Geovation Hub are 51.5236° N, 0.1047° W according to Google, so we can convert them like this:

echo "51.5236N 0.1047W" | cs2cs -r  +proj=longlat +datum=WGS84 +no_defs +to +proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs

The result is:

531585.12	182222.85 -46.11

This means the Easting, Northing, and Height.

There are a few different formats you can use in the input and you can put more than one line in at once. The man page has this example:

            45d15'33.1"   111.5W
            45d15.551666667N   -111d30
            +45.25919444444    111d30'000w

These exact ones won't work for us though since they are outside the area covered by the British National Grid.

Here's some WIP code to translate the easting and northing into grid ref letters:

function grid(easting, northing) {
    // Big 500kmx500km squares
    const big = [
        ['S', 'N', 'H'],
        ['T'],
    ]
    const fiveht = 500;
    const bigEasting = Math.floor(easting/fiveht)
    const bigNorthing = Math.floor(northing/fiveht)
    const first = big[bigEasting][bigNorthing];
    // Smaller 100kmx100km squares within each big one
    // I is not used, the cols are numbered left to right correctly,
    // but rows are numbered backwards, hence the funny order
    const letters = [
        'V', 'W', 'X', 'Y', 'Z',
        'Q', 'R', 'S', 'T', 'U',
        'L', 'M', 'N', 'O', 'P',
        'F', 'G', 'H', 'J', 'K',
        'A', 'B', 'C', 'D', 'E']
    const oneht = fiveht/5;
    const smallEasting = easting - (bigEasting*fiveht);
    const smallNorthing = northing - (bigNorthing*fiveht);
    const offsetEasting = Math.floor((smallEasting/oneht));
    const offsetNorthing = Math.floor(smallNorthing/oneht)*5;
    const second = letters[offsetNorthing+offsetEasting];
    const result = first + second;
    return result;
}


console.log(grid(0,0) == 'SV');
console.log(grid(323,599) == 'NY');
console.log(grid(531.12,182.85) === 'TQ');
console.log(grid(351.12,182.85) === 'ST');
console.log(grid(201,600) == 'NS');
console.log(grid(491.12,1101) === 'HU');

See also:

Copyright James Gardner 1996-2020 All Rights Reserved. Admin.