0

I am working on a UWP navigation app.

What I want to do?

  1. I want to draw multiple (10 to be exact) polylines on the Map control.
  2. I want one to be different color, while the others are grey.
  3. Once either of the polyline is selected the new selected polyline becomes of the primary color while the others are greyed out. Something like the Maps app for multiple routes just on a larger scale that shows movements of shipping trucks.

Everywhere online there are ways to implement the polyline via c# or code behind, but I want to do it via XAML as adding 10 polylines from codebehind doesn't give much flexibility with events and opacity and Tags and Names.

What all have I tried:

I tried creating an attached polyline to the mapElement but the issue with the approach is that I'll have to each time remove and recreate the polyline to change colors. More about this here. Also, it's just a pretty way of implementing polyline from code behind.

What am I doing currently:

I added the DataTemplate of the PolyLine in my Page.Resources like below:

 <DataTemplate x:Key="PolylineDataTemplate" x:DataType="polyLineData:IPolylinePath">
        <Polyline Points="{x:Bind Polyline,Mode=OneWay}" Fill="{x:Bind PolylineColor,Mode=OneWay}" Tag="{x:Bind PolylineTag,Mode=OneWay}" StrokeThickness="{x:Bind PolylineThinkness}" />
    </DataTemplate>`

Where the IPolylinePath is defined as:

public interface IPolylinePath
{
    SolidColorBrush PolylineColor { get; set; }

    int PolylineThinkness { get; set; }

    string PolylineTag { get; set; }

    IEnumerable<IBasicGeoposition> PolylinePoints { get; set; }

    Geopath PolylineGeopath { get; }

    PointCollection Polyline { get; }
}`

My Polyline property is populated as below:

 public PointCollection Polyline
    {
        get
        {
            PointCollection returnObject = new PointCollection();
            //could have used LINQ but wanted to check if the collection is being populated correctly
            foreach (var location in PolylinePoints)
            {
                returnObject.Add(new Windows.Foundation.Point(location.Latitude, location.Longitude));
            }
            return returnObject;
        }
    }

And I am just calling it in the MapItems control like below:

<maps:MapControl x:Name="MyMap"  >
                <maps:MapItemsControl ItemTemplate="{StaticResource PolylineDataTemplate}" ItemsSource="{x:Bind ViewModel.PolylinePoints}"/>
            </maps:MapControl>

The Issue is:

The code works perfectly well. Just the polyline is not visible. I thought that it's just small that's why I can't see it. So I increased the size and the distance and it just appears as a small arc on the top left corner (with some spacing) and doesn't get scoped or panned.

Can anyone please help?

Community
  • 1
  • 1
iam.Carrot
  • 4,976
  • 2
  • 24
  • 71

1 Answers1

1

Just the polyline is not visible.

Firstly, it seems like you didn't give a Stoke property for the Polyline, by default it is null. Your code snippet set color with Fill property it is not for the color of the line, you may find the value of StrokeThickness has no influence with the Polyline and a straight line will not been seen without the Stroke property. So here the color should be bind to Stroke property.

it just appears as a small arc on the top left corner

It is because you build points of the Points property for the Polyline by code line new Windows.Foundation.Point(location.Latitude, location.Longitude). The latitude and longitude defined the element location on the MapControl not the application view. In another words, actually you add a GeoPoint to the PointCollection, not a Point. So you may need to transfer the GeoPoint to Point by GetOffsetFromLocation(Geopoint, Point) method.

doesn't get scoped or panned.

For this, the Polyline is actually a shape not a MapElement. You should control its MapLocation by listening the map zoom events. If you want it be pan with the map, you should use Map​Polyline. For sample of this please reference the scenario 2 of the official sample. But MapPolyline cannot be added directly by binding, only code behind.

A completed simple sample based on yours for testing as follows:

XAML

<Page.Resources>
   <DataTemplate x:Key="PolylineDataTemplate" x:DataType="local:PolylinePath">
       <Polyline
           Points="{x:Bind Polyline}"
           Stroke="{x:Bind PolylineColor}"
           StrokeThickness="{x:Bind PolylineThinkness}"
           Tag="{x:Bind PolylineTag}" />
   </DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
   <maps:MapControl x:Name="MyMap" Loaded="MyMap_Loaded">
       <maps:MapItemsControl x:Name="mapitems" ItemTemplate="{StaticResource PolylineDataTemplate}" />
   </maps:MapControl>
   <Button
       x:Name="btnaddpolyline"
       Click="btnaddpolyline_Click"
       Content="add" />
