This is a migrated thread and some comments may be shown as answers.

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

5 Answers 196 Views
Map
This is a migrated thread and some comments may be shown as answers.
Rod Yager
Top achievements
Rank 1
Rod Yager asked on 11 Dec 2010, 01:21 AM
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

5 Answers, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 15 Dec 2010, 08:48 AM
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
0
Rod Yager
Top achievements
Rank 1
answered on 15 Dec 2010, 04:27 PM
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;
            }
      
        }
 
0
Accepted
Andrey
Telerik team
answered on 17 Dec 2010, 01:54 PM
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
0
xusan Rahimov
Top achievements
Rank 1
answered on 24 Jan 2011, 03:21 PM
Hi Andrey Murzov using your code I'm always getting ZoomLevle = 1
any idea what can be wrong ?

Thanks
Xusan.

0
Andrey
Telerik team
answered on 26 Jan 2011, 08:54 AM
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>>
Tags
Map
Asked by
Rod Yager
Top achievements
Rank 1
Answers by
Andrey
Telerik team
Rod Yager
Top achievements
Rank 1
xusan Rahimov
Top achievements
Rank 1
Share this question
or