Automatic default WMS Layer

This commit is contained in:
ClemensF 2020-04-19 12:47:39 +02:00
parent c915860eff
commit 7cd1ccddc1
2 changed files with 80 additions and 55 deletions

View file

@ -19,6 +19,9 @@ using System.Windows.Media;
namespace MapControl namespace MapControl
{ {
/// <summary>
/// Displays a single map image from a Web Map Service (WMS).
/// </summary>
public partial class WmsImageLayer : MapImageLayer public partial class WmsImageLayer : MapImageLayer
{ {
public static readonly DependencyProperty ServiceUriProperty = DependencyProperty.Register( public static readonly DependencyProperty ServiceUriProperty = DependencyProperty.Register(
@ -27,7 +30,7 @@ namespace MapControl
public static readonly DependencyProperty LayersProperty = DependencyProperty.Register( public static readonly DependencyProperty LayersProperty = DependencyProperty.Register(
nameof(Layers), typeof(string), typeof(WmsImageLayer), nameof(Layers), typeof(string), typeof(WmsImageLayer),
new PropertyMetadata(string.Empty, async (o, e) => await ((WmsImageLayer)o).UpdateImageAsync())); new PropertyMetadata(null, async (o, e) => await ((WmsImageLayer)o).UpdateImageAsync()));
public static readonly DependencyProperty StylesProperty = DependencyProperty.Register( public static readonly DependencyProperty StylesProperty = DependencyProperty.Register(
nameof(Styles), typeof(string), typeof(WmsImageLayer), nameof(Styles), typeof(string), typeof(WmsImageLayer),
@ -37,24 +40,36 @@ namespace MapControl
nameof(Format), typeof(string), typeof(WmsImageLayer), nameof(Format), typeof(string), typeof(WmsImageLayer),
new PropertyMetadata("image/png", async (o, e) => await ((WmsImageLayer)o).UpdateImageAsync())); new PropertyMetadata("image/png", async (o, e) => await ((WmsImageLayer)o).UpdateImageAsync()));
/// <summary>
/// The base request URL.
/// </summary>
public Uri ServiceUri public Uri ServiceUri
{ {
get { return (Uri)GetValue(ServiceUriProperty); } get { return (Uri)GetValue(ServiceUriProperty); }
set { SetValue(ServiceUriProperty, value); } set { SetValue(ServiceUriProperty, value); }
} }
/// <summary>
/// Comma-separated list of Layer names to be displayed. If not set, the first Layer is displayed.
/// </summary>
public string Layers public string Layers
{ {
get { return (string)GetValue(LayersProperty); } get { return (string)GetValue(LayersProperty); }
set { SetValue(LayersProperty, value); } set { SetValue(LayersProperty, value); }
} }
/// <summary>
/// Comma-separated list of requested styles. Default is an empty string.
/// </summary>
public string Styles public string Styles
{ {
get { return (string)GetValue(StylesProperty); } get { return (string)GetValue(StylesProperty); }
set { SetValue(StylesProperty, value); } set { SetValue(StylesProperty, value); }
} }
/// <summary>
/// Requested image format. Default is image/png.
/// </summary>
public string Format public string Format
{ {
get { return (string)GetValue(FormatProperty); } get { return (string)GetValue(FormatProperty); }
@ -64,36 +79,19 @@ namespace MapControl
/// <summary> /// <summary>
/// Gets a list of all layer names returned by a GetCapabilities response. /// Gets a list of all layer names returned by a GetCapabilities response.
/// </summary> /// </summary>
public async Task<List<string>> GetLayerNamesAsync() public async Task<IEnumerable<string>> GetLayerNamesAsync()
{ {
List<string> layerNames = null; IEnumerable<string> layerNames = null;
var capabilities = await GetCapabilities();
if (ServiceUri != null) if (capabilities != null)
{ {
var uri = GetRequestUri("GetCapabilities").Replace(" ", "%20"); var ns = capabilities.Name.Namespace;
try layerNames = capabilities
{ .Descendants(ns + "Layer")
XElement capabilities; .Select(e => e.Element(ns + "Name")?.Value)
.Where(n => !string.IsNullOrEmpty(n));
using (var stream = await ImageLoader.HttpClient.GetStreamAsync(uri))
{
capabilities = XDocument.Load(stream).Root;
}
var ns = capabilities.Name.Namespace;
layerNames = capabilities
.Descendants(ns + "Layer")
.Where(e => e.Attribute("queryable")?.Value == "1")
.Select(e => e.Element(ns + "Name")?.Value)
.Where(n => !string.IsNullOrEmpty(n))
.ToList();
}
catch (Exception ex)
{
Debug.WriteLine("WmsImageLayer: {0}: {1}", uri, ex.Message);
}
} }
return layerNames; return layerNames;
@ -104,6 +102,13 @@ namespace MapControl
/// </summary> /// </summary>
protected override async Task<ImageSource> GetImageAsync() protected override async Task<ImageSource> GetImageAsync()
{ {
if (Layers == null && // get first Layer
ServiceUri != null &&
ServiceUri.ToString().IndexOf("LAYERS=", StringComparison.OrdinalIgnoreCase) < 0)
{
Layers = (await GetLayerNamesAsync())?.FirstOrDefault() ?? "";
}
var uri = GetImageUri(); var uri = GetImageUri();
return uri != null return uri != null
@ -170,5 +175,31 @@ namespace MapControl
return uri + "REQUEST=" + request; return uri + "REQUEST=" + request;
} }
private async Task<XElement> GetCapabilities()
{
XElement capabilities = null;
if (ServiceUri != null)
{
var uri = GetRequestUri("GetCapabilities").Replace(" ", "%20");
try
{
using (var stream = await ImageLoader.HttpClient.GetStreamAsync(uri))
{
capabilities = XDocument.Load(stream).Root;
}
var ns = capabilities.Name.Namespace;
}
catch (Exception ex)
{
Debug.WriteLine("WmsImageLayer: {0}: {1}", uri, ex.Message);
}
}
return capabilities;
}
} }
} }

View file

@ -21,7 +21,13 @@ namespace ViewModel
{ {
{ {
"OpenStreetMap", "OpenStreetMap",
MapTileLayer.OpenStreetMapTileLayer new MapTileLayer
{
SourceName = "OpenStreetMap",
Description = "© [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)",
TileSource = new TileSource { UriFormat = "https://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png" },
MaxZoomLevel = 19
}
}, },
{ {
"OpenStreetMap German", "OpenStreetMap German",
@ -29,7 +35,7 @@ namespace ViewModel
{ {
SourceName = "OpenStreetMap German", SourceName = "OpenStreetMap German",
Description = "© [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)", Description = "© [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)",
TileSource = new TileSource { UriFormat = "http://{c}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png" }, TileSource = new TileSource { UriFormat = "https://{c}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png" },
MaxZoomLevel = 19 MaxZoomLevel = 19
} }
}, },
@ -53,16 +59,6 @@ namespace ViewModel
MaxZoomLevel = 18 MaxZoomLevel = 18
} }
}, },
{
"Seamarks",
new MapTileLayer
{
SourceName = "OpenSeaMap",
TileSource = new TileSource { UriFormat = "http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png" },
MinZoomLevel = 9,
MaxZoomLevel = 18
}
},
{ {
"Bing Maps Road", "Bing Maps Road",
new BingMapsTileLayer new BingMapsTileLayer
@ -100,17 +96,7 @@ namespace ViewModel
new WmsImageLayer new WmsImageLayer
{ {
Description = "© [terrestris GmbH & Co. KG](http://ows.terrestris.de/)\nData © [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)", Description = "© [terrestris GmbH & Co. KG](http://ows.terrestris.de/)\nData © [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)",
ServiceUri = new Uri("http://ows.terrestris.de/osm/service"), ServiceUri = new Uri("http://ows.terrestris.de/osm/service")
Layers = "OSM-WMS"
}
},
{
"OpenStreetMap TOPO WMS",
new WmsImageLayer
{
Description = "© [terrestris GmbH & Co. KG](http://ows.terrestris.de/)\nData © [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)",
ServiceUri = new Uri("http://ows.terrestris.de/osm/service"),
Layers = "TOPO-OSM-WMS"
} }
}, },
{ {
@ -118,8 +104,7 @@ namespace ViewModel
new WmsImageLayer new WmsImageLayer
{ {
Description = "© [BKG](https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wms-topplusopen-mit-layer-fur-normalausgabe-und-druck-wms-topplus-open.html)", Description = "© [BKG](https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wms-topplusopen-mit-layer-fur-normalausgabe-und-druck-wms-topplus-open.html)",
ServiceUri = new Uri("https://sgx.geodatenzentrum.de/wms_topplus_open"), ServiceUri = new Uri("https://sgx.geodatenzentrum.de/wms_topplus_open")
Layers = "web"
} }
}, },
{ {
@ -132,9 +117,19 @@ namespace ViewModel
} }
}, },
{ {
"SevenCs ChartServer", "SevenCs ChartServer WMS",
new ChartServerLayer() new ChartServerLayer()
}, },
{
"Seamarks",
new MapTileLayer
{
SourceName = "OpenSeaMap",
TileSource = new TileSource { UriFormat = "http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png" },
MinZoomLevel = 9,
MaxZoomLevel = 18
}
},
}; };
private string currentMapLayerName = "OpenStreetMap"; private string currentMapLayerName = "OpenStreetMap";
@ -167,10 +162,9 @@ namespace ViewModel
"Stamen Terrain", "Stamen Terrain",
"Stamen Toner Light", "Stamen Toner Light",
"OpenStreetMap WMS", "OpenStreetMap WMS",
"OpenStreetMap TOPO WMS",
"TopPlusOpen WMS", "TopPlusOpen WMS",
"TopPlusOpen WMTS", "TopPlusOpen WMTS",
"SevenCs ChartServer", "SevenCs ChartServer WMS",
}; };
public MapLayers() public MapLayers()