ArcGIS Engine简单图形绘制功能的实现(点、线、面)

  • 2019 年 10 月 28 日
  • 筆記

我们添加点、线、面来实现图形的编辑需要使用Geometry对象类

 

 

 

 

Point(点)

是一个0维的几何图形,具有X、Y坐标值,以及可选的属性,如高程值(Z值)、度量值(M值)、ID值等,可用于描述需要精确定位的对象。

Polyline(线)

是一个有序路径(Path)的集合,这些路径既可以是连续的,也可以是离散的。折线可用于表示具有线状特征的对象,用户可以用单路径构成的折线来表示简单线,也可以用具有多个路径的多义线来表示复杂线类型。

Polygon(面)

是环(Ring)的集合,环是一种封闭的路径。Polygon可以由一个或者多个环组成,甚至环内嵌套环。但是内、外环之间不能重叠,它通常用来描述面状特征的要素。

 

 

 

 

 

操作步骤大纲:

①定义一个Operation枚举

②设置鼠标移动的函数

③添加图形绘制的单击事件

④axMapContol控件的鼠标单击事件

⑤完善各事件中需要用到的函数

 

①定义一个Operation枚举

//定义一个Operation枚举  enum Operation  {      ConstructionPoint,//绘制点      ConstructionPolyLine,//绘制线      ConstructionPolygon,//绘制面      Nothing  }

 

②设置鼠标移动的函数

/// <summary>  /// 鼠标移动的函数  /// </summary>  /// <param name="sender"></param>  /// <param name="e"></param>  private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)  {      try      {          toolStripStatusLabel1.Text = string.Format("{0},{1}  {2}", e.mapX.ToString("#######.##"), e.mapY.ToString("#######.##"), axMapControl1.MapUnits.ToString().Substring(4));      }      catch      { }    }


③添加图形绘制的单击事件

 

#region 添加图形绘制的单击事件  private void 点ToolStripMenuItem_Click(object sender, EventArgs e)  {      oprFlag = Operation.ConstructionPoint;  }      private void 折线ToolStripMenuItem_Click(object sender, EventArgs e)  {      oprFlag = Operation.ConstructionPolyLine;      geoCollection = new PolylineClass();      ptCollection = new PolylineClass();  }    private void 面ToolStripMenuItem_Click(object sender, EventArgs e)  {      oprFlag = Operation.ConstructionPolygon;  }      #endregion

 

 

④axMapContol控件的鼠标单击事件

 

/// <summary>  /// axMapContol控件的鼠标单击事件  /// </summary>  /// <param name="sender"></param>  /// <param name="e"></param>  private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)  {      //表示 System.Type 信息中的缺少值。 此字段为只读。      missing = Type.Missing;      //若为添加点的事件      if (oprFlag == Operation.ConstructionPoint)      {          //axMapControl1控件的当前地图工具为空          axMapControl1.CurrentTool = null;          //通过AddPointByStore函数, 获取绘制点的图层——Cities          //从GetPoint函数获取点的坐标          AddPointByStore("Cities", GetPoint(e.mapX, e.mapY) as IPoint);          //点添加完之后结束编辑状态          oprFlag = Operation.Nothing;      }      //若为添加折线的事件      if (oprFlag == Operation.ConstructionPolyLine)      {          //axMapControl1控件的当前地图工具为空          axMapControl1.CurrentTool = null;          //获取鼠标单击的坐标          //ref参数能够将一个变量带入一个方法中进行改变, 改变完成后, 再将改变后的值带出方法          //ref参数要求在方法外必须为其赋值, 而方法内可以不赋值          ptCollection.AddPoint(GetPoint(e.mapX, e.mapY), ref missing, ref missing);          //定义集合类型绘制折线的方法          pGeometry = axMapControl1.TrackLine();            //通过addFeature函数的两个参数, Highways——绘制折线的图层; Geometry——绘制的几何折线          AddFeature("Highways", pGeometry);            //折线添加完之后结束编辑状态          oprFlag = Operation.Nothing;      }      //若为添加面的事件      if (oprFlag == Operation.ConstructionPolygon)      {          //axMapControl1控件的当前地图工具为空          axMapControl1.CurrentTool = null;          //          CreateDrawPolygon(axMapControl1.ActiveView, "Counties");          //面添加完之后结束编辑状态          oprFlag = Operation.Nothing;      }  }

 

 

 

⑤完善各事件中需要用到的函数

1、添加点的事件中需要用到的函数:

AddPointByStore

