Converting Latitude and Longitude to British National Grid in .Net and Mono
- 1 Introduction
- 2 Latitude and Longitude
- 3 Why so Many Datums
- 4 Different Coordinate Systems
- 5 Map Projections
- 6 Getting Started
- 7 British National Grid Example
- 8 Height
- 9 Obtaining Greater Accuracy
- 10 Summary
This article aims to demystify the concepts of transforming from one coordinate system to another. The article will walk through some C# examples, including how to convert from GPS coordinates to British National Grid and back again. The freely available GeoUK NuGet package is used for these examples. GeoUK was built as a Portable Class Library project (Profile 78) and as such can be added to Visual Studio or Xamarin and runs against .Net 4.5+, Windows Phone 8+, Xamarin.IOS/Android, Windows 8 Store Apps and so on. The product is licensed under the GNU Lesser General Public License (LGPL).
One thing I should mention is that this article is an greatly simplified discussion of a complex topic. Ordnance Survey (http://www.ordnancesurvey.co.uk/) provide detailed documentation in relation to coordinate systems used in the UK.
Latitude and Longitude
The earth is almost spherical. If you took a inflated beach ball, placed your foot on it and gently pressed, you would have a squashed sphere, referred to as an ellipsoid. The earth is ellipsoidal, albeit with a few lumps and bumps.
The Latitude and Longitude coordinate system can describe any point on earth, however, it can only do that if we have first defined the details of the earth such as the origins of the Latitude and Longitude system and the size and shape of the ellipsoid to be used. These definitions are referred to as a Datum. The thing is, different ellipsoids, and therefore different datums, are often used depending upon where in the world you are. In some cases several datums can be in use at the same location depending upon specific requirements. This means that Latitude and Longitude can only describe a point on the earth if we know which datum is being used. It can be shown that if a Latitude and Longitude based on the OSGB36 datum were entered into a GPS using a WGS84 datum, it would point to a different place. Therefore, being able to transform coordinates to and from different datums is essential, the examples shown later in the article will show how to do this in C# using the GeoUK package.
Why so Many Datums
Before moving on to discuss coordinate systems it is worth explaining why we use different ellipsoids, and therefore different datums. WGS84 is a standard datum used as the default in most GPS systems, so why not simply use that? The figure below shows a rough image of the earth with all of its lumps and bumps. The large ellipsoid whilst not fitting perfectly gives us a general ellipsoid that can be used all over the world, think of this as WGS84. However, the smaller ellipsoid can be seen to be a better fit for a small part of the earth. Therefore, if you happen to be on this small part of the earth, using this smaller ellipsoid would give greater accuracy. Hence, multiple ellipsoids and the need to convert between them. If you are in the UK, this smaller ellipsoid would be the Airy Ellipsoid, part of the OSGB36 datum. The ellipsoid was originally defined by Sir George Airy in 1830.
Something else to consider is that the WGS84 position of any particular point on the Earth’s surface is changing continuously due to various effects, the most important of which is tectonic motion. So WGS84 itself is unsuitable for mapping as the ground would keep sliding across the surface of any WGS84 based mapping grid. This is not the case with a system that covers a small region as the mapping grid can move also. As a result there are datums, in various parts of the world, that were based on the WGS84 datum at one point in time (Epoch), but have diverged from it slightly in order to account for land mass movement. One such datum in Europe is called ETRS89. More of that later.
Different Coordinate Systems
The Latitude and Longitude system is probably the most well known coordinate system. However, here in the UK, Ordnance Survey maps often use Eastings and Northings (Map References) as a coordinate system. Cartesian coordinates (X, Y and Z) can also be very useful. It is not the intention to describe Cartesian coordinates here, however, the code detailed below will use them in intermediate steps.
It is important to understand that converting between coordinates occurs within the same datum. Converting an OSGB36 Easting and Northing to Latitude and Longitude, returns a Latitude and Longitude based on the same OSGB36 datum. To convert these coordinates to Latitude and Longitude for a GPS using WGS84, a datum transformation is also required. The examples shown below will show how to do this in C# using the GeoUK package.
Before we get into the actual code it would be worth quickly discussing Projections.
A projection can be thought of any function that transfers points on an ellipsoid onto a plane surface such as a Map. For our purposes we can consider this to mean converting a Latitude and Longitude to an Easting and Northing. What this means is that any conversion to or from Easting/Northing coordinates, needs a Projection specifying.
The GeoUK package is a PCL78 assembly and can be used with .Net and Mono. Add the package to Xamarin or Visual Studio using the NuGet Package Manager prompt.
> Install-Package GeoUK
The first example takes an Ordnance Survey map Easting/Northing and transforms it to a GPS (WGS84) Latitude and Longitude. Therefore, a coordinate conversion is required (Easting/Northing to Latitude/Longitude) and a datum transformation is also required (OSGB36 to WGS84). As previously mentioned the ETRS89 datum is the European version of WGS84. In 1989 these datums were aligned, since then they have diverged very slightly, however, for our purposes we can consider them to be the same.
First the coordinate conversion. The Easting/Northing is from an Ordnance Survey map and is therefore using the OSGB36 datum with the Airy ellipsoid and the British National Grid projection (BNG).
Step 1: Convert to Cartesian.
using GeoUK; using GeoUK.Projections; using GeoUK.Coordinates; using GeoUK.Ellipsoids; ... // Given an easting and northing in metres (see text) const double easting = 651409.903; const double northing = 313177.270; // Convert to Cartesian var cartesian = Convert.ToCartesian (new Airy1830 (), new BritishNationalGrid (), new EastingNorthing ( easting, northing));
Step 2: Transform from OSBB36 datum to ETRS89 datum (see article text).
var wgsCartesian = Transform.OSBB36ToEtrs89 (cartesian); //ETRS89 is effectively WGS84
Now we have Cartesian results referencing the WGS84 datum (using the WGS84 ellipsoid) and can simply convert those to Latitude/Longitude.
Step 3: Convert back to Latitude/Longitude.
var wgsLatLong = Convert.ToLatitudeLongitude (new Wgs84 (), wgsCartesian);
To summarise, for a datum change of Easting Northing coordinates from datum A to datum B, first convert to Cartesian coordinates using the ellipsoid of datum A. Then apply a transformation from datum A to datum B before converting back to latitude/longitude using the ellipsoid of datum B. The same process is used going the other way.
British National Grid Example
The code below transforms from WGS84/ETRS89 Latitude/Longitude to OSGB36 Easting/Northing in the manner described above.
var latLong = new LatitudeLongitude(52.6579785974266, 1.71605194571289);
var cartesian = Convert.ToCartesian (new Wgs84 (), latLong); var bngCartesian = Transform.Etrs89ToOsgb36 (cartesian); var bngEN = Convert.ToEastingNorthing (new Airy1830 (), new BritishNationalGrid (), bngCartesian);
OS Map References
The map references (Easting/Northing) used in Ordnance Survey maps are divided into 500km squares which are sub-divided into 100km squares. These squares are given a two letter code. The first letter represents the 500km square and the second represents the 100km square within it. A six digit map reference would look something like TL123456 where the first two characters represents the 100km square as indicated on the map with the first three digits of the six representing the easting and the last three digits representing the northing. Using this system means that a map reference is quoted as an easting/northing (in metres) from the square’s origin. An EastingNorthing coordinate object, as returned from the transformation described above, can be converted to an OS map reference by using the Osgb36 class as follows.
// Convert to Osgb36 coordinates by creating a new object passing // in the EastingNorthing object to the constructor. var osgb36EN = new Osgb36(bngEN); var mapReference = osgb36EN.MapReference;
Height is a complex topic and there are many ways to measure it. The term ‘sea level’ is often used in conversation but the sea changes all of the time, large land mass has an effect on gravity and this affects the sea. Consider also that some of the earths highest mountains can be found under the sea. As I said it all gets very tricky very quickly.
As we have seen above, we use an ellipsoid to represent the earth in our conversions, this means that height when represented within the LatitudeLongitude coordinates object is usually ellipsoid height. Ellipsoid height is not very useful as point A can have a greater ellipsoid height than point B while being downhill of B. This is due to the fact that an ellipsoid is not a level surface as it does not take account of the irregularities that exist with the earths surface.
Image showing Geoid model compared to the ellipsoid.
A level surface is a surface that is at right angles to gravity at all points. This means that it must take account of the various bumps and lumps that affect gravity. A Geoid is a level surface and can be useful to measure height. A height measured in this way is called an Orthometric Height. A Geoid can be global (usually stated with a capital ‘G’) or can be local to a country or region (usually stated with a lower case ‘g’).
Ordnance Survey mapping on the British mainland uses the Ordnance Datum Newlyn (ODN) vertical coordinate system. ODN corresponds to the average sea level measured by the tide-gauge at Newlyn, Cornwall between 1915 and 1921. Heights that refer to this particular ‘mean sea level’ as the point of zero height are called ODN heights. ODN is therefore a local geoid definition as mentioned above. ODN heights are used for all British mainland Ordnance Survey contours, spot heights and bench mark heights. Many islands around Britain have their own ‘mean sea level’ (local geoid) based on local tide-gauges.
In terms of the examples detailed here relating to the transformation from WGS84 to OSGB36, the WGS ellipsoid height is converted to something like ODN heights, accuracy is around 5 meters in all directions.
Obtaining Greater Accuracy
In order to obtain greater accuracy when transforming ETRS89 (WGS84) coordinates to British National Grid, the Ordnance Survey Geoid Model (OSGM02) needs to be used. The OSGM02 can be thought of as a large rubber sheet covering Great Britain, Northern Island and the Republic of Ireland. Special transformations are applied to the data within the OSGM02 to transform from ETRS89 and OSGB36. For Great Britain the transformation is called OSTN02. The OSTN02 transformations combined with the ETRS89 positions of active GPS network stations represents the official definition of OSGB36 and can give very accurate transformations.
This rubber sheet geoid is effectively a lookup table that can be used to determine Othometric (geoid) heights and, via the OSTN transformation, accurate Easting and Northing coordinates. It is worth noting that Northern Island and the Republic of Ireland use the same geoid model but with a different transformation (OSi/OSNI) which, for now at least, is outside of the scope of this article.
The GeoUK.OSTN Nuget package extends the GeoUK package to include OSGM02/OSTN02 functionality and provides a simple method to make an accurate one-way transformation from ETRS89 to BNG. The package can be added to a project using the following Package Manager command. The package is dependent upon the GeoUK package and will add it as required.
> Install-Package GeoUK.OSTN
It should be noted that the GeoUK.OSTN package contains the OSGM02 geoid and OSTN02 transformation, as a result is fairly large at 38Mb. In addition, transformations will be slower than using the Helmert transformations as in the examples above.
The example below converts an ETRS89 Latitude/Longitude/Ellipsoid height to BNG Easting and Northing and ODN Height to within 10 centimetres or so.
var latLong = new LatitudeLongitude(52.658007833, 1.716073973, 108.05); var bng = GeoUK.OSTN.Transform.Etrs89ToOsgb (latLong);
This article discussed the various elements to be considered when converting from GPS coordinates to British National Grid. The Helmert transformation was demonstrated with an accuracy of around 5 meters in all directions and a more accurate method, that followed the Ordnance Survey recommended approach by using the OSGM02 geoid model, was also shown.
The library is provided free of charge via NuGet with the primary aim of simplifying an otherwise complex problem. If you wish to use the library for a commercial project and require technical support or advice, please feel free to get in touch.
Source code is available here https://bitbucket.org/johnnewcombe/geouk/src