Map information Layer Points in view

6 posts, 0 answers
  1. Paul Lewis
    Paul Lewis avatar
    31 posts
    Member since:
    Jan 2010

    Posted 17 Sep 2010 Link to this post

    Hi,

    Im binding a collection of points to an information layer, once the points have been created is there a way to zoom out so all the points are in view? for example:

    if all the points are in one city the map zooms to city level or
    if the points are all in a country e.g. france the map zooms so france in all in view

    Thanks
  2. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 21 Sep 2010 Link to this post

    Hi Paul Lewis,

    You can use the InformationLayer.GetBestView method to get the location rectangle that contains optimal zoom and center.
    The sample code is below.
    private void SetBestView()
    {
        LocationRect rect = this.informationLayer.GetBestView(this.informationLayer.Items);
        rect.MapControl = this.radMap;
        this.radMap.Center = rect.Center;
        this.radMap.ZoomLevel = rect.ZoomLevel;
    }

    Sincerely yours,
    Andrey Murzov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. DevCraft banner
  4. xusan Rahimov
    xusan Rahimov avatar
    10 posts
    Member since:
    Dec 2009

    Posted 24 Jan 2011 Link to this post

    Hi Paul Lewis I have same scenario there are set of Location Items that are added to InformationLayer and need to get best rect view for them, so I'm using your approach and the problem is that I'm always getting ZoomLevle as 1, I'm thinking to use some custome calculation instead,  the new code that I'm trying to use is follow:

    private void SetCenterAndZoomByRectangle(Location leftTop, Location rightBottom)
            {
                Location centerLocation = new Location((leftTop.Latitude + rightBottom.Latitude) / 2,
                    (leftTop.Longitude + rightBottom.Longitude) / 2);
                this.RadMap1.Center = centerLocation;
                Point leftTopPoint = this.RadMap1.SpatialReference.GeographicToLogical(leftTop);
                Point rightBottomPoint = this.RadMap1.SpatialReference.GeographicToLogical(rightBottom);
                double viewportWidth = rightBottomPoint.X - leftTopPoint.X;
                double viewportHeight = rightBottomPoint.Y - leftTopPoint.Y;
                double proportionalWidth = viewportWidth / this.RadMap1.ActualWidth;
                double proportionalHeight = viewportHeight / this.RadMap1.ActualHeight;
                double tileSize = 256;
                if (proportionalWidth > proportionalHeight)
                {
                    this.RadMap1.ZoomLevel = (int)Math.Log(this.RadMap1.ActualWidth / tileSize / viewportWidth, 2d);
                }
                else
                {
                    this.RadMap1.ZoomLevel = (int)Math.Log(this.RadMap1.ActualHeight / tileSize / viewportHeight, 2d);
                }
            }

    but I don't have any idea how to determine which Location is topLeft and which one is rightBottom
    Thanks
    Xusan
  5. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 26 Jan 2011 Link to this post

    Hello Xusan Rahimov,

    This custom code is a line by line copy of the our LocationRect.ZoomLevel property, so it will not give you anything better than our code already does. It is hard to say why you always get zoom level 1 without your code where you add items to the information layer. But I can suppose that you trying to call GetBestView method right after assigning of the items source (or adding items) to the information layer. GetBestView method requires that markers will be on screen already. Otherwise it will not work. Similar to any other ItemsControl the information layer takes some time to process all markers in the list and show them over the map. So if you try to use this method in CollectionChanged event for collection which is an items source for information layer, then it will not work, because at this moment markers aren't on the screen yet.

    The InformationLayer.GetBestView method takes into account the visible size of the markers (in pixels) and makes best possible assumption about its geographical size when calculating location rectangle. But if it is enough for your to ensure that all locations are on the screen (regardless whether actual markers are visible), then you can use simplified version to calculate location rectangle. For example:

    LocationRect bestView = this.GetBestView(collection, new Size(0.001, 0.001));
    this.radMap.SetView(bestView);
      
    public LocationRect GetBestView(IEnumerable<PointOfInterest> itemsList, Size defaultSize)
    {
        LocationRect bestView = new LocationRect();
        Location northEast = Location.Empty;
        Location southWest = Location.Empty;
      
        foreach (PointOfInterest item in itemsList)
        {
            Location location = item.Location;
      
            if (northEast.IsEmpty)
            {
                northEast = location;
            }
            else
            {
                if (!location.IsEmpty)
                {
                    northEast.Latitude = Math.Max(northEast.Latitude, location.Latitude);
                    northEast.Longitude = Math.Max(northEast.Longitude, location.Longitude);
                }
            }
      
            if (southWest.IsEmpty)
            {
                southWest = location;
            }
            else
            {
                if (!location.IsEmpty)
                {
                    southWest.Latitude = Math.Min(southWest.Latitude, location.Latitude);
                    southWest.Longitude = Math.Min(southWest.Longitude, location.Longitude);
                }
            }
        }
      
        if (!northEast.IsEmpty && !southWest.IsEmpty)
        {
            bestView = new LocationRect(northEast, southWest);
      
            if (bestView.IsEmpty)
            {
                bestView = new LocationRect(
                    new Location(bestView.North + defaultSize.Height / 2.0, bestView.West - defaultSize.Width / 2.0),
                    new Location(bestView.North - defaultSize.Height / 2.0, bestView.West + defaultSize.Width / 2.0));
            }
        }
      
        return bestView;
    }


    All the best,
    Andrey Murzov
    the Telerik team
    Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>
  6. xusan Rahimov
    xusan Rahimov avatar
    10 posts
    Member since:
    Dec 2009

    Posted 26 Jan 2011 Link to this post

    Hi Andrey Thank you for you really quick response I'll surely decide to choose your approach but one more question I have looked one your GetBestView method and wondering what I need to pass  to Size defaultSize parameter, is it should be the size of RadMap control ?

    Best regards.
    Xusan
  7. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 31 Jan 2011 Link to this post

    Hi Xusan,

    The defaultSize in this code is default size of the location rectangle in degrees for the cases when only one location (marker) exists in the list. It can be anything you'd like. For example new Size(0.001, 0.001). Just keep in mind that this is size in degrees.

    Regards,
    Andrey Murzov
    the Telerik team
    Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>
Back to Top
DevCraft banner