Contains information about a single map tile.
Inheritance: IDisposable
        /// <summary>
        /// Asynchronously gets a tile image from the Bing maps REST service.
        /// </summary>
        /// <param name="requestInformation">The tile information which is to handle the request and receive the 
        /// image.</param>        
        /// <param name="centerCoordinate">The geo-coordinate which should serve as the image center.</param>
        /// <param name="zoomLevel">The desired image zoom level.</param>
        /// <param name="viewType">The desired image view type.</param>
        void GetImageFromServer(TileInformation requestInformation, GeoCoordinate centerCoordinate, int zoomLevel,
            BingMapsViewType viewType)
        {
            // Build the request URI according to the parameters
            string requestUri = string.Format(
                "http://dev.virtualearth.net/REST/V1/Imagery/Map/{4}/{0},{1}/{2}?mapSize={5},{6}&key={3}",
                centerCoordinate.Latitude, centerCoordinate.Longitude, zoomLevel, BingMapKey, viewType,
                (int)tileDimensions.X, (int)tileDimensions.Y);
            //System.Diagnostics.Debug.WriteLine(requestUri);

            // Launch the request
            requestInformation.RequestImageAync(new Uri(requestUri, UriKind.Absolute));

            pendingRequestCount++;
        }
        /// <summary>
        /// Sets the image from the image stream contained in the supplied asynchronous as the image for the tile 
        /// represented by the supplied tile information. The image stream will be closed.
        /// </summary>
        /// <param name="e">Asynchronous read result which contains the image stream and is free of errors.</param>
        /// <param name="tileInformation">Tile information where the image is to be set.</param>
        private void SetTileImage(OpenReadCompletedEventArgs e, TileInformation tileInformation)
        {
            // Read the image from the stream
            Texture2D image = Texture2D.FromStream(SpriteBatch.GraphicsDevice, e.Result);

            e.Result.Seek(0, SeekOrigin.Begin);

            int imageByteCount = (int)e.Result.Length;

            byte[] imageBuffer = tileInformation.AsyncImageBuffer;

            // Resize the image buffer if it is too small
            if (imageByteCount > imageBuffer.Length)
            {
                Array.Resize<byte>(ref imageBuffer, imageByteCount);
            }

            e.Result.Read(imageBuffer, 0, imageByteCount);

            e.Result.Close();

            tileInformation.Image = image;

            string fileName = tileInformation.name + ".png";
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            using (var writeStream = new IsolatedStorageFileStream(fileName, FileMode.Create, store))
            //using (var writer = new StreamWriter(writeStream))
            {
                image.SaveAsPng(writeStream, image.Width, image.Height);
            }
        }
        /// <summary>
        /// Initializes the active tile plane by requesting images centered at the specified geo-coordinate.
        /// </summary>        
        /// <param name="centerCoordinate">The geo-coordinate which will serve as the center of the 
        /// middle tile.</param>
        private void GetActivePlaneImages(GeoCoordinate centerCoordinate)
        {
            Vector2 centerPixelXY = TileSystem.LatLongToPixelXY(centerCoordinate, zoomLevel);
            centerPixelXY.X = (int)(centerPixelXY.X / tileDimensions.X) * tileDimensions.X;
            centerPixelXY.Y = (int)(centerPixelXY.Y / tileDimensions.Y) * tileDimensions.Y;

            int planeCenterIndex = PlaneCenterIndex;

            for (int xIndex = 0; xIndex < ActiveTilePlaneSize; xIndex++)
            {
                int xDelta = xIndex - planeCenterIndex;

                for (int yIndex = 0; yIndex < ActiveTilePlaneSize; yIndex++)
                {
                    int yDelta = yIndex - planeCenterIndex;

                    TileInformation cellInformation = activeTilePlane[xIndex, yIndex];

                    // Initialize or clean the active tile cube cell
                    if (cellInformation == null)
                    {
                        cellInformation = new TileInformation(TileServerRequestCompleted);
                        activeTilePlane[xIndex, yIndex] = cellInformation;
                    }
                    else
                    {
                        cellInformation.Dispose();
                    }

                    // Calculate the center geo-coordinate for the current tile
                    Vector2 tileCenterPixelXY = centerPixelXY + tileDimensions * new Vector2(xDelta, yDelta);
                    GeoCoordinate tileCenterGeoCoordinate;

                    cellInformation.name = "" + zoomLevel + "_" + tileCenterPixelXY.X + "_" + tileCenterPixelXY.Y;
                    string fileName = cellInformation.name + ".png";

                    bool imageread = false;
                    try
                    {
                        using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                            if (store.FileExists(fileName))
                            {
                                using (var readStream = new IsolatedStorageFileStream(fileName, FileMode.Open, store))
                                //using (var reader = new StreamReader(readStream))
                                {
                                    try
                                    {
                                        cellInformation.Image = Texture2D.FromStream(SpriteBatch.GraphicsDevice, readStream);
                                        imageread = true;
                                    }
                                    catch (System.InvalidOperationException)
                                    {
                                    }
                                }
                            }
                    }
                    catch (IsolatedStorageException)
                    {
                    }
                    try
                    {
                        if (!imageread)
                        {
                            tileCenterGeoCoordinate = TileSystem.PixelXYToLatLong(tileCenterPixelXY, zoomLevel);
                            GetImageFromServer(cellInformation, tileCenterGeoCoordinate, zoomLevel, ViewType);
                            imageread = true;
                        }
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        if (!imageread)
                        {
                            cellInformation.Image = unavailableImage;
                            imageread = true;
                        }
                    }
                }
            }
        }