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二次開發,如果有不對的地方,請多多包涵!