/// <summary>  /// 获取绘制点的图层——Cities, 保存点绘制的函数  /// </summary>  /// <param name="pointLayerName"></param>  /// <param name="point"></param>  private void AddPointByStore(string pointLayerName, IPoint pt)  {      //得到要添加地物的图层      IFeatureLayer pFeatureLayer = GetLayerByName(pointLayerName) as IFeatureLayer;      if (pFeatureLayer != null)      {          //定义一个地物类, 把要编辑的图层转化为定义的地物类          IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;          //先定义一个编辑的工作空间, 然后将其转化为数据集, 最后转化为编辑工作空间          IWorkspaceEdit w = (pFeatureClass as IDataset).Workspace as IWorkspaceEdit;          IFeature pFeature;          //开始事务操作          w.StartEditing(false);          //开始编辑          w.StartEditOperation();          //创建一个(点)要素          pFeature = pFeatureClass.CreateFeature();          //赋值该要素的Shape属性          pFeature.Shape = pt;            //保存要素, 完成点要素生成          //此时生成的点要素只要集合特征(shape/Geometry), 无普通属性          pFeature.Store();            //结束编辑          w.StopEditOperation();          //结束事务操作          w.StopEditing(true);        }      //屏幕刷新      this.axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, pFeatureLayer, null);    }

 

2、添加线事件中需要用到的函数(也包含面面事件)

GetPoint

/// <summary>  /// 获取鼠标单击时的坐标位置信息  /// </summary>  /// <param name="x"></param>  /// <param name="y"></param>  /// <returns></returns>  private IPoint GetPoint(double x, double y)  {      IPoint pt = new PointClass();      pt.PutCoords(x, y);      return pt;  }

 

添加实体对象到地图图层(添加线、面要素)  AddFeature

 

/// <summary>  /// 添加实体对象到地图图层(添加线、面要素)  /// </summary>  /// <param name="layerName">图层名称</param>  /// <param name="pGeometry">绘制形状(线、面)</param>  private void AddFeature(string layerName, IGeometry pGeometry)  {      ILayer pLayer = GetLayerByName(layerName);      //得到要添加地物的图层      IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;      if (pFeatureLayer != null)      {          //定义一个地物类, 把要编辑的图层转化为定义的地物类          IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;          //先定义一个编辑的工作空间, 然后将其转化为数据集, 最后转化为编辑工作空间          IWorkspaceEdit w = (pFeatureClass as IDataset).Workspace as IWorkspaceEdit;          IFeature pFeature;            //开始事务操作          w.StartEditing(true);          //开始编辑          w.StartEditOperation();            //在内存创建一个用于暂时存放编辑数据的要素(FeatureBuffer)          IFeatureBuffer pFeatureBuffer = pFeatureClass.CreateFeatureBuffer();          //定义游标          IFeatureCursor pFtCursor;          //查找到最后一条记录, 游标指向该记录后再进行插入操作          pFtCursor = pFeatureClass.Search(null, true);          pFeature = pFtCursor.NextFeature();          //开始插入新的实体对象(插入对象要使用Insert游标)          pFtCursor = pFeatureClass.Insert(true);          try          {              //向缓存游标的Shape属性赋值              pFeatureBuffer.Shape = pGeometry;          }          catch (COMException ex)          {              MessageBox.Show("绘制的几何图形超出了边界!");              return;          }          //判断:几何图形是否为多边形          if (pGeometry.GeometryType.ToString() == "esriGeometryPolygon")          {              int index = pFeatureBuffer.Fields.FindField("STATE_NAME");              pFeatureBuffer.set_Value(index, "California");          }          object featureOID = pFtCursor.InsertFeature(pFeatureBuffer);          //保存实体          pFtCursor.Flush();            //结束编辑          w.StopEditOperation();          //结束事务操作          w.StopEditing(true);            //释放游标          Marshal.ReleaseComObject(pFtCursor);          axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, pLayer, null);      }      else      {          MessageBox.Show("未发现" + layerName + "图层");      }  }

 

 

3、添加面事件中需要用到的函数

CreateDrawPolygon

/// <summary>  /// 添加面事件  /// </summary>  /// <param name="activeView"></param>  /// <param name="v"></param>  private void CreateDrawPolygon(IActiveView activeView, string sLayer)  {      //绘制多边形事件      pGeometry = axMapControl1.TrackPolygon();      //通过AddFeature函数的两个参数, sLayer——绘制折线的图层; pGeometry——绘制几何的图层      AddFeature(sLayer, pGeometry);  }

 

注:AddFeature函数在上面已经提及,调用即可

 

核心AddFeature函数总结:

 

 

 

谢谢观看!本人初学GIS二次开发,如果有不对的地方,请多多包涵!