mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2026-04-05 14:37:01 +00:00
.NET 9, including UWP
This commit is contained in:
parent
3526438f58
commit
cf0f4645d4
56 changed files with 484 additions and 1206 deletions
|
|
@ -63,7 +63,7 @@ namespace MapControl
|
|||
private static string QueryString(ushort tag) => $"/ifd/{{ushort={tag}}}";
|
||||
|
||||
private static ILogger logger;
|
||||
private static ILogger Logger => logger ?? (logger = ImageLoader.LoggerFactory?.CreateLogger(nameof(GeoImage)));
|
||||
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<GroundOverlay>();
|
||||
|
||||
public static readonly DependencyProperty SourcePathProperty =
|
||||
DependencyPropertyHelper.RegisterAttached<string>("SourcePath", typeof(GeoImage), null,
|
||||
|
|
@ -158,33 +158,32 @@ namespace MapControl
|
|||
|
||||
private static async Task<Matrix> ReadWorldFileMatrix(string worldFilePath)
|
||||
{
|
||||
using (var fileStream = File.OpenRead(worldFilePath))
|
||||
using (var streamReader = new StreamReader(fileStream))
|
||||
using var fileStream = File.OpenRead(worldFilePath);
|
||||
using var streamReader = new StreamReader(fileStream);
|
||||
|
||||
var parameters = new double[6];
|
||||
var index = 0;
|
||||
string line;
|
||||
|
||||
while (index < 6 &&
|
||||
(line = await streamReader.ReadLineAsync()) != null &&
|
||||
double.TryParse(line, NumberStyles.Float, CultureInfo.InvariantCulture, out double parameter))
|
||||
{
|
||||
var parameters = new double[6];
|
||||
var index = 0;
|
||||
string line;
|
||||
|
||||
while (index < 6 &&
|
||||
(line = await streamReader.ReadLineAsync()) != null &&
|
||||
double.TryParse(line, NumberStyles.Float, CultureInfo.InvariantCulture, out double parameter))
|
||||
{
|
||||
parameters[index++] = parameter;
|
||||
}
|
||||
|
||||
if (index != 6)
|
||||
{
|
||||
throw new ArgumentException($"Insufficient number of parameters in world file {worldFilePath}.");
|
||||
}
|
||||
|
||||
return new Matrix(
|
||||
parameters[0], // line 1: A or M11
|
||||
parameters[1], // line 2: D or M12
|
||||
parameters[2], // line 3: B or M21
|
||||
parameters[3], // line 4: E or M22
|
||||
parameters[4], // line 5: C or OffsetX
|
||||
parameters[5]); // line 6: F or OffsetY
|
||||
parameters[index++] = parameter;
|
||||
}
|
||||
|
||||
if (index != 6)
|
||||
{
|
||||
throw new ArgumentException($"Insufficient number of parameters in world file {worldFilePath}.");
|
||||
}
|
||||
|
||||
return new Matrix(
|
||||
parameters[0], // line 1: A or M11
|
||||
parameters[1], // line 2: D or M12
|
||||
parameters[2], // line 3: B or M21
|
||||
parameters[3], // line 4: E or M22
|
||||
parameters[4], // line 5: C or OffsetX
|
||||
parameters[5]); // line 6: F or OffsetY
|
||||
}
|
||||
|
||||
private static MapProjection GetProjection(short[] geoKeyDirectory)
|
||||
|
|
|
|||
|
|
@ -52,23 +52,22 @@ namespace MapControl
|
|||
|
||||
if (entry != null)
|
||||
{
|
||||
using (var memoryStream = new MemoryStream((int)entry.Length))
|
||||
using var memoryStream = new MemoryStream((int)entry.Length);
|
||||
|
||||
using (var zipStream = entry.Open())
|
||||
{
|
||||
using (var zipStream = entry.Open())
|
||||
{
|
||||
zipStream.CopyTo(memoryStream); // can't use CopyToAsync with ZipArchive
|
||||
}
|
||||
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
Image.Source = await ImageLoader.LoadImageAsync(memoryStream);
|
||||
zipStream.CopyTo(memoryStream); // can't use CopyToAsync with ZipArchive
|
||||
}
|
||||
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
Image.Source = await ImageLoader.LoadImageAsync(memoryStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ILogger logger;
|
||||
private static ILogger Logger => logger ?? (logger = ImageLoader.LoggerFactory?.CreateLogger<GroundOverlay>());
|
||||
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<GroundOverlay>();
|
||||
|
||||
public static readonly DependencyProperty SourcePathProperty =
|
||||
DependencyPropertyHelper.Register<GroundOverlay, string>(nameof(SourcePath), null,
|
||||
|
|
@ -127,20 +126,19 @@ namespace MapControl
|
|||
|
||||
private static async Task<List<ImageOverlay>> LoadImageOverlaysFromArchive(string archiveFilePath)
|
||||
{
|
||||
using (var archive = ZipFile.OpenRead(archiveFilePath))
|
||||
using var archive = ZipFile.OpenRead(archiveFilePath);
|
||||
|
||||
var docEntry = archive.GetEntry("doc.kml") ??
|
||||
archive.Entries.FirstOrDefault(e => e.Name.EndsWith(".kml")) ??
|
||||
throw new ArgumentException($"No KML entry found in {archiveFilePath}.");
|
||||
XDocument document;
|
||||
|
||||
using (var docStream = docEntry.Open())
|
||||
{
|
||||
var docEntry = archive.GetEntry("doc.kml") ??
|
||||
archive.Entries.FirstOrDefault(e => e.Name.EndsWith(".kml")) ??
|
||||
throw new ArgumentException($"No KML entry found in {archiveFilePath}.");
|
||||
XDocument document;
|
||||
|
||||
using (var docStream = docEntry.Open())
|
||||
{
|
||||
document = await LoadXDocument(docStream);
|
||||
}
|
||||
|
||||
return await LoadImageOverlays(document, imageOverlay => imageOverlay.LoadImage(archive));
|
||||
document = await LoadXDocument(docStream);
|
||||
}
|
||||
|
||||
return await LoadImageOverlays(document, imageOverlay => imageOverlay.LoadImage(archive));
|
||||
}
|
||||
|
||||
private static async Task<List<ImageOverlay>> LoadImageOverlaysFromFile(string docFilePath)
|
||||
|
|
|
|||
|
|
@ -326,34 +326,30 @@ namespace MapControl.Caching
|
|||
|
||||
private static byte[] ReadAllBytes(FileInfo file)
|
||||
{
|
||||
using (var stream = file.OpenRead())
|
||||
using var stream = file.OpenRead();
|
||||
var buffer = new byte[stream.Length];
|
||||
var offset = 0;
|
||||
|
||||
while (offset < buffer.Length)
|
||||
{
|
||||
var buffer = new byte[stream.Length];
|
||||
var offset = 0;
|
||||
|
||||
while (offset < buffer.Length)
|
||||
{
|
||||
offset += stream.Read(buffer, offset, buffer.Length - offset);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
offset += stream.Read(buffer, offset, buffer.Length - offset);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static async Task<byte[]> ReadAllBytes(FileInfo file, CancellationToken token)
|
||||
{
|
||||
using (var stream = file.OpenRead())
|
||||
using var stream = file.OpenRead();
|
||||
var buffer = new byte[stream.Length];
|
||||
var offset = 0;
|
||||
|
||||
while (offset < buffer.Length)
|
||||
{
|
||||
var buffer = new byte[stream.Length];
|
||||
var offset = 0;
|
||||
|
||||
while (offset < buffer.Length)
|
||||
{
|
||||
offset += await stream.ReadAsync(buffer, offset, buffer.Length - offset, token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
offset += await stream.ReadAsync(buffer, offset, buffer.Length - offset, token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static void SetExpiration(FileInfo file, DistributedCacheEntryOptions options)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace MapControl
|
|||
public static partial class ImageLoader
|
||||
{
|
||||
private static ILogger logger;
|
||||
private static ILogger Logger => logger ?? (logger = LoggerFactory?.CreateLogger(typeof(ImageLoader)));
|
||||
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<GroundOverlay>();
|
||||
|
||||
public static ILoggerFactory LoggerFactory { get; set; }
|
||||
|
||||
|
|
@ -33,10 +33,9 @@ namespace MapControl
|
|||
|
||||
public static async Task<ImageSource> LoadImageAsync(byte[] buffer)
|
||||
{
|
||||
using (var stream = new MemoryStream(buffer))
|
||||
{
|
||||
return await LoadImageAsync(stream);
|
||||
}
|
||||
using var stream = new MemoryStream(buffer);
|
||||
|
||||
return await LoadImageAsync(stream);
|
||||
}
|
||||
|
||||
public static async Task<ImageSource> LoadImageAsync(Uri uri, IProgress<double> progress = null)
|
||||
|
|
@ -84,25 +83,24 @@ namespace MapControl
|
|||
{
|
||||
var completionOptions = progress != null ? HttpCompletionOption.ResponseHeadersRead : HttpCompletionOption.ResponseContentRead;
|
||||
|
||||
using (var responseMessage = await HttpClient.GetAsync(uri, completionOptions).ConfigureAwait(false))
|
||||
{
|
||||
if (responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
if (progress != null && responseMessage.Content.Headers.ContentLength.HasValue)
|
||||
{
|
||||
buffer = await ReadAsByteArray(responseMessage.Content, progress).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
|
||||
}
|
||||
using var responseMessage = await HttpClient.GetAsync(uri, completionOptions).ConfigureAwait(false);
|
||||
|
||||
maxAge = responseMessage.Headers.CacheControl?.MaxAge;
|
||||
if (responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
if (progress != null && responseMessage.Content.Headers.ContentLength.HasValue)
|
||||
{
|
||||
buffer = await ReadAsByteArray(responseMessage.Content, progress).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger?.LogWarning("{status} ({reason}) from {uri}", (int)responseMessage.StatusCode, responseMessage.ReasonPhrase, uri);
|
||||
buffer = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
maxAge = responseMessage.Headers.CacheControl?.MaxAge;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger?.LogWarning("{status} ({reason}) from {uri}", (int)responseMessage.StatusCode, responseMessage.ReasonPhrase, uri);
|
||||
}
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace MapControl
|
|||
public class TileImageLoader : ITileImageLoader
|
||||
{
|
||||
private static ILogger logger;
|
||||
private static ILogger Logger => logger ?? (logger = ImageLoader.LoggerFactory?.CreateLogger<TileImageLoader>());
|
||||
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<GroundOverlay>();
|
||||
|
||||
/// <summary>
|
||||
/// Default folder path where a persistent cache implementation may save data, i.e. "C:\ProgramData\MapControl\TileCache".
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace MapControl
|
|||
public class WmsImageLayer : MapImageLayer
|
||||
{
|
||||
private static ILogger logger;
|
||||
private static ILogger Logger => logger ?? (logger = ImageLoader.LoggerFactory?.CreateLogger<WmsImageLayer>());
|
||||
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<GroundOverlay>();
|
||||
|
||||
public static readonly DependencyProperty ServiceUriProperty =
|
||||
DependencyPropertyHelper.Register<WmsImageLayer, Uri>(nameof(ServiceUri), null,
|
||||
|
|
@ -112,10 +112,9 @@ namespace MapControl
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var stream = await ImageLoader.HttpClient.GetStreamAsync(uri))
|
||||
{
|
||||
element = XDocument.Load(stream).Root;
|
||||
}
|
||||
using var stream = await ImageLoader.HttpClient.GetStreamAsync(uri);
|
||||
|
||||
element = XDocument.Load(stream).Root;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,10 +31,9 @@ namespace MapControl
|
|||
|
||||
if (capabilitiesUri.IsAbsoluteUri && (capabilitiesUri.Scheme == "http" || capabilitiesUri.Scheme == "https"))
|
||||
{
|
||||
using (var stream = await ImageLoader.HttpClient.GetStreamAsync(capabilitiesUri))
|
||||
{
|
||||
capabilities = ReadCapabilities(XDocument.Load(stream).Root, layer, capabilitiesUri.ToString());
|
||||
}
|
||||
using var stream = await ImageLoader.HttpClient.GetStreamAsync(capabilitiesUri);
|
||||
|
||||
capabilities = ReadCapabilities(XDocument.Load(stream).Root, layer, capabilitiesUri.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -46,12 +45,8 @@ namespace MapControl
|
|||
|
||||
public static WmtsCapabilities ReadCapabilities(XElement capabilitiesElement, string layer, string capabilitiesUrl)
|
||||
{
|
||||
var contentsElement = capabilitiesElement.Element(wmts + "Contents");
|
||||
|
||||
if (contentsElement == null)
|
||||
{
|
||||
throw new ArgumentException("Contents element not found.");
|
||||
}
|
||||
var contentsElement = capabilitiesElement.Element(wmts + "Contents")
|
||||
?? throw new ArgumentException("Contents element not found.");
|
||||
|
||||
XElement layerElement;
|
||||
|
||||
|
|
@ -102,12 +97,8 @@ namespace MapControl
|
|||
{
|
||||
var tileMatrixSetElement = contentsElement
|
||||
.Elements(wmts + "TileMatrixSet")
|
||||
.FirstOrDefault(s => s.Element(ows + "Identifier")?.Value == tileMatrixSetId);
|
||||
|
||||
if (tileMatrixSetElement == null)
|
||||
{
|
||||
throw new ArgumentException($"Linked TileMatrixSet element not found in Layer \"{layer}\".");
|
||||
}
|
||||
.FirstOrDefault(s => s.Element(ows + "Identifier")?.Value == tileMatrixSetId)
|
||||
?? throw new ArgumentException($"Linked TileMatrixSet element not found in Layer \"{layer}\".");
|
||||
|
||||
tileMatrixSets.Add(ReadTileMatrixSet(tileMatrixSetElement));
|
||||
}
|
||||
|
|
@ -134,7 +125,7 @@ namespace MapControl
|
|||
.ToLookup(r => r.Attribute("format").Value,
|
||||
r => r.Attribute("template").Value);
|
||||
|
||||
if (resourceUrls.Any())
|
||||
if (resourceUrls.Count != 0)
|
||||
{
|
||||
var urlTemplates = resourceUrls.Contains(formatPng) ? resourceUrls[formatPng]
|
||||
: resourceUrls.Contains(formatJpg) ? resourceUrls[formatJpg]
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace MapControl
|
|||
public class WmtsTileLayer : MapTileLayerBase
|
||||
{
|
||||
private static ILogger logger;
|
||||
private static ILogger Logger => logger ?? (logger = ImageLoader.LoggerFactory?.CreateLogger<WmtsTileLayer>());
|
||||
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<GroundOverlay>();
|
||||
|
||||
public static readonly DependencyProperty CapabilitiesUriProperty =
|
||||
DependencyPropertyHelper.Register<WmtsTileLayer, Uri>(nameof(CapabilitiesUri), null,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace MapControl
|
|||
{
|
||||
public WmtsTileMatrixSet TileMatrixSet { get; set; }
|
||||
|
||||
public override Uri GetUri(int column, int row, int zoomLevel)
|
||||
public override Uri GetUri(int zoomLevel, int column, int row)
|
||||
{
|
||||
Uri uri = null;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue