mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2026-01-05 08:10:15 +01:00
Added GeoApiProjectionFactory
This commit is contained in:
parent
d7c45effc6
commit
5b9e5529f6
|
|
@ -106,6 +106,15 @@ namespace MapControl.Projections
|
|||
get { return isWebMercator; }
|
||||
}
|
||||
|
||||
|
||||
public GeoApiProjection(string wkt = null)
|
||||
{
|
||||
if (wkt != null)
|
||||
{
|
||||
WKT = wkt;
|
||||
}
|
||||
}
|
||||
|
||||
public override Point LocationToMap(Location location)
|
||||
{
|
||||
if (LocationToMapTransform == null)
|
||||
|
|
|
|||
70
MapProjections/Shared/GeoApiProjectionFactory.cs
Normal file
70
MapProjections/Shared/GeoApiProjectionFactory.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// © 2022 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace MapControl.Projections
|
||||
{
|
||||
public class GeoApiProjectionFactory : MapProjectionFactory
|
||||
{
|
||||
private readonly Dictionary<int, string> wkts = new Dictionary<int, string>();
|
||||
private readonly HttpClient httpClient = new HttpClient();
|
||||
|
||||
public override MapProjection CreateProjection(string projectionDefinition)
|
||||
{
|
||||
var projection = base.CreateProjection(projectionDefinition);
|
||||
|
||||
if (projection == null &&
|
||||
projectionDefinition.StartsWith("EPSG:") &&
|
||||
int.TryParse(projectionDefinition.Substring(5), out int epsgCode))
|
||||
{
|
||||
if (epsgCode >= 32601 && epsgCode <= 32660)
|
||||
{
|
||||
projection = new UtmProjection(epsgCode - 32600, true);
|
||||
}
|
||||
else if (epsgCode == 32661)
|
||||
{
|
||||
projection = new UpsNorthProjection();
|
||||
}
|
||||
else if (epsgCode >= 32701 && epsgCode <= 32760)
|
||||
{
|
||||
projection = new UtmProjection(epsgCode - 32700, false);
|
||||
}
|
||||
else if (epsgCode == 32761)
|
||||
{
|
||||
projection = new UpsSouthProjection();
|
||||
}
|
||||
else
|
||||
{
|
||||
projection = new GeoApiProjection(GetWkt(epsgCode));
|
||||
}
|
||||
}
|
||||
|
||||
return projection;
|
||||
}
|
||||
|
||||
private string GetWkt(int epsgCode)
|
||||
{
|
||||
if (!wkts.TryGetValue(epsgCode, out string wkt))
|
||||
{
|
||||
var url = string.Format("https://epsg.io/{0}.wkt", epsgCode);
|
||||
|
||||
try
|
||||
{
|
||||
wkt = httpClient.GetStringAsync(url).Result; // potential deadlock?
|
||||
wkts[epsgCode] = wkt;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"GeoApiProjectionFactory.GetWkt({epsgCode}): {url}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return wkt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -114,14 +114,16 @@ namespace MapControl.Projections
|
|||
|
||||
public class UpsNorthProjection : PolarStereographicProjection
|
||||
{
|
||||
public UpsNorthProjection() : base("EPSG:32661", true, 0.994, 2e6, 2e6)
|
||||
public UpsNorthProjection()
|
||||
: base("EPSG:32661", true, 0.994, 2e6, 2e6)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class UpsSouthProjection : PolarStereographicProjection
|
||||
{
|
||||
public UpsSouthProjection() : base("EPSG:32761", false, 0.994, 2e6, 2e6)
|
||||
public UpsSouthProjection()
|
||||
: base("EPSG:32761", false, 0.994, 2e6, 2e6)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,23 @@ namespace MapControl.Projections
|
|||
}
|
||||
}
|
||||
|
||||
public UtmProjection()
|
||||
{
|
||||
}
|
||||
|
||||
public UtmProjection(int zoneNumber, bool north)
|
||||
{
|
||||
SetZone(zoneNumber, north);
|
||||
}
|
||||
|
||||
public UtmProjection(Location location)
|
||||
{
|
||||
SetZone(location);
|
||||
}
|
||||
|
||||
public void SetZone(int zoneNumber, bool north)
|
||||
{
|
||||
if (zoneNumber < 1 || zoneNumber > 61)
|
||||
if (zoneNumber < 1 || zoneNumber > 60)
|
||||
{
|
||||
throw new ArgumentException("Invalid UTM zone number.", nameof(zoneNumber));
|
||||
}
|
||||
|
|
@ -56,7 +70,7 @@ namespace MapControl.Projections
|
|||
{
|
||||
var zoneNumber = Math.Min((int)(Location.NormalizeLongitude(location.Longitude) + 180d) / 6 + 1, 60);
|
||||
|
||||
SetZone(zoneNumber, location.Latitude >= 0);
|
||||
SetZone(zoneNumber, location.Latitude >= 0d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@
|
|||
<Compile Include="..\Shared\GeoApiProjection.cs">
|
||||
<Link>GeoApiProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\GeoApiProjectionFactory.cs">
|
||||
<Link>GeoApiProjectionFactory.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\PolarStereographicProjection.cs">
|
||||
<Link>PolarStereographicProjection.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@
|
|||
<Compile Include="..\Shared\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net48' or '$(TargetFramework)'=='net462'">
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ProjNET4GeoAPI" Version="1.4.1" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
Loading…
Reference in a new issue