mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2026-04-05 14:37:01 +00:00
Extend map projections
This commit is contained in:
parent
57e614978b
commit
d8d1cbccaf
27 changed files with 448 additions and 207 deletions
40
MapControl/Shared/Etrs89UtmProjection.cs
Normal file
40
MapControl/Shared/Etrs89UtmProjection.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// ETRS89 UTM Projection with zone number.
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
if (zone < FirstZone || zone > LastZone)
|
||||
{
|
||||
throw new ArgumentException($"Invalid ETRS89 UTM zone {zone}.", nameof(zone));
|
||||
}
|
||||
|
||||
Zone = zone;
|
||||
CrsId = $"EPSG:{Zone - FirstZone + FirstZoneEpsgCode}";
|
||||
|
||||
// GRS 1980
|
||||
EquatorialRadius = 6378137d;
|
||||
Flattening = 1d / 298.257222101;
|
||||
ScaleFactor = DefaultScaleFactor;
|
||||
CentralMeridian = Zone * 6d - 183d;
|
||||
FalseEasting = 5e5;
|
||||
FalseNorthing = 0d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -381,15 +381,19 @@ namespace MapControl
|
|||
public void ZoomToBounds(BoundingBox boundingBox)
|
||||
{
|
||||
var mapRect = MapProjection.BoundingBoxToMapRect(boundingBox);
|
||||
var targetCenter = MapProjection.MapToLocation(mapRect.Center);
|
||||
|
||||
if (targetCenter != null)
|
||||
if (mapRect != null)
|
||||
{
|
||||
var scale = Math.Min(RenderSize.Width / mapRect.Width, RenderSize.Height / mapRect.Height);
|
||||
var targetCenter = MapProjection.MapToLocation(mapRect.Center);
|
||||
|
||||
TargetZoomLevel = ViewTransform.ScaleToZoomLevel(scale);
|
||||
TargetCenter = targetCenter;
|
||||
TargetHeading = 0d;
|
||||
if (targetCenter != null)
|
||||
{
|
||||
var scale = Math.Min(RenderSize.Width / mapRect.Width, RenderSize.Height / mapRect.Height);
|
||||
|
||||
TargetZoomLevel = ViewTransform.ScaleToZoomLevel(scale);
|
||||
TargetCenter = targetCenter;
|
||||
TargetHeading = 0d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,15 +134,11 @@ namespace MapControl
|
|||
//
|
||||
const double p = 0.01;
|
||||
|
||||
var bbox = string.Format(CultureInfo.InvariantCulture, "{0:F2},{1:F2},{2:F2},{3:F2}",
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0:F2},{1:F2},{2:F2},{3:F2}",
|
||||
p * Math.Ceiling(mapRect.XMin / p),
|
||||
p * Math.Ceiling(mapRect.YMin / p),
|
||||
p * Math.Floor(mapRect.XMax / p),
|
||||
p * Math.Floor(mapRect.YMax / p));
|
||||
|
||||
System.Diagnostics.Debug.WriteLine(bbox);
|
||||
|
||||
return bbox;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ namespace MapControl
|
|||
projection = new Nad27UtmProjection(epsgCode % 100);
|
||||
break;
|
||||
|
||||
case var c when c >= Nad83UtmProjection.FirstZoneEpsgCode && c <= Nad83UtmProjection.LastZoneEpsgCode:
|
||||
projection = new Nad83UtmProjection(epsgCode % 100);
|
||||
break;
|
||||
|
||||
case var c when c >= Wgs84UtmProjection.FirstZoneNorthEpsgCode && c <= Wgs84UtmProjection.LastZoneNorthEpsgCode:
|
||||
projection = new Wgs84UtmProjection(epsgCode % 100, true);
|
||||
break;
|
||||
|
|
|
|||
40
MapControl/Shared/Nad27UtmProjection.cs
Normal file
40
MapControl/Shared/Nad27UtmProjection.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// NAD27 UTM Projection with zone number.
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
if (zone < FirstZone || zone > LastZone)
|
||||
{
|
||||
throw new ArgumentException($"Invalid NAD27 UTM zone {zone}.", nameof(zone));
|
||||
}
|
||||
|
||||
Zone = zone;
|
||||
CrsId = $"EPSG:{Zone - FirstZone + FirstZoneEpsgCode}";
|
||||
|
||||
// Clarke 1866
|
||||
EquatorialRadius = 6378206.4;
|
||||
Flattening = 1d / 294.978698213898;
|
||||
ScaleFactor = DefaultScaleFactor;
|
||||
CentralMeridian = Zone * 6d - 183d;
|
||||
FalseEasting = 5e5;
|
||||
FalseNorthing = 0d;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
MapControl/Shared/Nad83UtmProjection.cs
Normal file
40
MapControl/Shared/Nad83UtmProjection.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// NAD83 UTM Projection with zone number.
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
if (zone < FirstZone || zone > LastZone)
|
||||
{
|
||||
throw new ArgumentException($"Invalid NAD83 UTM zone {zone}.", nameof(zone));
|
||||
}
|
||||
|
||||
Zone = zone;
|
||||
CrsId = $"EPSG:{Zone - FirstZone + FirstZoneEpsgCode}";
|
||||
|
||||
// GRS 1980
|
||||
EquatorialRadius = 6378137d;
|
||||
Flattening = 1d / 298.257222101;
|
||||
ScaleFactor = DefaultScaleFactor;
|
||||
CentralMeridian = Zone * 6d - 183d;
|
||||
FalseEasting = 5e5;
|
||||
FalseNorthing = 0d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,70 +6,6 @@ using System;
|
|||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// ETRS89 UTM Projection with zone number.
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
if (zone < FirstZone || zone > LastZone)
|
||||
{
|
||||
throw new ArgumentException($"Invalid ETRS89 UTM zone {zone}.", nameof(zone));
|
||||
}
|
||||
|
||||
Zone = zone;
|
||||
CrsId = $"EPSG:{Zone - FirstZone + FirstZoneEpsgCode}";
|
||||
|
||||
// GRS 1980
|
||||
EquatorialRadius = 6378137d;
|
||||
Flattening = 1d / 298.257222101;
|
||||
ScaleFactor = DefaultScaleFactor;
|
||||
CentralMeridian = Zone * 6d - 183d;
|
||||
FalseEasting = 5e5;
|
||||
FalseNorthing = 0d;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NAD27 UTM Projection with zone number.
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
if (zone < FirstZone || zone > LastZone)
|
||||
{
|
||||
throw new ArgumentException($"Invalid NAD27 UTM zone {zone}.", nameof(zone));
|
||||
}
|
||||
|
||||
Zone = zone;
|
||||
CrsId = $"EPSG:{Zone - FirstZone + FirstZoneEpsgCode}";
|
||||
|
||||
// Clarke 1866
|
||||
EquatorialRadius = 6378206.4;
|
||||
Flattening = 1d / 294.978698213898;
|
||||
ScaleFactor = DefaultScaleFactor;
|
||||
CentralMeridian = Zone * 6d - 183d;
|
||||
FalseEasting = 5e5;
|
||||
FalseNorthing = 0d;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WGS84 UTM Projection with zone number and north/south flag.
|
||||
/// </summary>
|
||||
|
|
@ -107,7 +43,7 @@ namespace MapControl
|
|||
IsNorth = north;
|
||||
CrsId = crsId ?? $"EPSG:{epsgCode}";
|
||||
EquatorialRadius = Wgs84EquatorialRadius;
|
||||
Flattening = 1d / Wgs84Flattening;
|
||||
Flattening = Wgs84Flattening;
|
||||
ScaleFactor = DefaultScaleFactor;
|
||||
CentralMeridian = Zone * 6d - 183d;
|
||||
FalseEasting = 5e5;
|
||||
|
|
@ -240,6 +240,12 @@ namespace MapControl
|
|||
protected virtual string GetMapRequestUri(BoundingBox boundingBox)
|
||||
{
|
||||
var mapRect = ParentMap.MapProjection.BoundingBoxToMapRect(boundingBox);
|
||||
|
||||
if (mapRect == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var viewScale = ParentMap.ViewTransform.Scale;
|
||||
|
||||
return GetRequestUri(new Dictionary<string, string>
|
||||
|
|
@ -265,6 +271,12 @@ namespace MapControl
|
|||
var viewSize = ParentMap.RenderSize;
|
||||
var boundingBox = ParentMap.ViewRectToBoundingBox(new Rect(0d, 0d, viewSize.Width, viewSize.Height));
|
||||
var mapRect = ParentMap.MapProjection.BoundingBoxToMapRect(boundingBox);
|
||||
|
||||
if (mapRect == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var viewRect = GetViewRect(mapRect);
|
||||
|
||||
var transform = new Matrix(1, 0, 0, 1, -viewSize.Width / 2, -viewSize.Height / 2);
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@
|
|||
<Compile Include="..\Shared\EquirectangularProjection.cs">
|
||||
<Link>EquirectangularProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Etrs89UtmProjection.cs">
|
||||
<Link>Etrs89UtmProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\FilePath.cs">
|
||||
<Link>FilePath.cs</Link>
|
||||
</Compile>
|
||||
|
|
@ -143,6 +146,12 @@
|
|||
<Compile Include="..\Shared\MapTileLayerBase.cs">
|
||||
<Link>MapTileLayerBase.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Nad27UtmProjection.cs">
|
||||
<Link>Nad27UtmProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Nad83UtmProjection.cs">
|
||||
<Link>Nad83UtmProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\OrthographicProjection.cs">
|
||||
<Link>OrthographicProjection.cs</Link>
|
||||
</Compile>
|
||||
|
|
@ -176,9 +185,6 @@
|
|||
<Compile Include="..\Shared\TransverseMercatorProjection.cs">
|
||||
<Link>TransverseMercatorProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\UtmProjection.cs">
|
||||
<Link>UtmProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\ViewportChangedEventArgs.cs">
|
||||
<Link>ViewportChangedEventArgs.cs</Link>
|
||||
</Compile>
|
||||
|
|
@ -191,6 +197,9 @@
|
|||
<Compile Include="..\Shared\WebMercatorProjection.cs">
|
||||
<Link>WebMercatorProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Wgs84UtmProjection.cs">
|
||||
<Link>Wgs84UtmProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\WmsImageLayer.cs">
|
||||
<Link>WmsImageLayer.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
|||
|
|
@ -37,17 +37,21 @@ namespace MapControl
|
|||
|
||||
if (projection != null && items != null)
|
||||
{
|
||||
image = await Task.Run(() => GetImage(projection, boundingBox, items));
|
||||
var mapRect = projection.BoundingBoxToMapRect(boundingBox);
|
||||
|
||||
if (mapRect != null)
|
||||
{
|
||||
image = await Task.Run(() => GetImage(projection, mapRect, items));
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private DrawingImage GetImage(MapProjection projection, BoundingBox boundingBox, IEnumerable<IMapDrawingItem> items)
|
||||
private DrawingImage GetImage(MapProjection projection, MapRect mapRect, IEnumerable<IMapDrawingItem> items)
|
||||
{
|
||||
var scale = ParentMap.ViewTransform.Scale;
|
||||
var rotation = ParentMap.ViewTransform.Rotation;
|
||||
var mapRect = projection.BoundingBoxToMapRect(boundingBox);
|
||||
var drawings = new DrawingGroup();
|
||||
|
||||
foreach (var item in items)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue