ArcGIS Engine簡單圖形繪制功能的實現(點、線、面)


我們添加點、線、面來實現圖形的編輯需要使用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二次開發,如果有不對的地方,請多多包涵!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM