none
GetLocationFromOffset Exception

    Question

  • Hi,

    I am using MapControl.GetLocationFromOffset to calculate the coordinates of the visible region of the map that is actually shown in the screen. For that I'm using the folllowing code:

    Map.GetLocationFromOffset(new Point(0, 0), out upperLeft);
    Map.GetLocationFromOffset(new Point(Map.ActualWidth, Map.ActualHeight), out bottomRight);

    This works fine unless the user pans the map to the north and the actual upper corner of the map is not (0,0)  (perhaps (0,100). In that case the method call raises an Exception with the message "Value does not fall within the expected range". 

    I understand that the Exception is raised because the upper corner of the map is not (0,0) but something else.

    How can I calculate the actual coordinate of this corner even when the panning moves the map below (0,0)?

    Thanks,

    Carlos.

    Tuesday, June 24, 2014 1:01 PM

Answers

  • I'm pretty sure this is known issue. I came across this a couple months ago and reported it to the team. It will likely be fixed in a future update of the map control. One solution, is to wrap the GetLocationFromOffset method with a try/catch. If it fails then use the GetOffsetFromLocation method with a value of (-85, 0). This should return the Y value should be the bottom of the map. You can do a similar process for the top of the map. I use -85 because that is usually where Mercator maps are clipped as some of the map math tends to go to infinity when set to 90/-90. Here is an extension method I created for the map to do this.

    public static GeoboundingBox GetBounds(this MapControl map)
    {
        Geopoint topLeft = null;
    
        try
        {
            map.GetLocationFromOffset(new Windows.Foundation.Point(0, 0), out topLeft);
        }
        catch
        {
            var topOfMap = new Geopoint(new BasicGeoposition()
            {
                Latitude = 85,
                Longitude = 0
            });
    
            Windows.Foundation.Point topPoint;
            map.GetOffsetFromLocation(topOfMap, out topPoint);
            map.GetLocationFromOffset(new Windows.Foundation.Point(0, topPoint.Y), out topLeft);
        }
    
        Geopoint bottomRight = null;
        try
        {
            map.GetLocationFromOffset(new Windows.Foundation.Point(0, 0), out bottomRight);
        }
        catch
        {
            var bottomOfMap = new Geopoint(new BasicGeoposition()
            {
                Latitude = -85,
                Longitude = 0
            });
    
            Windows.Foundation.Point bottomPoint;
            map.GetOffsetFromLocation(bottomOfMap, out bottomPoint);
            map.GetLocationFromOffset(new Windows.Foundation.Point(0, bottomPoint.Y), out bottomRight);
        }
    
        if (topLeft != null && bottomRight != null)
        {
            return new GeoboundingBox(topLeft.Position, bottomRight.Position);
        }
    
        return null;
    }


    http://rbrundritt.wordpress.com

    Tuesday, June 24, 2014 6:48 PM

All replies

  • I'm pretty sure this is known issue. I came across this a couple months ago and reported it to the team. It will likely be fixed in a future update of the map control. One solution, is to wrap the GetLocationFromOffset method with a try/catch. If it fails then use the GetOffsetFromLocation method with a value of (-85, 0). This should return the Y value should be the bottom of the map. You can do a similar process for the top of the map. I use -85 because that is usually where Mercator maps are clipped as some of the map math tends to go to infinity when set to 90/-90. Here is an extension method I created for the map to do this.

    public static GeoboundingBox GetBounds(this MapControl map)
    {
        Geopoint topLeft = null;
    
        try
        {
            map.GetLocationFromOffset(new Windows.Foundation.Point(0, 0), out topLeft);
        }
        catch
        {
            var topOfMap = new Geopoint(new BasicGeoposition()
            {
                Latitude = 85,
                Longitude = 0
            });
    
            Windows.Foundation.Point topPoint;
            map.GetOffsetFromLocation(topOfMap, out topPoint);
            map.GetLocationFromOffset(new Windows.Foundation.Point(0, topPoint.Y), out topLeft);
        }
    
        Geopoint bottomRight = null;
        try
        {
            map.GetLocationFromOffset(new Windows.Foundation.Point(0, 0), out bottomRight);
        }
        catch
        {
            var bottomOfMap = new Geopoint(new BasicGeoposition()
            {
                Latitude = -85,
                Longitude = 0
            });
    
            Windows.Foundation.Point bottomPoint;
            map.GetOffsetFromLocation(bottomOfMap, out bottomPoint);
            map.GetLocationFromOffset(new Windows.Foundation.Point(0, bottomPoint.Y), out bottomRight);
        }
    
        if (topLeft != null && bottomRight != null)
        {
            return new GeoboundingBox(topLeft.Position, bottomRight.Position);
        }
    
        return null;
    }


    http://rbrundritt.wordpress.com

    Tuesday, June 24, 2014 6:48 PM
  • I'm using UWP with Maps and I'm trying to implement your code on this project. But I'm having a few issues.

    The code works as expected with both heading and tilt, but it crashes on the mapcanvas bounds.

    If the user navigates the map outside the upper or lower bounds the code will throw a {"Value does not fall within the expected range."} exception


    Tuesday, August 2, 2016 9:20 AM