mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2026-02-16 04:35:08 +01:00
Added MapBase.MapBounds and MapBase.GeoBounds
This commit is contained in:
parent
4db96b9e83
commit
263deb5fd6
|
|
@ -14,11 +14,10 @@ namespace MapControl
|
|||
Scale = scale;
|
||||
Rotation = ((rotation % 360d) + 360d) % 360d;
|
||||
|
||||
MapToViewMatrix
|
||||
= Matrix.CreateTranslation(-mapCenter.X, -mapCenter.Y)
|
||||
* Matrix.CreateScale(scale, -scale)
|
||||
* Matrix.CreateRotation(Matrix.ToRadians(Rotation))
|
||||
* Matrix.CreateTranslation(viewCenter.X, viewCenter.Y);
|
||||
MapToViewMatrix = Matrix.CreateTranslation(-mapCenter.X, -mapCenter.Y)
|
||||
* Matrix.CreateScale(scale, -scale)
|
||||
* Matrix.CreateRotation(Matrix.ToRadians(Rotation))
|
||||
* Matrix.CreateTranslation(viewCenter.X, viewCenter.Y);
|
||||
|
||||
ViewToMapMatrix = MapToViewMatrix.Invert();
|
||||
}
|
||||
|
|
@ -28,10 +27,8 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public Matrix GetMapTransform(Point relativeScale)
|
||||
{
|
||||
var scale = GetMapScale(relativeScale);
|
||||
|
||||
return Matrix.CreateScale(scale.X, scale.Y)
|
||||
* Matrix.CreateRotation(Matrix.ToRadians(Rotation));
|
||||
return Matrix.CreateScale(Scale * relativeScale.X, Scale * relativeScale.Y)
|
||||
* Matrix.CreateRotation(Matrix.ToRadians(Rotation));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -47,13 +44,13 @@ namespace MapControl
|
|||
|
||||
// Tile matrix origin in view coordinates.
|
||||
//
|
||||
var viewOrigin = MapToView(mapOrigin);
|
||||
var viewOrigin = MapToViewMatrix.Transform(mapOrigin);
|
||||
|
||||
var transformScale = Scale / tileMatrixScale;
|
||||
|
||||
return Matrix.CreateScale(transformScale, transformScale)
|
||||
* Matrix.CreateRotation(Matrix.ToRadians(Rotation))
|
||||
* Matrix.CreateTranslation(viewOrigin.X, viewOrigin.Y);
|
||||
* Matrix.CreateRotation(Matrix.ToRadians(Rotation))
|
||||
* Matrix.CreateTranslation(viewOrigin.X, viewOrigin.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -63,13 +60,12 @@ namespace MapControl
|
|||
{
|
||||
// View origin in map coordinates.
|
||||
//
|
||||
var origin = ViewToMap(new Point());
|
||||
var origin = ViewToMapMatrix.Transform(new Point());
|
||||
|
||||
var transformScale = tileMatrixScale / Scale;
|
||||
|
||||
var transform
|
||||
= Matrix.CreateScale(transformScale, transformScale)
|
||||
* Matrix.CreateRotation(Matrix.ToRadians(-Rotation));
|
||||
var transform = Matrix.CreateScale(transformScale, transformScale)
|
||||
* Matrix.CreateRotation(Matrix.ToRadians(-Rotation));
|
||||
|
||||
// Translate origin to tile matrix origin in pixels.
|
||||
//
|
||||
|
|
@ -88,8 +84,8 @@ namespace MapControl
|
|||
double translation2X, double translation2Y)
|
||||
{
|
||||
return Matrix.CreateTranslation(translation1X, translation1Y)
|
||||
* Matrix.CreateRotation(Matrix.ToRadians(rotation))
|
||||
* Matrix.CreateTranslation(translation2X, translation2Y);
|
||||
* Matrix.CreateRotation(Matrix.ToRadians(rotation))
|
||||
* Matrix.CreateTranslation(translation2X, translation2Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ namespace MapControl
|
|||
|
||||
private Location transformCenter;
|
||||
private Point viewCenter;
|
||||
private Rect? mapBounds;
|
||||
private BoundingBox geoBounds;
|
||||
private double centerLongitude;
|
||||
private double maxLatitude = 85.05112878; // default WebMercatorProjection
|
||||
private bool internalPropertyChange;
|
||||
|
|
@ -170,6 +172,27 @@ namespace MapControl
|
|||
set => SetValue(TargetHeadingProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the map viewport bounds in projected map coordinates.
|
||||
/// </summary>
|
||||
public Rect MapBounds
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!mapBounds.HasValue)
|
||||
{
|
||||
mapBounds = ViewRectToMap(0d, 0d, ActualWidth, ActualHeight);
|
||||
}
|
||||
|
||||
return mapBounds.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the map viewport bounds in geographic coordinates.
|
||||
/// </summary>
|
||||
public BoundingBox GeoBounds => geoBounds ??= MapProjection.MapToBoundingBox(MapBounds);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ViewTransform instance that is used to transform between projected
|
||||
/// map coordinates and view coordinates.
|
||||
|
|
@ -180,18 +203,22 @@ namespace MapControl
|
|||
/// Gets the map scale as horizontal and vertical scaling factors from meters to
|
||||
/// view coordinates at the specified geographic coordinates.
|
||||
/// </summary>
|
||||
public Point GetScale(double latitude, double longitude)
|
||||
public Point GetMapScale(double latitude, double longitude)
|
||||
{
|
||||
return ViewTransform.GetMapScale(MapProjection.GetRelativeScale(latitude, longitude));
|
||||
var relativeScale = MapProjection.GetRelativeScale(latitude, longitude);
|
||||
|
||||
return new Point(ViewTransform.Scale * relativeScale.X, ViewTransform.Scale * relativeScale.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the map scale as horizontal and vertical scaling factors from meters to
|
||||
/// view coordinates at the specified location.
|
||||
/// </summary>
|
||||
public Point GetScale(Location location)
|
||||
public Point GetMapScale(Location location)
|
||||
{
|
||||
return ViewTransform.GetMapScale(MapProjection.GetRelativeScale(location));
|
||||
var relativeScale = MapProjection.GetRelativeScale(location);
|
||||
|
||||
return new Point(ViewTransform.Scale * relativeScale.X, ViewTransform.Scale * relativeScale.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -212,7 +239,7 @@ namespace MapControl
|
|||
|
||||
if (point.HasValue)
|
||||
{
|
||||
point = ViewTransform.MapToView(point.Value);
|
||||
point = ViewTransform.MapToViewMatrix.Transform(point.Value);
|
||||
}
|
||||
|
||||
return point;
|
||||
|
|
@ -231,25 +258,35 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public Location ViewToLocation(Point point)
|
||||
{
|
||||
return MapProjection.MapToLocation(ViewTransform.ViewToMap(point));
|
||||
return MapProjection.MapToLocation(ViewTransform.ViewToMapMatrix.Transform(point));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a BoundingBox in geographic coordinates that covers a Rect in view coordinates.
|
||||
/// Gets a Rect in projected map coordinates that covers a rectangle in view coordinates.
|
||||
/// </summary>
|
||||
public BoundingBox ViewRectToBoundingBox(Rect rect)
|
||||
public Rect ViewRectToMap(double x, double y, double width, double height)
|
||||
{
|
||||
var p1 = ViewTransform.ViewToMap(new Point(rect.X, rect.Y));
|
||||
var p2 = ViewTransform.ViewToMap(new Point(rect.X, rect.Y + rect.Height));
|
||||
var p3 = ViewTransform.ViewToMap(new Point(rect.X + rect.Width, rect.Y));
|
||||
var p4 = ViewTransform.ViewToMap(new Point(rect.X + rect.Width, rect.Y + rect.Height));
|
||||
var viewToMap = ParentMap.ViewTransform.ViewToMapMatrix;
|
||||
|
||||
var p1 = viewToMap.Transform(new Point(x, y));
|
||||
var p2 = viewToMap.Transform(new Point(x, y + height));
|
||||
var p3 = viewToMap.Transform(new Point(x + width, y));
|
||||
var p4 = viewToMap.Transform(new Point(x + width, y + height));
|
||||
|
||||
var x1 = Math.Min(p1.X, Math.Min(p2.X, Math.Min(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.MapToBoundingBox(new Rect(x1, y1, x2 - x1, y2 - y1));
|
||||
return new Rect(x1, y1, x2 - x1, y2 - y1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a BoundingBox in geographic coordinates that covers a rectangle in view coordinates.
|
||||
/// </summary>
|
||||
public BoundingBox ViewRectToBoundingBox(double x, double y, double width, double height)
|
||||
{
|
||||
return MapProjection.MapToBoundingBox(ViewRectToMap(x, y, width, height));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -354,9 +391,9 @@ namespace MapControl
|
|||
/// Sets the TargetZoomLevel and TargetCenter properties so that the specified BoundingBox
|
||||
/// fits into the current view. The TargetHeading property is set to zero.
|
||||
/// </summary>
|
||||
public void ZoomToBounds(BoundingBox boundingBox)
|
||||
public void ZoomToBounds(BoundingBox bounds)
|
||||
{
|
||||
var mapRect = MapProjection.BoundingBoxToMap(boundingBox);
|
||||
var mapRect = MapProjection.BoundingBoxToMap(bounds);
|
||||
|
||||
if (mapRect.HasValue)
|
||||
{
|
||||
|
|
@ -486,16 +523,16 @@ namespace MapControl
|
|||
|
||||
if (center != null)
|
||||
{
|
||||
var centerLatitude = center.Latitude;
|
||||
var centerLongitude = Location.NormalizeLongitude(center.Longitude);
|
||||
var centerLat = center.Latitude;
|
||||
var centerLon = Location.NormalizeLongitude(center.Longitude);
|
||||
|
||||
if (centerLatitude < -maxLatitude || centerLatitude > maxLatitude)
|
||||
if (centerLat < -maxLatitude || centerLat > maxLatitude)
|
||||
{
|
||||
centerLatitude = Math.Min(Math.Max(centerLatitude, -maxLatitude), maxLatitude);
|
||||
centerLat = Math.Min(Math.Max(centerLat, -maxLatitude), maxLatitude);
|
||||
resetTransformCenter = true;
|
||||
}
|
||||
|
||||
center = new Location(centerLatitude, centerLongitude);
|
||||
center = new Location(centerLat, centerLon);
|
||||
|
||||
SetValueInternal(CenterProperty, center);
|
||||
|
||||
|
|
@ -539,6 +576,9 @@ namespace MapControl
|
|||
{
|
||||
base.OnViewportChanged(e);
|
||||
|
||||
mapBounds = null;
|
||||
geoBounds = null;
|
||||
|
||||
ViewportChanged?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ namespace MapControl
|
|||
|
||||
private double PixelPerLongitudeDegree(double latitude, double longitude)
|
||||
{
|
||||
var scale = ParentMap.GetScale(latitude, longitude);
|
||||
var scale = ParentMap.GetMapScale(latitude, longitude);
|
||||
|
||||
return Math.Max(1d, // a reasonable lower limit
|
||||
scale.X * Math.Cos(latitude * Math.PI / 180d) * MapProjection.Wgs84MeterPerDegree);
|
||||
|
|
@ -171,14 +171,14 @@ namespace MapControl
|
|||
|
||||
private void DrawCylindricalGraticule(PathFigureCollection figures, List<Label> labels)
|
||||
{
|
||||
var boundingBox = ParentMap.ViewRectToBoundingBox(new Rect(0d, 0d, ParentMap.ActualWidth, ParentMap.ActualHeight));
|
||||
var latLabelStart = Math.Ceiling(boundingBox.South / lineDistance) * lineDistance;
|
||||
var lonLabelStart = Math.Ceiling(boundingBox.West / lineDistance) * lineDistance;
|
||||
var bounds = ParentMap.GeoBounds;
|
||||
var latLabelStart = Math.Ceiling(bounds.South / lineDistance) * lineDistance;
|
||||
var lonLabelStart = Math.Ceiling(bounds.West / lineDistance) * lineDistance;
|
||||
|
||||
for (var lat = latLabelStart; lat <= boundingBox.North; lat += lineDistance)
|
||||
for (var lat = latLabelStart; lat <= bounds.North; lat += lineDistance)
|
||||
{
|
||||
var p1 = ParentMap.LocationToView(lat, boundingBox.West);
|
||||
var p2 = ParentMap.LocationToView(lat, boundingBox.East);
|
||||
var p1 = ParentMap.LocationToView(lat, bounds.West);
|
||||
var p2 = ParentMap.LocationToView(lat, bounds.East);
|
||||
|
||||
if (p1.HasValue && p2.HasValue)
|
||||
{
|
||||
|
|
@ -186,17 +186,17 @@ namespace MapControl
|
|||
}
|
||||
}
|
||||
|
||||
for (var lon = lonLabelStart; lon <= boundingBox.East; lon += lineDistance)
|
||||
for (var lon = lonLabelStart; lon <= bounds.East; lon += lineDistance)
|
||||
{
|
||||
var p1 = ParentMap.LocationToView(boundingBox.South, lon);
|
||||
var p2 = ParentMap.LocationToView(boundingBox.North, lon);
|
||||
var p1 = ParentMap.LocationToView(bounds.South, lon);
|
||||
var p2 = ParentMap.LocationToView(bounds.North, lon);
|
||||
|
||||
if (p1.HasValue && p2.HasValue)
|
||||
{
|
||||
figures.Add(CreateLineFigure(p1.Value, p2.Value));
|
||||
}
|
||||
|
||||
for (var lat = latLabelStart; lat <= boundingBox.North; lat += lineDistance)
|
||||
for (var lat = latLabelStart; lat <= bounds.North; lat += lineDistance)
|
||||
{
|
||||
var position = ParentMap.LocationToView(lat, lon);
|
||||
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ namespace MapControl
|
|||
var x = (ParentMap.ActualWidth - width) / 2d;
|
||||
var y = (ParentMap.ActualHeight - height) / 2d;
|
||||
|
||||
boundingBox = ParentMap.ViewRectToBoundingBox(new Rect(x, y, width, height));
|
||||
boundingBox = ParentMap.ViewRectToBoundingBox(x, y, width, height);
|
||||
image = await GetImageAsync(boundingBox, loadingProgress);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ namespace MapControl
|
|||
private Rect GetViewRect(Rect mapRect)
|
||||
{
|
||||
var center = new Point(mapRect.X + mapRect.Width / 2d, mapRect.Y + mapRect.Height / 2d);
|
||||
var position = parentMap.ViewTransform.MapToView(center);
|
||||
var position = parentMap.ViewTransform.MapToViewMatrix.Transform(center);
|
||||
|
||||
if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical &&
|
||||
!parentMap.InsideViewBounds(position))
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ namespace MapControl
|
|||
|
||||
if (point.HasValue)
|
||||
{
|
||||
point = parentMap.ViewTransform.MapToView(point.Value);
|
||||
point = parentMap.ViewTransform.MapToViewMatrix.Transform(point.Value);
|
||||
}
|
||||
|
||||
return point;
|
||||
|
|
|
|||
|
|
@ -94,16 +94,10 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public virtual Rect? BoundingBoxToMap(BoundingBox boundingBox)
|
||||
{
|
||||
Rect? rect = null;
|
||||
var southWest = LocationToMap(boundingBox.South, boundingBox.West);
|
||||
var northEast = LocationToMap(boundingBox.North, boundingBox.East);
|
||||
|
||||
if (southWest.HasValue && northEast.HasValue)
|
||||
{
|
||||
rect = new Rect(southWest.Value, northEast.Value);
|
||||
}
|
||||
|
||||
return rect;
|
||||
return southWest.HasValue && northEast.HasValue ? new Rect(southWest.Value, northEast.Value) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -112,16 +106,10 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public virtual BoundingBox MapToBoundingBox(Rect rect)
|
||||
{
|
||||
BoundingBox boundingBox = null;
|
||||
var southWest = MapToLocation(rect.X, rect.Y);
|
||||
var northEast = MapToLocation(rect.X + rect.Width, rect.Y + rect.Height);
|
||||
|
||||
if (southWest != null && northEast != null)
|
||||
{
|
||||
boundingBox = new BoundingBox(southWest, northEast);
|
||||
}
|
||||
|
||||
return boundingBox;
|
||||
return southWest != null && northEast != null ? new BoundingBox(southWest, northEast) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ namespace MapControl
|
|||
{
|
||||
double scale;
|
||||
|
||||
if (ParentMap == null || (scale = ParentMap.GetScale(ParentMap.Center).X) <= 0d)
|
||||
if (ParentMap == null || (scale = ParentMap.GetMapScale(ParentMap.Center).X) <= 0d)
|
||||
{
|
||||
return new Size();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,31 +38,6 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public Matrix ViewToMapMatrix { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a Point from projected map coordinates to view coordinates.
|
||||
/// </summary>
|
||||
public Point MapToView(Point point)
|
||||
{
|
||||
return MapToViewMatrix.Transform(point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a Point from view coordinates to projected map coordinates.
|
||||
/// </summary>
|
||||
public Point ViewToMap(Point point)
|
||||
{
|
||||
return ViewToMapMatrix.Transform(point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transform relative to absolute map scale. Returns horizontal and vertical
|
||||
/// scaling factors from meters to view coordinates.
|
||||
/// </summary>
|
||||
public Point GetMapScale(Point relativeScale)
|
||||
{
|
||||
return new Point(Scale * relativeScale.X, Scale * relativeScale.Y);
|
||||
}
|
||||
|
||||
#if WPF || UWP || WINUI
|
||||
/// <summary>
|
||||
/// Initializes a ViewTransform from a map center point in projected coordinates,
|
||||
|
|
@ -90,9 +65,7 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public Matrix GetMapTransform(Point relativeScale)
|
||||
{
|
||||
var scale = GetMapScale(relativeScale);
|
||||
|
||||
var transform = new Matrix(scale.X, 0d, 0d, scale.Y, 0d, 0d);
|
||||
var transform = new Matrix(Scale * relativeScale.X, 0d, 0d, Scale * relativeScale.Y, 0d, 0d);
|
||||
transform.Rotate(Rotation);
|
||||
|
||||
return transform;
|
||||
|
|
@ -111,7 +84,7 @@ namespace MapControl
|
|||
|
||||
// Tile matrix origin in view coordinates.
|
||||
//
|
||||
var viewOrigin = MapToView(mapOrigin);
|
||||
var viewOrigin = MapToViewMatrix.Transform(mapOrigin);
|
||||
|
||||
var transformScale = Scale / tileMatrixScale;
|
||||
|
||||
|
|
@ -129,7 +102,7 @@ namespace MapControl
|
|||
{
|
||||
// View origin in map coordinates.
|
||||
//
|
||||
var origin = ViewToMap(new Point());
|
||||
var origin = ViewToMapMatrix.Transform(new Point());
|
||||
|
||||
var transformScale = tileMatrixScale / Scale;
|
||||
|
||||
|
|
|
|||
|
|
@ -170,9 +170,7 @@ namespace MapControl
|
|||
ParentMap.ActualWidth > 0d &&
|
||||
ParentMap.ActualHeight > 0d)
|
||||
{
|
||||
var boundingBox = ParentMap.ViewRectToBoundingBox(new Rect(0d, 0d, ParentMap.ActualWidth, ParentMap.ActualHeight));
|
||||
|
||||
var uri = GetFeatureInfoRequestUri(boundingBox, position, format);
|
||||
var uri = GetFeatureInfoRequestUri(ParentMap.GeoBounds, position, format);
|
||||
|
||||
if (uri != null)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue