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);
        }
示例#2
0
        private static async Task LoadCachedTileAsync(Tile tile, Uri uri, string cacheKey)
        {
            var cacheItem = await GetCacheAsync(cacheKey).ConfigureAwait(false);

            var buffer = cacheItem?.Buffer;

            if (cacheItem == null || cacheItem.Expiration < DateTime.UtcNow)
            {
                var response = await ImageLoader.GetHttpResponseAsync(uri).ConfigureAwait(false);

                if (response != null)         // download succeeded
                {
                    buffer = response.Buffer; // may be null or empty when no tile available, but still be cached

                    await SetCacheAsync(cacheKey, buffer, GetExpiration(response.MaxAge)).ConfigureAwait(false);
                }
            }

            if (buffer != null && buffer.Length > 0)
            {
                var image = await ImageLoader.LoadImageAsync(buffer).ConfigureAwait(false);

                await tile.Image.Dispatcher.InvokeAsync(() => tile.SetImage(image));
            }
        }
示例#3
0
        private async Task LoadTileImageAsync(Tile tile, IBuffer buffer)
        {
            var tcs = new TaskCompletionSource <object>();

            using (var stream = new InMemoryRandomAccessStream())
            {
                await stream.WriteAsync(buffer);

                stream.Seek(0);

                await tile.Image.Dispatcher.RunAsync(CoreDispatcherPriority.Low, async() =>
                {
                    try
                    {
                        tile.SetImage(await ImageLoader.LoadImageAsync(stream));
                        tcs.SetResult(null);
                    }
                    catch (Exception ex)
                    {
                        tcs.SetException(ex);
                    }
                });
            }

            await tcs.Task;
        }
        private static async Task LoadCachedTile(Tile tile, Uri uri, string cacheKey)
        {
            var cacheItem = Cache.Get(cacheKey) as Tuple <byte[], DateTime>;
            var buffer    = cacheItem?.Item1;

            if (cacheItem == null || cacheItem.Item2 < DateTime.UtcNow)
            {
                var response = await ImageLoader.GetHttpResponseAsync(uri).ConfigureAwait(false);

                if (response != null)         // download succeeded
                {
                    buffer = response.Buffer; // may be null or empty when no tile available, but still be cached

                    cacheItem = Tuple.Create(buffer, GetExpiration(response.MaxAge));

                    Cache.Set(cacheKey, cacheItem, new CacheItemPolicy {
                        AbsoluteExpiration = cacheItem.Item2
                    });
                }
            }
            //else System.Diagnostics.Debug.WriteLine($"Cached: {cacheKey}");

            if (buffer != null && buffer.Length > 0)
            {
                var image = await ImageLoader.LoadImageAsync(buffer).ConfigureAwait(false);

                await tile.Image.Dispatcher.InvokeAsync(() => tile.SetImage(image));
            }
        }
        private static Task SetTileImage(Tile tile, Func <Task <ImageSource> > loadImageFunc)
        {
            var tcs = new TaskCompletionSource();

            async void callback()
            {
                try
                {
                    tile.SetImage(await loadImageFunc());
                    tcs.TrySetResult();
                }
                catch (Exception ex)
                {
                    tcs.TrySetException(ex);
                }
            }

            if (!tile.Image.DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, callback))
            {
                tile.Pending = true;
                tcs.TrySetResult();
            }

            return(tcs.Task);
        }
示例#6
0
        private async Task SetTileImageAsync(Tile tile, IBuffer buffer)
        {
            var tcs = new TaskCompletionSource <object>();

            using (var stream = new InMemoryRandomAccessStream())
            {
                await stream.WriteAsync(buffer);

                await stream.FlushAsync(); // necessary?

                stream.Seek(0);

                await tile.Image.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
                {
                    try
                    {
                        var bitmapImage = new BitmapImage();
                        await bitmapImage.SetSourceAsync(stream);

                        tile.SetImage(bitmapImage);
                        tcs.SetResult(null);
                    }
                    catch (Exception ex)
                    {
                        tcs.SetException(ex);
                    }
                });
            }

            await tcs.Task;
        }
