Bing 地图控件上的地图折线

Map Polyline on Bing Map Control

我正在开发 UWP 导航应用程序。

我想做什么?

  1. 我想在地图控件上绘制多条(准确地说是 10 条)折线。
  2. 我想要一个不同的颜色,而其他的是灰色的。
  3. 一旦选择了其中一条多段线,新选择的多段线就会变成原色,而其他多段线则变灰。类似地图应用程序的多条路线,只是在更大范围内显示运输卡车的移动。

网上到处都有通过 c# 或代码隐藏实现多段线的方法,但我想通过 XAML 来实现,因为从代码隐藏中添加 10 条多段线不会给事件、不透明度和标签带来太大的灵活性和名字。

我都试过了:

我尝试为 mapElement 创建一条附加的多段线,但该方法的问题是我每次都必须删除并重新创建多段线以更改颜色。有关此 的更多信息。此外,它只是从代码隐藏实现折线的一种很好的方式。

我现在在做什么:

我在 Page.Resources 中添加了 PolyLine 的数据模板,如下所示:

 <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>`

其中 IPolylinePath 定义为:

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; }
}`

我的 Polyline 属性 填充如下:

 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;
        }
    }

我只是在 MapItems 控件中调用它,如下所示:

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

问题是:

代码运行良好。只有折线不可见。 我以为它很小,所以我看不到它。所以我增加了大小和距离,它只是在左上角显示为一个小圆弧(有一些间距)并且没有被范围或平移。

有人可以帮忙吗?

Just the polyline is not visible.

首先,您似乎没有给出 Stoke property for the Polyline,默认情况下它是空的。您的代码片段设置颜色 Fill 属性 它不是用于线条的颜色,您可能会发现 StrokeThickness 的值对 Polyline 和直线没有影响没有 Stroke 属性 就看不到行。所以这里的颜色应该绑定到 Stroke 属性.

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

这是因为您通过代码行 new Windows.Foundation.Point(location.Latitude, location.Longitude)Polyline 创建了 Points 属性 的点。 纬度和经度定义了 MapControl 上的元素位置,而不是应用程序视图。换句话说,实际上你添加了一个GeoPoint to the PointCollection, not a Point. So you may need to transfer the GeoPoint to Point by GetOffsetFromLocation(Geopoint, Point)方法。

doesn't get scoped or panned.

为此,Polyline 实际上是 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。但是MapPolyline不能通过绑定直接添加,只能代码隐藏。

根据您的测试完成的简单样本如下:

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>

后面的代码:

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;
        }
    }
}