diff --git a/MapControl/Shared/MapBase.cs b/MapControl/Shared/MapBase.cs
index f901530c..fa4d1652 100644
--- a/MapControl/Shared/MapBase.cs
+++ b/MapControl/Shared/MapBase.cs
@@ -31,8 +31,6 @@ namespace MapControl
///
public partial class MapBase : MapPanel
{
- private const double MaximumZoomLevel = 22d;
-
public static TimeSpan ImageFadeDuration { get; set; } = TimeSpan.FromSeconds(0.1);
public static readonly DependencyProperty MapLayerProperty = DependencyProperty.Register(
@@ -321,6 +319,7 @@ namespace MapControl
if (rotation != 0d)
{
var heading = (((Heading + rotation) % 360d) + 360d) % 360d;
+
SetValueInternal(HeadingProperty, heading);
SetValueInternal(TargetHeadingProperty, heading);
}
@@ -328,6 +327,7 @@ namespace MapControl
if (scale != 1d)
{
var zoomLevel = Math.Min(Math.Max(ZoomLevel + Math.Log(scale, 2d), MinZoomLevel), MaxZoomLevel);
+
SetValueInternal(ZoomLevelProperty, zoomLevel);
SetValueInternal(TargetZoomLevelProperty, zoomLevel);
}
@@ -437,17 +437,16 @@ namespace MapControl
private void AdjustCenterProperty(DependencyProperty property, ref Location center)
{
- if (center == null)
- {
- center = new Location();
- SetValueInternal(property, center);
- }
- else if (center.Longitude < -180d || center.Longitude > 180d ||
+ if (center == null ||
+ center.Longitude < -180d || center.Longitude > 180d ||
center.Latitude < -MapProjection.MaxLatitude || center.Latitude > MapProjection.MaxLatitude)
{
- center = new Location(
- Math.Min(Math.Max(center.Latitude, -MapProjection.MaxLatitude), MapProjection.MaxLatitude),
- Location.NormalizeLongitude(center.Longitude));
+ center = (center == null)
+ ? new Location()
+ : new Location(
+ Math.Min(Math.Max(center.Latitude, -MapProjection.MaxLatitude), MapProjection.MaxLatitude),
+ Location.NormalizeLongitude(center.Longitude));
+
SetValueInternal(property, center);
}
}
@@ -519,6 +518,7 @@ namespace MapControl
if (minZoomLevel < 0d || minZoomLevel > MaxZoomLevel)
{
minZoomLevel = Math.Min(Math.Max(minZoomLevel, 0d), MaxZoomLevel);
+
SetValueInternal(MinZoomLevelProperty, minZoomLevel);
}
@@ -530,9 +530,10 @@ namespace MapControl
private void MaxZoomLevelPropertyChanged(double maxZoomLevel)
{
- if (maxZoomLevel < MinZoomLevel || maxZoomLevel > MaximumZoomLevel)
+ if (maxZoomLevel < MinZoomLevel)
{
- maxZoomLevel = Math.Min(Math.Max(maxZoomLevel, MinZoomLevel), MaximumZoomLevel);
+ maxZoomLevel = MinZoomLevel;
+
SetValueInternal(MaxZoomLevelProperty, maxZoomLevel);
}
@@ -547,6 +548,7 @@ namespace MapControl
if (zoomLevel < MinZoomLevel || zoomLevel > MaxZoomLevel)
{
zoomLevel = Math.Min(Math.Max(zoomLevel, MinZoomLevel), MaxZoomLevel);
+
SetValueInternal(property, zoomLevel);
}
}
@@ -611,6 +613,7 @@ namespace MapControl
if (heading < 0d || heading > 360d)
{
heading = ((heading % 360d) + 360d) % 360d;
+
SetValueInternal(property, heading);
}
}
@@ -684,7 +687,9 @@ namespace MapControl
private void SetValueInternal(DependencyProperty property, object value)
{
internalPropertyChange = true;
+
SetValue(property, value);
+
internalPropertyChange = false;
}
diff --git a/MapControl/Shared/TileImageLoader.cs b/MapControl/Shared/TileImageLoader.cs
index f51315cd..bb43b610 100644
--- a/MapControl/Shared/TileImageLoader.cs
+++ b/MapControl/Shared/TileImageLoader.cs
@@ -30,11 +30,10 @@ namespace MapControl
public static TimeSpan DefaultCacheExpiration { get; set; } = TimeSpan.FromDays(1);
///
- /// Format string for creating cache keys from the cacheName argument passed to LoadTilesAsync,
- /// the ZoomLevel, XIndex, and Y properties of a Tile, and the image file extension.
- /// The default value is "{0}/{1}/{2}/{3}{4}".
+ /// Maximum expiration time for cached tile images. A transmitted expiration time
+ /// that exceeds this value is ignored. The default value is ten days.
///
- public static string CacheKeyFormat { get; set; } = "{0}/{1}/{2}/{3}{4}";
+ public static TimeSpan MaxCacheExpiration { get; set; } = TimeSpan.FromDays(10);
private class TileQueue : ConcurrentStack
@@ -51,7 +50,7 @@ namespace MapControl
}
private readonly TileQueue tileQueue = new TileQueue();
- private Func loadTile;
+ private Func loadTileFunc;
private int taskCount;
///
@@ -72,11 +71,11 @@ namespace MapControl
tileSource.UriFormat.StartsWith("http") &&
!string.IsNullOrEmpty(cacheName))
{
- loadTile = tile => LoadCachedTileAsync(tile, tileSource, cacheName);
+ loadTileFunc = tile => LoadCachedTileAsync(tile, tileSource, cacheName);
}
else
{
- loadTile = tile => LoadTileAsync(tile, tileSource);
+ loadTileFunc = tile => LoadTileAsync(tile, tileSource);
}
tileQueue.Enqueue(tiles);
@@ -98,7 +97,7 @@ namespace MapControl
try
{
- await loadTile(tile).ConfigureAwait(false);
+ await loadTileFunc(tile).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -122,7 +121,7 @@ namespace MapControl
extension = ".jpg";
}
- var cacheKey = string.Format(CacheKeyFormat, cacheName, tile.ZoomLevel, tile.XIndex, tile.Y, extension);
+ var cacheKey = string.Format("{0}/{1}/{2}/{3}{4}", cacheName, tile.ZoomLevel, tile.XIndex, tile.Y, extension);
await LoadCachedTileAsync(tile, uri, cacheKey).ConfigureAwait(false);
}
@@ -130,7 +129,16 @@ namespace MapControl
private static DateTime GetExpiration(TimeSpan? maxAge)
{
- return DateTime.UtcNow.Add(maxAge ?? DefaultCacheExpiration);
+ if (!maxAge.HasValue)
+ {
+ maxAge = DefaultCacheExpiration;
+ }
+ else if (maxAge.Value > MaxCacheExpiration)
+ {
+ maxAge = MaxCacheExpiration;
+ }
+
+ return DateTime.UtcNow.Add(maxAge.Value);
}
}
}
diff --git a/MapControl/WPF/ImageFileCache.WPF.cs b/MapControl/WPF/ImageFileCache.WPF.cs
index fb528554..2d9016d1 100644
--- a/MapControl/WPF/ImageFileCache.WPF.cs
+++ b/MapControl/WPF/ImageFileCache.WPF.cs
@@ -169,7 +169,9 @@ namespace MapControl.Caching
string path;
- if (imageCacheItem.Buffer != null && imageCacheItem.Buffer.Length > 0 && (path = GetPath(key)) != null)
+ if (imageCacheItem.Buffer != null &&
+ imageCacheItem.Buffer.Length > 0 &&
+ (path = GetPath(key)) != null)
{
try
{
@@ -282,7 +284,7 @@ namespace MapControl.Caching
{
try
{
- return Path.Combine(rootDirectory, Path.Combine(key.Split('\\', '/', ',', ':', ';')));
+ return Path.Combine(rootDirectory, Path.Combine(key.Split('/', ':', ';', ',')));
}
catch (Exception ex)
{
@@ -294,14 +296,15 @@ namespace MapControl.Caching
private async Task CleanRootDirectory()
{
- var deletedFileCount = 0;
-
foreach (var dir in new DirectoryInfo(rootDirectory).EnumerateDirectories())
{
- deletedFileCount += await CleanDirectory(dir).ConfigureAwait(false);
- }
+ var deletedFileCount = await CleanDirectory(dir).ConfigureAwait(false);
- Debug.WriteLine("ImageFileCache: Cleaned {0} files in {1}", deletedFileCount, rootDirectory);
+ if (deletedFileCount > 0)
+ {
+ Debug.WriteLine("ImageFileCache: Cleaned {0} files in {1}", deletedFileCount, dir);
+ }
+ }
}
private static async Task CleanDirectory(DirectoryInfo directory)