diff --git a/MapControl/Avalonia/MapControl.Avalonia.csproj b/MapControl/Avalonia/MapControl.Avalonia.csproj
index 3a5231b1..cc123a41 100644
--- a/MapControl/Avalonia/MapControl.Avalonia.csproj
+++ b/MapControl/Avalonia/MapControl.Avalonia.csproj
@@ -12,7 +12,6 @@
-
diff --git a/MapControl/Avalonia/ViewTransform.Avalonia.cs b/MapControl/Avalonia/ViewTransform.Avalonia.cs
index d49776d6..139002a2 100644
--- a/MapControl/Avalonia/ViewTransform.Avalonia.cs
+++ b/MapControl/Avalonia/ViewTransform.Avalonia.cs
@@ -2,47 +2,10 @@
// Copyright © 2024 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
-using System;
-
namespace MapControl
{
- ///
- /// Defines the transformation between projected map coordinates in meters
- /// and view coordinates in pixels.
- ///
- public class ViewTransform
+ public partial class ViewTransform
{
- public static double ZoomLevelToScale(double zoomLevel)
- {
- return 256d * Math.Pow(2d, zoomLevel) / (360d * MapProjection.Wgs84MeterPerDegree);
- }
-
- public static double ScaleToZoomLevel(double scale)
- {
- return Math.Log(scale * 360d * MapProjection.Wgs84MeterPerDegree / 256d, 2d);
- }
-
- ///
- /// Gets the scaling factor from projected map coordinates to view coordinates,
- /// as pixels per meter.
- ///
- public double Scale { get; private set; }
-
- ///
- /// Gets the rotation angle of the transform matrix.
- ///
- public double Rotation { get; private set; }
-
- ///
- /// Gets the transform matrix from projected map coordinates to view coordinates.
- ///
- public Matrix MapToViewMatrix { get; private set; }
-
- ///
- /// Gets the transform matrix from view coordinates to projected map coordinates.
- ///
- public Matrix ViewToMapMatrix { get; private set; }
-
///
/// Initializes a ViewTransform from a map center point in projected coordinates,
/// a view conter point, a scaling factor from projected coordinates to view coordinates
@@ -62,31 +25,6 @@ namespace MapControl
ViewToMapMatrix = MapToViewMatrix.Invert();
}
- ///
- /// Transforms a Point from projected map coordinates to view coordinates.
- ///
- public Point MapToView(Point point)
- {
- return MapToViewMatrix.Transform(point);
- }
-
- ///
- /// Transforms a Point from view coordinates to projected map coordinates.
- ///
- public Point ViewToMap(Point point)
- {
- return ViewToMapMatrix.Transform(point);
- }
-
- ///
- /// Transform relative to absolute map scale. Returns horizontal and vertical
- /// scaling factors from meters to view coordinates.
- ///
- public Point GetMapScale(Point relativeScale)
- {
- return new Point(Scale * relativeScale.X, Scale * relativeScale.Y);
- }
-
///
/// Gets a transform Matrix from meters to view coordinates for a relative map scale.
///
diff --git a/MapControl/Shared/BoundingBox.cs b/MapControl/Shared/BoundingBox.cs
index bbc2c0fe..c62836d1 100644
--- a/MapControl/Shared/BoundingBox.cs
+++ b/MapControl/Shared/BoundingBox.cs
@@ -17,7 +17,7 @@ namespace MapControl
#endif
public class BoundingBox
{
- public BoundingBox()
+ protected BoundingBox()
{
}
@@ -34,15 +34,27 @@ namespace MapControl
{
}
- public double South { get; }
- public double North { get; }
- public double West { get; }
- public double East { get; }
+ public double South { get; private set; }
+ public double North { get; private set; }
+ public double West { get; private set; }
+ public double East { get; private set; }
public virtual double Width => East - West;
public virtual double Height => North - South;
- public virtual Location Center => new Location((South + North) / 2d, (West + East) / 2d);
+ public virtual Location Center
+ {
+ get => new Location((South + North) / 2d, (West + East) / 2d);
+ set
+ {
+ var latOffset = value.Latitude - (South + North) / 2d;
+ var lonOffset = value.Longitude - (West + East) / 2d;
+ South += latOffset;
+ North += latOffset;
+ West += lonOffset;
+ East += lonOffset;
+ }
+ }
///
/// Creates a BoundingBox instance from a string containing a comma-separated sequence of four floating point numbers.
diff --git a/MapControl/Shared/CenteredBoundingBox.cs b/MapControl/Shared/CenteredBoundingBox.cs
index 33799812..b8c06761 100644
--- a/MapControl/Shared/CenteredBoundingBox.cs
+++ b/MapControl/Shared/CenteredBoundingBox.cs
@@ -8,19 +8,15 @@ namespace MapControl
{
public class CenteredBoundingBox : BoundingBox
{
- private readonly Location center;
- private readonly double width;
- private readonly double height;
-
- public CenteredBoundingBox(Location c, double w, double h)
+ public CenteredBoundingBox(Location center, double width, double height)
{
- center = c;
- width = Math.Max(w, 0d);
- height = Math.Max(h, 0d);
+ Center = center;
+ Width = Math.Max(width, 0d);
+ Height = Math.Max(height, 0d);
}
- public override Location Center => center;
- public override double Width => width;
- public override double Height => height;
+ public override Location Center { get; set; }
+ public override double Width { get; }
+ public override double Height { get; }
}
}
diff --git a/MapControl/Shared/MapBase.cs b/MapControl/Shared/MapBase.cs
index 10d7f488..b511766e 100644
--- a/MapControl/Shared/MapBase.cs
+++ b/MapControl/Shared/MapBase.cs
@@ -31,6 +31,10 @@ namespace MapControl
///
public partial class MapBase : MapPanel
{
+ public static double ZoomLevelToScale(double zoomLevel) => 256d * Math.Pow(2d, zoomLevel) / (360d * MapProjection.Wgs84MeterPerDegree);
+
+ public static double ScaleToZoomLevel(double scale) => Math.Log(scale * 360d * MapProjection.Wgs84MeterPerDegree / 256d, 2d);
+
public static TimeSpan ImageFadeDuration { get; set; } = TimeSpan.FromSeconds(0.1);
public static readonly DependencyProperty AnimationDurationProperty =
@@ -361,7 +365,7 @@ namespace MapControl
{
var scale = Math.Min(ActualWidth / rect.Value.Width, ActualHeight / rect.Value.Height);
- TargetZoomLevel = ViewTransform.ScaleToZoomLevel(scale);
+ TargetZoomLevel = ScaleToZoomLevel(scale);
TargetCenter = targetCenter;
TargetHeading = 0d;
}
@@ -497,7 +501,7 @@ namespace MapControl
private void UpdateTransform(bool resetTransformCenter = false, bool projectionChanged = false)
{
var transformCenterChanged = false;
- var viewScale = ViewTransform.ZoomLevelToScale(ZoomLevel);
+ var viewScale = ZoomLevelToScale(ZoomLevel);
var projection = MapProjection;
projection.Center = ProjectionCenter ?? Center;
diff --git a/MapControl/Shared/MapPanel.cs b/MapControl/Shared/MapPanel.cs
index b27a6543..92458317 100644
--- a/MapControl/Shared/MapPanel.cs
+++ b/MapControl/Shared/MapPanel.cs
@@ -189,66 +189,53 @@ namespace MapControl
protected Point? GetViewPosition(Location location)
{
- var position = parentMap.LocationToView(location);
-
- if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical &&
- position.HasValue &&
- !InsideViewport(position.Value))
+ if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical)
{
- position = parentMap.LocationToView(
- new Location(location.Latitude, parentMap.CoerceLongitude(location.Longitude)));
+ var longitude = parentMap.CoerceLongitude(location.Longitude);
+
+ if (longitude != location.Longitude)
+ {
+ location = new Location(location.Latitude, longitude);
+ }
}
- return position;
+ return parentMap.LocationToView(location);
}
protected ViewRect? GetViewRect(BoundingBox boundingBox)
{
- var mapRect = parentMap.MapProjection.BoundingBoxToMap(boundingBox);
-
- if (!mapRect.HasValue)
+ if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical)
{
- return null;
+ var center = boundingBox.Center;
+ var longitude = parentMap.CoerceLongitude(center.Longitude);
+
+ if (longitude != center.Longitude)
+ {
+ boundingBox.Center = new Location(center.Latitude, longitude);
+ }
}
- return GetViewRect(mapRect.Value);
+ var mapRect = parentMap.MapProjection.BoundingBoxToMap(boundingBox);
+
+ if (mapRect.HasValue)
+ {
+ return GetViewRect(mapRect.Value);
+ }
+
+ return null;
}
protected ViewRect GetViewRect(Rect mapRect)
{
+ var transform = parentMap.ViewTransform;
var center = new Point(mapRect.X + mapRect.Width / 2d, mapRect.Y + mapRect.Height / 2d);
- var position = parentMap.ViewTransform.MapToView(center);
- var projection = parentMap.MapProjection;
-
- if (projection.Type <= MapProjectionType.NormalCylindrical &&
- !InsideViewport(position))
- {
- var location = projection.MapToLocation(center);
-
- if (location != null)
- {
- var pos = parentMap.LocationToView(
- new Location(location.Latitude, parentMap.CoerceLongitude(location.Longitude)));
-
- if (pos.HasValue)
- {
- position = pos.Value;
- }
- }
- }
-
- var width = mapRect.Width * parentMap.ViewTransform.Scale;
- var height = mapRect.Height * parentMap.ViewTransform.Scale;
+ var position = transform.MapToView(center);
+ var width = mapRect.Width * transform.Scale;
+ var height = mapRect.Height * transform.Scale;
var x = position.X - width / 2d;
var y = position.Y - height / 2d;
- return new ViewRect(x, y, width, height, parentMap.ViewTransform.Rotation);
- }
-
- private bool InsideViewport(Point point)
- {
- return point.X >= 0d && point.X <= parentMap.ActualWidth
- && point.Y >= 0d && point.Y <= parentMap.ActualHeight;
+ return new ViewRect(x, y, width, height, transform.Rotation);
}
private void ArrangeChildElement(FrameworkElement element, Size panelSize)
@@ -263,7 +250,10 @@ namespace MapControl
if (GetAutoCollapse(element))
{
- SetVisible(element, position.HasValue && InsideViewport(position.Value));
+ SetVisible(element,
+ position.HasValue &&
+ position.Value.X >= 0d && position.Value.X <= parentMap.ActualWidth &&
+ position.Value.Y >= 0d && position.Value.Y <= parentMap.ActualHeight);
}
if (position.HasValue)
diff --git a/MapControl/Shared/MapPath.cs b/MapControl/Shared/MapPath.cs
index 2a92db89..b6d77f3b 100644
--- a/MapControl/Shared/MapPath.cs
+++ b/MapControl/Shared/MapPath.cs
@@ -4,13 +4,10 @@
#if WPF
using System.Windows;
-using System.Windows.Media;
#elif UWP
using Windows.UI.Xaml;
-using Windows.UI.Xaml.Media;
#elif WINUI
using Microsoft.UI.Xaml;
-using Microsoft.UI.Xaml.Media;
#endif
namespace MapControl
@@ -79,6 +76,18 @@ namespace MapControl
MapPanel.SetLocation(this, Location);
}
+ protected double GetLongitudeOffset(Location location)
+ {
+ var longitudeOffset = 0d;
+
+ if (location != null && parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical)
+ {
+ longitudeOffset = parentMap.CoerceLongitude(location.Longitude) - location.Longitude;
+ }
+
+ return longitudeOffset;
+ }
+
protected Point? LocationToMap(Location location, double longitudeOffset)
{
if (longitudeOffset != 0d)
@@ -107,31 +116,12 @@ namespace MapControl
{
var point = LocationToMap(location, longitudeOffset);
- if (!point.HasValue)
+ if (point.HasValue)
{
- return null;
+ point = parentMap.ViewTransform.MapToView(point.Value);
}
- return parentMap.ViewTransform.MapToView(point.Value);
- }
-
- protected double GetLongitudeOffset(Location location)
- {
- var longitudeOffset = 0d;
-
- if (location != null && parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical)
- {
- var point = parentMap.LocationToView(location);
-
- if (point.HasValue &&
- (point.Value.X < 0d || point.Value.X > parentMap.ActualWidth ||
- point.Value.Y < 0d || point.Value.Y > parentMap.ActualHeight))
- {
- longitudeOffset = parentMap.CoerceLongitude(location.Longitude) - location.Longitude;
- }
- }
-
- return longitudeOffset;
+ return point;
}
}
}
diff --git a/MapControl/Shared/MapTileLayer.cs b/MapControl/Shared/MapTileLayer.cs
index 39eddf30..ffa4710a 100644
--- a/MapControl/Shared/MapTileLayer.cs
+++ b/MapControl/Shared/MapTileLayer.cs
@@ -156,7 +156,7 @@ namespace MapControl
//
var tileMatrixOrigin = new Point(TileSize * TileMatrix.XMin, TileSize * TileMatrix.YMin);
- var tileMatrixScale = ViewTransform.ZoomLevelToScale(TileMatrix.ZoomLevel);
+ var tileMatrixScale = MapBase.ZoomLevelToScale(TileMatrix.ZoomLevel);
((MatrixTransform)RenderTransform).Matrix =
ParentMap.ViewTransform.GetTileLayerTransform(tileMatrixScale, MapTopLeft, tileMatrixOrigin);
@@ -169,7 +169,7 @@ namespace MapControl
//
var tileMatrixZoomLevel = (int)Math.Floor(ParentMap.ZoomLevel - ZoomLevelOffset + 0.001);
- var tileMatrixScale = ViewTransform.ZoomLevelToScale(tileMatrixZoomLevel);
+ var tileMatrixScale = MapBase.ZoomLevelToScale(tileMatrixZoomLevel);
// Bounds in tile pixels from view size.
//
diff --git a/MapControl/Shared/ViewTransform.cs b/MapControl/Shared/ViewTransform.cs
index 1576c195..beeada3e 100644
--- a/MapControl/Shared/ViewTransform.cs
+++ b/MapControl/Shared/ViewTransform.cs
@@ -2,7 +2,6 @@
// Copyright © 2024 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
-using System;
#if WPF
using System.Windows;
using System.Windows.Media;
@@ -18,18 +17,8 @@ namespace MapControl
/// Defines the transformation between projected map coordinates in meters
/// and view coordinates in pixels.
///
- public class ViewTransform
+ public partial class ViewTransform
{
- public static double ZoomLevelToScale(double zoomLevel)
- {
- return 256d * Math.Pow(2d, zoomLevel) / (360d * MapProjection.Wgs84MeterPerDegree);
- }
-
- public static double ScaleToZoomLevel(double scale)
- {
- return Math.Log(scale * 360d * MapProjection.Wgs84MeterPerDegree / 256d, 2d);
- }
-
///
/// Gets the scaling factor from projected map coordinates to view coordinates,
/// as pixels per meter.
@@ -51,6 +40,32 @@ namespace MapControl
///
public Matrix ViewToMapMatrix { get; private set; }
+ ///
+ /// Transforms a Point from projected map coordinates to view coordinates.
+ ///
+ public Point MapToView(Point point)
+ {
+ return MapToViewMatrix.Transform(point);
+ }
+
+ ///
+ /// Transforms a Point from view coordinates to projected map coordinates.
+ ///
+ public Point ViewToMap(Point point)
+ {
+ return ViewToMapMatrix.Transform(point);
+ }
+
+ ///
+ /// Transform relative to absolute map scale. Returns horizontal and vertical
+ /// scaling factors from meters to view coordinates.
+ ///
+ public Point GetMapScale(Point relativeScale)
+ {
+ return new Point(Scale * relativeScale.X, Scale * relativeScale.Y);
+ }
+
+#if WPF || UWP || WINUI
///
/// Initializes a ViewTransform from a map center point in projected coordinates,
/// a view conter point, a scaling factor from projected coordinates to view coordinates
@@ -72,30 +87,6 @@ namespace MapControl
ViewToMapMatrix = transform;
}
- ///
- /// Transforms a Point from projected map coordinates to view coordinates.
- ///
- public Point MapToView(Point point)
- {
- return MapToViewMatrix.Transform(point);
- }
-
- ///
- /// Transforms a Point from view coordinates to projected map coordinates.
- ///
- public Point ViewToMap(Point point)
- {
- return ViewToMapMatrix.Transform(point);
- }
-
- ///
- /// Gets scaling factors from meters to view coordinates for a relative map scale.
- ///
- public Point GetMapScale(Point relativeScale)
- {
- return new Point(Scale * relativeScale.X, Scale * relativeScale.Y);
- }
-
///
/// Gets a transform Matrix from meters to view coordinates for a relative map scale.
///
@@ -170,5 +161,6 @@ namespace MapControl
return transform;
}
+#endif
}
}