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> /// </summary>
public class MapTileLayer : TilePyramidLayer 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); 180d * MapProjection.Wgs84MeterPerDegree);
public static readonly DependencyProperty TileSourceProperty = public static readonly DependencyProperty TileSourceProperty =
@ -116,9 +116,9 @@ namespace MapControl
{ {
// Arrange tiles relative to TileMatrix.XMin/YMin. // Arrange tiles relative to TileMatrix.XMin/YMin.
// //
var tileSize = TileSize << (TileMatrix.ZoomLevel - tile.ZoomLevel); var tileSize = MapTileLayer.tileSize << (TileMatrix.ZoomLevel - tile.ZoomLevel);
var x = tileSize * tile.X - TileSize * TileMatrix.XMin; var x = tileSize * tile.X - MapTileLayer.tileSize * TileMatrix.XMin;
var y = tileSize * tile.Y - TileSize * TileMatrix.YMin; var y = tileSize * tile.Y - MapTileLayer.tileSize * TileMatrix.YMin;
tile.Image.Width = tileSize; tile.Image.Width = tileSize;
tile.Image.Height = tileSize; tile.Image.Height = tileSize;
@ -134,11 +134,11 @@ namespace MapControl
{ {
// Tile matrix origin in pixels. // 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); var tileMatrixScale = MapBase.ZoomLevelToScale(TileMatrix.ZoomLevel);
((MatrixTransform)RenderTransform).Matrix = ((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. // 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. // Tile X and Y bounds.
// //
var xMin = (int)Math.Floor(bounds.X / TileSize); var xMin = (int)Math.Floor(bounds.X / tileSize);
var yMin = (int)Math.Floor(bounds.Y / TileSize); var yMin = (int)Math.Floor(bounds.Y / tileSize);
var xMax = (int)Math.Floor((bounds.X + bounds.Width) / TileSize); var xMax = (int)Math.Floor((bounds.X + bounds.Width) / tileSize);
var yMax = (int)Math.Floor((bounds.Y + bounds.Height) / TileSize); var yMax = (int)Math.Floor((bounds.Y + bounds.Height) / tileSize);
if (TileMatrix != null && if (TileMatrix != null &&
TileMatrix.ZoomLevel == tileMatrixZoomLevel && TileMatrix.ZoomLevel == tileMatrixZoomLevel &&

View file

@ -13,14 +13,6 @@ using Avalonia;
namespace MapControl 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> /// <summary>
/// For reference see https://www.ogc.org/standards/wmts, 07-057r7_Web_Map_Tile_Service_Standard.pdf /// For reference see https://www.ogc.org/standards/wmts, 07-057r7_Web_Map_Tile_Service_Standard.pdf
/// </summary> /// </summary>

View file

@ -8,8 +8,7 @@ using Avalonia;
namespace MapControl namespace MapControl
{ {
public class WmtsTileMatrix( public class WmtsTileMatrix(
string identifier, double scale, Point topLeft, string identifier, double scale, Point topLeft, int tileWidth, int tileHeight, int matrixWidth, int matrixHeight)
int tileWidth, int tileHeight, int matrixWidth, int matrixHeight)
{ {
public string Identifier => identifier; public string Identifier => identifier;
public double Scale => scale; 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]; PixelBuffer = new byte[4 * width * height];
bitmap.CopyPixels(PixelBuffer, 4 * width, 0); 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; tile.Completed -= OnTileCompleted;
Dispatcher.Invoke(() => if (tile.PixelBuffer != null)
{ {
if (tile.X >= TileMatrix.XMin && tile.X <= TileMatrix.XMax && Dispatcher.Invoke(() =>
tile.Y >= TileMatrix.YMin && tile.Y <= TileMatrix.YMax)
{ {
CopyTile(tile); if (tile.X >= TileMatrix.XMin && tile.X <= TileMatrix.XMax &&
} tile.Y >= TileMatrix.YMin && tile.Y <= TileMatrix.YMax)
}); {
CopyTile(tile);
}
});
}
} }
} }
} }