ArcGIS Engine: Creation of view menu and implementation of Eagle Eye diagram

Table of contents

01 Create project

1.1 Create a form application through ArcGIS-ExtendingArcObjects

1.2 Create a form application through C#-Windows Form application

1.2.1 Create a basic project

1.2.2 Building the interface

02 Create a view menu

03 Implementation of Eagle Eye Diagram

3.1 Triggering of OnMapReplaced event

 3.2 Triggering of OnExtentUpdated event

 04 Give a short demonstration


01 Create project

1.1 Create a form application through ArcGIS-ExtendingArcObjects

There may be no ArcGIS-ExtendingArcObjects option in your template. This may be related to the VS version. Generally, this situation may occur by changing the registry and using a VS version higher than 12.

But in fact, the module is to first add some simple ArcGIS modules to the most basic C# form application (.NET framework) for you. This is just more convenient. So later on, in order to take care of some of my classmates, I started masturbating from scratch. Of course, it saves time. It won’t have the same functions as the above template, but it’s just roughly the same.

(Because the experiment is based on this template, no matter whether we use this template or do it by ourselves, the subsequent experiments are the same, except that the first creation project here is to use a template, and the other is to create a basic form application. Then add the same functionality as the template yourself.)

 

Let’s take a look at the software interface after running:

Okay, let’s start from the beginning and see how my skills are. After all, I only studied for two or three days.

1.2 Create a form application through C#-Windows Form application

1.2.1 Create a basic project

1.2.2 Building the interface

The interface here is only for viewing, but no code has been put into it, that is, interactive events have been written. Like what happens when I click, that sort of thing.

 Let’s come back and see what their interface looks like:

Okay, let's start building the menu bar 

This is just typing on the keyboard, there is nothing difficult. As for the dividing line, set it as follows:
 

Okay, let's start building the three controls ToolBar, TOC, and Map.

 Let's start adjusting the layout:

 

But it seems that other people's toolbars (ToolBar) seem to have some tools, but ours does not, so we still need to add some tools (this is very simple). The operation is as follows:

 

Add all the tools you need. I'll just add these for now:

There is no need to add anything to other controls, but there is a big problem here, that is, we have now added three key ArcGIS controls (TOC, ToolBar, Map), but we have not yet associated several controls. . So, why should we associate or bind? Because our code is written from scratch in a certain sense, each control is independent of each other. For example, normal people know that the tool in your ToolBar control should be used in the MapControl control (or More or less), for example, the layer information displayed in the TOC control should be the files displayed in the MapControl control, and for example, if you use the tools in the ToolBar control to load data, should the loaded data be displayed in the MapControl? , so this is another connection. Therefore, there is a correlation between various controls, so we need to bind them to let them know that they are actually related, otherwise you can only display them, as follows:

If you have bound it, it may be as follows (some tools are gray because you have not loaded the file or performed certain operations, so they are gray):

Okay, let's start explaining how to bind:

One step before you can run a yet incomplete software is to identify the ArcGIS version of the current application. This ensures that the correct ArcGIS Runtime version is bound to the application. This is a step that is often required in .NET applications developed using ArcGIS Engine or ArcGIS Desktop. This binding generally ensures that when your application runs, it finds and uses the correct version of the ArcGIS component. This is particularly important to avoid conflicts with multiple versions of the ArcGIS runtime.

In short, if you write this application from scratch and use ArcGIS components, you generally need this line of code:

Otherwise, the following error will be reported when running:

Unhandled System.InvalidOperationException:

ArcGIS version not specified. You must call RuntimeManager.Bind before creating any ArcGIS components.

 How to add code to solve the problem of unclear ArGIS version?

 This line of code:

ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);  // 解决版本不清晰问题

 Now you can run:

Below is the interface and the tools are ready for use. (I forgot one thing, you need to put the license control (LicenseControl control) in, otherwise it won’t work)

 As for the function of the menu bar, we will see the situation. Time is limited now. If we will use it in subsequent experiments, I will continue to add it.

02 Create a view menu

The previous file menu has also been put away. Our experiment is to create a view menu, including four functions: zoom in, zoom out, pan, and full image display.

First, let’s build the interface:

Then double-click the <Zoom> function to enter the specific event writing of the function, instead of just a layer of skin:

It should be noted that the code cannot be pasted directly because I have changed the names of each control (for my better understanding, it is also to know the meaning of the name, so when using each control in the code, the class name of the control is different from everyone else, for example Your Map control is axMapcontrol1, and mine is MainMapcontrol), change the name => Control-Properties-Name.

 The code for the zoom function is as follows:

