许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  ArcGIS Engine10.0入门教程(四):基本功能开发详解

ArcGIS Engine10.0入门教程(四):基本功能开发详解

阅读数 4
点赞 0
article_banner

1地图编辑功能

 地图编辑功能涉及到比较复杂的地图与鼠标的交互以及事件的响应,ArcGIS提供了强大的地图编辑的相关功能。本节我们将尝试实现一些简单的地图编辑功能,包括点、线、面要素形状的创建和移动。通过本节希望你能掌握ArcEngine实现地图编辑的机制以及常用的地图编辑的接口。

   新建一个C#.Net项目,项目名称为MapEdit,添加MapControlLicenceControl、四个Button、一个ComboBox、一个Label等控件。如下图:


    ArcEngine中的地图编辑使用IWorkspaceEdit接口来进行编辑状态的管理,在需要对指定的工作空间进行编辑时,首先使用IWorkspaceEdit获取该工作空间的数据,然后使用StartEditing方法开始编辑状态,StartEditOperation方法打开具体编辑的操作,编辑完成后,使用StopEditOperation方法关闭编辑操作,使用StopEditing方法关闭编辑状态,完成编辑。

   在本例中,我们实现了新的点线面要素的创建和移动的功能,涉及到了比较复杂的鼠标与地图间的交互,这个功能的实现中,IDisplayFeedback是一个十分关键的接口,它具有涉及创建要素,移动要素、编辑节点等31个实现类,能够实现鼠标与地图交互中的事件的追踪,返回新的几何对象。

  创建项目后注意把ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);这句代码加入到Program.cs文件中。  

  using ESRI.ArcGIS.Carto;
   using ESRI.ArcGIS.Controls;

  using ESRI.ArcGIS.Geometry;
   using ESRI.ArcGIS.Geodatabase;
   using ESRI.ArcGIS.Display;
  定义如下成员变量。

       //操作类型
        string strOperator = "";
        //当前地图视图
        IActiveView m_activeView = null;
        //当前操作图层
        IFeatureLayer m_FeatureLayer = null;
        //当前操作实体
        IFeature m_Feature = null;
        //当前点移动反馈对象
        IMovePointFeedback m_MovePointFeedback = new MovePointFeedbackClass();
        //当前线移动反馈对象
        IMoveLineFeedback m_MoveLineFeedback = new MoveLineFeedbackClass();
        //当前面移动反馈对象
        IMovePolygonFeedback m_MovePolygonFeedback = new MovePolygonFeedbackClass();

    加载地图文档的函数代码:

     private void button1_Click(object sender, EventArgs e)
        {
            //加载地图文档
            loadMapDocument();
            //将图层名填加到下拉列表框
            for (int i = 0; i < this.axMapControl1.LayerCount; i++)
            {
                ILayer layer = this.axMapControl1.get_Layer(i);
                this.comboBox1.Items.Add(layer.Name);
            }          
        }

       //加载地图文档
        private void loadMapDocument()
        {
            System.Windows.Forms.OpenFileDialog openFileDialog;
            openFileDialog = new OpenFileDialog();
            openFileDialog.Title = "打开地图文档";
            openFileDialog.Filter = "map documents(*.mxd)|*.mxd";
            openFileDialog.ShowDialog();
            string filePath = openFileDialog.FileName;
            if (axMapControl1.CheckMxFile(filePath))
            {
                axMapControl1.MousePointer = esriControlsMousePointer.esriPointerHourglass;
                axMapControl1.LoadMxFile(filePath, 0, Type.Missing);
                axMapControl1.MousePointer = esriControlsMousePointer.esriPointerDefault;
            }
            else
            {
                MessageBox.Show(filePath + "不是有效的地图文档");
            }
        }

    combobox1添加selectedchange事件。

   private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.comboBox1.Text != "")
            {
                for (int i = 0; i < this.axMapControl1.LayerCount; i++)
                {
                    ILayer layer = this.axMapControl1.get_Layer(i);
                    if (layer.Name == this.comboBox1.Text.ToString())
                    {
                        m_FeatureLayer = layer as IFeatureLayer;
                        m_Feature = m_FeatureLayer.FeatureClass.GetFeature(0);

                       if (m_Feature != null)
                        {
                            this.axMapControl1.Map.ClearSelection();
                            this.axMapControl1.Map.SelectFeature(m_FeatureLayer, m_Feature);
                            this.axMapControl1.Refresh();
                        }
                        m_activeView = this.axMapControl1.ActiveView;
                        return;
                    }
                }
            }
        }

          移动要素按钮添加事件:

       private void button2_Click(object sender, EventArgs e)
        {
            strOperator = "move";
            m_MovePointFeedback = new MovePointFeedbackClass();
            m_MoveLineFeedback = new MoveLineFeedbackClass();
            m_MovePolygonFeedback = new MovePolygonFeedbackClass();
        }

   下面添加鼠标与地图的交互事件,包括移动要素时鼠标的PanMouseDown事件、MouseMove事件和MouseUp事件。代码如下:

