概述
ArcMap的编辑功能是很强大的,ArcEngine编写的CS程序也能够用到ArcMap中提供的编辑功能,那么ArcGIS API forSilverlight针对Geometry的编辑提供了哪些功能呢?
本文说的只是对Geometry本身的编辑,并不涉及到编辑时的拓扑检查,编辑的数据源等。对于BS程序来说,能够方便的编辑Geometry基本上就满足大部分需求了。
ArcGIS Runtime API支持的几何体主要是点、线和面。
还有要注意的一点,如果在BS上要编辑ArcServer上发布的地图数据,在发布时要把地图的Edite功能复选框勾上。并且数据源必须通过Sde存储。
画点、线和面
其实要把点、线和面添加到地图上并不难,难得是交互过程。至于店,在画的时候基本上没有交互过程,只要捕捉Map空间的MouseDown或者MouseUp事件即可,得到鼠标点击的位置在地图上的坐标,声明一个MapPoint几何体,初始化一个Graphic,设置MarkerSymbol,就可以了。
但是对于线和面,就必须有个交互过程,需要鼠标点击地图数次、并且还有能撤销上个节点等。还好,ArcGIS API 为我们提供Draw类,通过该类我们就可以画线(折线、*线等)、面(多边形、矩形、圆、椭圆等)。Draw类的主要定义如下:
//画的几何体的类型 public DrawMode DrawMode { get; set; } //画面时 交互的样式 public FillSymbol FillSymbol { get; set; } //是否启用 public bool IsEnabled { get; set; } //画线时的样式,也是画面时的边线样式 public LineSymbol LineSymbol { get; set; } //作用的地图控件 public Map Map { get; set; } // 开始画触发的事件 public event EventHandler DrawBegin; //画完后触发的时间,一般是双击结束 public event EventHandler<DrawEventArgs> DrawComplete; //增加了一个节点触发的事件 public event EventHandler<VertexAddedEventArgs> VertexAdded; // 增加一个节点函数 public void AddVertex(MapPoint mp); //完成画操作 public void CompleteDraw(); //撤销上一节点 public void UndoLastVertex();可以看出Draw类定义的功能还是很丰富的,暴漏的属性、函数和事件也比较多,灵活性很高。
DrawMode属性定义了我们要画的几何体是什么类型的,定义如下:
public enum DrawMode { None = 0, //点(点) Point = 1, //折线(线) Polyline = 2, //多边形(面) Polygon = 3, //矩形(面) Rectangle = 4, //*线(线) Freehand = 5, //箭头(面) Arrow = 6, //三角形(面) Triangle = 7, //椭圆(面) Ellipse = 8, //圆(面) Circle = 9, //只包含两个点的线段(线) LineSegment = 10, }下面的代码就是画线时调用的代码:
this._Draw = new Draw(this._Application.Map);//初始化一个Draw,把Map传进去 this._Draw.DrawMode = DrawMode.Polygon;//设置要画的几何体类型 this._Draw.DrawComplete += (sender, e) => { this.ShowDialog(e.Geometry as Polygon);//定义画完之后要执行的操作 }; this._Draw.IsEnabled = true;//设置可用状态,此时在地图上点击操作的时候,就进入了画多边形的状态。
其中图上的边线为黑色的多边形就是画多边形产生的,在画没完成之前,鼠标移动,上一节点和鼠标位置以及第一个节点和鼠标位置之间的连线时一直动态变化的,双击就可以完成画多边形操作,进入我们定义的完成之后的代码。
编辑点、线和多边形
对于点的编辑,我们完全自己可以写了,过程就是当我们在地图上选中一个点Graphic时,鼠标按下后移动,随着鼠标的移动,动态变化Graphic的geometry,这样就用动态效果了。
private void Map_MouseMove(object sender, MouseEventArgs e) { if (this._Application.CrruteTool == this) { if (this._SelectPointGraphic != null) { this._SelectPointGraphic.Geometry = this._Application.Map.ScreenToMap(e.GetPosition(this._Application.Map)); } } }
对于线和面,就比较复杂了,除了移动之外,还有增加节点、删除节点、旋转、缩放等,这些操作要都自己写代码实现,确实有些复杂,还好ArcGIS API为我们提供了EditGeometry类,使用该类就可以对线和面这样的Geometry进行编辑。
EditGeometry的定义比较复杂,我们就说几个比较主要的操作。
//是否允许编辑节点 public bool EditVerticesEnabled { get; set; } //当前是否可用 public bool IsEnabled { get; set; } //是否需要保持纵横比 public bool MaintainAspectRatio { get; set; } //是否允许移动 public bool MoveEnabled { get; set; } //是否允许旋转 public bool RotateEnabled { get; set; } //旋转时,旋转点的样式 public MarkerSymbol RotatePointSymbol { get; set; } //缩放时,缩放框的样式 public LineSymbol ScaleBoxSymbol { get; set; } //是否允许缩放 public bool ScaleEnabled { get; set; } //缩放时,缩放点的样式 public MarkerSymbol ScalePointSymbol { get; set; } //编辑节点的样式 public MarkerSymbol VertexSymbol { get; set; }除了这些定义外,还定义了需要函数和事件,包括节点变化触发的事件、编辑完成触发的事件等。
如何使用EditGeometry?
1.初始化
this._EditGeometry = new EditGeometry(pApplication.Map); this._EditGeometry.EditVerticesEnabled = true; this._EditGeometry.RotateEnabled = true; this._EditGeometry.MoveEnabled = true; this._EditGeometry.GeometryEdit += new EventHandler<EditGeometry.GeometryEditEventArgs>(EditGeometry_GeometryEdit);2.设置要编辑的Graphic,里面包含我们要编辑的Geometry
this._EditGeometry.StartEdit(e.Graphic);
3.编辑完成后,我们要出发的逻辑函数
private void EditGeometry_GeometryEdit(object sender, EditGeometry.GeometryEditEventArgs e) { if (e.Action == EditGeometry.Action.EditCompleted) { //当线编辑完之后执行的代码 Geometry myNewGeometry = e.Graphic.Geometry; } }
编辑过程中会有一些交互效果,其中很多样式都是我们自己可以设置的。
默认情况下,鼠标放在一段线上,或出现圆圈,点击可以插入一个节点。鼠标选中一个节点后,可以移动该节点。鼠标双击一个节点,可以删除该节点。操作外包框可以缩放和旋转geometry。