Search code examples
botframeworkbing-mapsbing-apiazure-maps

Bing Maps API - mapArea: this parameter value is out of range


I'm using the Bing Maps API to generate images from certain locations using the BotFramework-Location NuGet package. (Which code can be found here)

Sometimes it works, but sometimes the images are not loaded due to an error in the Rest call (which is called by the BotFramework, not by me)

This is my code:

IGeoSpatialService geoService = new AzureMapsSpatialService(this.azureApiKey);
List < Location > concreteLocations = new List < Location > ();

foreach(String location in locations) {
 LocationSet locationSet = await geoService.GetLocationsByQueryAsync(location);
 concreteLocations.AddRange(locationSet ? .Locations);
}

// Filter out duplicates
var seenKeys = new HashSet < String > ();
var uniqueLocations = new List < Location > ();

foreach(Location location in concreteLocations) {
 if (seenKeys.Add(location.Address.AddressLine)) {
  uniqueLocations.Add(location);
 }
}

concreteLocations = new List < Location > (uniqueLocations.Take(5));

if (concreteLocations.Count == 0) {
 await context.PostAsync("No dealers found.");
 context.Done(true);
} else {
 var locationsCardReply = context.MakeMessage();
 locationsCardReply.Attachments = new LocationCardBuilder(this.bingApiKey, new LocationResourceManager()).CreateHeroCards(concreteLocations).Select(card => card.ToAttachment()).ToList();
 locationsCardReply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
 await context.PostAsync(locationsCardReply);
}

Which responds this: Location HeroCards returned by BotFramework-Location NuGet Package.

The reason not all images are shown is because the Rest call to the Bing Maps API returns this:

mapArea: This parameter value is out of range.

Here is one of the image uris that fail (I removed my key):

https://dev.virtualearth.net/REST/V1/Imagery/Map/Road?form=BTCTRL&mapArea=49.5737,5.53792,49.57348,5.53744&mapSize=500,280&pp=49.5737,5.53744;1;1&dpi=1&logo=always&key=NOT_REAL_12758FDLKJLDKJO8769KLJDLKJF

Anyone know what I've been doing wrong?


Solution

  • I think I understood why you got that error. I tried to get this map and got the same result as yours, as you said:

    mapArea: This parameter value is out of range.

    If you look at the sample url you provided, the mapArea is equal to 49.5737,5.53792,49.57348,5.53744

    So I just inverted the coordinates of the 2 points defining this area, putting the one with the smaller latitude value first, I got a reply:

    Image from maps

    EDIT:

    As you commented, this call is made inside BotBuilder-Location code, not on yours. I had a look to it, this is the method to generate the map, called inside LocationCardBuilder class that you are instantiating:

    public string GetLocationMapImageUrl(Location location, int? index = null)
    {
        if (location == null)
        {
            throw new ArgumentNullException(nameof(location));
        }
    
        var point = location.Point;
        if (point == null)
        {
            throw new ArgumentNullException(nameof(point));
        }
    
        if (location.BoundaryBox != null && location.BoundaryBox.Count >= 4)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                ImageUrlByBBox,
                location.BoundaryBox[0],
                location.BoundaryBox[1],
                location.BoundaryBox[2],
                location.BoundaryBox[3],
                point.Coordinates[0],
                point.Coordinates[1], 
                index, 
                this.apiKey);
        }
        else
        {
            return string.Format(
                CultureInfo.InvariantCulture, 
                ImageUrlByPoint, 
                point.Coordinates[0], 
                point.Coordinates[1], 
                index, 
                apiKey);
        }
    }
    

    As you can see, there is no restriction on the format of the BoundaryBox item. But if you look at the documentation about location data here:

    BoundingBox: A geographic area that contains the location. A bounding box contains SouthLatitude, WestLongitude, NorthLatitude, and EastLongitude values in units of degrees.

    As you may know, in code, SouthLatitude is smaller that NorthLatitude (as it expressed with positive and negative values in code depending on the location compared to Ecuador: 43N is 43, 43S is -43). So the problem seems to be here.

    I made a quick test to see if I got the error base on the call you are doing before (to GetLocationsByQueryAsync), I wasn't able to reproduce this case. Can you share the query you did that linked to this problem?