Library tutorials & articles

GPS- Deriving British Ordnance Survey Grid Reference from NMEA data

Part 2 - create NMEA2OSG class

The NMEA2OSG class will work in a similar way to the NMEAinterpreter class.
Latitude, longitude and ellipsoidal height will pe passed to the NMEA2OSG class which will then generate events producing the transformed data.

At this point I have to give thanks and credit to Roger Muggleton, the creator of the pages which detailed the necessary calculations. - (http://www.carabus.co.uk/)  and who kindly gave me permission to make use of his work.

Thanks are also due to Nick Daniels ( nickdaniels.com) for his invaluable advice on C# coding.

This is quite involved maths, and I am not going to try to explain all of it. It is the same as that used in the Ordnance Survey document A Guide to Coordinate Systems in Great Britain and converts latitude and longitude to a Transverse Mercator projection.

The NMEAinterpreter class produces latitude and longitude in the following form:-

52°09.1461"N         002°33.3717"W

In order to work mathematically with the latitude and longitude, they need to be converted into decimal values. So the first function of our class is to parse latitude and longitude and then pass them, along with ellipsoid height, to the transformation function.

We want to convert the minutes to degrees (divide by 60) and take account of the fact that Southerly and Westerly values are considered to be negative.



    public double deciLat;
    public double deciLon;

    public bool ParseNMEA(string Nlat, string Nlon, double height)     {      //grab the bit up to the °
     deciLat = Convert.ToDouble(Nlat.Substring(0, Nlat.IndexOf("°")));      deciLon = Convert.ToDouble(Nlon.Substring(0, Nlon.IndexOf("°")));      //remove that bit from the string now we've used it and the ° symbol      Nlat = Nlat.Substring(Nlat.IndexOf("°") + 1);      Nlon = Nlon.Substring(Nlon.IndexOf("°") + 1);      //grab the bit up to the ", divide it by 60 to convert to degrees
     //and add it to our double value
     deciLat += (Convert.ToDouble(Nlat.Substring(0, Nlat.IndexOf("\""))))/60;      deciLon += (Convert.ToDouble(Nlon.Substring(0, Nlat.IndexOf("\""))))/60;      //remove that part of the string now and just leave the compass direction
     Nlat = Nlat.Substring(Nlat.IndexOf("\"") + 1);      Nlon = Nlon.Substring(Nlon.IndexOf("\"") + 1);     // check for negative directions      if (Nlat == "S") deciLat = 0 - deciLat;      if (Nlon == "W") deciLon = 0 - deciLon;      //now we can transform them
     return Transform(deciLat, deciLon, height);     }

Now that we have our decimal values, we can transform them - see the next page.

Comments

Leave a comment

Sign in or Join us (it's free).

Alex Etchells

Related podcasts

  • Looking into the C# Crystal Ball with Charlie Calvert and Bill Wagner

    One of the most exciting announcements from PDC was the news about C# 4.0 and Visual Studio 2010. With all the excitement and discussion throughout the event about these new developer tools, we reached out to two experts in the fields. Charlie Calvert and Bill Wagner sat down with Keith and Woody...

We'd love to hear what you think! Submit ideas or give us feedback