private async Task LoadCachedImage(TileLayer tileLayer, Tile tile, Uri uri, BitmapImage bitmap) { var cacheKey = string.Format(@"{0}\{1}\{2}\{3}{4}", tileLayer.SourceName, tile.ZoomLevel, tile.XIndex, tile.Y, Path.GetExtension(uri.LocalPath)); var buffer = await Cache.GetAsync(cacheKey) as IBuffer; if (buffer != null) { await LoadImageFromBuffer(buffer, bitmap); //Debug.WriteLine("Loaded cached image {0}", cacheKey); } else { DownloadAndCacheImage(uri, bitmap, cacheKey); } }
protected void SelectTiles() { var newTiles = new List<Tile>(); if (TileZoomLevel >= 0 && parentMap != null && TileSource != null) { var maxZoomLevel = Math.Min(TileZoomLevel, MaxZoomLevel); var minZoomLevel = MinZoomLevel; if (minZoomLevel < maxZoomLevel && this != parentMap.TileLayers.FirstOrDefault()) { // do not load background tiles if this is not the base layer minZoomLevel = maxZoomLevel; } for (var z = minZoomLevel; z <= maxZoomLevel; z++) { var tileSize = 1 << (TileZoomLevel - z); var x1 = (int)Math.Floor((double)TileRect.X / tileSize); // may be negative var x2 = (TileRect.X + TileRect.Width - 1) / tileSize; var y1 = Math.Max(TileRect.Y / tileSize, 0); var y2 = Math.Min((TileRect.Y + TileRect.Height - 1) / tileSize, (1 << z) - 1); for (var y = y1; y <= y2; y++) { for (var x = x1; x <= x2; x++) { var tile = Tiles.FirstOrDefault(t => t.ZoomLevel == z && t.X == x && t.Y == y); if (tile == null) { tile = new Tile(z, x, y); var equivalentTile = Tiles.FirstOrDefault( t => t.ZoomLevel == z && t.XIndex == tile.XIndex && t.Y == y && t.Image.Source != null); if (equivalentTile != null) { // do not animate to avoid flicker when crossing 180° tile.SetImage(equivalentTile.Image.Source, false); } } newTiles.Add(tile); } } } } Tiles = newTiles; }
private void SelectTiles() { var maxZoomLevel = Math.Min(zoomLevel, MaxZoomLevel); var minZoomLevel = maxZoomLevel; if (LoadLowerZoomLevels && Parent is TileContainer && ((TileContainer)Parent).TileLayers.FirstOrDefault() == this) { minZoomLevel = MinZoomLevel; } var newTiles = new List<Tile>(); for (var z = minZoomLevel; z <= maxZoomLevel; z++) { var tileSize = 1 << (zoomLevel - z); var x1 = (int)Math.Floor((double)grid.X / tileSize); // may be negative var x2 = (grid.X + grid.Width - 1) / tileSize; var y1 = Math.Max(grid.Y / tileSize, 0); var y2 = Math.Min((grid.Y + grid.Height - 1) / tileSize, (1 << z) - 1); for (var y = y1; y <= y2; y++) { for (var x = x1; x <= x2; x++) { var tile = tiles.FirstOrDefault(t => t.ZoomLevel == z && t.X == x && t.Y == y && t.Rotation == rotation); if (tile == null) { tile = new Tile(z, x, y, rotation); var equivalentTile = tiles.FirstOrDefault( t => t.Image.Source != null && t.ZoomLevel == z && t.XIndex == tile.XIndex && t.Y == y); if (equivalentTile != null) { // do not animate to avoid flicker when crossing date line tile.SetImageSource(equivalentTile.Image.Source, false, equivalentTile.Rotation != rotation); } } newTiles.Add(tile); } } } tiles = newTiles; }
public static string Key(string sourceName, Tile tile) { return string.Format("{0}/{1}/{2}/{3}/{4}", sourceName, tile.ZoomLevel, tile.XIndex, tile.Y, tile.Rotation); }
private static ImageSource LoadImage(ImageTileSource tileSource, Tile tile) { ImageSource image = null; try { image = tileSource.LoadImage(tile.XIndex, tile.Y, tile.ZoomLevel, tile.Rotation); } catch (Exception ex) { Trace.TraceWarning("Loading tile image failed: {0}", ex.Message); } return image; }
public PendingTile(Tile tile, ImageSource cachedImage) { Tile = tile; CachedImage = cachedImage; }
private static string TileKey(TileSource tileSource, Tile tile) { return string.Format("{0:X}/{1:X}/{2:X}/{3:X}", tileSource.GetHashCode(), tile.ZoomLevel, tile.XIndex, tile.Y); }
private static ImageSource LoadImage(ImageTileSource tileSource, Tile tile) { ImageSource image = null; try { image = tileSource.LoadImage(tile.XIndex, tile.Y, tile.ZoomLevel); } catch (Exception ex) { Debug.WriteLine("Loading tile image failed: {0}", (object)ex.Message); } return image; }
private static string CacheKey(string sourceName, Tile tile) { return string.IsNullOrEmpty(sourceName) ? null : string.Format("{0}/{1}/{2}/{3}", sourceName, tile.ZoomLevel, tile.XIndex, tile.Y); }
public PendingTile(Tile tile, Uri uri) { Tile = tile; Uri = uri; Image = new BitmapImage(); }
private async Task<bool> LoadImageFromStream(Tile tile, BitmapSource image, IRandomAccessStream stream) { var completion = new TaskCompletionSource<bool>(); var action = image.Dispatcher.RunAsync( CoreDispatcherPriority.Normal, async () => { try { await image.SetSourceAsync(stream); tile.SetImage(image, true, false); completion.SetResult(true); } catch (Exception ex) { Debug.WriteLine(ex.Message); tile.SetImage(null); completion.SetResult(false); } }); return await completion.Task; }
private async Task<bool> LoadImageFromHttpResponse(HttpResponseMessage response, Tile tile, BitmapSource image, string cacheKey) { using (var stream = new InMemoryRandomAccessStream()) { using (var content = response.Content) { await content.WriteToStreamAsync(stream); } await stream.FlushAsync(); stream.Seek(0); var loaded = await LoadImageFromStream(tile, image, stream); if (loaded && cacheKey != null) { var buffer = new Windows.Storage.Streams.Buffer((uint)stream.Size); stream.Seek(0); await stream.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.None); var maxAge = DefaultCacheExpiration; if (response.Headers.CacheControl.MaxAge.HasValue && response.Headers.CacheControl.MaxAge.Value < maxAge) { maxAge = response.Headers.CacheControl.MaxAge.Value; } await Cache.SetAsync(cacheKey, buffer, DateTime.UtcNow.Add(maxAge)); } return loaded; } }
private async Task<bool> DownloadImage(Tile tile, BitmapSource image, Uri uri, string cacheKey) { try { using (var httpClient = new HttpClient(new HttpBaseProtocolFilter { AllowAutoRedirect = false })) using (var response = await httpClient.GetAsync(uri)) { if (response.IsSuccessStatusCode) { return await LoadImageFromHttpResponse(response, tile, image, cacheKey); } Debug.WriteLine("{0}: ({1}) {2}", uri, (int)response.StatusCode, response.ReasonPhrase); } } catch (Exception ex) { Debug.WriteLine("{0}: {1}", uri, ex.Message); } return false; }