mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Cleaner code, mainly WmsImageLayer
This commit is contained in:
parent
4b4eecf810
commit
c46b6c1afa
|
|
@ -204,55 +204,57 @@ namespace MapControl
|
|||
|
||||
private void UpdateTiles()
|
||||
{
|
||||
var newTiles = new List<Tile>();
|
||||
int maxZoomLevel;
|
||||
var tiles = new List<Tile>();
|
||||
|
||||
if (TileSource != null &&
|
||||
TileMatrix != null &&
|
||||
(maxZoomLevel = Math.Min(TileMatrix.ZoomLevel, MaxZoomLevel)) >= MinZoomLevel)
|
||||
if (TileSource != null && TileMatrix != null)
|
||||
{
|
||||
var minZoomLevel = IsBaseMapLayer
|
||||
? Math.Max(TileMatrix.ZoomLevel - MaxBackgroundLevels, MinZoomLevel)
|
||||
: maxZoomLevel;
|
||||
var maxZoomLevel = Math.Min(TileMatrix.ZoomLevel, MaxZoomLevel);
|
||||
|
||||
for (var z = minZoomLevel; z <= maxZoomLevel; z++)
|
||||
if (maxZoomLevel >= MinZoomLevel)
|
||||
{
|
||||
var tileSize = 1 << (TileMatrix.ZoomLevel - z);
|
||||
var x1 = (int)Math.Floor((double)TileMatrix.XMin / tileSize); // may be negative
|
||||
var x2 = TileMatrix.XMax / tileSize;
|
||||
var y1 = Math.Max(TileMatrix.YMin / tileSize, 0);
|
||||
var y2 = Math.Min(TileMatrix.YMax / tileSize, (1 << z) - 1);
|
||||
var minZoomLevel = IsBaseMapLayer
|
||||
? Math.Max(TileMatrix.ZoomLevel - MaxBackgroundLevels, MinZoomLevel)
|
||||
: maxZoomLevel;
|
||||
|
||||
for (var y = y1; y <= y2; y++)
|
||||
for (var z = minZoomLevel; z <= maxZoomLevel; z++)
|
||||
{
|
||||
for (var x = x1; x <= x2; x++)
|
||||
var tileSize = 1 << (TileMatrix.ZoomLevel - z);
|
||||
var x1 = (int)Math.Floor((double)TileMatrix.XMin / tileSize); // may be negative
|
||||
var x2 = TileMatrix.XMax / tileSize;
|
||||
var y1 = Math.Max(TileMatrix.YMin / tileSize, 0);
|
||||
var y2 = Math.Min(TileMatrix.YMax / tileSize, (1 << z) - 1);
|
||||
|
||||
for (var y = y1; y <= y2; y++)
|
||||
{
|
||||
var tile = Tiles.FirstOrDefault(t => t.ZoomLevel == z && t.X == x && t.Y == y);
|
||||
|
||||
if (tile == null)
|
||||
for (var x = x1; x <= x2; x++)
|
||||
{
|
||||
tile = new Tile(z, x, y);
|
||||
var tile = Tiles.FirstOrDefault(t => t.ZoomLevel == z && t.X == x && t.Y == y);
|
||||
|
||||
var equivalentTile = Tiles.FirstOrDefault(
|
||||
t => t.ZoomLevel == z && t.XIndex == tile.XIndex && t.Y == y && !t.Pending);
|
||||
|
||||
if (equivalentTile != null)
|
||||
if (tile == null)
|
||||
{
|
||||
tile.SetImage(equivalentTile.Image.Source, false); // no fade-in animation
|
||||
}
|
||||
}
|
||||
tile = new Tile(z, x, y);
|
||||
|
||||
newTiles.Add(tile);
|
||||
var equivalentTile = Tiles.FirstOrDefault(
|
||||
t => t.ZoomLevel == z && t.XIndex == tile.XIndex && t.Y == y && !t.Pending);
|
||||
|
||||
if (equivalentTile != null)
|
||||
{
|
||||
tile.SetImage(equivalentTile.Image.Source, false); // no fade-in animation
|
||||
}
|
||||
}
|
||||
|
||||
tiles.Add(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tiles = newTiles;
|
||||
Tiles = tiles;
|
||||
|
||||
Children.Clear();
|
||||
|
||||
foreach (var tile in Tiles)
|
||||
foreach (var tile in tiles)
|
||||
{
|
||||
Children.Add(tile.Image);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace MapControl
|
|||
nameof(Description), typeof(string), typeof(MapTileLayerBase), new PropertyMetadata(null));
|
||||
|
||||
public static readonly DependencyProperty MaxBackgroundLevelsProperty = DependencyProperty.Register(
|
||||
nameof(MaxBackgroundLevels), typeof(int), typeof(MapTileLayerBase), new PropertyMetadata(8));
|
||||
nameof(MaxBackgroundLevels), typeof(int), typeof(MapTileLayerBase), new PropertyMetadata(5));
|
||||
|
||||
public static readonly DependencyProperty UpdateIntervalProperty = DependencyProperty.Register(
|
||||
nameof(UpdateInterval), typeof(TimeSpan), typeof(MapTileLayerBase),
|
||||
|
|
@ -111,7 +111,7 @@ namespace MapControl
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of background tile levels. Default value is 8.
|
||||
/// Maximum number of background tile levels. Default value is 5.
|
||||
/// Only effective in a MapTileLayer or WmtsTileLayer that is the MapLayer of its ParentMap.
|
||||
/// </summary>
|
||||
public int MaxBackgroundLevels
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace MapControl
|
|||
new PropertyMetadata(null,
|
||||
async (o, e) =>
|
||||
{
|
||||
if (e.OldValue != null) // ignore initial property change from GetImageAsync
|
||||
if (e.OldValue != null) // ignore property change from GetImageAsync
|
||||
{
|
||||
await ((WmsImageLayer)o).UpdateImageAsync();
|
||||
}
|
||||
|
|
@ -222,7 +222,12 @@ namespace MapControl
|
|||
/// </summary>
|
||||
protected virtual string GetCapabilitiesRequestUri()
|
||||
{
|
||||
return GetRequestUri("GetCapabilities").Replace(" ", "%20");
|
||||
return GetRequestUri(new Dictionary<string, string>
|
||||
{
|
||||
{ "SERVICE", "WMS" },
|
||||
{ "VERSION", "1.3.0" },
|
||||
{ "REQUEST", "GetCapabilities" }
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -230,40 +235,29 @@ namespace MapControl
|
|||
/// </summary>
|
||||
protected virtual string GetMapRequestUri()
|
||||
{
|
||||
string uri = null;
|
||||
var projection = ParentMap?.MapProjection;
|
||||
|
||||
if (projection != null)
|
||||
if (projection == null)
|
||||
{
|
||||
uri = GetRequestUri("GetMap");
|
||||
|
||||
if (uri.IndexOf("LAYERS=", StringComparison.OrdinalIgnoreCase) < 0 && Layers != null)
|
||||
{
|
||||
uri += "&LAYERS=" + Layers;
|
||||
}
|
||||
|
||||
if (uri.IndexOf("STYLES=", StringComparison.OrdinalIgnoreCase) < 0 && Styles != null)
|
||||
{
|
||||
uri += "&STYLES=" + Styles;
|
||||
}
|
||||
|
||||
if (uri.IndexOf("FORMAT=", StringComparison.OrdinalIgnoreCase) < 0)
|
||||
{
|
||||
uri += "&FORMAT=image/png";
|
||||
}
|
||||
|
||||
var mapRect = projection.BoundingBoxToRect(BoundingBox);
|
||||
var viewScale = ParentMap.ViewTransform.Scale;
|
||||
|
||||
uri += "&" + GetCrsParam(projection);
|
||||
uri += "&" + GetBboxParam(projection, mapRect);
|
||||
uri += "&WIDTH=" + (int)Math.Round(viewScale * mapRect.Width);
|
||||
uri += "&HEIGHT=" + (int)Math.Round(viewScale * mapRect.Height);
|
||||
|
||||
uri = uri.Replace(" ", "%20");
|
||||
return null;
|
||||
}
|
||||
|
||||
return uri;
|
||||
var mapRect = projection.BoundingBoxToRect(BoundingBox);
|
||||
var viewScale = ParentMap.ViewTransform.Scale;
|
||||
|
||||
return GetRequestUri(new Dictionary<string, string>
|
||||
{
|
||||
{ "SERVICE", "WMS" },
|
||||
{ "VERSION", "1.3.0" },
|
||||
{ "REQUEST", "GetMap" },
|
||||
{ "LAYERS", Layers ?? "" },
|
||||
{ "STYLES", Styles ?? "" },
|
||||
{ "FORMAT", "image/png" },
|
||||
{ "CRS", GetCrsValue(projection) },
|
||||
{ "BBOX", GetBboxValue(projection, mapRect) },
|
||||
{ "WIDTH", Math.Round(viewScale * mapRect.Width).ToString("F0") },
|
||||
{ "HEIGHT", Math.Round(viewScale * mapRect.Height).ToString("F0") }
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -271,82 +265,72 @@ namespace MapControl
|
|||
/// </summary>
|
||||
protected virtual string GetFeatureInfoRequestUri(Point position, string format)
|
||||
{
|
||||
string uri = null;
|
||||
var projection = ParentMap?.MapProjection;
|
||||
|
||||
if (projection != null)
|
||||
if (projection == null)
|
||||
{
|
||||
uri = GetRequestUri("GetFeatureInfo");
|
||||
return null;
|
||||
}
|
||||
|
||||
var i = uri.IndexOf("LAYERS=", StringComparison.OrdinalIgnoreCase);
|
||||
var mapRect = projection.BoundingBoxToRect(BoundingBox);
|
||||
var viewRect = GetViewRect(mapRect);
|
||||
var viewSize = ParentMap.RenderSize;
|
||||
|
||||
if (i >= 0)
|
||||
var transform = new Matrix(1, 0, 0, 1, -viewSize.Width / 2, -viewSize.Height / 2);
|
||||
transform.Rotate(-viewRect.Rotation);
|
||||
transform.Translate(viewRect.Width / 2, viewRect.Height / 2);
|
||||
|
||||
var imagePos = transform.Transform(position);
|
||||
|
||||
var queryParameters = new Dictionary<string, string>
|
||||
{
|
||||
{ "SERVICE", "WMS" },
|
||||
{ "VERSION", "1.3.0" },
|
||||
{ "REQUEST", "GetFeatureInfo" },
|
||||
{ "LAYERS", Layers ?? "" },
|
||||
{ "STYLES", Styles ?? "" },
|
||||
{ "FORMAT", "image/png" },
|
||||
{ "INFO_FORMAT", format },
|
||||
{ "CRS", GetCrsValue(projection) },
|
||||
{ "BBOX", GetBboxValue(projection, mapRect) },
|
||||
{ "WIDTH", Math.Round(viewRect.Width).ToString("F0") },
|
||||
{ "HEIGHT", Math.Round(viewRect.Height).ToString("F0") },
|
||||
{ "I", Math.Round(imagePos.X).ToString("F0") },
|
||||
{ "J", Math.Round(imagePos.Y).ToString("F0") }
|
||||
};
|
||||
|
||||
return GetRequestUri(queryParameters) + "&QUERY_LAYERS=" + queryParameters["LAYERS"];
|
||||
}
|
||||
|
||||
protected virtual string GetCrsValue(MapProjection projection)
|
||||
{
|
||||
return projection.GetCrsValue();
|
||||
}
|
||||
|
||||
protected virtual string GetBboxValue(MapProjection projection, Rect mapRect)
|
||||
{
|
||||
return projection.GetBboxValue(mapRect);
|
||||
}
|
||||
|
||||
protected string GetRequestUri(IDictionary<string, string> queryParameters)
|
||||
{
|
||||
var query = ServiceUri.Query;
|
||||
|
||||
if (!string.IsNullOrEmpty(query))
|
||||
{
|
||||
foreach (var param in query.Substring(1).Split('&'))
|
||||
{
|
||||
i += "LAYERS=".Length;
|
||||
var j = uri.IndexOf('&', i);
|
||||
var layers = j >= i ? uri.Substring(i, j - i) : uri.Substring(i);
|
||||
uri += "&QUERY_LAYERS=" + layers;
|
||||
var pair = param.Split('=');
|
||||
queryParameters[pair[0].ToUpper()] = pair.Length > 1 ? pair[1] : "";
|
||||
}
|
||||
else if (Layers != null)
|
||||
{
|
||||
uri += "&LAYERS=" + Layers;
|
||||
uri += "&QUERY_LAYERS=" + Layers;
|
||||
}
|
||||
|
||||
var mapRect = projection.BoundingBoxToRect(BoundingBox);
|
||||
var viewRect = GetViewRect(mapRect);
|
||||
var viewSize = ParentMap.RenderSize;
|
||||
|
||||
var transform = new Matrix(1, 0, 0, 1, -viewSize.Width / 2, -viewSize.Height / 2);
|
||||
transform.Rotate(-viewRect.Rotation);
|
||||
transform.Translate(viewRect.Width / 2, viewRect.Height / 2);
|
||||
|
||||
var imagePos = transform.Transform(position);
|
||||
|
||||
uri += "&" + GetCrsParam(projection);
|
||||
uri += "&" + GetBboxParam(projection, mapRect);
|
||||
uri += "&WIDTH=" + (int)Math.Round(viewRect.Width);
|
||||
uri += "&HEIGHT=" + (int)Math.Round(viewRect.Height);
|
||||
uri += "&I=" + (int)Math.Round(imagePos.X);
|
||||
uri += "&J=" + (int)Math.Round(imagePos.Y);
|
||||
uri += "&INFO_FORMAT=" + format;
|
||||
|
||||
uri = uri.Replace(" ", "%20");
|
||||
}
|
||||
|
||||
return uri;
|
||||
}
|
||||
var uri = ServiceUri.GetLeftPart(UriPartial.Path) + "?"
|
||||
+ string.Join("&", queryParameters.Select(kv => kv.Key + "=" + kv.Value));
|
||||
|
||||
protected virtual string GetCrsParam(MapProjection projection)
|
||||
{
|
||||
return "CRS=" + projection.GetCrsValue();
|
||||
}
|
||||
Debug.WriteLine(uri);
|
||||
|
||||
protected virtual string GetBboxParam(MapProjection projection, Rect mapRect)
|
||||
{
|
||||
return "BBOX=" + projection.GetBboxValue(mapRect);
|
||||
}
|
||||
|
||||
protected string GetRequestUri(string request)
|
||||
{
|
||||
var uri = ServiceUri.ToString();
|
||||
|
||||
if (!uri.EndsWith("?") && !uri.EndsWith("&"))
|
||||
{
|
||||
uri += !uri.Contains("?") ? "?" : "&";
|
||||
}
|
||||
|
||||
if (uri.IndexOf("SERVICE=", StringComparison.OrdinalIgnoreCase) < 0)
|
||||
{
|
||||
uri += "SERVICE=WMS&";
|
||||
}
|
||||
|
||||
if (uri.IndexOf("VERSION=", StringComparison.OrdinalIgnoreCase) < 0)
|
||||
{
|
||||
uri += "VERSION=1.3.0&";
|
||||
}
|
||||
|
||||
return uri + "REQUEST=" + request;
|
||||
return uri.Replace(" ", "%20");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,44 +133,36 @@ namespace MapControl
|
|||
|
||||
if (resourceUrls.Any())
|
||||
{
|
||||
var urlTemplates
|
||||
= resourceUrls.Contains(formatPng) ? resourceUrls[formatPng]
|
||||
: resourceUrls.Contains(formatJpg) ? resourceUrls[formatJpg]
|
||||
: resourceUrls.First();
|
||||
var urlTemplates = resourceUrls.Contains(formatPng) ? resourceUrls[formatPng]
|
||||
: resourceUrls.Contains(formatJpg) ? resourceUrls[formatJpg]
|
||||
: resourceUrls.First();
|
||||
|
||||
urlTemplate = urlTemplates.First().Replace("{Style}", style);
|
||||
}
|
||||
else if (capabilitiesUrl != null)
|
||||
else if (capabilitiesUrl != null &&
|
||||
capabilitiesUrl.IndexOf("Request=GetCapabilities", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
const string requestParam = "Request=GetCapabilities";
|
||||
var requestIndex = capabilitiesUrl.IndexOf(requestParam, StringComparison.OrdinalIgnoreCase);
|
||||
var formats = layerElement.Descendants(ns + "Format").Select(e => e.Value).ToList();
|
||||
var format = formatPng;
|
||||
|
||||
if (requestIndex > 0)
|
||||
if (formats.Count > 0)
|
||||
{
|
||||
var formats = layerElement.Descendants(ns + "Format").Select(e => e.Value).ToList();
|
||||
|
||||
if (formats.Count == 0)
|
||||
{
|
||||
throw new ArgumentException($"No Format element found in Layer \"{layerIdentifier}\".");
|
||||
}
|
||||
|
||||
var format
|
||||
= formats.Contains(formatPng) ? formatPng
|
||||
: formats.Contains(formatJpg) ? formatJpg
|
||||
: formats[0];
|
||||
|
||||
urlTemplate = capabilitiesUrl.Substring(0, requestIndex)
|
||||
+ "Request=GetTile"
|
||||
+ capabilitiesUrl.Substring(requestIndex + requestParam.Length)
|
||||
+ "&Version=1.0.0"
|
||||
+ "&Layer=" + layerIdentifier
|
||||
+ "&Format=" + format
|
||||
+ "&Style=" + style
|
||||
+ "&TileMatrixSet={TileMatrixSet}"
|
||||
+ "&TileMatrix={TileMatrix}"
|
||||
+ "&TileCol={TileCol}"
|
||||
+ "&TileRow={TileRow}";
|
||||
format = formats.Contains(formatPng) ? formatPng
|
||||
: formats.Contains(formatJpg) ? formatJpg
|
||||
: formats[0];
|
||||
}
|
||||
|
||||
urlTemplate = capabilitiesUrl.Split('?')[0]
|
||||
+ "?Service=WMTS"
|
||||
+ "&Request=GetTile"
|
||||
+ "&Version=1.0.0"
|
||||
+ "&Layer=" + layerIdentifier
|
||||
+ "&Style=" + style
|
||||
+ "&Format=" + format
|
||||
+ "&TileMatrixSet={TileMatrixSet}"
|
||||
+ "&TileMatrix={TileMatrix}"
|
||||
+ "&TileRow={TileRow}"
|
||||
+ "&TileCol={TileCol}";
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(urlTemplate))
|
||||
|
|
|
|||
Loading…
Reference in a new issue