本博文的软件环境如下:
操作系统:win7
ArcGIS 版本 ArcGIS 10.1,以及发布的要素服务。
开发工具VS2010sp1+ArcGIS API for Silverlight 3.0+Silverlight 4.0
关于要素服务
通过上一篇博客,已经给大家介绍了,第一次发布要素服务可能会遇到的一些问题,接下来,我们要开始使用要素服务。我们发布的要素服务的时候,在Capabilities里面选中了FeatureAccess和Maping,也就是我们发布了两个服务,一个地图服务和一个要素服务。这里我们只取要素服务(地图服务可以用来当做底图,同时也可以查询要素),其次是确定编辑图层,我这里选择了第一个图层,这个图层可以在前端通过FeatureLayer来显示,这里的编辑主要包括,增加要素,改变要素的形状,改变要素的属性。删除要素。
http://localhost:6080/arcgis/rest/services/FeatureService/FeatureServer/0
开始开发Demo:环境VS2010sp1+ArcGIS API for Silverlight 3.0+Silverlight 4.0,要素服务地址
http://localhost:6080/arcgis/rest/services/FeatureService/FeatureServer
底图地址:http://www.arcgisonline.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer。
增加要素。
我首先要在Map 上绘制一个要素,我在这里使用了Draw ,这个工具也挺好用的。只要与一个地图进行绑定我们既可以实现绘制点线面,只需要设置绘制的模式(点,线,面)以及绘制的符号。
当我们绘制之后可以得到一个Geometry,然后我们新建一个Graphic,绘制的Geometry赋值为Graphic的Geometry属性,同时呢,我们可以设置Graphic的Attribute属性,然后把这个新建的Graphic 添加到承载要素服务的要素图层上。值得是我们在设置Attribute的时候一定要与要素服务中图层的字段名字要一致的。
XAML 代码如下
<Grid x:Name="LayoutRoot" Background="White"> <esri:Map Name="MyMap" WrapAround="True"> <esri:Map.Layers> <esri:LayerCollection> <esri:ArcGISTiledMapServiceLayer Url="http://www.arcgisonline.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer" /> <esri:FeatureLayer ID="MyFeatureLayer" Url="http://localhost:6080/arcgis/rest/services/FeatureService/FeatureServer/0" Opacity="0.6"></esri:FeatureLayer> </esri:LayerCollection> </esri:Map.Layers> </esri:Map> <Button Content="启用编辑" Height="23" HorizontalAlignment="Left" Margin="68,56,0,0" Name="StartDraw" Click="StartDraw_Click" VerticalAlignment="Top" Width="75" /> </Grid>
添加Map,并以FeatureLayer的形式来存储要素服务。
C# 代码如下
public partial class DrawAddGraphic : UserControl { Draw draw; SimpleFillSymbol symbol; public DrawAddGraphic() { InitializeComponent(); draw = new Draw(MyMap); symbol= new SimpleFillSymbol(); symbol.Fill = new SolidColorBrush(Color.FromArgb(100, 255, 0, 0)); draw.FillSymbol = symbol; draw.DrawComplete += new EventHandler<DrawEventArgs>(draw_DrawComplete); } void draw_DrawComplete(object sender, DrawEventArgs e) { FeatureLayer featureLayer = MyMap.Layers["MyFeatureLayer"] as FeatureLayer; featureLayer.Graphics.Add(new Graphic() { Geometry = e.Geometry }); } private void StartDraw_Click(object sender, RoutedEventArgs e) { draw.DrawMode = DrawMode.Polygon; draw.IsEnabled = true; } }
上面的代码与我们之前向GraphicsLayer里面增加一个Graphic几乎是一样的,只是当我们添加一个Graphic到要素图层时,他会自动更新到要素图层对应后台的SDE中的FeatureClass 中。 运行程序,要素图层上有三个谈黄色的面要素。我启动编辑之后,为增加一个面,当我刷新之后。新增的面依然存在
以上是我编辑前后的对比,如果我要编辑属性的话,怎么办呢,我们知道Grapphic 有个Attributes属性,那么我们直接对每一个属性赋值就可以了。添加如下代码
以上的属性字段名,不是自己随便写的,必须与要素图层对应的后台数据源字段一致,再次运行程序,再添加一个面,在网页上操作完成之后用Arcmap连接SDE中的要素类。如下
其中第四个要素和第五个要素分别是我两次运行程序添加的,最后一次添加的面是带有属性的,说明通过这样我们已经完成了要素的添加到后台的数据中并且可以增加属性。
通过以上的代码,我们发现这与向一个GraphicLayer添加Graphic 没有什么不同,只是我们通过FeatureLayer结合要素服务实现了与后台数据的交互,并且这个过程是自动完成,我们并没有调用保存或者更新编辑之类的方法。那么如果我要手动的保存编辑结果怎么办呢。查看一下 OMD,会发现以下几个方法
有一个AutoSave ,默认是为ture的,我们在编辑之后会自动保存到后台,如果要把他设置为false的话,需要在编辑之后手动调用SaveEdits或者UndoEdits方法这样就会保存或者撤销编辑的结果 。
修改要素的形状
实现点击一个要素然后让该图形处于编辑状态,并且手动保存编辑的结果,在这里用到一个编辑要素形状的对象EditGeometry,主要属性如下
Map 就是我要编辑的要素所在的地图控件,其他的***Enble属性是允许的编辑操作,是否可以移动。旋转缩放。同时还可以使用VertexSymbol设置编辑时节点的符号。还包括一些与编辑有关的方法,比如取消编辑,开始编辑,停止编辑,撤销上一步编辑。下面通过一个实例来演示形状的编辑。
XAML代码如下
<Grid x:Name="LayoutRoot" Background="White"> <esri:Map Name="MyMap" WrapAround="True"> <esri:Map.Layers> <esri:LayerCollection> <esri:ArcGISTiledMapServiceLayer Url="http://www.arcgisonline.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer" /> <esri:FeatureLayer AutoSave="False" MouseLeftButtonDown="FeatureLayer_MouseLeftButtonDown" ID="MyFeatureLayer" Url="http://localhost:6080/arcgis/rest/services/FeatureService/FeatureServer/0" Opacity="0.6"></esri:FeatureLayer> </esri:LayerCollection> </esri:Map.Layers> </esri:Map> <Button Content="保存结果" Height="23" HorizontalAlignment="Left" Margin="68,56,0,0" Click="SaveEdits_Click" VerticalAlignment="Top" Width="75" /> </Grid>
添加一个FeatureLayer并且把AutoSave设置为了 false,同时添加了一个鼠标按下的事件,来获取要编辑的元素。
C# 代码如下:
public partial class UpdateGeomtry : UserControl
{
EditGeometry _editorGemetry;
Graphic g;
public UpdateGeomtry()
{ InitializeComponent();
_editorGemetry = new EditGeometry(MyMap);
_editorGemetry.IsEnabled = true;
}
private void SaveEdits_Click(object sender, RoutedEventArgs e)
{ _editorGemetry.StopEdit();
g.Attributes["属性一"] = "修改面3属性1";
g.Attributes["属性二"] = "修改面属性2";
g.Attributes["属性三"] = "修改面属性3";
FeatureLayer featureLayer = MyMap.Layers["MyFeatureLayer"] as FeatureLayer;
featureLayer.SaveEdits();
}
private void FeatureLayer_MouseLeftButtonDown(object sender, ESRI.ArcGIS.Client.GraphicMouseButtonEventArgs e)
{
g = e.Graphic;
_editorGemetry.StartEdit(g);
}
}
新建一个EditorGeometry对象并且绑定相应Map控件,如果要让编辑可用的话还必须把IsEnable属性设置为true,在鼠标点击FeatureLayer的事件里,获得点击到的要素,并调用StartEdit()方法启用编辑。在按钮事件里,由于FeatureLayer的AutoSave设置为false,所以我们要手动的调用SaveEditor 方法,在保存之前还可以修改属性。
以上左侧是我新添加的一个四边形。中间是启用编辑的状态,右侧是我进行缩放,位置移动,增加了点并保存之后的结果。发现位置和形状都发生的变化,再次加载网页,发现确实是编辑了,我再用Arcmap来加载SDE中的数据看看
与我们要实现的目的一致,并且属性也有了修改。前面已经介绍过,我们可以修改EditGeometry的属性来对编辑进行定制,是否允许移动,旋转,缩放,以及编辑状态的符号。
删除要素,
关于删除也比较简单,当我们获得要删除的要素之后调用 FeatureLayer.Graphics.Remove(Graphic g);如果Auto Save为false的话,还要再次调用 featureLayer.SaveEdits();这里就不写demo介绍了
与编辑有关的对象。
Editor 是一组编辑命令的组合,可以对GraphicsLayer和 FeatureLayer进行编辑,支持多图层编辑,可以设置编辑图层的编号,同时也支持复杂的编辑功能比如裁剪,合并等图形的空间运算,正因如此我们必须将Editor对象与一个几何服务绑定,使用的时候我们可以把相应的命令与按钮绑定,当然如果我们要实现保存结果的话,要求编辑的图层必须来要素服务。Editor Widget 是Tookit.dll中的一个用来编辑的工具条,使用也比较简单。另外
还可以对属性表进行编辑的FeatureDataForm ,FeatureDataGrid。。,另外多说一句,关于Tookit中的部件虽然用起来方便但是界面不好看,不过大家可以修改相应的样式,定制模板(这里会有些难度,建议使用Blend)。另外Tookit 的源码是开源的,我们可以到http://esrisilverlight.codeplex.com/ 来下载源码,自己可以定制界面。关于编辑的更多信息参阅ArcGIS API for Silverlight帮助文档编辑部分
5 总结:
通过以上的简单例子,实现了对要素服务中要素图层的编辑,我们会发现真正的编辑工作都是API中相关的对象帮我们完成的,我们要做的只是调用相关的方法。所以使用起来比较简单,如果你对要素服务不是熟悉,或者发布中遇到什么难题,请参阅我们的上一篇博文要素服务发布 或者参阅中文帮助文档