diff --git a/MapProjections/Shared/AutoUtmProjection.cs b/MapProjections/Shared/AutoUtmProjection.cs
new file mode 100644
index 00000000..d172c985
--- /dev/null
+++ b/MapProjections/Shared/AutoUtmProjection.cs
@@ -0,0 +1,50 @@
+// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
+// © 2022 Clemens Fischer
+// Licensed under the Microsoft Public License (Ms-PL)
+
+using ProjNet.CoordinateSystems;
+using System.Windows;
+
+namespace MapControl.Projections
+{
+ public class AutoUtmProjection : GeoApiProjection
+ {
+ private int zoneNumber;
+ private bool zoneIsNorth;
+
+ public AutoUtmProjection()
+ {
+ UpdateZone();
+ }
+
+ public override Point LocationToMap(Location location)
+ {
+ UpdateZone();
+ return base.LocationToMap(location);
+ }
+
+ public override Location MapToLocation(Point point)
+ {
+ UpdateZone();
+ return base.MapToLocation(point);
+ }
+
+ private void UpdateZone()
+ {
+ var north = Center.Latitude >= 0d;
+ var lon = Location.NormalizeLongitude(Center.Longitude);
+ var zone = (int)(lon + 180d) / 6 + 1;
+
+ if (zoneNumber != zone || zoneIsNorth != north)
+ {
+ zoneNumber = zone;
+ zoneIsNorth = north;
+
+ CoordinateSystem = ProjectedCoordinateSystem.WGS84_UTM(zoneNumber, zoneIsNorth);
+ CrsId = "AUTO2:42001";
+
+ System.Diagnostics.Debug.WriteLine(CoordinateSystem.Name);
+ }
+ }
+ }
+}
diff --git a/MapProjections/Shared/Ed50UtmProjection.cs b/MapProjections/Shared/Ed50UtmProjection.cs
index 114d2044..4a4fac7f 100644
--- a/MapProjections/Shared/Ed50UtmProjection.cs
+++ b/MapProjections/Shared/Ed50UtmProjection.cs
@@ -9,11 +9,6 @@ namespace MapControl.Projections
public class Ed50UtmProjection : GeoApiProjection
{
public Ed50UtmProjection(int zone)
- {
- SetZone(zone);
- }
-
- protected void SetZone(int zone)
{
if (zone < 28 || zone > 38)
{
diff --git a/MapProjections/Shared/Etrs89UtmProjection.cs b/MapProjections/Shared/Etrs89UtmProjection.cs
index 2a704654..71aa201c 100644
--- a/MapProjections/Shared/Etrs89UtmProjection.cs
+++ b/MapProjections/Shared/Etrs89UtmProjection.cs
@@ -9,11 +9,6 @@ namespace MapControl.Projections
public class Etrs89UtmProjection : GeoApiProjection
{
public Etrs89UtmProjection(int zone)
- {
- SetZone(zone);
- }
-
- protected void SetZone(int zone)
{
if (zone < 28 || zone > 38)
{
diff --git a/MapProjections/Shared/GeoApiProjectionFactory.cs b/MapProjections/Shared/GeoApiProjectionFactory.cs
index 4bb30f47..839a03ba 100644
--- a/MapProjections/Shared/GeoApiProjectionFactory.cs
+++ b/MapProjections/Shared/GeoApiProjectionFactory.cs
@@ -10,6 +10,7 @@ namespace MapControl.Projections
{
public const int WorldMercator = 3395;
public const int WebMercator = 3857;
+ public const int AutoUtm = 42001;
public const int Ed50UtmFirst = 23028;
public const int Ed50UtmLast = 23038;
public const int Etrs89UtmFirst = 25828;
@@ -26,16 +27,19 @@ namespace MapControl.Projections
public override MapProjection GetProjection(string crsId)
{
MapProjection projection = null;
+ var str = crsId.StartsWith("EPSG:") ? crsId.Substring(5)
+ : crsId.StartsWith("AUTO2:") ? crsId.Substring(6)
+ : null;
- if (crsId.StartsWith("EPSG:") && int.TryParse(crsId.Substring(5), out int epsgCode))
+ if (int.TryParse(str, out int code))
{
- if (CoordinateSystemWkts.TryGetValue(epsgCode, out string wkt))
+ if (CoordinateSystemWkts.TryGetValue(code, out string wkt))
{
projection = new GeoApiProjection(wkt);
}
else
{
- switch (epsgCode)
+ switch (code)
{
case WorldMercator:
projection = new WorldMercatorProjection();
@@ -45,20 +49,24 @@ namespace MapControl.Projections
projection = new WebMercatorProjection();
break;
+ case AutoUtm:
+ projection = new AutoUtmProjection();
+ break;
+
case int c when c >= Ed50UtmFirst && c <= Ed50UtmLast:
- projection = new Ed50UtmProjection(epsgCode % 100);
+ projection = new Ed50UtmProjection(code % 100);
break;
case int c when c >= Etrs89UtmFirst && c <= Etrs89UtmLast:
- projection = new Etrs89UtmProjection(epsgCode % 100);
+ projection = new Etrs89UtmProjection(code % 100);
break;
case int c when c >= Wgs84UtmNorthFirst && c <= Wgs84UtmNorthLast:
- projection = new Wgs84UtmProjection(epsgCode % 100, true);
+ projection = new Wgs84UtmProjection(code % 100, true);
break;
case int c when c >= Wgs84UtmSouthFirst && c <= Wgs84UtmSouthLast:
- projection = new Wgs84UtmProjection(epsgCode % 100, false);
+ projection = new Wgs84UtmProjection(code % 100, false);
break;
case Wgs84UpsNorth:
diff --git a/MapProjections/Shared/Wgs84UtmProjection.cs b/MapProjections/Shared/Wgs84UtmProjection.cs
index f774b08d..1072853e 100644
--- a/MapProjections/Shared/Wgs84UtmProjection.cs
+++ b/MapProjections/Shared/Wgs84UtmProjection.cs
@@ -10,11 +10,6 @@ namespace MapControl.Projections
public class Wgs84UtmProjection : GeoApiProjection
{
public Wgs84UtmProjection(int zone, bool north)
- {
- SetZone(zone, north);
- }
-
- protected void SetZone(int zone, bool north)
{
if (zone < 1 || zone > 60)
{
diff --git a/MapProjections/UWP/MapProjections.UWP.csproj b/MapProjections/UWP/MapProjections.UWP.csproj
index c5c8d671..9fffc773 100644
--- a/MapProjections/UWP/MapProjections.UWP.csproj
+++ b/MapProjections/UWP/MapProjections.UWP.csproj
@@ -40,6 +40,9 @@
PackageReference
+
+ AutoUtmProjection.cs
+
Ed50UtmProjection.cs