ArcGIS Engine二次开发(基于C#)

目录

1 前言

2 准备工作

2.1 License的加入

 2.2 ToolStrip控件

 2.3 MenuStrip控件

2.4 帮助文档的查看

 3 数据加载

3.1 矢量数据的加载

 3.2 栅格数据的加载

4 地图浏览功能

5.点线面的绘制:点、线、圆、多边形、矩形,

5.1 测试

(1)对“绘制点”功能进行测试

(2)对“绘制线”功能进行测试

(3)对“绘制面”功能进行测试

(4)对“绘制矩形”功能进行测试

(5)对“绘制多边形”功能进行测试

5.2 代码

6.书签功能

6.1 测试

6.2 代码

(1)主窗口代码

(2)副窗口代码

7.选择要素(拉框选择、按多边形选择、按圆选择、按线选择)

7.1 图标

7.2 测试

(1)按矩形选择

(2)按圆选择

(3)按多边形选择

(4)按线选择

(5)清除所选要素

7.3 代码

8.属性查询

8.1界面设计

(1)地图显示界面

(2)属性查询界面

8.2 测试

(1)创建一个新的选择

(2)添加到现有选择中

(3)从已有选择中移除

(4)从已有选择中选择

8.3 代码

(1)主窗口代码

(2)副窗口代码

9 空间查询

9.1 界面设计

(1)主界面

(2)空间查询界面

9.2 代码

(1)主窗口mapForm

(2)副窗口spatialQueryForm

10 集成

10.1 界面设计

10.2 代码

(1)主窗口mapForm

(2)属性查询的窗口attributeQueryForm

(3)属性表窗口attributeTable

(4)书签窗口bookMarkForm

(5)空间查询窗口spatialQueryForm

11 总结


 


1 前言


这是一份关于ArcGIS Engine二次开发的一份报告总结,在这份报告中包含了简单的ArcGIS功能。包含的功能如下:

  1. 对数据的加载,包括矢量数据和栅格数据
  2. 地图浏览功能:拉框放大、拉框缩小、平移、全图、逐级放大、逐级缩小、历史视图浏览(撤销、重做)
  3. 点线面的绘制:点、圆、多边形、矩形,能分别设置颜色、样式、大小及面填充方式

  4. 书签功能

  5. 选择要素:拉框选择、按多边形选择、按圆选择、按线选择,并能设置选择颜色

  6. 属性查询

  7. 空间查询

首先会先对各个功能分别进行介绍,我之前做也是一个功能一个功能写过来的,最后会放出集成的界面和代码。


2 准备工作


在开始正式书写代码之前,我们需要了解一些基本知识。

2.1 License的加入

 License是进行AE开发必须加入的功能,我们创建一个窗体项目后首先加入 LicenseControl控件,然后在Program.cs中添加如下橙色部分代码(注意不要加错位置):

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
            Application.Run(new mapForm());

b2092733fa8afb9b78ffe15869e415ba.jpeg99c9a3b67827126b85541c1cff860f35.jpeg

 2.2 ToolStrip控件

ToolStrip控件位于工具箱的菜单和工具栏中,可以添加图中所示的几个功能:Button、Label、SplitButton、DropDownButton、Separator、ComboBox、TextBox、ProgressBar。这里用到了Button功能,前九个功能通过添加Button来完成,图片可以自行添加。

79bdb2f28817e4d437d34ce1fe98717e.jpeg9e2f7914d413b3374c153f7456380aa7.jpeg

 

 2.3 MenuStrip控件

menustrip可以进行下拉菜单的创建,比如查询功能中包含两个功能,一个是属性查询,一个是空间查询,通过menustrip将二者放到一个下拉菜单中,可以保证界面的整洁舒适,以及功能的方便使用。

1208502412dbbb12cfe54a1b4e7dd73f.jpeg

06c859b230969596d8e8a8312d0572c7.jpeg

2.4 帮助文档的查看

在开始中找到ArcGIS,找到对应的帮助文档,我的Visual Studio是2012版的,用的是第二个。打开帮助我们可以对需要使用的功能进行查询,比如OpenFileDialog,右边是对其用法的介绍。

e6dd4a04f7080f7248a9ad7daadee84a.jpeg

1403e1393e41ef7dcfd59d76859c787a.jpeg


 3 数据加载


3.1 矢量数据的加载

首先在ToolStrip中添加一个button,直接点击可进行添加;然后在Image中填充“添加数据”的图片,以便和其它功能进行区分,该图片可自行到ArcGIS中进行截图或在网上寻找相关图像;最后通过ToolTipText可以添加对该按钮的描述,当鼠标停在该按钮上时,显示文字。

7272c8c1ee60d9c9e1ddb4b90a858859.jpeg

 

 5b26b0a2458ee5bf25356300bc91344c.jpeg

 

8c3ce8f31138901e628606edce962fab.jpeg

双击按钮默认使用click事件,双击按钮,加入以下代码:

注:由于每行代码都有注释,这里不再赘述。

//打开矢量数据
        private void btnShpOpen_Click(object sender, EventArgs e)
        {
            //实例化一个对象
            OpenFileDialog openShipFile = new OpenFileDialog();
            //打开窗体名称
            openShipFile.Title = "加载矢量数据";
            //允许选择多项
            openShipFile.Multiselect = true;
            //过滤选择矢量数据
            openShipFile.Filter = "ShapeFile数据|*.shp";

            //定义整型intPosition,用于存放位置
            int intPosition;
            //定义字符型stringFilePath和stringFileName,用于存放文件路径和文件名
            string stringFilePath, stringFileName;

            if (openShipFile.ShowDialog() == DialogResult.OK)
            {
                //定义字符型file表示打开文件中的文件名,用foreach进行访问
                foreach (String file in openShipFile.FileNames)
                {
                    //将\\的最后一个位置赋予intPosition
                    intPosition = file.LastIndexOf("\\");
                    //将intPosition前的路径存入stringFilePath中
                    stringFilePath = file.Substring(0, intPosition);
                    //将intPosition后的文件名存入stringFileName中
                    stringFileName = file.Substring(intPosition + 1);

                    //显示数据
                    axMapControl1.AddShapeFile(stringFilePath, stringFileName);
                    //弹框显示数据路径和名称
                    //MessageBox.Show(stringFilePath, stringFileName);
                }
            }
        }

 3.2 栅格数据的加载

栅格数据比矢量数据复杂,这里我并没有将栅格数据和矢量数据的加载放在同一个按钮上实现,而是通过一个新的按钮进行添加。

这里对jpg、img、tiff三种格式的栅格数据进行了添加。

双击按钮默认使用click事件,双击按钮,加入以下代码:

//打开栅格数据
        private void btnRasterOpen_Click(object sender, EventArgs e)
        {
            //实例化对象
            OpenFileDialog openRaster = new OpenFileDialog();
            //命名弹窗名称
            openRaster.Title=("加载栅格数据");
            //允许选择多项
            openRaster.Multiselect = true;
            //过滤栅格数据
            openRaster.Filter = "栅格文件jpg|*.jpg|栅格文件tiff|*.tiff|栅格文件img|*.img";

            //定义整型位置intPosition
            int intPosition;
            //定义字符型路径stringFilePath和名字stringFileName
            string stringFilePath, stringFileName;

            if (openRaster.ShowDialog() == DialogResult.OK)
            {
                //foreach访问
                foreach (String file in openRaster.FileNames)
                {
                    //intPosition的1位置在最后一个\\处
                    intPosition = file.LastIndexOf("\\");
                    //路径
                    stringFilePath = file.Substring(0, intPosition);
                    //文件名
                    stringFileName = file.Substring(intPosition + 1);

                    //IWorkSpace是一个容器,存放空间数据与非空间数据
                    //如:FeatureClass、RasterDataset、table等
                    //IWorkSpace有三种类型:FileSystemWorkspace、LocalDatsbaseWorkspace,RemoteDatabaseWorkspace
                    //WorkSpace类不能直接实例化,必须由IWorkSpaceFactory的Create方法创建
                    //WorkspaceFactory:create workspace

                    //IRasterWorkspace Interfece:provides access to members that control a raster workspace
                    //含OpenRasterDataset:Opens a rasterdataset in the workspace given its name

                    //通过IworkSpaceFactory创建工作空间,将其在RasterWorkspaceFactory中实例化
                    IWorkspaceFactory prasterWorspaceFactory = new RasterWorkspaceFactory();
                    //创建一个栅格工作空间,将其在工作空间中的栅格文件在栅格工作空间中打开
                    IRasterWorkspace rasterWorkSpace = prasterWorspaceFactory.OpenFromFile(stringFilePath, 0) as IRasterWorkspace;
                    //将栅格空间中的空间数据打开
                    IRasterDataset pRasterDataset = rasterWorkSpace.OpenRasterDataset(stringFileName);

                    //IRasterLayer:provide access to members that create or modify a raster layer
                    //RasterLayerClass:raster layer source and display options
                    IRasterLayer pRasterLayer = new RasterLayerClass();
                    //在图层中创建栅格数据
                    pRasterLayer.CreateFromDataset(pRasterDataset);
                    //ILayer:provide access to members that work with all layers
                    //将栅格图层转换为图层形式
                    ILayer pLayer = pRasterLayer as ILayer;

                    //显示栅格图层
                    axMapControl1.AddLayer(pLayer);
                }
            }
        }

至此便可完成对矢量数据和栅格数据的加载。


4 地图浏览功能


地图浏览功能包含:矩形拉框放大、矩形拉框缩小、平移(漫游)、全图显示、逐级放大、逐级缩小、历史视图浏览(撤销、重做)

在ToolStrip中分别八个功能进行添加,分别设置好图片内容和鼠标悬浮显示文字。

93f4198afad58fadbe0146c366439717.jpeg

双击按钮默认使用click事件,双击按钮,加入以下代码:

注:由于全图显示、逐级放大、逐级缩小、历史视图浏览(撤销、重做)五个功能只需要点击对应按钮,触发Click事件即可实现,因此不对其进行功能标识;而矩形拉框放大、矩形拉框缩小、平移(漫游)在触发Click事件之后还要在axMapControl1中进行鼠标点击以实现功能,故需通过flag对其进行标识。

//地图浏览
        int flag;
        //放大
        private void enLarge_Click(object sender, EventArgs e)
        {
            flag = 1;
            axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomIn;
        }
        //缩小
        private void Suoxiao_Click(object sender, EventArgs e)
        {
            flag = 2;
            axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomOut;
        }
        //平移
        private void Pingyi_Click(object sender, EventArgs e)
        {
            flag = 3;
            axMapControl1.MousePointer = esriControlsMousePointer.esriPointerPan;
        }
        //逐级放大
        private void EnlargeByStep_Click(object sender, EventArgs e)
        {
            IEnvelope yEnvelop = axMapControl1.Extent;
            yEnvelop.Expand(0.5, 0.5, true);
            axMapControl1.Extent = yEnvelop;
            axMapControl1.ActiveView.Refresh();
        }
        //逐级缩小
        private void SuoxiaoBystep_Click(object sender, EventArgs e)
        {
            IEnvelope yEnvelop = axMapControl1.Extent;
            yEnvelop.Expand(2, 2, true);
            axMapControl1.Extent = yEnvelop;
            axMapControl1.ActiveView.Refresh();
        }
        //全图显示
        private void Entire_Click(object sender, EventArgs e)
        {
            axMapControl1.Extent = axMapControl1.FullExtent;
        }
        
        IExtentStack yExtentStack;
        //上一级视图
        private void before_Click(object sender, EventArgs e)
        {
            yExtentStack = axMapControl1.ActiveView.ExtentStack;
            //判断是否可返回
            if (yExtentStack.CanUndo())
            {
                yExtentStack.Undo();
                before.Enabled = true;
                if (!yExtentStack.CanUndo())
                {
                    before.Enabled = false;
                }
            }
            axMapControl1.ActiveView.Refresh();
        }
        //下一级视图
        private void after_Click(object sender, EventArgs e)
        {
            yExtentStack = axMapControl1.ActiveView.ExtentStack;
            if (yExtentStack.CanRedo())
            {
                yExtentStack.Redo();
                after.Enabled = true;
                if (!yExtentStack.CanRedo())
                {
                    after.Enabled = false;
                }
            }
            axMapControl1.ActiveView.Refresh();
        }

 在axMapControl1_OnMouseDown中加入以下代码:

*地图浏览
            //激活
            IActiveView yActiveView = axMapControl1.ActiveView;
            //框架
            IEnvelope yEnvelope = new EnvelopeClass();
            switch (flag)
            {
                case 1:
                    //框架为矩形
                    yEnvelope = axMapControl1.TrackRectangle();
                    //视图范围为框架选择范围
                    yActiveView.Extent = yEnvelope;
                    //刷新
                    yActiveView.Refresh();
                    break;

                case 2:
                    //框架为矩形缩小
                    yEnvelope = axMapControl1.TrackRectangle();
                    //两倍缩小
                    yEnvelope.Expand(2, 2, true);
                    //视图范围为框架范围
                    yActiveView.Extent = yEnvelope;
                    //刷新
                    yActiveView.Refresh();
                    break;

                case 3:
                    //漫游
                    axMapControl1.Pan();
                    break;

                default:
                    break;

            }

 至此便可实现地图浏览的“矩形拉框放大、矩形拉框缩小、平移(漫游)、全图显示、逐级放大、逐级缩小、历史视图浏览(撤销、重做)”八个功能。


5.点线面的绘制:点、线、圆、多边形、矩形,


点线面的绘制要求能分别设置颜色、样式、大小及多边形面的填充方式

如图所示是我设计的绘制界面,有点潦草,朋友们自己做的时候可以设计的好看一点哈哈哈。

f3c9e4fea5e3430a8c541e6dbad2c9aa.png

5.1 测试

(1)对“绘制点”功能进行测试

点的样式共有四种,分别是正方形、圆形、十字型、X型和棱形,分别对这些样式进行颜色和大小的测试,总体上没问题。

d4643e33c27845b99b0d461aee1f20f0.png

(2)对“绘制线”功能进行测试

这个功能稍微有点问题,一个是绘制的线条无法完成绘制,鼠标总是拖着线走,还有一个是线的样式、粗细和颜色都无法改变,这一块稍微有点问题,我也在积极解决中,虽然这个没有做出来但并不影响后面的噢。

35593670558a4c409067a597d4c1c274.png

(3)对“绘制面”功能进行测试

这个与其说是“绘制面”,不如说是“绘制圆”,代码引用的也是axMapControl1.TrackCircle(),命名的时候可以改一下。

这个圆有九种填充方式,分别是实心填充、不填充、空心填充、水平线填充、垂直线填充、45度下斜线填充、45度上斜线填充、水平十字线填充和45度交叉线填充,其中不填充和空心填充的表现形式是一样的。

经过测试,面边框宽度、填充样式、填充颜色和边框线功能都正常,测试结果如图所示。

7473f4b087ef4fc59518ac7772ba7f11.png

(4)对“绘制矩形”功能进行测试

“绘制矩形”功能同样有九种填充样式,分别是实心填充、不填充、空心填充、水平线填充、垂直线填充、45度下斜线填充、45度上斜线填充、水平十字线填充和45度交叉线填充,其中不填充和空心填充的表现形式是一样的。

经过测试,矩形边框宽度、填充样式、填充颜色和边框线功能都正常,测试结果如图所示。

b829773bfeba4310b224bb67b9d11a28.png

(5)对“绘制多边形”功能进行测试

绘制矩形”功能同样有九种填充样式,分别是实心填充、不填充、空心填充、水平线填充、垂直线填充、45度下斜线填充、45度上斜线填充、水平十字线填充和45度交叉线填充,其中不填充和空心填充的表现形式是一样的。

经过测试,矩形边框宽度、填充样式、填充颜色和边框线功能都正常,测试结果如图所示。

b74b37e78ded4d7b8d3cc7628cd65f55.png

5.2 代码

所以呢,除了“绘制线”功能有点问题之外,其他功能都正常,下面是点线面绘制的整体代码。

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.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;


namespace Drwaing
{
    public partial class frmDrawShape : Form
    {
        public frmDrawShape()
        {
            InitializeComponent();
            btnDrawPoint.Text = "绘制点"; //设置按钮的名称
            btnDrawLine.Text = "绘制线"; //设置按钮的名称
            btnDrawSurface.Text = "绘制面"; //设置按钮的名称
            btnDrawRectangle.Text = "绘制矩形"; //设置按钮的名称
            nbtnDrawPolygon.Text = "绘制多边形";
            btnDrawText.Text = "输入文字";
            label1.Text = "边框颜色";
        }

        int flag = 0; //默认状态
        IRgbColor pColor; //用pColor调用颜色
        IRgbColor rColor;

        private void btnDrawPoint_Click(object sender, EventArgs e)
        {
            //画点
            flag = 1;
            setPoint();
        }
        private void setPoint()
        {
            //设置相关标签名称和点的可选样式
            lblSize.Text = "点的大小"; 
            txtSize.Text = "3"; 
            txtSize.Visible = true;
            lblStyle.Text = "点的样式";
            lblColor.Text = "颜色";

            cmbStyle.Items.Clear(); //进行下拉框内容的清楚,防止重复出现
            cmbStyle.Items.Add("正方形");
            cmbStyle.Items.Add("圆");
            cmbStyle.Items.Add("十字形");
            cmbStyle.Items.Add("X形");
            cmbStyle.Items.Add("菱形");
            cmbStyle.SelectedIndex = 0; //默认选择第一个样式
        }

        private void btnDrawLine_Click(object sender, EventArgs e)
        {
            //画线
            flag = 2;

            lblSize.Text = "线的宽度";
            lblStyle.Text = "线的样式";
            txtSize.Visible = true;
            txtSize.Text = "1";

            cmbStyle.Items.Clear(); //进行下拉框内容的清除,防止重复出现
            cmbStyle.Items.Add("实线");
            cmbStyle.Items.Add("短横线");
            cmbStyle.Items.Add("点线");
            cmbStyle.Items.Add("短横线和点线");
            cmbStyle.Items.Add("短横线两点线");
            cmbStyle.Items.Add("不可见的线");
            cmbStyle.Items.Add("矩形边界线");
            cmbStyle.SelectedIndex = 0; //默认为实线
        }

        private void btnDrawSurface_Click(object sender, EventArgs e)
        {
            flag = 3;
            setSurface();
        }
        private void btnDrawRectangle_Click(object sender, EventArgs e)
        {
            flag = 4;
            setSurface();
        }
        private void nbtnDrawPolygon_Click(object sender, EventArgs e)
        {
            flag = 5;
            setSurface();
        }
        private void setSurface()
        {
            lblSize.Text = "面边框的宽度";
            txtSize.Text = "1";
            txtSize.Visible = true;
            lblStyle.Visible = true;

            cmbStyle.Items.Clear();
            cmbStyle.Items.Add("实心填充");
            cmbStyle.Items.Add("不填充");
            cmbStyle.Items.Add("空心填充");
            cmbStyle.Items.Add("水平线填充");
            cmbStyle.Items.Add("垂直线填充");
            cmbStyle.Items.Add("45度下斜线填充");
            cmbStyle.Items.Add("45度上斜线填充");
            cmbStyle.Items.Add("水平十字线填充");
            cmbStyle.Items.Add("45度交叉线填充");
            cmbStyle.SelectedIndex = 0;
        }

        private void btnDrawText_Click(object sender, EventArgs e)
        {
            flag = 6;
            lblSize.Text = "字的大小";
            txtSize.Text = "16";
            txtSize.Visible = true;
            lblStyle.Visible = false;
            cmbStyle.Visible = false;
        }
        private void drawMapText(IGeometry geometry)
        {
            setColor();
            ITextSymbol txtSymbol;
            stdole.IFontDisp pFont;
            pFont = new stdole.StdFontClass() as stdole.IFontDisp;

            txtSymbol = new TextSymbol();
            object symbol = txtSymbol;

            double pDouble, pWith;
            bool isNum = System.Double.TryParse(txtSize.Text, System.Globalization.NumberStyles.Integer, null, out pDouble);
            if (isNum == false)
            {
                MessageBox.Show("您输入的不是一个数字,请输入一个数字。", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
            }
            else
            {
                pWith = Convert.ToDouble(txtSize.Text);
                pFont.Size = (decimal)pWith;
            }

            txtSymbol.Color = pColor;
            txtSymbol.Font = pFont;
            axMapControl1.DrawText(geometry, txtSymbol.Text, ref symbol);
        }

        private void setColor()
        {
            //默认颜色,黑色
            if (pColor == null)
            {
                pColor = new RgbColor();
                pColor.Red = 0;
                pColor.Blue = 0;
                pColor.Green = 0;
            }
            if (rColor == null)
            {
                rColor = new RgbColor();
                rColor.Red = 0;
                rColor.Blue = 0;
                rColor.Green = 0;
            }

        }
        private void frmDrawShape_Load(object sender, EventArgs e)
        {
            setPoint();
        }

        private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            IGeometry geometry = null; //geometry初始为空
            IPoint point = new ESRI.ArcGIS.Geometry.Point(); //point为ArcGIS中的point

            if (flag == 1 || flag == 0)
            {
                point.X = e.mapX; //屏幕X坐标为地图X坐标
                point.Y = e.mapY; //屏幕Y坐标为地图Y坐标
                geometry = point as IGeometry;
            }
            else if (flag == 2)
            {
                geometry = axMapControl1.TrackLine();
            }
            else if (flag == 3)
            {
                geometry = axMapControl1.TrackCircle();
            }
            else if (flag == 4)
            {
                geometry = axMapControl1.TrackRectangle();
            }
            else if (flag == 5)
            {
                geometry = axMapControl1.TrackPolygon();
            }
            else if (flag == 6)
            {
                point.X = e.mapX;
                point.Y = e.mapY;
                geometry = point as IGeometry;
            }
            if (flag >= 0 && flag <= 5)
            {
                drawMapShape(geometry);
            }
            else if (flag == 6)
            {
                drawMapText(geometry);
            }
        }

        private void drawMapShape(IGeometry pGeometry)
        {

            object symbol = null; //符号初始为空值
            setColor(); //调用setColor方法,使用默认颜色值

            double pWith; //定义一个双精度型的pWith,用来存放符号大小
            double pDouble; //定义一个pDouble用来输出输入的大小
            bool isNum; //用于判别输入的是否为数字

            isNum = System.Double.TryParse(txtSize.Text, System.Globalization.NumberStyles.Integer, null,out pDouble);
            if (isNum == false)
            {
                MessageBox.Show("这不是一个数字,请输入一个数字。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else
            {
                pWith = Convert.ToDouble(txtSize.Text); //将文本型的字符转换为双精度数字

                if (pGeometry.GeometryType == esriGeometryType.esriGeometryPoint)
                {
                    ISimpleMarkerSymbol pmarkerSymbol = new SimpleMarkerSymbol(); //实例化一个pmarkerSymbol用来存放点的符号类型
                    pmarkerSymbol.Color = pColor; //将默认的颜色赋给pmarkerSymbol
                    pmarkerSymbol.Size = pWith; //将转换后得到的符号大小赋给pmarkerSymbol
                    if (cmbStyle.SelectedItem.ToString() == "正方形")
                    {
                        pmarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSSquare;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "圆")
                    {
                        pmarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "十字形")
                    {
                        pmarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCross;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "X形")
                    {
                        pmarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSX;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "菱形")
                    {
                        pmarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSDiamond;
                    }
                    symbol = pmarkerSymbol; //将各类情况下的pmarkerSymbol赋给symbol
                }
                else if (pGeometry.GeometryType == esriGeometryType.esriGeometryLine)
                {
                    ISimpleLineSymbol pSLS;
                    pSLS = new SimpleLineSymbol();
                    pSLS.Color = pColor;
                    pSLS.Width = pWith;
                    if (cmbStyle.SelectedItem.ToString() == "实线")
                    {
                        pSLS.Style = esriSimpleLineStyle.esriSLSSolid;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "短横线")
                    {
                        pSLS.Style = esriSimpleLineStyle.esriSLSDash;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "点线")
                    {
                        pSLS.Style = esriSimpleLineStyle.esriSLSDot;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "短横线和点线")
                    {
                        pSLS.Style = esriSimpleLineStyle.esriSLSDashDot;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "短横线两点线")
                    {
                        pSLS.Style = esriSimpleLineStyle.esriSLSDashDotDot;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "不可见的线")
                    {
                        pSLS.Style = esriSimpleLineStyle.esriSLSNull;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "矩形边界线")
                    {
                        pSLS.Style = esriSimpleLineStyle.esriSLSInsideFrame;
                    }
                    symbol = pSLS;
                }
                else
                {
                    ISimpleFillSymbol psimpleFillSymbol;
                    psimpleFillSymbol=new SimpleFillSymbol();
                    psimpleFillSymbol.Color = pColor; //内部颜色

                    ILineSymbol pLineSymbol = new SimpleLineSymbol();
                    pLineSymbol.Width = pWith;
                    pLineSymbol.Color = rColor; //边框颜色
                    psimpleFillSymbol.Outline = pLineSymbol;

                    if (cmbStyle.SelectedItem.ToString() == "实心填充")
                    {
                        psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "不填充")
                    {
                        psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSNull;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "空心填充")
                    {
                        psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSHollow;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "水平线填充")
                    {
                        psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSHorizontal;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "垂直线填充")
                    {
                        psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSVertical;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "45度下斜线填充")
                    {
                        psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSForwardDiagonal;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "45度上斜线填充")
                    {
                        psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSBackwardDiagonal;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "水平十字线填充")
                    {
                        psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSCross;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "45度交叉线填充")
                    {
                        psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSDiagonalCross;
                    }
                    symbol = psimpleFillSymbol;
                }
                axMapControl1.DrawShape(pGeometry, ref symbol);
            }
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            //设置可选颜色
            ColorDialog pColorDialog = new ColorDialog();
            if (pColorDialog.ShowDialog() == DialogResult.OK)
            {
                pColor = new RgbColor();
                pColor.Red = pColorDialog.Color.R;
                pColor.Green = pColorDialog.Color.G;
                pColor.Blue = pColorDialog.Color.B;
            }
        }

        private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            if (flag >=1&&flag<7)
            {
                axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
            }
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {
            ColorDialog pColorDialog = new ColorDialog();
            if (pColorDialog.ShowDialog() == DialogResult.OK)
            {
                rColor = new RgbColor();
                rColor.Red = pColorDialog.Color.R;
                rColor.Green = pColorDialog.Color.G;
                rColor.Blue = pColorDialog.Color.B;
            }
        }


    }
}

6.书签功能


书签这一部分功能涉及到两个窗口,一个是主窗口,一个是副窗口。主窗口就是我们浏览地图的主界面,副窗口是创建书签时弹出来的界面,自然也就涉及到了主副窗口之间的交互。

主窗口界面如下所示,窗口命名为frmMain,注意是代码里的名称,不是窗口显示的名字。

fcaf1a342dc84cfd98cfceb2e42d02d7.png

副窗口界面如下所示,窗口命名为frmSub

0d227b0642254b0a8ca4e71923c16fbf.png

6.1 测试

对正常大小,放大,缩小三种状态进行书签标记测试,任意添加一层矢量图层。

cef8a16de00643688885cee4393e77da.png

添加书签,标记正常大小视图。

a9909f6ea3ff477bbdec30c1dc8f407a.png

c128da53ddcb40fcb178d60869c051cd.png

添加书签,标记放大视图。

d99f5a017b47407a96f266a469ef8f54.png

18457b07d0224038a9e94745b621676c.png

添加书签,标记缩小视图。

f2829fe020b14c70a708825443a5d43c.png

5b98601ac3a34fdbb682d65a2233fcec.png

点开书签,打开所建书签,可以看到之前记录的三个书签,分别打开,可以还原到所记录时的视图。

264dd0a7a4c742ea8cbe1ca120fcdefd.png

经测试,添加书签功能正常。

6.2 代码

(1)主窗口代码

首先展示主窗口的代码,大家直接看代码里的注释就好,这里就不再赘述。

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.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geometry;

namespace bookMark
{
    public partial class frmMain : Form
    {
        //主窗体
        public frmMain() 
        {
            InitializeComponent(); //初始化
        }

        //添加书签
        private void addBookMark_Click(object sender, EventArgs e)
        {
            frmSub bookMark = new frmSub(this); //this引用frmSub中的mainFrm
            bookMark.Show(); //显示添加书签的副窗体
        }


        //书签功能用到的三个接口
        //1.IMapBookmarks
        //  属性:Bookmarks,用于得到地图文档中已经存在的所有书签对象
        //  方法一:AddBookmark,用于添加书签
        //  方法二:RemoveBookmark,用于删除书签
        //2.ISpatialBookmark
        //  属性:Name,用于定义书签的名字
        //  方法:ZoomTo,用于跳转到书签位置
        //3.IAOIBookmark(继承于ISpatialBookmark)
        //  属性:Location,用于存储地图中感兴趣的范围


        //添加函数CreatBookmark用于创建书签,内涵一个字符型参数sBookmarkName
        public void createBookmark(string sBookmarkName)
        {
            IAOIBookmark aoiBookmark = new AOIBookmarkClass();

            if (aoiBookmark != null)
            {
                //将地图中的范围赋给aoiBookmark中的位置属性
                aoiBookmark.Location = axMapControl1.ActiveView.Extent;
                //将书签名字赋给aoiBookmark的Name
                aoiBookmark.Name = sBookmarkName;
            }

            //得到书签
            IMapBookmarks bookmarks = axMapControl1.Map as IMapBookmarks;

            //如果bookmarks不为空,也就是有书签
            if (bookmarks != null)
            { //将aoiBookmark添加到书签
                bookmarks.AddBookmark(aoiBookmark);
            }

            //在cmbBookMark中添加变量aoiBookmark中的名称
            cmbBookMark.Items.Add(aoiBookmark.Name);
        }

        //选中组合框中的标签,显示所选标签范围
        private void cmbBookMark_SelectedIndexChanged(object sender, EventArgs e)
        {
            //获得书签列表
            IMapBookmarks bookmarks = axMapControl1.Map as IMapBookmarks;
            IEnumSpatialBookmark enumSpatialBookmark = bookmarks.Bookmarks;

            enumSpatialBookmark.Reset(); //重置标签顺序
            //Next 返回下一空间书签
            ISpatialBookmark spatialBookmark = enumSpatialBookmark.Next();
            while (spatialBookmark != null)
            {
                if (cmbBookMark.SelectedItem.ToString() == spatialBookmark.Name)
                {
                    //将选中标签范围进行显示
                    spatialBookmark.ZoomTo((IMap)axMapControl1.ActiveView);
                    axMapControl1.ActiveView.Refresh(); //刷新窗口
                    break;
                }
                spatialBookmark = enumSpatialBookmark.Next();
            }
        }
    }
}

(2)副窗口代码

由于副窗口是要根据主窗口展示的内容进行运行的,所以肯定有两个窗口之间的交互,这里我用到了类和构造函数,不是很能理解的小伙伴建议补一下C#的相关内容,我当时也琢磨了很久。

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;

namespace bookMark
{
    //副窗体
    public partial class frmSub : Form
    {
        public frmMain mainFrm; //创建一个frmMain类下的mainFrm,用于接收副窗体的内容

        static int count=1; //定义一个静态整形变量count

        //副窗体,用于存储书签
        public frmSub(frmMain frmB) //构造函数,frmMain,frmB为两个参数
        {
            InitializeComponent(); //初始化
            if (frmB != null) //如果frmB不是空值
            {
                mainFrm = frmB; //将副窗体中的内容赋给主窗体
            }
            txtBookMark.Text = "书签" + count;
        }

        //点击取消键
        private void btnCancel_Click(object sender, EventArgs e)
        {
            //关闭窗口
            this.Close();
        }

        //点击确定键
        private void btnOK_Click_1(object sender, EventArgs e)
        {
            if (mainFrm != null || txtBookMark.Name == "")
            {
                mainFrm.createBookmark(txtBookMark.Text);
            }

            count++; //通过确定键的点击次数来计算书签的变化数
            
           
            this.Close();
        }


    }
}

7.选择要素(拉框选择、按多边形选择、按圆选择、按线选择)


7.1 图标

这里先放几个会用到的图标,颜色的图标小伙伴们可以自己百度找一下,其实我有一整套的ArcGIS图标,但是还不知道咋个上传。

e7b67254842e4fa5b340c2ad6862a067.png34e5a595d3cd430da1d499016f457612.png7386f04611514993892bcc2e6ded3a23.png78407c6fdf1846f3a24c3269a10d5767.pngbdf103abfd8d42169a0528022e9690ca.pngd7b5494f265f41c0ae3a659060bf5ba6.png

7.2 测试

选择要素这一部分所包含的功能有通过拉框、圆、多边形和线选择矢量数据,改变所选要素颜色和清除所选要素。

首先点开一份矢量数据。

2c61d71bbb564c56b67a941390480ec9.png

(1)按矩形选择

468e9cb0d1f043288904c30df6825ed1.png

(2)按圆选择

c850b5bfb91d4a7cab05158f1b84ed22.png

(3)按多边形选择

同时更改所选要素颜色为粉色

73d07a6005964623a2833856c8f504c9.png

(4)按线选择

同时更改所选要素颜色为绿色。

a36f5edd066142ba99af5d095fb37c04.png

(5)清除所选要素

每次选择后都有在清除,这里就不展示了。

7.3 代码

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.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;

namespace selectFeature
{
    //选择要素
    //1.按矩形选择
    //2.按圆选择
    //3.按多边形选择
    //4.按线选择

    public partial class selectFeatureForm : Form
    {
        public selectFeatureForm()
        {
            InitializeComponent();
        }

        int flag = 0; //定义一个整型变量flag,用以判断情况

        private void axMapControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e)
        {
            IGeometry pGeometry = null; //因多个条件语句中都要用到,故定义在外
            ISelectionEnvironment pSelect = null; 因多个条件语句中都要用到,故定义在外

            if (flag == 1)
            {
                //按矩形选择
                pGeometry = axMapControl1.TrackRectangle(); //动态绘制矩形
                pSelect = new SelectionEnvironment(); //用于调用DefaultColor,改变选择要素的显示颜色
                axMapControl1.Map.SelectByShape(pGeometry, pSelect, false);  //SelectedByShape方法
            }
            else if (flag == 2)
            {
                //按圆选择
                pGeometry = axMapControl1.TrackCircle(); //动态绘制圆形
                pSelect = new SelectionEnvironment(); //用于调用DefaultColor,改变选择要素的显示颜色
                axMapControl1.Map.SelectByShape(pGeometry, pSelect, false);  //SelectedByShape方法
            }
            else if (flag == 3)
            {
                //按多边形选择
                pGeometry = axMapControl1.TrackPolygon(); //动态绘制多边形
                pSelect = new SelectionEnvironment(); //用于调用DefaultColor,改变选择要素的显示颜色
                axMapControl1.Map.SelectByShape(pGeometry, pSelect, false);  //SelectedByShape方法
            }
            else if (flag == 4)
            {
                //按线选择
                pGeometry = axMapControl1.TrackLine(); //动态绘制线
                pSelect = new SelectionEnvironment(); //用于调用DefaultColor,改变选择要素的显示颜色
                axMapControl1.Map.SelectByShape(pGeometry, pSelect, false);  //SelectedByShape方法
            }
           
            //颜色
            if (flag >= 1 && flag <= 4)
            {
                IActiveView pActive = (IActiveView)(axMapControl1.Map);
                pActive.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null); //部分刷新
                pSelect.DefaultColor = pColor;
            }
            
        }

        IRgbColor pColor; //因两个事件都要用到pColor,故将其定义在事件之外

        private void tsbColor_Click(object sender, EventArgs e)
        {
            //设置颜色
            pColor = new RgbColor(); //实例化一个颜色变量
            ColorDialog pColorDialog = new ColorDialog();

            if (pColorDialog.ShowDialog() == DialogResult.OK)
            {
                pColor.Red = pColorDialog.Color.R;
                pColor.Green = pColorDialog.Color.G;
                pColor.Blue = pColorDialog.Color.B;
            }
        }

        private void selectByRectangle_Click(object sender, EventArgs e)
        {
            //按矩形选择
            flag = 1;
        }

        private void tsbSelecByCircle_Click(object sender, EventArgs e)
        {
            //按圆形选择
            flag = 2;
        }

        private void tbsSelectByPolygon_Click(object sender, EventArgs e)
        {
            //按多边形选择
            flag = 3;
        }

        private void tsbSelectByLine_Click(object sender, EventArgs e)
        {
            //按线选择
            flag = 4;
        }

        private void tsbClear_Click(object sender, EventArgs e)
        {
            //清空所选元素
            axMapControl1.Map.ClearSelection(); //清空
            axMapControl1.ActiveView.Refresh(); //刷新,清空之后刷新视图才能看到元素被清除
        }


    }
}

 


8.属性查询


8.1界面设计

(1)地图显示界面

bf33a3beaee34aba850e8642305f198e.png

(2)属性查询界面

be058afeea654b3a93326544bbfe8844.png

8.2 测试

加载一副矢量地图

5891d8fadfd240778a7ab8c75ca7706a.png

点击查询,选择按属性查询

0e9873e576d04a54938045771a0c71cf.png

弹出如下界面

f9cadf502ec24c0ea0e3413857a484b0.png

查询方法有四种,分别是创建一个新的选择、添加到现有选择中、从已有选择中移除和从已有选择中选择。

9fa8dc59f31a43f6bb63da96edca87c6.png

(1)创建一个新的选择

在查询框中输入Name = ‘雨花街道’,这里最好通过直接选择字段,运算符和字段值来组成查询语句,自己输容易出错,典型的错误是格式不对,这在平常的ArcGIS中进行查询时也是需要注意的。

a829d9995d8d40898166ce4e2aec5b61.png

点击应用

a9d3080ff5154a9c9e182b395b28f80f.png

(2)添加到现有选择中

将查询方法切换到添加到现有选择中,添加龙城街道和大渔街道。该方法可以在已有选择的基础上再添加新的选择,而第一种方法,也就是创建一个新的选择只能选择一个新的要素,再选择会清除原来选择的要素。

dc38c353acd948899ff9bf1808a4813b.png

(3)从已有选择中移除

我们选择移除雨花街道,移除结果如图所示。

d8e7544bcf34413695c7a036cfa4ba4e.png

(4)从已有选择中选择

顾名思义就是在已选择的要素中再进行选择,现在已选择的要素有龙城街道和大渔街道,我们选择大渔街道。

可以看到留下了大渔街道,原来的龙城街道被剔除了。

948a3ad7a4a64bfb96fde93cad8e9c49.png

8.3 代码

显然,属性查询功能也有主副窗口,主窗口即地图,代码中命名为mapShow,副窗口即属性查询,代码中命名为attributeQuery。

(1)主窗口代码

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.Carto;
using ESRI.ArcGIS.Geodatabase;

namespace Query
{
    public partial class Map : Form
    {
        public Map()
        {
            InitializeComponent();
        }

        private void 按属性查询ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //显示按属性查询窗口
            attributeQuery aQ = new attributeQuery();
            //将主窗体图层的属性通过子窗体窗口mainMap输入
            aQ.mainMap = axMapControl1.Map;
            aQ.Show();
        }
    }
}

