/// <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);
    }
Example #2
0
    /// <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);
    }