XAML-Map-Control/MBTiles/Shared/MBTileLayer.cs

97 lines
2.9 KiB
C#
Raw Normal View History

2025-04-01 16:11:53 +02:00
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
2024-05-22 11:25:32 +02:00
#if WPF
using System.Windows;
2021-11-17 23:46:48 +01:00
#elif UWP
2017-10-07 17:43:28 +02:00
using Windows.UI.Xaml;
2024-05-22 11:25:32 +02:00
#elif WINUI
using Microsoft.UI.Xaml;
#elif AVALONIA
using DependencyProperty = Avalonia.AvaloniaProperty;
2017-10-07 17:43:28 +02:00
#endif
2026-04-13 17:14:49 +02:00
namespace MapControl.MBTiles;
/// <summary>
/// MapTileLayer that uses an MBTiles SQLite Database. See https://wiki.openstreetmap.org/wiki/MBTiles.
/// </summary>
public class MBTileLayer : MapTileLayer
2017-10-07 17:43:28 +02:00
{
2026-04-13 17:14:49 +02:00
private static ILogger Logger => field ??= ImageLoader.LoggerFactory?.CreateLogger<MBTileLayer>();
public static readonly DependencyProperty FileProperty =
DependencyPropertyHelper.Register<MBTileLayer, string>(nameof(File), null,
async (layer, oldValue, newValue) => await layer.FilePropertyChanged(newValue));
public string File
{
get => (string)GetValue(FileProperty);
set => SetValue(FileProperty, value);
}
/// <summary>
2026-04-13 17:14:49 +02:00
/// May be overridden to create a derived MBTileSource that handles other tile formats than png and jpg.
/// </summary>
2026-04-13 17:14:49 +02:00
protected virtual async Task<MBTileSource> CreateTileSourceAsync(string file)
2017-10-07 17:43:28 +02:00
{
2026-04-13 17:14:49 +02:00
var tileSource = new MBTileSource();
2025-08-31 14:30:20 +02:00
2026-04-13 17:14:49 +02:00
await tileSource.OpenAsync(file);
2017-10-07 17:43:28 +02:00
2026-04-13 17:14:49 +02:00
if (tileSource.Metadata.TryGetValue("format", out string format) && format != "png" && format != "jpg")
2017-10-07 17:43:28 +02:00
{
2026-04-13 17:14:49 +02:00
tileSource.Dispose();
2017-10-07 17:43:28 +02:00
2026-04-13 17:14:49 +02:00
throw new NotSupportedException($"Tile image format {format} is not supported.");
}
2024-08-20 18:00:04 +02:00
2026-04-13 17:14:49 +02:00
return tileSource;
}
2024-08-20 18:00:04 +02:00
2026-04-13 17:14:49 +02:00
private async Task FilePropertyChanged(string file)
{
(TileSource as MBTileSource)?.Close();
2024-08-20 18:00:04 +02:00
2026-04-13 17:14:49 +02:00
ClearValue(TileSourceProperty);
ClearValue(SourceNameProperty);
ClearValue(DescriptionProperty);
ClearValue(MinZoomLevelProperty);
ClearValue(MaxZoomLevelProperty);
2024-08-20 18:00:04 +02:00
2026-04-13 17:14:49 +02:00
if (!string.IsNullOrEmpty(file))
2017-10-07 17:43:28 +02:00
{
2026-04-13 17:14:49 +02:00
try
2017-10-07 17:43:28 +02:00
{
2026-04-13 17:14:49 +02:00
var tileSource = await CreateTileSourceAsync(file);
2017-10-07 17:43:28 +02:00
2026-04-13 17:14:49 +02:00
TileSource = tileSource;
2017-10-07 17:43:28 +02:00
2026-04-13 17:14:49 +02:00
if (tileSource.Metadata.TryGetValue("name", out string value))
{
SourceName = value;
}
2024-08-20 18:00:04 +02:00
2026-04-13 17:14:49 +02:00
if (tileSource.Metadata.TryGetValue("description", out value))
{
Description = value;
}
2024-08-20 18:00:04 +02:00
2026-04-13 17:14:49 +02:00
if (tileSource.Metadata.TryGetValue("minzoom", out value) && int.TryParse(value, out int zoomLevel))
{
MinZoomLevel = zoomLevel;
2024-08-20 18:00:04 +02:00
}
2026-04-13 17:14:49 +02:00
if (tileSource.Metadata.TryGetValue("maxzoom", out value) && int.TryParse(value, out zoomLevel))
2017-10-07 17:43:28 +02:00
{
2026-04-13 17:14:49 +02:00
MaxZoomLevel = zoomLevel;
2017-10-07 17:43:28 +02:00
}
}
2026-04-13 17:14:49 +02:00
catch (Exception ex)
{
Logger?.LogError(ex, "Invalid file: {file}", file);
}
2017-10-07 17:43:28 +02:00
}
}
}