(2)副窗口代码

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.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;

namespace Query
{
    public partial class attributeQuery : Form
    {
        public attributeQuery()
        {
            InitializeComponent();
        }

        //1.通过属性访问器传值

        //定义一个属性pMap
        private IMap pMap;
        //定义一个接口 mainMap,用于接收图层属性
        public IMap mainMap
        {
            //将主窗体中的值赋予属性pMap
            set { pMap = value; }
        }

        //2.加载图层到combBox中
        private void attributeQuery_Load(object sender, EventArgs e)
        {
            for(int i=0;i<pMap.LayerCount;i++)
            {
                //将pMap获得的图层名称添加到显示图层的组合框queryLayer中
                queryLayer.Items.Add(pMap.get_Layer(i).Name);
            }

            //3.默认显示选中图层名称
            if (queryLayer.Items.Count > 0) //如果图层不为0的话
            {
                queryLayer.SelectedIndex = 0; //显示选中的第一个图层
            }


            //向selectMethod中添加选项
            selectMethod.Items.Add("创建一个新的选择");
            selectMethod.Items.Add("添加到现有选择中");
            selectMethod.Items.Add("从已有选择中移除");
            selectMethod.Items.Add("从已有选择中选择");


            //使SQL运算上方的文字随图层而变化
            labMath.Text = "SELECT * FROM "+queryLayer.Text+" WHERE:";
        }

