mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
ITile, ITileSource interfaces
This commit is contained in:
parent
cb4dff8bcb
commit
20e4fcce75
|
|
@ -16,7 +16,7 @@ namespace MapControl.MBTiles
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MapTileLayer that uses an MBTiles SQLite Database. See https://wiki.openstreetmap.org/wiki/MBTiles.
|
/// MapTileLayer that uses an MBTiles SQLite Database. See https://wiki.openstreetmap.org/wiki/MBTiles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MBTileLayer : MapTileLayer
|
public partial class MBTileLayer : MapTileLayer
|
||||||
{
|
{
|
||||||
private static ILogger logger;
|
private static ILogger logger;
|
||||||
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<MBTileLayer>();
|
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<MBTileLayer>();
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ using ImageSource = Avalonia.Media.IImage;
|
||||||
|
|
||||||
namespace MapControl.MBTiles
|
namespace MapControl.MBTiles
|
||||||
{
|
{
|
||||||
public sealed class MBTileSource : TileSource, IDisposable
|
public sealed partial class MBTileSource : TileSource, IDisposable
|
||||||
{
|
{
|
||||||
private static ILogger logger;
|
private static ILogger logger;
|
||||||
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<MBTileSource>();
|
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<MBTileSource>();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Avalonia;
|
global using DependencyProperty = Avalonia.AvaloniaProperty;
|
||||||
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Data;
|
using Avalonia.Data;
|
||||||
using System;
|
using System;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,4 @@
|
||||||
global using DependencyProperty = Avalonia.AvaloniaProperty;
|
using Avalonia;
|
||||||
global using FrameworkElement = Avalonia.Controls.Control;
|
|
||||||
global using Brush = Avalonia.Media.IBrush;
|
|
||||||
global using ImageSource = Avalonia.Media.IImage;
|
|
||||||
global using PropertyPath = System.String;
|
|
||||||
using Avalonia;
|
|
||||||
using Avalonia.Animation;
|
using Avalonia.Animation;
|
||||||
using Avalonia.Animation.Easings;
|
using Avalonia.Animation.Easings;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
|
@ -13,6 +8,7 @@ using Avalonia.Media;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Brush = Avalonia.Media.IBrush;
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Avalonia;
|
global using FrameworkElement = Avalonia.Controls.Control;
|
||||||
using Avalonia.Controls;
|
using Avalonia;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
|
|
@ -20,18 +20,18 @@ namespace MapControl
|
||||||
AffectsParentArrange<MapPanel>(LocationProperty, BoundingBoxProperty);
|
AffectsParentArrange<MapPanel>(LocationProperty, BoundingBoxProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MapBase GetParentMap(Control element)
|
public static MapBase GetParentMap(FrameworkElement element)
|
||||||
{
|
{
|
||||||
return (MapBase)element.GetValue(ParentMapProperty);
|
return (MapBase)element.GetValue(ParentMapProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetRenderTransform(Control element, Transform transform, double originX = 0d, double originY = 0d)
|
public static void SetRenderTransform(FrameworkElement element, Transform transform, double originX = 0d, double originY = 0d)
|
||||||
{
|
{
|
||||||
element.RenderTransform = transform;
|
element.RenderTransform = transform;
|
||||||
element.RenderTransformOrigin = new RelativePoint(originX, originY, RelativeUnit.Relative);
|
element.RenderTransformOrigin = new RelativePoint(originX, originY, RelativeUnit.Relative);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetVisible(Control element, bool visible)
|
private static void SetVisible(FrameworkElement element, bool visible)
|
||||||
{
|
{
|
||||||
element.IsVisible = visible;
|
element.IsVisible = visible;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ using System.Windows.Media;
|
||||||
using Windows.UI.Xaml.Media;
|
using Windows.UI.Xaml.Media;
|
||||||
#elif WINUI
|
#elif WINUI
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
#elif AVALONIA
|
||||||
|
using ImageSource = Avalonia.Media.IImage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Microsoft.UI.Xaml.Media;
|
||||||
#elif AVALONIA
|
#elif AVALONIA
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Brush = Avalonia.Media.IBrush;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Microsoft.UI.Xaml.Media;
|
||||||
#elif AVALONIA
|
#elif AVALONIA
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
using Brush = Avalonia.Media.IBrush;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ using Microsoft.UI.Xaml.Media;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
using Brush = Avalonia.Media.IBrush;
|
||||||
|
using ImageSource = Avalonia.Media.IImage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ using Microsoft.UI.Xaml.Data;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Data;
|
using Avalonia.Data;
|
||||||
|
using PropertyPath = System.String;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ using Avalonia.Controls.Shapes;
|
||||||
using Avalonia.Data;
|
using Avalonia.Data;
|
||||||
using Avalonia.Layout;
|
using Avalonia.Layout;
|
||||||
using PointCollection = System.Collections.Generic.List<Avalonia.Point>;
|
using PointCollection = System.Collections.Generic.List<Avalonia.Point>;
|
||||||
|
using PropertyPath = System.String;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace MapControl
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Displays a standard Web Mercator map tile pyramid, e.g. a OpenStreetMap tiles.
|
/// Displays a standard Web Mercator map tile pyramid, e.g. a OpenStreetMap tiles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class MapTileLayer : MapTilePyramidLayer
|
public partial class MapTileLayer : TilePyramidLayer
|
||||||
{
|
{
|
||||||
public static readonly DependencyProperty MinZoomLevelProperty =
|
public static readonly DependencyProperty MinZoomLevelProperty =
|
||||||
DependencyPropertyHelper.Register<MapTileLayer, int>(nameof(MinZoomLevel), 0);
|
DependencyPropertyHelper.Register<MapTileLayer, int>(nameof(MinZoomLevel), 0);
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,14 @@ using Avalonia.Media;
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
public partial class Tile(int zoomLevel, int x, int y, int columnCount)
|
public partial class Tile(int zoomLevel, int x, int y, int columnCount) : ITile
|
||||||
{
|
{
|
||||||
public int ZoomLevel { get; } = zoomLevel;
|
public int ZoomLevel { get; } = zoomLevel;
|
||||||
public int X { get; } = x;
|
public int X { get; } = x;
|
||||||
public int Y { get; } = y;
|
public int Y { get; } = y;
|
||||||
public int Column { get; } = ((x % columnCount) + columnCount) % columnCount;
|
public int Column { get; } = ((x % columnCount) + columnCount) % columnCount;
|
||||||
public int Row => Y;
|
public int Row => Y;
|
||||||
|
|
||||||
public Image Image { get; } = new Image { Stretch = Stretch.Fill };
|
|
||||||
public bool IsPending { get; set; } = true;
|
public bool IsPending { get; set; } = true;
|
||||||
|
public Image Image { get; } = new Image { Stretch = Stretch.Fill };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,71 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
#if WPF
|
||||||
|
using System.Windows.Media;
|
||||||
|
#elif UWP
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
#elif WINUI
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
#elif AVALONIA
|
||||||
|
using ImageSource = Avalonia.Media.IImage;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface ITile
|
||||||
/// Loads and optionally caches map tile images for a MapTileLayer.
|
{
|
||||||
/// </summary>
|
int ZoomLevel { get; }
|
||||||
|
int Column { get; }
|
||||||
|
int Row { get; }
|
||||||
|
bool IsPending { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs a tile image download Task and marshals the result to the UI thread.
|
||||||
|
/// </summary>
|
||||||
|
Task LoadImageAsync(Func<Task<ImageSource>> loadImageFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITileSource
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether tile images from this source should be cached.
|
||||||
|
/// </summary>
|
||||||
|
bool Cacheable { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the image Uri for the specified zoom level and tile indices.
|
||||||
|
/// </summary>
|
||||||
|
Uri GetUri(int zoomLevel, int column, int row);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads a tile image whithout caching.
|
||||||
|
/// </summary>
|
||||||
|
Task<ImageSource> LoadImageAsync(int zoomLevel, int column, int row);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads a cacheable tile image from an encoded frame buffer.
|
||||||
|
/// </summary>
|
||||||
|
Task<ImageSource> LoadImageAsync(byte[] buffer);
|
||||||
|
}
|
||||||
|
|
||||||
public interface ITileImageLoader
|
public interface ITileImageLoader
|
||||||
{
|
{
|
||||||
void BeginLoadTiles(IEnumerable<Tile> tiles, TileSource tileSource, string cacheName, IProgress<double> progress);
|
/// <summary>
|
||||||
|
/// Loads all pending tiles from the tiles collection.
|
||||||
|
/// Tile image caching is enabled when tileSource.UriFormat starts with "http" and cacheName is a non-empty string.
|
||||||
|
/// </summary>
|
||||||
|
void BeginLoadTiles(IEnumerable<ITile> tiles, ITileSource tileSource, string cacheName, IProgress<double> progress);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cancels a potentially ongoing tile loading task.
|
||||||
|
/// </summary>
|
||||||
void CancelLoadTiles();
|
void CancelLoadTiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads and optionally caches map tile images for a MapTilePyramidLayer.
|
||||||
|
/// </summary>
|
||||||
public class TileImageLoader : ITileImageLoader
|
public class TileImageLoader : ITileImageLoader
|
||||||
{
|
{
|
||||||
private static ILogger logger;
|
private static ILogger logger;
|
||||||
|
|
@ -63,17 +115,13 @@ namespace MapControl
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static int MaxLoadTasks { get; set; } = 4;
|
public static int MaxLoadTasks { get; set; } = 4;
|
||||||
|
|
||||||
private readonly Queue<Tile> tileQueue = new();
|
private readonly Queue<ITile> tileQueue = new();
|
||||||
private int tileCount;
|
private int tileCount;
|
||||||
private int taskCount;
|
private int taskCount;
|
||||||
|
|
||||||
/// <summary>
|
public void BeginLoadTiles(IEnumerable<ITile> tiles, ITileSource tileSource, string cacheName, IProgress<double> progress)
|
||||||
/// Loads all pending tiles from the tiles collection. Tile image caching is enabled when the Cache
|
|
||||||
/// property is not null and tileSource.UriFormat starts with "http" and cacheName is a non-empty string.
|
|
||||||
/// </summary>
|
|
||||||
public void BeginLoadTiles(IEnumerable<Tile> tiles, TileSource tileSource, string cacheName, IProgress<double> progress)
|
|
||||||
{
|
{
|
||||||
if (Cache == null || tileSource.UriTemplate == null || !tileSource.UriTemplate.StartsWith("http"))
|
if (Cache == null || !tileSource.Cacheable)
|
||||||
{
|
{
|
||||||
cacheName = null; // disable caching
|
cacheName = null; // disable caching
|
||||||
}
|
}
|
||||||
|
|
@ -110,9 +158,9 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadTilesFromQueue(TileSource tileSource, string cacheName, IProgress<double> progress)
|
private async Task LoadTilesFromQueue(ITileSource tileSource, string cacheName, IProgress<double> progress)
|
||||||
{
|
{
|
||||||
bool TryDequeueTile(out Tile tile)
|
bool TryDequeueTile(out ITile tile)
|
||||||
{
|
{
|
||||||
lock (tileQueue)
|
lock (tileQueue)
|
||||||
{
|
{
|
||||||
|
|
@ -130,7 +178,7 @@ namespace MapControl
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (TryDequeueTile(out Tile tile))
|
while (TryDequeueTile(out ITile tile))
|
||||||
{
|
{
|
||||||
tile.IsPending = false;
|
tile.IsPending = false;
|
||||||
|
|
||||||
|
|
@ -170,7 +218,7 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<byte[]> LoadCachedBuffer(Tile tile, Uri uri, string cacheName)
|
private static async Task<byte[]> LoadCachedBuffer(ITile tile, Uri uri, string cacheName)
|
||||||
{
|
{
|
||||||
var extension = Path.GetExtension(uri.LocalPath).ToLower();
|
var extension = Path.GetExtension(uri.LocalPath).ToLower();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,47 +20,48 @@ using Microsoft.UI.Xaml.Media;
|
||||||
#elif AVALONIA
|
#elif AVALONIA
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
using Brush = Avalonia.Media.IBrush;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
public abstract class MapTilePyramidLayer : Panel, IMapLayer
|
public abstract class TilePyramidLayer : Panel, IMapLayer
|
||||||
{
|
{
|
||||||
public static readonly DependencyProperty TileSourceProperty =
|
public static readonly DependencyProperty TileSourceProperty =
|
||||||
DependencyPropertyHelper.Register<MapTilePyramidLayer, TileSource>(nameof(TileSource), null,
|
DependencyPropertyHelper.Register<TilePyramidLayer, TileSource>(nameof(TileSource), null,
|
||||||
(layer, oldValue, newValue) => layer.UpdateTiles(true));
|
(layer, oldValue, newValue) => layer.UpdateTiles(true));
|
||||||
|
|
||||||
public static readonly DependencyProperty SourceNameProperty =
|
public static readonly DependencyProperty SourceNameProperty =
|
||||||
DependencyPropertyHelper.Register<MapTilePyramidLayer, string>(nameof(SourceName));
|
DependencyPropertyHelper.Register<TilePyramidLayer, string>(nameof(SourceName));
|
||||||
|
|
||||||
public static readonly DependencyProperty DescriptionProperty =
|
public static readonly DependencyProperty DescriptionProperty =
|
||||||
DependencyPropertyHelper.Register<MapTilePyramidLayer, string>(nameof(Description));
|
DependencyPropertyHelper.Register<TilePyramidLayer, string>(nameof(Description));
|
||||||
|
|
||||||
public static readonly DependencyProperty MaxBackgroundLevelsProperty =
|
public static readonly DependencyProperty MaxBackgroundLevelsProperty =
|
||||||
DependencyPropertyHelper.Register<MapTilePyramidLayer, int>(nameof(MaxBackgroundLevels), 5);
|
DependencyPropertyHelper.Register<TilePyramidLayer, int>(nameof(MaxBackgroundLevels), 5);
|
||||||
|
|
||||||
public static readonly DependencyProperty UpdateIntervalProperty =
|
public static readonly DependencyProperty UpdateIntervalProperty =
|
||||||
DependencyPropertyHelper.Register<MapTilePyramidLayer, TimeSpan>(nameof(UpdateInterval), TimeSpan.FromSeconds(0.2),
|
DependencyPropertyHelper.Register<TilePyramidLayer, TimeSpan>(nameof(UpdateInterval), TimeSpan.FromSeconds(0.2),
|
||||||
(layer, oldValue, newValue) => layer.updateTimer.Interval = newValue);
|
(layer, oldValue, newValue) => layer.updateTimer.Interval = newValue);
|
||||||
|
|
||||||
public static readonly DependencyProperty UpdateWhileViewportChangingProperty =
|
public static readonly DependencyProperty UpdateWhileViewportChangingProperty =
|
||||||
DependencyPropertyHelper.Register<MapTilePyramidLayer, bool>(nameof(UpdateWhileViewportChanging));
|
DependencyPropertyHelper.Register<TilePyramidLayer, bool>(nameof(UpdateWhileViewportChanging));
|
||||||
|
|
||||||
public static readonly DependencyProperty MapBackgroundProperty =
|
public static readonly DependencyProperty MapBackgroundProperty =
|
||||||
DependencyPropertyHelper.Register<MapTilePyramidLayer, Brush>(nameof(MapBackground));
|
DependencyPropertyHelper.Register<TilePyramidLayer, Brush>(nameof(MapBackground));
|
||||||
|
|
||||||
public static readonly DependencyProperty MapForegroundProperty =
|
public static readonly DependencyProperty MapForegroundProperty =
|
||||||
DependencyPropertyHelper.Register<MapTilePyramidLayer, Brush>(nameof(MapForeground));
|
DependencyPropertyHelper.Register<TilePyramidLayer, Brush>(nameof(MapForeground));
|
||||||
|
|
||||||
public static readonly DependencyProperty LoadingProgressProperty =
|
public static readonly DependencyProperty LoadingProgressProperty =
|
||||||
DependencyPropertyHelper.Register<MapTilePyramidLayer, double>(nameof(LoadingProgress), 1d);
|
DependencyPropertyHelper.Register<TilePyramidLayer, double>(nameof(LoadingProgress), 1d);
|
||||||
|
|
||||||
private readonly Progress<double> loadingProgress;
|
private readonly Progress<double> loadingProgress;
|
||||||
private readonly UpdateTimer updateTimer;
|
private readonly UpdateTimer updateTimer;
|
||||||
private ITileImageLoader tileImageLoader;
|
private ITileImageLoader tileImageLoader;
|
||||||
private MapBase parentMap;
|
private MapBase parentMap;
|
||||||
|
|
||||||
protected MapTilePyramidLayer()
|
protected TilePyramidLayer()
|
||||||
{
|
{
|
||||||
IsHitTestVisible = false;
|
IsHitTestVisible = false;
|
||||||
|
|
||||||
|
|
@ -191,7 +192,7 @@ namespace MapControl
|
||||||
|
|
||||||
protected bool IsBaseMapLayer => parentMap != null && parentMap.Children.Count > 0 && parentMap.Children[0] == this;
|
protected bool IsBaseMapLayer => parentMap != null && parentMap.Children.Count > 0 && parentMap.Children[0] == this;
|
||||||
|
|
||||||
protected void BeginLoadTiles(IEnumerable<Tile> tiles, string cacheName)
|
protected void BeginLoadTiles(IEnumerable<ITile> tiles, string cacheName)
|
||||||
{
|
{
|
||||||
if (TileSource != null && tiles != null && tiles.Any(tile => tile.IsPending))
|
if (TileSource != null && tiles != null && tiles.Any(tile => tile.IsPending))
|
||||||
{
|
{
|
||||||
|
|
@ -7,6 +7,8 @@ using System.Windows.Media;
|
||||||
using Windows.UI.Xaml.Media;
|
using Windows.UI.Xaml.Media;
|
||||||
#elif WINUI
|
#elif WINUI
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
#elif AVALONIA
|
||||||
|
using ImageSource = Avalonia.Media.IImage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
|
|
@ -19,7 +21,7 @@ namespace MapControl
|
||||||
#else
|
#else
|
||||||
[System.ComponentModel.TypeConverter(typeof(TileSourceConverter))]
|
[System.ComponentModel.TypeConverter(typeof(TileSourceConverter))]
|
||||||
#endif
|
#endif
|
||||||
public class TileSource
|
public class TileSource : ITileSource
|
||||||
{
|
{
|
||||||
private string uriTemplate;
|
private string uriTemplate;
|
||||||
|
|
||||||
|
|
@ -35,19 +37,15 @@ namespace MapControl
|
||||||
|
|
||||||
if (uriTemplate != null && uriTemplate.Contains("{s}") && Subdomains == null)
|
if (uriTemplate != null && uriTemplate.Contains("{s}") && Subdomains == null)
|
||||||
{
|
{
|
||||||
Subdomains = new string[] { "a", "b", "c" }; // default OpenStreetMap subdomains
|
Subdomains = ["a", "b", "c"]; // default OpenStreetMap subdomains
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets an array of request subdomain names that are replaced for the {s} format specifier.
|
|
||||||
/// </summary>
|
|
||||||
public string[] Subdomains { get; set; }
|
public string[] Subdomains { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
public bool Cacheable => UriTemplate != null && UriTemplate.StartsWith("http");
|
||||||
/// Gets the image Uri for the specified tile indices and zoom level.
|
|
||||||
/// </summary>
|
|
||||||
public virtual Uri GetUri(int zoomLevel, int column, int row)
|
public virtual Uri GetUri(int zoomLevel, int column, int row)
|
||||||
{
|
{
|
||||||
Uri uri = null;
|
Uri uri = null;
|
||||||
|
|
@ -71,10 +69,6 @@ namespace MapControl
|
||||||
return uri;
|
return uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Loads a tile ImageSource asynchronously from GetUri(zoomLevel, column, row).
|
|
||||||
/// This method is called by TileImageLoader when caching is disabled.
|
|
||||||
/// </summary>
|
|
||||||
public virtual Task<ImageSource> LoadImageAsync(int zoomLevel, int column, int row)
|
public virtual Task<ImageSource> LoadImageAsync(int zoomLevel, int column, int row)
|
||||||
{
|
{
|
||||||
var uri = GetUri(zoomLevel, column, row);
|
var uri = GetUri(zoomLevel, column, row);
|
||||||
|
|
@ -82,10 +76,6 @@ namespace MapControl
|
||||||
return uri != null ? ImageLoader.LoadImageAsync(uri) : Task.FromResult((ImageSource)null);
|
return uri != null ? ImageLoader.LoadImageAsync(uri) : Task.FromResult((ImageSource)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Loads a tile ImageSource asynchronously from an encoded frame buffer in a byte array.
|
|
||||||
/// This method is called by TileImageLoader when caching is enabled.
|
|
||||||
/// </summary>
|
|
||||||
public virtual Task<ImageSource> LoadImageAsync(byte[] buffer)
|
public virtual Task<ImageSource> LoadImageAsync(byte[] buffer)
|
||||||
{
|
{
|
||||||
return ImageLoader.LoadImageAsync(buffer);
|
return ImageLoader.LoadImageAsync(buffer);
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MapProjectionConverter : TypeConverter, IValueConverter
|
public partial class MapProjectionConverter : TypeConverter, IValueConverter
|
||||||
{
|
{
|
||||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ using Microsoft.UI.Xaml.Media;
|
||||||
#elif AVALONIA
|
#elif AVALONIA
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
|
using ImageSource = Avalonia.Media.IImage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace MapControl
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Displays map tiles from a Web Map Tile Service (WMTS).
|
/// Displays map tiles from a Web Map Tile Service (WMTS).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class WmtsTileLayer : MapTilePyramidLayer
|
public partial class WmtsTileLayer : TilePyramidLayer
|
||||||
{
|
{
|
||||||
private static ILogger logger;
|
private static ILogger logger;
|
||||||
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(WmtsTileLayer));
|
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(WmtsTileLayer));
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue