【问题标题】:Displaying pushpins on a map在地图上显示图钉
【发布时间】:2014-09-19 19:52:20
【问题描述】:

我很难将图钉添加到以我喜欢的方式工作的地图中。

首先,我尝试添加 MapItemsControl 并绑定到它。

<map:MapItemsControl ItemsSource="{Binding Path=Locations}">
    <map:MapItemsControl.ItemTemplate>
        <DataTemplate>
            <controls:NumberedCircle Number="{Binding Path=Number}" map:MapControl.Location="{Binding Path=Point}"/>      
        </DataTemplate>
    </map:MapItemsControl.ItemTemplate>
</map:MapItemsControl>

这可行,但是当您平移地图时看起来绝对糟糕;地图平移和图钉图标赶上它们应该在的位置之间存在非常明显的延迟。如果我来回平移地图的速度足够快,我就可以从街道的一侧跳到另一侧。列表中只有一项会发生这种情况,因此地图不会被淹没。

这是一个效果视频:http://youtu.be/9FIvkOf71bg

接下来我尝试将 MapIcons 添加到 MapElements 集合中。这是在行为中完成的,因为我使用的是 MVVM,但总体思路是

var mapIcon = new MapIcon() { Location = pushpinDrawBehavior.Location};
mapControl.MapElements.Add(mapIcon);

这很好用。我平移地图,无论我平移多快,MapIcon 都会准确地停留在它应该在的位置。完全没有迟钝的行为。但是 - 当您放大和缩小时,MapIcon 会出现和消失,如文档中所述:

不保证会显示 MapIcon。它可能隐藏时 遮挡地图上的其他元素或标签。

我很沮丧,因为我有两种方法可以将图钉添加到地图中,而且由于不同的原因,它们都会造成糟糕的用户体验。所以,问题是:

1) 我错过了什么吗?有没有办法让 XAML 元素不落后于 pan?有没有办法让 MapIcons 始终可见?

2) 有没有办法创建一个行为类似于 MapIcon 的自定义类?它派生自 MapElement,但我看不到图钉的实际渲染是如何完成的,或者图像、标题等的布局是如何定义的。如果我可以创建自己的 MapIcon,我可能会禁用隐藏行为。

编辑:在诺基亚 925 上运行应用程序,效果不太明显(上面的视频来自 521)。保持 XAML 覆盖与地图同步似乎是处理器密集型的,并且在较小的硬件上会更糟。

【问题讨论】:

  • 嗨,保罗,从那以后你有什么新东西要添加的吗?注意到同样的效果。

标签: xaml windows-phone-8.1


【解决方案1】:

恐怕要告诉你,除了减少元素的数量或图钉的 XAML 代码的复杂性之外,你无能为力。

MapIcon 和 MapElements 的区别在于 MapIcon 是直接发送到地图控件并在那里呈现的位图,而 MapElements 是 XAML 元素并由 XAML 线程呈现。延迟是由于地图线程中的地图交互与应用程序的 UI 线程之间需要同步造成的。

您可以尝试将图钉的 XAML 作为位图(请参阅 RenderTargetBitmap)。渲染可能需要一些时间,但您可以将它们用于 MapIcons。但是,几个月前我尝试过,发现无法一直显示 MapIcons。

由于我也在开发一个应用程序,我希望 MapIcons 始终可见,所以我们希望将来 Map 组件会有变化。地图中有很多错误,例如我也无法更改图钉的锚点...MS 可以在这里改进很多。

编辑:要了解有关地图控件和 MapIcons/MapElements/... 的更多信息,请查看 this BUILD conference talk

【讨论】:

  • 任何想法我可以从会议演讲中找到他们的源代码。
【解决方案2】:

这可能是一个长镜头(而且不太漂亮),但请尝试在 UI 线程上填充 MapItemsControl

为图钉创建一个类:

public class PushpinData
{
    public GeoCoordinate Location { get; set; }
    public string Text { get; set; }
    public SolidColorBrush DisplayBrush { get; set; }
}

使用DataTemplate 为图钉创建您的MapControl

xmlns:maps="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"
xmlns:maptk="clr-namespace:Microsoft.Phone.Maps.Toolkit;assembly=Microsoft.Phone.Controls.Toolkit"

<maps:Map x:Name="mapControl" >
    <maptk:MapExtensions.Children>
    <maptk:MapItemsControl x:Name="PushpinLayer">
        <maptk:MapItemsControl.ItemTemplate>
            <DataTemplate>
                <maptk:Pushpin GeoCoordinate="{Binding Location}" 
                Content="{Binding Text}" 
                Background="{Binding DisplayBrush}"/>
            </DataTemplate>
        </maptk:MapItemsControl.ItemTemplate>
    </maptk:MapItemsControl>
    </maptk:MapExtensions.Children>
</maps:Map>

在视图和地图控件的Loaded 事件中声明您的图钉列表,获取对MapItemsControl 的引用并分配其ItemsSource

using Microsoft.Phone.Maps.Toolkit;

ObservableCollection<PushpinData> pushpinList = new ObservableCollection<PushpinData>();

mapControl.Loaded += (s, e) =>
  {
    ObservableCollection<DependencyObject> children = MapExtensions.GetChildren(mapControl);
    var pushPinLayer = children.FirstOrDefault(x => x.GetType() == typeof(MapItemsControl)) as MapItemsControl;
    pushPinLayer.ItemsSource = pushpinList;
  }

一旦你有了它,你就可以填充pushpinList。为了避免破坏 MVVM,您当然可以通过 Messenger 从您的 VM 接收图钉列表。还要确保您的图钉集合仅包含在任何给定时间显示的图钉集合。

【讨论】:

  • 谢谢,但 Microsoft.Phone.Maps 是 WP 8.0 的命名空间;我在 8.1,他们改变了一切(再次)。
  • 哦...我以为您的目标是 WP8.1 Silverlight(或者那里也缺少它...)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
相关资源
最近更新 更多