创建要素时首先在MouseDown事件中获取鼠标点击的点位,若图层为点图层,则直接创建要素,若为线图层或面图层,则作为第一个节点,以后每次点击都会添加一个节点,直到双击鼠标完成要素的创建。创建要素时的MouseDown事件在这里定义为CreateMouseDown。代码如下:

    private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            IPoint point = new PointClass();
            IFeatureClass featureClass = null;
            if (m_Feature == null) return;
            switch (strOperator)
            {
                case "move":
                    //将当前鼠标位置的点转换为地图上的坐标
                    point = m_activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                    if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPoint)
                    {
                        //设置显示对象,并启动移动
                        m_MovePointFeedback.Display = m_activeView.ScreenDisplay;
                        m_MovePointFeedback.Start(m_Feature.Shape as IPoint, point);
                    }
                    else if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPolyline)
                    {
                        //设置显示对象,并启动移动
                        m_MoveLineFeedback.Display = m_activeView.ScreenDisplay;
                        m_MoveLineFeedback.Start(m_Feature.Shape as IPolyline, point);
                    }
                    else if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                    {
                        //设置显示对象,并启动移动
                        m_MovePolygonFeedback.Display = m_activeView.ScreenDisplay;
                        m_MovePolygonFeedback.Start(m_Feature.Shape as IPolygon, point);
                    }
                    break;
            }
        }

       private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            IPoint point = new PointClass();
            switch (strOperator)
            {
                case "move":
                    if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPoint)
                    {
                        if (m_MovePointFeedback != null)
                        {
                            //将当前鼠标位置的点转换为地图上的坐标
                            point = m_activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                            //移动对象到当前鼠标位置
                            m_MovePointFeedback.MoveTo(point);
                        }
                    }
                    else if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPolyline)
                    {
                        if (m_MoveLineFeedback != null)
                        {
                            //将当前鼠标位置的点转换为地图上的坐标
                            point = m_activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                            //移动对象到当前鼠标位置
                            m_MoveLineFeedback.MoveTo(point);
                        }
                    }
                    else if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                    {
                        if (m_MovePolygonFeedback != null)
                        {
                            //将当前鼠标位置的点转换为地图上的坐标
                            point = m_activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                            //移动对象到当前鼠标位置
                            m_MovePolygonFeedback.MoveTo(point);
                        }
                    }
                    break;
            }
        }

       private void axMapControl1_OnMouseUp(object sender, IMapControlEvents2_OnMouseUpEvent e)
        {
            if (m_Feature == null) return;
            IGeometry resultGeometry = null;
            switch (strOperator)
            {
                case "move":
                    if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPoint)
                    {
                        //停止移动
                        resultGeometry = m_MovePointFeedback.Stop() as IGeometry;
                        m_Feature.Shape = resultGeometry;
                    }
                    else if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPolyline)
                    {
                        //停止移动
                        resultGeometry = m_MoveLineFeedback.Stop() as IGeometry;
                        m_Feature.Shape = resultGeometry;
                    }
                    else if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                    {
                        //停止移动
                        resultGeometry = m_MovePolygonFeedback.Stop() as IGeometry;
                        m_Feature.Shape = resultGeometry;
                    }
                    IWorkspaceEdit workspaceEdit;
                    IWorkspace workspace;
                    IDataset dataset = m_FeatureLayer.FeatureClass as IDataset;
                    workspace = dataset.Workspace;
                    workspaceEdit = workspace as IWorkspaceEdit;
                    //开始编辑
                    workspaceEdit.StartEditing(true);
                    workspaceEdit.StartEditOperation();
                    //保存实体
                    m_Feature.Store();
                    //结束编辑
                    workspaceEdit.StopEditOperation();
                    workspaceEdit.StopEditing(true);
                    m_MovePointFeedback = null;
                    m_MoveLineFeedback = null;
                    m_MovePolygonFeedback = null;
                    break;
            }
            m_activeView.Refresh();
            this.axMapControl1.Map.ClearSelection();
        }

    删除节点按钮事件的代码如下:

    private void button3_Click(object sender, EventArgs e)
        {
            IPointCollection pointCollection;
            if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPolyline)
            {
                pointCollection = new PolylineClass();
                IPolyline polyline = m_Feature.Shape as IPolyline;

               pointCollection = polyline as IPointCollection;
                //如果点个数少于两个无法构成线
                if (pointCollection.PointCount > 2)
                {
                    //移除指定的节点
                    pointCollection.RemovePoints(pointCollection.PointCount - 1, 1);
                }
            }
            else if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
            {
                pointCollection = new PolygonClass();
                IPolygon polygon = m_Feature.Shape as IPolygon;
                pointCollection = polygon as IPointCollection;
                //如果点个数少于三个无法构成面
                if (pointCollection.PointCount > 3)
                {
                    //移除指定的节点
                    pointCollection.RemovePoints(pointCollection.PointCount - 1, 1);
                }
            }
            IWorkspaceEdit workspaceEdit;
            IWorkspace workspace;
            IDataset dataset = m_FeatureLayer.FeatureClass as IDataset;
            workspace = dataset.Workspace;
            workspaceEdit = workspace as IWorkspaceEdit;
            //开始编辑
            workspaceEdit.StartEditing(true);
            workspaceEdit.StartEditOperation();
            //保存数据
            m_Feature.Store();
            //结束编辑
            workspaceEdit.StopEditOperation();
            workspaceEdit.StopEditing(true);
            m_activeView.Refresh();
        }


    双击“增加节点”添加如下代码:


       private void button4_Click(object sender, EventArgs e)
        {
            IPointCollection pointCollection;
            IPoint point = new PointClass();
            IPoint fromPoint = new PointClass();
            IPoint toPoint = new PointClass();
            if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPolyline)
            {
                pointCollection = new PolylineClass();
                IPolyline polyline = m_Feature.Shape as IPolyline;

               object missing1 = Type.Missing;
                object missing2 = Type.Missing;
                pointCollection = polyline as IPointCollection;
                //获取线对象的最后两个点
                fromPoint = pointCollection.get_Point(pointCollection.PointCount - 2);
                toPoint = pointCollection.get_Point(pointCollection.PointCount - 1);
                //根据线最后两个点,创建一个新点
                point.PutCoords((fromPoint.X + toPoint.X) / 2, (fromPoint.Y + toPoint.Y) / 2 + 50);
                //将新点添加到线对象的点集合中
                pointCollection.AddPoint(point, ref missing1, ref missing2);

           }
            else if (m_Feature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
            {
                pointCollection = new PolygonClass();
                IPolygon polygon = m_Feature.Shape as IPolygon;

               object missing1 = Type.Missing;
                object missing2 = Type.Missing;
                pointCollection = polygon as IPointCollection;
                //获取面对象点集最后两个点
                fromPoint = pointCollection.get_Point(pointCollection.PointCount - 2);
                toPoint = pointCollection.get_Point(pointCollection.PointCount - 1);
                //根据线最后两个点,创建一个新点
                point.PutCoords((fromPoint.X + toPoint.X) / 2, (fromPoint.Y + toPoint.Y) / 2 + 50);
                //将新点添加到线对象的点集合中
                pointCollection.AddPoint(point, ref missing1, ref missing2);
            }
            IWorkspaceEdit workspaceEdit;
            IWorkspace workspace;
            IDataset dataset = m_FeatureLayer.FeatureClass as IDataset;
            workspace = dataset.Workspace;
            workspaceEdit = workspace as IWorkspaceEdit;
            //开始编辑
            workspaceEdit.StartEditing(true);
            workspaceEdit.StartEditOperation();
            //保存数据
            m_Feature.Store();
            //结束编辑
            workspaceEdit.StopEditOperation();
            workspaceEdit.StopEditing(true);
            m_activeView.Refresh();
        }


    至此,我们完成了代码的编写,效果如图所示。


   地图编辑的GIS中比较复杂和困难的环节,涉及到的对象和接口非常多,上面实例只是实现了最基础的编辑的活动,如果读者对二次开发感兴趣,可以自己试着阅读GIS二次开发相关书籍,了解与编辑相关的接口和方法,自己实现。

