/// <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 //Bing Maps 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); //Google Maps //string requestUri = string.Format( // "http://maps.googleapis.com/maps/api/staticmap?center={0},%20{1}&zoom=17&size=640x400&sensor=false", // centerCoordinate.Latitude, centerCoordinate.Longitude); //string requestUri = string.Format("http://maps.googleapis.com/maps/api/staticmap?center={0:F5},{1:F1}&zoom=11&size=600x400&sensor=false",36.88333, -76.3); //string requestUri = "http://maps.googleapis.com/maps/api/staticmap?center=36.88333,-76.3&zoom=11&size=640x400&sensor=false"; //string blah = string.Format("test: {0}", centerCoordinate.Latitude); //string blah2 = string.Format("test: {0:F}", centerCoordinate.Latitude); //string blah3 = string.Format("test: {0:F2}", centerCoordinate.Latitude); //string blah4 = string.Format("test: {0:F3}", centerCoordinate.Latitude); // B1 = 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(DownloadDataCompletedEventArgs e, TileInformation tileInformation) { //Generate a memory stream from the byte array; MemoryStream stream = new MemoryStream(e.Result); //GraphicsDevice graphicsDevie // Read the image from the stream Texture2D image = Texture2D.FromStream(SpriteBatch.GraphicsDevice, stream); tileInformation.Image = image; }
/// <summary> /// Place images received from the REST service in the proper place in the active tile cube, and save them to /// the cache. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void TileServerRequestCompleted(object sender, DownloadDataCompletedEventArgs e) { pendingRequestCount--; TileInformation requestInformation = (TileInformation)e.UserState; // Do not handle the event if the request was cancelled if (requestInformation.IsRequestCancelled) { requestInformation.MarkImageRequestCancelled(); if (pendingRequestCount == 0) { MoveToNextPhase(); } return; } bool imageAvailable = e.Error == null ? true : false; // Clean the old image, if any requestInformation.Dispose(true); try { if (imageAvailable == true) { SetTileImage(e, requestInformation); } } catch (Exception) { imageAvailable = false; Console.WriteLine("image not available Error exception"); } if (imageAvailable == false) { Console.WriteLine("image not available bad key?"); requestInformation.Image = unavailableImage; } requestInformation.MarkImageRequestCompleted(); // If all asynchronous calls returned, we can move to the next phase if (pendingRequestCount == 0) { MoveToNextPhase(); } }
/// <summary> /// Cancels all currently ongoing tile image requests, and disposes of all current tile images. /// </summary> private void CancelActiveRequestsAndResetImages() { for (int xIndex = 0; xIndex < ActiveTilePlaneSize; xIndex++) { for (int yIndex = 0; yIndex < ActiveTilePlaneSize; yIndex++) { TileInformation cellInformation = activeTilePlane[xIndex, yIndex]; if (cellInformation != null) { cellInformation.Dispose(); } } } }
/// <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); 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; try { tileCenterGeoCoordinate = TileSystem.PixelXYToLatLong(tileCenterPixelXY, zoomLevel); GetImageFromServer(cellInformation, tileCenterGeoCoordinate, zoomLevel, ViewType); } catch (ArgumentOutOfRangeException) { cellInformation.Image = unavailableImage; } } } }