        //4.选中图层的同时显示相应的字段
        int selectedLayer = 0; //用于判断

        IField pField = null;

        private void queryLayer_SelectedIndexChanged(object sender, EventArgs e)
        {
            //判断哪一个图层被选中
            //int selectedLayer = 0; //用于判断
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                if (queryLayer.Text == pMap.get_Layer(i).Name) //如果查询框显示的图层名称是选中的图层
                {
                    selectedLayer = i;
                }
            }

            //获得相应图层字段
            ITable pTable = pMap.get_Layer(selectedLayer) as ITable; //将所获图层的属性转换为ITable形并将其存于pTable中
            IField pField = null;

            //避免字段累加
            listField.Items.Clear();

            for (int i = 0; i < pTable.Fields.FieldCount; i++)
            {
                pField = pTable.Fields.get_Field(i); //将从源表中获得的字段付给变量pField
                //不显示矢量和栅格形字段
                if (pField.Type != esriFieldType.esriFieldTypeGeometry && pField.Type != esriFieldType.esriFieldTypeRaster)
                {
                    //将字段显示到字段显示框中
                    listField.Items.Add(pField.Name);
                }
            }
        }
        
        private void listField_Click(object sender, EventArgs e)
        {
            //两个接口
            //IFeatureLayer,对应矢量图层
            //IRasterLayer,对应栅格图层

            //强制转换
            //两种方法
            //IFeatureLayer pFeatureLayer = pMap.get_Layer(selectedLayer) as IFeatureLayer;
            //IFeatureLayer pFeatureLayer = (IFeatureLayer)pMap.get_Layer(selectedLayer);
            //将选中图层转换为IFeatureLayer格式,并赋给pFeatureLayer
            IFeatureLayer pFeatureLayer = pMap.get_Layer(selectedLayer) as IFeatureLayer;

            //获得对应矢量图层的字段
            IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;

            //search表示将符合条件的查询出来
            //该代码类似于打开属性表
            IFeatureCursor pFeatureCursor=pFeatureClass.Search(null,false);

            //用于获取唯一值
            IDataStatistics pDataStatistic = new DataStatistics();

            //pFeatureCursor是IFeatureCursor型,要使用pDataStatistic.Cursor,要将其转换为Cursor型
            pDataStatistic.Cursor = (ICursor)pFeatureCursor;

            //用于记录所取字段的顺序
            int recordField = 0;

            //如果选中的是第一个字段
            if (listField.SelectedIndex == 0)
            {
                pDataStatistic.Field = pFeatureClass.Fields.get_Field(listField.SelectedIndex).Name;
                recordField = listField.SelectedIndex;
            }
            else
            {
                pDataStatistic.Field = pFeatureClass.Fields.get_Field(listField.SelectedIndex+1).Name;
                recordField = listField.SelectedIndex + 1;
            }
            System.Collections.IEnumerator pEnumrator = pDataStatistic.UniqueValues;

            //避免重复
            listFieldValue.Items.Clear();

            while (pEnumrator.MoveNext())
            {
                object pObject = pEnumrator.Current;
                string pFieldValue;
                
                if (pFeatureClass.Fields.get_Field(recordField).Type == esriFieldType.esriFieldTypeString)
                {
                    pFieldValue = "'" + pObject.ToString() + "'";
                }
                else
                {
                    pFieldValue = pObject.ToString();
                }
                listFieldValue.Items.Add(pFieldValue);
            }
             
        }