</Grid>

Code behind:

public sealed partial class MainPage : Page
{
    public List<PolylinePath> polylines { get; set; }
    Geopoint SeattleGeopoint = new Geopoint(new BasicGeoposition() { Latitude = 47.604, Longitude = -122.329 });       
    public MainPage()
    {
        this.InitializeComponent();
    }
    private void MyMap_Loaded(object sender, RoutedEventArgs e)
    {
        MyMap.Center = SeattleGeopoint;
        MyMap.ZoomLevel = 16;
    }
    private void btnaddpolyline_Click(object sender, RoutedEventArgs e)
    {
        polylines = new List<PolylinePath>()
        {
            new PolylinePath(MyMap)
            {
                PolylineColor=new SolidColorBrush(Colors.Red),
                PolylineThinkness=3,
                PolylineTag="testing",
                PolylinePoints = new List<BasicGeoposition>()
                {
                    SeattleGeopoint.Position,
                    new BasicGeoposition()
                    {
                        Latitude = SeattleGeopoint.Position.Latitude + 0.003,
                        Longitude = SeattleGeopoint.Position.Longitude - 0.003
                    }
                }
            }
        };
        mapitems.ItemsSource = polylines;
    }
}
public class PolylinePath
{
    public PolylinePath(MapControl MyMap)
    {
        this.MyMap = MyMap;
    }
    MapControl MyMap;
    public SolidColorBrush PolylineColor { get; set; }

    public int PolylineThinkness { get; set; }

    public string PolylineTag { get; set; }

    public IEnumerable<BasicGeoposition> PolylinePoints { get; set; }

    public PointCollection Polyline
    {
        get
        {
            PointCollection returnObject = new PointCollection();
            //could have used LINQ but wanted to check if the collection is being populated correctly
            foreach (var location in PolylinePoints)
            {
                Point actualpoint;
                MyMap.GetOffsetFromLocation(new Geopoint(location), out actualpoint);
                returnObject.Add(actualpoint);
            }
            return returnObject;
        }
    }
}
Sunteen Wu
  • 10,509
  • 1
  • 10
  • 21
  • thank you for the answer, but This doesn't work that well. neither does it zoom or move it looks more like a blot on the map. Using a MapPolyline which can only be plot from codebehind can you please advise a way to plot more than one MapPolyline and change their colors when one is selected? It'll be of great help. – iam.Carrot May 12 '17 at 04:07
  • @AdityaSharma, There is no API in uwp map control that make `MapPloyline` selected. It seems like you are looking for more power features. For this you can try to use [Bing map service](https://www.microsoft.com/maps/choose-your-bing-maps-API.aspx). [Here](https://github.com/Microsoft/Windows-appsample-trafficapp) is a UWP sample that has similar features you want you can reference. – Sunteen Wu May 23 '17 at 08:29
  • Thank you for the guide. Just one last quick question, does using the Bing map SDK allow to provide a custom map tile source? via vector or raster ways? I have a heat and transport activity tile layer to be displayed instead of the Map aerial or other views. is it possible? it'll be of great help. +1 for the links. – iam.Carrot May 23 '17 at 16:20
  • @AdityaSharma, I guess the answer is yes. It seems like `MapControl` also have relative features, if `MapControl` has, Bind should be able do. Check [this](https://learn.microsoft.com/en-us/windows/uwp/maps-and-location/overlay-tiled-images). If you have new issues you can open new threads we will deal with them in time. Thanks for understanding. – Sunteen Wu Jun 02 '17 at 09:40
  • I am sorry for prolonging this, but I wasn't able to find a way to use vector tiles on the Map Control in UWP. I do have a thread open [Here](https://stackoverflow.com/questions/41565154/vector-map-tiles-on-bing-map-control) the answer was quite different, it makes me first get the vector tiles and then make them into raster ones and then use it as a httpp tile source. Could you please provide a much direct answer? – iam.Carrot Jun 04 '17 at 16:54