Search code examples
c#dictionarybing-mapsbingbing-api

It is possible to request a bing map image from a given size ( meters )?


Hello I work on a game that is based on a map generation with BING.

The problem is: The card is generated based on address given by the user, after which I would like to generate a 1km2 card (1000m wide and 1000m long).

Unfortunately I found no bing API to retrieve a map with defined size in meters. I can only define a "level zoom" and a resolution.

Here's what I use now (from Microsoft Bing Api Tile code library example):

Bing Maps Tile System

// Get a bing Map (resolution max. 834 pixel) with zoom level 16
var stream = await httpClient.GetStreamAsync("api/newmap/?latitude=46.6052284&longitude=7.0967002&mapSizeHeight=834&mapSizeWidth=834&zoomLevel=16");
    // Calculated from "latitudeCentre" and "zoom level" , i get like 0.8 meter/pixel
double meterPerPixel = TileSystem.GroundResolution(latitudeCentre, 16);

For example (834/834 pixel) and zoom level 16 => which gives me about a scale of 0.8 meter / pixel. I can not generate a 1 meter / pixel map. Do you think a solution to my problem exist?

I really hope so if yes ^^ :-)


Solution

  • Ok , YES It's possible !! I take time for make a function for finally i solve it by myself . But i am shocked , nobody has never ask this question , and Microsoft never post the code for that . I think this function can be really usefull .

    private void SetBoundingBoxLocationAndZoom(double latitudeCentre)
        {
            // 1024/1024 meters
            double desiredMapSize = 1024.0;
    
    
            int bestMatchMapSize = 0;
            int bestMatchMapResolution = 0;
            int bestMatchMapZoom = 0;
    
    
    
            //Starts with the largest zoom and ending with the smallest (remote) (min zoomLevel [1])
            // 1 - 21
            for (int zoom = 21; zoom >= 1; zoom--)
            {
    
                //Starts with the highest resolution and ending with the smallest (min pixel 80/80)
                // 80 - 834
                for (int resolution = 834; resolution >= 80; resolution--)
                {
                    double meterPerPixel = TileSystem.GroundResolution(latitudeCentre, zoom);
                    double mapSize = meterPerPixel * resolution;
    
                    if(Math.Abs(desiredMapSize - mapSize) < Math.Abs(desiredMapSize - bestMatchMapSize))
                    {
                        bestMatchMapSize = (int)mapSize;
                        bestMatchMapResolution = resolution;
                        bestMatchMapZoom = zoom;
                    }
                }
            }
    
    
            zoomLevel = bestMatchMapZoom;
            sizeMapInMeter = bestMatchMapSize;
            resolutionMap = bestMatchMapResolution;
    
    
    
        }
    
        /// <summary>
            /// Determines the ground resolution (in meters per pixel) at a specified
            /// latitude and level of detail.
            /// </summary>
            /// <param name="latitude">Latitude (in degrees) at which to measure the
            /// ground resolution.</param>
            /// <param name="levelOfDetail">Level of detail, from 1 (lowest detail)
            /// to 23 (highest detail).</param>
            /// <returns>The ground resolution, in meters per pixel.</returns>
            public static double GroundResolution(double latitude, int levelOfDetail)
            {
                latitude = Clip(latitude, MinLatitude, MaxLatitude);
                return Math.Cos(latitude * Math.PI / 180) * 2 * Math.PI * EarthRadius / MapSize(levelOfDetail);
            }