ArcGIS Engine10.0轻松入门级教程(2)——创建一个ArcGIS Engine桌面应用程序

这篇教程介绍了如何使用ArcGIS Engine10.0创建一个简单的地图显示程序,包括创建工程、添加控件、控件绑定、添加工具和菜单,适合初学者和C#.NET新手。教程详细讲述了每个步骤,从项目创建到地图导航、图层管理等功能的实现。
摘要由CSDN通过智能技术生成

       这个例子将引导您创建第一个简单的地图显示程序,并添加基本的缩放和漫游功能。如果您之前没有接触过ArcGIS Engine的开发,那么这个例子是您迈入ArcGIS Engine二次开发大门的极好例子,如果您之前没有接触过C#.NET,也无需担心,这个例子将从零开始引导您一步一步完成任务。

1创建一个新的工程

       首先打开Microsoft Visual Studio 2008,点击菜单栏中的文件”—>“新建”—>“项目,在弹出的对话框中选择新建一个Visual C#Windows应用程序,之后更改项目名称为“ZZUMap”,更改文件的路径为个人实习文件夹,点击确定即可。

       选中项目“ZZUMap”中的窗体“Form1”,修改其Name属性为“MainForm”,Text属性为“ZZUMap”。

2添加控件

      选择工具箱中的“菜单和工具栏|MenuStrip”,将其拖入窗体。
     选择工具箱中的“ArcGIS Windows Forms”节,将“ToolbarControl”控件拖入窗体,并将其属性中的Dock设置为Top。
     选择工具箱中的“菜单和工具栏|StatusStrip”,将其拖入到窗体。
     选择工具箱中的“容器|SplitContainer”容器拖入窗体,并将其属性中的Dock设置为Fill。

     再将“容器|SplitContainer”容器拖入Panel1,设置为水平拆分方向,并将其属性中的Dock设置为Fill。

     将TabControl控件拖入Panel1,将Alignment属性设置为Bottom,Dock属性设置为Fill。点击TabPages属性右边的按钮,弹出TabPage集合编辑器,将tabPage1的Name设置为tabPageLayer,Text设置为图层,将tabPage2的Name设置为tabPageProperty,Text设置为属性。

     选择“图层”选项卡,拖入TOCControl控件,设置Dock属性为Fill。
     选择“属性”选项卡,拖入PropertyGrid设置Dock属性为Fill。
     拖入TabControl控件到第一个SplitContainer容器的Panel2,设置Dock属性为Fill。并上述类似的方法,将两个选项卡的Name和Text分别设置为:(tabPageMap、地图),(tabPageLayout,制版)。
     选择“地图”选项卡,拖入MapControl控件,设置Dock属性为Fill。
     选择“制版”选项卡,拖入PageLayoutControl控件,设置Dock属性为Fill。

     将MapControl控件拖入第二个SplitContainer容器的Panel2,设置Dock属性为Fill。
     最后将LicenseControl控件拖入到窗体的任意地方。
    按F5编译运行还不能运行,因就很可能是你的ArcEngine10.0没有许可,因为我的就是这个情况,所以会报错,重新授权下就OK了,解决方法:打开program.cs

    把ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);

    这句放到Application.SetCompatibleTextRenderingDefault(false);和Application.Run(new Form1());之间

3控件绑定

       通过以上步骤添加的控件还只是单独存在,而我们的程序需要各控件间协同工作,因此要进行控件绑定。
分别右击ToolbarControl、TOCControl控件,将Buddy设置为axMapControl1,如下图所示。
 


      这样,工具条和图层控件就与地图控件关联了。

4添加工具

     此时,工具条中还没有任何工具,添加的方法也很简单。右击ToolbarControl,选择“属性|Items”,点击Add,选择Commands选项卡中的Generic,双击Open、SaveAs、Redo、Undo即可将相应工具添加到工具条。
     常见的工具有:
     Map Navigation中的导航工具,Map Inquiry中的查询工具,Feature Selection中的选择工具,你可以根据需要酌情添加工具,如下图。

      目前为止运行程序界面如下:

