2
votes

I have been working over a GPS mapping application where NMEA data from a GPS (L76) development board is obtained via a serial port. The CSV data is parsed and the longitude/latitude information is then saved in a Queue. The objective is to dynamically display pushpins on a WPF-based mapping application as and when the location information is available via the serial port.

<WPF:Map Name="XAMLMap" ZoomLevel="17" CredentialsProvider="the key" Mode="road" Margin="241,157,10.334,10">
</WPF:Map>

The application successfully displays its initial Bing Map display via the code given below:

Dispatcher.Invoke(() =>
{
    XAMLMap.CredentialsProvider = new ApplicationIdCredentialsProvider("the key");
    XAMLMap.Center = new Microsoft.Maps.MapControl.WPF.Location(50.8, -1.12222);

    Pushpin currentPushpin = new Pushpin();
    currentPushpin.Location = new Microsoft.Maps.MapControl.WPF.Location(50.8, -1.12222);
    XAMLMap.ZoomLevel = 18;
    XAMLMap.Margin = new Thickness(243, 151, 0, 0);
    XAMLMap.Children.Add(currentPushpin);
    mapGrid.Children.Add(XAMLMap);
});

However, the actual challenge appears when the push pin Location coordinates are generated dynamically from the serial data within the following event method:

void serialPortHandler_NewSerialDataRecieved(object sender, SerialDataEventArgs e)
{
    AddLocation(currentLocation);
}

private void AddLocation(Location location)
{
    Dispatcher.Invoke(() =>
    {
        try
        {                           
            Microsoft.Maps.MapControl.WPF.Location currentLocation = new Microsoft.Maps.MapControl.WPF.Location(location.latitude, location.longitude);

            Pushpin currentPushpin = new Pushpin();
            currentPushpin.Location = currentLocation;    
            XAMLMap.Margin = new Thickness(243, 151, 0, 0);                        
            XAMLMap.Children.Add(currentPushpin);
            mapGrid.Children.Add(XAMLMap);    
        }
        catch (Exception exc)
        {    
        }
    });
} 

The updated coordinate latitude/longitude values are still placed properly on the map (XAMLMap). However, when the map is zoomed-out/in or panned, the map content, i.e. the roads, geographical details, resolution, do not update at all i.e. newly visible map information is not updated at all leaving a jigsaw of irregular patches.

Also, please note that the problem has nothing to do with the way I am adding the XAMLMap object to the grid in the code above or any other children.

I've looked into various possibilities to resolve this issue but have been unsuccessful so far. This also includes:

  1. Keeping the mapping application over a separate thread
  2. Using a timer control and using Peek method to return and display the top-most location object from the Queue

Any help or direction in this regard would be highly appreciated.

1

1 Answers

2
votes

It looks like your code keeps adding the map to the Grid. You should create the map once in XAML and set the credentials there only. There is not need to set the credentials in code. I'm also not sure why you are changing the margin of the map when adding a pushpin. No need for that code either.

You AddLocation method should look something like this:

private void AddLocation(Location location)
{
    Dispatcher.Invoke(() =>
    {
        try
        {                           
Microsoft.Maps.MapControl.WPF.Location currentLocation = new Microsoft.Maps.MapControl.WPF.Location(location.latitude, location.longitude);

            Pushpin currentPushpin = new Pushpin();
            currentPushpin.Location = currentLocation;                         
            XAMLMap.Children.Add(currentPushpin);
        }
        catch (Exception exc)
        {    
        }
    });
}