示例#7
0
        private static async Task SetTileImageAsync(Tile tile, Func <Task <ImageSource> > loadImageFunc)
        {
            var tcs = new TaskCompletionSource <object>();

            await tile.Image.Dispatcher.RunAsync(CoreDispatcherPriority.Low, async() =>
            {
                try
                {
                    var image = await loadImageFunc();

                    if (image != null)
                    {
                        tile.SetImage(image);
                    }

                    tcs.SetResult(null);
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            });

            await tcs.Task.ConfigureAwait(false);
        }
示例#8
0
        private void UpdateTiles()
        {
            var newTiles = new List <Tile>();

            if (parentMap != null && TileGrid != null && TileSource != null)
            {
                var maxZoomLevel = Math.Min(TileGrid.ZoomLevel, MaxZoomLevel);
                var minZoomLevel = MinZoomLevel;

                if (minZoomLevel < maxZoomLevel && parentMap.MapLayer != this)
                {
                    minZoomLevel = maxZoomLevel; // do not load lower level tiles if this is note a "base" layer
                }

                for (var z = minZoomLevel; z <= maxZoomLevel; z++)
                {
                    var tileSize = 1 << (TileGrid.ZoomLevel - z);
                    var x1       = (int)Math.Floor((double)TileGrid.XMin / tileSize); // may be negative
                    var x2       = TileGrid.XMax / tileSize;
                    var y1       = Math.Max(TileGrid.YMin / tileSize, 0);
                    var y2       = Math.Min(TileGrid.YMax / 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)
                                {
                                    tile.SetImage(equivalentTile.Image.Source, false); // no fade-in animation
                                }
                            }

                            newTiles.Add(tile);
                        }
                    }
                }
            }

            Tiles = newTiles;

            Children.Clear();

            foreach (var tile in Tiles)
            {
                Children.Add(tile.Image);
            }

            TileImageLoader.LoadTilesAsync(this);
        }
示例#9
0
        private void SetTiles()
        {
            int maxZoomLevel;

            if (TileSource == null ||
                TileMatrix == null ||
                (maxZoomLevel = Math.Min(TileMatrix.ZoomLevel, MaxZoomLevel)) < MinZoomLevel)
            {
                Tiles.Clear();
            }
            else
            {
                var newTiles     = new List <Tile>();
                var minZoomLevel = maxZoomLevel;

                if (this == ParentMap.MapLayer) // load background tiles
                {
                    minZoomLevel = Math.Max(TileMatrix.ZoomLevel - MaxBackgroundLevels, MinZoomLevel);
                }

                var oldTiles = Tiles.Where(t => t.ZoomLevel >= minZoomLevel && t.ZoomLevel <= maxZoomLevel).ToList();

                Tiles.Clear();

                for (var z = minZoomLevel; z <= maxZoomLevel; z++)
                {
                    var tileSize = 1 << (TileMatrix.ZoomLevel - z);
                    var x1       = (int)Math.Floor((double)TileMatrix.XMin / tileSize); // may be negative
                    var x2       = TileMatrix.XMax / tileSize;
                    var y1       = Math.Max(TileMatrix.YMin / tileSize, 0);
                    var y2       = Math.Min(TileMatrix.YMax / tileSize, (1 << z) - 1);

                    for (var y = y1; y <= y2; y++)
                    {
                        for (var x = x1; x <= x2; x++)
                        {
                            var tile = oldTiles.FirstOrDefault(t => t.ZoomLevel == z && t.X == x && t.Y == y);

                            if (tile == null)
                            {
                                tile = new Tile(z, x, y);

                                var equivalentTile = oldTiles.FirstOrDefault(
                                    t => t.ZoomLevel == z && t.XIndex == tile.XIndex && t.Y == y && !t.Pending);

                                if (equivalentTile != null)
                                {
                                    tile.SetImage(equivalentTile.Image.Source, false); // no fade-in animation
                                }
                            }

                            Tiles.Add(tile);
                        }
                    }
                }
            }
        }
示例#10
0
        private void UpdateTiles()
        {
            var newTiles = new List <Tile>();

            if (parentMap != null && TileGrid != null && TileSource != null)
            {
                var maxZoomLevel = Math.Min(TileGrid.ZoomLevel, MaxZoomLevel);
                var minZoomLevel = parentMap.MapLayer == this ? MinZoomLevel : maxZoomLevel; // load background tiles only if this is the base layer

                for (var z = minZoomLevel; z <= maxZoomLevel; z++)
                {
                    var tileSize = 1 << (TileGrid.ZoomLevel - z);
                    var x1       = (int)Math.Floor((double)TileGrid.XMin / tileSize); // may be negative
                    var x2       = TileGrid.XMax / tileSize;
                    var y1       = Math.Max(TileGrid.YMin / tileSize, 0);
                    var y2       = Math.Min(TileGrid.YMax / 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)
                                {
                                    tile.SetImage(equivalentTile.Image.Source, false); // do not animate to avoid flicker when crossing 180° longitude
                                }
                            }

                            newTiles.Add(tile);
                        }
                    }
                }
            }

            Tiles = newTiles;

            Children.Clear();

            foreach (var tile in Tiles)
            {
                Children.Add(tile.Image);
            }

            var task = TileImageLoader.LoadTilesAsync(this);
        }