5添加菜单

       在设计视图中,单击菜单栏,会出现“请在此处键入”的提示,单击提示就可以键入菜单名称,如“文件”,再单击“文件”,即可输入其下拉子菜单。           

       每创建一个菜单,请在其属性面板中设置 Name 属性,而且不要为中文,因此 Name 值将是此菜单响应函数的函数名的一部分,带中文的函数名,总是不好吧。我们将添加新建( New )、打开( Open )、添加数据( AddData )、保存( Save )、另存为( SaveAs )、退出( Exit )这些菜单,()内为相应的 Name 属性值。

      你可以在属性面板中的 Text 属性中,把菜单名设置为中英文形式,如“打开 O pen ”,带下划线的 O 表示此项菜单的快捷键是字母 O ,设置方法是在相应字母前加上“ & ”字符,如“打开 &Open ”。但这种快捷键只在打开此下拉菜单时才有效,即当你单击“文件”菜单弹出下拉菜单时,按下字母 O 就可以定位到“打开”菜单。

      还有一种在程序运行时都有效的全局快捷键,可以在属性面板中的“ ShortCutKeys ”中设置。

      你还可以在属性面板中的 Image 属性中设置你喜欢的菜单图标。单击 Image 那一行右边的按钮,弹出如下菜单。选择“项目资源文件”,再单击导入就可以选择你的图标了。

       最终效果如下所示。


       注意,在解决方案面板中,选中刚才添加的所有图标,在其属性面板中将生成操作设置为“嵌入的资源”,这一点很重要!菜单的实现参考ArcEngine自带的模板MapControl Application中的菜单实现。先新建一个类,命名为CreateNewDocument.cs,添加引用:

       using ESRI.ArcGIS.ADF.BaseClasses;
       using ESRI.ArcGIS.ADF.CATIDs;
       using ESRI.ArcGIS.Controls;
       using ESRI.ArcGIS.Carto;
      using ESRI.ArcGIS.SystemUI;
      using System.Windows.Forms;

      在构造函数中继承类:

       public class CreateNewDocument : BaseCommand;

       {

                           ……

       }

       然后将以下代码复制覆盖到类CreateNewDocument中

        private IHookHelper m_hookHelper = null;

        //constructor
        public CreateNewDocument()
        {
            //update the base properties
            base.m_category = ".NET Application";
            base.m_caption = "NewDocument";
            base.m_message = "Create a new map";
            base.m_toolTip = "Create a new map";
            base.m_name = "DotNetTemplate_NewDocumentCommand";
        }

        #region Overridden Class Methods

        /// <summary>
        /// Occurs when this command is created
        /// </summary>
        /// <param name="hook">Instance of the application</param>
        public override void OnCreate(object hook)
        {
            if (m_hookHelper == null)
                m_hookHelper = new HookHelperClass();

            m_hookHelper.Hook = hook;
        }

        /// <summary>
        /// Occurs when this command is clicked
        /// </summary>
        public override void OnClick()
        {
            IMapControl3 mapControl = null;

            //get the MapControl from the hook in case the container is a ToolbarControl
            if (m_hookHelper.Hook is IToolbarControl)
            {
                mapControl = (IMapControl3)((IToolbarControl)m_hookHelper.Hook).Buddy;
            }
            //In case the container is MapControl
            else if (m_hookHelper.Hook is IMapControl3)
            {
                mapControl = (IMapControl3)m_hookHelper.Hook;
            }
            else
            {
                MessageBox.Show("Active control must be MapControl!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            //check to see if there is an active edit session and whether edits have been made
            DialogResult result;
            IEngineEditor engineEditor = new EngineEditorClass();

            if ((engineEditor.EditState == esriEngineEditState.esriEngineStateEditing) && (engineEditor.HasEdits() == true))
            {
                result = MessageBox.Show("Would you like to save your edits", "Save Edits", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

                switch (result)
                {

                    case DialogResult.Cancel:
                        return;

                    case DialogResult.No:
                        engineEditor.StopEditing(false);
                        break;

                    case DialogResult.Yes:
                        engineEditor.StopEditing(true);
                        break;

                }
            }

            //allow the user to save the current document
            DialogResult res = MessageBox.Show("Would you like to save the current document?", "AoView", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (res == DialogResult.Yes)
            {
                //launch the save command
                ICommand command = new ControlsSaveAsDocCommandClass();
                command.OnCreate(m_hookHelper.Hook);
                command.OnClick();
            }

            //create a new Map
            IMap map = new MapClass();
            map.Name = "Map";

            //assign the new map to the MapControl
            mapControl.DocumentFilename = string.Empty;
            mapControl.Map = map;
        }

        #endregion

      然后定义指针和变量:

         privEmpty; ate ESRI.ArcGIS.Controls.IMapControl4 m_mapControl = null; 
      private ESRI.ArcGIS.Controls.IPageLayoutControl3 m_pageLayoutControl = null; 
      private string m_mapDocumentName = string.      

      最后在菜单按钮的事件中填入以下代码:

       private void AddData_Click(object sender, EventArgs e)
        {
            int currentLayerCount = this.axMapControl1.LayerCount;

            ICommand pCommand = new ControlsAddDataCommandClass();

            pCommand.OnCreate(this.axMapControl1.Object);

            pCommand.OnClick();

        }

        private void Save_Click(object sender, EventArgs e)
        {
            //execute Save Document command
            if (m_mapControl.CheckMxFile(m_mapDocumentName))
            {
                //create a new instance of a MapDocument
                IMapDocument mapDoc = new MapDocumentClass();
                mapDoc.Open(m_mapDocumentName, string.Empty);

                //Make sure that the MapDocument is not readonly
                if (mapDoc.get_IsReadOnly(m_mapDocumentName))
                {
                    MessageBox.Show("Map document is read only!");
                    mapDoc.Close();
                    return;
                }

            }

        }

        private void SavaAs_Click(object sender, EventArgs e)
        {
            //execute SaveAs Document command
            ICommand command = new ControlsSaveAsDocCommandClass();
            command.OnCreate(m_mapControl.Object);
            command.OnClick();

        }

        private void Open_Click(object sender, EventArgs e)
        {
            //execute Open Document command
            ICommand command = new ControlsOpenDocCommandClass();
            command.OnCreate(m_mapControl.Object);
            command.OnClick();
        }

        private void Exit_Click(object sender, EventArgs e)
        {
            //exit the application
            Application.Exit();
        }

        private void New_Click(object sender, EventArgs e)
        {
            //execute New Document command
            ICommand command = new CreateNewDocument();
            command.OnCreate(m_mapControl.Object);
            command.OnClick();

        }

6PageLayout与MapControl联动

        ArcMap程序中,数据视图和布局视图中的数据改变是实时互动的,那是因为它们本来就是在处理同一份数据。将axMapControl1中的Map拷贝到axPageLayoutControl1代码如下:

private voidCopyAndOverwriteMap()

{

//Get IObjectCopy interface

IObjectCopy objectCopy =newObjectCopyClass();

//Get IUnknown interface (map to copy)

object toCopyMap = axMapControl1.Map;

//Get IUnknown interface (copied map)

object copiedMap = objectCopy.Copy(toCopyMap);

//Get IUnknown interface (map to overwrite)

object toOverwriteMap = axPageLayoutControl1.ActiveView.FocusMap;

//Overwrite the PageLayoutControl's map

objectCopy.Overwrite(copiedMap,reftoOverwriteMap);

}

要实现axPageLayoutControl1中的数据与axMapControl1中的数据同步,需要在axMapControl1的以下事件中写入相应的代码:

private voidaxMapControl1_OnMapReplaced(objectsender,

ESRI.ArcGIS.MapControl.IMapControlEvents2_OnMapReplacedEvent e)

{

       CopyAndOverwriteMap();

}

private voidaxMapControl1_OnAfterScreenDraw(objectsender,

ESRI.ArcGIS.MapControl.IMapControlEvents2_OnAfterScreenDrawEvent e)

{

//Get IActiveView interface

IActiveView activeView = (IActiveView)

axPageLayoutControl1.ActiveView.FocusMap;

//Get IDisplayTransformation interface

IDisplayTransformation displayTransformation =

activeView.ScreenDisplay.DisplayTransformation;

//Set the visible extent of the focus map

displayTransformation.VisibleBounds = axMapControl1.Extent;                    

axPageLayoutControl1.ActiveView.Refresh(); //根据MapControl的视图范围,确定PageLayoutControl的视图范围

CopyAndOverwriteMap();

}

private voidaxMapControl1_OnViewRefreshed(objectsender,

ESRI.ArcGIS.MapControl.IMapControlEvents2_OnViewRefreshedEvent e)

{

         //axTOCControl1.Update ();

        CopyAndOverwriteMap();

}

         运行但是axTOCControl控件图层不显示,这是因为还要设置SetBuddyControl,ToolBarControl控件中同样要设置,只需要在在主窗口Load函数中添加下面一句话就可以了

        private void MainForm_Load(object sender, EventArgs e)
        {
            axTOCControl1.SetBuddyControl(axMapControl1);//ADD
            axToolbarControl1.SetBuddyControl(m_mapControl);
        } 
 

7鹰眼的实现

         鹰眼用来显示主窗体当前视图范围在全景视图中的位置,在ArcMap中使用一个线框在鹰眼视图中标识。当主视图中的视图范围改变时,鹰眼中的线框随之改变,当拖动鹰眼视图中的红线框时,主视图中的视图范围也随之改变。

下面开始实现鹰眼功能,添加using ESRI.ArcGIS.Carto、using ESRI.ArcGIS.Geometry、

using ESRI.ArcGIS.Display三个引用。首先在axMapControl1中视图范围改变时鹰眼窗体要做出对应的响应,即绘制线框并显示,在OnExtentUpdated事件中添加代码如下:

         private void axMapControl1_OnExtentUpdated       (object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnExtentUpdatedEvent e)

        {

            //创建鹰眼中线框

            IEnvelope pEnv = (IEnvelope)e.newEnvelope;

            IRectangleElement pRectangleEle = new RectangleElementClass();

            IElement pEle = pRectangleEle as IElement;

            pEle.Geometry = pEnv;

            //设置线框的边线对象࿰

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值