ArcGIS API for Silverlight 自定义MarkerSymbol

概述

之前我们做ArcGIS开发的时候都是使用ArcEngine或是ArcServer ADF,展示给用户的都是一些图片,要做成好的效果动态效果基本上是很难的。,并且随着用户对界面体验的要求越来越高,GIS行业需要一种技术来满足客户的这种需求。随着ArcGIS10.0的发布,富客户端技术在GIS行业中的兴起,富客户端系统是在浏览器上运行的,必须安装该技术的运行环境插件,当我们访问这个地址时,浏览器会把我们开发的富客户端需要在客户端运行的包下载到本地,运行。这样相当于我们有相当一部分的代码是可以在客户端运行的,特别是UI模块,这就为我们在UI层做一些效果提供了可能性。

JS也算是一种富客户端技术,但js开发起来还是比较复杂的,而且不同的浏览器对js的支持也不尽相同。在我自己看来,我一直不认为js是一个典型的富客户端技术。我认为Flex和Silverlight都是很典型的富客户端技术,而且大家使用起来也比较方便。并且这两种技术都有自己的运行时,并且安装包也不算大,这样我们写的代码就不用考虑浏览器是否支持,只要客户端的运行环境支持该浏览器,那么我们写的代码该浏览器就能运行。这个是我个人感觉比较好的。

并且我自己主要还是使用C#,所以在选择富客户端开发方式时,肯定是要选择Silverlight的。这个和平台的前景关系不大,毕竟现在Silverlight能满足目前项目的需求。


使用API自带的MarkerSymbol

ArcGISMarkerSymbol相关的继承体系如下图所示:

简单符号样式、图片符号样式和文本样式。

通过简单符号样式,可以设置符号的颜色、大小、偏移量等信息,Style属性来控制符号的形状,包括圆形、三角、十字交叉等。

图片符号样式主要用图片来标识符号。

文本样式是用来标记文字的。

通过上述三种样式,基本上可以满足我们项目的需求,例如鼠标放上去,图标变大,离开图标变小。甚至变更图片等都可以,但是要做成动态效果,就没那么简单了。此时就用到了自定义MarkerSymbol。


自定义MarkerSymbol

因为MarkerSymbol是一个实体类,我们可以在此基础上自定义,并且MarkerSymbol最终是继承DependencyObject和INotifyPropertyChanged的,所以MarkerSymbol是可以绑定一个对象的。并且Symbol有ControlTemplate属性,说明我们是可以自定义模板的。其实下面自定义模板和GIS的关系不大了,主要是Silverlight的一些特性。

下面我们就定义一个报警闪烁的点样式,代码如下:

<esri:MarkerSymbol x:Key="DefaultAlarmMarkerSymbol">
        <esri:MarkerSymbol.ControlTemplate>
            <ControlTemplate>
                <Canvas>
                    <vsm:VisualStateManager.VisualStateGroups>
                        <vsm:VisualStateGroup x:Name="CommonStates">
                            <vsm:VisualState x:Name="Normal">
                                <Storyboard RepeatBehavior="Forever">
                                    <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" From="1" To="10" Duration="00:00:01" />
                                    <DoubleAnimation BeginTime="0:0:0" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" From="1" To="10" Duration="00:00:01" />
                                    <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.Opacity)" From="1" To="0" Duration="00:00:01" />
                                </Storyboard>
                            </vsm:VisualState>

                        </vsm:VisualStateGroup>
                    </vsm:VisualStateManager.VisualStateGroups>
                    <Ellipse Height="10" Width="10" Canvas.Left="-5" Canvas.Top="-5" RenderTransformOrigin="0.5,0.5" x:Name="ellipse" IsHitTestVisible="False">
                        <Ellipse.RenderTransform>
                            <ScaleTransform />
                        </Ellipse.RenderTransform>
                        <Ellipse.Fill>
                            <RadialGradientBrush>
                                <GradientStop Color="#00FF0000" />
                                <GradientStop Color="#FFFF0000" Offset="0.25" />
                                <GradientStop Color="#00FF0000" Offset="0.5" />
                                <GradientStop Color="#FFFF0000" Offset="0.75" />
                                <GradientStop Color="#00FF0000" Offset="1" />
                            </RadialGradientBrush>
                        </Ellipse.Fill>
                    </Ellipse>
                    <Ellipse Height="10" Width="10" Canvas.Left="-5" Canvas.Top="-5" Fill="#FFFF0000" x:Name="ellipse1" />
                </Canvas>
            </ControlTemplate>
        </esri:MarkerSymbol.ControlTemplate>
    </esri:MarkerSymbol>

