public void EqualityTest_2(double e, double n, double h, double e2, double n2, double h2, bool e1) { EastingNorthing k = new EastingNorthing(e, n, h); EastingNorthing k2 = new EastingNorthing(e2, n2, h2); Assert.AreNotEqual(k, k2); }
/// <summary> /// Performs an OSGB36/ODN to ETRS89 datum transformation. Accuracy is approximately 10 centimeters. /// Whilst very accurate this method is much slower than the Helmert transformation. /// </summary> public static LatitudeLongitude OsgbToEtrs89(Osgb36 coordinates, OstnVersionEnum ostnVersion = OstnVersionEnum.OSTN15) { //calculate shifts from OSGB36 point double errorN = double.MaxValue; double errorE = double.MaxValue; EastingNorthing enCoordinates = null; Shifts shiftsA = GetShifts(coordinates, ostnVersion); //0.0001 error meters int iter = 0; while ((errorN > 0.0001 || errorE > 0.0001) && iter < 10) { enCoordinates = new EastingNorthing(coordinates.Easting - shiftsA.Se, coordinates.Northing - shiftsA.Sn); Shifts shiftsB = GetShifts(enCoordinates, ostnVersion); errorE = Math.Abs(shiftsA.Se - shiftsB.Se); errorN = Math.Abs(shiftsA.Sn - shiftsB.Sn); shiftsA = shiftsB; iter++; } return(Convert.ToLatitudeLongitude(new Wgs84(), new BritishNationalGrid(), enCoordinates)); }
public void EqualityTest(double e, double n, double h, bool e1) { EastingNorthing k = new EastingNorthing(e, n, h); EastingNorthing k2 = new EastingNorthing(e, n, h); Assert.AreEqual(k, k2); }
public void ToString_Test() { EastingNorthing k = new EastingNorthing(10, 20, 30); string outcome = k.ToString(); string expected = "Easting:10 Northing:20 Height:30"; Assert.AreEqual(expected, outcome); }
private static Osgb36 Etrs89ToOsgb(EastingNorthing coordinates, double ellipsoidHeight, OstnVersionEnum ostnVersion = OstnVersionEnum.OSTN15) { Shifts shifts = GetShifts(coordinates, ostnVersion); double easting = coordinates.Easting + shifts.Se; double northing = coordinates.Northing + shifts.Sn; double height = ellipsoidHeight - shifts.Sg; return(new Osgb36(easting, northing, height, shifts.GeoidDatum)); }
public void To_OSGB36(double a, double b, double c, double e, double f, double g) { ICoodrinateSupport q = new CoordinateSupport(); ToOSGB36 k = new ToOSGB36(Shifts_, q); var Outcome = k.Calculate(a, b, c); EastingNorthing Expected = new EastingNorthing(e, f, g); Assert.AreEqual(Expected, Outcome); }
/// <summary> /// Calling this method will convert from the passed value to the OSGB36 /// </summary> /// <param name="pCoordinate">The latitude and longtitude to be converted </param> /// <returns>The location as a OSGB36 coordinate</returns> public ICoordinate Calculate(ICoordinate pCoordinate) { if (pCoordinate.GetType() != typeof(EastingNorthing)) { throw new CoordinateTypeException("the wrong coordinate type has been passed"); } else { EastingNorthing p = (EastingNorthing)pCoordinate; return(Calculate(p.Easting, p.Northing, p.Height)); } }
public void Test_ToLatLon_AsCoodrinate(double a, double b, double c, double e, double f, double g) { ICoodrinateSupport q = new CoordinateSupport(); ToLatLon k = new ToLatLon(Shifts_, q); EastingNorthing n = new EastingNorthing(f, e, g); var Outcome = (LatLon)k.Calculate(n); LatLon Expected = new LatLon(a, b, c); Assert.AreEqual(Expected.Latitude, Outcome.Latitude, 0.01); Assert.AreEqual(Expected.Longtitude, Outcome.Longtitude, 0.01); Assert.AreEqual(Expected.Height, Outcome.Height, 0.01); }
/// <summary> /// Calling this method will convert from the passed value to the OSGB36 convertor /// </summary> /// <param name="pHorizontal">The point on the horizontal axis (easting or latitude)</param> /// <param name="pVertical">The point on the vertical axis (northing or longtitude)</param> /// <param name="pHeight">The height to be converted</param> /// <returns>The location as a OSGB36 coordinate</returns> private ICoordinate InternalCalculate(double pHorizontal, double pVertical, double pHeight) { double lat = mCoordinateSupport.DegreeesToRadians(pVertical); double lon = mCoordinateSupport.DegreeesToRadians(pHorizontal); double ht = pHeight; double a = OSGB35Constants.a; a *= OSGB35Constants.f0; double b = OSGB35Constants.b; b *= OSGB35Constants.f0; double n = (a - b) / (a + b); double e2 = ((a * a) - (b * b)) / (a * a); double nu = (a / Math.Pow(1 - e2 * Math.Pow(Math.Sin(lat), 2.0), 0.5)); double rho = ((a * (1 - e2)) / Math.Pow(1 - e2 * Math.Pow(Math.Sin(lat), 2.0), 1.5)); double n2 = (nu / rho) - 1; double dLat = lat - OSGB35Constants.lat0; // difference in latitude double sLat = lat + OSGB35Constants.lat0; // sum of latitude double M = MeridianArc.ComputeMeridanArc(dLat, sLat, n, b); double P = lon - OSGB35Constants.lon0; // difference in longitude // The following are taken from [1] pp10-11 double I = M + OSGB35Constants.n0; double II = (nu / 2) * Math.Sin(lat) * Math.Cos(lat); double III = (nu / 24) * Math.Sin(lat) * Math.Pow(Math.Cos(lat), 3.0) * (5 - Math.Pow(Math.Tan(lat), 2.0) + (9 * n2)); double IIIA = (nu / 720) * Math.Sin(lat) * Math.Pow(Math.Cos(lat), 5.0) * (61 - (58 * Math.Pow(Math.Tan(lat), 2.0)) + Math.Pow(Math.Tan(lat), 4.0)); double IV = nu * Math.Cos(lat); double V = (nu / 6) * Math.Pow(Math.Cos(lat), 3.0) * ((nu / rho) - Math.Pow(Math.Tan(lat), 2.0)); double VI = (nu / 120) * Math.Pow(Math.Cos(lat), 5.0) * (5 - (18 * Math.Pow(Math.Tan(lat), 2.0)) + Math.Pow(Math.Tan(lat), 4.0) + (14 * n2) - (58 * Math.Pow(Math.Tan(lat), 2.0) * n2)); double y = I + (Math.Pow(P, 2.0) * II) + (Math.Pow(P, 4.0) * III) + (Math.Pow(P, 6.0) * IIIA); double x = OSGB35Constants.e0 + (P * IV) + (Math.Pow(P, 3.0) * V) + (Math.Pow(P, 5.0) * VI); Shift s = (Shift)mShifts.CalculateShift(x, y); double lLat = x + s.Easting; double lLon = y + s.Northing; double lHeight = pHeight - s.Height; EastingNorthing x1 = new EastingNorthing(lLat, lLon, lHeight); return(x1); }
public static void Example() { Console.WriteLine("-- Latitude/ Longitude to Easting/ Northing --"); LatitudeLongitude latLong = new LatitudeLongitude(51.469886, -3.1636964); Console.WriteLine("INPUT"); Console.WriteLine($"Latitude: {latLong.Latitude}"); Console.WriteLine($"Longitude: {latLong.Longitude}"); Cartesian cartesian = Convert.ToCartesian(new Wgs84(), latLong); Cartesian bngCartesian = Transform.Etrs89ToOsgb36(cartesian); EastingNorthing bngEN = Convert.ToEastingNorthing(new Airy1830(), new BritishNationalGrid(), bngCartesian); Console.WriteLine("OUTPUT"); Console.WriteLine($"Easting: {bngEN.Easting}"); Console.WriteLine($"Northing: {bngEN.Northing}"); Console.WriteLine(); }
public static void Examples() { Console.WriteLine("-- OS Map reference --"); // Convert to Osgb36 coordinates by creating a new object passing // in the EastingNorthing object to the constructor. EastingNorthing eastingNorthing = new EastingNorthing(319267, 175189); Console.WriteLine("INPUT"); Console.WriteLine($"Easting: {eastingNorthing.Easting}"); Console.WriteLine($"Northing: {eastingNorthing.Northing}"); Osgb36 osgb36EN = new Osgb36(eastingNorthing); string mapReference = osgb36EN.MapReference; Console.WriteLine("OUTPUT"); Console.WriteLine($"Map reference: {mapReference}"); Console.WriteLine(); }
/// <summary> /// Method to convert from Easting Northing coordinates to Latitude Longitude coordinates. /// </summary> /// <returns>The latitude longitude.</returns> /// <param name = "ellipsoid"></param> /// <param name="projection">Projection.</param> /// <param name="coordinates">Coordinates.</param> public static LatitudeLongitude ToLatitudeLongitude(Ellipsoid ellipsoid, Projection projection, EastingNorthing coordinates) { double M; double N = coordinates.Northing; double E = coordinates.Easting; //from OS Guide //constants needed are a Semi-Major Axis , b , e2 , N0 , E0 , F0 ,φ0 , and λ0 double a = ellipsoid.SemiMajorAxis; double b = ellipsoid.SemiMinorAxis; double e2 = ellipsoid.EccentricitySquared; double F0 = projection.ScaleFactor; double lat0 = ToRadians(projection.TrueOriginLatitude); double lon0 = ToRadians(projection.TrueOriginLongitude); double E0 = projection.TrueOriginEasting; double N0 = projection.TrueOriginNorthing; double lat = ((N - N0) / (a * F0)) + lat0; //check for error and reiterate as required int loopCount = 0; do { M = CalculateM(lat, lat0, a, b, F0); lat += ((N - N0 - M) / (a * F0)); loopCount++; } while (!IsNearlyZero(N - N0 - M, 1e-16) && loopCount < 10); double v = a * F0 * Math.Pow((1 - e2 * Math.Pow(Math.Sin(lat), 2)), -0.5); double p = a * F0 * (1 - e2) * Math.Pow((1 - e2 * Math.Pow(Math.Sin(lat), 2)), -1.5); double n2 = (v / p) - 1; double VII = Math.Tan(lat) / (2 * p * v); double VIIIa = Math.Tan(lat) / (24 * p * Math.Pow(v, 3)); double VIIIb = 5 + (3 * Math.Pow(Math.Tan(lat), 2)) + n2 - 9 * (Math.Pow(Math.Tan(lat), 2)) * n2; double VIII = VIIIa * VIIIb; double IXa = Math.Tan(lat) / (720 * p * Math.Pow(v, 5)); double IXb = 61 + (90 * Math.Pow(Math.Tan(lat), 2)) + (45 * Math.Pow(Math.Tan(lat), 4)); double IX = IXa * IXb; double X = MathEx.Secant(lat) / v; double XIa = MathEx.Secant(lat) / (6 * Math.Pow(v, 3)); double XIb = v / p + (2 * Math.Pow(Math.Tan(lat), 2)); double XI = XIa * XIb; double XIIa = MathEx.Secant(lat) / (120 * Math.Pow(v, 5)); double XIIb = 5 + (28 * Math.Pow(Math.Tan(lat), 2)) + (24 * Math.Pow(Math.Tan(lat), 4)); double XII = XIIa * XIIb; double XIIAa = MathEx.Secant(lat) / (5040 * Math.Pow(v, 7)); double XIIAb = 61 + (662 * Math.Pow(Math.Tan(lat), 2)) + (1320 * Math.Pow(Math.Tan(lat), 4)) + (720 * Math.Pow(Math.Tan(lat), 6)); double XIIA = XIIAa * XIIAb; lat = lat - VII * Math.Pow(E - E0, 2) + VIII * Math.Pow(E - E0, 4) - IX * Math.Pow(E - E0, 6); double lon = lon0 + X * (E - E0) - XI * Math.Pow(E - E0, 3) + XII * Math.Pow(E - E0, 5) - XIIA * Math.Pow(E - E0, 7); return(new LatitudeLongitude(ToDegrees(lat), ToDegrees(lon))); }
public static Cartesian ToCartesian(Ellipsoid ellipsoid, Projection projection, EastingNorthing coordinates) { LatitudeLongitude latLongCoordinates = ToLatitudeLongitude( ellipsoid, projection, coordinates); return(ToCartesian(ellipsoid, latLongCoordinates)); }
private static Shifts GetShifts(EastingNorthing coordinates, OstnVersionEnum ostnVersion) { //See OS Document: Transformations and OSGM02/OSGM15 user guide chapter 3 Dictionary <int, OstnDataRecord> ostnData = GetOstnData(ostnVersion); List <int> recordNumbers = new List <int>(); OstnDataRecord[] records = new OstnDataRecord[4]; //determine record numbers int eastIndex = (int)(coordinates.Easting / 1000.0); int northIndex = (int)(coordinates.Northing / 1000.0); double x0 = eastIndex * 1000; double y0 = northIndex * 1000; //work out the four records recordNumbers.Add(CalculateRecordNumber(eastIndex, northIndex)); recordNumbers.Add(CalculateRecordNumber(eastIndex + 1, northIndex)); recordNumbers.Add(CalculateRecordNumber(eastIndex + 1, northIndex + 1)); recordNumbers.Add(CalculateRecordNumber(eastIndex, northIndex + 1)); // Get the corresponding records from the data dictionary for (int index = 0; index < 4; index++) { records[index] = ostnData[recordNumbers[index]]; } //populate the properties double se0 = System.Convert.ToDouble(records[0].ETRS89_OSGB36_EShift); double se1 = System.Convert.ToDouble(records[1].ETRS89_OSGB36_EShift); double se2 = System.Convert.ToDouble(records[2].ETRS89_OSGB36_EShift); double se3 = System.Convert.ToDouble(records[3].ETRS89_OSGB36_EShift); double sn0 = System.Convert.ToDouble(records[0].ETRS89_OSGB36_NShift); double sn1 = System.Convert.ToDouble(records[1].ETRS89_OSGB36_NShift); double sn2 = System.Convert.ToDouble(records[2].ETRS89_OSGB36_NShift); double sn3 = System.Convert.ToDouble(records[3].ETRS89_OSGB36_NShift); double sg0 = System.Convert.ToDouble(records[0].ETRS89_ODN_HeightShift); double sg1 = System.Convert.ToDouble(records[1].ETRS89_ODN_HeightShift); double sg2 = System.Convert.ToDouble(records[2].ETRS89_ODN_HeightShift); double sg3 = System.Convert.ToDouble(records[3].ETRS89_ODN_HeightShift); double dx = coordinates.Easting - x0; double dy = coordinates.Northing - y0; double t = dx / 1000.0; double u = dy / 1000.0; Shifts shifts = new Shifts { Se = (1 - t) * (1 - u) * se0 + t * (1 - u) * se1 + t * u * se2 + (1 - t) * u * se3, Sn = (1 - t) * (1 - u) * sn0 + t * (1 - u) * sn1 + t * u * sn2 + (1 - t) * u * sn3, Sg = (1 - t) * (1 - u) * sg0 + t * (1 - u) * sg1 + t * u * sg2 + (1 - t) * u * sg3, GeoidDatum = (Osgb36GeoidDatum)System.Convert.ToInt32(records[0].Height_Datum_Flag) }; return(shifts); }
/// <summary> /// Performs an ETRS89 to OSGB36/ODN datum transformation. Accuracy is approximately 10 centimeters. /// Whilst very accurate this method is much slower than the Helmert transformation. /// </summary> public static Osgb36 Etrs89ToOsgb(LatitudeLongitude coordinates) { EastingNorthing enCoordinates = Convert.ToEastingNorthing(new Grs80(), new BritishNationalGrid(), coordinates); return(Etrs89ToOsgb(enCoordinates, coordinates.EllipsoidalHeight)); }
private static Osgb36 Etrs89ToOsgb(EastingNorthing coordinates, double ellipsoidHeight) { Stream dataStream = GetEmbeddedOSTN02(); TextReader tr = new StreamReader(dataStream); List <int> recordNumbers = new List <int>(); string[] records = new string[4]; //determine record numbers int eastIndex = (int)(coordinates.Easting / 1000.0); int northIndex = (int)(coordinates.Northing / 1000.0); double x0 = eastIndex * 1000; double y0 = northIndex * 1000; //work out the four records recordNumbers.Add(CalculateRecordNumber(eastIndex, northIndex)); recordNumbers.Add(CalculateRecordNumber(eastIndex + 1, northIndex)); recordNumbers.Add(CalculateRecordNumber(eastIndex + 1, northIndex + 1)); recordNumbers.Add(CalculateRecordNumber(eastIndex, northIndex + 1)); //get records from the data file int recordsFound = 0; while (recordsFound < 4) { string csvRecord = tr.ReadLine(); for (int index = 0; index < 4; index++) { if (csvRecord != null && !csvRecord.StartsWith(recordNumbers[index].ToString().Trim() + ",", StringComparison.Ordinal)) { continue; } //don't use add as we need to keep these in same order as record numbers records[index] = csvRecord; recordsFound++; } } //populate the properties string[] fields0 = records[0].Split(",".ToCharArray()); string[] fields1 = records[1].Split(",".ToCharArray()); string[] fields2 = records[2].Split(",".ToCharArray()); string[] fields3 = records[3].Split(",".ToCharArray()); double se0 = System.Convert.ToDouble(fields0[3]); double se1 = System.Convert.ToDouble(fields1[3]); double se2 = System.Convert.ToDouble(fields2[3]); double se3 = System.Convert.ToDouble(fields3[3]); double sn0 = System.Convert.ToDouble(fields0[4]); double sn1 = System.Convert.ToDouble(fields1[4]); double sn2 = System.Convert.ToDouble(fields2[4]); double sn3 = System.Convert.ToDouble(fields3[4]); double sg0 = System.Convert.ToDouble(fields0[5]); double sg1 = System.Convert.ToDouble(fields1[5]); double sg2 = System.Convert.ToDouble(fields2[5]); double sg3 = System.Convert.ToDouble(fields3[5]); double dx = coordinates.Easting - x0; double dy = coordinates.Northing - y0; double t = dx / 1000.0; double u = dy / 1000.0; double se = (1 - t) * (1 - u) * se0 + t * (1 - u) * se1 + t * u * se2 + (1 - t) * u * se3; double sn = (1 - t) * (1 - u) * sn0 + t * (1 - u) * sn1 + t * u * sn2 + (1 - t) * u * sn3; double sg = (1 - t) * (1 - u) * sg0 + t * (1 - u) * sg1 + t * u * sg2 + (1 - t) * u * sg3; Osgb36GeoidDatum geoidDatum = (Osgb36GeoidDatum)System.Convert.ToInt32(fields0[6]); double easting = coordinates.Easting + se; double northing = coordinates.Northing + sn; double height = ellipsoidHeight - sg; return(new Osgb36(easting, northing, height, geoidDatum)); }