/// <summary> /// Override the getMesh function to get data from Bing's REST API /// </summary> /// <param name="x">Unity units in direction x from origin</param> /// <param name="z">Unity units in direction z from origin</param> /// <returns>A list of elevation points</returns> List <float> IMapResources.getMesh(float x, float z) { //Use x and z to offset the quadkey int initx = 0; int initz = 0; int initChosenZoomLevel = 14; QuadKeyFuncs.QuadKeyToTileXY(originQuadKey, out initx, out initz, out initChosenZoomLevel); initx = initx + Convert.ToInt32(x) / 256; initz = initz + Convert.ToInt32(z) / 256; String newQuadKey = QuadKeyFuncs.TileXYToQuadKey(initx, initz, initChosenZoomLevel); double ucLat; double ucLong; QuadKeyFuncs.QuadKeyToLatLong(newQuadKey, out ucLat, out ucLong); double lcLat; double lcLong; //Get the lower right corner int tilex = 0; int tilez = 0; int chosenZoomLevel; QuadKeyFuncs.QuadKeyToTileXY(newQuadKey, out tilex, out tilez, out chosenZoomLevel); tilex = tilex + 1; tilez = tilez + 1; String lcquadkey = QuadKeyFuncs.TileXYToQuadKey(tilex, tilez, chosenZoomLevel); QuadKeyFuncs.QuadKeyToLatLong(lcquadkey, out lcLat, out lcLong); //Get chunks from database if it exists //Otherwise, get the mesh from Bing's REST API List <float> mesh = ElevationRequest(ucLat, ucLong, lcLat, lcLong, 32, newQuadKey.Length); return(mesh); }
/// <summary> /// This is an asynchronous version of the getElevFunction in BingMapResources.cs. /// It gets an elevation chunk from BingMaps Rest API using an offset from the /// starting latitude and longitude in globals. /// </summary> /// <param name="x">The Unity coordinate for X</param> /// <param name="z">The Unity coordinate for Z</param> /// <returns></returns> async public Task <List <float> > getElevChunk(float x, float z) { String originQuadKey = QuadKeyFuncs.getQuadKey(Globals.latitude, Globals.longitude, 14); int initx = 0; int initz = 0; int initChosenZoomLevel = 14; QuadKeyFuncs.QuadKeyToTileXY(originQuadKey, out initx, out initz, out initChosenZoomLevel); initx = initx + Convert.ToInt32(x) / 256; initz = initz + Convert.ToInt32(z) / 256; //Get the upper left corner String newQuadKey = QuadKeyFuncs.TileXYToQuadKey(initx, initz, initChosenZoomLevel); double ucLat; double ucLong; QuadKeyFuncs.QuadKeyToLatLong(newQuadKey, out ucLat, out ucLong); double lcLat; double lcLong; //Get the lower right corner int tilex = 0; int tilez = 0; int chosenZoomLevel; QuadKeyFuncs.QuadKeyToTileXY(newQuadKey, out tilex, out tilez, out chosenZoomLevel); tilex = tilex + 1; tilez = tilez + 1; String lcquadkey = QuadKeyFuncs.TileXYToQuadKey(tilex, tilez, chosenZoomLevel); QuadKeyFuncs.QuadKeyToLatLong(lcquadkey, out lcLat, out lcLong); //Request Bing API elevations using the corners as a bounding box String requestString = "http://dev.virtualearth.net/REST/v1/Elevation/Bounds?bounds=" + (lcLat) + "," + (lcLong) + "," + (ucLat) + "," + (ucLong) + "&rows=32&cols=32&key=" + Globals.BingAPIKey; HttpClient client = new HttpClient(); var content = ""; bool tooManyRequestFlag = false; do { tooManyRequestFlag = false; try { content = await client.GetStringAsync(requestString); } catch (HttpRequestException e) { if (e.Message == "429 (Too Many Requests)") { tooManyRequestFlag = true; } else { throw e; } } } while (tooManyRequestFlag); int i; int j; int k; //Convert the retrieved elevations into a usable chunk int start = content.IndexOf("\"elevations\"") + 14; int end = content.IndexOf("\"zoomLevel\"") - 2; String elevation_string = content.Substring(start, end - start); List <String> elevation_strings = elevation_string.Split(',').ToList(); List <float> retrieved_chunk = new List <float>(); for (k = 0; k < elevation_strings.Count; k++) { retrieved_chunk.Add(Convert.ToSingle(elevation_strings[k])); } //Flip the values in the retrieved chunks so that it matches the order of satellite imagery //Note that elevations in Bing go from the bottom up in a square while the imagery uses the //top left corner as its baseline. We chose to change the order of the elevations List <float> newElevChunk = new List <float>(); for (i = 0; i < Math.Sqrt(retrieved_chunk.Count); i++) { for (j = 0; j < Math.Sqrt(retrieved_chunk.Count); j++) { newElevChunk.Add(retrieved_chunk[(31 - j) * Convert.ToInt32(Math.Sqrt(retrieved_chunk.Count)) + (31 - i)]); } } return(newElevChunk); }