下面我们就解释一下上述代码.

<esri:MarkerSymbol x:Key="DefaultAlarmMarkerSymbol"> 表示我们定义了一个MarkerSymbol类,关键字是DefaultAlarmMarkerSymbol。

<esri:MarkerSymbol.ControlTemplate>我们要定义MarkerSymbol的模板。

<Ellipse Height="10" Width="10" Canvas.Left="-5" Canvas.Top="-5"  RenderTransformOrigin="0.5,0.5" x:Name="ellipse" IsHitTestVisible="False">
                        <Ellipse.RenderTransform>
                            <ScaleTransform />
                        </Ellipse.RenderTransform>
                        <Ellipse.Fill>
                            <RadialGradientBrush>
                                <GradientStop Color="#00FF0000" />
                                <GradientStop Color="#FFFF0000" Offset="0.25" />
                                <GradientStop Color="#00FF0000" Offset="0.5" />
                                <GradientStop Color="#FFFF0000" Offset="0.75" />
                                <GradientStop Color="#00FF0000" Offset="1" />
                            </RadialGradientBrush>
                        </Ellipse.Fill>
                    </Ellipse>
                    <Ellipse Height="10" Width="10" Canvas.Left="-5" Canvas.Top="-5" Fill="#FFFF0000" x:Name="ellipse1" />

这段代码定义了两个椭圆,一个椭圆的名字叫ellipse,另一个叫ellipes1。

RenderTransformOrigin 以较为非标准的方式使用 Point 结构值,因为 Point 不表示坐标系统中的绝对位置。 相反,0 和 1 之间的值被解释为当前元素在每个 X 轴和 Y 轴上的范围的因子。 例如,(0.5,0.5) 将使呈现转换位于元素中心,而 (1,1) 会将呈现转换置于元素的右下角。 NaN 不是一个接受的值。

RadialGradientBrush,定义渲染颜色,根据透明度和颜色的定义可以形成一个个的圈。

<vsm:VisualStateManager.VisualStateGroups>
                        <vsm:VisualStateGroup x:Name="CommonStates">
                            <vsm:VisualState x:Name="Normal">
                                <Storyboard RepeatBehavior="Forever">
                                    <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" From="1" To="10" Duration="00:00:01" />
                                    <DoubleAnimation BeginTime="0:0:0" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" From="1" To="10" Duration="00:00:01" />
                                    <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.Opacity)" From="1" To="0" Duration="00:00:01" />
                                </Storyboard>
                            </vsm:VisualState>

                        </vsm:VisualStateGroup>

该部分代码是定义MarkerSymbol在各种状态下的表现形式。

<vsm:VisualStateGroup x:Name="CommonStates">//表示普通状态,普通状态包括Normal(默认状态)、Disabled (控件被禁用)、MouseOver(当鼠标位于控件上方时)
<pre name="code" class="html"><vsm:VisualState x:Name="Normal">//由此代码可以看出,该节点包含的代码都是作用于控件的默认状态的。
<pre name="code" class="html"><Storyboard RepeatBehavior="Forever">//代码定义了动画,动画的播放模式是循环播放

//共有三个动画模式,都是针对Double数值的
<DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" From="1" To="10" Duration="00:00:01" />
//针对的对象是ellipse,也就是我们定义的第一个椭圆。针对的属性是椭圆的渲染变换对象。该对象初始化为缩放变换对象,并且对象的X方向的值从1变换到10,用时1秒。
<DoubleAnimation BeginTime="0:0:0" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" From="1" To="10" Duration="00:00:01" />
<pre name="code" class="html"><pre name="code" class="html"><pre name="code" class="html">//针对的对象也是ellipse,把Y方向缩放量值从1变换到10,用时1秒。

 
  <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.Opacity)" From="1" To="0" Duration="00:00:01" /> 
 
<pre name="code" class="html"><pre name="code" class="html"><pre name="code" class="html"><pre name="code" class="html"><pre name="code" class="html">//针对的对象也是ellipse,设置的属性书透明度,从1变为0,用时1秒,也就是从显示慢慢变成透明。
 
 
 
 
 
 
 

通过上面的代码我们可以想象一下,效果是符号有一个半径为5的红色圆形符号一直显示,然后另一个两个环的红色的符号变放大、边消失。

大致就是这个效果了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值