mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Abstract classes Tile, TileSource
This commit is contained in:
parent
20e4fcce75
commit
cb8fff0dd1
|
|
@ -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 partial class MBTileLayer : MapTileLayer
|
public 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 partial class MBTileSource : TileSource, IDisposable
|
public sealed 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>();
|
||||||
|
|
@ -24,6 +24,8 @@ namespace MapControl.MBTiles
|
||||||
|
|
||||||
public IDictionary<string, string> Metadata { get; } = new Dictionary<string, string>();
|
public IDictionary<string, string> Metadata { get; } = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
public override bool Cacheable => false;
|
||||||
|
|
||||||
public async Task OpenAsync(string file)
|
public async Task OpenAsync(string file)
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
|
|
@ -85,5 +87,10 @@ namespace MapControl.MBTiles
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Uri GetUri(int zoomLevel, int column, int row)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Animation;
|
using Avalonia.Animation;
|
||||||
|
using Avalonia.Controls;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
|
@ -8,9 +9,12 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
public partial class Tile
|
public class ImageTile(int zoomLevel, int x, int y, int columnCount)
|
||||||
|
: Tile(zoomLevel, x, y, columnCount)
|
||||||
{
|
{
|
||||||
public async Task LoadImageAsync(Func<Task<IImage>> loadImageFunc)
|
public Image Image { get; } = new Image { Stretch = Stretch.Fill };
|
||||||
|
|
||||||
|
public override async Task LoadImageAsync(Func<Task<IImage>> loadImageFunc)
|
||||||
{
|
{
|
||||||
var image = await loadImageFunc().ConfigureAwait(false);
|
var image = await loadImageFunc().ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -4,7 +4,7 @@ using System.Text;
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
public class BoundingBoxTileSource : TileSource
|
public class BoundingBoxTileSource : UriTileSource
|
||||||
{
|
{
|
||||||
public override Uri GetUri(int zoomLevel, int column, int row)
|
public override Uri GetUri(int zoomLevel, int column, int row)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@ using System.Linq;
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
public partial class TileCollection : List<Tile>
|
public partial class ImageTileList : List<ImageTile>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds existing Tiles from the source collection or newly created Tiles to fill the specified tile matrix.
|
/// Adds existing ImageTile from the source collection or newly created ImageTile to fill the specified tile matrix.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void FillMatrix(TileCollection source, int zoomLevel, int xMin, int yMin, int xMax, int yMax, int columnCount)
|
public void FillMatrix(ImageTileList source, int zoomLevel, int xMin, int yMin, int xMax, int yMax, int columnCount)
|
||||||
{
|
{
|
||||||
for (var y = yMin; y <= yMax; y++)
|
for (var y = yMin; y <= yMax; y++)
|
||||||
{
|
{
|
||||||
|
|
@ -18,7 +18,7 @@ namespace MapControl
|
||||||
|
|
||||||
if (tile == null)
|
if (tile == null)
|
||||||
{
|
{
|
||||||
tile = new Tile(zoomLevel, x, y, columnCount);
|
tile = new ImageTile(zoomLevel, x, y, columnCount);
|
||||||
|
|
||||||
var equivalentTile = source.FirstOrDefault(
|
var equivalentTile = source.FirstOrDefault(
|
||||||
t => t.Image.Source != null && t.ZoomLevel == tile.ZoomLevel && t.Column == tile.Column && t.Row == tile.Row);
|
t => t.Image.Source != null && t.ZoomLevel == tile.ZoomLevel && t.Column == tile.Column && t.Row == tile.Row);
|
||||||
|
|
@ -43,7 +43,7 @@ namespace MapControl
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static MapTileLayer OpenStreetMapTileLayer => new()
|
public static MapTileLayer OpenStreetMapTileLayer => new()
|
||||||
{
|
{
|
||||||
TileSource = new TileSource { UriTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png" },
|
TileSource = TileSource.Parse("https://tile.openstreetmap.org/{z}/{x}/{y}.png"),
|
||||||
SourceName = "OpenStreetMap",
|
SourceName = "OpenStreetMap",
|
||||||
Description = "© [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
|
Description = "© [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
|
||||||
};
|
};
|
||||||
|
|
@ -52,7 +52,7 @@ namespace MapControl
|
||||||
|
|
||||||
public TileMatrix TileMatrix { get; private set; }
|
public TileMatrix TileMatrix { get; private set; }
|
||||||
|
|
||||||
public TileCollection Tiles { get; private set; } = [];
|
public ImageTileList Tiles { get; private set; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Minimum zoom level supported by the MapTileLayer. Default value is 0.
|
/// Minimum zoom level supported by the MapTileLayer. Default value is 0.
|
||||||
|
|
@ -178,7 +178,7 @@ namespace MapControl
|
||||||
|
|
||||||
private void UpdateTiles(bool reset)
|
private void UpdateTiles(bool reset)
|
||||||
{
|
{
|
||||||
var tiles = new TileCollection();
|
var tiles = new ImageTileList();
|
||||||
|
|
||||||
if (TileSource != null && TileMatrix != null)
|
if (TileSource != null && TileMatrix != null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,18 @@
|
||||||
#if WPF
|
using System;
|
||||||
using System.Windows.Controls;
|
using System.Threading.Tasks;
|
||||||
|
#if WPF
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
#elif UWP
|
#elif UWP
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
using Windows.UI.Xaml.Media;
|
using Windows.UI.Xaml.Media;
|
||||||
#elif WINUI
|
#elif WINUI
|
||||||
using Microsoft.UI.Xaml.Controls;
|
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Microsoft.UI.Xaml.Media;
|
||||||
#elif AVALONIA
|
#elif AVALONIA
|
||||||
using Avalonia.Controls;
|
using ImageSource = Avalonia.Media.IImage;
|
||||||
using Avalonia.Media;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
public partial class Tile(int zoomLevel, int x, int y, int columnCount) : ITile
|
public abstract class Tile(int zoomLevel, int x, int y, int columnCount)
|
||||||
{
|
{
|
||||||
public int ZoomLevel { get; } = zoomLevel;
|
public int ZoomLevel { get; } = zoomLevel;
|
||||||
public int X { get; } = x;
|
public int X { get; } = x;
|
||||||
|
|
@ -22,6 +20,10 @@ namespace MapControl
|
||||||
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 bool IsPending { get; set; } = true;
|
public bool IsPending { get; set; } = true;
|
||||||
public Image Image { get; } = new Image { Stretch = Stretch.Fill };
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs a tile image download Task and marshals the result to the UI thread.
|
||||||
|
/// </summary>
|
||||||
|
public abstract Task LoadImageAsync(Func<Task<ImageSource>> loadImageFunc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,61 +7,16 @@ 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
|
||||||
{
|
{
|
||||||
public interface ITile
|
|
||||||
{
|
|
||||||
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
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads all pending tiles from the tiles collection.
|
/// 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.
|
/// Tile image caching is enabled when tileSource.UriFormat starts with "http" and cacheName is a non-empty string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void BeginLoadTiles(IEnumerable<ITile> tiles, ITileSource tileSource, string cacheName, IProgress<double> progress);
|
void BeginLoadTiles(IEnumerable<Tile> tiles, TileSource tileSource, string cacheName, IProgress<double> progress);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Cancels a potentially ongoing tile loading task.
|
/// Cancels a potentially ongoing tile loading task.
|
||||||
|
|
@ -115,11 +70,11 @@ namespace MapControl
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static int MaxLoadTasks { get; set; } = 4;
|
public static int MaxLoadTasks { get; set; } = 4;
|
||||||
|
|
||||||
private readonly Queue<ITile> tileQueue = new();
|
private readonly Queue<Tile> tileQueue = new();
|
||||||
private int tileCount;
|
private int tileCount;
|
||||||
private int taskCount;
|
private int taskCount;
|
||||||
|
|
||||||
public void BeginLoadTiles(IEnumerable<ITile> tiles, ITileSource tileSource, string cacheName, IProgress<double> progress)
|
public void BeginLoadTiles(IEnumerable<Tile> tiles, TileSource tileSource, string cacheName, IProgress<double> progress)
|
||||||
{
|
{
|
||||||
if (Cache == null || !tileSource.Cacheable)
|
if (Cache == null || !tileSource.Cacheable)
|
||||||
{
|
{
|
||||||
|
|
@ -158,9 +113,9 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadTilesFromQueue(ITileSource tileSource, string cacheName, IProgress<double> progress)
|
private async Task LoadTilesFromQueue(TileSource tileSource, string cacheName, IProgress<double> progress)
|
||||||
{
|
{
|
||||||
bool TryDequeueTile(out ITile tile)
|
bool TryDequeueTile(out Tile tile)
|
||||||
{
|
{
|
||||||
lock (tileQueue)
|
lock (tileQueue)
|
||||||
{
|
{
|
||||||
|
|
@ -178,7 +133,7 @@ namespace MapControl
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (TryDequeueTile(out ITile tile))
|
while (TryDequeueTile(out Tile tile))
|
||||||
{
|
{
|
||||||
tile.IsPending = false;
|
tile.IsPending = false;
|
||||||
|
|
||||||
|
|
@ -218,7 +173,7 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<byte[]> LoadCachedBuffer(ITile tile, Uri uri, string cacheName)
|
private static async Task<byte[]> LoadCachedBuffer(Tile tile, Uri uri, string cacheName)
|
||||||
{
|
{
|
||||||
var extension = Path.GetExtension(uri.LocalPath).ToLower();
|
var extension = Path.GetExtension(uri.LocalPath).ToLower();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,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<ITile> tiles, string cacheName)
|
protected void BeginLoadTiles(IEnumerable<Tile> tiles, string cacheName)
|
||||||
{
|
{
|
||||||
if (TileSource != null && tiles != null && tiles.Any(tile => tile.IsPending))
|
if (TileSource != null && tiles != null && tiles.Any(tile => tile.IsPending))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,41 @@ namespace MapControl
|
||||||
#else
|
#else
|
||||||
[System.ComponentModel.TypeConverter(typeof(TileSourceConverter))]
|
[System.ComponentModel.TypeConverter(typeof(TileSourceConverter))]
|
||||||
#endif
|
#endif
|
||||||
public class TileSource : ITileSource
|
public abstract class TileSource
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether tile images from this source should be cached.
|
||||||
|
/// </summary>
|
||||||
|
public abstract bool Cacheable { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the image Uri for the specified zoom level and tile indices.
|
||||||
|
/// </summary>
|
||||||
|
public abstract Uri GetUri(int zoomLevel, int column, int row);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads a tile image whithout caching.
|
||||||
|
/// </summary>
|
||||||
|
public abstract Task<ImageSource> LoadImageAsync(int zoomLevel, int column, int row);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads a cacheable tile image from an encoded frame buffer.
|
||||||
|
/// </summary>
|
||||||
|
public virtual Task<ImageSource> LoadImageAsync(byte[] buffer)
|
||||||
|
{
|
||||||
|
return ImageLoader.LoadImageAsync(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a TileSource instance from an Uri template string.
|
||||||
|
/// </summary>
|
||||||
|
public static TileSource Parse(string uriTemplate)
|
||||||
|
{
|
||||||
|
return new UriTileSource { UriTemplate = uriTemplate };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UriTileSource : TileSource
|
||||||
{
|
{
|
||||||
private string uriTemplate;
|
private string uriTemplate;
|
||||||
|
|
||||||
|
|
@ -44,9 +78,9 @@ namespace MapControl
|
||||||
|
|
||||||
public string[] Subdomains { get; set; }
|
public string[] Subdomains { get; set; }
|
||||||
|
|
||||||
public bool Cacheable => UriTemplate != null && UriTemplate.StartsWith("http");
|
public override bool Cacheable => UriTemplate != null && UriTemplate.StartsWith("http");
|
||||||
|
|
||||||
public virtual Uri GetUri(int zoomLevel, int column, int row)
|
public override Uri GetUri(int zoomLevel, int column, int row)
|
||||||
{
|
{
|
||||||
Uri uri = null;
|
Uri uri = null;
|
||||||
|
|
||||||
|
|
@ -69,33 +103,20 @@ namespace MapControl
|
||||||
return uri;
|
return uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Task<ImageSource> LoadImageAsync(int zoomLevel, int column, int row)
|
public override Task<ImageSource> LoadImageAsync(int zoomLevel, int column, int row)
|
||||||
{
|
{
|
||||||
var uri = GetUri(zoomLevel, column, row);
|
var uri = GetUri(zoomLevel, column, row);
|
||||||
|
|
||||||
return uri != null ? ImageLoader.LoadImageAsync(uri) : Task.FromResult((ImageSource)null);
|
return uri != null ? ImageLoader.LoadImageAsync(uri) : Task.FromResult((ImageSource)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Task<ImageSource> LoadImageAsync(byte[] buffer)
|
|
||||||
{
|
|
||||||
return ImageLoader.LoadImageAsync(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return UriTemplate;
|
return UriTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a TileSource instance from an Uri template string.
|
|
||||||
/// </summary>
|
|
||||||
public static TileSource Parse(string uriTemplate)
|
|
||||||
{
|
|
||||||
return new TileSource { UriTemplate = uriTemplate };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TmsTileSource : TileSource
|
public class TmsTileSource : UriTileSource
|
||||||
{
|
{
|
||||||
public override Uri GetUri(int zoomLevel, int column, int row)
|
public override Uri GetUri(int zoomLevel, int column, int row)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ namespace MapControl
|
||||||
|
|
||||||
public TileMatrix TileMatrix { get; private set; }
|
public TileMatrix TileMatrix { get; private set; }
|
||||||
|
|
||||||
public TileCollection Tiles { get; private set; } = [];
|
public ImageTileList Tiles { get; private set; } = [];
|
||||||
|
|
||||||
public void UpdateRenderTransform(ViewTransform viewTransform)
|
public void UpdateRenderTransform(ViewTransform viewTransform)
|
||||||
{
|
{
|
||||||
|
|
@ -85,7 +85,7 @@ namespace MapControl
|
||||||
|
|
||||||
TileMatrix = new TileMatrix(TileMatrix.ZoomLevel, xMin, yMin, xMax, yMax);
|
TileMatrix = new TileMatrix(TileMatrix.ZoomLevel, xMin, yMin, xMax, yMax);
|
||||||
|
|
||||||
var tiles = new TileCollection();
|
var tiles = new ImageTileList();
|
||||||
tiles.FillMatrix(Tiles, TileMatrix.ZoomLevel, xMin, yMin, xMax, yMax, WmtsTileMatrix.MatrixWidth);
|
tiles.FillMatrix(Tiles, TileMatrix.ZoomLevel, xMin, yMin, xMax, yMax, WmtsTileMatrix.MatrixWidth);
|
||||||
|
|
||||||
Tiles = tiles;
|
Tiles = tiles;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ using System.Text;
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
public class WmtsTileSource : TileSource
|
public class WmtsTileSource : UriTileSource
|
||||||
{
|
{
|
||||||
public WmtsTileMatrixSet TileMatrixSet { get; set; }
|
public WmtsTileMatrixSet TileMatrixSet { get; set; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,12 @@ using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
public partial class Tile
|
public class ImageTile(int zoomLevel, int x, int y, int columnCount)
|
||||||
|
: Tile(zoomLevel, x, y, columnCount)
|
||||||
{
|
{
|
||||||
public async Task LoadImageAsync(Func<Task<ImageSource>> loadImageFunc)
|
public Image Image { get; } = new Image { Stretch = Stretch.Fill };
|
||||||
|
|
||||||
|
public override async Task LoadImageAsync(Func<Task<ImageSource>> loadImageFunc)
|
||||||
{
|
{
|
||||||
var image = await loadImageFunc().ConfigureAwait(false);
|
var image = await loadImageFunc().ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -3,12 +3,14 @@ using System.Threading.Tasks;
|
||||||
#if UWP
|
#if UWP
|
||||||
using Windows.UI.Core;
|
using Windows.UI.Core;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Media;
|
using Windows.UI.Xaml.Media;
|
||||||
using Windows.UI.Xaml.Media.Animation;
|
using Windows.UI.Xaml.Media.Animation;
|
||||||
using Windows.UI.Xaml.Media.Imaging;
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
#else
|
#else
|
||||||
using Microsoft.UI.Dispatching;
|
using Microsoft.UI.Dispatching;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Microsoft.UI.Xaml.Media;
|
||||||
using Microsoft.UI.Xaml.Media.Animation;
|
using Microsoft.UI.Xaml.Media.Animation;
|
||||||
using Microsoft.UI.Xaml.Media.Imaging;
|
using Microsoft.UI.Xaml.Media.Imaging;
|
||||||
|
|
@ -16,9 +18,12 @@ using Microsoft.UI.Xaml.Media.Imaging;
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
public partial class Tile
|
public class ImageTile(int zoomLevel, int x, int y, int columnCount)
|
||||||
|
: Tile(zoomLevel, x, y, columnCount)
|
||||||
{
|
{
|
||||||
public async Task LoadImageAsync(Func<Task<ImageSource>> loadImageFunc)
|
public Image Image { get; } = new Image { Stretch = Stretch.Fill };
|
||||||
|
|
||||||
|
public override async Task LoadImageAsync(Func<Task<ImageSource>> loadImageFunc)
|
||||||
{
|
{
|
||||||
var tcs = new TaskCompletionSource<object>();
|
var tcs = new TaskCompletionSource<object>();
|
||||||
|
|
||||||
Loading…
Reference in a new issue