mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Improve MapRect
This commit is contained in:
parent
07a8e454d5
commit
8bb2555533
|
|
@ -30,21 +30,23 @@ namespace MapControl
|
||||||
|
|
||||||
var width = boundingBox.Width * Wgs84MeterPerDegree;
|
var width = boundingBox.Width * Wgs84MeterPerDegree;
|
||||||
var height = boundingBox.Height * 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)
|
if (center == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var width = rect.Width / Wgs84MeterPerDegree;
|
var width = mapRect.Width / Wgs84MeterPerDegree;
|
||||||
var height = rect.Height / Wgs84MeterPerDegree;
|
var height = mapRect.Height / Wgs84MeterPerDegree;
|
||||||
|
|
||||||
return new CenteredBoundingBox(center, width, height);
|
return new CenteredBoundingBox(center, width, height);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,23 +15,32 @@ namespace MapControl
|
||||||
#endif
|
#endif
|
||||||
public class BoundingBox
|
public class BoundingBox
|
||||||
{
|
{
|
||||||
private double south = double.NaN;
|
private double south;
|
||||||
private double north = double.NaN;
|
private double north;
|
||||||
|
|
||||||
public BoundingBox()
|
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;
|
South = Math.Min(latitude1, latitude2);
|
||||||
West = west;
|
North = Math.Max(latitude1, latitude2);
|
||||||
North = north;
|
West = Math.Min(longitude1, longitude2);
|
||||||
East = east;
|
East = Math.Max(longitude1, longitude2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double West { get; set; } = double.NaN;
|
public BoundingBox(Location location1, Location location2)
|
||||||
public double East { get; set; } = double.NaN;
|
: this(location1.Latitude, location1.Longitude, location2.Latitude, location2.Longitude)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public double West { get; set; }
|
||||||
|
public double East { get; set; }
|
||||||
|
|
||||||
public double South
|
public double South
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,14 @@ namespace MapControl
|
||||||
point.X / Wgs84MeterPerDegree);
|
point.X / Wgs84MeterPerDegree);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetBboxValue(MapRect rect)
|
public override string GetBboxValue(MapRect mapRect)
|
||||||
{
|
{
|
||||||
return string.Format(CultureInfo.InvariantCulture,
|
return string.Format(CultureInfo.InvariantCulture,
|
||||||
CrsId == "CRS:84" ? "{0},{1},{2},{3}" : "{1},{0},{3},{2}",
|
CrsId == "CRS:84" ? "{0},{1},{2},{3}" : "{1},{0},{3},{2}",
|
||||||
rect.X / Wgs84MeterPerDegree, rect.Y / Wgs84MeterPerDegree,
|
mapRect.XMin / Wgs84MeterPerDegree,
|
||||||
(rect.X + rect.Width) / Wgs84MeterPerDegree, (rect.Y + rect.Height) / Wgs84MeterPerDegree);
|
mapRect.YMin / Wgs84MeterPerDegree,
|
||||||
|
mapRect.XMax / Wgs84MeterPerDegree,
|
||||||
|
mapRect.YMax / Wgs84MeterPerDegree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,11 +100,10 @@ namespace MapControl
|
||||||
transform.M21 = 0;
|
transform.M21 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rect = new MapRect(
|
var p1 = transform.Transform(new Point());
|
||||||
transform.Transform(new Point()),
|
var p2 = transform.Transform(new Point(bitmap.PixelWidth, bitmap.PixelHeight));
|
||||||
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;
|
Content = image;
|
||||||
|
|
|
||||||
|
|
@ -270,11 +270,11 @@ namespace MapControl
|
||||||
var p4 = ViewTransform.ViewToMap(new Point(rect.X + rect.Width, rect.Y + rect.Height));
|
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 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 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)));
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -380,13 +380,12 @@ namespace MapControl
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ZoomToBounds(BoundingBox boundingBox)
|
public void ZoomToBounds(BoundingBox boundingBox)
|
||||||
{
|
{
|
||||||
var rect = MapProjection.BoundingBoxToMapRect(boundingBox);
|
var mapRect = MapProjection.BoundingBoxToMapRect(boundingBox);
|
||||||
var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d);
|
var targetCenter = MapProjection.MapToLocation(mapRect.Center);
|
||||||
var targetCenter = MapProjection.MapToLocation(center);
|
|
||||||
|
|
||||||
if (targetCenter != null)
|
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);
|
TargetZoomLevel = ViewTransform.ScaleToZoomLevel(scale);
|
||||||
TargetCenter = targetCenter;
|
TargetCenter = targetCenter;
|
||||||
|
|
|
||||||
|
|
@ -223,15 +223,14 @@ namespace MapControl
|
||||||
return GetViewRect(parentMap.MapProjection.BoundingBoxToMapRect(boundingBox));
|
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(mapRect.Center);
|
||||||
var position = parentMap.ViewTransform.MapToView(center);
|
|
||||||
|
|
||||||
if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical &&
|
if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical &&
|
||||||
IsOutsideViewport(position))
|
IsOutsideViewport(position))
|
||||||
{
|
{
|
||||||
var location = parentMap.MapProjection.MapToLocation(center);
|
var location = parentMap.MapProjection.MapToLocation(mapRect.Center);
|
||||||
|
|
||||||
if (location != null)
|
if (location != null)
|
||||||
{
|
{
|
||||||
|
|
@ -245,8 +244,8 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var width = rect.Width * parentMap.ViewTransform.Scale;
|
var width = mapRect.Width * parentMap.ViewTransform.Scale;
|
||||||
var height = rect.Height * parentMap.ViewTransform.Scale;
|
var height = mapRect.Height * parentMap.ViewTransform.Scale;
|
||||||
var x = position.X - width / 2d;
|
var x = position.X - width / 2d;
|
||||||
var y = position.Y - height / 2d;
|
var y = position.Y - height / 2d;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,14 +82,12 @@ namespace MapControl
|
||||||
/// Transforms a MapRect in projected map coordinates to a BoundingBox in geographic coordinates.
|
/// Transforms a MapRect in projected map coordinates to a BoundingBox in geographic coordinates.
|
||||||
/// Returns null when the MapRect can not be transformed.
|
/// Returns null when the MapRect can not be transformed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual BoundingBox MapRectToBoundingBox(MapRect rect)
|
public virtual BoundingBox MapRectToBoundingBox(MapRect mapRect)
|
||||||
{
|
{
|
||||||
var sw = MapToLocation(new Point(rect.X, rect.Y));
|
var sw = MapToLocation(new Point(mapRect.XMin, mapRect.YMin));
|
||||||
var ne = MapToLocation(new Point(rect.X + rect.Width, rect.Y + rect.Height));
|
var ne = MapToLocation(new Point(mapRect.XMax, mapRect.YMax));
|
||||||
|
|
||||||
return sw != null && ne != null
|
return sw != null && ne != null ? new BoundingBox(sw, ne) : null;
|
||||||
? new BoundingBox(sw.Latitude, sw.Longitude, ne.Latitude, ne.Longitude)
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -105,10 +103,17 @@ namespace MapControl
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the BBOX parameter value for a WMS GetMap request.
|
/// Gets the BBOX parameter value for a WMS GetMap request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual string GetBboxValue(MapRect rect)
|
public virtual string GetBboxValue(MapRect mapRect)
|
||||||
{
|
{
|
||||||
return string.Format(CultureInfo.InvariantCulture,
|
// Truncate bounding box to 1 cm precision.
|
||||||
"{0},{1},{2},{3}", rect.X, rect.Y, (rect.X + rect.Width), (rect.Y + rect.Height));
|
//
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,31 +15,29 @@ namespace MapControl
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MapRect
|
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;
|
XMin = Math.Min(x1, x2);
|
||||||
Y = y;
|
YMin = Math.Min(y1, y2);
|
||||||
Width = width;
|
XMax = Math.Max(x1, x2);
|
||||||
Height = height;
|
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 XMin { get; }
|
||||||
public double Y { get; }
|
public double YMin { get; }
|
||||||
public double Width { get; }
|
public double XMax { get; }
|
||||||
public double Height { get; }
|
public double YMax { get; }
|
||||||
|
|
||||||
public bool Contains(Point p)
|
public double Width => XMax - XMin;
|
||||||
{
|
public double Height => YMax - YMin;
|
||||||
return p.X >= X && p.X <= X + Width
|
|
||||||
&& p.Y >= Y && p.Y <= Y + Height;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ namespace MapControl
|
||||||
for (int i = 0; i < points.Count; i++)
|
for (int i = 0; i < points.Count; i++)
|
||||||
{
|
{
|
||||||
points[i] = new Point(
|
points[i] = new Point(
|
||||||
scale * (points[i].X - mapRect.X),
|
scale * (points[i].X - mapRect.XMin),
|
||||||
scale * (mapRect.Height + mapRect.Y - points[i].Y));
|
scale * (mapRect.YMax - points[i].Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
drawings.Children.Add(item.GetDrawing(points, scale, rotation));
|
drawings.Children.Add(item.GetDrawing(points, scale, rotation));
|
||||||
|
|
|
||||||
|
|
@ -150,8 +150,10 @@ namespace MapControl.Projections
|
||||||
public override string GetBboxValue(MapRect rect)
|
public override string GetBboxValue(MapRect rect)
|
||||||
{
|
{
|
||||||
return string.Format(CultureInfo.InvariantCulture, bboxFormat,
|
return string.Format(CultureInfo.InvariantCulture, bboxFormat,
|
||||||
rect.X / scaleFactor, rect.Y / scaleFactor,
|
rect.XMin / scaleFactor,
|
||||||
(rect.X + rect.Width) / scaleFactor, (rect.Y + rect.Height) / scaleFactor);
|
rect.YMin / scaleFactor,
|
||||||
|
rect.XMax / scaleFactor,
|
||||||
|
rect.YMax / scaleFactor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue