做GIS系统时,通常不仅需要简单的地图浏览、地图查询功能,对地图上要素的编辑也是基本要求之一。对ArcGIS Server发布的数据进行编辑的要求有:所有数据必须来自同一个ArcSDE数据库中;编辑图层只能输FeatureLayer类型,如可以在发布地图服务时,将FeactureAccess功能勾选上。满足以上两个条件的地图数据才能被编辑。而地图编辑其实也就是分为添加、修改、删除三个内容,我们可以从这三个方面进行详细介绍。
一、添加
添加的方式一般有两种,一种是通过在地图上绘制图形添加,另一种是通过输入相关参数进行添加,比如我们用点表示事件,可直接在事件发生的地区点击添加,也可以通过输入事件发生的地点、然后系统自动通过地址匹配找到地图位置后进行添加。这两种方式,只是说操作的方式,其实它们本质上都是一样的,都是通过创建Graphic对象,然后设置它的Geometry(图形位置几何信息)和Attributte(属性信息),最后用FeatureLayer.Graphic.add(Graphics)方法将要素加入进去即可。重点代码,如下。
通常创建Graphics对象都是以绘图(Draw)交互方式进行,因为这样获取Geometry对象比较方便,因此下面的代码都在Draw_Completed绘制完成事件中添加。
private Draw_Completed(object sender, DrawEventArgs e)
{
Graphic g=new Graphic();
g.Geometry=e.Geometry;//赋值Geometry几何属性
g.Attributes["Name"]="**事件";//设置属性信息,Attributes是一个IDictionary<string,object>对象,因此要以键值的形式添加数据
g.Attributes["Place"]="***街";
FeatureLayer flyr=map.Layers["Matter"] as FeatureLayer;
flyr.Graphics.add(g);//将新创建的图形元素添加到图层中
flyr.SaveEdits();//保存添加的内容,否则可用flyr.UndoEdits()可取消当前添加内容,且在程序退出之前不执行该操作添加的内容不会保存,若之前 //FeatureLayer.AutoSave设置为Ture,那么编辑完以后就会自动保存,不用再调用该方法
}
二、修改
修改同样包括直接通过点击地图获取目标要素和通过属性条件获取属性要素两种方式进行,还有只修改图形信息、只修改属性信息、和都修改几种形式,直接通过设置FeatureLayer.Graphics要素集的要素值就可以修改,不过如果要以跟地图交互式的方式修改要素几何图形信息则要通过EditGeometry对象进行操作。
1、直接进行修改
直接修改即是直接通过FeatureLayer.Graphics属性获取Graphic对象,然后对它的Geometry和Attributes属性进行更改即可。
FeatureLayer flyr=map.Layers["Matter"] as FeatureLayer;//获取编辑图层
Graphic g=flyr.Graphics[0];//获取要编辑的要素
g.Geometry=new MapPoint(){X=114.225,Y=45.523};//更改要素几何位置信息,本实例用的是点要素
g.Attributes["Name"]="512事件";//修改属性信息
g.Attributes["Place"]="太平街";
flyr.SaveEdits();
直接修改的方式,通常用于对属性条件查询后结果的修改,可结合设置FeatureLayer.Where查询信息,然后再修改FeatureLayer.Graphics(查询结果就保存在这)即可;
2、通过与地图交互修改
通过地图交互的方式,需要用到EditGeometry对象,EditGeometry能对线和面要素进行移动、旋转、节点编辑、放大缩小等编辑,但是有点不足的是,它不能对点进行编辑,进行编辑时需要先选定对象元素然后才能进行,根据点和线面两种不同类型,步骤如下:
(1).对线面进行编辑
A.选中对象要素
对象要素的选择可以通过FeatureLayer_MouseLeftButtonDown(object sender, GraphicMouseButtonEventArgs e)事件的参数e获取
Graphic g=null;
EditGeometry editGeo=new EditGeometry(){Map=map1};
FeatureLayer_MouseLeftButtonDown(object sender, GraphicMouseButtonEventArgs e)
{
e.Handled = true;//使Map.Pan事件不可用
g = e.Graphic;//获取编辑要素对象
g.Selected = true;//使对象元素处于选中状态
edtGeo.StartEdit(g);//开始编辑,此时就可以在地图上编辑选中对象的几何形状了
}
B.编辑属性信息、保存
edtGeo.StopEdit();//停止编辑
if (g!=null)
{
g.Attributes["Name"] = "***区";//修改属性信息
}
flyr.SaveEdits();
g = null;
(2).对点进行编辑
点没有形状信息,只有位置信息,因此只能进行移动操作,EditGeometry对象对它不起作业,因此只能通过其他方式,不过操作步骤和上面相似,都是先选中对象,最后修改保存信息,不过它中间还要通过Map_MouseMove实践记录要移动的位置,具体如下
A.选中对象要素
对象要素的选择可以通过FeatureLayer_MouseLeftButtonDown(object sender, GraphicMouseButtonEventArgs e)事件的参数e获取
Graphic g=null;
FeatureLayer_MouseLeftButtonDown(object sender, GraphicMouseButtonEventArgs e)
{
e.Handled = true;//使Map.Pan事件不可用
g = e.Graphic;//获取编辑要素对象
g.Selected = true;//使对象元素处于选中状态
}
B.移动点要素
移动在Map_MouseMove实践中进行,控制移动停止在Map_MouseUp中:
private void map1_MouseMove(object sender, MouseEventArgs e)
{
if (g!=null&&g.Selected==true)
{
g.Geometry=map1.ScreenToMap(e.GetPosition(map1)); //移动点
}
}
private void map1_MouseUp(object sender, MouseButtonEventArgs e)
{
if (g!=null)
{
g.Selected = false;//取消选中时停止移动
}
}
C.保存编辑
if (g!=null)
{
g.Attributes["Name"] = "***事件";//修改属性信息
}
flyr.SaveEdits();
g = null;
三、删除
删除也有两种方式,一种是直接通过对FeatureLayer.Graphics属性操作,一种是利用Editor,先选中要素,然后删除选中的要素即可,这是方式是与地图交互的方式。
1、直接通过FeatureLayer.Graphics操作删除
在FeatureLayer.Graphics属性中有RemoveAt(int index)和Remove(Graphic g)方法,通过它们即可以删除指定的要素,这种方式适合于属性条件查询后,对查询结果的操作,结合FeatureLayer.Where操作,方式很简单,具体就说明;
2、通过Editor进行删除
通过Editor删除首先要选中要素,然后才能通过删除选中实现。
(1)、构造Editor对象
Editor edit = new Editor();
edit.GeometryServiceUrl = "http://localhost/arcgis/rest/services/Geometry/GeometryServer";//设置地理服务地址
List<String> lyrIds = new List<string>();
lyrIds.Add("People");
lyrIds.Add("Matter");
edit.LayerIDs = lyrIds.AsEnumerable<string>();//设置Edit的工作图层集合
edit.Map = map1;
(2)、选中对象
edit.Select.Execute("New");//新建选择,有Add, Remove, New, Keyboard (default)四个参数
这里是以ICommand命令的形式执行的,下面的删除也是
(3)、删除选中
if (edit.DeleteSelected.CanExecute("") == true)
{ //判断是否可以删除,即是否有对象处于选中状态
edit.DeleteSelected.Execute("");//删除选中的对象
}
四、总结
由上面的操作可知,对于添加、修改、删除操作都可以直接通过FeatureLayer.Graphics属性对象里的方法实现,不过这种方式适合不与地图交互,与而通过属性表展示的情况,而与地图交互的方式实现,则要借助EditGeometry和Editor对象实现。