        //构建表达式
        //当双击listField中的字段时,将其显示到进行SQL运算的文本框里
        private void listField_DoubleClick(object sender, EventArgs e)
        {
            //将字段中的内容转换为字符型赋给运算SQL文本框的文本内容
            txtSQL.Text = txtSQL.Text + listField.SelectedItem.ToString();
        }

        //当点击数学运算符时,将其显示到进行SQL运算的文本框里
        private void btnXiangden_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " = ";
        }

        private void btnKuohao_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " <> ";
        }

        private void btnDayu_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " = ";
        }

        private void btnDayuDenyu_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " >= ";
        }

        private void btnXiaoyu_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " < ";
        }

        private void btnXiaoyudenyu_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " <= ";
        }

        private void btn__Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " _ ";
        }

        private void btnPercentage_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " % ";
        }

        private void btnYuankuo_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " () ";
        }

        //当点击逻辑运算符时,将其显示到进行SQL运算的文本框里
        private void btnLike_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " LIKE ";
        }

        private void btnAnd_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " AND ";
        }

        private void btnOr_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " OR ";
        }

        private void btnNot_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " NOT ";
        }

        private void btnIs_Click(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + " IS ";
        }

        //当点击字段值时,将其显示到进行SQL运算的文本框里
        private void listFieldValue_SelectedIndexChanged(object sender, EventArgs e)
        {
            txtSQL.Text = txtSQL.Text + listFieldValue.Text;
        }


        //当点击应用的时候,进行属性查询,将所选择内容高亮显示
        private void btnApplication_Click(object sender, EventArgs e)
        {
            SQL_Query();
        }

        private void SQL_Query()
        {
            //selectedLayer表示选中的图层
            IFeatureLayer pFeatureLayer = pMap.get_Layer(selectedLayer) as IFeatureLayer;
            IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
            IQueryFilter pQueryFilter = new QueryFilter();

            //建立SQL查询框与查询过滤器的联系
            pQueryFilter.WhereClause = txtSQL.Text;
            //esriSelectionResultEnum.esriSelectionResultNew包含and,add,new,substruct,XOR

            //创建一个新的选择
            if (selectMethod.SelectedIndex == 0)
            {
                pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
            }
            //添加到现有选择中
            if (selectMethod.SelectedIndex == 1)
            {
                pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
            }
            //从已有选择中移除
            if (selectMethod.SelectedIndex == 2)
            {
                pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultXOR, false);
            }
            //从已有选择中选择
            if (selectMethod.SelectedIndex == 3)
            {
                pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultAnd, false);
            }

            IActiveView pActiveView = pMap as IActiveView;
            pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, pActiveView.Extent);
        }

        //当点击取消时关闭窗体
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        //当点击清除时清楚内容
        private void btnClear_Click(object sender, EventArgs e)
        {
            txtSQL.Text = "";
        }

        //当点击确定时,进行属性查询功能并关闭窗口
        //由于该功能是在应用的基础上添加一个关闭窗口的功能
        //故将应用中的代码放到外面,写成一个方法,然后分别调用即可
        private void btnOK_Click(object sender, EventArgs e)
        {
            SQL_Query();
            this.Close();
        }
    }
}

9 空间查询


9.1 界面设计

(1)主界面

fa2eca71e2a449e59371bc07dea9d60d.png

(2)空间查询界面

e39f80ca48274291a4f8a1625a3aa349.png

9.2 代码

这部分有点复杂,光目标图层要素的空间选择方法就有九种,我自己的数据也有点问题,就不进行测试了,直接上代码。

(1)主窗口mapForm

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.Geometry;
using ESRI.ArcGIS.Carto;
//空间查询思路
//构建基本的地图显示窗体,也就是主窗体,命名为mapForm
//当点击查询中的空间查询时,弹出空间查询副窗体,命名为spatialQueryForm
//选择方法中默认选择从以下图层中选择要素,将其对应内容使用Items.Add添入,在图层加载时即添加
//目标图层组合框中,采用传值的方式,将主窗体中的图层信息显示到副窗体中
//两种传值方式:其一,使用属性的读写功能;其二,使用函数/方法传值
//此处选用属性的读写功能进行传值
//首先在副窗体中定义一个公共的IMap接口的mainMap,用于接收主窗体中的图层信息
//然后定义一个私有的pMap用于进行副窗体内部的读写
//最后在主窗体中将图层信息传递给副窗体  【注】先传值,再显示副窗体,否则会无法添加图层信息

//由于目标图层有多个,在副窗体中使用for循环将其加入
//源图层的图层信息添加方式也是在for循环中完成
//

namespace Query
{
    public partial class mapForm : Form
    {
        public mapForm()
        {
            InitializeComponent();
        }

        //当点击查询中的空间查询时,弹出空间查询窗口
        private void 属性查询ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //实例化一个空间查询窗体下的对象
            spatialQueryForm spatialForm = new spatialQueryForm();
          
            //传值
            spatialForm.mainMap = axMapControl1.Map;

            //显示该对象
            spatialForm.Show();

            
        }
    }
}

(2)副窗口spatialQueryForm

我记得这部分代码有个地方我好像改过,后面一会儿会放一个我做的以上所有功能的一个集成代码,里面有修改后的代码,总之是进行了功能上的提升的。

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.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.AnalysisTools;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Controls;

namespace Query
{
    public partial class spatialQueryForm : Form
    {
        public spatialQueryForm()
        {
            InitializeComponent();
        }

        //pMap用于副窗体内部接收
        private IMap pMap;
        
        //mainMap用于主副窗体之间的值传递
        public IMap mainMap
        {
            //写入功能
            set 
            {
                pMap = value;
            }

        }

        public void addMethoodAndLayer()
        {
            //添加选择方法
            cmbSelectMethod.Items.Add("从以下图层中选择要素");
            cmbSelectMethod.Items.Add("添加到已选择的要素中");
            cmbSelectMethod.Items.Add("从已选择的要素中移除");
            cmbSelectMethod.Items.Add("从已选择的要素中选择");
            cmbSelectMethod.SelectedIndex = 0;

            //添加空间查询方法
            cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体相交");
            cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体的矩形选框相交");
            cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体的索引项相交(主索引筛选器)");
            cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体接触");
            cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体重叠");
            cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体交叉");
            cmbTargetSelectedMethod.Items.Add("查询几何体在目标几何体中");
            cmbTargetSelectedMethod.Items.Add("查询几何体包含在目标几何体中");
            cmbTargetSelectedMethod.Items.Add("查询几何体IBE(内边界--外部)与目标几何体的关系");
            cmbTargetSelectedMethod.SelectedIndex = 0;

            //添加图层
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                ILayer pLayer = pMap.get_Layer(i);
                //如果图层是矢量图层则对其进行添加
                if (pLayer is IFeatureLayer)
                {
                    //将图层名称添加到目标图层显示框中
                    clbTarget.Items.Add(pMap.get_Layer(i).Name);
                    //默认显示第一个图层名称
                    clbTarget.SelectedIndex = 0;
                    //将图层名称添加到源图层组合框中
                    cmbSourceLayer.Items.Add(pMap.get_Layer(i).Name);
                    //默认显示第一个图层名称
                    cmbSourceLayer.SelectedIndex = 0;
                }
                //问题一:如何判断矢量图层和栅格图层,空间查询只针对矢量图层
            }

        }

        public void unitTrans()
        {
            //将英文转换为中文
            string unitType = null;
            unitType = pMap.MapUnits.ToString();
            if (unitType == esriUnits.esriMeters.ToString())
            {
                lblUnit.Text = "米";
            }
            else if (unitType == esriUnits.esriCentimeters.ToString())
            {
                lblUnit.Text = "厘米";
            }
            else if (unitType == esriUnits.esriDecimalDegrees.ToString())
            {
                lblUnit.Text = "十进制度";
            }
            else if (unitType == esriUnits.esriDecimeters.ToString())
            {
                lblUnit.Text = "分米";
            }
            else if (unitType == esriUnits.esriFeet.ToString())
            {
                lblUnit.Text = "尺";
            }
            else if (unitType == esriUnits.esriInches.ToString())
            {
                lblUnit.Text = "英尺";
            }
            else if (unitType == esriUnits.esriKilometers.ToString())
            {
                lblUnit.Text = "千米";
            }
            else if (unitType == esriUnits.esriMiles.ToString())
            {
                lblUnit.Text = "英里";
            }
            else if (unitType == esriUnits.esriMillimeters.ToString())
            {
                lblUnit.Text = "毫米";
            }
            else if (unitType == esriUnits.esriNauticalMiles.ToString())
            {
                lblUnit.Text = "海里";
            }
            else if (unitType == esriUnits.esriUnknownUnits.ToString())
            {
                lblUnit.Text = "未知单位";
            }
            else if (unitType == esriUnits.esriPoints.ToString())
            {
                lblUnit.Text = "点";
            }
            else if (unitType == esriUnits.esriYards.ToString())
            {
                lblUnit.Text = "码";
            }
            else if (unitType == esriUnits.esriUnitsLast.ToString())
            {
                lblUnit.Text = "无单位";
            }
        }

