diff --git a/MapControl/Shared/BingMapsTileLayer.cs b/MapControl/Shared/BingMapsTileLayer.cs index 40ced4f0..03b1deb2 100644 --- a/MapControl/Shared/BingMapsTileLayer.cs +++ b/MapControl/Shared/BingMapsTileLayer.cs @@ -6,12 +6,12 @@ using System; using System.Diagnostics; using System.Globalization; using System.Linq; +using System.Xml.Linq; +using System.Threading.Tasks; #if WINDOWS_UWP -using Windows.Data.Xml.Dom; using Windows.UI.Xaml; #else using System.Windows; -using System.Xml; #endif namespace MapControl @@ -23,6 +23,8 @@ namespace MapControl /// public class BingMapsTileLayer : MapTileLayer { + private static readonly XNamespace imageryMetadataNamespace = "http://schemas.microsoft.com/search/local/ws/rest/v1"; + public enum MapMode { Road, Aerial, AerialWithLabels @@ -47,7 +49,7 @@ namespace MapControl public string Culture { get; set; } public Uri LogoImageUri { get; private set; } - private async void OnLoaded(object sender, RoutedEventArgs e) + private async void OnLoaded(object sender, RoutedEventArgs args) { Loaded -= OnLoaded; @@ -57,74 +59,59 @@ namespace MapControl return; } - var imageryMetadataUrl = "http://dev.virtualearth.net/REST/V1/Imagery/Metadata/" + Mode; + var uri = "http://dev.virtualearth.net/REST/V1/Imagery/Metadata/" + Mode + "?output=xml&key=" + ApiKey; try { - var uri = new Uri(imageryMetadataUrl + "?output=xml&key=" + ApiKey); - var document = await XmlDocument.LoadFromUriAsync(uri); - var imageryMetadata = document.DocumentElement.GetElementsByTagName("ImageryMetadata").OfType().FirstOrDefault(); + var document = await Task.Run(() => XDocument.Load(uri)); + var imageryMetadata = document.Descendants(imageryMetadataNamespace + "ImageryMetadata").FirstOrDefault(); + var brandLogoUri = document.Descendants(imageryMetadataNamespace + "BrandLogoUri").FirstOrDefault(); if (imageryMetadata != null) { ReadImageryMetadata(imageryMetadata); } - var brandLogoUri = document.DocumentElement.GetElementsByTagName("BrandLogoUri").OfType().FirstOrDefault(); - if (brandLogoUri != null) { - LogoImageUri = new Uri(brandLogoUri.InnerText); + LogoImageUri = new Uri(brandLogoUri.Value); } } catch (Exception ex) { - Debug.WriteLine("BingMapsTileLayer: {0}: {1}", imageryMetadataUrl, ex.Message); + Debug.WriteLine("BingMapsTileLayer: {0}: {1}", uri, ex.Message); } } - private void ReadImageryMetadata(XmlElement imageryMetadata) + private void ReadImageryMetadata(XElement imageryMetadata) { - string imageUrl = null; - string[] imageUrlSubdomains = null; - int? zoomMin = null; - int? zoomMax = null; + var imageUrl = imageryMetadata.Element(imageryMetadataNamespace + "ImageUrl")?.Value; + var imageUrlSubdomains = imageryMetadata.Element(imageryMetadataNamespace + "ImageUrlSubdomains")? + .Elements() + .Where(e => e.Name.LocalName == "string") + .Select(e => e.Value) + .ToArray(); - foreach (var element in imageryMetadata.ChildNodes.OfType()) + if (!string.IsNullOrEmpty(imageUrl) && + imageUrlSubdomains != null && + imageUrlSubdomains.Length > 0) { - switch ((string)element.LocalName) - { - case "ImageUrl": - imageUrl = element.InnerText; - break; - case "ImageUrlSubdomains": - imageUrlSubdomains = element.ChildNodes - .OfType() - .Where(e => (string)e.LocalName == "string") - .Select(e => e.InnerText) - .ToArray(); - break; - case "ZoomMin": - zoomMin = int.Parse(element.InnerText); - break; - case "ZoomMax": - zoomMax = int.Parse(element.InnerText); - break; - default: - break; - } - } + var zoomMin = imageryMetadata.Element(imageryMetadataNamespace + "ZoomMin")?.Value; + var zoomMax = imageryMetadata.Element(imageryMetadataNamespace + "ZoomMax")?.Value; + int z; - if (!string.IsNullOrEmpty(imageUrl) && imageUrlSubdomains != null && imageUrlSubdomains.Length > 0) - { - if (zoomMin.HasValue && zoomMin.Value > MinZoomLevel) + if (!string.IsNullOrEmpty(zoomMin) && + int.TryParse(zoomMin, out z) && + MinZoomLevel < z) { - MinZoomLevel = zoomMin.Value; + MinZoomLevel = z; } - if (zoomMax.HasValue && zoomMax.Value < MaxZoomLevel) + if (!string.IsNullOrEmpty(zoomMax) && + int.TryParse(zoomMax, out z) && + MaxZoomLevel > z) { - MaxZoomLevel = zoomMax.Value; + MaxZoomLevel = z; } if (string.IsNullOrEmpty(Culture)) diff --git a/MapControl/Shared/WmsImageLayer.cs b/MapControl/Shared/WmsImageLayer.cs index 33e01dbc..a43933ea 100644 --- a/MapControl/Shared/WmsImageLayer.cs +++ b/MapControl/Shared/WmsImageLayer.cs @@ -8,13 +8,12 @@ using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using System.Globalization; +using System.Xml.Linq; #if WINDOWS_UWP -using Windows.Data.Xml.Dom; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; #else -using System.Xml; using System.Windows; using System.Windows.Media; #endif @@ -23,6 +22,8 @@ namespace MapControl { public partial class WmsImageLayer : MapImageLayer { + private static readonly XNamespace wmsNamespace = "http://www.opengis.net/wms"; + public static readonly DependencyProperty ServiceUriProperty = DependencyProperty.Register( nameof(ServiceUri), typeof(Uri), typeof(WmsImageLayer), new PropertyMetadata(null, async (o, e) => await ((WmsImageLayer)o).UpdateImageAsync())); @@ -72,29 +73,17 @@ namespace MapControl if (ServiceUri != null) { - var uri = GetRequestUri("GetCapabilities"); + var uri = GetRequestUri("GetCapabilities").Replace(" ", "%20"); try { - var document = await XmlDocument.LoadFromUriAsync(new Uri(uri.Replace(" ", "%20"))); - layerNames = new List(); - - var capability = ChildElements(document.DocumentElement, "Capability").FirstOrDefault(); - if (capability != null) - { - var rootLayer = ChildElements(capability, "Layer").FirstOrDefault(); - if (rootLayer != null) - { - foreach (var layer in ChildElements(rootLayer, "Layer")) - { - var name = ChildElements(layer, "Name").FirstOrDefault(); - if (name != null) - { - layerNames.Add(name.InnerText); - } - } - } - } + layerNames = await Task.Run(() => + XDocument.Load(uri) + .Descendants(wmsNamespace + "Layer") + .Where(e => e.Attribute("queryable")?.Value == "1") + .Select(e => e.Element(wmsNamespace + "Name")?.Value) + .Where(n => !string.IsNullOrEmpty(n)) + .ToList()); } catch (Exception ex) { @@ -200,10 +189,5 @@ namespace MapControl return uri + "REQUEST=" + request; } - - private static IEnumerable ChildElements(XmlElement element, string name) - { - return element.ChildNodes.OfType().Where(e => (string)e.LocalName == name); - } } } diff --git a/MapControl/WPF.Core/MapControl.WPF.Core.csproj b/MapControl/WPF.Core/MapControl.WPF.Core.csproj index cd524ed3..5af2dc38 100644 --- a/MapControl/WPF.Core/MapControl.WPF.Core.csproj +++ b/MapControl/WPF.Core/MapControl.WPF.Core.csproj @@ -80,7 +80,6 @@ - diff --git a/MapControl/WPF/MapControl.WPF.csproj b/MapControl/WPF/MapControl.WPF.csproj index b17b3661..e4ac0451 100644 --- a/MapControl/WPF/MapControl.WPF.csproj +++ b/MapControl/WPF/MapControl.WPF.csproj @@ -47,10 +47,11 @@ - 4.0 + + @@ -195,7 +196,6 @@ Code - MapControl.snk diff --git a/MapControl/WPF/XmlDocument.WPF.cs b/MapControl/WPF/XmlDocument.WPF.cs deleted file mode 100644 index 9eac11bc..00000000 --- a/MapControl/WPF/XmlDocument.WPF.cs +++ /dev/null @@ -1,24 +0,0 @@ -// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control -// © 2019 Clemens Fischer -// Licensed under the Microsoft Public License (Ms-PL) - -using System; -using System.Threading.Tasks; - -namespace MapControl -{ - internal class XmlDocument : System.Xml.XmlDocument - { - public static XmlDocument LoadFromUri(Uri uri) - { - var document = new XmlDocument(); - document.Load(uri.ToString()); - return document; - } - - public static Task LoadFromUriAsync(Uri uri) - { - return Task.Run(() => LoadFromUri(uri)); - } - } -}