diff --git a/MapControl/Shared/Etrs89UtmProjection.cs b/MapControl/Shared/Etrs89UtmProjection.cs deleted file mode 100644 index 17490e15..00000000 --- a/MapControl/Shared/Etrs89UtmProjection.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; - -namespace MapControl -{ - /// - /// ETRS89 Universal Transverse Mercator Projection - EPSG:25828 to EPSG:25838. - /// - public class Etrs89UtmProjection : TransverseMercatorProjection - { - public const int FirstZone = 28; - public const int LastZone = 38; - public const int FirstZoneEpsgCode = 25800 + FirstZone; - public const int LastZoneEpsgCode = 25800 + LastZone; - - public int Zone { get; } - - public Etrs89UtmProjection(int zone) : base(zone) - { - if (zone < FirstZone || zone > LastZone) - { - throw new ArgumentException($"Invalid ETRS89 UTM zone {zone}.", nameof(zone)); - } - - Zone = zone; - CrsId = $"EPSG:{25800 + zone}"; - - // GRS 1980 - EquatorialRadius = 6378137d; - Flattening = 1d / 298.257222101; - } - } -} diff --git a/MapControl/Shared/Nad27UtmProjection.cs b/MapControl/Shared/Nad27UtmProjection.cs deleted file mode 100644 index 2fd35922..00000000 --- a/MapControl/Shared/Nad27UtmProjection.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; - -namespace MapControl -{ - /// - /// NAD27 Universal Transverse Mercator Projection - EPSG:26701 to EPSG:26722. - /// - public class Nad27UtmProjection : TransverseMercatorProjection - { - public const int FirstZone = 1; - public const int LastZone = 22; - public const int FirstZoneEpsgCode = 26700 + FirstZone; - public const int LastZoneEpsgCode = 26700 + LastZone; - - public int Zone { get; } - - public Nad27UtmProjection(int zone) : base(zone) - { - if (zone < FirstZone || zone > LastZone) - { - throw new ArgumentException($"Invalid NAD27 UTM zone {zone}.", nameof(zone)); - } - - Zone = zone; - CrsId = $"EPSG:{26700 + zone}"; - - // Clarke 1866 - EquatorialRadius = 6378206.4; - Flattening = 1d / 294.978698213898; - } - } -} diff --git a/MapControl/Shared/Nad83UtmProjection.cs b/MapControl/Shared/Nad83UtmProjection.cs deleted file mode 100644 index e46566da..00000000 --- a/MapControl/Shared/Nad83UtmProjection.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; - -namespace MapControl -{ - /// - /// NAD83 Universal Transverse Mercator Projection - EPSG:26901 to EPSG:26923. - /// - public class Nad83UtmProjection : TransverseMercatorProjection - { - public const int FirstZone = 1; - public const int LastZone = 23; - public const int FirstZoneEpsgCode = 26900 + FirstZone; - public const int LastZoneEpsgCode = 26900 + LastZone; - - public int Zone { get; } - - public Nad83UtmProjection(int zone) : base(zone) - { - if (zone < FirstZone || zone > LastZone) - { - throw new ArgumentException($"Invalid NAD83 UTM zone {zone}.", nameof(zone)); - } - - Zone = zone; - CrsId = $"EPSG:{26900 + zone}"; - - // GRS 1980 - EquatorialRadius = 6378137d; - Flattening = 1d / 298.257222101; - } - } -} diff --git a/MapControl/Shared/TransverseMercatorProjection.cs b/MapControl/Shared/TransverseMercatorProjection.cs index e0c0430a..b48e681c 100644 --- a/MapControl/Shared/TransverseMercatorProjection.cs +++ b/MapControl/Shared/TransverseMercatorProjection.cs @@ -16,24 +16,32 @@ namespace MapControl /// public class TransverseMercatorProjection : MapProjection { - private double f; - private double n; - private double a1; // α1 - private double a2; // α2 - private double a3; // α3 - private double b1; // β1 - private double b2; // β2 - private double b3; // β3 - private double d1; // δ1 - private double d2; // δ2 - private double d3; // δ3 - private double f1; // A/a - private double f2; // 2*sqrt(n)/(1+n) + private readonly double n; + private readonly double a1; // α1 + private readonly double a2; // α2 + private readonly double a3; // α3 + private readonly double b1; // β1 + private readonly double b2; // β2 + private readonly double b3; // β3 + private readonly double d1; // δ1 + private readonly double d2; // δ2 + private readonly double d3; // δ3 + private readonly double f1; // A/a + private readonly double f2; // 2*sqrt(n)/(1+n) - private void InitializeParameters() + public TransverseMercatorProjection( + double equatorialRadius, double flattening, + double scaleFactor, double centralMeridian, + double falseEasting, double falseNorthing = 0d) { - f = Flattening; - n = f / (2d - f); + EquatorialRadius = equatorialRadius; + Flattening = flattening; + ScaleFactor = scaleFactor; + CentralMeridian = centralMeridian; + FalseEasting = falseEasting; + FalseNorthing = falseNorthing; + + n = flattening / (2d - flattening); var n2 = n * n; var n3 = n * n2; a1 = n / 2d - n2 * 2d / 3d + n3 * 5d / 16d; @@ -49,17 +57,14 @@ namespace MapControl f2 = 2d * Math.Sqrt(n) / (1d + n); } - public TransverseMercatorProjection() + public TransverseMercatorProjection( + double equatorialRadius, double flattening, + double scaleFactor, int utmZone, bool north = true) + : this(equatorialRadius, flattening, + scaleFactor, utmZone * 6d - 183d, 5e5, north ? 0d : 1e7) { } - public TransverseMercatorProjection(int utmZone) : this() - { - CentralMeridian = utmZone * 6d - 183d; - ScaleFactor = 0.9996; - FalseEasting = 5e5; - } - public override double GridConvergence(double latitude, double longitude) { // φ @@ -74,11 +79,6 @@ namespace MapControl public override Matrix RelativeTransform(double latitude, double longitude) { - if (f != Flattening) - { - InitializeParameters(); - } - // φ var phi = latitude * Math.PI / 180d; var sinPhi = Math.Sin(phi); @@ -118,11 +118,6 @@ namespace MapControl public override Point LocationToMap(double latitude, double longitude) { - if (f != Flattening) - { - InitializeParameters(); - } - // φ var phi = latitude * Math.PI / 180d; var sinPhi = Math.Sin(phi); @@ -152,11 +147,6 @@ namespace MapControl public override Location MapToLocation(double x, double y) { - if (f != Flattening) - { - InitializeParameters(); - } - // k0 * A var k0A = ScaleFactor * EquatorialRadius * f1; // ξ diff --git a/MapControl/Shared/TransverseMercatorProjectionSnyder.cs b/MapControl/Shared/TransverseMercatorProjectionSnyder.cs index 12026aeb..cd47232b 100644 --- a/MapControl/Shared/TransverseMercatorProjectionSnyder.cs +++ b/MapControl/Shared/TransverseMercatorProjectionSnyder.cs @@ -15,15 +15,24 @@ namespace MapControl /// public class TransverseMercatorProjectionSnyder : MapProjection { - public TransverseMercatorProjectionSnyder() + public TransverseMercatorProjectionSnyder( + double equatorialRadius, double flattening, double scaleFactor, + double centralMeridian, double latitudeOfOrigin, + double falseEasting, double falseNorthing = 0d) { + EquatorialRadius = equatorialRadius; + Flattening = flattening; + ScaleFactor = scaleFactor; + CentralMeridian = centralMeridian; + LatitudeOfOrigin = latitudeOfOrigin; + FalseEasting = falseEasting; + FalseNorthing = falseNorthing; } - public TransverseMercatorProjectionSnyder(int utmZone) : this() + public TransverseMercatorProjectionSnyder(int utmZone, bool north = true) + : this(Wgs84EquatorialRadius, Wgs84Flattening, + 0.9996, utmZone * 6d - 183d, 0d, 5e5, north ? 0d : 1e7) { - CentralMeridian = utmZone * 6d - 183d; - ScaleFactor = 0.9996; - FalseEasting = 5e5; } public override double GridConvergence(double latitude, double longitude) diff --git a/MapControl/Shared/UtmProjections.cs b/MapControl/Shared/UtmProjections.cs new file mode 100644 index 00000000..1496b880 --- /dev/null +++ b/MapControl/Shared/UtmProjections.cs @@ -0,0 +1,107 @@ +using System; + +namespace MapControl +{ + /// + /// WGS84 Universal Transverse Mercator Projection - + /// EPSG:32601 to EPSG:32660 and EPSG:32701 to EPSG:32760. + /// + public class Wgs84UtmProjection : TransverseMercatorProjection + { + public const int FirstZone = 1; + public const int LastZone = 60; + public const int FirstZoneNorthEpsgCode = 32600 + FirstZone; + public const int LastZoneNorthEpsgCode = 32600 + LastZone; + public const int FirstZoneSouthEpsgCode = 32700 + FirstZone; + public const int LastZoneSouthEpsgCode = 32700 + LastZone; + + public int Zone { get; } + + public Wgs84UtmProjection(int zone, bool north) + : base(Wgs84EquatorialRadius, Wgs84Flattening, 0.9996, zone, north) + { + if (zone < FirstZone || zone > LastZone) + { + throw new ArgumentException($"Invalid WGS84 UTM zone {zone}.", nameof(zone)); + } + + Zone = zone; + CrsId = $"EPSG:{(north ? 32600 : 32700) + zone}"; + } + } + + /// + /// ETRS89 Universal Transverse Mercator Projection - EPSG:25828 to EPSG:25838. + /// + public class Etrs89UtmProjection : TransverseMercatorProjection + { + public const int FirstZone = 28; + public const int LastZone = 38; + public const int FirstZoneEpsgCode = 25800 + FirstZone; + public const int LastZoneEpsgCode = 25800 + LastZone; + + public int Zone { get; } + + public Etrs89UtmProjection(int zone) + : base(6378137d, 1d / 298.257222101, 0.9996, zone) // GRS 1980 + { + if (zone < FirstZone || zone > LastZone) + { + throw new ArgumentException($"Invalid ETRS89 UTM zone {zone}.", nameof(zone)); + } + + Zone = zone; + CrsId = $"EPSG:{25800 + zone}"; + } + } + + /// + /// NAD83 Universal Transverse Mercator Projection - EPSG:26901 to EPSG:26923. + /// + public class Nad83UtmProjection : TransverseMercatorProjection + { + public const int FirstZone = 1; + public const int LastZone = 23; + public const int FirstZoneEpsgCode = 26900 + FirstZone; + public const int LastZoneEpsgCode = 26900 + LastZone; + + public int Zone { get; } + + public Nad83UtmProjection(int zone) + : base(6378137d, 1d / 298.257222101, 0.9996, zone) // GRS 1980 + { + if (zone < FirstZone || zone > LastZone) + { + throw new ArgumentException($"Invalid NAD83 UTM zone {zone}.", nameof(zone)); + } + + Zone = zone; + CrsId = $"EPSG:{26900 + zone}"; + } + } + + /// + /// NAD27 Universal Transverse Mercator Projection - EPSG:26701 to EPSG:26722. + /// + public class Nad27UtmProjection : TransverseMercatorProjection + { + public const int FirstZone = 1; + public const int LastZone = 22; + public const int FirstZoneEpsgCode = 26700 + FirstZone; + public const int LastZoneEpsgCode = 26700 + LastZone; + + public int Zone { get; } + + public Nad27UtmProjection(int zone) + : base(6378206.4, 1d / 294.978698213898, 0.9996, zone) // Clarke 1866 + { + if (zone < FirstZone || zone > LastZone) + { + throw new ArgumentException($"Invalid NAD27 UTM zone {zone}.", nameof(zone)); + } + + Zone = zone; + CrsId = $"EPSG:{26700 + zone}"; + } + } +} diff --git a/MapControl/Shared/Wgs84UtmProjection.cs b/MapControl/Shared/Wgs84UtmProjection.cs deleted file mode 100644 index 82aae18a..00000000 --- a/MapControl/Shared/Wgs84UtmProjection.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; - -namespace MapControl -{ - /// - /// WGS84 Universal Transverse Mercator Projection - - /// EPSG:32601 to EPSG:32660 and EPSG:32701 to EPSG:32760. - /// - public class Wgs84UtmProjection : TransverseMercatorProjection - { - public const int FirstZone = 1; - public const int LastZone = 60; - public const int FirstZoneNorthEpsgCode = 32600 + FirstZone; - public const int LastZoneNorthEpsgCode = 32600 + LastZone; - public const int FirstZoneSouthEpsgCode = 32700 + FirstZone; - public const int LastZoneSouthEpsgCode = 32700 + LastZone; - - public int Zone { get; } - - public Wgs84UtmProjection(int zone, bool north) : base(zone) - { - if (zone < FirstZone || zone > LastZone) - { - throw new ArgumentException($"Invalid WGS84 UTM zone {zone}.", nameof(zone)); - } - - Zone = zone; - CrsId = $"EPSG:{(north ? 32600 : 32700) + zone}"; - FalseNorthing = north ? 0d : 1e7; - } - } -}