        private void spatialQueryForm_Load(object sender, EventArgs e)
        {
            addMethoodAndLayer();

            cbSelectedFeature.Enabled = true;
            txtImportBuffer.Enabled = false;
            lblUnit.Enabled = false;
            //将地图单位赋予标签
            lblUnit.Text = pMap.MapUnits.ToString();

            lblFeatureCount.Enabled = false;
            unitTrans();
        }

        private void cbDistance_CheckedChanged(object sender, EventArgs e)
        {
            //如果“应用搜索范围”复选框被选中,则可输入数值
            if (cbDistance.Checked == true)
            {
                txtImportBuffer.Enabled = true;
                lblUnit.Enabled = true;
            }
            if (cbDistance.Checked == false)
            {
                txtImportBuffer.Enabled = false;
                lblUnit.Enabled = false;
            }
                txtImportBuffer.Text = "1";
        }

        private void lblUnit_Click(object sender, EventArgs e)
        {
            MessageBox.Show(lblUnit.Text);
        }

        private void btnApply_Click(object sender, EventArgs e)
        {
            spatialQueryApply();
        }

        public void spatialQueryApply()
        {
            //ISpatialFilter的两个属性:Geometry,spatialRel
            //将源图层的要素合并为一个几何体

            ISpatialFilter pSpatialFilter = new SpatialFilter();
            IFeatureLayer pFeatureLayer = new FeatureLayer();
            

            //for循环得到源图层
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                //如果所得图层名字与框内选择的图层名相同
                if (pMap.get_Layer(i).Name == cmbSourceLayer.SelectedItem.ToString())
                {
                    //将该图层赋予要素图层
                    pFeatureLayer = pMap.get_Layer(i) as IFeatureLayer;
                }
            }
            //当没有缓冲区时
            if (txtImportBuffer.Enabled==false)
            {

                //搜寻所有要素
                IFeatureCursor pFeatureCursor = pFeatureLayer.Search(null, false);
                IFeature pFeature = pFeatureCursor.NextFeature();

                //*建立拓扑关系
                ITopologicalOperator pTopo;
                //存放要素形状
                IGeometry pGeometry = null;
                while (pFeature != null)
                {
                        if (pGeometry != null)
                        {
                            pTopo = (ITopologicalOperator)pGeometry;
                            pGeometry = pTopo.Union(pFeature.Shape);
                        }
                        else
                        {
                            pGeometry = pFeature.Shape;
                        }
                    pFeature = pFeatureCursor.NextFeature();
                    
                }
                    pSpatialFilter.Geometry = pGeometry;
                
            }
            //有缓冲区,当有要素集合时
            if (pFeatureLayer.FeatureClass != null)
            {
                //得到所有要素
                IFeatureCursor pFeatureCursor = pFeatureLayer.FeatureClass.Search(null, false);
                IFeature pFeature = pFeatureCursor.NextFeature();
                IGeometry pGeometry = pFeature.Shape;
                //当要素不为空时
                while (pFeature != null)
                {
                    
                    if (txtImportBuffer.Enabled == true)
                    {
                        ITopologicalOperator pItopo = pGeometry as ITopologicalOperator;
                        IGeometry pBuffer = pItopo.Buffer(Double.Parse(txtImportBuffer.Text));
                        pGeometry = pBuffer; 
                    }
                    pFeature = pFeatureCursor.NextFeature();
                }
                pSpatialFilter.Geometry = pGeometry;
            }
            
            //对目标图层选择列表进行for循环
            for (int i = 0; i < clbTarget.CheckedItems.Count; i++)
            {
                //对地图图层数量进行for循环
                for (int j = 0; j < pMap.LayerCount; j++)
                {
                    //如果所得到的地图图层名称等于目标图层所选图层名称
                    if (pMap.get_Layer(j).Name == clbTarget.CheckedItems[i].ToString())
                    {
                        //将地图图层赋予要素图层
                        pFeatureLayer = pMap.get_Layer(j) as IFeatureLayer;
                    }
                }
            }
            //空间选择方法
            switch (cmbSelectMethod.SelectedIndex)
            {
                case 0:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                    break;
                case 1:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelEnvelopeIntersects;
                    break;
                case 2:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIndexIntersects;
                    break;
                case 3:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelTouches;
                    break;
                case 4:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelOverlaps;
                    break;
                case 5:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
                    break;
                case 6:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
                    break;
                case 7:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
                    break;
                case 8:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelRelation;
                    break;
            }
            //选择方法
            IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
            switch (cmbTargetSelectedMethod.SelectedIndex)
            {
                case 0:
                    pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
                    break;
                case 1:
                    pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
                    break;
                case 2:
                    pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultSubtract, false);
                    break;
                case 3:
                    pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultAnd, false);
                    break;
            }

            //如果源图层被选择
            IFeatureSelection pFeatureS = pFeatureLayer as IFeatureSelection;
            ISelectionSet pSelectionSet = pFeatureS.SelectionSet;
            ISelectionEnvironment pSelectionEnvironment = null;
            lblFeatureCount.Text = "已选要素: " + pSelectionSet.Count + " 个";

            
            IActiveView pActiveView = pMap as IActiveView;
            //刷新
            //pActiveView.Refresh();
            pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, pActiveView.Extent);
        }


        private void btnOK_Click(object sender, EventArgs e)
        {
            spatialQueryApply();
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void cbSelectedFeature_CheckedChanged(object sender, EventArgs e)
        {
            if (cbSelectedFeature.Checked == true)
            {
 
            }
        }
    }
}

10 集成

10.1 界面设计

83250250d00d484faf50c64032e0f5dc.png

这个集成包含了很多窗口,有显示地图的主窗口mapForm,属性查询的窗口attributeQueryForm,属性表窗口attributeTable,书签窗口bookMarkForm,和空间查询窗口spatialQueryForm。因为我后面有做过修改,主要是名称之类的,但写的思路和前面的一样,但是为了避免争议,这里把整个的代码都再放一次。

e777556043214b0fbada4760fcaf2a53.png

10.2 代码

(1)主窗口mapForm

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;

//IWorkspaceFactory
using ESRI.ArcGIS.Geodatabase;
//RasterWorkspaceFactory()
using ESRI.ArcGIS.DataSourcesRaster;
//IRasterLayer
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Display;

namespace gatherLast
{
    //GIS系统集成
    //1.数据加载:矢量数据,栅格数据;
    //2.地图浏览:拉框放大、拉框缩小、平移、全图、逐级放大、逐级缩小、历史视图浏览(撤销、重做)
    //3.点线面的绘制:点、线、圆、多边形、矩形、文字的绘制,能分别设置颜色、样式、大小及面填充方式;
    //4.书签功能:能设置、输入书签名字,通过下拉选择框浏览书签;
    //5.选择要素:拉框选择、按多边形选择、按圆选择、按线选择,并能设置选择颜色;
    //6.打开属性表
    //7.属性查询功能实现:界面设计,实现图层选择,字段选择,字段值唯一值显示功能,构建查询语句并实现查询功能
    public partial class mapForm : Form
    {
        public mapForm()
        {
            InitializeComponent();
        }

        

        //打开矢量数据
        private void btnShpOpen_Click(object sender, EventArgs e)
        {
            //实例化一个对象
            OpenFileDialog openShipFile = new OpenFileDialog();
            //打开窗体名称
            openShipFile.Title = "加载矢量数据";
            //允许选择多项
            openShipFile.Multiselect = true;
            //过滤选择矢量数据
            openShipFile.Filter = "ShapeFile数据|*.shp";

            //定义整型intPosition,用于存放位置
            int intPosition;
            //定义字符型stringFilePath和stringFileName,用于存放文件路径和文件名
            string stringFilePath, stringFileName;

            if (openShipFile.ShowDialog() == DialogResult.OK)
            {
                //定义字符型file表示打开文件中的文件名,用foreach进行访问
                foreach (String file in openShipFile.FileNames)
                {
                    //将\\的最后一个位置赋予intPosition
                    intPosition = file.LastIndexOf("\\");
                    //将intPosition前的路径存入stringFilePath中
                    stringFilePath = file.Substring(0, intPosition);
                    //将intPosition后的文件名存入stringFileName中
                    stringFileName = file.Substring(intPosition + 1);

                    //显示数据
                    axMapControl1.AddShapeFile(stringFilePath, stringFileName);
                    //弹框显示数据路径和名称
                    //MessageBox.Show(stringFilePath, stringFileName);
                }
            }
        }

        //打开栅格数据
        private void btnRasterOpen_Click(object sender, EventArgs e)
        {
            //实例化对象
            OpenFileDialog openRaster = new OpenFileDialog();
            //命名弹窗名称
            openRaster.Title=("加载栅格数据");
            //允许选择多项
            openRaster.Multiselect = true;
            //过滤栅格数据
            openRaster.Filter = "栅格文件jpg|*.jpg|栅格文件tiff|*.tiff|栅格文件img|*.img";

            //定义整型位置intPosition
            int intPosition;
            //定义字符型路径stringFilePath和名字stringFileName
            string stringFilePath, stringFileName;

            if (openRaster.ShowDialog() == DialogResult.OK)
            {
                //foreach访问
                foreach (String file in openRaster.FileNames)
                {
                    //intPosition的1位置在最后一个\\处
                    intPosition = file.LastIndexOf("\\");
                    //路径
                    stringFilePath = file.Substring(0, intPosition);
                    //文件名
                    stringFileName = file.Substring(intPosition + 1);

                    //IWorkSpace是一个容器,存放空间数据与非空间数据
                    //如:FeatureClass、RasterDataset、table等
                    //IWorkSpace有三种类型:FileSystemWorkspace、LocalDatsbaseWorkspace,RemoteDatabaseWorkspace
                    //WorkSpace类不能直接实例化,必须由IWorkSpaceFactory的Create方法创建
                    //WorkspaceFactory:create workspace

                    //IRasterWorkspace Interfece:provides access to members that control a raster workspace
                    //含OpenRasterDataset:Opens a rasterdataset in the workspace given its name

                    //通过IworkSpaceFactory创建工作空间,将其在RasterWorkspaceFactory中实例化
                    IWorkspaceFactory prasterWorspaceFactory = new RasterWorkspaceFactory();
                    //创建一个栅格工作空间,将其在工作空间中的栅格文件在栅格工作空间中打开
                    IRasterWorkspace rasterWorkSpace = prasterWorspaceFactory.OpenFromFile(stringFilePath, 0) as IRasterWorkspace;
                    //将栅格空间中的空间数据打开
                    IRasterDataset pRasterDataset = rasterWorkSpace.OpenRasterDataset(stringFileName);

                    //IRasterLayer:provide access to members that create or modify a raster layer
                    //RasterLayerClass:raster layer source and display options
                    IRasterLayer pRasterLayer = new RasterLayerClass();
                    //在图层中创建栅格数据
                    pRasterLayer.CreateFromDataset(pRasterDataset);
                    //ILayer:provide access to members that work with all layers
                    //将栅格图层转换为图层形式
                    ILayer pLayer = pRasterLayer as ILayer;

                    //显示栅格图层
                    axMapControl1.AddLayer(pLayer);
                }
            }
        }


        //地图浏览

        //用于标识功能状态
        int flag;


        private void btnEnlarge_Click(object sender, EventArgs e)
        {
            //放大
            flag = 1;

            axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomIn;
        }

        private void btnNarrow_Click(object sender, EventArgs e)
        {
            //缩小
            flag = 2;

            axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomOut;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //漫游、平移
            flag = 3;

            axMapControl1.MousePointer = esriControlsMousePointer.esriPointerPan;
        }

        //鼠标点击地图时
        private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            //激活视图
            IActiveView pActiveView = axMapControl1.ActiveView;
            //实例框架
            IEnvelope pEnvelope = new EnvelopeClass();

            switch (flag)
            {
                case 1:
                    //框架为矩形
                    pEnvelope = axMapControl1.TrackRectangle();
                    //视图范围为框架选择范围
                    pActiveView.Extent = pEnvelope;
                    //刷新
                    pActiveView.Refresh();
                    break;

                case 2:
                    //框架为矩形缩小
                    pEnvelope = axMapControl1.TrackRectangle();
                    //两倍缩小
                    pEnvelope.Expand(2, 2, true);
                    //视图范围为框架范围
                    pActiveView.Extent = pEnvelope;
                    //刷新
                    pActiveView.Refresh();
                    break;

                case 3:
                    //漫游
                    axMapControl1.Pan();
                    break;

                default:
                    break;
            }

            //***********************************************************************
            //绘制地图要素
            //这是在 private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)中

            IGeometry pgeometry = null;
            //避免与System中的point()方法混淆
            IPoint point = new ESRI.ArcGIS.Geometry.Point();


            //绘制点要素
            //思路:
            //1.在Map窗口中布设好绘制点的按钮,点大小的标签和输入的textBox
            //  点颜色的标签,和一个pictureBox用于表示点击此处可以改变颜色
            //  点样式的标签,用comBox来列出各类型的点样式
            //  设置默认的颜色,该颜色同样适用于其他类型的绘制
            //  设置默认的点的大小
            //  添加点样式到comBox中
            //  当点击“绘制点”时,相应的标签、大小、样式自动调到点模式下
            //  当点击修改颜色图片时,可以更改颜色
            //  当点击点样式时,可以显示各类点类型
            //  当点击地图区域时可以进行点的绘制

