diff --git a/MapControl/Shared/MapPanel.cs b/MapControl/Shared/MapPanel.cs
index abf720b7..0e89db9a 100644
--- a/MapControl/Shared/MapPanel.cs
+++ b/MapControl/Shared/MapPanel.cs
@@ -122,16 +122,22 @@ namespace MapControl
///
public ViewRect GetViewRectangle(BoundingBox boundingBox)
{
- var projection = parentMap.MapProjection;
- var rect = projection.BoundingBoxToRect(boundingBox);
+ return GetViewRectangle(parentMap.MapProjection.BoundingBoxToRect(boundingBox));
+ }
+
+ ///
+ /// Returns the potentially rotated view rectangle of a map coordinate rectangle.
+ ///
+ public ViewRect GetViewRectangle(Rect rect)
+ {
var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d);
var pos = parentMap.ViewTransform.MapToView(center);
- if (projection.IsNormalCylindrical &&
+ if (parentMap.MapProjection.IsNormalCylindrical &&
(pos.X < 0d || pos.X > parentMap.RenderSize.Width ||
pos.Y < 0d || pos.Y > parentMap.RenderSize.Height))
{
- var location = projection.MapToLocation(center);
+ var location = parentMap.MapProjection.MapToLocation(center);
location.Longitude = parentMap.ConstrainedLongitude(location.Longitude);
pos = parentMap.LocationToView(location);
@@ -224,7 +230,8 @@ namespace MapControl
{
element.Width = rect.Width;
element.Height = rect.Height;
- element.Arrange(new Rect(rect.X, rect.Y, rect.Width, rect.Height));
+
+ ArrangeElement(element, new Rect(rect.X, rect.Y, rect.Width, rect.Height));
if (element.RenderTransform is RotateTransform rotateTransform)
{
@@ -270,15 +277,7 @@ namespace MapControl
break;
}
- if (element.UseLayoutRounding)
- {
- rect.X = Math.Round(rect.X);
- rect.Y = Math.Round(rect.Y);
- rect.Width = Math.Round(rect.Width);
- rect.Height = Math.Round(rect.Height);
- }
-
- element.Arrange(rect);
+ ArrangeElement(element, rect);
}
private static void ArrangeElement(FrameworkElement element, Size parentSize)
@@ -321,6 +320,11 @@ namespace MapControl
break;
}
+ ArrangeElement(element, rect);
+ }
+
+ private static void ArrangeElement(FrameworkElement element, Rect rect)
+ {
if (element.UseLayoutRounding)
{
rect.X = Math.Round(rect.X);
diff --git a/MapControl/Shared/WmsImageLayer.cs b/MapControl/Shared/WmsImageLayer.cs
index 227820c3..e2529213 100644
--- a/MapControl/Shared/WmsImageLayer.cs
+++ b/MapControl/Shared/WmsImageLayer.cs
@@ -36,6 +36,14 @@ namespace MapControl
nameof(Styles), typeof(string), typeof(WmsImageLayer),
new PropertyMetadata(string.Empty, async (o, e) => await ((WmsImageLayer)o).UpdateImageAsync()));
+ public WmsImageLayer()
+ {
+ foreach (FrameworkElement child in Children)
+ {
+ child.UseLayoutRounding = true;
+ }
+ }
+
///
/// The base request URL.
///
@@ -64,7 +72,29 @@ namespace MapControl
}
///
- /// Calls GetCapabilitiesRequestUri() and asynchronously loads an XElement from the returned URL.
+ /// Gets a list of all layer names returned by a GetCapabilities response.
+ ///
+ public async Task> GetLayerNamesAsync()
+ {
+ IEnumerable layerNames = null;
+
+ var capabilities = await GetCapabilitiesAsync();
+
+ if (capabilities != null)
+ {
+ var ns = capabilities.Name.Namespace;
+
+ layerNames = capabilities
+ .Descendants(ns + "Layer")
+ .Select(e => e.Element(ns + "Name")?.Value)
+ .Where(n => !string.IsNullOrEmpty(n));
+ }
+
+ return layerNames;
+ }
+
+ ///
+ /// Loads an XElement from the URL returned by GetCapabilitiesRequestUri().
///
public async Task GetCapabilitiesAsync()
{
@@ -91,7 +121,7 @@ namespace MapControl
}
///
- /// Calls GetFeatureInfoRequestUri() and asynchronously loads an XElement from the returned URL.
+ /// Loads an XElement from the URL returned by GetFeatureInfoRequestUri().
///
public async Task GetFeatureInfoAsync(Point position)
{
@@ -118,29 +148,7 @@ namespace MapControl
}
///
- /// Gets a list of all layer names returned by a GetCapabilities response.
- ///
- public async Task> GetLayerNamesAsync()
- {
- IEnumerable layerNames = null;
-
- var capabilities = await GetCapabilitiesAsync();
-
- if (capabilities != null)
- {
- var ns = capabilities.Name.Namespace;
-
- layerNames = capabilities
- .Descendants(ns + "Layer")
- .Select(e => e.Element(ns + "Name")?.Value)
- .Where(n => !string.IsNullOrEmpty(n));
- }
-
- return layerNames;
- }
-
- ///
- /// Calls GetMapRequestUri() and asynchronously loads an ImageSource from the returned URL.
+ /// Loads an ImageSource from the URL returned by GetMapRequestUri().
///
protected override async Task GetImageAsync()
{
@@ -200,12 +208,13 @@ namespace MapControl
uri += "&FORMAT=image/png";
}
- var rect = projection.BoundingBoxToRect(BoundingBox);
+ var mapRect = projection.BoundingBoxToRect(BoundingBox);
+ var viewScale = ParentMap.ViewTransform.Scale;
uri += "&CRS=" + projection.GetCrsValue();
- uri += "&BBOX=" + projection.GetBboxValue(rect);
- uri += "&WIDTH=" + (int)Math.Round(ParentMap.ViewTransform.Scale * rect.Width);
- uri += "&HEIGHT=" + (int)Math.Round(ParentMap.ViewTransform.Scale * rect.Height);
+ uri += "&BBOX=" + projection.GetBboxValue(mapRect);
+ uri += "&WIDTH=" + (int)Math.Round(viewScale * mapRect.Width);
+ uri += "&HEIGHT=" + (int)Math.Round(viewScale * mapRect.Height);
}
return uri.Replace(" ", "%20");
@@ -238,14 +247,20 @@ namespace MapControl
uri += "&QUERY_LAYERS=" + Layers;
}
- var rect = projection.BoundingBoxToRect(BoundingBox);
- var image = Children[1]; // top Image element
- var imagePos = ParentMap.TransformToVisual(image).Transform(position);
+ var mapRect = projection.BoundingBoxToRect(BoundingBox);
+ var viewRect = GetViewRectangle(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 += "&CRS=" + projection.GetCrsValue();
- uri += "&BBOX=" + projection.GetBboxValue(rect);
- uri += "&WIDTH=" + (int)Math.Round(ParentMap.ViewTransform.Scale * rect.Width);
- uri += "&HEIGHT=" + (int)Math.Round(ParentMap.ViewTransform.Scale * rect.Height);
+ uri += "&BBOX=" + projection.GetBboxValue(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=text/xml";