This project has moved. For the latest updates, please go here.

MapPolyLine Locations of Different Type

Nov 7, 2014 at 10:32 AM
Hello,

This control is simply great work.

Any idea why the following doesn't render?

<map:MapPolyline Locations="{Binding Path=Map.Waypoints, Converter={StaticResource WaypointToLocationConverter}}" StrokeThickness="2" Stroke="#fff100" Fill="Black"/>

Map.Waypoints is a of type ObservableCollection<IWaypoint> and WaypointToLocationConverter simply returns a new Location from an IWaypoint, I'm hitting a breakpoint there per IWaypoint.

Thanks!
Superware
Coordinator
Nov 7, 2014 at 11:17 AM
May sound stupid, but when your breakpoint gets hit, did you also check that the Locations are created with correct values, i.e. Latitude and Longitude in degrees, not radians or meters or whatever?

What is the parent control of the MapPolyline? Is it a MapPanel (e.g. in a MapItemsControl), or the Map control directly?

Which platform are you using?
Nov 7, 2014 at 11:31 AM
Thank you for your quick reply.
  • Yes, the created locations are correct (same Map.Waypoints is being used in a MapItemsControl to show waypoint items).
  • The map control itself is the parent, but I also tried MapItemsControl per the Samples project.
  • I'm on Windows 7/WPF.
Thanks again!
Nov 7, 2014 at 11:38 AM
Maybe this is the wrong approach altogether.

How would you implement a full route? showing waypoints and connecting lines? I also need each waypoint to be moveable with a final Moved/ChangedLocation event :)

Thanks.
Coordinator
Nov 7, 2014 at 12:07 PM
Edited Nov 7, 2014 at 2:05 PM
It should work, provided that your converter is correct. I've added the following line as the last direct child of the Map control in the WPF sample application, and it correctly shows the polyline data from the sample applications' view model. Note also that I've left out the Fill property.
<map:MapPolyline Locations="{Binding Path=Polylines[0].Locations}" StrokeThickness="2" Stroke="#fff100"/>
Nov 7, 2014 at 1:27 PM
Edited Nov 7, 2014 at 1:27 PM
Well, this is the converter:
class WaypointToLocationConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is IWaypoint)
        {
            var waypoint = (IWaypoint)value;
            return new Location(waypoint.Lat, waypoint.Lon);
        }
        return null;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
It's also being used successfully like this:
<map:MapItemsControl ItemsSource="{Binding Map.Waypoints}"
                                 ItemContainerStyle="{StaticResource WaypointStyle}"
                                 IsSynchronizedWithCurrentItem="True"/>
<Style x:Key="WaypointStyle" TargetType="map:MapItem">
    <Setter Property="map:MapPanel.Location" Value="{Binding Path=., Converter={StaticResource WaypointToLocationConverter}}"/>
    ...
</Style>
Any ideas?
Coordinator
Nov 7, 2014 at 1:53 PM
Edited Nov 7, 2014 at 1:55 PM
In a binding like
Locations="{Binding Path=Map.Waypoints, Converter={StaticResource WaypointToLocationConverter}}"
the converter must convert a collection of waypoint objects to a collection of Location objects. Yours only converts single objects.
Nov 7, 2014 at 2:06 PM
Yeah, that's what I thought in the beginning, but I noticed the Convert object value is actually an IWaypoint :)
I guess WPF is iterating automatically to convert each item, but then again, this might not be working as expected.
Coordinator
Nov 7, 2014 at 2:16 PM
"I guess WPF is iterating automatically to convert each item". No, it isn't. The binding passes the value of the source property to the Convert method's value parameter.
Nov 7, 2014 at 11:14 PM
Yes, you were right, I'm sorry... :| now I can see the polyline :)

While the MapItemsControl (showing MapItem) is actually reflecting Waypoint changes in alt/lon, the MapPolyline stays the same.
They are both bound to Map.Waypoints, which is an ObservableCollection, any idea?

I really need to make a two-way binding with MapItems, so when one of them is being dragged/moved over the map their location will affect the bounded source. How would you approach this?

Isn't there an inherent problem with MapControl having it's own Location, while utilizing apps have their own ILocation/GeoCoordinate or whatever interface/class/structure in the Model/ViewModel/infrastructure level?

Thank you (again!)
Superware
Coordinator
Nov 8, 2014 at 8:24 AM
A view model is meant to be a "model of the view". So in case you have problems with converting collections from one element type to the other, it would be entirely acceptable to have a collection of MapControl.Location objects that represent your route in the view model.