            if (shapeFileFlag == 1 || shapeFileFlag == 0)
            {
                point.X = e.mapX;
                point.Y = e.mapY;

                pgeometry = point as IGeometry;

                //调用drawMapShape方法,以便进行点的绘制
                drawMapShape(pgeometry);
            }

            //绘制线要素
            if (shapeFileFlag == 2)
            {
                pgeometry = axMapControl1.TrackLine();
                drawMapShape(pgeometry);
            }

            //绘制面要素
            //圆
            if (shapeFileFlag == 3)
            {
                pgeometry = axMapControl1.TrackCircle();
                drawMapShape(pgeometry);
            }

            //矩形
            if (shapeFileFlag == 4)
            {
                pgeometry = axMapControl1.TrackRectangle();
                drawMapShape(pgeometry);
            }

            //多边形
            if (shapeFileFlag == 5)
            {
                pgeometry = axMapControl1.TrackPolygon();
                drawMapShape(pgeometry);
            }

            //字体
            if (shapeFileFlag == 6)
            {
                point.X = e.mapX;
                point.Y = e.mapY;
                pgeometry = point as IGeometry;

                drawText(pgeometry);
            }
            //***************************************************************************
            //选择地图要素
            IGeometry bmGeometry = null;
            ISelectionEnvironment bmSelect = null;

            if (selectFeatureFlag == 1)
            {
                //按矩形选择
                bmGeometry = axMapControl1.TrackRectangle();
                //调用颜色
                bmSelect = new SelectionEnvironment();
                axMapControl1.Map.SelectByShape(bmGeometry, bmSelect, false);
            }
            else if (selectFeatureFlag == 2)
            {
                //按圆选择
                bmGeometry = axMapControl1.TrackCircle();
                bmSelect = new SelectionEnvironment();
                axMapControl1.Map.SelectByShape(bmGeometry, bmSelect, false);
            }
            else if (selectFeatureFlag == 3)
            {
                //按多边形选择
                bmGeometry = axMapControl1.TrackPolygon();
                bmSelect = new SelectionEnvironment();
                axMapControl1.Map.SelectByShape(bmGeometry, bmSelect, false);
            }
            else if (selectFeatureFlag == 4)
            {
                //按线选择
                bmGeometry = axMapControl1.TrackLine();
                bmSelect = new SelectionEnvironment();
                axMapControl1.Map.SelectByShape(bmGeometry, bmSelect, false);
            }

            //颜色
            if (selectFeatureFlag >= 1 && selectFeatureFlag <= 4)
            {
                IActiveView bmActive = (IActiveView)(axMapControl1.Map);
                //部分刷新
                bmActive.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
                bmSelect.DefaultColor = bmColor;
            }
        }

        
        //逐级放大
        private void btnEnlargeBystep_Click(object sender, EventArgs e)
        {
            //实例化框架为地图显示范围
            IEnvelope pEnvelop = axMapControl1.Extent;
            //以0.5倍放大
            pEnvelop.Expand(0.5, 0.5, true);
            //显示放大范围
            axMapControl1.Extent = pEnvelop;
            //刷新
            axMapControl1.ActiveView.Refresh();
        }

        //逐级缩小
        private void btnNarrowBystep_Click(object sender, EventArgs e)
        {
            //将地图范围赋予框架
            IEnvelope pEnvelope = axMapControl1.Extent;
            //设置缩小倍数
            pEnvelope.Expand(2, 2, true);
            //将缩小后的视图赋予地图
            axMapControl1.Extent = pEnvelope;
            //刷新
            axMapControl1.ActiveView.Refresh();
        }

        //全图显示
        private void btnAll_Click(object sender, EventArgs e)
        {
            axMapControl1.Extent = axMapControl1.FullExtent;
        }

        //用于连接各视图的范围堆
        IExtentStack pExtentStack;

        //上一级视图
        private void btnBefore_Click(object sender, EventArgs e)
        {
            //判断当前视图是否可以撤回,第一个视图无法撤回
            pExtentStack = axMapControl1.ActiveView.ExtentStack;
            if (pExtentStack.CanUndo())
            {
                //撤回到上一级视图
                pExtentStack.Undo();
                //前一视图按钮可用
                btnBefore.Enabled = true;

                if (!pExtentStack.CanUndo())
                {
                    //前一视图不可返回
                    btnBefore.Enabled = false;
                }
            }
            //刷新显示
            axMapControl1.ActiveView.Refresh();
        }

        //下一级视图
        private void btnNext_Click(object sender, EventArgs e)
        {
            pExtentStack = axMapControl1.ActiveView.ExtentStack;

            //如果可以下一级
            if (pExtentStack.CanRedo())
            {
                //下一级
                pExtentStack.Redo();
                //下一级按钮可用
                btnNext.Enabled = true;
                //如果不可下一级视图
                if (!pExtentStack.CanRedo())
                {
                    btnNext.Enabled = false;
                }
            }
            axMapControl1.ActiveView.Refresh();
        }

        //*******************************************************************
        //绘制矢量要素
        int shapeFileFlag = 0;

        //调用颜色
        //内部颜色
        IRgbColor pColor;
        //边框颜色
        IRgbColor rColor;

        //点击图片改变内部颜色
        private void pictureBox1_Click_1(object sender, EventArgs e)
        {
            ColorDialog pColorDialog = new ColorDialog();
            if (pColorDialog.ShowDialog() == DialogResult.OK)
            {
                pColor = new RgbColor();
                pColor.Red = pColorDialog.Color.R;
                pColor.Green = pColorDialog.Color.G;
                pColor.Blue = pColorDialog.Color.B;
            }
        }

        //点击图片改变边框颜色
        private void pBlayout_Click(object sender, EventArgs e)
        {
            ColorDialog rColrDialog = new ColorDialog();
            if (rColrDialog.ShowDialog() == DialogResult.OK)
            {
                rColor = new RgbColor();
                rColor.Red = rColrDialog.Color.R;
                rColor.Green = rColrDialog.Color.G;
                rColor.Blue = rColrDialog.Color.B;
            }
        }

        //设置颜色
        private void setColor()
        {
            //当没有设置颜色时
            //默认颜色为黑色
            if (pColor == null)
            {
                pColor = new RgbColor();
                pColor.Red = 0;
                pColor.Green = 0;
                pColor.Blue = 0;
            }

            if (rColor == null)
            {
                rColor = new RgbColor();
                rColor.Red = 0;
                rColor.Green = 0;
                rColor.Blue = 0;
            }
        }

        //对点的绘制
        //定义一个函数用于绘制点
        private void setPoint()
        {
            //设置相关标签名称
            lblSize.Text = "点的大小:";
            lblColor.Text = "点的颜色:";
            lblStyle.Text = "点的样式:";

            //点的默认大小
            txtSize.Text = "3";
            txtSize.Visible = true;

            //下拉框内容的清除刷新
            cmbStyle.Items.Clear();

            //点的样式
            cmbStyle.Items.Add("正方形");
            cmbStyle.Items.Add("圆形");
            cmbStyle.Items.Add("十字形");
            cmbStyle.Items.Add("X形");
            cmbStyle.Items.Add("棱形");

            //默认选择第一个点样式
            cmbStyle.SelectedIndex = 0;
        }

        //当点击“绘制点”时,对应的大小和样式标签进行变化
        private void btnPoint_Click(object sender, EventArgs e)
        {
            shapeFileFlag = 1;
            setPoint();
        }

        //当一打开程序时,便默认加载点的相关样式大小标签
        private void mapForm_Load(object sender, EventArgs e)
        {
            setPoint();
        }

        //对线的绘制
        //当点击绘制线时
        private void btnLine_Click(object sender, EventArgs e)
        {
            shapeFileFlag = 2;

            //修改线宽度标签
            lblSize.Text = "线的宽度";
            //线的样式
            lblStyle.Text = "线的样式";
            //线宽度输入框可见
            lblColor.Text = "线的颜色";
            txtSize.Visible = true;
            //线宽度默认值为1
            txtSize.Text = "1";

            //避免点样式重复出现
            cmbStyle.Items.Clear();
            //添加线类型
            cmbStyle.Items.Add("实线");
            cmbStyle.Items.Add("短横线");
            cmbStyle.Items.Add("点线");
            cmbStyle.Items.Add("短横线和点线");
            cmbStyle.Items.Add("短横线两点线");
            cmbStyle.Items.Add("不可见的线");
            cmbStyle.Items.Add("矩形边界线");
            //默认线类型为实线
            cmbStyle.SelectedIndex = 0;
        }

        //对面的绘制,含圆、矩形、多边形
        //单独定义一个函数
        private void setSurface()
        {
            //面边框粗细
            lblSize.Text = "边框粗细:";
            //默认显示粗细
            txtSize.Text = "1";
            //大小文本框可见
            txtSize.Visible = true;
            //类型标签可见
            lblStyle.Visible = true;
            //边框颜色标签可见
            lblColorLayout.Visible = true;
            //边框图片颜色可见
            pBlayout.Visible = true;
            //填充颜色
            lblColor.Text = "填充颜色";
            //填充样式
            lblStyle.Text = "填充样式";

            //清除之前的cmb下拉框中的内容
            cmbStyle.Items.Clear();
            //添加类型
            cmbStyle.Items.Add("实心填充");
            cmbStyle.Items.Add("不填充");
            cmbStyle.Items.Add("空心填充");
            cmbStyle.Items.Add("水平线填充");
            cmbStyle.Items.Add("垂直线填充");
            cmbStyle.Items.Add("45度下斜线填充");
            cmbStyle.Items.Add("45度上斜线填充");
            cmbStyle.Items.Add("水平十字线填充");
            cmbStyle.Items.Add("45度交叉线填充");
            //默认第一个样式
            cmbStyle.SelectedIndex = 0;
        }

        //面-圆
        private void btnFace_Click(object sender, EventArgs e)
        {
            shapeFileFlag = 3;
            setSurface();
        }

        //面-矩形
        private void btnRectangle_Click(object sender, EventArgs e)
        {
            shapeFileFlag = 4;
            setSurface();
        }

        //面-多边形
        private void btnMul_Click(object sender, EventArgs e)
        {
            shapeFileFlag = 5;
            setSurface();
        }