private void 放大ToolStripMenuItem_Click(object sender, EventArgs e)
{
    // 该函数用于将鼠标状态切换为放大工具
    ControlsMapZoomInToolClass zoom_in = new ControlsMapZoomInToolClass();  //  实例化一个工具
    zoom_in.OnCreate(MainMapControl.Object);  // 告诉放大工具,它应该服务于谁,==> Map
    MainMapControl.CurrentTool = zoom_in;  // 将Map控件的当前使用工具切换为放大
}

But you cannot paste it directly, as errors may occur. You need to double-click your own zoomed-in designer location to enter the function it gives you to write, because my function name may not be consistent with yours, and even if it is consistent, there may be problems.

The other functions are similar, so I won’t explain them one by one (the comments are also written in more detail). There are four functions and four functions. Each function is the interface of ArcGIS called. Of course, because we use these Controls related classes, so make sure you have introduced the relevant libraries:

using ESRI.ArcGIS.Controls;  // 使用其中的工具类(例如平移工具Pan等)

The complete code for this part is as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using ESRI.ArcGIS.Controls;  // 使用其中的工具类(例如平移工具Pan等)

namespace Ex2Twinborn
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);  // 解决版本不清晰问题
            InitializeComponent();
        }

        private void 放大ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 该函数用于将鼠标状态切换为放大工具
            ControlsMapZoomInToolClass zoom_in = new ControlsMapZoomInToolClass();  //  实例化一个工具
            zoom_in.OnCreate(MainMapControl.Object);  // 告诉放大工具,它应该服务于谁,==> Map
            MainMapControl.CurrentTool = zoom_in;  // 将Map控件的当前使用工具切换为放大
        }

        private void 缩小ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 当前函数用于将鼠标状态切换为缩小工具
            ControlsMapZoomOutToolClass zoom_out = new ControlsMapZoomOutToolClass();
            zoom_out.OnCreate(MainMapControl.Object);  // 将缩小工具的服务对象进行绑定
            MainMapControl.CurrentTool = zoom_out;  // 将Map控件的当前使用工具切换为缩小
        }

        private void 平移ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 该函数用于将当前鼠标状态切换为平移工具
            ControlsMapPanToolClass pan = new ControlsMapPanToolClass();  //  如果不能正常运行, 请将引用下关于ESRI的所有引用的属性-嵌入互操作类型更改为false.
            pan.OnCreate(MainMapControl.Object);  // 告诉pan工具,你是在Map控件上进行工作的
            MainMapControl.CurrentTool = pan;  // 将Map控件当前的使用工具更改为平移工具
        }

        private void 全图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 该函数用于将当前Map进行全图显示-方法1
            MainMapControl.Extent = MainMapControl.FullExtent;
            MainMapControl.Refresh();
             方法2
            //ControlsMapFullExtentCommandClass full_extent = new ControlsMapFullExtentCommandClass();
            //full_extent.OnCreate(MainMapControl.Object);
            //full_extent.OnClick();
        }

        
    }
}

In fact, I think this part of the experiment is actually a bit redundant. There is actually no difference between the four tools in the view section of the menu bar that we wrote ourselves and the zoom, zoom, and pan functions of the ArcGIS Toolbar control (without doing every experiment) They are some comprehensive small projects rather than just doing some trivial things in this kind of place. It is like taking off your pants and farting). I can only say that for the time being, it is better to practice, which is better than nothing. This is the case.

03 Implementation of Eagle Eye Diagram

There are still some difficulties, and because of the flaws in the experiment, I don’t have the time and energy to fix some of the minor problems.

I think the implementation of the Eagle Eye Chart (actually a MapControl <can be more than one>) is divided into two parts. The first part is that when we add data to the main view, we also add the same data to the Eagle Eye Chart. Data actually means keeping the data of the two MapControl controls consistent. (But the experiment only completed the synchronization effect only when the mxd map document is added, we will talk about this later); The second is that when we move the main view or zoom in and out of the main view, the Eagle Eye map displays the global position of the main view ( The relative position is shown by the small red box).

3.1 Triggering of OnMapReplaced event

So we divide it into two events. The first one is when the data is added or modified (the data here is actually just the MXD document), the event is triggered, and we synchronize the data in the main view to the Eagle Eye chart. It is very simple in itself, but it is difficult to trigger when. The experiment is directly when the MXD document changes (replaces or adds something), then the Eagle Eye chart data display changes. PassOnMapReplaced.

