This class stores information about a tile
        /// <summary>
        /// Removes an image from tile list
        /// </summary>
        /// <param name="tileInfo">Image to be removed</param>
        private void RemoveImage(TileInfo tileInfo)
        {
            var animation = new DoubleAnimation();
            animation.From = 1.0;
            animation.To = 0.0;
            animation.Duration = TimeSpan.FromSeconds(0.1);

            var storyboard = new Storyboard();
            storyboard.Children.Add(animation);
            Storyboard.SetTarget(storyboard, tileInfo.TileImage);
            Storyboard.SetTargetProperty(storyboard, "Image.Opacity");
            storyboard.Begin();

            storyboard.Completed += (x, y) =>
            {
                this.Children.Remove(tileInfo.TileImage);
                this.notLoadedTiles.Remove(tileInfo);
                this.addedTiles.Remove(tileInfo);
            };
        }
        private void UpdateTile(TileInfo tileInfo)
        {
            if ((tileInfo.Zoom > (this.CurrentZoomLevel + 1))
                || (tileInfo.Zoom < (this.CurrentZoomLevel - 2)))
            {
                // Hide unused images
                this.RemoveImage(tileInfo);
            }

            var zoom = this.CurrentZoomLevel;
            var localZoom = Math.Pow(2, zoom);
            localZoom = Math.Pow(2, tileInfo.Zoom);

            var position = tileInfo.GetCoordinates(localZoom);
            Canvas.SetLeft(
                tileInfo.TileImage,
                (position.X + this.CurrentPosition.X)
                    * this.CurrentZoom * BaseZoom
                    + this.ActualWidth / 2);
            Canvas.SetTop(
                tileInfo.TileImage,
                (position.Y + this.CurrentPosition.Y)
                    * this.CurrentZoom * BaseZoom
                    + this.ActualHeight / 2);
            tileInfo.TileImage.Width = (this.CurrentZoom / localZoom) + 0.5;
            tileInfo.TileImage.Height = (this.CurrentZoom / localZoom) + 0.5;
        }
        /// <summary>
        /// Shows a specific tile
        /// </summary>
        /// <param name="tileX">X-Coordinate of tile</param>
        /// <param name="tileY">Y-Coordinate of tile</param>
        /// <param name="zoom">Zoomlevel of tile</param>
        /// <param name="visible">Flag whether tiles are visible</param>
        protected TileInfo ShowTile(int tileX, int tileY, int zoom)
        {
            // Shows if shown tile is in loadedtiles
            var found = this.addedTiles.FirstOrDefault(
                x => x.TileX == tileX && x.TileY == tileY && x.Zoom == zoom);

            if (found != null)
            {
                if (found.TileImage != null)
                {
                    if (zoom <= this.CurrentZoom &&
                        found.TileImage.Visibility == Windows.UI.Xaml.Visibility.Collapsed)
                    {
                        // Switch visibility flag
                        found.TileImage.Visibility = Windows.UI.Xaml.Visibility.Visible;
                    }
                }

                // Already loaded
                return found;
            }

            // Creates images if necessary
            var tileInfo = new TileInfo();
            tileInfo.TileX = tileX;
            tileInfo.TileY = tileY;
            tileInfo.Zoom = zoom;

            this.addedTiles.Add(tileInfo);
            this.notLoadedTiles.Add(tileInfo);
            this.TilesRetrieved++;

            return tileInfo;
        }