diff --git a/MapControl/Shared/MapImageLayer.cs b/MapControl/Shared/MapImageLayer.cs index 470947aa..8faf0e74 100644 --- a/MapControl/Shared/MapImageLayer.cs +++ b/MapControl/Shared/MapImageLayer.cs @@ -165,29 +165,27 @@ namespace MapControl protected override async void OnViewportChanged(ViewportChangedEventArgs e) { + base.OnViewportChanged(e); + if (e.ProjectionChanged) { ClearImages(); - base.OnViewportChanged(e); - await UpdateImageAsync(); // update immediately } else { - ValidateBoundingBox(); - - base.OnViewportChanged(e); - updateTimer.Run(!UpdateWhileViewportChanging); } } protected async Task UpdateImageAsync() { - if (updateInProgress) // update image on next tick + if (updateInProgress) { - updateTimer.Run(); // start timer if not running + // update image on next tick, start timer if not running + // + updateTimer.Run(); } else { @@ -233,35 +231,6 @@ namespace MapControl BoundingBox = ParentMap.ViewRectToBoundingBox(rect); } - private void ValidateBoundingBox() - { - if (BoundingBox != null) - { - var offset = ParentMap.Center.Longitude - BoundingBox.Center.Longitude; - - 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()) - { - var imageBbox = GetBoundingBox(image); - - if (imageBbox != null) - { - SetBoundingBox(image, new BoundingBox( - imageBbox.South, imageBbox.West + offset, - imageBbox.North, imageBbox.East + offset)); - } - } - } - } - } - private void ClearImages() { foreach (var image in Children.OfType()) diff --git a/MapControl/Shared/MapTileLayer.cs b/MapControl/Shared/MapTileLayer.cs index 335055cf..cbe9c613 100644 --- a/MapControl/Shared/MapTileLayer.cs +++ b/MapControl/Shared/MapTileLayer.cs @@ -3,7 +3,6 @@ // Licensed under the Microsoft Public License (Ms-PL) using System; -using System.Linq; using System.Threading.Tasks; #if WINUI using Windows.Foundation; @@ -149,7 +148,14 @@ namespace MapControl SetRenderTransform(); } - return updateTiles ? UpdateTiles() : Task.CompletedTask; + if (updateTiles) + { + UpdateTiles(); + + return TileImageLoader.LoadTiles(Tiles, TileSource, SourceName); + } + + return Task.CompletedTask; } protected override void SetRenderTransform() @@ -197,7 +203,7 @@ namespace MapControl return true; } - private Task UpdateTiles() + private void UpdateTiles() { var tiles = new TileCollection(); @@ -239,8 +245,6 @@ namespace MapControl { Children.Add(tile.Image); } - - return TileImageLoader.LoadTiles(tiles, TileSource, SourceName); } } } diff --git a/MapControl/Shared/MapTileLayerBase.cs b/MapControl/Shared/MapTileLayerBase.cs index 291f73a8..fe6e3681 100644 --- a/MapControl/Shared/MapTileLayerBase.cs +++ b/MapControl/Shared/MapTileLayerBase.cs @@ -201,7 +201,7 @@ namespace MapControl private async void OnViewportChanged(object sender, ViewportChangedEventArgs e) { - if (Children.Count == 0 || e.ProjectionChanged || e.TransformCenterChanged) + if (e.TransformCenterChanged || e.ProjectionChanged || Children.Count == 0) { await Update(); // update immediately } diff --git a/MapControl/Shared/WmtsTileLayer.cs b/MapControl/Shared/WmtsTileLayer.cs index 65a88b3e..0a04de9c 100644 --- a/MapControl/Shared/WmtsTileLayer.cs +++ b/MapControl/Shared/WmtsTileLayer.cs @@ -91,14 +91,15 @@ namespace MapControl { Children.Clear(); - return UpdateTiles(null); + return LoadTiles(null); // stop TileImageLoader } - var updateTiles = UpdateChildLayers(tileMatrixSet); + if (UpdateChildLayers(tileMatrixSet)) + { + return LoadTiles(tileMatrixSet); + } - SetRenderTransform(); - - return updateTiles ? UpdateTiles(tileMatrixSet) : Task.CompletedTask; + return Task.CompletedTask; } protected override void SetRenderTransform() @@ -111,7 +112,6 @@ namespace MapControl private bool UpdateChildLayers(WmtsTileMatrixSet tileMatrixSet) { - var layersChanged = false; var maxScale = 1.001 * ParentMap.ViewTransform.Scale; // avoid rounding issues // show all WmtsTileMatrix layers with Scale <= maxScale, at least the first layer @@ -129,42 +129,33 @@ namespace MapControl currentMatrixes = currentMatrixes.Skip(currentMatrixes.Count - MaxBackgroundLevels - 1).ToList(); } - var currentLayers = ChildLayers.Where(layer => currentMatrixes.Contains(layer.TileMatrix)).ToList(); + var currentLayers = ChildLayers.Where(layer => currentMatrixes.Contains(layer.WmtsTileMatrix)).ToList(); + var tilesChanged = false; Children.Clear(); foreach (var tileMatrix in currentMatrixes) { - var layer = currentLayers.FirstOrDefault(l => l.TileMatrix == tileMatrix); + var layer = currentLayers.FirstOrDefault(l => l.WmtsTileMatrix == tileMatrix) + ?? new WmtsTileMatrixLayer(tileMatrix, tileMatrixSet.TileMatrixes.IndexOf(tileMatrix)); - if (layer == null) + if (layer.UpdateTiles(ParentMap.ViewTransform, ParentMap.RenderSize)) { - layer = new WmtsTileMatrixLayer(tileMatrix, tileMatrixSet.TileMatrixes.IndexOf(tileMatrix)); - layersChanged = true; + tilesChanged = true; } - if (layer.SetBounds(ParentMap.ViewTransform, ParentMap.RenderSize)) - { - layersChanged = true; - } + layer.SetRenderTransform(ParentMap.ViewTransform); Children.Add(layer); } - return layersChanged; + return tilesChanged; } - private Task UpdateTiles(WmtsTileMatrixSet tileMatrixSet) + private Task LoadTiles(WmtsTileMatrixSet tileMatrixSet) { - var tiles = new List(); var cacheName = SourceName; - foreach (var layer in ChildLayers) - { - layer.UpdateTiles(); - tiles.AddRange(layer.Tiles); - } - if (tileMatrixSet != null && TileSource is WmtsTileSource tileSource) { tileSource.TileMatrixSet = tileMatrixSet; @@ -180,6 +171,8 @@ namespace MapControl } } + var tiles = ChildLayers.SelectMany(layer => layer.Tiles); + return TileImageLoader.LoadTiles(tiles, TileSource, cacheName); } diff --git a/MapControl/Shared/WmtsTileMatrixLayer.cs b/MapControl/Shared/WmtsTileMatrixLayer.cs index 6e19599a..4cf5b870 100644 --- a/MapControl/Shared/WmtsTileMatrixLayer.cs +++ b/MapControl/Shared/WmtsTileMatrixLayer.cs @@ -21,21 +21,18 @@ namespace MapControl { public class WmtsTileMatrixLayer : Panel { + // zoomLevel is index of tileMatrix in a WmtsTileMatrixSet.TileMatrixes list + // public WmtsTileMatrixLayer(WmtsTileMatrix tileMatrix, int zoomLevel) { RenderTransform = new MatrixTransform(); - TileMatrix = tileMatrix; - ZoomLevel = zoomLevel; + WmtsTileMatrix = tileMatrix; + TileMatrix = new TileMatrix(zoomLevel, 1, 1, 0, 0); } - public WmtsTileMatrix TileMatrix { get; } + public WmtsTileMatrix WmtsTileMatrix { get; } - public int ZoomLevel { get; } // index of TileMatrix in WmtsTileMatrixSet.TileMatrixes - - public int XMin { get; private set; } - public int YMin { get; private set; } - public int XMax { get; private set; } - public int YMax { get; private set; } + public TileMatrix TileMatrix { get; private set; } public TileCollection Tiles { get; private set; } = new TileCollection(); @@ -43,62 +40,57 @@ namespace MapControl { // tile matrix origin in pixels // - var tileMatrixOrigin = new Point(TileMatrix.TileWidth * XMin, TileMatrix.TileHeight * YMin); + var tileMatrixOrigin = new Point(WmtsTileMatrix.TileWidth * TileMatrix.XMin, WmtsTileMatrix.TileHeight * TileMatrix.YMin); ((MatrixTransform)RenderTransform).Matrix = - viewTransform.GetTileLayerTransform(TileMatrix.Scale, TileMatrix.TopLeft, tileMatrixOrigin); + viewTransform.GetTileLayerTransform(WmtsTileMatrix.Scale, WmtsTileMatrix.TopLeft, tileMatrixOrigin); } - public bool SetBounds(ViewTransform viewTransform, Size viewSize) + public bool UpdateTiles(ViewTransform viewTransform, Size viewSize) { // bounds in tile pixels from view size // - var bounds = viewTransform.GetTileMatrixBounds(TileMatrix.Scale, TileMatrix.TopLeft, viewSize); + var bounds = viewTransform.GetTileMatrixBounds(WmtsTileMatrix.Scale, WmtsTileMatrix.TopLeft, viewSize); // tile X and Y bounds // - var xMin = (int)Math.Floor(bounds.X / TileMatrix.TileWidth); - var yMin = (int)Math.Floor(bounds.Y / TileMatrix.TileHeight); - var xMax = (int)Math.Floor((bounds.X + bounds.Width) / TileMatrix.TileWidth); - var yMax = (int)Math.Floor((bounds.Y + bounds.Height) / TileMatrix.TileHeight); + var xMin = (int)Math.Floor(bounds.X / WmtsTileMatrix.TileWidth); + var yMin = (int)Math.Floor(bounds.Y / WmtsTileMatrix.TileHeight); + var xMax = (int)Math.Floor((bounds.X + bounds.Width) / WmtsTileMatrix.TileWidth); + var yMax = (int)Math.Floor((bounds.Y + bounds.Height) / WmtsTileMatrix.TileHeight); // total tile matrix width in meters // - var totalWidth = TileMatrix.MatrixWidth * TileMatrix.TileWidth / TileMatrix.Scale; + var totalWidth = WmtsTileMatrix.MatrixWidth * WmtsTileMatrix.TileWidth / WmtsTileMatrix.Scale; if (Math.Abs(totalWidth - 360d * MapProjection.Wgs84MeterPerDegree) > 1d) { // no full longitudinal coverage, restrict x index // xMin = Math.Max(xMin, 0); - xMax = Math.Min(Math.Max(xMax, 0), TileMatrix.MatrixWidth - 1); + xMax = Math.Min(Math.Max(xMax, 0), WmtsTileMatrix.MatrixWidth - 1); } yMin = Math.Max(yMin, 0); - yMax = Math.Min(Math.Max(yMax, 0), TileMatrix.MatrixHeight - 1); + yMax = Math.Min(Math.Max(yMax, 0), WmtsTileMatrix.MatrixHeight - 1); - if (XMin == xMin && YMin == yMin && XMax == xMax && YMax == yMax) + if (TileMatrix.XMin == xMin && TileMatrix.YMin == yMin && + TileMatrix.XMax == xMax && TileMatrix.YMax == yMax) { + // no change of the TileMatrix and the Tiles collection + // return false; } - XMin = xMin; - YMin = yMin; - XMax = xMax; - YMax = yMax; + TileMatrix = new TileMatrix(TileMatrix.ZoomLevel, xMin, yMin, xMax, yMax); - return true; - } - - public void UpdateTiles() - { var tiles = new TileCollection(); - for (var y = YMin; y <= YMax; y++) + for (var y = yMin; y <= yMax; y++) { - for (var x = XMin; x <= XMax; x++) + for (var x = xMin; x <= xMax; x++) { - tiles.Add(Tiles.GetTile(ZoomLevel, x, y, TileMatrix.MatrixWidth)); + tiles.Add(Tiles.GetTile(TileMatrix.ZoomLevel, x, y, WmtsTileMatrix.MatrixWidth)); } } @@ -106,10 +98,12 @@ namespace MapControl Children.Clear(); - foreach (var tile in Tiles) + foreach (var tile in tiles) { Children.Add(tile.Image); } + + return true; } protected override Size MeasureOverride(Size availableSize) @@ -130,12 +124,12 @@ namespace MapControl { // arrange tiles relative to XMin/YMin // - var x = TileMatrix.TileWidth * (tile.X - XMin); - var y = TileMatrix.TileHeight * (tile.Y - YMin); + var x = WmtsTileMatrix.TileWidth * (tile.X - TileMatrix.XMin); + var y = WmtsTileMatrix.TileHeight * (tile.Y - TileMatrix.YMin); - tile.Image.Width = TileMatrix.TileWidth; - tile.Image.Height = TileMatrix.TileHeight; - tile.Image.Arrange(new Rect(x, y, TileMatrix.TileWidth, TileMatrix.TileHeight)); + tile.Image.Width = WmtsTileMatrix.TileWidth; + tile.Image.Height = WmtsTileMatrix.TileHeight; + tile.Image.Arrange(new Rect(x, y, WmtsTileMatrix.TileWidth, WmtsTileMatrix.TileHeight)); } return finalSize;