From cdc3855537ddd0af14afdc78a93b04598e33606a Mon Sep 17 00:00:00 2001 From: Ieuan Walker Date: Tue, 16 Jul 2019 13:20:17 +0100 Subject: [PATCH] Code updates based on Codacy and updated test project from .net framework to .net core --- Demo/DemoProject/Program.cs | 6 +- GeoUK.OSTN.Tests/GeoUK.OSTN.Tests.csproj | 138 ------ GeoUK.OSTN.Tests/Properties/AssemblyInfo.cs | 35 -- GeoUK.OSTN.Tests/packages.config | 13 - .../ExtensionMethods.cs | 2 +- GeoUK.OSTN.XUnit/GeoUK.OSTN.XUnit.csproj | 64 +++ .../Models/DataPoint.cs | 2 +- .../OSGM15_NI_TestInput_ETRS89toIG.txt | 0 .../OSGM15_NI_TestInput_IGtoETRS89.txt | 0 .../OSGM15_NI_TestOutput_ETRS89toIG.txt | 0 .../OSGM15_NI_TestOutput_IGtoETRS89.txt | 0 .../OSTN15_OSGM15_TestFiles_README.txt | 0 .../OSTN15_OSGM15_TestInput_ETRStoOSGB.txt | 0 .../OSTN15_OSGM15_TestInput_OSGBtoETRS.txt | 0 .../OSTN15_OSGM15_TestOutput_ETRStoOSGB.txt | 0 .../OSTN15_OSGM15_TestOutput_OSGBtoETRS.txt | 0 .../TransformTests.cs | 8 +- GeoUK.OSTN.sln | 14 +- GeoUK/Convert.cs | 461 +++++++++--------- GeoUK/Coordinates/Osgb36.cs | 215 ++++---- 20 files changed, 416 insertions(+), 542 deletions(-) delete mode 100644 GeoUK.OSTN.Tests/GeoUK.OSTN.Tests.csproj delete mode 100644 GeoUK.OSTN.Tests/Properties/AssemblyInfo.cs delete mode 100644 GeoUK.OSTN.Tests/packages.config rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/ExtensionMethods.cs (95%) create mode 100644 GeoUK.OSTN.XUnit/GeoUK.OSTN.XUnit.csproj rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/Models/DataPoint.cs (84%) rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestInput_ETRS89toIG.txt (100%) rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestInput_IGtoETRS89.txt (100%) rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestOutput_ETRS89toIG.txt (100%) rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestOutput_IGtoETRS89.txt (100%) rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestFiles_README.txt (100%) rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestInput_ETRStoOSGB.txt (100%) rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestInput_OSGBtoETRS.txt (100%) rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestOutput_ETRStoOSGB.txt (100%) rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestOutput_OSGBtoETRS.txt (100%) rename {GeoUK.OSTN.Tests => GeoUK.OSTN.XUnit}/TransformTests.cs (98%) diff --git a/Demo/DemoProject/Program.cs b/Demo/DemoProject/Program.cs index e68f089..7939456 100644 --- a/Demo/DemoProject/Program.cs +++ b/Demo/DemoProject/Program.cs @@ -3,9 +3,9 @@ using DemoProject.Examples; namespace DemoProject { - class Program + internal class Program { - static void Main() + private static void Main() { EastingNorthingToLatitudeLongitude.Example(); @@ -18,4 +18,4 @@ namespace DemoProject Console.ReadKey(); } } -} +} \ No newline at end of file diff --git a/GeoUK.OSTN.Tests/GeoUK.OSTN.Tests.csproj b/GeoUK.OSTN.Tests/GeoUK.OSTN.Tests.csproj deleted file mode 100644 index fc1416d..0000000 --- a/GeoUK.OSTN.Tests/GeoUK.OSTN.Tests.csproj +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - Debug - AnyCPU - {7DAF4F03-B372-43B2-A22C-64C2790BCF68} - Library - Properties - GeoUK.OSTN.Tests - GeoUK.OSTN.Tests - v4.7.2 - 512 - - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Microsoft.CodeCoverage.16.2.0\lib\net45\Microsoft.VisualStudio.CodeCoverage.Shim.dll - - - - - - - - - - - ..\packages\xunit.abstractions.2.0.3\lib\net35\xunit.abstractions.dll - - - ..\packages\xunit.assert.2.4.1\lib\netstandard1.1\xunit.assert.dll - - - ..\packages\xunit.extensibility.core.2.4.1\lib\net452\xunit.core.dll - - - ..\packages\xunit.extensibility.execution.2.4.1\lib\net452\xunit.execution.desktop.dll - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - {e7c614ac-e67d-4e04-ba4e-e1bbf4cac6fd} - GeoUK.OSTN - - - {5c458fbf-4e2a-4f9d-acc2-9ce5bed34236} - GeoUK - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - - - \ No newline at end of file diff --git a/GeoUK.OSTN.Tests/Properties/AssemblyInfo.cs b/GeoUK.OSTN.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 1cc6ec1..0000000 --- a/GeoUK.OSTN.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("GeoUK.OSTN.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GeoUK.OSTN.Tests")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7daf4f03-b372-43b2-a22c-64c2790bcf68")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/GeoUK.OSTN.Tests/packages.config b/GeoUK.OSTN.Tests/packages.config deleted file mode 100644 index 7b476da..0000000 --- a/GeoUK.OSTN.Tests/packages.config +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/GeoUK.OSTN.Tests/ExtensionMethods.cs b/GeoUK.OSTN.XUnit/ExtensionMethods.cs similarity index 95% rename from GeoUK.OSTN.Tests/ExtensionMethods.cs rename to GeoUK.OSTN.XUnit/ExtensionMethods.cs index 4fa1564..f02727d 100644 --- a/GeoUK.OSTN.Tests/ExtensionMethods.cs +++ b/GeoUK.OSTN.XUnit/ExtensionMethods.cs @@ -1,6 +1,6 @@ using System; -namespace GeoUK.OSTN.Tests +namespace GeoUK.OSTN.XUnit { // Source: https://scottlilly.com/c-tip-how-to-check-if-two-double-values-are-equal/ public static class ExtensionMethods diff --git a/GeoUK.OSTN.XUnit/GeoUK.OSTN.XUnit.csproj b/GeoUK.OSTN.XUnit/GeoUK.OSTN.XUnit.csproj new file mode 100644 index 0000000..fd0f6fc --- /dev/null +++ b/GeoUK.OSTN.XUnit/GeoUK.OSTN.XUnit.csproj @@ -0,0 +1,64 @@ + + + + netcoreapp2.2 + + false + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + \ No newline at end of file diff --git a/GeoUK.OSTN.Tests/Models/DataPoint.cs b/GeoUK.OSTN.XUnit/Models/DataPoint.cs similarity index 84% rename from GeoUK.OSTN.Tests/Models/DataPoint.cs rename to GeoUK.OSTN.XUnit/Models/DataPoint.cs index f113d32..8905003 100644 --- a/GeoUK.OSTN.Tests/Models/DataPoint.cs +++ b/GeoUK.OSTN.XUnit/Models/DataPoint.cs @@ -1,4 +1,4 @@ -namespace GeoUK.OSTN.Tests.Models +namespace GeoUK.OSTN.XUnit.Models { public class DataPoint { diff --git a/GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestInput_ETRS89toIG.txt b/GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestInput_ETRS89toIG.txt similarity index 100% rename from GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestInput_ETRS89toIG.txt rename to GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestInput_ETRS89toIG.txt diff --git a/GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestInput_IGtoETRS89.txt b/GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestInput_IGtoETRS89.txt similarity index 100% rename from GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestInput_IGtoETRS89.txt rename to GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestInput_IGtoETRS89.txt diff --git a/GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestOutput_ETRS89toIG.txt b/GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestOutput_ETRS89toIG.txt similarity index 100% rename from GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestOutput_ETRS89toIG.txt rename to GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestOutput_ETRS89toIG.txt diff --git a/GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestOutput_IGtoETRS89.txt b/GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestOutput_IGtoETRS89.txt similarity index 100% rename from GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestOutput_IGtoETRS89.txt rename to GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSGM15_NI_TestOutput_IGtoETRS89.txt diff --git a/GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestFiles_README.txt b/GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestFiles_README.txt similarity index 100% rename from GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestFiles_README.txt rename to GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestFiles_README.txt diff --git a/GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestInput_ETRStoOSGB.txt b/GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestInput_ETRStoOSGB.txt similarity index 100% rename from GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestInput_ETRStoOSGB.txt rename to GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestInput_ETRStoOSGB.txt diff --git a/GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestInput_OSGBtoETRS.txt b/GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestInput_OSGBtoETRS.txt similarity index 100% rename from GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestInput_OSGBtoETRS.txt rename to GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestInput_OSGBtoETRS.txt diff --git a/GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestOutput_ETRStoOSGB.txt b/GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestOutput_ETRStoOSGB.txt similarity index 100% rename from GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestOutput_ETRStoOSGB.txt rename to GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestOutput_ETRStoOSGB.txt diff --git a/GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestOutput_OSGBtoETRS.txt b/GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestOutput_OSGBtoETRS.txt similarity index 100% rename from GeoUK.OSTN.Tests/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestOutput_OSGBtoETRS.txt rename to GeoUK.OSTN.XUnit/TestDataFiles_OSGM15_OSTN15/OSTN15_OSGM15_TestOutput_OSGBtoETRS.txt diff --git a/GeoUK.OSTN.Tests/TransformTests.cs b/GeoUK.OSTN.XUnit/TransformTests.cs similarity index 98% rename from GeoUK.OSTN.Tests/TransformTests.cs rename to GeoUK.OSTN.XUnit/TransformTests.cs index cd239a6..0d2e39b 100644 --- a/GeoUK.OSTN.Tests/TransformTests.cs +++ b/GeoUK.OSTN.XUnit/TransformTests.cs @@ -1,11 +1,11 @@ -using GeoUK.Coordinates; -using GeoUK.OSTN.Tests.Models; -using System; +using System; using System.Collections.Generic; using System.IO; +using GeoUK.Coordinates; +using GeoUK.OSTN.XUnit.Models; using Xunit; -namespace GeoUK.OSTN.Tests +namespace GeoUK.OSTN.XUnit { public class TransformTests { diff --git a/GeoUK.OSTN.sln b/GeoUK.OSTN.sln index 1c37586..900ef11 100644 --- a/GeoUK.OSTN.sln +++ b/GeoUK.OSTN.sln @@ -7,11 +7,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeoUK.OSTN", "GeoUK.OSTN\Ge EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeoUK", "GeoUK\GeoUK.csproj", "{5C458FBF-4E2A-4F9D-ACC2-9CE5BED34236}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeoUK.OSTN.Tests", "GeoUK.OSTN.Tests\GeoUK.OSTN.Tests.csproj", "{7DAF4F03-B372-43B2-A22C-64C2790BCF68}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo", "Demo", "{848710E1-EBD1-44BA-9F97-C24D760806E9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoProject", "Demo\DemoProject\DemoProject.csproj", "{1BB0810A-37FF-4F68-8C7E-E687A5369E0C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DemoProject", "Demo\DemoProject\DemoProject.csproj", "{1BB0810A-37FF-4F68-8C7E-E687A5369E0C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeoUK.OSTN.XUnit", "GeoUK.OSTN.XUnit\GeoUK.OSTN.XUnit.csproj", "{FA7CD528-E649-49A7-8C3A-0BAB8B2C0E34}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -27,14 +27,14 @@ Global {5C458FBF-4E2A-4F9D-ACC2-9CE5BED34236}.Debug|Any CPU.Build.0 = Debug|Any CPU {5C458FBF-4E2A-4F9D-ACC2-9CE5BED34236}.Release|Any CPU.ActiveCfg = Release|Any CPU {5C458FBF-4E2A-4F9D-ACC2-9CE5BED34236}.Release|Any CPU.Build.0 = Release|Any CPU - {7DAF4F03-B372-43B2-A22C-64C2790BCF68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7DAF4F03-B372-43B2-A22C-64C2790BCF68}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7DAF4F03-B372-43B2-A22C-64C2790BCF68}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7DAF4F03-B372-43B2-A22C-64C2790BCF68}.Release|Any CPU.Build.0 = Release|Any CPU {1BB0810A-37FF-4F68-8C7E-E687A5369E0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1BB0810A-37FF-4F68-8C7E-E687A5369E0C}.Debug|Any CPU.Build.0 = Debug|Any CPU {1BB0810A-37FF-4F68-8C7E-E687A5369E0C}.Release|Any CPU.ActiveCfg = Release|Any CPU {1BB0810A-37FF-4F68-8C7E-E687A5369E0C}.Release|Any CPU.Build.0 = Release|Any CPU + {FA7CD528-E649-49A7-8C3A-0BAB8B2C0E34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA7CD528-E649-49A7-8C3A-0BAB8B2C0E34}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA7CD528-E649-49A7-8C3A-0BAB8B2C0E34}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA7CD528-E649-49A7-8C3A-0BAB8B2C0E34}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/GeoUK/Convert.cs b/GeoUK/Convert.cs index 2ceace3..a4da06e 100644 --- a/GeoUK/Convert.cs +++ b/GeoUK/Convert.cs @@ -5,281 +5,278 @@ using System; namespace GeoUK { - /// - /// This class performs various generic conversions between coordinate systems and units of measure. - /// This class does not perform transformations. - /// - public static class Convert - { - /// - /// Method to convert from Easting Northing coordinates to Latitude Longitude coordinates. - /// - /// The latitude longitude. - /// - /// Projection. - /// Coordinates. - public static LatitudeLongitude ToLatitudeLongitude(Ellipsoid ellipsoid, Projection projection, EastingNorthing coordinates) - { - double M; - double N = coordinates.Northing; - double E = coordinates.Easting; + /// + /// This class performs various generic conversions between coordinate systems and units of measure. + /// This class does not perform transformations. + /// + public static class Convert + { + /// + /// Method to convert from Easting Northing coordinates to Latitude Longitude coordinates. + /// + /// The latitude longitude. + /// + /// Projection. + /// Coordinates. + 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; + //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); + //check for error and reiterate as required + int loopCount = 0; + do + { + M = CalculateM(lat, lat0, a, b, F0); - lat += ((N - N0 - M) / (a * F0)); + lat += ((N - N0 - M) / (a * F0)); - loopCount++; - } while (!IsNearlyZero(N - N0 - M, 1e-16) & loopCount < 10); + 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 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 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 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 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 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 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 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; + 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); + 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)); - } + return new LatitudeLongitude(ToDegrees(lat), ToDegrees(lon)); + } - private static bool IsNearlyZero(double x, double tolerance) - { - if (x < 0) - { - x *= -1; - } + private static bool IsNearlyZero(double x, double tolerance) + { + if (x < 0) + { + x *= -1; + } - return (x < 0 && x > tolerance * -1) || (x >= 0 && x < tolerance); - } + return (x < 0 && x > tolerance * -1) || (x >= 0 && x < tolerance); + } - private static double CalculateM(double latitude, double latitudeOrigin, double semiMajorAxis, double semiMinorAxis, double scaleFactor) - { - double n = (semiMajorAxis - semiMinorAxis) / (semiMajorAxis + semiMinorAxis); + private static double CalculateM(double latitude, double latitudeOrigin, double semiMajorAxis, double semiMinorAxis, double scaleFactor) + { + double n = (semiMajorAxis - semiMinorAxis) / (semiMajorAxis + semiMinorAxis); - double Ma = (1 + n + ((5.0 / 4.0) * Math.Pow(n, 2)) + ((5.0 / 4.0) * Math.Pow(n, 3))) * (latitude - latitudeOrigin); - double Mb = ((3 * n) + (3 * Math.Pow(n, 2)) + ((21.0 / 8.0) * Math.Pow(n, 3))) * Math.Sin(latitude - latitudeOrigin) * Math.Cos(latitude + latitudeOrigin); - double Mc = (((15.0 / 8.0) * Math.Pow(n, 2)) + (15.0 / 8.0) * Math.Pow(n, 3)) * Math.Sin(2 * (latitude - latitudeOrigin)) * Math.Cos(2 * (latitude + latitudeOrigin)); - double Md = (35.0 / 24.0 * Math.Pow(n, 3)) * Math.Sin(3 * (latitude - latitudeOrigin)) * Math.Cos(3 * (latitude + latitudeOrigin)); - double M = semiMinorAxis * scaleFactor * (Ma - Mb + Mc - Md); + double Ma = (1 + n + ((5.0 / 4.0) * Math.Pow(n, 2)) + ((5.0 / 4.0) * Math.Pow(n, 3))) * (latitude - latitudeOrigin); + double Mb = ((3 * n) + (3 * Math.Pow(n, 2)) + ((21.0 / 8.0) * Math.Pow(n, 3))) * Math.Sin(latitude - latitudeOrigin) * Math.Cos(latitude + latitudeOrigin); + double Mc = (((15.0 / 8.0) * Math.Pow(n, 2)) + (15.0 / 8.0) * Math.Pow(n, 3)) * Math.Sin(2 * (latitude - latitudeOrigin)) * Math.Cos(2 * (latitude + latitudeOrigin)); + double Md = (35.0 / 24.0 * Math.Pow(n, 3)) * Math.Sin(3 * (latitude - latitudeOrigin)) * Math.Cos(3 * (latitude + latitudeOrigin)); + double M = semiMinorAxis * scaleFactor * (Ma - Mb + Mc - Md); - return M; - } + return M; + } - /// - /// Converts decimal degrees to radians. - /// - /// - /// - public static double ToRadians(double degrees) => degrees * (Math.PI / 180); + /// + /// Converts decimal degrees to radians. + /// + /// + /// + public static double ToRadians(double degrees) => degrees * (Math.PI / 180); - /// - /// Converts radians to decimal degrees. - /// - /// - /// - public static double ToDegrees(double radians) => radians * (180 / Math.PI); + /// + /// Converts radians to decimal degrees. + /// + /// + /// + public static double ToDegrees(double radians) => radians * (180 / Math.PI); - /// - /// Converts cartesian coordinates to grid eastings and northings for any Transverse Mercator map projection, including the Ordnance Survey National Grid. - /// Ellipsoid height is ignored. - /// - /// - /// When converting OSGB36 coordinates between (easting, northing) and (latitude, longitude), - /// use the Airy 1830 ellipsoid. When converting ETRS89 coordinates between (easting, northing) and - /// (latitude, longitude), use the GRS80 ellipsoid. Use the same National Grid projection - /// constants for both ETRS89 and OSGB36 coordinates. - /// - public static EastingNorthing ToEastingNorthing(Ellipsoid ellipsoid, Projection projection, Cartesian coordinates) - { - LatitudeLongitude coords = ToLatitudeLongitude(ellipsoid, coordinates); - return ToEastingNorthing(ellipsoid, projection, coords); - } + /// + /// Converts cartesian coordinates to grid eastings and northings for any Transverse Mercator map projection, including the Ordnance Survey National Grid. + /// Ellipsoid height is ignored. + /// + /// + /// When converting OSGB36 coordinates between (easting, northing) and (latitude, longitude), + /// use the Airy 1830 ellipsoid. When converting ETRS89 coordinates between (easting, northing) and + /// (latitude, longitude), use the GRS80 ellipsoid. Use the same National Grid projection + /// constants for both ETRS89 and OSGB36 coordinates. + /// + public static EastingNorthing ToEastingNorthing(Ellipsoid ellipsoid, Projection projection, Cartesian coordinates) + { + LatitudeLongitude coords = ToLatitudeLongitude(ellipsoid, coordinates); + return ToEastingNorthing(ellipsoid, projection, coords); + } - /// - /// Converts latitude and longitude to grid eastings and northings for any Transverse Mercator map projection, including the Ordnance Survey National Grid. - /// Ellipsoid height is ignored. - /// - /// - /// When converting OSGB36 coordinates between (easting, northing) and (latitude, longitude), - /// use the Airy 1830 ellipsoid. When converting ETRS89 coordinates between (easting, northing) and - /// (latitude, longitude), use the GRS80 ellipsoid. Use the same National Grid projection - /// constants for both ETRS89 and OSGB36 coordinates. - /// - /// - /// - /// - /// - public static EastingNorthing ToEastingNorthing(Ellipsoid ellipsoid, Projection projection, LatitudeLongitude coordinates) - { - double lat = ToRadians(coordinates.Latitude); - double lon = ToRadians(coordinates.Longitude); + /// + /// Converts latitude and longitude to grid eastings and northings for any Transverse Mercator map projection, including the Ordnance Survey National Grid. + /// Ellipsoid height is ignored. + /// + /// + /// When converting OSGB36 coordinates between (easting, northing) and (latitude, longitude), + /// use the Airy 1830 ellipsoid. When converting ETRS89 coordinates between (easting, northing) and + /// (latitude, longitude), use the GRS80 ellipsoid. Use the same National Grid projection + /// constants for both ETRS89 and OSGB36 coordinates. + /// + /// + /// + /// + /// + public static EastingNorthing ToEastingNorthing(Ellipsoid ellipsoid, Projection projection, LatitudeLongitude coordinates) + { + double lat = ToRadians(coordinates.Latitude); + double lon = ToRadians(coordinates.Longitude); - //OS Document Transformation and OSGM02 User Guide, Appendix B. - //B1 - 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; + //OS Document Transformation and OSGM02 User Guide, Appendix B. + //B1 + 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; - //B2 - //double n = (a - b) / (a + b); + //B3 + double v = a * F0 * Math.Pow((1 - e2 * Math.Pow(Math.Sin(lat), 2)), -0.5); - //B3 - double v = a * F0 * Math.Pow((1 - e2 * Math.Pow(Math.Sin(lat), 2)), -0.5); + //B4 + double p = a * F0 * (1 - e2) * Math.Pow((1 - e2 * Math.Pow(Math.Sin(lat), 2)), -1.5); - //B4 - double p = a * F0 * (1 - e2) * Math.Pow((1 - e2 * Math.Pow(Math.Sin(lat), 2)), -1.5); + //B5 + double n2 = v / p - 1; - //B5 - double n2 = v / p - 1; + //B6 + double M = CalculateM(lat, lat0, a, b, F0); - //B6 - double M = CalculateM(lat, lat0, a, b, F0); + double I = M + N0; + double II = (v / 2) * Math.Sin(lat) * Math.Cos(lat); + double III = (v / 24) * Math.Sin(lat) * Math.Pow(Math.Cos(lat), 3) * (5 - Math.Pow(Math.Tan(lat), 2) + 9 * n2); + double IIIA = (v / 720) * Math.Sin(lat) * Math.Pow(Math.Cos(lat), 5) * (61 - 58 * Math.Pow(Math.Tan(lat), 2) + Math.Pow(Math.Tan(lat), 4)); + double IV = v * Math.Cos(lat); + double V = (v / 6) * Math.Pow(Math.Cos(lat), 3) * ((v / p) - Math.Pow(Math.Tan(lat), 2)); + double VI = (v / 120) * Math.Pow(Math.Cos(lat), 5) * (5 - 18 * Math.Pow(Math.Tan(lat), 2) + Math.Pow(Math.Tan(lat), 4) + 14 * n2 - 58 * Math.Pow(Math.Tan(lat), 2) * n2); - double I = M + N0; - double II = (v / 2) * Math.Sin(lat) * Math.Cos(lat); - double III = (v / 24) * Math.Sin(lat) * Math.Pow(Math.Cos(lat), 3) * (5 - Math.Pow(Math.Tan(lat), 2) + 9 * n2); - double IIIA = (v / 720) * Math.Sin(lat) * Math.Pow(Math.Cos(lat), 5) * (61 - 58 * Math.Pow(Math.Tan(lat), 2) + Math.Pow(Math.Tan(lat), 4)); - double IV = v * Math.Cos(lat); - double V = (v / 6) * Math.Pow(Math.Cos(lat), 3) * ((v / p) - Math.Pow(Math.Tan(lat), 2)); - double VI = (v / 120) * Math.Pow(Math.Cos(lat), 5) * (5 - 18 * Math.Pow(Math.Tan(lat), 2) + Math.Pow(Math.Tan(lat), 4) + 14 * n2 - 58 * Math.Pow(Math.Tan(lat), 2) * n2); + //B7 + double N = I + (II * Math.Pow((lon - lon0), 2)) + (III * Math.Pow((lon - lon0), 4)) + (IIIA * Math.Pow((lon - lon0), 6)); - //B7 - double N = I + (II * Math.Pow((lon - lon0), 2)) + (III * Math.Pow((lon - lon0), 4)) + (IIIA * Math.Pow((lon - lon0), 6)); + //B8 + double E = E0 + (IV * (lon - lon0)) + (V * Math.Pow((lon - lon0), 3)) + (VI * Math.Pow((lon - lon0), 5)); - //B8 - double E = E0 + (IV * (lon - lon0)) + (V * Math.Pow((lon - lon0), 3)) + (VI * Math.Pow((lon - lon0), 5)); + return new EastingNorthing(E, N, coordinates.EllipsoidalHeight); //height is still with respect to the ellipsoid + } - return new EastingNorthing(E, N, coordinates.EllipsoidalHeight); //height is still with respect to the ellipsoid - } + public static Cartesian ToCartesian(Ellipsoid ellipsoid, Projection projection, EastingNorthing coordinates) + { + LatitudeLongitude latLongCoordinates = ToLatitudeLongitude( + ellipsoid, + projection, + coordinates); - public static Cartesian ToCartesian(Ellipsoid ellipsoid, Projection projection, EastingNorthing coordinates) - { - LatitudeLongitude latLongCoordinates = ToLatitudeLongitude( - ellipsoid, - projection, - coordinates); + return ToCartesian(ellipsoid, latLongCoordinates); + } - return ToCartesian(ellipsoid, latLongCoordinates); - } + /// + /// Converts latitude, longitude and ellipsoidal height coordinates to cartesian coordinates using the same ellipsoid. + /// Please note this is not a transformation between ellipsoids. + /// + /// + /// + /// + public static Cartesian ToCartesian(Ellipsoid ellipsoid, LatitudeLongitude coordinates) + { + double lat = ToRadians(coordinates.Latitude); + double lon = ToRadians(coordinates.Longitude); + double height = coordinates.EllipsoidalHeight; - /// - /// Converts latitude, longitude and ellipsoidal height coordinates to cartesian coordinates using the same ellipsoid. - /// Please note this is not a transformation between ellipsoids. - /// - /// - /// - /// - public static Cartesian ToCartesian(Ellipsoid ellipsoid, LatitudeLongitude coordinates) - { - double lat = ToRadians(coordinates.Latitude); - double lon = ToRadians(coordinates.Longitude); - double height = coordinates.EllipsoidalHeight; + double e2 = ellipsoid.EccentricitySquared; + double a = ellipsoid.SemiMajorAxis; - double e2 = ellipsoid.EccentricitySquared; - double a = ellipsoid.SemiMajorAxis; + double v = a / Math.Sqrt(1 - (e2 * Math.Pow(Math.Sin(lat), 2))); - double v = a / Math.Sqrt(1 - (e2 * Math.Pow(Math.Sin(lat), 2))); + double x = (v + height) * Math.Cos(lat) * Math.Cos(lon); + double y = (v + height) * Math.Cos(lat) * Math.Sin(lon); + double z = ((1 - e2) * v + height) * Math.Sin(lat); - double x = (v + height) * Math.Cos(lat) * Math.Cos(lon); - double y = (v + height) * Math.Cos(lat) * Math.Sin(lon); - double z = ((1 - e2) * v + height) * Math.Sin(lat); + return new Cartesian(x, y, z); + } - return new Cartesian(x, y, z); - } + /// + /// Converts cartesian coordinates to latitude, longitude and ellipsoidal height using the same ellipsoid. + /// Please note this is not a transformation between ellipsoids. + /// + /// + /// + /// + public static LatitudeLongitude ToLatitudeLongitude(Ellipsoid ellipsoid, Cartesian coordinates) + { + double e2 = ellipsoid.EccentricitySquared; + double a = ellipsoid.SemiMajorAxis; + double p = Math.Sqrt(Math.Pow(coordinates.X, 2) + Math.Pow(coordinates.Y, 2)); + double lon = Math.Atan(coordinates.Y / coordinates.X); - /// - /// Converts cartesian coordinates to latitude, longitude and ellipsoidal height using the same ellipsoid. - /// Please note this is not a transformation between ellipsoids. - /// - /// - /// - /// - public static LatitudeLongitude ToLatitudeLongitude(Ellipsoid ellipsoid, Cartesian coordinates) - { - double e2 = ellipsoid.EccentricitySquared; - double a = ellipsoid.SemiMajorAxis; - double p = Math.Sqrt(Math.Pow(coordinates.X, 2) + Math.Pow(coordinates.Y, 2)); - double lon = Math.Atan(coordinates.Y / coordinates.X); + //have a first stab + double v = 0.0; + double lat = Math.Atan(coordinates.Z / (p * (1 - e2))); - //have a first stab - double v = 0.0; - double lat = Math.Atan(coordinates.Z / (p * (1 - e2))); + //iterate a few times 3 is enough but 10 to be safe + for (int iterations = 0; iterations < 10; iterations++) + { + v = a / Math.Sqrt(1 - (e2 * Math.Pow(Math.Sin(lat), 2))); + lat = Math.Atan((coordinates.Z + e2 * v * Math.Sin(lat)) / p); + } + double height = (p / Math.Cos(lat)) - v; - //iterate a few times 3 is enough but 10 to be safe - for (int iterations = 0; iterations < 10; iterations++) - { - v = a / Math.Sqrt(1 - (e2 * Math.Pow(Math.Sin(lat), 2))); - lat = Math.Atan((coordinates.Z + e2 * v * Math.Sin(lat)) / p); - } - double height = (p / Math.Cos(lat)) - v; + return new LatitudeLongitude(ToDegrees(lat), ToDegrees(lon), height); + } - return new LatitudeLongitude(ToDegrees(lat), ToDegrees(lon), height); - } + /// + /// Converts degrees minutes and seconds to decimal degrees. + /// + /// + /// + /// + /// + public static double ToDecimalDegrees(int degrees, int minutes, double seconds) + { + //determine seconds as minutes + double m = minutes + (seconds / 60.0); + return ToDecimalDegrees(degrees, m); + } - /// - /// Converts degrees minutes and seconds to decimal degrees. - /// - /// - /// - /// - /// - public static double ToDecimalDegrees(int degrees, int minutes, double seconds) - { - //determine seconds as minutes - double m = minutes + (seconds / 60.0); - return ToDecimalDegrees(degrees, m); - } - - /// - /// Converts degrees and decimal minutes to decimal degrees. - /// - /// - /// - /// - public static double ToDecimalDegrees(int degrees, double minutes) => degrees + (minutes / 60.0); - } + /// + /// Converts degrees and decimal minutes to decimal degrees. + /// + /// + /// + /// + public static double ToDecimalDegrees(int degrees, double minutes) => degrees + (minutes / 60.0); + } } \ No newline at end of file diff --git a/GeoUK/Coordinates/Osgb36.cs b/GeoUK/Coordinates/Osgb36.cs index 4029c69..84d2ba3 100644 --- a/GeoUK/Coordinates/Osgb36.cs +++ b/GeoUK/Coordinates/Osgb36.cs @@ -2,135 +2,134 @@ using System; namespace GeoUK.Coordinates { - /// - /// This immutable class, derived from EastingNorthingCoordinates, provides a convenient means - /// to represent OSGB36 eastings and northings. - /// - /// - /// Eastings and northings are represented in British National Grid and Height is specified - /// in meters based on the geoid datum returned by the RegionGeoidDatum property. - /// - public class Osgb36 : EastingNorthing - { + /// + /// This immutable class, derived from EastingNorthingCoordinates, provides a convenient means + /// to represent OSGB36 eastings and northings. + /// + /// + /// Eastings and northings are represented in British National Grid and Height is specified + /// in meters based on the geoid datum returned by the RegionGeoidDatum property. + /// + public class Osgb36 : EastingNorthing + { + /// + /// Initializes a new instance of the class. + /// + /// Easting. + /// Northing. + public Osgb36(double easting, double northing) + : base(easting, northing, 0) + { + RegionGeoidDatum = Osgb36GeoidDatum.NewlynUkMainland; + } - /// - /// Initializes a new instance of the class. - /// - /// Easting. - /// Northing. - public Osgb36(double easting, double northing) - : base(easting, northing, 0) - { - RegionGeoidDatum = Osgb36GeoidDatum.NewlynUkMainland; - } + /// + /// Initializes a new instance of the class. + /// + /// Easting northing coordinates. + public Osgb36(EastingNorthing eastingNorthingCoordinates) + : base(eastingNorthingCoordinates.Easting, eastingNorthingCoordinates.Northing, eastingNorthingCoordinates.Height) + { + RegionGeoidDatum = Osgb36GeoidDatum.NewlynUkMainland; + } - /// - /// Initializes a new instance of the class. - /// - /// Easting northing coordinates. - public Osgb36(EastingNorthing eastingNorthingCoordinates) - : base(eastingNorthingCoordinates.Easting, eastingNorthingCoordinates.Northing, eastingNorthingCoordinates.Height) - { - RegionGeoidDatum = Osgb36GeoidDatum.NewlynUkMainland; - } + /// + /// Initializes a new instance of the class. + /// + /// Easting northing coordinates. + /// Datum. + public Osgb36(EastingNorthing eastingNorthingCoordinates, Osgb36GeoidDatum datum) + : base(eastingNorthingCoordinates.Easting, eastingNorthingCoordinates.Northing, eastingNorthingCoordinates.Height) + { + RegionGeoidDatum = datum; + } - /// - /// Initializes a new instance of the class. - /// - /// Easting northing coordinates. - /// Datum. - public Osgb36(EastingNorthing eastingNorthingCoordinates, Osgb36GeoidDatum datum) - : base(eastingNorthingCoordinates.Easting, eastingNorthingCoordinates.Northing, eastingNorthingCoordinates.Height) - { - RegionGeoidDatum = datum; - } + /// + /// Initializes a new instance of the class. + /// + /// Easting. + /// Northing. + /// Height. + /// Datum. + public Osgb36(double easting, double northing, double height, Osgb36GeoidDatum datum) + : base(easting, northing, height) + { + RegionGeoidDatum = datum; + } - /// - /// Initializes a new instance of the class. - /// - /// Easting. - /// Northing. - /// Height. - /// Datum. - public Osgb36(double easting, double northing, double height, Osgb36GeoidDatum datum) - : base(easting, northing, height) - { - RegionGeoidDatum = datum; - } + /// + /// Returns the Local Geoid datum in use. other property values should be + /// considered invalid if this property is set to OutsideModelBoundary. + /// + public Osgb36GeoidDatum RegionGeoidDatum { get; } - /// - /// Returns the Local Geoid datum in use. other property values should be - /// considered invalid if this property is set to OutsideModelBoundary. - /// - public Osgb36GeoidDatum RegionGeoidDatum { get; } - - public string MapReference - { - get - { - /* + public string MapReference + { + get + { + /* 10km (2-figure) Grid Reference: SO84 = 380000 Easting 240000 Northing 1km (4-figure) Grid Reference: NS2468 = 224000 Easting 668000 Northing 100m (6-figure) Grid Reference: TL123456 = 512300 Easting 245600 Northing */ - double easting = Easting; - double northing = Northing; + double easting = Easting; + double northing = Northing; - string bngSquare = GetBngSquare(easting, northing); + string bngSquare = GetBngSquare(easting, northing); - //get the number of complete 500k squares - int indexNorthing = (int)Math.Floor(northing / 500000); - int indexEasting = (int)Math.Floor(easting / 500000); + //get the number of complete 500k squares + int indexNorthing = (int)Math.Floor(northing / 500000); + int indexEasting = (int)Math.Floor(easting / 500000); - //reduce E and N by the number of 500k squares - northing -= indexNorthing * 500000; - easting -= indexEasting * 500000; + //reduce E and N by the number of 500k squares + northing -= indexNorthing * 500000; + easting -= indexEasting * 500000; - //reduce by the number of 100k squares within the 500k square. - indexNorthing = (int)Math.Floor(northing) / 100000; - indexEasting = (int)Math.Floor(easting) / 100000; + //reduce by the number of 100k squares within the 500k square. + indexNorthing = (int)Math.Floor(northing) / 100000; + indexEasting = (int)Math.Floor(easting) / 100000; - northing -= indexNorthing * 100000; - easting -= indexEasting * 100000; + northing -= indexNorthing * 100000; + easting -= indexEasting * 100000; - northing = Math.Round(northing / 100); - easting = Math.Round(easting / 100); - return $"{bngSquare}{Math.Round(easting):000}{Math.Round(northing):000}"; - } - } + northing = Math.Round(northing / 100); + easting = Math.Round(easting / 100); + return $"{bngSquare}{Math.Round(easting):000}{Math.Round(northing):000}"; + } + } - /// - /// Returns the two letter OS code based on easting and northing in metres. - /// - /// The square with northing. - /// Northing. - /// Easting. - public static string GetBngSquare(double easting, double northing) - { - string result = string.Empty; + /// + /// Returns the two letter OS code based on easting and northing in metres. + /// + /// The square with northing. + /// Northing. + /// Easting. + public static string GetBngSquare(double easting, double northing) + { + string result = string.Empty; - //test for our upper and lower limits - if (!(easting >= 0) || !(easting < 700000) || !(northing >= 0) || !(northing < 1300000)) return result; + //test for our upper and lower limits + if (easting < 0 || easting > 700000 || northing < 0 || northing > 1300000) return result; - char[] firstChar = { 'S', 'N', 'H', 'T', 'O', 'J' }; - char[] secondChar = { 'V', 'Q', 'L', 'F', 'A', 'W', 'R', 'M', 'G', 'B', 'X', 'S', 'N', 'H', 'C', 'Y', 'T', 'O', 'J', 'D', 'Z', 'U', 'P', 'K', 'E' }; + char[] firstChar = { 'S', 'N', 'H', 'T', 'O', 'J' }; + char[] secondChar = { 'V', 'Q', 'L', 'F', 'A', 'W', 'R', 'M', 'G', 'B', 'X', 'S', 'N', 'H', 'C', 'Y', 'T', 'O', 'J', 'D', 'Z', 'U', 'P', 'K', 'E' }; - //calculate the first letter - int indexNorthing = (int)Math.Floor(northing / 500000); - int indexEasting = (int)Math.Floor(easting / 500000); + //calculate the first letter + int indexNorthing = (int)Math.Floor(northing / 500000); + int indexEasting = (int)Math.Floor(easting / 500000); - //get the first char - char chr1 = firstChar[(indexEasting * 3) + indexNorthing]; + //get the first char + char chr1 = firstChar[(indexEasting * 3) + indexNorthing]; - //to get the second letter we subtract the number of 500km sectors calculated above - indexNorthing = (int)Math.Floor((northing - (indexNorthing * 500000)) / 100000); - indexEasting = (int)Math.Floor((easting - (indexEasting * 500000)) / 100000); + //to get the second letter we subtract the number of 500km sectors calculated above + indexNorthing = (int)Math.Floor((northing - (indexNorthing * 500000)) / 100000); + indexEasting = (int)Math.Floor((easting - (indexEasting * 500000)) / 100000); - //get the second char - char chr2 = secondChar[(indexEasting * 5) + indexNorthing]; + //get the second char + char chr2 = secondChar[(indexEasting * 5) + indexNorthing]; - result = $"{chr1}{chr2}"; - return result; - } - } + result = $"{chr1}{chr2}"; + return result; + } + } } \ No newline at end of file