1

Does anyone have a solution for calculating the Latitude and Longitude corners of a view based on heading?

I have a function that calculates the LatLng corners of a view if heading is 0. But I wish to find a way to calculate the corners based on a new heading, if the user spins the map for example.

The code I have now that does this with Heading = 0 is this.

public GeoboundingBox GetBounds(MapControl map)
    {
        if(map.Center.Position.Latitude == 0) { return default(GeoboundingBox); }

        /*
         * resolution m/px = 15653.04 m/px * Cos(LatInRad) / 2^zoomLevel
         * 111325 m/deg
         */

        double latInRad = Math.Cos(map.Center.Position.Latitude * Math.PI / 180);
        double lngInRad = Math.Cos(map.Center.Position.Longitude * Math.PI / 180);

        double degreePerPixel = (156543.04 * latInRad * lngInRad) / (111325 * Math.Pow(2, map.ZoomLevel));

        double mHalfWidthInDegrees = map.ActualWidth * degreePerPixel / 0.89;
        double mHalfHeightInDegrees = map.ActualHeight * degreePerPixel / 1.65;

        double mNorth = map.Center.Position.Latitude + mHalfHeightInDegrees;
        double mWest = map.Center.Position.Longitude - mHalfWidthInDegrees;
        double mSouth = map.Center.Position.Latitude - mHalfHeightInDegrees;
        double mEast = map.Center.Position.Longitude + mHalfWidthInDegrees;

        GeoboundingBox mBounds = new GeoboundingBox(
            new BasicGeoposition()
            {
                Latitude = mNorth,
                Longitude = mWest
            },
            new BasicGeoposition()
            {
                Latitude = mSouth,
                Longitude = mEast
            });
      return mBounds;
 }
S. Matthews
  • 355
  • 2
  • 9
Startail
  • 67
  • 7

2 Answers2

2

The simplest solution to get the bounding box of the visible map area is to get the values directly from the map control.

For the built-in Map control by Microsoft you have the MapControl.GetLocationFromOffset method which takes a Point relative to the control and returns the geographic location at that point.

mapControl.GetLocationFromOffset(
   new Point(0, 0),
   out upperLeftGeoPoint
);
mapControl.GetLocationFromOffset (
   new Point( mapControl.ActualWidth, 0 ), 
   out upperRightGeoPoint
);
mapControl.GetLocationFromOffset (
   new Point( 0, mapControl.ActualHeight ), 
   out bottomLeftGeoPoint
);
mapControl.GetLocationFromOffset (
   new Point( mapControl.ActualWidth, mapControl.ActualHeight ), 
   out bottomRightGeoPoint
);

Be aware that the method will throw an exception in case the point is outside the range of the map control.

In your case, you will need to get the values for all four corners, because it the map is rotated.

For more documentation of this method, see MSDN.

If you are using the third-party XAML Map Control, you have the equivalent ViewportPointToLocation method

var northWestCorner = mapControl.ViewportPointToLocation( 
   new Point( 0, 0 )
);
var southEastCorner = mapControl.ViewportPointToLocation(
   new Point( mapControl.ActualWidth, mapControl.ActualHeight )
);
//analogous for north east, south west
Martin Zikmund
  • 38,440
  • 7
  • 70
  • 91
0

It looks like you are trying to calculate the bounding box of the map. Using degree per pixel won't work as this value changes with the latitude value. Instead take a look at the solution here on how to calculate the bounding box of a map in WP8.1 (this basis to the Win10 map control) Get view bounds of a Map

Community
  • 1
  • 1
rbrundritt
  • 16,570
  • 2
  • 21
  • 46
  • Thank you. This code seems to be working best, but I've encountered some issues with this code when the user navigates outside the top and bottom of the map canvas. – Startail Aug 02 '16 at 09:04
  • This code addresses the issue when the user navigates too far up or down. That's what the try/catches are for. If a point isn't inside the map it then snaps to the limit of the latitude which is 85/-85. In reality it is 90/-90 but then the calculations error out due to division by zero. – rbrundritt Aug 02 '16 at 16:09
  • The problem I get is that the catch code throws an exception on GetLocationFromOffset. If the Point(x,y) coordinates are invalid it will throw an error and bottomRight or topLeft will be null. I have solved this with putting these parts of the code inside try{} catch{} statements. This may not be good for general use since I do nothing if they fail. But I don't expect my users to get any data on the top/bottom of the canvas. This is just to prevent the application from crashing. – Startail Aug 03 '16 at 15:08