WmsImageLayer.InitializeAsync

This commit is contained in:
ClemensFischer 2025-09-22 09:17:26 +02:00
parent 7b2b95d629
commit a7e4f50256
3 changed files with 86 additions and 62 deletions

View file

@ -189,8 +189,7 @@ namespace MapControl
if (ParentMap != null && if (ParentMap != null &&
ParentMap.ActualWidth > 0d && ParentMap.ActualWidth > 0d &&
ParentMap.ActualHeight > 0d && ParentMap.ActualHeight > 0d &&
SupportedCrsIds != null && (SupportedCrsIds == null || SupportedCrsIds.Contains(ParentMap.MapProjection.CrsId)))
SupportedCrsIds.Contains(ParentMap.MapProjection.CrsId))
{ {
var width = ParentMap.ActualWidth * RelativeImageSize; var width = ParentMap.ActualWidth * RelativeImageSize;
var height = ParentMap.ActualHeight * RelativeImageSize; var height = ParentMap.ActualHeight * RelativeImageSize;

View file

@ -41,11 +41,6 @@ namespace MapControl
DependencyPropertyHelper.Register<WmsImageLayer, string>(nameof(RequestLayers), null, DependencyPropertyHelper.Register<WmsImageLayer, string>(nameof(RequestLayers), null,
async (layer, oldValue, newValue) => await layer.UpdateImageAsync()); async (layer, oldValue, newValue) => await layer.UpdateImageAsync());
public WmsImageLayer()
{
Loaded += OnLoaded;
}
/// <summary> /// <summary>
/// The base request URL. /// The base request URL.
/// </summary> /// </summary>
@ -83,6 +78,64 @@ namespace MapControl
/// </summary> /// </summary>
public override IReadOnlyCollection<string> SupportedCrsIds => supportedCrsIds; public override IReadOnlyCollection<string> SupportedCrsIds => supportedCrsIds;
private List<string> supportedCrsIds;
private bool HasLayer =>
RequestLayers != null ||
AvailableLayers?.Count > 0 ||
ServiceUri.Query?.IndexOf("LAYERS=", StringComparison.OrdinalIgnoreCase) > 0;
public WmsImageLayer()
{
Loaded += OnLoaded;
}
private async void OnLoaded(object sender, RoutedEventArgs e)
{
Loaded -= OnLoaded;
if (ServiceUri != null && !HasLayer)
{
await InitializeAsync();
if (AvailableLayers != null && AvailableLayers.Count > 0)
{
await UpdateImageAsync();
}
}
}
/// <summary>
/// Initializes the AvailableLayers and SupportedCrsIds properties.
/// Calling this method is only necessary when no layer name is known in advance.
/// It is called internally in a Loaded event handler when the RequestLayers and AvailableLayers
/// properties are null and the ServiceUri.Query part does not contain a LAYERS parameter.
/// </summary>
public async Task InitializeAsync()
{
var capabilities = await GetCapabilitiesAsync();
if (capabilities != null)
{
var ns = capabilities.Name.Namespace;
var capability = capabilities.Element(ns + "Capability");
supportedCrsIds = capability
.Descendants(ns + "Layer")
.Descendants(ns + "CRS")
.Select(e => e.Value)
.ToList();
var layerNames = capability
.Descendants(ns + "Layer")
.Select(e => e.Element(ns + "Name")?.Value)
.Where(n => !string.IsNullOrEmpty(n))
.ToList();
AvailableLayers = layerNames;
}
}
/// <summary> /// <summary>
/// Loads an XElement from the URL returned by GetCapabilitiesRequestUri(). /// Loads an XElement from the URL returned by GetCapabilitiesRequestUri().
/// </summary> /// </summary>
@ -94,7 +147,7 @@ namespace MapControl
{ {
var uri = GetCapabilitiesRequestUri(); var uri = GetCapabilitiesRequestUri();
if (!string.IsNullOrEmpty(uri)) if (uri != null)
{ {
try try
{ {
@ -120,6 +173,7 @@ namespace MapControl
string response = null; string response = null;
if (ServiceUri != null && if (ServiceUri != null &&
HasLayer &&
ParentMap?.MapProjection != null && ParentMap?.MapProjection != null &&
ParentMap.ActualWidth > 0d && ParentMap.ActualWidth > 0d &&
ParentMap.ActualHeight > 0d) ParentMap.ActualHeight > 0d)
@ -128,7 +182,7 @@ namespace MapControl
var uri = GetFeatureInfoRequestUri(boundingBox, position, format); var uri = GetFeatureInfoRequestUri(boundingBox, position, format);
if (!string.IsNullOrEmpty(uri)) if (uri != null)
{ {
try try
{ {
@ -151,7 +205,7 @@ namespace MapControl
{ {
ImageSource image = null; ImageSource image = null;
try if (ServiceUri != null && HasLayer)
{ {
if (boundingBox.West >= -180d && boundingBox.East <= 180d || if (boundingBox.West >= -180d && boundingBox.East <= 180d ||
ParentMap.MapProjection.Type > MapProjectionType.NormalCylindrical) ParentMap.MapProjection.Type > MapProjectionType.NormalCylindrical)
@ -160,7 +214,14 @@ namespace MapControl
if (uri != null) if (uri != null)
{ {
image = await ImageLoader.LoadImageAsync(new Uri(uri), progress); try
{
image = await ImageLoader.LoadImageAsync(new Uri(uri), progress);
}
catch (Exception ex)
{
Logger?.LogError(ex, "ImageLoader.LoadImageAsync");
}
} }
} }
else else
@ -183,14 +244,17 @@ namespace MapControl
if (uri1 != null && uri2 != null) if (uri1 != null && uri2 != null)
{ {
image = await ImageLoader.LoadMergedImageAsync(new Uri(uri1), new Uri(uri2), progress); try
{
image = await ImageLoader.LoadMergedImageAsync(new Uri(uri1), new Uri(uri2), progress);
}
catch (Exception ex)
{
Logger?.LogError(ex, "ImageLoader.LoadMergedImageAsync");
}
} }
} }
} }
catch (Exception ex)
{
Logger?.LogError(ex, "GetImageAsync");
}
return image; return image;
} }
@ -226,7 +290,7 @@ namespace MapControl
{ "SERVICE", "WMS" }, { "SERVICE", "WMS" },
{ "VERSION", "1.3.0" }, { "VERSION", "1.3.0" },
{ "REQUEST", "GetMap" }, { "REQUEST", "GetMap" },
{ "LAYERS", RequestLayers ?? "" }, { "LAYERS", RequestLayers ?? AvailableLayers?.FirstOrDefault() ?? "" },
{ "STYLES", RequestStyles ?? "" }, { "STYLES", RequestStyles ?? "" },
{ "FORMAT", "image/png" }, { "FORMAT", "image/png" },
{ "CRS", GetCrsValue() }, { "CRS", GetCrsValue() },
@ -264,7 +328,7 @@ namespace MapControl
{ "SERVICE", "WMS" }, { "SERVICE", "WMS" },
{ "VERSION", "1.3.0" }, { "VERSION", "1.3.0" },
{ "REQUEST", "GetFeatureInfo" }, { "REQUEST", "GetFeatureInfo" },
{ "LAYERS", RequestLayers ?? "" }, { "LAYERS", RequestLayers ?? AvailableLayers?.FirstOrDefault() ?? "" },
{ "STYLES", RequestStyles ?? "" }, { "STYLES", RequestStyles ?? "" },
{ "FORMAT", "image/png" }, { "FORMAT", "image/png" },
{ "INFO_FORMAT", format }, { "INFO_FORMAT", format },
@ -329,6 +393,8 @@ namespace MapControl
if (!string.IsNullOrEmpty(query)) if (!string.IsNullOrEmpty(query))
{ {
// Parameters from ServiceUri.Query take higher precedence than queryParameters.
//
foreach (var param in query.Substring(1).Split('&')) foreach (var param in query.Substring(1).Split('&'))
{ {
var pair = param.Split('='); var pair = param.Split('=');
@ -341,48 +407,5 @@ namespace MapControl
return uri.Replace(" ", "%20"); return uri.Replace(" ", "%20");
} }
private List<string> supportedCrsIds = [];
private async void OnLoaded(object sender, RoutedEventArgs e)
{
Loaded -= OnLoaded;
if (AvailableLayers == null && ServiceUri != null)
{
var capabilities = await GetCapabilitiesAsync();
if (capabilities != null)
{
var ns = capabilities.Name.Namespace;
var capability = capabilities.Element(ns + "Capability");
supportedCrsIds = capability
.Descendants(ns + "Layer")
.Descendants(ns + "CRS")
.Select(e => e.Value)
.ToList();
var layerNames = capability
.Descendants(ns + "Layer")
.Select(e => e.Element(ns + "Name")?.Value)
.Where(n => !string.IsNullOrEmpty(n))
.ToList();
AvailableLayers = layerNames;
if (layerNames.Count > 0 &&
RequestLayers == null &&
ServiceUri.OriginalString.IndexOf("LAYERS=", StringComparison.OrdinalIgnoreCase) < 0)
{
RequestLayers = layerNames[0];
}
else
{
await UpdateImageAsync();
}
}
}
}
} }
} }

View file

@ -28,7 +28,9 @@ namespace MapControl.UiTools
protected override bool GetIsEnabled(MapBase map) protected override bool GetIsEnabled(MapBase map)
{ {
return map.MapLayer is not IMapLayer mapLayer || mapLayer.SupportedCrsIds.Contains(CrsId); return map.MapLayer is not IMapLayer mapLayer
|| mapLayer.SupportedCrsIds == null
|| mapLayer.SupportedCrsIds.Contains(CrsId);
} }
protected override bool GetIsChecked(MapBase map) protected override bool GetIsChecked(MapBase map)