zoukankan      html  css  js  c++  java
  • 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二次开发,如果有不对的地方,请多多包涵!

  • 相关阅读:
    【AngularJS】学习资料
    Anaconda环境安装
    ORM表之间高级设计
    drf序列化和反序列化
    安装与使用django-restframework
    django-restframework
    顶象滑块验证码
    Restful接口规范
    Web API接口
    BBS配置
  • 原文地址:https://www.cnblogs.com/edcoder/p/11751966.html
Copyright © 2011-2022 走看看