如何将ArcGIS用于具有数据绑定的WPF自定义符号



Esri的ArcGIS for WPF似乎没有任何真正的MVVM支持或绑定支持;除非我弄错了。

无论如何,我正在创建一个跟踪应用程序,它需要通过GPS坐标来跟踪对象。

我已经实现了一个与GpsLayer一起使用的自定义IGeoPositionWatcher<GeoCoordinate>。这一切都很完美。我可以修改GPS坐标,我在地图上的小圆点就会顺利地移动到它的最后安息之地。我的问题是我不能使用GpsLayer附带的小圆点和箭头。我需要一个自定义的MarkerSymbol类似于以下内容:

<Grid>
   <Image Source="{Binding Pogostick.HeightImage}" />
   <TextBlock Text="{Binding Pogostick.PogoId}" />
</Grid>

我有一个这些"pogostick"的列表(数量未知,随时变化),它们总是通过GPS跟踪,需要根据其状态更新符号。问题是,我无法将Pogostick对象作为自定义MarkerSymbol.ControlTemplateDataContext,并且我的图像源和文本不显示。

我试图避免在GraphicLayer中使用Graphic,并希望它能用于GpsLayer。有办法做到这一点吗?我是否正确地处理了这个问题。。。我应该使用GraphicLayer还是FeatureLayer

我想在用户的桌面应用程序上呈现这些跟踪的pogostick,而不是通过编辑地图服务上的图层或功能。也许我应该使用自定义渲染器?

我已经找到了一种方法。我创建了一个继承自MarkerSymbol的类,它有一个DependencyProperty,它保存了我想要绑定的对象(Pogostick类)。

public class EntityMarkerSymbol : MarkerSymbol
{
    public static readonly DependencyProperty EntityProperty;
    static EntityMarkerSymbol()
    {
        EntityMarkerSymbol.EntityProperty = DependencyProperty.Register("Entity", typeof(object), typeof(EntityMarkerSymbol), new PropertyMetadata());
        return;
    }
    public EntityMarkerSymbol()
    {
        return;
    }
    public object Entity
    {
        get { return this.GetValue(EntityMarkerSymbol.EntityProperty); }
        set { this.SetValue(EntityMarkerSymbol.EntityProperty, value); }
    }
}

然后我在资源字典中创建一个ControlTemplate,如下所示:

<ControlTemplate x:Key="PogostickMarker">
    <StackPanel>
        <Image Source="{Binding Symbol.Entity.HeightImage}" />
        <TextBlock Text="{Binding Symbol.Entity.PogostickId}" />
    </StackPanel>
</ControlTemplate>

这项工作的关键是,WPF的ArcGIS将自动将MarkerSymbolDataContext分配给它的密封类DataBinding,该类包含对分配给GpsLayerLocationMarkerSymbolMarkerSymbol的引用。因此,我可以通过此绑定访问我的自定义符号Entity属性。

用于创建GpsLayer和分配MarkerSymbol的代码如下:

GpsLayer layer = new GpsLayer();
EntityMarkerSymbol marker = new EntityMarkerSymbol() { Entity = pogoStick };
marker.ControlTemplate = Application.Current.Resources["ConvoyMarker"] as ControlTemplate;
layer.LocationMarkerSymbol = marker;

注意:当映射的UseAcceleratedDisplay属性设置为True时,不能使用此方法。如果有人能想出如何在该属性设置为true的情况下使用这种方法,请告诉我。

最新更新