示例#11
0
        protected void SelectTiles()
        {
            var newTiles = new List <Tile>();

            if (TileGrid != null && parentMap != null && TileSource != null)
            {
                var maxZoomLevel = Math.Min(TileGrid.ZoomLevel, 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 << (TileGrid.ZoomLevel - z);
                    var x1       = (int)Math.Floor((double)TileGrid.XMin / tileSize); // may be negative
                    var x2       = TileGrid.XMax / tileSize;
                    var y1       = Math.Max(TileGrid.YMin / tileSize, 0);
                    var y2       = Math.Min(TileGrid.YMax / 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;
        }
示例#12
0
        private async Task <bool> LoadImageFromHttpResponse(HttpResponseMessage response, Tile tile, string cacheKey)
        {
            string tileInfo;

            if (response.Headers.TryGetValue("X-VE-Tile-Info", out tileInfo) && tileInfo == "no-tile") // set by Bing Maps
            {
                tile.SetImage(null);
                return(true);
            }

            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, 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 expiration = DefaultCacheExpiration;

                    if (response.Headers.CacheControl.MaxAge.HasValue)
                    {
                        expiration = response.Headers.CacheControl.MaxAge.Value;

                        if (expiration < MinimumCacheExpiration)
                        {
                            expiration = MinimumCacheExpiration;
                        }
                    }

                    await Cache.SetAsync(cacheKey, buffer, DateTime.UtcNow.Add(expiration));
                }

                return(loaded);
            }
        }
        private async Task LoadTileImageAsync(TileSource tileSource, Tile tile)
        {
            tile.Pending = false;

            try
            {
                var imageSource = await tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel);

                if (imageSource != null)
                {
                    tile.SetImage(imageSource);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("TileImageLoader: {0}/{1}/{2}: {3}", tile.ZoomLevel, tile.XIndex, tile.Y, ex.Message);
            }
        }
示例#14
0
        private async Task LoadTileImageAsync(Tile tile, TileSource tileSource)
        {
            var tcs = new TaskCompletionSource <object>();

            await tile.Image.Dispatcher.RunAsync(CoreDispatcherPriority.Low, async() =>
            {
                try
                {
                    tile.SetImage(await tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel));
                    tcs.SetResult(null);
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            });

            await tcs.Task;
        }
示例#15
0
        private static async Task SetTileImageAsync(Tile tile, Func <Task <ImageSource> > loadImage)
        {
            var tcs = new TaskCompletionSource <object>();

            await tile.Image.Dispatcher.RunAsync(CoreDispatcherPriority.Low, async() =>
            {
                try
                {
                    tile.SetImage(await loadImage());
                    tcs.SetResult(null);
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            });

            await tcs.Task.ConfigureAwait(false); // wait until image loading in the UI thread is completed
        }
        private static async Task SetTileImage(Tile tile, Func <Task <ImageSource> > loadImageFunc)
        {
            var tcs = new TaskCompletionSource <object>();

            async void callback()
            {
                try
                {
                    tile.SetImage(await loadImageFunc());
                    tcs.TrySetResult(null);
                }
                catch (Exception ex)
                {
                    tcs.TrySetException(ex);
                }
            }

            await tile.Image.Dispatcher.RunAsync(CoreDispatcherPriority.Low, callback);

            await tcs.Task.ConfigureAwait(false);
        }
        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;
        }
示例#18
0
        private async Task SetTileImageAsync(Tile tile, MemoryStream stream)
        {
            var imageSource = BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);

            await tile.Image.Dispatcher.InvokeAsync(() => tile.SetImage(imageSource));
        }
示例#19
0
        private static async Task LoadTileAsync(Tile tile, TileSource tileSource)
        {
            var image = await tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel).ConfigureAwait(false);

            await tile.Image.Dispatcher.InvokeAsync(() => tile.SetImage(image));
        }
示例#20
0
        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 static void SetTileImageAsync(Tile tile, ImageSource image)
 {
     tile.Image.Dispatcher.InvokeAsync(() => tile.SetImage(image));
 }
示例#22
0
        private void UpdateTiles()
        {
            var newTiles = new List <Tile>();

            if (ParentMap != null && TileMatrix != null && TileSource != null)
            {
                var maxZoomLevel = Math.Min(TileMatrix.ZoomLevel, MaxZoomLevel);

                if (maxZoomLevel >= MinZoomLevel)
                {
                    var minZoomLevel = maxZoomLevel;

                    if (this == ParentMap.MapLayer) // load background tiles
                    {
                        minZoomLevel = Math.Max(TileMatrix.ZoomLevel - MaxBackgroundLevels, MinZoomLevel);
                    }

                    for (var z = minZoomLevel; z <= maxZoomLevel; z++)
                    {
                        var tileSize = 1 << (TileMatrix.ZoomLevel - z);
                        var x1       = (int)Math.Floor((double)TileMatrix.XMin / tileSize); // may be negative
                        var x2       = TileMatrix.XMax / tileSize;
                        var y1       = Math.Max(TileMatrix.YMin / tileSize, 0);
                        var y2       = Math.Min(TileMatrix.YMax / 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)
                                    {
                                        tile.SetImage(equivalentTile.Image.Source, false); // no fade-in animation
                                    }
                                }

                                newTiles.Add(tile);
                            }
                        }
                    }
                }
            }

            Tiles = newTiles;

            Children.Clear();

            foreach (var tile in Tiles)
            {
                Children.Add(tile.Image);
            }

            TileImageLoader.LoadTilesAsync(Tiles, TileSource, SourceName);
        }