This project has moved. For the latest updates, please go here.

Blank space above and below the map

Mar 28, 2013 at 4:49 PM
Hi,
congratulations for your map control, the best I've ever tried.

Here is my question, is there a way to remove the blank space that is displayed below and above the map? Even when setting a higher MinZoomLevel the user is able to translate the map to this blank space.

Thank you
Coordinator
Apr 1, 2013 at 8:45 PM
The map control only forces its center point to lie inside the area that is covered by map content. So there is currently no built-in way to achieve what you want. However, I have been thinking of a feature like this for a while and might introduce it in the future. But it would have to work for rotated maps, too.
Apr 2, 2013 at 8:00 AM
Thank you for your answer, I will work on such a feature if I have time.
I'll keep you updated of my results
Apr 2, 2013 at 4:02 PM
Hi, it would be something like this. This method have to be called in the ZoomLevelPropertyChanged method as well to ensure that the map fits within the window.
It is not the cleaner code I've ever written but it works for now:
private Location CoerceLocation(Location location)
        {
            // initialize window size when the app is loaded
            if (Application.Current.MainWindow != null && Application.Current.MainWindow.IsLoaded)
            {
                windowSize = new Size(Application.Current.MainWindow.ActualWidth, Application.Current.MainWindow.ActualHeight);
            }

            // calculate coerced lat/lon without taking window bound into account
            double lat = Math.Min(Math.Max(location.Latitude, -mapTransform.MaxLatitude), mapTransform.MaxLatitude);
            double lon = Location.NormalizeLongitude(location.Longitude);

            // ensure that the app is loaded
            if (windowSize.Width != 0 && windowSize.Height != 0)
            {
                // getting top screen X/Y as geo coordinates
                Location topScreen = this.ViewportPointToLocation(new Point(windowSize.Width / 2, 0));

                // getting bottom screen X/Y as geo coordinates
                Location bottomScreen = this.ViewportPointToLocation(new Point(windowSize.Width / 2, windowSize.Height));
                
                // getting middle screen X/Y as geo coordinates
                Location midScreen = this.ViewportPointToLocation(new Point(windowSize.Width / 2, windowSize.Height / 2));

                // calculating the diff between Top and Middle point
                double topMidDiffLatitude = topScreen.Latitude - midScreen.Latitude;

                // calculating the diff between Bottom and Middle point
                double bottomMidDiffLatitude = Math.Abs(bottomScreen.Latitude - midScreen.Latitude);

                // testing if the new latitude is greater than the Maximum latitude
                if (lat + topMidDiffLatitude > mapTransform.MaxLatitude)
                {
                    lat = mapTransform.MaxLatitude - topMidDiffLatitude;
                }
                // testing if the new latitude is lower than the Minimum latitude
                else if (lat - bottomMidDiffLatitude < -mapTransform.MaxLatitude)
                {
                    lat = -mapTransform.MaxLatitude + bottomMidDiffLatitude;
                }
            }

            return new Location(lat, lon);
        }
Coordinator
Apr 2, 2013 at 4:51 PM
Sorry, but I haven't read your code further than the very first line (containing Application.Current.MainWindow) to decide that I can't adopt it. I can't see any reason for doing a calculation that is based on the MainWindow's size. Why don't you simply use the map control's own ActualWidth and ActualHeight values? And will your code work with a rotated map, with a Heading value of let's say 45 or 180?
Apr 3, 2013 at 1:06 PM
Hi,
you're totally right for the size of the window, ActualSize of the map should be used, I used it for test purposes but it stayed...

About the rotated map it won't work of course as I don't take Heading into account, this code was just a hint for the solution and wasn't posted for you to adopt it ;)