2地理变换

     以下演示了如何改变一个图层的空间参考。运行效果如下图:


   先新建一个MapControl Application模板,添加菜单按钮,事件代码为:

    private void 空间参考ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Transform attributeQueryForm = new Transform(this.axMapControl1);
            attributeQueryForm.Show();
        }

    然后见一个窗体,命名为Transform,控件布局见上图。添加变量:

       //地图数据
        private AxMapControl mMapControl;
        //选中图层
        private IFeatureLayer mFeatureLayer;

       构造函数修改为:

      public Transform(AxMapControl mapControl)
        {
            InitializeComponent();
            this.mMapControl = mapControl;
        }

      Load事件为:

   

private void Transform_Load(object sender, EventArgs e)

           {

               //MapControl中没有图层时返回

               if (this.mMapControl.LayerCount <= 0)

                   return;

           //获取MapControl中的全部图层名称,并加入ComboBox

               //图层

               ILayer pLayer;

               //图层名称

               string strLayerName;

               for (int i = 0; i < this.mMapControl.LayerCount; i++)

               {

                   pLayer = this.mMapControl.get_Layer(i);

                   strLayerName = pLayer.Name;

                   //图层名称加入cboLayer

                   this.comboBox1.Items.Add(strLayerName);

               }

               //默认显示第一个选项

               this.comboBox1.SelectedIndex = 0;

           }

     comboBox1_SelectedIndexChanged 事件 为:

     private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)

           {

               //获取cboLayer中选中的图层

               mFeatureLayer = mMapControl.get_Layer(comboBox1.SelectedIndex) as IFeatureLayer;

           }

        添加改变图层的空间参考的函数:

       /// <summary>

           /// 改变图层的空间参考

           /// </summary>

           /// <param name="pFeatureLayer">图层</param>

           /// <param name="pGeoType">空间参考类型</param>

           private void ChangeLayerRef(IFeatureLayer pFeatureLayer, int gcsType)

           {

               try

               {

                   IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;

                   //QI到IGeoDataset

                   IGeoDataset pGeoDataset = pFeatureClass as IGeoDataset;

                   //QI到IGeoDatasetSchemaEdit

                   IGeoDatasetSchemaEdit pGeoDatasetSchemaEdit = pGeoDataset as IGeoDatasetSchemaEdit;

                   if (pGeoDatasetSchemaEdit.CanAlterSpatialReference == true)

                   {

                       //创建SpatialReferenceEnvironmentClass对象

                       ISpatialReferenceFactory2 pSpaRefFactory = new SpatialReferenceEnvironmentClass();

                       //创建地理坐标系对象

                       IGeographicCoordinateSystem pNewGeoSys = pSpaRefFactory.CreateGeographicCoordinateSystem(gcsType);//4214代表Beijing1954

                       pGeoDatasetSchemaEdit.AlterSpatialReference(pNewGeoSys);

                   }

               }

               catch (Exception Err)

               {

                   MessageBox.Show(Err.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

               }

           }

       在转换坐标按钮下添加事件:

       private void button1_Click(object sender, EventArgs e)

           {

               ChangeLayerRef(mFeatureLayer, 4214);

               MessageBox.Show("转换成功!");

           }

       运行就能成功了!


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空