How to get best possible map view when considering all POI's

6 posts, 1 answers
  1. Rod Yager
    Rod Yager avatar
    79 posts
    Member since:
    May 2010

    Posted 10 Dec 2010 Link to this post

    I have a couple of layers on my map. One layers contains routes and the other contains random POI's. How can I get the map to choose the best possible center and zoom level based on all the POI's?

    Thanks,
    Rod
  2. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 15 Dec 2010 Link to this post

    Hi Rod Yager,

    If you would like to take into count all POIs in the information layer then you can use code similar to the following:

    LocationRect bestView = this.poiLayer.GetBestView( 
        this.GetIEnumerable(this.poiLayer)); 
    this.RadMap1.SetView(bestView); 
        
        
    private IEnumerable<object> GetIEnumerable(InformationLayer layer) 
        foreach (object item in layer.Items) 
        
            yield return item; 
        


    Greetings,
    Andrey Murzov
    the Telerik team
    Browse the videos here>> to help you get started with RadControls for WPF
  3. UI for WPF is Visual Studio 2017 Ready
  4. Rod Yager
    Rod Yager avatar
    79 posts
    Member since:
    May 2010

    Posted 15 Dec 2010 Link to this post

    How can I tell when all the items have been added to the information layers. Seems like the binding to the layers hasn't actually created the items yet when I try to set the SetView. Also, I have multiple layers that I want to consider when getting the best view. Will this work?

    LocationRect bestView = this.poiInformationLayer.GetBestView(GetAllPoiItems());
    taskRadmap.SetView(bestView);


    private IEnumerable<object> GetAllPoiItems()
            {
                foreach (object item in this.poiInformationLayer.Items)
                {
                    yield return item;
                }
      
                foreach (object item in this.informationLayer.Items)
                {
                    yield return item;
                }
      
                foreach (object item in this.kmlInformationLayer.Items)
                {
                    yield return item;
                }
      
                foreach (object item in this.closestResourceInformationLayer.Items)
                {
                    yield return item;
                }
          
            }
     
  5. Answer
    Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 17 Dec 2010 Link to this post

    Hi Rod Yager,

    Similar to other items controls, the InformationLayer takes some time to generate the presentation for items which have been added. You can control when this process is finished using a standard method for ItemsControl by tracking status of the ItemContainerGenerator. For example:

    this.informationLayer.ItemContainerGenerator.StatusChanged += 
        new EventHandler(this.ItemContainerGenerator_StatusChanged);
    this.informationLayer.ItemsSource = collection;
      
      
    private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
    {
        if (this.informationLayer.ItemContainerGenerator.Status 
            == Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
        {
            this.informationLayer.ItemContainerGenerator.StatusChanged -= 
                new EventHandler(this.ItemContainerGenerator_StatusChanged);
      
            LocationRect bestView = this.informationLayer.GetBestView(
                this.GetIEnumerable(this.informationLayer));
            this.radMap.SetView(bestView);
        }
    }

    Your approach for multiple layers will work, but you should take in account status of the ItemContainerGenerator for all levels.

    Best wishes,
    Andrey Murzov
    the Telerik team
    Browse the videos here>> to help you get started with RadControls for WPF
  6. xusan Rahimov
    xusan Rahimov avatar
    10 posts
    Member since:
    Dec 2009

    Posted 24 Jan 2011 Link to this post

    Hi Andrey Murzov using your code I'm always getting ZoomLevle = 1
    any idea what can be wrong ?

    Thanks
    Xusan.

  7. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 26 Jan 2011 Link to this post

    Hi Xusan Rahimov,

    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 in account 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;
    }

     



    Best wishes,
    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
UI for WPF is Visual Studio 2017 Ready