2020-03-20 18:12:56 +01:00
|
|
|
|
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
2021-01-13 21:19:27 +01:00
|
|
|
|
// © 2021 Clemens Fischer
|
2020-03-20 18:12:56 +01:00
|
|
|
|
// Licensed under the Microsoft Public License (Ms-PL)
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
2021-06-14 21:41:37 +02:00
|
|
|
|
#if WINUI
|
|
|
|
|
|
using Windows.Foundation;
|
|
|
|
|
|
using Microsoft.UI.Xaml.Controls;
|
|
|
|
|
|
using Microsoft.UI.Xaml.Media;
|
|
|
|
|
|
#elif WINDOWS_UWP
|
2020-03-20 18:12:56 +01:00
|
|
|
|
using Windows.Foundation;
|
|
|
|
|
|
using Windows.UI.Xaml.Controls;
|
|
|
|
|
|
using Windows.UI.Xaml.Media;
|
|
|
|
|
|
#else
|
|
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Controls;
|
|
|
|
|
|
using System.Windows.Media;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
namespace MapControl
|
|
|
|
|
|
{
|
|
|
|
|
|
public class WmtsTileMatrixLayer : Panel
|
|
|
|
|
|
{
|
|
|
|
|
|
public WmtsTileMatrixLayer(WmtsTileMatrix tileMatrix, int zoomLevel)
|
|
|
|
|
|
{
|
|
|
|
|
|
RenderTransform = new MatrixTransform();
|
|
|
|
|
|
TileMatrix = tileMatrix;
|
|
|
|
|
|
ZoomLevel = zoomLevel;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public WmtsTileMatrix TileMatrix { get; }
|
2021-11-13 00:28:27 +01:00
|
|
|
|
|
2020-03-23 17:13:50 +01:00
|
|
|
|
public int ZoomLevel { get; } // index of TileMatrix in WmtsTileMatrixSet.TileMatrixes
|
|
|
|
|
|
|
2020-03-20 18:12:56 +01:00
|
|
|
|
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 IReadOnlyCollection<Tile> Tiles { get; private set; } = new List<Tile>();
|
|
|
|
|
|
|
2020-03-26 19:08:20 +01:00
|
|
|
|
public void SetRenderTransform(ViewTransform viewTransform)
|
2020-03-20 18:12:56 +01:00
|
|
|
|
{
|
2020-03-26 19:08:20 +01:00
|
|
|
|
// tile matrix origin in pixels
|
2020-03-20 18:12:56 +01:00
|
|
|
|
//
|
2020-03-26 19:08:20 +01:00
|
|
|
|
var tileMatrixOrigin = new Point(TileMatrix.TileWidth * XMin, TileMatrix.TileHeight * YMin);
|
2020-03-20 18:12:56 +01:00
|
|
|
|
|
2020-03-22 18:33:34 +01:00
|
|
|
|
((MatrixTransform)RenderTransform).Matrix =
|
2020-03-26 19:08:20 +01:00
|
|
|
|
viewTransform.GetTileLayerTransform(TileMatrix.Scale, TileMatrix.TopLeft, tileMatrixOrigin);
|
2020-03-22 18:33:34 +01:00
|
|
|
|
}
|
2020-03-20 18:12:56 +01:00
|
|
|
|
|
2020-03-28 21:53:38 +01:00
|
|
|
|
public bool SetBounds(ViewTransform viewTransform, Size viewSize)
|
2020-03-22 18:33:34 +01:00
|
|
|
|
{
|
2020-03-28 21:53:38 +01:00
|
|
|
|
// bounds in tile pixels from view size
|
2020-03-21 08:17:15 +01:00
|
|
|
|
//
|
2020-03-28 21:53:38 +01:00
|
|
|
|
var bounds = viewTransform.GetTileMatrixBounds(TileMatrix.Scale, TileMatrix.TopLeft, viewSize);
|
2020-03-20 18:12:56 +01:00
|
|
|
|
|
2020-03-22 18:33:34 +01:00
|
|
|
|
// tile column and row index bounds
|
|
|
|
|
|
//
|
2020-03-20 18:12:56 +01:00
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
xMin = Math.Max(xMin, 0);
|
|
|
|
|
|
yMin = Math.Max(yMin, 0);
|
|
|
|
|
|
xMax = Math.Min(Math.Max(xMax, 0), TileMatrix.MatrixWidth - 1);
|
|
|
|
|
|
yMax = Math.Min(Math.Max(yMax, 0), TileMatrix.MatrixHeight - 1);
|
|
|
|
|
|
|
|
|
|
|
|
if (XMin == xMin && YMin == yMin && XMax == xMax && YMax == yMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
XMin = xMin;
|
|
|
|
|
|
YMin = yMin;
|
|
|
|
|
|
XMax = xMax;
|
|
|
|
|
|
YMax = yMax;
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void UpdateTiles()
|
|
|
|
|
|
{
|
|
|
|
|
|
var newTiles = new List<Tile>();
|
|
|
|
|
|
|
|
|
|
|
|
for (var y = YMin; y <= YMax; y++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (var x = XMin; x <= XMax; x++)
|
|
|
|
|
|
{
|
|
|
|
|
|
newTiles.Add(Tiles.FirstOrDefault(t => t.X == x && t.Y == y) ?? new Tile(ZoomLevel, x, y));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Tiles = newTiles;
|
|
|
|
|
|
|
|
|
|
|
|
Children.Clear();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var tile in Tiles)
|
|
|
|
|
|
{
|
|
|
|
|
|
Children.Add(tile.Image);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override Size MeasureOverride(Size availableSize)
|
|
|
|
|
|
{
|
|
|
|
|
|
availableSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var tile in Tiles)
|
|
|
|
|
|
{
|
|
|
|
|
|
tile.Image.Measure(availableSize);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return new Size();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override Size ArrangeOverride(Size finalSize)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var tile in Tiles)
|
|
|
|
|
|
{
|
|
|
|
|
|
// arrange tiles relative to XMin/YMin
|
|
|
|
|
|
//
|
|
|
|
|
|
var x = TileMatrix.TileWidth * (tile.X - XMin);
|
|
|
|
|
|
var y = TileMatrix.TileHeight * (tile.Y - YMin);
|
|
|
|
|
|
|
|
|
|
|
|
tile.Image.Width = TileMatrix.TileWidth;
|
|
|
|
|
|
tile.Image.Height = TileMatrix.TileHeight;
|
|
|
|
|
|
tile.Image.Arrange(new Rect(x, y, TileMatrix.TileWidth, TileMatrix.TileHeight));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return finalSize;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|