        //对文字的绘制
        private void drawText(IGeometry txtGeometry)
        {
            //存放符号
            object symbol;
            //存放输入符号大小
            double pWith;
            //存放输出符号大小
            double pDouble;
            //判断输入大小是否为数字
            bool isNumber;
            //调用颜色
            setColor();
            
            //实例化一个txtSymbol
            ITextSymbol txtSymbol = new TextSymbol();
            //实例化一个pFont
            stdole.IFontDisp pFont = new stdole.StdFontClass() as stdole.IFontDisp;
            //字符串转换为整型
            isNumber = System.Double.TryParse
                (txtSize.Text, System.Globalization.NumberStyles.Integer, null, out pDouble);

            //如果输入的不是数字
            if (isNumber == false)
            {
                MessageBox.Show("您输入的不是一个数字,请输入一个数字!", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
            }
            //如果是一个数字
            else
            {
                //将输入的字符型数字转换为双精度
                pWith = Convert.ToDouble(txtSize.Text);
                //将字符大小赋予字体大小
                pFont.Size = (decimal)pWith;
            }
            //字体颜色
            txtSymbol.Color = pColor;
            //字体类型
            txtSymbol.Font = pFont;
            symbol = txtSymbol;
            axMapControl1.DrawText(txtGeometry, txtSymbol.Text, ref symbol);
        }

        private void btnText_Click(object sender, EventArgs e)
        {
            shapeFileFlag = 6;
            lblSize.Text = "字体大小";
            txtSize.Text = "16";
            lblColor.Text = "字体颜色";
            lblStyle.Visible = false;
            cmbStyle.Visible = false;
        }

        private void drawMapShape(IGeometry drawGeometry)
        {
            //定义符号初始值为空
            //symbol用于存放各种符号
            object symbol = null;
            //调用默认符号颜色
            setColor();
            //存放符号大小
            double pWith;
            //输出对应大小的符号
            double pOutput;
            //判断是否为数字
            bool isNumber;

            //将输入的文本数字进行转换
            isNumber = System.Double.TryParse
                (txtSize.Text, System.Globalization.NumberStyles.Integer, null, out pOutput);
            //如果输入大小不是数字,进行提示
            if (isNumber == false)
            {
                MessageBox.Show
                    ("这不是一个数字,请输入一个数字!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            //如果输入是一个数字
            else
            {
                //将文本型的字符大小转换为双精度
                pWith = Convert.ToDouble(txtSize.Text);
                //如果geometry的一个类型是esri中的点
                if (drawGeometry.GeometryType == esriGeometryType.esriGeometryPoint)
                {
                    //存放点符号类型
                    ISimpleMarkerSymbol pSimplePoint = new SimpleMarkerSymbol();
                    //点符号默认颜色为黑色
                    pSimplePoint.Color = pColor;
                    //将输入转换后的符号大小赋予点符号
                    pSimplePoint.Size = pWith;
                    //设置对应的符号类型
                    if (cmbStyle.SelectedItem.ToString() == "正方形")
                    {
                        pSimplePoint.Style = esriSimpleMarkerStyle.esriSMSSquare;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "圆")
                    {
                        pSimplePoint.Style = esriSimpleMarkerStyle.esriSMSCircle;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "十字形")
                    {
                        pSimplePoint.Style = esriSimpleMarkerStyle.esriSMSCross;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "X形")
                    {
                        pSimplePoint.Style = esriSimpleMarkerStyle.esriSMSX;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "棱形")
                    {
                        pSimplePoint.Style = esriSimpleMarkerStyle.esriSMSDiamond;
                    }
                    symbol = pSimplePoint;
                }
                else if (drawGeometry.GeometryType == esriGeometryType.esriGeometryLine)
                {
                    //存放线符号类型
                    ISimpleLineSymbol pSimpleLine = new SimpleLineSymbol();
                    //存放线宽度
                    pSimpleLine.Width = pWith;
                    //设置线默认颜色为黑色
                    pSimpleLine.Color = pColor;

                    if (cmbStyle.SelectedItem.ToString() == "实线")
                    {
                        pSimpleLine.Style = esriSimpleLineStyle.esriSLSSolid;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "短横线")
                    {
                        pSimpleLine.Style = esriSimpleLineStyle.esriSLSDash;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "点线")
                    {
                        pSimpleLine.Style = esriSimpleLineStyle.esriSLSDashDot;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "短横线和点线")
                    {
                        pSimpleLine.Style = esriSimpleLineStyle.esriSLSDashDot;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "不可见的线")
                    {
                        pSimpleLine.Style = esriSimpleLineStyle.esriSLSNull;
                    }
                    else if (cmbStyle.SelectedItem.ToString() == "矩形边界线")
                    {
                        pSimpleLine.Style = esriSimpleLineStyle.esriSLSInsideFrame;
                    }
                    symbol = pSimpleLine;
                }
                else
                {
                    //存放面符号类型
                    ISimpleFillSymbol pSimpleSurface = new SimpleFillSymbol();
                    //面颜色
                    pSimpleSurface.Color = pColor;
                    //存放面边框
                    ILineSymbol pSurfaceLine=new SimpleLineSymbol();
                    //面边框宽度
                    pSurfaceLine.Width = pWith;
                    //面边框颜色
                    pSurfaceLine.Color = rColor;
                    //将面边框赋给SimpleFillSymbol下的OutLine
                    pSimpleSurface.Outline = pSurfaceLine;

                    if (cmbStyle.SelectedItem.ToString() == "实心填充")
                    {
                        pSimpleSurface.Style = esriSimpleFillStyle.esriSFSSolid;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "不填充")
                    {
                        pSimpleSurface.Style = esriSimpleFillStyle.esriSFSNull;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "空心填充")
                    {
                        pSimpleSurface.Style = esriSimpleFillStyle.esriSFSHollow;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "水平线填充")
                    {
                        pSimpleSurface.Style = esriSimpleFillStyle.esriSFSHorizontal;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "垂直线填充")
                    {
                        pSimpleSurface.Style = esriSimpleFillStyle.esriSFSVertical;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "45度下斜线填充")
                    {
                        pSimpleSurface.Style = esriSimpleFillStyle.esriSFSForwardDiagonal;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "45度上斜线填充")
                    {
                        pSimpleSurface.Style = esriSimpleFillStyle.esriSFSBackwardDiagonal;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "水平十字线填充")
                    {
                        pSimpleSurface.Style = esriSimpleFillStyle.esriSFSCross;
                    }
                    if (cmbStyle.SelectedItem.ToString() == "45度交叉线填充")
                    {
                        pSimpleSurface.Style = esriSimpleFillStyle.esriSFSDiagonalCross;
                    }
                    symbol = pSimpleSurface;
                }
                axMapControl1.DrawShape(drawGeometry, ref symbol);
            }

        }

        //在地图上移动鼠标
        private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            if (shapeFileFlag >= 1 && shapeFileFlag <= 6)
            {
                axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
            }
        }

        //*******************************************************************************
        //添加书签
        private void 添加书签ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //传参
            bookMarkForm bookMark = new bookMarkForm(this);
            //显示书签窗体
            bookMark.Show();
        }

        //定义一个函数用于创建书签
        public void createBookMark(string BMName)
        {
            IAOIBookmark aoiBM = new AOIBookmarkClass();

            if (aoiBM != null)
            {
                //将所需标签范围赋给aoiBM中的位置
                aoiBM.Location = axMapControl1.ActiveView.Extent;
                //将书签名称赋予aoiBM中的name
                aoiBM.Name = BMName;
            }

            //获得书签
            IMapBookmarks bookMarks = axMapControl1.Map as IMapBookmarks;

            //如果有书签
            if (bookMarks != null)
            {
                //将aoiBM添加到书签
                bookMarks.AddBookmark(aoiBM);
            }

            //在管理书签中添加书签名
            tscHeldMark.Items.Add(aoiBM.Name);
        }

        //选中已有标签,显示标签的范围
        private void tscHeldMark_SelectedIndexChanged(object sender, EventArgs e)
        {
            IMapBookmarks bookMarks = axMapControl1.Map as IMapBookmarks;
            IEnumSpatialBookmark enumSpatialBookMark = bookMarks.Bookmarks;

            //重置标签顺序
            enumSpatialBookMark.Reset();

            //返回下一标签
            ISpatialBookmark spatialBookMark = enumSpatialBookMark.Next();

            while (spatialBookMark != null)
            {
                if (tscHeldMark.SelectedItem.ToString() == spatialBookMark.Name)
                {
                    //显示标签范围
                    spatialBookMark.ZoomTo((IMap)axMapControl1.ActiveView);
                    //刷新窗口
                    axMapControl1.ActiveView.Refresh();
                    break;
                }
                spatialBookMark = enumSpatialBookMark.Next();
            }
        }

        //*****************************************************************************
        //选择要素:按矩形选择;按圆选择;按多边形选择;按线选择

        //判断
        int selectFeatureFlag = 0;

        private void tsbRectabgle_Click(object sender, EventArgs e)
        {
            //按矩形选择
            selectFeatureFlag = 1;
        }

        private void tsbCircle_Click(object sender, EventArgs e)
        {
            //按圆形选择
            selectFeatureFlag = 2;
        }

        private void tsbPolygon_Click(object sender, EventArgs e)
        {
            //按多边形选择
            selectFeatureFlag = 3;
        }

        private void tsbLine_Click(object sender, EventArgs e)
        {
            //按线选择
            selectFeatureFlag = 4;
        }

        private void tsbClear_Click(object sender, EventArgs e)
        {
            //清除所选要素
            axMapControl1.Map.ClearSelection();
            //刷新
            axMapControl1.ActiveView.Refresh();
        }

        IRgbColor bmColor;
        private void tsbColor_Click(object sender, EventArgs e)
        {
            //设置颜色
            bmColor = new RgbColor();
            ColorDialog bmColorDialog = new ColorDialog();
            if (bmColorDialog.ShowDialog() == DialogResult.OK)
            {
                bmColor.Red = bmColorDialog.Color.R;
                bmColor.Green = bmColorDialog.Color.G;
                bmColor.Blue = bmColorDialog.Color.B;
            }
        }

        //****************************************
        //打开属性表

        ILayer aTLayer = null;

        private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
        {
            //当点击鼠标右键
            if (e.button == 2)
            {
                //MessageBox.Show("yeach!");

                esriTOCControlItem aTItem = esriTOCControlItem.esriTOCControlItemNone;
                IBasicMap aTBasicMap = null;
                object unk = null, data = null;

                axTOCControl1.HitTest(e.x, e.y, ref aTItem, ref aTBasicMap, ref aTLayer, ref unk, ref data);

                //如果点击的是图层
                if (aTItem == esriTOCControlItem.esriTOCControlItemLayer)
                {
                    //将屏幕上的点转换到坐标上
                    System.Drawing.Point p = new System.Drawing.Point();
                    p.X = e.x;
                    p.Y = e.y;

                    //显示菜单
                    contextMenuStrip1.Show(axTOCControl1, p);
                }
            }
        }

        private void 打开属性表ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            attributeTable aTShow = new attributeTable();
            aTShow.createAT(aTLayer);
            aTShow.Show();
        }

        //********************************************************************

        //属性查询
        private void 属性查询ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            attributeQueryForm aQshow = new attributeQueryForm();
            aQshow.mainMap = axMapControl1.Map;
            aQshow.Show();
        }

        //****************************************************************
        private void 空间查询ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            spatialQueryForm spQF = new spatialQueryForm();
            spQF.mainMap = axMapControl1.Map;
            spQF.Show();
        }
        
        //空间查询路线
        //1.设置空间查询界面
        //2.添加选择方法
        //3.添加空间选择方法
        //4.添加目标图层
        //5.添加源图层
        //6.当勾选应用搜索距离时listbox和lable可用
        //7.显示地图单位,并进行中英文转换

        //8.当点击取消按钮,关闭窗口
        //9.当点击确定按钮,进行空间查询,并关闭窗口
        //10.当点击应用按钮,进行空间查询,不关闭窗口

        //两个问题:(1).如何在已选择要素中进行要素查询;(2).如何在缓冲区中进行查询(已解决)

               
        
    }
}

(2)属性查询的窗口attributeQueryForm

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.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;

namespace gatherLast
{
    public partial class attributeQueryForm : Form
    {
        private IMap pMap;
        public IMap mainMap
        {
            set { pMap = value; }
        }
        public attributeQueryForm()
        {
            InitializeComponent();
        }

        //加载图层名称
        private void attributeQueryForm_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                cmbQueryLayer.Items.Add(pMap.get_Layer(i).Name);
            }
            //默认显示第一个图层名称
            if (cmbQueryLayer.Items.Count > 0)
            {
                cmbQueryLayer.SelectedIndex = 0;
            }

            //添加查询方法
            cmbQueryMethod.Items.Add("创建一个新的选择");
            cmbQueryMethod.Items.Add("添加到现有选择中");
            cmbQueryMethod.Items.Add("从已有选择中移除");
            cmbQueryMethod.Items.Add("从已有选择中选择");
            //默认选择第一个方法
            cmbQueryMethod.SelectedIndex = 0;

            //运算框上方文字变化
            lblSQL.Text = "SELECT * FROM " + cmbQueryLayer.Text + " WHERES:";
        }
        
            //选中图层显示字段
            int selectedLayer = 0;
            IField queryField = null;

            private void cmbQueryLayer_SelectedIndexChanged(object sender, EventArgs e)
            {
                //判断选中图层
                for (int i = 0; i < pMap.LayerCount; i++)
                {
                    if (cmbQueryLayer.Text == pMap.get_Layer(i).Name)
                        selectedLayer = i;
                }
                //获取选中图层字段
                ITable pTabel = pMap.get_Layer(selectedLayer) as ITable;
                IField pField = null;

                //避免累加
                listField.Items.Clear();

                for (int i = 0; i < pTabel.Fields.FieldCount; i++)
                {
                    pField = pTabel.Fields.get_Field(i);
                    //不显示矢量和栅格型字段
                    if (pField.Type != esriFieldType.esriFieldTypeGeometry && pField.Type != esriFieldType.esriFieldTypeRaster)
                        listField.Items.Add(pField.Name);
                }
            }

            private void listField_Click(object sender, EventArgs e)
            {
                IFeatureLayer pFeatryeLayer = pMap.get_Layer(selectedLayer) as IFeatureLayer;

                //获取字段
                IFeatureClass pFeatureClass = pFeatryeLayer.FeatureClass;
                //查询符合条件的字段值
                IFeatureCursor pFeatureCursor = pFeatureClass.Search(null, false);
                //获取唯一值
                IDataStatistics pDataStatistic = new DataStatistics();
                pDataStatistic.Cursor = (ICursor)pFeatureCursor;

                //记录所取字段顺序
                int recordField = 0;
                //如果选中第一个字段
                if (listField.SelectedIndex == 0)
                {
                    pDataStatistic.Field = pFeatureClass.Fields.get_Field(listField.SelectedIndex).Name;
                    recordField = listField.SelectedIndex;
                }
                else
                {
                    pDataStatistic.Field = pFeatureClass.Fields.get_Field(listField.SelectedIndex + 1).Name;
                    recordField = listField.SelectedIndex + 1;
                }
                System.Collections.IEnumerator pEnumerator = pDataStatistic.UniqueValues;

                listFieldValue.Items.Clear();

                while (pEnumerator.MoveNext())
                {
                    object pO = pEnumerator.Current;
                    string pFieldValue;

                    if (pFeatureClass.Fields.get_Field(recordField).Type == esriFieldType.esriFieldTypeString)
                        pFieldValue = "'" + pO.ToString() + "'";
                    else
                        pFieldValue = pO.ToString();
                    listFieldValue.Items.Add(pFieldValue);
                }
            }

            //显示表达式符号表达式
            private void listField_DoubleClick(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + listField.SelectedItem.ToString();
            }

            private void btnDengyu_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "=";
            }

            private void btnDX_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "<>";
            }

            private void btnDayu_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + ">";
            }

            private void btnDayuDengyu_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + ">=";
            }

            private void btnXiaoyu_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "<";
            }

            private void btnXioayuDengyu_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "<=";
            }

            private void btnXiahuaxian_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "_";
            }

            private void btnPercentage_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "%";
            }

            private void btnKuohao_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "%";
            }

            private void btnLike_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "LIKE";
            }

            private void btnAnd_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "AND";
            }

            private void btnOr_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "OR";
            }

            private void btnNot_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "NOT";
            }

            private void btnIs_Click(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + "IS";
            }

            private void listFieldValue_SelectedIndexChanged(object sender, EventArgs e)
            {
                txtSQL.Text = txtSQL.Text + listFieldValue.Text;
            }
        //构建表达式
            private void sqlQuery()
            {
                IFeatureLayer pFeatureLayer = pMap.get_Layer(selectedLayer) as IFeatureLayer;
                IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
                IQueryFilter pQueryFilter = new QueryFilter();

                //建立查询框与过滤器的关系
                pQueryFilter.WhereClause = txtSQL.Text;

                //属性选择方法
                //创建一个新的选择
                if (cmbQueryMethod.SelectedIndex == 0)
                {
                    pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
                }
                //添加到已有选择中
                if (cmbQueryMethod.SelectedIndex == 1)
                {
                    pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
                }
                //从已有选择中移除
                if (cmbQueryMethod.SelectedIndex == 2)
                {
                    pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultXOR,false);
                }
                //从已有选择中选择
                if (cmbQueryMethod.SelectedIndex == 3)
                {
                    pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultAnd, false);
                }

                IActiveView pActiveView = pMap as IActiveView;
                //局部刷新
                pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphicSelection, null, pActiveView.Extent);
                pActiveView.Refresh();
            }

        //当点击“确定”时,应用且关闭
            private void btnOK_Click(object sender, EventArgs e)
            {
                sqlQuery();
                this.Close();
            }

            private void btnApply_Click(object sender, EventArgs e)
            {
                sqlQuery();
            }

            private void btnClear_Click(object sender, EventArgs e)
            {
                txtSQL.Text = "";
            }

            private void btnCancel_Click(object sender, EventArgs e)
            {
                this.Close();
            }

    }
}