So in summary, when will the OnMapReplaced event be triggered?

  1. Load MXD document : When you use AxMapControlthe LoadMxFilemethod to load a new MXD (Map Exchange Document, ArcMap map document format), the current Mapobject will be replaced by the object in the new MXD Map, so this event is triggered.

  2. Set the Map property : If the property you set directly AxMapControlis Mapa new Mapobject, then this event will also be triggered.

  3. Add/remove data frames : If you have multiple data frames in ArcMap and add or remove data frames using ArcObjects code or the ArcMap interface, the OnMapReplacedevent may also be triggered.

  4. New Map : If you create a brand new map in ArcMap, this will also trigger OnMapReplacedthe event.

etc.

Okay, let's start the operation now.

When the main view's data changes, the event is triggered, so:

code show as below:

// 当主视图(MainMapControl)的内容被替换了(实际上此处仅仅是针对mxd文档被替换,对于一般数据的加载实际上不会触发此函数), 那么执行该部分函数
// 该函数用于将主视图上的所有图层同步加载到鹰眼图中
for (int ix = 0; ix < MainMapControl.LayerCount; ix++)
{
    ILayer layer = MainMapControl.get_Layer(ix);
    EyeMapControl.AddLayer(layer);
}
EyeMapControl.Extent = EyeMapControl.FullExtent;  // 全图显示
EyeMapControl.Refresh();
EyeMapControl.AutoMouseWheel = false;  // 不允许有滚动条

 The idea is very simple. Find the total number of layers in the main view, MainMapControl.LayerCount, and then loop through each layer to find MainMapControl.get_layer (index <starting from 0>), and then add the found layer to the Eagle Eye view. Loop After the end, the entire image is displayed, and then refreshed; then no scroll bars are allowed.

Note adding the corresponding reference:

using ESRI.ArcGIS.Carto;  //  使用ILayer类

 3.2 Triggering of OnExtentUpdated event

As we have said before, there are two parts. The previous one about the need to synchronize the data of the main view has been solved on the Eagle Eye diagram, but if we perform operations such as panning, zooming in, and zooming out in the main view, how to The range of the current main view is displayed in the Eagle Eye diagram as a small red box to mark the relative position of our current browsing?

Here we actually already understand that whether you pan, zoom in, or otherwise, it is essentially a change in the display range of the current view, so we only need to detect that once the range of the current main view changes, the small red box will be redrawn immediately. Show new new location. So this requires passing the OnExtentUpdated event.

The specific operations are as follows:

 Code:

// 当主视图的Extent范围发生变化, 那么触发此事件
// 该函数用于更新鹰眼图中的矩形框(矩形框范围为主视图的Extent)
IRectangleElement pRectangleElement = new RectangleElement() as IRectangleElement;  // 新建一个矩形框并更换类型
IElement pEle = pRectangleElement as IElement;  //  再次更换类型
IEnvelope pEnv = e.newEnvelope as IEnvelope;  // 获取主视图的范围边框并更换类型为包络线==> IEnvelope
pEle.Geometry = pEnv;  // 设置刚刚创建的矩形边框的几何形状为刚刚主视图的范围的边框.

IRgbColor pColor = new RgbColor();  // 实例化一个颜色对象
pColor.Red = 200;  // 红色分量为200, 255表示完全红色
pColor.Transparency = 255;  // 颜色的透明度, 255表示完全不透明

ILineSymbol pLineSymbol = new SimpleLineSymbol();  // 实例化一个线对象
pLineSymbol.Width = 2;  // 线的宽度为2
pLineSymbol.Color = pColor;  // 线的颜色为刚刚设置的不饱和但完全不透明的红色

IFillSymbol pFillSymbol = new SimpleFillSymbol();  // 创建一个填充符号
pColor.Transparency = 0;  // 刚刚的颜色透明度修改为0也就是完全透明度
pFillSymbol.Color = pColor;  // 填充色设置为刚刚的颜色, 实际上就是透明度的没有任何填充
pFillSymbol.Outline = pLineSymbol;  // 但是填充符号的外边框(它是线)设置为刚刚的线对象

IFillShapeElement pFillShapeElement = pRectangleElement as IFillShapeElement;
pFillShapeElement.Symbol = pFillSymbol;

IGraphicsContainer pGC = EyeMapControl.Map as IGraphicsContainer;  // 创建一个
pGC.DeleteAllElements();  // 清除之前所有的图形\注记等等避免与后面新的图形发生冲突或者重叠.
pGC.AddElement(pEle, 0);  // 添加矩形框在最底层

IActiveView pActiveView = EyeMapControl.Map as IActiveView;
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
// 刷新的图层是图形层(不包括加载的数据等)、刷新的对象(null表示图形层的所有对象)、刷新的空间范围(null表示整个鹰眼图范围)

 04 Give a short demonstration

 

Guess you like

Origin blog.csdn.net/m0_63001937/article/details/133577248