WPF Arcgis 开发实现带有图片和标题的渲染图标

WPF开发Arcgis的时候如果在地图上添加点图标是很容易实现的,自定义一下Symbol的模板即可实现。但是如果模板中标题文字不固定的时候,点图标没法做偏移(点图标在地图上锚定的时候是以左上角的点位锚定点,如果图标的下部中点和锚点重合就没有这个问题),这样会造成放大和缩小地图的时候点图标乱动的效果。线面介绍一种做偏移的方法,基本思路是使用3个俯角属性绑定模板中控件的实际宽高及模板数据源Symbol,然后处理偏移,OffsetX取实际宽的一半,OffsetY取实际高度,代码如下:
首先自定义一个点图标(使用现有的PictureMarkerSymbol也行,但是需要附加属性控制字体颜色背景之类的)
///
/// 模块编号:控件库
/// 作用:带有图片及标题的地图点标识
/// 作者:丁纪名
/// 编写日期:2018-01-22
///
public class TitlePictureMarkerSymbol : MarkerSymbol
{
///
/// 图片数据源
///
public ImageSource Source
{
get { return (ImageSource)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}

    // Using a DependencyProperty as the backing store for Source.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SourceProperty =
        DependencyProperty.Register("Source", typeof(ImageSource), typeof(TitlePictureMarkerSymbol), new PropertyMetadata(null));
    /// <summary>
    /// 标题
    /// </summary>
    public string Title
    {
        get { return (string)GetValue(TitleProperty); }
        set { SetValue(TitleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TitleProperty =
        DependencyProperty.Register("Title", typeof(string), typeof(TitlePictureMarkerSymbol), new PropertyMetadata(null));
    /// <summary>
    /// 标题字体大小
    /// </summary>
    public double FontSize
    {
        get { return (double)GetValue(FontSizeProperty); }
        set { SetValue(FontSizeProperty, value); }
    }

    // Using a DependencyProperty as the backing store for FontSize.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FontSizeProperty = TextElement.FontSizeProperty.AddOwner(
                    typeof(TitlePictureMarkerSymbol),
                    new FrameworkPropertyMetadata(SystemFonts.MessageFontSize,
                        FrameworkPropertyMetadataOptions.Inherits));
    /// <summary>
    /// 标题前景色
    /// </summary>
    public Brush Foreground
    {
        get { return (Brush)GetValue(ForegroundProperty); }
        set { SetValue(ForegroundProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Foreground.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ForegroundProperty = TextElement.ForegroundProperty.AddOwner(
                    typeof(TitlePictureMarkerSymbol),
                    new FrameworkPropertyMetadata(SystemColors.ControlTextBrush,
                        FrameworkPropertyMetadataOptions.Inherits));
    /// <summary>
    /// 文本背景色
    /// </summary>
    public Brush Background
    {
        get { return (Brush)GetValue(BackgroundProperty); }
        set { SetValue(BackgroundProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Background.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BackgroundProperty = Panel.BackgroundProperty.AddOwner(typeof(TitlePictureMarkerSymbol),
                new FrameworkPropertyMetadata(
                    Panel.BackgroundProperty.DefaultMetadata.DefaultValue,
                    FrameworkPropertyMetadataOptions.None));

    public static double GetWidth(DependencyObject obj)
    {
        return (double)obj.GetValue(WidthProperty);
    }

    public static void SetWidth(DependencyObject obj, double value)
    {
        obj.SetValue(WidthProperty, value);
    }

    // Using a DependencyProperty as the backing store for Width1.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty WidthProperty =
        DependencyProperty.RegisterAttached("Width", typeof(double), typeof(TitlePictureMarkerSymbol), new FrameworkPropertyMetadata(default(double), new PropertyChangedCallback(OnWidthChanged)));

    private static void OnWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement element = d as FrameworkElement;
        if (element != null)
        {
            TitlePictureMarkerSymbol symbol = TitlePictureMarkerSymbol.GetSymbol(element) as TitlePictureMarkerSymbol;
            if (symbol != null)
            {
                symbol.OffsetX = element.ActualWidth / 2;
            }
        }
    }

    public static double GetHeight(DependencyObject obj)
    {
        return (double)obj.GetValue(HeightProperty);
    }

    public static void SetHeight(DependencyObject obj, double value)
    {
        obj.SetValue(HeightProperty, value);
    }

    // Using a DependencyProperty as the backing store for Height1.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HeightProperty =
        DependencyProperty.RegisterAttached("Height", typeof(double), typeof(TitlePictureMarkerSymbol), new FrameworkPropertyMetadata(default(double), new PropertyChangedCallback(OnHeightChanged)));

    private static void OnHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement element = d as FrameworkElement;
        if (element != null)
        {
            TitlePictureMarkerSymbol symbol = TitlePictureMarkerSymbol.GetSymbol(element) as TitlePictureMarkerSymbol;
            if (symbol != null)
            {
                symbol.OffsetY = element.ActualHeight;
            }
        }
    }

    public static object GetSymbol(DependencyObject obj)
    {
        return (object)obj.GetValue(SymbolProperty);
    }

    public static void SetSymbol(DependencyObject obj, object value)
    {
        obj.SetValue(SymbolProperty, value);
    }

    // Using a DependencyProperty as the backing store for Symbol.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SymbolProperty =
        DependencyProperty.RegisterAttached("Symbol", typeof(object), typeof(TitlePictureMarkerSymbol), new PropertyMetadata(null));
}

定义模板:
这里写图片描述
使用方式:
var symbol = new TitlePictureMarkerSymbol
{
Source = img,
Background = Brushes.DimGray,
FontSize = 12,
Foreground = Brushes.White
};
symbol.ControlTemplate = SymbolResource.Resource[“TitlePictureMarkerSymbolStyle”] as ControlTemplate;
如此即可实现不固定宽度的图片文本点图标了。

猜你喜欢

转载自blog.csdn.net/yulongguiziyao/article/details/79147740