(3)属性表窗口attributeTable

做的有点粗糙,大概是这个样子。

9e40b995785148d0a3188f25a8aa985b.png

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.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;

using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;

namespace gatherLast
{
    public partial class attributeTable : Form
    {
        public attributeTable()
        {
            InitializeComponent();
        }

        //构造函数
        public void createAT(ILayer aTLayer)
        {
            //MessageBox.Show(aTLayer.Name);

            //创建图层虚拟表
            DataTable pDataTable = new DataTable(aTLayer.Name);
            //将图层中的表进行转移
            ITable pTable = aTLayer as ITable;
            //属性字段
            IField pField = null;

            //创建表中数据列
            DataColumn pDataColumn;

            //使用for将原表中的字段分别赋予新表
            for (int i = 0; i < pTable.Fields.FieldCount; i++)
            {
                pField = pTable.Fields.get_Field(i);
                //MessageBox.Show(pField.Name);

                pDataColumn = new DataColumn(pField.Name);
                pDataColumn.Caption = pField.Name;
                pDataTable.Columns.Add(pDataColumn);
            }

            
            //显示新表中的内容
            ICursor pCur = pTable.Search(null, false);
            //行
            DataRow pDataRow = null;
            //获取行
            IRow pRow = pCur.NextRow();

            while (pRow != null)
            {
                //将虚拟表中的行赋给行
                pDataRow = pDataTable.NewRow();
                for (int i=0; i < pTable.Fields.FieldCount; i++)
                {
                    pDataRow[i] = pRow.get_Value(i);
                }
                pDataTable.Rows.Add(pDataRow);
                pRow = pCur.NextRow();
            }

            //清空
            pRow = null;
            pField = null;

            //接受数据源
            dataGridView1.DataSource = pDataTable;

            transShape(aTLayer);

            //显示数据
            this.Text = "属性表 [" + aTLayer.Name + "] 记录数: " + pDataTable.Rows.Count;
        }

        //类型转换
        public static string transShape(ILayer tranLayer)
        {
            object tLayer = null;
            IFeatureLayer pFeature = tranLayer as IFeatureLayer;

            switch (pFeature.FeatureClass.ShapeType)
            {
                case esriGeometryType.esriGeometryPoint:
                    return "点";
                case esriGeometryType.esriGeometryLine:
                    return "线";
                case esriGeometryType.esriGeometryPolygon:
                    return "面";
                default:
                    return " ";
            }
        }

        private void attributeTable_Load(object sender, EventArgs e)
        {

        }
    }
}

(4)书签窗口bookMarkForm

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;

namespace gatherLast
{
    public partial class bookMarkForm : Form
    {
        //传参
        public mapForm mainForm;
        //定义静态变量count
        static int count = 1;

        public bookMarkForm(mapForm frmA)
        {
            InitializeComponent();
            //如果frmA不是空值
            if (frmA != null)
            {
                //将副窗体中的内容赋给主窗体,也就是将书签标志地图赋给主
                mainForm = frmA;
            }
            //默认显示
            txtBM.Text = "书签" + count;
        }

        //点击确定键
        private void btnOK_Click(object sender, EventArgs e)
        {
            if (mainForm != null||txtBM.Name=="")
            {
                mainForm.createBookMark(txtBM.Text);
            }

            //通过确定键的次数计算书签数
            count++;
            //关闭窗口
            this.Close();
        }

        //点击取消键
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

(5)空间查询窗口spatialQueryForm

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.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;

namespace gatherLast
{
    public partial class spatialQueryForm : Form
    {
        
        //用于副窗体内部传参
        private IMap pMap;
        //用于主副窗体传参
        public IMap mainMap
        {
            set { pMap = value; }
        }

        public spatialQueryForm()
        {
            InitializeComponent();
        }

        private void cbDistance_CheckedChanged(object sender, EventArgs e)
        {
            if (cbDistance.Checked == true)
            {
                txtBuffer.Enabled = true;
                lblUnit.Enabled = true;
            }
            if (cbDistance.Checked == false)
            {
                txtBuffer.Enabled = false;
                lblUnit.Enabled = false;
            }
            
        }

        private void spatialQueryForm_Load(object sender, EventArgs e)
        {
            //添加选择方法
            cmbSelectedMethod.Items.Add("从以下图层中选择要素");
            cmbSelectedMethod.Items.Add("添加到已选择的要素中");
            cmbSelectedMethod.Items.Add("从已选择的要素中移除");
            cmbSelectedMethod.Items.Add("从已选择的要素中选择");
            //默认选择第一个选择方法
            cmbSelectedMethod.SelectedIndex = 0;

            //添加空间查询方法
            cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体相交");
            cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体矩形选框相交");
            cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体索引项相交");
            cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体接触");
            cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体重叠");
            cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体交叉");
            cmbSpatialSelectMethod.Items.Add("查询几何体位于目标几何体中");
            cmbSpatialSelectMethod.Items.Add("查询几何体含于目标几何体中");
            cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体的IBE(内边界-外部)关系");
            //默认
            cmbSpatialSelectMethod.SelectedIndex = 0;

            //添加目标图层和源图层,需要将空间查询窗体与地图窗体进行联系,传值
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                //判断是否为矢量图层
                ILayer pLayer = pMap.get_Layer(i);
                if (pLayer is IFeatureLayer)
                {
                    clbTargetLayer.Items.Add(pMap.get_Layer(i).Name);
                    clbTargetLayer.SelectedIndex = 0;

                    cmbSourceLayer.Items.Add(pMap.get_Layer(i).Name);
                    cmbSourceLayer.SelectedIndex = 0;
                }
            }

            txtBuffer.Text = "1.00";
            lblFeatureCount.Text = "已选要素: 0 个";

            //得到地图单位
            lblUnit.Text = pMap.MapUnits.ToString();
            //中英文转换
            string unitType = null;
            unitType = pMap.MapUnits.ToString();

            if (unitType == esriUnits.esriUnknownUnits.ToString())
            {
                lblUnit.Text = "未知单位";
            }
            else if (unitType == esriUnits.esriMeters.ToString())
            {
                lblUnit.Text = "米";
            }
            else if (unitType == esriUnits.esriDecimalDegrees.ToString())
            {
                lblUnit.Text = "十进度制";
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            spatialQueryWay();
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnApply_Click(object sender, EventArgs e)
        {
            spatialQueryWay();
        }

        //查询方法,便于在应用和确定中调用
        public void spatialQueryWay()
        {
            //调用ISpatialFilter下的Geometry和SpatialRel
            ISpatialFilter pSpatialFilter = new SpatialFilter();
            //要素图层
            IFeatureLayer pFeatureLayer = new FeatureLayer();

            //for循环得到源图层
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                if (pMap.get_Layer(i).Name == cmbSourceLayer.SelectedItem.ToString())
                {
                    pFeatureLayer = pMap.get_Layer(i) as IFeatureLayer;
                }
            }

            if (pFeatureLayer.FeatureClass!=null)
            {
                //当没有缓冲区时
                if (txtBuffer.Enabled==true)
                {
                    //游标,搜寻图层所有要素
                    //(null,false)表示搜寻看所有要素
                    IFeatureCursor pFeatureCursor = pFeatureLayer.Search(null, false);
                    //NextFeature获得所有要素
                    IFeature pFeature = pFeatureCursor.NextFeature();

                    //建立拓扑关系
                    ITopologicalOperator pTO;
                    IGeometry pGeometry = null;

                    //目的:将所有的要素集合在一个几何上,以便于调用ISpatialFilter中的Geometry

                    //当要素不为空时
                    //while循环,满足条件进入循环,直到条件不满足才跳出循环

                    while (pFeature != null)
                    {
                        //几何不为空时
                        if (pGeometry != null)
                        {
                            //为几何建立拓扑关系
                            pTO = pGeometry as ITopologicalOperator;
                            pGeometry = pTO.Union(pFeature.Shape);
                        }
                        //几何为空时,也就是图层只有一个几何时
                        else
                        {
                            //只有一个几何,无需建立拓扑关系
                            pGeometry = pFeature.Shape;
                        }
                        //避免死循环
                        pFeature = pFeatureCursor.NextFeature();
                    }
                    //得到具有拓扑关系的几何集合
                    pSpatialFilter.Geometry = pGeometry;
                }
                //当有缓冲区时
                if (txtBuffer.Enabled == true)
                {
                    if (pFeatureLayer.FeatureClass != null)
                    {
                        //游标,搜寻图层所有要素
                        //(null,false)表示搜寻看所有要素
                        IFeatureCursor pFeatureCursor = pFeatureLayer.FeatureClass.Search(null, false);
                        //NextFeature获得所有要素
                        IFeature pFeature = pFeatureCursor.NextFeature();
                        IGeometry pGeometry = pFeature.Shape;



                        //目的:将所有的要素集合在一个几何上,以便于调用ISpatialFilter中的Geometry

                        //当要素不为空时
                        //while循环,满足条件进入循环,直到条件不满足才跳出循环

                        while (pFeature != null)
                        {
                            
                            //为几何建立拓扑关系
                            if (pGeometry != null)
                            {
                                ITopologicalOperator pTO;
                                pTO = pGeometry as ITopologicalOperator;
                                IGeometry pBuffer = pTO.Buffer(Double.Parse(txtBuffer.Text));
                                pGeometry = pBuffer;
                            }
                            //避免死循环
                            pFeature = pFeatureCursor.NextFeature();
                        }
                        //得到具有拓扑关系的几何集合
                        pSpatialFilter.Geometry = pGeometry;
                    }
                }
            }

            //空间查询方法
            switch (cmbSpatialSelectMethod.SelectedIndex)
            {
                case 0:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                    break;
                case 1:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelEnvelopeIntersects;
                    break;
                case 2:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIndexIntersects;
                    break;
                case 3:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelTouches;
                    break;
                case 4:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelOverlaps;
                    break;
                case 5:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
                    break;
                case 6:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
                    break;
                case 7:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
                    break;
                case 8:
                    pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelRelation;
                    break;
            }

            //得到目标图层
            for (int i = 0; i < clbTargetLayer.CheckedItems.Count; i++)
            {
                for (int j = 0; j < pMap.LayerCount; j++)
                {
                    if (pMap.get_Layer(j).Name == clbTargetLayer.CheckedItems[i].ToString())
                    {
                        //要素图层
                        pFeatureLayer = pMap.get_Layer(j) as IFeatureLayer;
                    }
                }
            }

            IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
            //选择方法
            switch (cmbSelectedMethod.SelectedIndex)
            {
                case 0:
                    pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
                    break;
                case 1:
                    pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
                    break;
                case 2:
                    pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultSubtract, false);
                    break;
                case 3:
                    pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultAnd, false);
                    break;
            }
            IFeatureSelection pFeatureS = pFeatureLayer as IFeatureSelection;
            ISelectionSet pSelectionSet = pFeatureS.SelectionSet;
            //显示所选要素个数
            lblFeatureCount.Text = "已选要素: " + pSelectionSet.Count + " 个";
            //刷新
            IActiveView pActiveView = pMap as IActiveView;
            pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, pActiveView.Extent);
            //pActiveView.Refresh();
        }
    }
}

11 总结

基于C#的ArcEngine二次开发是ArcGIS中很有趣的一部分,C#本身是面向对象语言,也有相关帮助文档查看,很多功能都是现有的,可以通过帮助文档查找,而我们要做的就是将这些功能组装成我们需要的产品。可能做出来没有WebGIS开发那么高大上,但我觉得这里面的学习思路是很值得借鉴的,至少,通过这一部分的研究学习,更了解了ArcGIS的运作原理。

我也在努力完善这方面的开发知识,总之,没有白走的路,希望这篇文章能对你有用,同时感谢看到这里的您,给个赞再走吧(✯ᴗ✯)。

 

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值