Mehdi Bugnard
Mehdi Bugnard

Reputation: 3979

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 ^^ :-)

Upvotes: 1

Views: 395

Answers (1)

Mehdi Bugnard
Mehdi Bugnard

Reputation: 3979

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

Upvotes: 1

Related Questions