WmtsTileMatrixSet

This commit is contained in:
ClemensFischer 2025-12-03 08:21:15 +01:00
parent e14c9e4102
commit 65c20c76b2
5 changed files with 67 additions and 30 deletions

View file

@ -24,9 +24,9 @@ namespace MapControl
/// </summary>
public class MapTileLayer : TilePyramidLayer
{
private const int TileSize = 256;
private const int tileSize = 256;
private static readonly Point MapTopLeft = new(-180d * MapProjection.Wgs84MeterPerDegree,
private static readonly Point mapTopLeft = new(-180d * MapProjection.Wgs84MeterPerDegree,
180d * MapProjection.Wgs84MeterPerDegree);
public static readonly DependencyProperty TileSourceProperty =
@ -116,9 +116,9 @@ namespace MapControl
{
// Arrange tiles relative to TileMatrix.XMin/YMin.
//
var tileSize = TileSize << (TileMatrix.ZoomLevel - tile.ZoomLevel);
var x = tileSize * tile.X - TileSize * TileMatrix.XMin;
var y = tileSize * tile.Y - TileSize * TileMatrix.YMin;
var tileSize = MapTileLayer.tileSize << (TileMatrix.ZoomLevel - tile.ZoomLevel);
var x = tileSize * tile.X - MapTileLayer.tileSize * TileMatrix.XMin;
var y = tileSize * tile.Y - MapTileLayer.tileSize * TileMatrix.YMin;
tile.Image.Width = tileSize;
tile.Image.Height = tileSize;
@ -134,11 +134,11 @@ namespace MapControl
{
// Tile matrix origin in pixels.
//
var tileMatrixOrigin = new Point(TileSize * TileMatrix.XMin, TileSize * TileMatrix.YMin);
var tileMatrixOrigin = new Point(tileSize * TileMatrix.XMin, tileSize * TileMatrix.YMin);
var tileMatrixScale = MapBase.ZoomLevelToScale(TileMatrix.ZoomLevel);
((MatrixTransform)RenderTransform).Matrix =
ParentMap.ViewTransform.GetTileLayerTransform(tileMatrixScale, MapTopLeft, tileMatrixOrigin);
ParentMap.ViewTransform.GetTileLayerTransform(tileMatrixScale, mapTopLeft, tileMatrixOrigin);
}
}
@ -178,14 +178,14 @@ namespace MapControl
// Tile matrix bounds in pixels.
//
var bounds = ParentMap.ViewTransform.GetTileMatrixBounds(tileMatrixScale, MapTopLeft, ParentMap.ActualWidth, ParentMap.ActualHeight);
var bounds = ParentMap.ViewTransform.GetTileMatrixBounds(tileMatrixScale, mapTopLeft, ParentMap.ActualWidth, ParentMap.ActualHeight);
// Tile X and Y bounds.
//
var xMin = (int)Math.Floor(bounds.X / TileSize);
var yMin = (int)Math.Floor(bounds.Y / TileSize);
var xMax = (int)Math.Floor((bounds.X + bounds.Width) / TileSize);
var yMax = (int)Math.Floor((bounds.Y + bounds.Height) / TileSize);
var xMin = (int)Math.Floor(bounds.X / tileSize);
var yMin = (int)Math.Floor(bounds.Y / tileSize);
var xMax = (int)Math.Floor((bounds.X + bounds.Width) / tileSize);
var yMax = (int)Math.Floor((bounds.Y + bounds.Height) / tileSize);
if (TileMatrix != null &&
TileMatrix.ZoomLevel == tileMatrixZoomLevel &&

View file

@ -13,14 +13,6 @@ using Avalonia;
namespace MapControl
{
public class WmtsTileMatrixSet(string identifier, string supportedCrsId, string uriTemplate, IEnumerable<WmtsTileMatrix> tileMatrixes)
{
public string Identifier => identifier;
public string SupportedCrsId => supportedCrsId;
public string UriTemplate { get; } = uriTemplate.Replace("{TileMatrixSet}", identifier);
public List<WmtsTileMatrix> TileMatrixes { get; } = tileMatrixes.OrderBy(m => m.Scale).ToList();
}
/// <summary>
/// For reference see https://www.ogc.org/standards/wmts, 07-057r7_Web_Map_Tile_Service_Standard.pdf
/// </summary>

View file

@ -8,8 +8,7 @@ using Avalonia;
namespace MapControl
{
public class WmtsTileMatrix(
string identifier, double scale, Point topLeft,
int tileWidth, int tileHeight, int matrixWidth, int matrixHeight)
string identifier, double scale, Point topLeft, int tileWidth, int tileHeight, int matrixWidth, int matrixHeight)
{
public string Identifier => identifier;
public double Scale => scale;

View file

@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.Linq;
#if WPF
using System.Windows;
#elif AVALONIA
using Avalonia;
#endif
namespace MapControl
{
public class WmtsTileMatrixSet(
string identifier, string supportedCrsId, string uriTemplate, IEnumerable<WmtsTileMatrix> tileMatrixes)
{
public string Identifier => identifier;
public string SupportedCrsId => supportedCrsId;
public string UriTemplate { get; } = uriTemplate.Replace("{TileMatrixSet}", identifier);
public List<WmtsTileMatrix> TileMatrixes { get; } = tileMatrixes.OrderBy(m => m.Scale).ToList();
public static WmtsTileMatrixSet CreateOpenStreetMapTileMatrixSet(
string uriTemplate, int minZoomLevel = 0, int maxZoomLevel = 19)
{
const int tileSize = 256;
const double baseScale = tileSize / (360d * MapProjection.Wgs84MeterPerDegree);
Point mapTopLeft = new(-180d * MapProjection.Wgs84MeterPerDegree,
180d * MapProjection.Wgs84MeterPerDegree);
return new WmtsTileMatrixSet(null,
WebMercatorProjection.DefaultCrsId,
uriTemplate
.Replace("{z}", "{0}")
.Replace("{x}", "{1}")
.Replace("{y}", "{2}"),
Enumerable
.Range(minZoomLevel, maxZoomLevel - minZoomLevel + 1)
.Select<int, (int zoomLevel, int matrixSize)>(z => (z, 1 << z))
.Select(t => new WmtsTileMatrix(
t.zoomLevel.ToString(),
t.matrixSize * baseScale, mapTopLeft,
tileSize, tileSize, t.matrixSize, t.matrixSize)));
}
}
}

View file

@ -28,9 +28,9 @@ namespace MapControl
PixelBuffer = new byte[4 * width * height];
bitmap.CopyPixels(PixelBuffer, 4 * width, 0);
Completed?.Invoke(this, EventArgs.Empty);
}
Completed?.Invoke(this, EventArgs.Empty);
}
}
@ -172,14 +172,17 @@ namespace MapControl
tile.Completed -= OnTileCompleted;
Dispatcher.Invoke(() =>
if (tile.PixelBuffer != null)
{
if (tile.X >= TileMatrix.XMin && tile.X <= TileMatrix.XMax &&
tile.Y >= TileMatrix.YMin && tile.Y <= TileMatrix.YMax)
Dispatcher.Invoke(() =>
{
CopyTile(tile);
}
});
if (tile.X >= TileMatrix.XMin && tile.X <= TileMatrix.XMax &&
tile.Y >= TileMatrix.YMin && tile.Y <= TileMatrix.YMax)
{
CopyTile(tile);
}
});
}
}
}
}