/// <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; } } } } }