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

Auto Rebinding Information layer data

1 Answer 125 Views
Map
This is a migrated thread and some comments may be shown as answers.
Syed Anwar
Top achievements
Rank 1
Syed Anwar asked on 13 Nov 2010, 05:37 PM
Hi,

I want to rebind the informationlayer data automatically so if any data changed it will reflect on map. i am fetching informationlayer data from database.

and using DispatchTimer to rebind it. on my informationlayer there is tooltip also. problem is some time this tooltip displayed in wrong position like upperleft corner of the map instead of on the item location.

my xaml is :

<UserControl x:Class="SitesMapp.MainPage"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">
  
    <Grid x:Name="LayoutRoot" Background="White">
        <telerik:RadMap Height="auto" HorizontalAlignment="Left" Margin="12,12,0,0"  Center="9.45, 7.46" ZoomLevel="6" Name="radMap1" VerticalAlignment="Top" Width="auto" >
            <telerik:InformationLayer x:Name="informationLayer">
                <telerik:InformationLayer.ItemTemplate>
                    <DataTemplate>
                        <Grid telerik:MapLayer.BaseZoomLevel="{Binding BaseZoomLevel}"
                       telerik:MapLayer.Location="{Binding Location}"
                       telerik:MapLayer.ZoomRange="{Binding ZoomRange}">
                            <telerik:MapLayer.HotSpot>
                                <telerik:HotSpot X="0.5"
                                           Y="0.5"
                                           ElementName="PART_Ellipse" />
                            </telerik:MapLayer.HotSpot>
                            <Ellipse x:Name="PART_Ellipse"
                               Width="20"
                               Height="20"
                               Stroke="Red"
                               StrokeThickness="3"
                               Fill="Transparent">
                                <ToolTipService.ToolTip>
                                    <ToolTip Content="{Binding Rating}" />
                                </ToolTipService.ToolTip>
                            </Ellipse>
                        </Grid>
                    </DataTemplate>
                </telerik:InformationLayer.ItemTemplate>
            </telerik:InformationLayer>
        </telerik:RadMap>
    </Grid>
</UserControl>


and my code behind is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using Telerik.Windows.Controls.Map;
using System.Threading;
using System.Windows.Threading;
  
namespace SitesMapp
{
    public partial class MainPage : UserControl
    {
        PammsDataService.PammsDataServiceClient client = new PammsDataService.PammsDataServiceClient();
        public MainPage()
        {
            InitializeComponent();
  
            radMap1.Provider = new OpenStreetMapProvider();
  
            radMap1.InitializeCompleted += new EventHandler(radMap1_InitializeCompleted);
  
            DispatcherTimer t = new DispatcherTimer();
            t.Interval = new TimeSpan( 0, 0, 1 );
            t.Tick += new EventHandler(Rebind);
            t.Start();
        }
  
        void radMap1_InitializeCompleted(object sender, EventArgs e)
        {
            //informationLayer.ItemsSource = GetMapData();
            client.GetSitesInformationAsync();
            client.GetSitesInformationCompleted += new EventHandler<PammsDataService.GetSitesInformationCompletedEventArgs>(client_GetSitesInformationCompleted);
        }
  
        void client_GetSitesInformationCompleted(object sender, PammsDataService.GetSitesInformationCompletedEventArgs e)
        {
            ObservableCollection<MapItem> data = new ObservableCollection<MapItem>();
            ObservableCollection<PammsDataService.Site> sites = e.Result;
            foreach (PammsDataService.Site site in sites)
            {
                MapItem mapItem = new MapItem(site.SiteName, new Location(site.Latitude, site.Longitude), 5, new ZoomRange(5, 12),site.Rating);
                data.Add(mapItem);
            }
              
            Dispatcher.BeginInvoke(() =>
            informationLayer.ItemsSource = data
            );
            //radMap1.UpdateLayout();
            //informationLayer.UpdateLayout();
        }
  
        private void Rebind(object e , EventArgs args)
        {
            client.GetSitesInformationAsync();
            client.GetSitesInformationCompleted += new EventHandler<PammsDataService.GetSitesInformationCompletedEventArgs>(client_GetSitesInformationCompleted);
        }
  
