none
Eastings Northings conversion to Latitude Longitude in C#

    Question

  • Hi All,

    We are developing an app using ASP.NET and C#

    We have a database full of locations - but they have their locations marked in the UK Ordnance Survey format of Eastings / Northings

    This needs converting to Latitude and Longitude for use in our Bingmap

    We had this sorted out in PHP, but are having a hard time finding a method for this in C#

    Anyone have any ideas or a direction to point me in?

    Cheers

    RAW
    Thursday, July 30, 2009 10:23 AM

Answers

  • Converting coordinates from Eastings/Northing to Latitude/Longitude is (relatively) simple - you can find all of the equations necessary to do so on the following guide:
    http://www.ordnancesurvey.co.uk/oswebsite/gps/docs/convertingcoordinatesEN.pdf (first example is lat/lon -> N/E, second example is N/E -> lat/lon).

    Note that this only converts the coordinates though - it does not transform the datum on which those coordinates are based. So if you're using N/E coordinates from the Ordnance Survey, the result will be lat/lon coordinates based on the Airy 1830 ellipsoid, NOT the WGS84 ellipsoid (which is what I suspect you actually want).

    To get results in WGS84, you can do an approximate Helmurt transformation based on the parameters listed in section 6.6 of the following:
    http://www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidecontents/guide6.html
    However, because there are distortions in the OSGB36 reference frame, this will only give an approximation. Different transformations are needed in different parts of Great Britain and you can't apply a simple Helmert datum transformation across the whole country.

    To get an accurate conversion, you need to apply the transformation grid specified by the OSTN02 transformation, but this is quite complex so I hope that you weren't expecting a few lines of C# code!
    Is there a reason why you have to do it in the application layer? If you have an existing database of information, I would recommend using a tool like Safe FME (http://www.safe.com) to do the conversion, and store the resulting WGS84 coordinates in a new column in the database rather than doing the transformation at run-time.


    Beginning Spatial with SQL Server http://www.apress.com/book/view/1430218290
    Thursday, July 30, 2009 11:53 AM
  • // from original work by Jonathan Stott

     

    using System;

    namespace os_latlong
    {
        public class LatLonConversions
        {
            const double a = 6377563.396;
            const double b = 6356256.91;
            const double e2 = (a - b) / a;
            const double n0 = -100000;
            const double e0 = 400000;
            const double f0 = 0.999601272;
            const double phi0 = 0.855211333;
            const double lambda0 = -0.034906585;
            const double n = (a - b) / (a + b);

            static double lat, lng;

            private LatLonConversions() { }

            private static double Deg2Rad(double x)
            {
              return x * (Math.PI / 180);
            }

            private static double Rad2Deg(double x) {
              return x * (180 / Math.PI);
            }

            private static double SinSquared(double x) {
              return Math.Sin(x) * Math.Sin(x);
            }

            private static double TanSquared(double x) {
              return Math.Tan(x) * Math.Tan(x);
            }

            private static double Sec( double x) {
              return 1.0 / Math.Cos(x);
            }

            private static void OSGB36ToWGS84()
            {
                var airy1830 = new RefEll(6377563.396, 6356256.909);
                var a = airy1830.maj;
                var b = airy1830.min;
                var eSquared = airy1830.ecc;
                var phi = Deg2Rad(lat);
                var lambda = Deg2Rad(lng);
                var v = a / (Math.Sqrt(1 - eSquared * SinSquared(phi)));
                var H = 0; // height
                var x = (v + H) * Math.Cos(phi) * Math.Cos(lambda);
                var y = (v + H) * Math.Cos(phi) * Math.Sin(lambda);
                var z = ((1 - eSquared) * v + H) * Math.Sin(phi);

                var tx = 446.448;
                var ty = -124.157;
                var tz = 542.060;
                var s = -0.0000204894;
                var rx = Deg2Rad(0.00004172222);
                var ry = Deg2Rad(0.00006861111);
                var rz = Deg2Rad(0.00023391666);

                var xB = tx + (x * (1 + s)) + (-rx * y) + (ry * z);
                var yB = ty + (rz * x) + (y * (1 + s)) + (-rx * z);
                var zB = tz + (-ry * x) + (rx * y) + (z * (1 + s));

                var wgs84 = new RefEll(6378137.000, 6356752.3141);
                a = wgs84.maj;
                b = wgs84.min;
                eSquared = wgs84.ecc;

                var lambdaB = Rad2Deg(Math.Atan(yB / xB));
                var p = Math.Sqrt((xB * xB) + (yB * yB));
                var phiN = Math.Atan(zB / (p * (1 - eSquared)));
                for (var i = 1; i < 10; i++)
                {
                    v = a / (Math.Sqrt(1 - eSquared * SinSquared(phiN)));
                    double phiN1 = Math.Atan((zB + (eSquared * v * Math.Sin(phiN))) / p);
                    phiN = phiN1;
                }

                var phiB = Rad2Deg(phiN);

                lat = phiB;
                lng = lambdaB;
            }

            public static LatLon ConvertOSToLatLon(double easting, double northing)
            {
                RefEll airy1830 = new RefEll(6377563.396, 6356256.909);
                double OSGB_F0 = 0.9996012717;
                double N0 = -100000.0;
                double E0 = 400000.0;
                double phi0 = Deg2Rad(49.0);
                double lambda0 = Deg2Rad(-2.0);
                double a = airy1830.maj;
                double b = airy1830.min;
                double eSquared = airy1830.ecc;
                double phi = 0.0;
                double lambda = 0.0;
                double E = easting;
                double N = northing;
                double n = (a - b) / (a + b);
                double M = 0.0;
                double phiPrime = ((N - N0) / (a * OSGB_F0)) + phi0;
                do
                {
                    M =
                      (b * OSGB_F0)
                        * (((1 + n + ((5.0 / 4.0) * n * n) + ((5.0 / 4.0) * n * n * n))
                          * (phiPrime - phi0))
                          - (((3 * n) + (3 * n * n) + ((21.0 / 8.0) * n * n * n))
                            * Math.Sin(phiPrime - phi0)
                            * Math.Cos(phiPrime + phi0))
                          + ((((15.0 / 8.0) * n * n) + ((15.0 / 8.0) * n * n * n))
                            * Math.Sin(2.0 * (phiPrime - phi0))
                            * Math.Cos(2.0 * (phiPrime + phi0)))
                          - (((35.0 / 24.0) * n * n * n)
                            * Math.Sin(3.0 * (phiPrime - phi0))
                            * Math.Cos(3.0 * (phiPrime + phi0))));
                    phiPrime += (N - N0 - M) / (a * OSGB_F0);
                } while ((N - N0 - M) >= 0.001);
                var v = a * OSGB_F0 * Math.Pow(1.0 - eSquared * SinSquared(phiPrime), -0.5);
                var rho =
                  a
                    * OSGB_F0
                    * (1.0 - eSquared)
                    * Math.Pow(1.0 - eSquared * SinSquared(phiPrime), -1.5);
                var etaSquared = (v / rho) - 1.0;
                var VII = Math.Tan(phiPrime) / (2 * rho * v);
                var VIII =
                  (Math.Tan(phiPrime) / (24.0 * rho * Math.Pow(v, 3.0)))
                    * (5.0
                      + (3.0 * TanSquared(phiPrime))
                      + etaSquared
                      - (9.0 * TanSquared(phiPrime) * etaSquared));
                var IX =
                  (Math.Tan(phiPrime) / (720.0 * rho * Math.Pow(v, 5.0)))
                    * (61.0
                      + (90.0 * TanSquared(phiPrime))
                      + (45.0 * TanSquared(phiPrime) * TanSquared(phiPrime)));
                var X = Sec(phiPrime) / v;
                var XI =
                  (Sec(phiPrime) / (6.0 * v * v * v))
                    * ((v / rho) + (2 * TanSquared(phiPrime)));
                var XII =
                  (Sec(phiPrime) / (120.0 * Math.Pow(v, 5.0)))
                    * (5.0
                      + (28.0 * TanSquared(phiPrime))
                      + (24.0 * TanSquared(phiPrime) * TanSquared(phiPrime)));
                var XIIA =
                  (Sec(phiPrime) / (5040.0 * Math.Pow(v, 7.0)))
                    * (61.0
                      + (662.0 * TanSquared(phiPrime))
                      + (1320.0 * TanSquared(phiPrime) * TanSquared(phiPrime))
                      + (720.0
                        * TanSquared(phiPrime)
                        * TanSquared(phiPrime)
                        * TanSquared(phiPrime)));
                phi =
                  phiPrime
                    - (VII * Math.Pow(E - E0, 2.0))
                    + (VIII * Math.Pow(E - E0, 4.0))
                    - (IX * Math.Pow(E - E0, 6.0));
                lambda =
                  lambda0
                    + (X * (E - E0))
                    - (XI * Math.Pow(E - E0, 3.0))
                    + (XII * Math.Pow(E - E0, 5.0))
                    - (XIIA * Math.Pow(E - E0, 7.0));


                lat = Rad2Deg(phi);
                lng = Rad2Deg(lambda);
                // convert to WGS84
                OSGB36ToWGS84();

                return new LatLon(lat, lng);
            }
        }

        public class RefEll
        {
            public double maj, min, ecc;
            public RefEll(double major, double minor)
            {
                maj = major;
                min = minor;
                ecc = ((major * major) - (minor * minor)) / (major * major);
            }
        }

        public class LatLon
        {
            public double Latitude;
            public double Longitude;

            public LatLon()
            {
                Latitude = 0;
                Longitude = 0;
            }

            public LatLon(double lat, double lon)
            {
                Latitude = lat;
                Longitude = lon;
            }
        }
    }



    Tuesday, July 12, 2011 10:45 PM
  • Use Proj4js or Proj4Net, it will be a lot easier and give you a lot more functionality. I personally stopped writing code to do these projections as these tools do the trick and are fast.

    http://trac.osgeo.org/proj4js/

    http://proj4net.codeplex.com/

    http://rbrundritt.wordpress.com

    Tuesday, September 25, 2012 10:32 AM

All replies

  • Converting coordinates from Eastings/Northing to Latitude/Longitude is (relatively) simple - you can find all of the equations necessary to do so on the following guide:
    http://www.ordnancesurvey.co.uk/oswebsite/gps/docs/convertingcoordinatesEN.pdf (first example is lat/lon -> N/E, second example is N/E -> lat/lon).

    Note that this only converts the coordinates though - it does not transform the datum on which those coordinates are based. So if you're using N/E coordinates from the Ordnance Survey, the result will be lat/lon coordinates based on the Airy 1830 ellipsoid, NOT the WGS84 ellipsoid (which is what I suspect you actually want).

    To get results in WGS84, you can do an approximate Helmurt transformation based on the parameters listed in section 6.6 of the following:
    http://www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidecontents/guide6.html
    However, because there are distortions in the OSGB36 reference frame, this will only give an approximation. Different transformations are needed in different parts of Great Britain and you can't apply a simple Helmert datum transformation across the whole country.

    To get an accurate conversion, you need to apply the transformation grid specified by the OSTN02 transformation, but this is quite complex so I hope that you weren't expecting a few lines of C# code!
    Is there a reason why you have to do it in the application layer? If you have an existing database of information, I would recommend using a tool like Safe FME (http://www.safe.com) to do the conversion, and store the resulting WGS84 coordinates in a new column in the database rather than doing the transformation at run-time.


    Beginning Spatial with SQL Server http://www.apress.com/book/view/1430218290
    Thursday, July 30, 2009 11:53 AM
  • Thanks a lot Tanoshimi :) I will chuck this at our developers :)

    *****

    We have also found the following code that seems to have done the trick, if anyone is interested.

    From http://www.hairy-spider.com/CategoryView,category,c-sharp.aspx

    using
     System;


    namespace tt
    {
    ///
    ///
    ///
    public class LatLonConversions
    {
    const double a = 6377563.396;
    const double b = 6356256.91;
    const double e2 = (a -b)/a;
    const double n0 = -100000;
    const double e0 = 400000;
    const double f0 = 0.999601272;
    const double phi0 = 0.855211333;
    const double lambda0 = -0.034906585;
    const double n = (a-b)/(a+b);


    private LatLonConversions()
    { }

    public static LatLon ConvertOSToLatLon(double E, double N)
    {
    double phi = 0;
    phi = (N-n0)/(a*f0) + phi0;
    double M = b * f0 * ( (1 + n + 5/4*n*n + 5/4*n*n*n)*(phi - phi0) - (3*n + 3*n*n + 21/8*n*n*n) * Math.Sin(phi-phi0) * Math.Cos(phi+phi0) +
    (15/8*n*n + 15/8*n*n*n) * Math.Sin(2*(phi-phi0))*Math.Cos(2*(phi+phi0))-35/24*n*n*n*Math.Sin(3*(phi-phi0))*Math.Cos(3*(phi+phi0)));

    while (N-n0-M>=0.01)
    {
    phi = (N-n0-M)/(a*f0)+phi;
    M = b * f0 * ( (1 + n + 5/4*n*n + 5/4*n*n*n)*(phi - phi0) - (3*n + 3*n*n + 21/8*n*n*n) * Math.Sin(phi-phi0) * Math.Cos(phi+phi0) +
    (15/8*n*n + 15/8*n*n*n) * Math.Sin(2*(phi-phi0))*Math.Cos(2*(phi+phi0))-35/24*n*n*n*Math.Sin(3*(phi-phi0))*Math.Cos(3*(phi+phi0)));
    }

    double v = a*f0*Math.Pow(1-e2*Math.Sin(phi)*Math.Sin(phi),-0.5);

    double p = a*f0*Math.Pow(1-e2*Math.Sin(phi)*Math.Sin(phi),-1.5)*(1-e2);
    double n2 = v/p-1;

    double vii = Math.Tan(phi)/(2*p*v);
    double viii = Math.Tan(phi)/(24*p*v*v*v)*(5+3*Math.Tan(phi)*Math.Tan(phi) + n2 - 9*Math.Tan(phi)*Math.Tan(phi)*n2);
    double ix = Math.Tan(phi)/(720*p*Math.Pow(v, 5)) * (61 + 90 * Math.Tan(phi) * Math.Tan(phi) + 45 * Math.Pow(Math.Tan(phi), 4));
    double x = (1/Math.Cos(phi))/v;
    double xi = (1/Math.Cos(phi))/(6*Math.Pow(v, 3)) * (v/p + 2*Math.Pow(Math.Tan(phi), 2));
    double xii = (1/Math.Cos(phi))/(120*Math.Pow(v, 5)) * (5 + 28*Math.Pow(Math.Tan(phi), 2) +24*Math.Pow(Math.Tan(phi), 4));
    double xiia = (1/Math.Cos(phi))/(5040*Math.Pow(v, 7)) * (61 + 662*Math.Pow(Math.Tan(phi), 2) +1320*Math.Pow(Math.Tan(phi), 4)+ 720*Math.Pow(Math.Tan(phi), 6));

    double e = (E-e0);
    double lon = (phi - vii * e*e + viii*e*e*e*e-ix*e*e*e*e*e*e ) * 180 / Math.PI;
    double lat = (lambda0 + x*e - xi*e*e*e + xii*e*e*e*e*e - xiia*e*e*e*e*e*e*e) *180 / Math.PI;



    return new LatLon(lon, lat);
    }
    }

    public class LatLon
    {
    public double Latitude;
    public double Longitude;


    public LatLon()
    {
    Latitude =0;
    Longitude =0;
    }

    public LatLon(double lat, double lon)
    {
    Latitude =lat;
    Longitude =lon;
    }

    }

    }
    Thursday, July 30, 2009 12:04 PM
  • That is exactly the same formula as in my first link (the author actually quotes the source at the top of the post), which performs a simple coordinate transformation.
    This code does not give you latitude and longitude coordinates in WGS84, as Bing Maps uses, but gives you angular coordinates based on the ellipsoid model used by the OSGB36 datum.
    Depending on your application, the error may be acceptable, but you should be aware.
    Beginning Spatial with SQL Server http://www.apress.com/book/view/1430218290
    Thursday, July 30, 2009 1:13 PM
  • One more thing - I suspect that the following line:
    return new LatLon(lon, lat);
     Should read:
    return new LatLon(lat, lon);

    (if not, that's a pretty poorly named structure!)
    Beginning Spatial with SQL Server http://www.apress.com/book/view/1430218290
    Thursday, July 30, 2009 1:16 PM
  • Yep Tanoshimi - this is exactly what is happening :D

    Our Pins are about 60m out to the south west a touch.

    So, we now have to figure out how to apply the Approximate WGS84 to OSGB36/ODN transformation or Helmert conversion to get the pins in place. I dont think we will need to get the specific conversion, the approximate one should do.

    I can find a lot of javascript and PHP code that will do this, but nothing that can be used in our ASP.NET or SQL app yet.

    The search continues for finding something that can make this work for us...
    Tuesday, August 04, 2009 2:28 PM
  • Did you see my earlier comment re: using a tool such as Safe FME to do this? You'll get more accurate results from a 'proper' GIS tool than a script on the internet, and you'll also get significantly better performance if you reproject and store the data it in your database as WGS84 rather than trying to do it on-the-fly in your application...
    Beginning Spatial with SQL Server http://www.apress.com/book/view/1430218290
    Tuesday, August 04, 2009 3:31 PM
  • Hi Tanoshimi :)

    Yep, I have visited that site a few times now trying to understand it.

    We are after storing the converted cords on the database. We have this working great in our PHP based version - our script will grab the data from the dataset we have with the eastings/northings - convert the cords to latitude long and store it in the database.

    We just cant find a script that does the same in our ASP.NET version using C#

    We would gladly pay to have a little script that does this, but I cant find anything like this on the Safe site.

    I will have a more in depth through their site tomorow.

    Cheers

    Raw
    Tuesday, August 04, 2009 4:01 PM
  • How complex is your PHP script? It's not too hard to convert from PHP to C# - just step through the function one line at a time.
    Is this a PHP function that you developed in-house, or is it publicly-available? If it's public, then paste it here and somebody might be able to help convert it to C# for you.
    Beginning Spatial with SQL Server http://www.apress.com/book/view/1430218290
    Tuesday, August 04, 2009 6:54 PM
  • Hi ,

    I am working on microsoft virtual map control.

    how to zoom virtual maps when user select two cities with line mark.

    Could you help me on this? if you have any code, could you share to me

    Thanks,

    Murali


    Murali Krishna.Konanki
    Saturday, August 08, 2009 3:21 PM
  • Hi,

    I am looking to do the same OSGB36 to WGS84  and back conversion for a GPS project and came across this post. Did you find any code to achieve this?
    Tuesday, October 27, 2009 4:10 PM
  • If I recall, we used the Helmert conversion - found a PHP based script on the web - and recoded this function for C#
    Tuesday, October 27, 2009 5:01 PM
  • Thanks for this, need to try this in my code.

    Am I right in saying the easting and northing are fed in as 'e' and 'n'

    and the results are 'Latitude' and 'Longitude'

     

    Many thanks

    Tuesday, December 07, 2010 3:14 PM
  • // from original work by Jonathan Stott

     

    using System;

    namespace os_latlong
    {
        public class LatLonConversions
        {
            const double a = 6377563.396;
            const double b = 6356256.91;
            const double e2 = (a - b) / a;
            const double n0 = -100000;
            const double e0 = 400000;
            const double f0 = 0.999601272;
            const double phi0 = 0.855211333;
            const double lambda0 = -0.034906585;
            const double n = (a - b) / (a + b);

            static double lat, lng;

            private LatLonConversions() { }

            private static double Deg2Rad(double x)
            {
              return x * (Math.PI / 180);
            }

            private static double Rad2Deg(double x) {
              return x * (180 / Math.PI);
            }

            private static double SinSquared(double x) {
              return Math.Sin(x) * Math.Sin(x);
            }

            private static double TanSquared(double x) {
              return Math.Tan(x) * Math.Tan(x);
            }

            private static double Sec( double x) {
              return 1.0 / Math.Cos(x);
            }

            private static void OSGB36ToWGS84()
            {
                var airy1830 = new RefEll(6377563.396, 6356256.909);
                var a = airy1830.maj;
                var b = airy1830.min;
                var eSquared = airy1830.ecc;
                var phi = Deg2Rad(lat);
                var lambda = Deg2Rad(lng);
                var v = a / (Math.Sqrt(1 - eSquared * SinSquared(phi)));
                var H = 0; // height
                var x = (v + H) * Math.Cos(phi) * Math.Cos(lambda);
                var y = (v + H) * Math.Cos(phi) * Math.Sin(lambda);
                var z = ((1 - eSquared) * v + H) * Math.Sin(phi);

                var tx = 446.448;
                var ty = -124.157;
                var tz = 542.060;
                var s = -0.0000204894;
                var rx = Deg2Rad(0.00004172222);
                var ry = Deg2Rad(0.00006861111);
                var rz = Deg2Rad(0.00023391666);

                var xB = tx + (x * (1 + s)) + (-rx * y) + (ry * z);
                var yB = ty + (rz * x) + (y * (1 + s)) + (-rx * z);
                var zB = tz + (-ry * x) + (rx * y) + (z * (1 + s));

                var wgs84 = new RefEll(6378137.000, 6356752.3141);
                a = wgs84.maj;
                b = wgs84.min;
                eSquared = wgs84.ecc;

                var lambdaB = Rad2Deg(Math.Atan(yB / xB));
                var p = Math.Sqrt((xB * xB) + (yB * yB));
                var phiN = Math.Atan(zB / (p * (1 - eSquared)));
                for (var i = 1; i < 10; i++)
                {
                    v = a / (Math.Sqrt(1 - eSquared * SinSquared(phiN)));
                    double phiN1 = Math.Atan((zB + (eSquared * v * Math.Sin(phiN))) / p);
                    phiN = phiN1;
                }

                var phiB = Rad2Deg(phiN);

                lat = phiB;
                lng = lambdaB;
            }

            public static LatLon ConvertOSToLatLon(double easting, double northing)
            {
                RefEll airy1830 = new RefEll(6377563.396, 6356256.909);
                double OSGB_F0 = 0.9996012717;
                double N0 = -100000.0;
                double E0 = 400000.0;
                double phi0 = Deg2Rad(49.0);
                double lambda0 = Deg2Rad(-2.0);
                double a = airy1830.maj;
                double b = airy1830.min;
                double eSquared = airy1830.ecc;
                double phi = 0.0;
                double lambda = 0.0;
                double E = easting;
                double N = northing;
                double n = (a - b) / (a + b);
                double M = 0.0;
                double phiPrime = ((N - N0) / (a * OSGB_F0)) + phi0;
                do
                {
                    M =
                      (b * OSGB_F0)
                        * (((1 + n + ((5.0 / 4.0) * n * n) + ((5.0 / 4.0) * n * n * n))
                          * (phiPrime - phi0))
                          - (((3 * n) + (3 * n * n) + ((21.0 / 8.0) * n * n * n))
                            * Math.Sin(phiPrime - phi0)
                            * Math.Cos(phiPrime + phi0))
                          + ((((15.0 / 8.0) * n * n) + ((15.0 / 8.0) * n * n * n))
                            * Math.Sin(2.0 * (phiPrime - phi0))
                            * Math.Cos(2.0 * (phiPrime + phi0)))
                          - (((35.0 / 24.0) * n * n * n)
                            * Math.Sin(3.0 * (phiPrime - phi0))
                            * Math.Cos(3.0 * (phiPrime + phi0))));
                    phiPrime += (N - N0 - M) / (a * OSGB_F0);
                } while ((N - N0 - M) >= 0.001);
                var v = a * OSGB_F0 * Math.Pow(1.0 - eSquared * SinSquared(phiPrime), -0.5);
                var rho =
                  a
                    * OSGB_F0
                    * (1.0 - eSquared)
                    * Math.Pow(1.0 - eSquared * SinSquared(phiPrime), -1.5);
                var etaSquared = (v / rho) - 1.0;
                var VII = Math.Tan(phiPrime) / (2 * rho * v);
                var VIII =
                  (Math.Tan(phiPrime) / (24.0 * rho * Math.Pow(v, 3.0)))
                    * (5.0
                      + (3.0 * TanSquared(phiPrime))
                      + etaSquared
                      - (9.0 * TanSquared(phiPrime) * etaSquared));
                var IX =
                  (Math.Tan(phiPrime) / (720.0 * rho * Math.Pow(v, 5.0)))
                    * (61.0
                      + (90.0 * TanSquared(phiPrime))
                      + (45.0 * TanSquared(phiPrime) * TanSquared(phiPrime)));
                var X = Sec(phiPrime) / v;
                var XI =
                  (Sec(phiPrime) / (6.0 * v * v * v))
                    * ((v / rho) + (2 * TanSquared(phiPrime)));
                var XII =
                  (Sec(phiPrime) / (120.0 * Math.Pow(v, 5.0)))
                    * (5.0
                      + (28.0 * TanSquared(phiPrime))
                      + (24.0 * TanSquared(phiPrime) * TanSquared(phiPrime)));
                var XIIA =
                  (Sec(phiPrime) / (5040.0 * Math.Pow(v, 7.0)))
                    * (61.0
                      + (662.0 * TanSquared(phiPrime))
                      + (1320.0 * TanSquared(phiPrime) * TanSquared(phiPrime))
                      + (720.0
                        * TanSquared(phiPrime)
                        * TanSquared(phiPrime)
                        * TanSquared(phiPrime)));
                phi =
                  phiPrime
                    - (VII * Math.Pow(E - E0, 2.0))
                    + (VIII * Math.Pow(E - E0, 4.0))
                    - (IX * Math.Pow(E - E0, 6.0));
                lambda =
                  lambda0
                    + (X * (E - E0))
                    - (XI * Math.Pow(E - E0, 3.0))
                    + (XII * Math.Pow(E - E0, 5.0))
                    - (XIIA * Math.Pow(E - E0, 7.0));


                lat = Rad2Deg(phi);
                lng = Rad2Deg(lambda);
                // convert to WGS84
                OSGB36ToWGS84();

                return new LatLon(lat, lng);
            }
        }

        public class RefEll
        {
            public double maj, min, ecc;
            public RefEll(double major, double minor)
            {
                maj = major;
                min = minor;
                ecc = ((major * major) - (minor * minor)) / (major * major);
            }
        }

        public class LatLon
        {
            public double Latitude;
            public double Longitude;

            public LatLon()
            {
                Latitude = 0;
                Longitude = 0;
            }

            public LatLon(double lat, double lon)
            {
                Latitude = lat;
                Longitude = lon;
            }
        }
    }



    Tuesday, July 12, 2011 10:45 PM
  • Sample usage for above, for all those who are being as dozy as me today:

    double east = 434885;
    double north = 0570925;

    txtLat.Text = LatLonConversions.ConvertOSToLatLon(east, north).Latitude.ToString();
    txtLng.Text = LatLonConversions.ConvertOSToLatLon(east, north).Longitude.ToString();

    Thursday, July 28, 2011 7:13 PM
  • Thanks Owen_g and JimGinhio, exactly what I have spent days searching for!

    Works like a charm.

    Friday, September 09, 2011 5:16 PM
  • Hi Owen,

    This is the first day in the new project and I am looking something like this to convert to latitude/ longitude from meters (points cordinates) for NZ map.

    I was told the points cordinates have to be converted to eastings & northing first and then to latitude / longitude.

    So just wondering whether can I use the same code for the above requirement?

    Thanks for your help!

    Cheers!

    KRT

    Tuesday, September 25, 2012 2:18 AM
  • Use Proj4js or Proj4Net, it will be a lot easier and give you a lot more functionality. I personally stopped writing code to do these projections as these tools do the trick and are fast.

    http://trac.osgeo.org/proj4js/

    http://proj4net.codeplex.com/

    http://rbrundritt.wordpress.com

    Tuesday, September 25, 2012 10:32 AM
  • Hi Richard,

    Thanks for your response, I am slightly confused after seeing their website, can you please brief me about what Proj4net application does and how it can be used.

    My understanding so far is like when we give input points value and we get the output as transformed point in longitude/latitude?

    can we use this as reference DLL in my project or do I need to use the code for the conversion part.

    Sorry if I am asking roookie questions

    Appreciate your help!

    Cheers!

    Thursday, September 27, 2012 2:18 AM
  • I'm not aware of any dll's. Adding one of the projects to your project solution should be easy enough to do. This tool provides you with the ability to pass in a coordinate and re-project it into another projection using code. You may also want to take a look at Proj.NET which has dll's: http://projnet.codeplex.com/releases/view/27838

    http://rbrundritt.wordpress.com

    Thursday, September 27, 2012 9:10 AM