diff --git a/MapProjections/Shared/Etrs89UtmProjection.cs b/MapProjections/Shared/Etrs89UtmProjection.cs new file mode 100644 index 00000000..d1117098 --- /dev/null +++ b/MapProjections/Shared/Etrs89UtmProjection.cs @@ -0,0 +1,51 @@ +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2022 Clemens Fischer +// Licensed under the Microsoft Public License (Ms-PL) + +using System; + +namespace MapControl.Projections +{ + public class Etrs89UtmProjection : GeoApiProjection + { + public Etrs89UtmProjection(int zone) + { + SetZone(zone); + } + + protected void SetZone(int zone) + { + if (zone < 28 || zone > 38) + { + throw new ArgumentException($"Invalid UTM zone {zone}.", nameof(zone)); + } + + const string wktFormat + = "PROJCS[\"ETRS89 / UTM zone {0}N\"," + + "GEOGCS[\"ETRS89\"," + + "DATUM[\"European_Terrestrial_Reference_System_1989\"," + + "SPHEROID[\"GRS 1980\",6378137,298.257222101," + + "AUTHORITY[\"EPSG\",\"7019\"]]," + + "TOWGS84[0,0,0,0,0,0,0]," + + "AUTHORITY[\"EPSG\",\"6258\"]]," + + "PRIMEM[\"Greenwich\",0," + + "AUTHORITY[\"EPSG\",\"8901\"]]," + + "UNIT[\"degree\",0.0174532925199433," + + "AUTHORITY[\"EPSG\",\"9122\"]]," + + "AUTHORITY[\"EPSG\",\"4258\"]]," + + "PROJECTION[\"Transverse_Mercator\"]," + + "PARAMETER[\"latitude_of_origin\",0]," + + "PARAMETER[\"central_meridian\",{1}]," + + "PARAMETER[\"scale_factor\",0.9996]," + + "PARAMETER[\"false_easting\",500000]," + + "PARAMETER[\"false_northing\",0]," + + "UNIT[\"metre\",1," + + "AUTHORITY[\"EPSG\",\"9001\"]]," + + "AXIS[\"Easting\",EAST]," + + "AXIS[\"Northing\",NORTH]," + + "AUTHORITY[\"EPSG\",\"258{0}\"]]"; + + WKT = string.Format(wktFormat, zone, 6 * zone - 183); + } + } +} diff --git a/MapProjections/Shared/GeoApiProjectionFactory.cs b/MapProjections/Shared/GeoApiProjectionFactory.cs index efdbdfa2..254707de 100644 --- a/MapProjections/Shared/GeoApiProjectionFactory.cs +++ b/MapProjections/Shared/GeoApiProjectionFactory.cs @@ -8,8 +8,8 @@ namespace MapControl.Projections { public const int WorldMercator = 3395; public const int WebMercator = 3857; - public const int Etrs89UtmNorthFirst = 25828; - public const int Etrs89UtmNorthLast = 25838; + public const int Etrs89UtmFirst = 25828; + public const int Etrs89UtmLast = 25838; public const int Wgs84UtmNorthFirst = 32601; public const int Wgs84UtmNorthLast = 32660; public const int Wgs84UpsNorth = 32661; @@ -33,16 +33,16 @@ namespace MapControl.Projections projection = new WebMercatorProjection(); break; - case int c when c >= Etrs89UtmNorthFirst && c <= Etrs89UtmNorthLast: - projection = new GeoApiProjection(GetEtrs89UtmWkt(epsgCode)); + case int c when c >= Etrs89UtmFirst && c <= Etrs89UtmLast: + projection = new Etrs89UtmProjection(epsgCode % 100); break; case int c when c >= Wgs84UtmNorthFirst && c <= Wgs84UtmNorthLast: - projection = new UtmProjection(epsgCode - Wgs84UtmNorthFirst + 1, true); + projection = new Wgs84UtmProjection(epsgCode % 100, true); break; case int c when c >= Wgs84UtmSouthFirst && c <= Wgs84UtmSouthLast: - projection = new UtmProjection(epsgCode - Wgs84UtmSouthFirst + 1, false); + projection = new Wgs84UtmProjection(epsgCode % 100, false); break; case Wgs84UpsNorth: @@ -60,38 +60,5 @@ namespace MapControl.Projections return projection ?? base.GetProjection(crsId); } - - private static string GetEtrs89UtmWkt(int epsgCode) - { - const string wktFormat - = "PROJCS[\"ETRS89 / UTM zone {1}N\"," - + "GEOGCS[\"ETRS89\"," - + "DATUM[\"European_Terrestrial_Reference_System_1989\"," - + "SPHEROID[\"GRS 1980\",6378137,298.257222101," - + "AUTHORITY[\"EPSG\",\"7019\"]]," - + "TOWGS84[0,0,0,0,0,0,0]," - + "AUTHORITY[\"EPSG\",\"6258\"]]," - + "PRIMEM[\"Greenwich\",0," - + "AUTHORITY[\"EPSG\",\"8901\"]]," - + "UNIT[\"degree\",0.0174532925199433," - + "AUTHORITY[\"EPSG\",\"9122\"]]," - + "AUTHORITY[\"EPSG\",\"4258\"]]," - + "PROJECTION[\"Transverse_Mercator\"]," - + "PARAMETER[\"latitude_of_origin\",0]," - + "PARAMETER[\"central_meridian\",{2}]," - + "PARAMETER[\"scale_factor\",0.9996]," - + "PARAMETER[\"false_easting\",500000]," - + "PARAMETER[\"false_northing\",0]," - + "UNIT[\"metre\",1," - + "AUTHORITY[\"EPSG\",\"9001\"]]," - + "AXIS[\"Easting\",EAST]," - + "AXIS[\"Northing\",NORTH]," - + "AUTHORITY[\"EPSG\",\"{0}\"]]"; - - var zone = epsgCode % 100; - var centralMeridian = 6 * (epsgCode - Etrs89UtmNorthFirst) - 15; - - return string.Format(wktFormat, epsgCode, zone, centralMeridian); - } } } diff --git a/MapProjections/Shared/UtmProjection.cs b/MapProjections/Shared/Wgs84UtmProjection.cs similarity index 55% rename from MapProjections/Shared/UtmProjection.cs rename to MapProjections/Shared/Wgs84UtmProjection.cs index d7aaa9a9..f774b08d 100644 --- a/MapProjections/Shared/UtmProjection.cs +++ b/MapProjections/Shared/Wgs84UtmProjection.cs @@ -7,25 +7,18 @@ using System; namespace MapControl.Projections { - public class UtmProjection : GeoApiProjection + public class Wgs84UtmProjection : GeoApiProjection { - public UtmProjection(int zone, bool north) + public Wgs84UtmProjection(int zone, bool north) { SetZone(zone, north); } - public UtmProjection(Location location) - { - var zone = Math.Min((int)Math.Floor(Location.NormalizeLongitude(location.Longitude) + 180d) / 6 + 1, 60); - - SetZone(zone, location.Latitude >= 0d); - } - protected void SetZone(int zone, bool north) { if (zone < 1 || zone > 60) { - throw new ArgumentException("Invalid UTM zone number.", nameof(zone)); + throw new ArgumentException($"Invalid UTM zone {zone}.", nameof(zone)); } CoordinateSystem = ProjectedCoordinateSystem.WGS84_UTM(zone, north); diff --git a/MapProjections/UWP/MapProjections.UWP.csproj b/MapProjections/UWP/MapProjections.UWP.csproj index 7ab95557..b0769ead 100644 --- a/MapProjections/UWP/MapProjections.UWP.csproj +++ b/MapProjections/UWP/MapProjections.UWP.csproj @@ -40,6 +40,9 @@ PackageReference + + Etrs89UtmProjection.cs + GeoApiProjection.cs @@ -49,12 +52,12 @@ PolarStereographicProjection.cs - - UtmProjection.cs - WebMercatorProjection.cs + + Wgs84UtmProjection.cs +