mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Fixed moving transform center across dateline.
This commit is contained in:
parent
7fbbf66acb
commit
afc93704d9
|
|
@ -30,12 +30,6 @@ namespace MapControl
|
||||||
East = east;
|
East = east;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoundingBox(BoundingBox boundingBox, double longitudeOffset)
|
|
||||||
: this(boundingBox.South, boundingBox.West + longitudeOffset,
|
|
||||||
boundingBox.North, boundingBox.East + longitudeOffset)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public double West { get; set; }
|
public double West { get; set; }
|
||||||
|
|
||||||
public double East { get; set; }
|
public double East { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,8 @@ namespace MapControl
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets a temporary center point in view coordinates for scaling and rotation transformations.
|
/// Sets a temporary center point in view coordinates for scaling and rotation transformations.
|
||||||
/// This center point is automatically reset when the Center property is set by application code.
|
/// This center point is automatically reset when the Center property is set by application code
|
||||||
|
/// or by the methods TranslateMap, TransformMap, ZoomMap and ZoomToBounds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetTransformCenter(Point center)
|
public void SetTransformCenter(Point center)
|
||||||
{
|
{
|
||||||
|
|
@ -728,6 +729,7 @@ namespace MapControl
|
||||||
|
|
||||||
private void UpdateTransform(bool resetTransformCenter = false, bool projectionChanged = false)
|
private void UpdateTransform(bool resetTransformCenter = false, bool projectionChanged = false)
|
||||||
{
|
{
|
||||||
|
var transformCenterChanged = false;
|
||||||
var viewScale = ViewTransform.ZoomLevelToScale(ZoomLevel);
|
var viewScale = ViewTransform.ZoomLevelToScale(ZoomLevel);
|
||||||
var projection = MapProjection;
|
var projection = MapProjection;
|
||||||
|
|
||||||
|
|
@ -762,6 +764,9 @@ namespace MapControl
|
||||||
|
|
||||||
if (resetTransformCenter)
|
if (resetTransformCenter)
|
||||||
{
|
{
|
||||||
|
// check if transform center moved across the dateline
|
||||||
|
transformCenterChanged = Math.Abs(center.Longitude - transformCenter.Longitude) > 180d;
|
||||||
|
|
||||||
ResetTransformCenter();
|
ResetTransformCenter();
|
||||||
|
|
||||||
projection.Center = ProjectionCenter ?? Center;
|
projection.Center = ProjectionCenter ?? Center;
|
||||||
|
|
@ -778,9 +783,11 @@ namespace MapControl
|
||||||
|
|
||||||
SetViewScale(ViewTransform.Scale);
|
SetViewScale(ViewTransform.Scale);
|
||||||
|
|
||||||
OnViewportChanged(new ViewportChangedEventArgs(projectionChanged, Center.Longitude - centerLongitude));
|
// check if view center moved across the dateline
|
||||||
|
transformCenterChanged = transformCenterChanged || Math.Abs(Center.Longitude - centerLongitude) > 180d;
|
||||||
centerLongitude = Center.Longitude;
|
centerLongitude = Center.Longitude;
|
||||||
|
|
||||||
|
OnViewportChanged(new ViewportChangedEventArgs(projectionChanged, transformCenterChanged));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,11 +171,11 @@ namespace MapControl
|
||||||
|
|
||||||
base.OnViewportChanged(e);
|
base.OnViewportChanged(e);
|
||||||
|
|
||||||
await UpdateImageAsync();
|
await UpdateImageAsync(); // update immediately
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AdjustBoundingBox(e.LongitudeOffset);
|
ValidateBoundingBox();
|
||||||
|
|
||||||
base.OnViewportChanged(e);
|
base.OnViewportChanged(e);
|
||||||
|
|
||||||
|
|
@ -233,21 +233,30 @@ namespace MapControl
|
||||||
BoundingBox = ParentMap.ViewRectToBoundingBox(rect);
|
BoundingBox = ParentMap.ViewRectToBoundingBox(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AdjustBoundingBox(double longitudeOffset)
|
private void ValidateBoundingBox()
|
||||||
{
|
{
|
||||||
if (Math.Abs(longitudeOffset) > 180d && BoundingBox != null)
|
if (BoundingBox != null)
|
||||||
{
|
{
|
||||||
var offset = 360d * Math.Sign(longitudeOffset);
|
var offset = ParentMap.Center.Longitude - BoundingBox.Center.Longitude;
|
||||||
|
|
||||||
BoundingBox = new BoundingBox(BoundingBox, offset);
|
if (Math.Abs(offset) > 180d)
|
||||||
|
{
|
||||||
|
offset = 360d * Math.Sign(offset);
|
||||||
|
|
||||||
|
BoundingBox = new BoundingBox(
|
||||||
|
BoundingBox.South, BoundingBox.West + offset,
|
||||||
|
BoundingBox.North, BoundingBox.East + offset);
|
||||||
|
|
||||||
foreach (var image in Children.OfType<Image>())
|
foreach (var image in Children.OfType<Image>())
|
||||||
{
|
{
|
||||||
var imageBoundingBox = GetBoundingBox(image);
|
var imageBbox = GetBoundingBox(image);
|
||||||
|
|
||||||
if (imageBoundingBox != null)
|
if (imageBbox != null)
|
||||||
{
|
{
|
||||||
SetBoundingBox(image, new BoundingBox(imageBoundingBox, offset));
|
SetBoundingBox(image, new BoundingBox(
|
||||||
|
imageBbox.South, imageBbox.West + offset,
|
||||||
|
imageBbox.North, imageBbox.East + offset));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// Licensed under the Microsoft Public License (Ms-PL)
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
#if WINUI
|
#if WINUI
|
||||||
using Windows.Foundation;
|
using Windows.Foundation;
|
||||||
|
|
@ -125,11 +126,11 @@ namespace MapControl
|
||||||
|
|
||||||
protected override Task UpdateTileLayer()
|
protected override Task UpdateTileLayer()
|
||||||
{
|
{
|
||||||
var update = false;
|
var updateTiles = false;
|
||||||
|
|
||||||
if (ParentMap == null || ParentMap.MapProjection.Type != MapProjectionType.WebMercator)
|
if (ParentMap == null || ParentMap.MapProjection.Type != MapProjectionType.WebMercator)
|
||||||
{
|
{
|
||||||
update = TileMatrix != null;
|
updateTiles = TileMatrix != null;
|
||||||
TileMatrix = null;
|
TileMatrix = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -137,27 +138,23 @@ namespace MapControl
|
||||||
if (TileSource != TileImageLoader.TileSource)
|
if (TileSource != TileImageLoader.TileSource)
|
||||||
{
|
{
|
||||||
Tiles = new TileCollection(); // clear all
|
Tiles = new TileCollection(); // clear all
|
||||||
update = true;
|
updateTiles = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SetTileMatrix())
|
if (SetTileMatrix())
|
||||||
{
|
{
|
||||||
|
updateTiles = true;
|
||||||
|
}
|
||||||
|
|
||||||
SetRenderTransform();
|
SetRenderTransform();
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update)
|
return updateTiles ? UpdateTiles() : Task.CompletedTask;
|
||||||
{
|
|
||||||
UpdateTiles();
|
|
||||||
|
|
||||||
return TileImageLoader.LoadTiles(Tiles, TileSource, SourceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SetRenderTransform()
|
protected override void SetRenderTransform()
|
||||||
|
{
|
||||||
|
if (TileMatrix != null)
|
||||||
{
|
{
|
||||||
// tile matrix origin in pixels
|
// tile matrix origin in pixels
|
||||||
//
|
//
|
||||||
|
|
@ -168,6 +165,7 @@ namespace MapControl
|
||||||
((MatrixTransform)RenderTransform).Matrix =
|
((MatrixTransform)RenderTransform).Matrix =
|
||||||
ParentMap.ViewTransform.GetTileLayerTransform(tileMatrixScale, MapTopLeft, tileMatrixOrigin);
|
ParentMap.ViewTransform.GetTileLayerTransform(tileMatrixScale, MapTopLeft, tileMatrixOrigin);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool SetTileMatrix()
|
private bool SetTileMatrix()
|
||||||
{
|
{
|
||||||
|
|
@ -199,7 +197,7 @@ namespace MapControl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateTiles()
|
private Task UpdateTiles()
|
||||||
{
|
{
|
||||||
var tiles = new TileCollection();
|
var tiles = new TileCollection();
|
||||||
|
|
||||||
|
|
@ -241,6 +239,8 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
Children.Add(tile.Image);
|
Children.Add(tile.Image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TileImageLoader.LoadTiles(tiles, TileSource, SourceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -201,9 +201,9 @@ namespace MapControl
|
||||||
|
|
||||||
private async void OnViewportChanged(object sender, ViewportChangedEventArgs e)
|
private async void OnViewportChanged(object sender, ViewportChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (Children.Count == 0 || e.ProjectionChanged || Math.Abs(e.LongitudeOffset) > 180d)
|
if (Children.Count == 0 || e.ProjectionChanged || e.TransformCenterChanged)
|
||||||
{
|
{
|
||||||
await Update(); // update immediately when projection has changed or center has moved across 180° longitude
|
await Update(); // update immediately
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,23 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
public class ViewportChangedEventArgs : EventArgs
|
public class ViewportChangedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public ViewportChangedEventArgs(bool projectionChanged = false, double longitudeOffset = 0d)
|
public ViewportChangedEventArgs(bool projectionChanged = false, bool transformCenterChanged = false)
|
||||||
{
|
{
|
||||||
ProjectionChanged = projectionChanged;
|
ProjectionChanged = projectionChanged;
|
||||||
LongitudeOffset = longitudeOffset;
|
TransformCenterChanged = transformCenterChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates if the map projection has changed. Used to control when a MapTileLayer or MapImageLayer
|
/// Indicates that the map projection has changed. Used to control when
|
||||||
/// should be updated immediately, or MapPath Data in projected map coordinates should be recalculated.
|
/// a MapTileLayer or a MapImageLayer should be updated immediately,
|
||||||
|
/// or MapPath Data in projected map coordinates should be recalculated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ProjectionChanged { get; }
|
public bool ProjectionChanged { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Offset of the map center longitude value from the previous viewport.
|
/// Indicates that the view transform center has moved across the dateline.
|
||||||
/// Used to detect if the map center has moved across 180° longitude.
|
/// Used to control when a MapTileLayer should be updated immediately.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double LongitudeOffset { get; }
|
public bool TransformCenterChanged { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,14 +94,11 @@ namespace MapControl
|
||||||
return UpdateTiles(null);
|
return UpdateTiles(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UpdateChildLayers(tileMatrixSet))
|
var updateTiles = UpdateChildLayers(tileMatrixSet);
|
||||||
{
|
|
||||||
SetRenderTransform();
|
SetRenderTransform();
|
||||||
|
|
||||||
return UpdateTiles(tileMatrixSet);
|
return updateTiles ? UpdateTiles(tileMatrixSet) : Task.CompletedTask;
|
||||||
}
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SetRenderTransform()
|
protected override void SetRenderTransform()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue