diff --git a/MapControl/Shared/AzimuthalProjection.cs b/MapControl/Shared/AzimuthalProjection.cs
index 986dd1dd..e5cfcb5f 100644
--- a/MapControl/Shared/AzimuthalProjection.cs
+++ b/MapControl/Shared/AzimuthalProjection.cs
@@ -30,21 +30,23 @@ namespace MapControl
var width = boundingBox.Width * Wgs84MeterPerDegree;
var height = boundingBox.Height * Wgs84MeterPerDegree;
+ var x = center.Value.X - width / 2d;
+ var y = center.Value.Y - height / 2d;
- return new MapRect(center.Value.X - width / 2d, center.Value.Y - height / 2d, width, height);
+ return new MapRect(x, y, x + width, y + height);
}
- public override BoundingBox MapRectToBoundingBox(MapRect rect)
+ public override BoundingBox MapRectToBoundingBox(MapRect mapRect)
{
- var center = MapToLocation(new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d));
+ var center = MapToLocation(mapRect.Center);
if (center == null)
{
return null;
}
- var width = rect.Width / Wgs84MeterPerDegree;
- var height = rect.Height / Wgs84MeterPerDegree;
+ var width = mapRect.Width / Wgs84MeterPerDegree;
+ var height = mapRect.Height / Wgs84MeterPerDegree;
return new CenteredBoundingBox(center, width, height);
}
diff --git a/MapControl/Shared/BoundingBox.cs b/MapControl/Shared/BoundingBox.cs
index 47d5b190..73325094 100644
--- a/MapControl/Shared/BoundingBox.cs
+++ b/MapControl/Shared/BoundingBox.cs
@@ -15,23 +15,32 @@ namespace MapControl
#endif
public class BoundingBox
{
- private double south = double.NaN;
- private double north = double.NaN;
+ private double south;
+ private double north;
public BoundingBox()
{
+ south = double.NaN;
+ north = double.NaN;
+ West = double.NaN;
+ East = double.NaN;
}
- public BoundingBox(double south, double west, double north, double east)
+ public BoundingBox(double latitude1, double longitude1, double latitude2, double longitude2)
{
- South = south;
- West = west;
- North = north;
- East = east;
+ South = Math.Min(latitude1, latitude2);
+ North = Math.Max(latitude1, latitude2);
+ West = Math.Min(longitude1, longitude2);
+ East = Math.Max(longitude1, longitude2);
}
- public double West { get; set; } = double.NaN;
- public double East { get; set; } = double.NaN;
+ public BoundingBox(Location location1, Location location2)
+ : this(location1.Latitude, location1.Longitude, location2.Latitude, location2.Longitude)
+ {
+ }
+
+ public double West { get; set; }
+ public double East { get; set; }
public double South
{
diff --git a/MapControl/Shared/EquirectangularProjection.cs b/MapControl/Shared/EquirectangularProjection.cs
index 0ad0ac15..2c4127bd 100644
--- a/MapControl/Shared/EquirectangularProjection.cs
+++ b/MapControl/Shared/EquirectangularProjection.cs
@@ -46,12 +46,14 @@ namespace MapControl
point.X / Wgs84MeterPerDegree);
}
- public override string GetBboxValue(MapRect rect)
+ public override string GetBboxValue(MapRect mapRect)
{
return string.Format(CultureInfo.InvariantCulture,
CrsId == "CRS:84" ? "{0},{1},{2},{3}" : "{1},{0},{3},{2}",
- rect.X / Wgs84MeterPerDegree, rect.Y / Wgs84MeterPerDegree,
- (rect.X + rect.Width) / Wgs84MeterPerDegree, (rect.Y + rect.Height) / Wgs84MeterPerDegree);
+ mapRect.XMin / Wgs84MeterPerDegree,
+ mapRect.YMin / Wgs84MeterPerDegree,
+ mapRect.XMax / Wgs84MeterPerDegree,
+ mapRect.YMax / Wgs84MeterPerDegree);
}
}
}
diff --git a/MapControl/Shared/GeoImage.cs b/MapControl/Shared/GeoImage.cs
index 58aa1d46..c544178f 100644
--- a/MapControl/Shared/GeoImage.cs
+++ b/MapControl/Shared/GeoImage.cs
@@ -100,11 +100,10 @@ namespace MapControl
transform.M21 = 0;
}
- var rect = new MapRect(
- transform.Transform(new Point()),
- transform.Transform(new Point(bitmap.PixelWidth, bitmap.PixelHeight)));
+ var p1 = transform.Transform(new Point());
+ var p2 = transform.Transform(new Point(bitmap.PixelWidth, bitmap.PixelHeight));
- boundingBox = new BoundingBox(rect.Y, rect.X, rect.Y + rect.Height, rect.X + rect.Width);
+ boundingBox = new BoundingBox(p1.Y, p1.X, p2.Y, p2.X); // Y=Latitude, X=Longitude
}
Content = image;
diff --git a/MapControl/Shared/MapBase.cs b/MapControl/Shared/MapBase.cs
index 032f9eea..5e53baaa 100644
--- a/MapControl/Shared/MapBase.cs
+++ b/MapControl/Shared/MapBase.cs
@@ -270,11 +270,11 @@ namespace MapControl
var p4 = ViewTransform.ViewToMap(new Point(rect.X + rect.Width, rect.Y + rect.Height));
var x1 = Math.Min(p1.X, Math.Min(p2.X, Math.Min(p3.X, p4.X)));
- var x2 = Math.Max(p1.X, Math.Max(p2.X, Math.Max(p3.X, p4.X)));
var y1 = Math.Min(p1.Y, Math.Min(p2.Y, Math.Min(p3.Y, p4.Y)));
+ var x2 = Math.Max(p1.X, Math.Max(p2.X, Math.Max(p3.X, p4.X)));
var y2 = Math.Max(p1.Y, Math.Max(p2.Y, Math.Max(p3.Y, p4.Y)));
- return MapProjection.MapRectToBoundingBox(new MapRect(x1, y1, x2 - x1, y2 - y1));
+ return MapProjection.MapRectToBoundingBox(new MapRect(x1, y1, x2, y2));
}
///
@@ -380,13 +380,12 @@ namespace MapControl
///
public void ZoomToBounds(BoundingBox boundingBox)
{
- var rect = MapProjection.BoundingBoxToMapRect(boundingBox);
- var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d);
- var targetCenter = MapProjection.MapToLocation(center);
+ var mapRect = MapProjection.BoundingBoxToMapRect(boundingBox);
+ var targetCenter = MapProjection.MapToLocation(mapRect.Center);
if (targetCenter != null)
{
- var scale = Math.Min(RenderSize.Width / rect.Width, RenderSize.Height / rect.Height);
+ var scale = Math.Min(RenderSize.Width / mapRect.Width, RenderSize.Height / mapRect.Height);
TargetZoomLevel = ViewTransform.ScaleToZoomLevel(scale);
TargetCenter = targetCenter;
diff --git a/MapControl/Shared/MapPanel.cs b/MapControl/Shared/MapPanel.cs
index e5972ecc..1e942e3b 100644
--- a/MapControl/Shared/MapPanel.cs
+++ b/MapControl/Shared/MapPanel.cs
@@ -223,15 +223,14 @@ namespace MapControl
return GetViewRect(parentMap.MapProjection.BoundingBoxToMapRect(boundingBox));
}
- protected ViewRect GetViewRect(MapRect rect)
+ protected ViewRect GetViewRect(MapRect mapRect)
{
- var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d);
- var position = parentMap.ViewTransform.MapToView(center);
+ var position = parentMap.ViewTransform.MapToView(mapRect.Center);
if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical &&
IsOutsideViewport(position))
{
- var location = parentMap.MapProjection.MapToLocation(center);
+ var location = parentMap.MapProjection.MapToLocation(mapRect.Center);
if (location != null)
{
@@ -245,8 +244,8 @@ namespace MapControl
}
}
- var width = rect.Width * parentMap.ViewTransform.Scale;
- var height = rect.Height * parentMap.ViewTransform.Scale;
+ var width = mapRect.Width * parentMap.ViewTransform.Scale;
+ var height = mapRect.Height * parentMap.ViewTransform.Scale;
var x = position.X - width / 2d;
var y = position.Y - height / 2d;
diff --git a/MapControl/Shared/MapProjection.cs b/MapControl/Shared/MapProjection.cs
index f3850eb9..0909bb08 100644
--- a/MapControl/Shared/MapProjection.cs
+++ b/MapControl/Shared/MapProjection.cs
@@ -82,14 +82,12 @@ namespace MapControl
/// Transforms a MapRect in projected map coordinates to a BoundingBox in geographic coordinates.
/// Returns null when the MapRect can not be transformed.
///
- public virtual BoundingBox MapRectToBoundingBox(MapRect rect)
+ public virtual BoundingBox MapRectToBoundingBox(MapRect mapRect)
{
- var sw = MapToLocation(new Point(rect.X, rect.Y));
- var ne = MapToLocation(new Point(rect.X + rect.Width, rect.Y + rect.Height));
+ var sw = MapToLocation(new Point(mapRect.XMin, mapRect.YMin));
+ var ne = MapToLocation(new Point(mapRect.XMax, mapRect.YMax));
- return sw != null && ne != null
- ? new BoundingBox(sw.Latitude, sw.Longitude, ne.Latitude, ne.Longitude)
- : null;
+ return sw != null && ne != null ? new BoundingBox(sw, ne) : null;
}
///
@@ -105,10 +103,17 @@ namespace MapControl
///
/// Gets the BBOX parameter value for a WMS GetMap request.
///
- public virtual string GetBboxValue(MapRect rect)
+ public virtual string GetBboxValue(MapRect mapRect)
{
- return string.Format(CultureInfo.InvariantCulture,
- "{0},{1},{2},{3}", rect.X, rect.Y, (rect.X + rect.Width), (rect.Y + rect.Height));
+ // Truncate bounding box to 1 cm precision.
+ //
+ const double p = 0.01;
+
+ return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}",
+ p * Math.Ceiling(mapRect.XMin / p),
+ p * Math.Ceiling(mapRect.YMin / p),
+ p * Math.Floor(mapRect.XMax / p),
+ p * Math.Floor(mapRect.YMax / p));
}
}
}
diff --git a/MapControl/Shared/MapRect.cs b/MapControl/Shared/MapRect.cs
index d91b03ee..5176388e 100644
--- a/MapControl/Shared/MapRect.cs
+++ b/MapControl/Shared/MapRect.cs
@@ -15,31 +15,29 @@ namespace MapControl
///
public class MapRect
{
- public MapRect(double x, double y, double width, double height)
+ public MapRect(double x1, double y1, double x2, double y2)
{
- X = x;
- Y = y;
- Width = width;
- Height = height;
+ XMin = Math.Min(x1, x2);
+ YMin = Math.Min(y1, y2);
+ XMax = Math.Max(x1, x2);
+ YMax = Math.Max(y1, y2);
}
- public MapRect(Point p1, Point p2)
+ public MapRect(Point point1, Point point2)
+ : this(point1.X, point1.Y, point2.X, point2.Y)
{
- X = Math.Min(p1.X, p2.X);
- Y = Math.Min(p1.Y, p2.Y);
- Width = Math.Max(p1.X, p2.X) - X;
- Height = Math.Max(p1.Y, p2.Y) - Y;
}
- public double X { get; }
- public double Y { get; }
- public double Width { get; }
- public double Height { get; }
+ public double XMin { get; }
+ public double YMin { get; }
+ public double XMax { get; }
+ public double YMax { get; }
- public bool Contains(Point p)
- {
- return p.X >= X && p.X <= X + Width
- && p.Y >= Y && p.Y <= Y + Height;
- }
+ public double Width => XMax - XMin;
+ public double Height => YMax - YMin;
+
+ public Point Center => new Point((XMin + XMax) / 2d, (YMin + YMax) / 2d);
+
+ public bool Contains(Point p) => p.X >= XMin && p.X <= XMax && p.Y >= YMin && p.Y <= YMax;
}
}
diff --git a/MapControl/WPF/MapItemsImageLayer.WPF.cs b/MapControl/WPF/MapItemsImageLayer.WPF.cs
index b0bba648..f0393372 100644
--- a/MapControl/WPF/MapItemsImageLayer.WPF.cs
+++ b/MapControl/WPF/MapItemsImageLayer.WPF.cs
@@ -63,8 +63,8 @@ namespace MapControl
for (int i = 0; i < points.Count; i++)
{
points[i] = new Point(
- scale * (points[i].X - mapRect.X),
- scale * (mapRect.Height + mapRect.Y - points[i].Y));
+ scale * (points[i].X - mapRect.XMin),
+ scale * (mapRect.YMax - points[i].Y));
}
drawings.Children.Add(item.GetDrawing(points, scale, rotation));
diff --git a/MapProjections/Shared/GeoApiProjection.cs b/MapProjections/Shared/GeoApiProjection.cs
index 22996be3..ac236d35 100644
--- a/MapProjections/Shared/GeoApiProjection.cs
+++ b/MapProjections/Shared/GeoApiProjection.cs
@@ -150,8 +150,10 @@ namespace MapControl.Projections
public override string GetBboxValue(MapRect rect)
{
return string.Format(CultureInfo.InvariantCulture, bboxFormat,
- rect.X / scaleFactor, rect.Y / scaleFactor,
- (rect.X + rect.Width) / scaleFactor, (rect.Y + rect.Height) / scaleFactor);
+ rect.XMin / scaleFactor,
+ rect.YMin / scaleFactor,
+ rect.XMax / scaleFactor,
+ rect.YMax / scaleFactor);
}
}
}