        private ObservableCollection<MapItem> GetMapData()
        {
            ObservableCollection<MapItem> data = new ObservableCollection<MapItem>();
            //data.Add(new MapItem("Sofia", new Location(9.45, 7.46), 5, new ZoomRange(5, 12)));
            //data.Add(new MapItem("Plovdiv", new Location(8.45, 7.46), 5, new ZoomRange(5, 12)));
            //data.Add(new MapItem("Burgas", new Location(5.45, 7.46), 5, new ZoomRange(5, 12)));
            //data.Add(new MapItem("Varna", new Location(4.45, 7.46), 5, new ZoomRange(5, 12)));
            return data;
        }
    }
}


please help also tell which is the best way to refresh the information layer when ever the data is updated in database. i am using WCF basichttpbinded service.

Regards,

Syed Fahad Anwar

1 Answer, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 17 Nov 2010, 11:25 AM
Hi Syed Anwar,

There are several possible issues here. The response time of the data service can be significantly more than 1 second in a real environment. You do not stop the timer when sending requests to server. So, let's suppose that response time for server will be from 2 to 5 seconds. In this case your application can send up to 5 requests to server before receiving the response for the first one. Then you will get all responses in a short time and force information layer to change data source. The resulting effect will be quite unpredictable. I would recommend you to have timer as class member and stop it when you send request to server and then start it when response will be processed. This way you always will operate with one result set in a time.

You setup completed event handler AFTER you send a request to server, and you do it every time when you refresh data. As result you can don’t get response for the first request (if it comes fast) and will increase number of the method call every time when you send next request. I would recommend assigning event handler once in main page constructor.

You change items source for the information layer to the NEW collection every time when you get a response. I would recommend you to have 1 collection which is set up as items source to information layer. When you process response you can clear this collection and add new items to it.

As for the tooltips -- in your data template you use standard Silverlight tooltip. Its behavior and location is controlled by Silverlight itself. We don’t anything in the RadMap to calculate location of the tooltip. The effect you’ve noticed (when tooltip appears at the left top corner) occurs when you point ellipse in the moment when correspondent map item is removed (you change items source or clear collection). This process take some time, so Silverlight tooltip service start the show tooltip process, but then can’t calculate real position, because object is removed. To minimize those cases I would recommend you increasing of the timer interval.

The prospective changes in your code could looks like the following:

public partial class MainPage : UserControl
{
    private DispatcherTimer timer = new DispatcherTimer(); 
    private ObservableCollection<MapItem> poiCollection = new ObservableCollection<MapItem>();
    PammsDataService.PammsDataServiceClient client = new PammsDataService.PammsDataServiceClient(); 
  
    public MainPage()
    {
        InitializeComponent();
  
        this.informationLayer.ItemsSource = this.poiCollection;
  
        this.client.GetSitesInformationCompleted += new EventHandler<PammsDataService.GetSitesInformationCompletedEventArgs>(client_GetSitesInformationCompleted);
  
        this.timer.Interval = new TimeSpan(0, 0, 5);
        this.timer.Tick += new EventHandler(this.Rebind); 
        this.radMap1.InitializeCompleted += new EventHandler(this.radMap1_InitializeCompleted); 
    }
  
    void radMap1_InitializeCompleted(object sender, EventArgs e) 
        
        this.timer.Start();
        
  
  
    private void Rebind(object e, EventArgs args)
    {
        this.timer.Stop();
        client.GetSitesInformationAsync();
    }
  
    void client_GetSitesInformationCompleted(object sender, PammsDataService.GetSitesInformationCompletedEventArgs e)
    {
        ObservableCollection<PammsDataService.Site> sites = e.Result;
  
        Dispatcher.BeginInvoke(() =>
            {
                this.poiCollection.Clear();
  
                foreach (PammsDataService.Site site in sites)
                {
                    MapItem mapItem = new MapItem(site.SiteName, new Location(site.Latitude, site.Longitude), 5, new ZoomRange(5, 12), site.Rating);
                    this.poiCollection.Add(mapItem);
                }
  
                timer.Start();
            });
    }
  
    // Rest of you code 
    // ...
  
}


Kind regards,
Andrey Murzov
the Telerik team
See What's New in RadControls for Silverlight in Q3 2010 on Tuesday, November 16, 2010 11:00 AM - 12:00 PM EST or 10:00 PM - 11:00 PM EST: Register here>>
Tags
Map
Asked by
Syed Anwar
Top achievements
Rank 1
Answers by
Andrey
Telerik team
Share this question
or