switch (snapContainer.GeometryType) {
case esriGeometryType.esriGeometryPolyline:
pTopo = snapContainer as ITopologicalOperator; buffer=pTopo.Buffer(3); polygon = buffer as IPolygon;
pRelOperator=polygon as IRelationalOperator; break;
case esriGeometryType.esriGeometryPolygon: polygon = snapContainer as IPolygon;
pRelOperator=polygon as IRelationalOperator; break;
case esriGeometryType.esriGeometryPoint:
pTopo = snapContainer as ITopologicalOperator; buffer = pTopo.Buffer(3); polygon = buffer as IPolygon;
pRelOperator = polygon as IRelationalOperator; break; default:
break; }
if (pRelOperator == null) return; if (pRelOperator.Contains(point)) {
m_MapControl.MousePointer = esriControlsMousePointer.esriPointerSizeAll; contained = true; }
else m_MapControl.MousePointer = esriControlsMousePointer.esriPointerArrow; return; } }
这里就是根据鼠标悬停的位置,来改变鼠标样式,抱歉的很,我没有从AE里面找到和ArcMap一样的鼠标样式,只要用一些简单的替代了,当然你可以自己定义,也可以打电话、发Email质问ESRI客服,如果你知道了,一定要告诉我,否则我诅咒你找不到女朋友!这个函数里面,我需要判断,鼠标是悬停在要素的节点上,还是悬停在要素内部了,这个对于后面处理是拽节点还是移动要素有很大的帮助。
这个根据鼠标悬停位置改变鼠标样式,还远远不够滴,当你悬停到绿色节点上时,按下鼠标时,就意味这拖拽开始,当鼠标左键按下并移动时,要出现像橡皮筋一样的连接线,当左键弹起时,就意味着拖拽结束,如果再按下左键,就意味着要素的编辑结束。这个怎么做到呢,请看下面的代码:
public bool EditFeature(int x,int y,IGeometry geometry) {
GetFeatureOnMouseDown(x, y); SelectOnMouseDown();
if(m_SelectedFeature.Count<1)return false; if (geometry == null) return false;
IPoint pHitPoint=null; double hitDist = 0, tol = 0;
int vertexIndex = 0, vertexOffset = 0, numVertices = 0, partIndex = 0; bool vertex=false;
IFeature editedFeature = m_SelectedFeature[0];
point = m_MapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
tol = ConvertPixelsToMapUnits(4); //IGeometry pGeo = editedFeature.Shape; //m_EditingFeature = editedFeature;
try {
switch (geometry.GeometryType) {
case esriGeometryType.esriGeometryPoint:
m_FeedBack = new MovePointFeedbackClass();
m_FeedBack.Display = m_MapControl.ActiveView.ScreenDisplay; IMovePointFeedback pointMove = m_FeedBack as IMovePointFeedback;
pointMove.Start(geometry as IPoint, point); break;
case esriGeometryType.esriGeometryPolyline:
if (TestGeometryHit(tol, point, geometry, ref pHitPoint, ref hitDist, ref partIndex, ref vertexOffset, ref vertexIndex, ref vertex)) {
if(!vertex) {
IGeometryCollection geometryColl = geometry as IGeometryCollection;
IPath path = geometryColl.get_Geometry(partIndex) as IPath; IPointCollection pointColl = path as IPointCollection; numVertices = pointColl.PointCount; object missing = Type.Missing;
if (vertexIndex == 0) {
object start = 1 as object;
pointColl.AddPoint(point, ref start, ref missing); }
else {
object objVertexIndex=vertexIndex as object;
pointColl.AddPoint(point, ref missing, ref objVertexIndex); }
TestGeometryHit(tol, point, geometry, ref pHitPoint, ref hitDist, ref partIndex, ref vertexOffset, ref vertexIndex, ref vertex); }
m_FeedBack = new LineMovePointFeedbackClass();
m_FeedBack.Display = m_MapControl.ActiveView.ScreenDisplay;
ILineMovePointFeedback lineMove = m_FeedBack as ILineMovePointFeedback;
lineMove.Start(geometry as IPolyline, vertexIndex, point); }
else return false; break;
case esriGeometryType.esriGeometryPolygon:
if (TestGeometryHit(tol, point, geometry, ref pHitPoint, ref hitDist, ref partIndex, ref vertexOffset, ref vertexIndex, ref vertex)) {
if(!vertex) {
IGeometryCollection geometryColl = geometry as IGeometryCollection; IPath path = geometryColl.get_Geometry(partIndex) as IPath; IPointCollection pointColl = path as IPointCollection; numVertices = pointColl.PointCount; object missing = Type.Missing; if (vertexIndex == 0) {
object start = 1 as object;
pointColl.AddPoint(point, ref start, ref missing); } else {
object objVertexIndex = vertexIndex as object;
pointColl.AddPoint(point, ref missing, ref objVertexIndex); }
TestGeometryHit(tol, point, geometry, ref pHitPoint, ref hitDist, ref partIndex, ref vertexOffset, ref vertexIndex, ref vertex); }
m_FeedBack = new PolygonMovePointFeedbackClass();
m_FeedBack.Display = m_MapControl.ActiveView.ScreenDisplay;
IPolygonMovePointFeedback polyMove = m_FeedBack as IPolygonMovePointFeedback;
polyMove.Start(geometry as IPolygon, vertexIndex + vertexOffset, point);
}
else return false; break; default: break; } }
catch {return false;} return true; }
public void FeatureEditMouseMove(int x,int y) {
if (m_FeedBack == null) return;
IPoint point = m_MapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
m_FeedBack.MoveTo(point); }
public IGeometry EndFeatureEdit(int x, int y) {
if (m_FeedBack == null) return null;
IGeometry geometry = null;
IPoint point = m_MapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
if ((m_FeedBack as IMovePointFeedback) != null) {
IMovePointFeedback pointMove = m_FeedBack as IMovePointFeedback; geometry = pointMove.Stop() as IGeometry; }
else if ((m_FeedBack as ILineMovePointFeedback) != null) {
ILineMovePointFeedback lineMove = m_FeedBack as ILineMovePointFeedback; geometry = lineMove.Stop() as IGeometry; }
else if ((m_FeedBack as IPolygonMovePointFeedback) != null) {
IPolygonMovePointFeedback polyMove = m_FeedBack as IPolygonMovePointFeedback; geometry = polyMove.Stop() as IGeometry; }
m_FeedBack = null;
m_MapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, m_SelectedLayer, null); return geometry; }
呵,这个排版真的是很累啊,无法自动缩进,害的我只能一行一行的移动。第一个函数,自然是点击下绿色节点时触发,意味着,我们的拖拽就开始了;但是,但按着鼠标左键来回移动时怎么处理啊?呵呵,这就是第二个函数的所具备的功能,所以你要在MapControl 的MouseMove事件中添加这个函数;但是当你确定你移动的位置是最佳位置的时候,想停下来怎么办呢?这就是第三个函数来帮你了,也就意味着你的拖拽结束,并返回一个IGeometry,这个IGeometry就是你编辑过后要素的新的几何形状,并且当你移动结束左键弹起的时候,这个新的IGeometry也需要显示出来它的绿色的节点,所以重绘的时候需要这个IGeometry。
好了,我们快大功告成了,stop!好像还少点东西,对了,我们最终是要把最新的几何形状赋给编辑的要素以实现更新,所以我们还需要下面的这个函数:
public bool UpdateEdit(IGeometry newGeom) {
if (m_SelectedFeature.Count < 1) return false; if (newGeom == null) return false; if (newGeom.IsEmpty) return false;
IFeature feature = m_SelectedFeature[0]; IDataset dataset = feature.Class as IDataset;
IWorkspaceEdit workspaceEdit = dataset.Workspace as IWorkspaceEdit; if (!workspaceEdit.IsBeingEdited()) return false;
workspaceEdit.StartEditOperation(); feature.Shape = newGeom; feature.Store();
workspaceEdit.StopEditOperation(); m_SelectedFeature.Clear(); m_SelectedFeature.Add(feature); ClearSelection();
return true; }
呵呵,对的,这个函数很简单,就是更新一下编辑要素的几何形状,注意啊,这里我获取当前编辑的要素是从容器中取出来的,这样是不是很方便啊?这样我们就可以更新一个要素了。别忘了最后记得调用StopEditing以保存你的编辑! 当然,不可能一次性做好,我们需要更人性化一点,我们需要添加撤销和重做:
public void UndoEdit() {