EX04:编写程序,使用QueryFilter、SpatialFilter和FeatureCursor。

 一、作业要求

27a7b6a1ed82494ba41fbf3aa17fc57c.png

  1. 在Country图层中,以"LANDLOCKED = \'Y\'"为条件进行查询,并对查询结果汇总Country的个数及面积之和。
  2. 在Country中先选中一个Country(例如Brazil),而后以"Population > 2000000"为条件查询该Country中的所有Cities,统计其个数。
  3. 将2中满足条件的Cities置于被选中状态。

二、作业过程

本来已经打算都删了,可还不是因为自己fanjian,又都放上了

1.新建MapControl Application

2.窗体布局

属性查询,空间查询,城市选择的翻译的可能不太对,大家可以根据自己习惯采用英文。

35792564651e467d8b1dac207b647ef5.png

3.引用的类库

8e5ad80dafab460fb9674d54fbc45565.png

4.编写代码

a.MainForm.cs

引入的命名空间

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;

using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;

代码

namespace EX04
{
    public sealed partial class MainForm : Form
    {
        #region class private members
        private IMapControl3 m_mapControl = null;
        private string m_mapDocumentName = string.Empty;
        #endregion

        #region class constructor
        public MainForm()
        {
            InitializeComponent();
        }
        #endregion

        private void MainForm_Load(object sender, EventArgs e)
        {
            //get the MapControl
            m_mapControl = (IMapControl3)axMapControl1.Object;

            //disable the Save menu (since there is no document yet)
            menuSaveDoc.Enabled = false;
        }

        #region Main Menu event handlers
        private void menuNewDoc_Click(object sender, EventArgs e)
        {
            //execute New Document command
            ICommand command = new CreateNewDocument();
            command.OnCreate(m_mapControl.Object);
            command.OnClick();
        }

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

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

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

                //Replace its contents with the current map
                mapDoc.ReplaceContents((IMxdContents)m_mapControl.Map);

                //save the MapDocument in order to persist it
                mapDoc.Save(mapDoc.UsesRelativePaths, false);

                //close the MapDocument
                mapDoc.Close();
            }
        }

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

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

        //listen to MapReplaced evant in order to update the statusbar and the Save menu
        private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
        {
            //get the current document name from the MapControl
            m_mapDocumentName = m_mapControl.DocumentFilename;

            //if there is no MapDocument, diable the Save menu and clear the statusbar
            if (m_mapDocumentName == string.Empty)
            {
                menuSaveDoc.Enabled = false;
                statusBarXY.Text = string.Empty;
            }
            else
            {
                //enable the Save manu and write the doc name to the statusbar
                menuSaveDoc.Enabled = true;
               
                statusBarXY.Text = System.IO.Path.GetFileName(m_mapDocumentName);   //“Path”是“ESRI.ArcGIS.Geometry.Path”和“System.IO.Path”之间的不明确的引用
                                                                                    //  分别ESRI.ArcGIS.Geometry.Path.和System.IO.Path.判断出是System.IO.Path.
            }
        }

        private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            statusBarXY.Text = string.Format("{0}, {1}  {2}", e.mapX.ToString("#######.##"), e.mapY.ToString("#######.##"), axMapControl1.MapUnits.ToString().Substring(4));
        }

        #region  在用户在地图控件上点击鼠标时,选择点击位置周围的对象(尽管这里的缓冲区距离为0,实际上没有创建缓冲区)
        private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
           
                IPoint pPoint = new PointClass();// 创建一个新的点对象,该对象表示用户在地图上点击的位置。  
            ITopologicalOperator pTopologicalOperator = pPoint as ITopologicalOperator;    // 将新创建的点对象强制转换为ITopologicalOperator接口类型。  
            pPoint.PutCoords(e.mapX, e.mapY);           // 设置点对象的位置,这里使用的是事件参数e中的mapX和mapY坐标。                                             // ITopologicalOperator接口包含用于几何运算的一组方法,这里主要是为了使用Buffer方法。  
            IGeometry pGeometry = pTopologicalOperator.Buffer(0);  // 使用Buffer方法创建一个基于该点的缓冲区,缓冲区的半径为0(表示无缓冲区)。  
                                                                   // 这里的Buffer方法是指定距离的缓冲区创建,但这里距离为0,所以实际上创建的是一个空几何对象。  
            axMapControl1.Map.SelectByShape(pGeometry, null, false);// 使用创建的几何对象(这里是空的)来选择地图上的对象。这里的SelectByShape方法会选择所有与给定几何对象相交的地理对象。 
            axMapControl1.Refresh(esriViewDrawPhase.esriViewGeoSelection, null, null);// 刷新axMapControl1控件的显示,以反映选择的变化。  
        }
        #endregion


        # region 用于查询并计算一个地理数据库中所有被锁定(LANDLOCKED = 'Y')的多边形区域的面积。
        private void QueryFilter_Click(object sender, EventArgs e)//此方法从 AxMapControl1 的图层中获取特征层,并查询所有被锁定的多边形区域。
        {
            if (axMapControl1.Map.LayerCount != 0) // 检查地图控件的图层数量是否大于0,如果不是,则不进行任何操作。  
            {
                IFeatureLayer pGeoLayer = this.axMapControl1.get_Layer(2) as IFeatureLayer;// 从 AxMapControl1 的图层中获取第三个图层(索引从0开始),并将其转换为 IFeatureLayer 接口类型。  
                ITable pTable = pGeoLayer.FeatureClass as ITable;  // 将 pGeoLayer 的 FeatureClass 转换为 ITable 接口类型。  
                IFeatureCursor pCursor; // 创建一个 IFeatureCursor 对象,用于遍历地图中的特征。  
                IQueryFilter pQueryFilter = new QueryFilter();    // 创建一个新的 QueryFilter 对象,用于设置查询条件。  
                pQueryFilter.WhereClause = "LANDLOCKED = \'Y\'"; // 设置 QueryFilter 的 WhereClause 属性,以便仅选择 LANDLOCKED 字段值为 'Y' 的记录。  
                pCursor = (IFeatureCursor)pTable.Search(pQueryFilter, true); // 使用 QueryFilter 在地图中搜索满足条件的特征,并将结果赋给 pCursor。 
                IFeature pFea = pCursor.NextFeature();   // 使用 pCursor 获取第一个满足条件的特征,并将其赋给 pFea。  
                double area = 0;// 初始化一个变量 area ,用于存储所有满足条件的特征的面积总和。  
                IArea pAea = pFea.Shape as IArea;// 将 pFea 的 Shape 属性转换为 IArea 接口类型,并将其赋给 pAea。  
                if (pFea != null) // 检查第一个特征是否为空,如果不为空,则计算其面积并加到 area 中。同时移动到下一个特征。
                {
                    if (pFea.Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                    {
                        area = area + pAea.Area;
                        pFea = pCursor.NextFeature();
                    }
                }
                int i = 1; // 初始化一个变量 i ,用于计数满足条件的特征的数量。  
                while (pFea != null) // 使用循环遍历所有满足条件的特征,计算它们的面积并累加到 area 中。同时计数器 i 也进行累加。  
                {
                    i++;
                    if (pFea.Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                    {
                        area = area + pAea.Area;
                        pFea = pCursor.NextFeature();
                    }
                }
                // 使用 MessageBox 显示满足条件的特征的数量和它们的面积总和。  
                MessageBox.Show(i + " countries with LANDLOCKED = Y \n " + "The sum of acreage:" + area + " Square Meter");
            }
        }
        #endregion


        #region  在地图控件中执行空间过滤操作
        private void SpatialFliter_Click(object sender, EventArgs e)//此方法从 AxMapControl1 的图层中获取特征层,并查询选中区域中人口大于2000000的城市数量。  
        {
           
            ISelection pSelection = axMapControl1.Map.FeatureSelection; // 获取地图控件中的特征选择对象。
            IEnumFeatureSetup pEnumFeatureSetup = pSelection as IEnumFeatureSetup;// 将特征选择对象转换为枚举特征设置对象。  
            pEnumFeatureSetup.AllFields = true;   // 设置枚举特征设置对象以返回所有字段。
            IEnumFeature pEnumFeature = pSelection as IEnumFeature;    // 将特征选择对象转换为枚举特征对象。
            IFeature pFeature = pEnumFeature.Next();    // 获取第一个选中的特征。
            if (pFeature != null) // 检查选中的特征是否为空。如果为空,则显示“未选中Country”消息框。
            {

                IFeatureLayer pFL = (IFeatureLayer)axMapControl1.get_Layer(0); // 从地图控件中获取第一个图层(索引从0开始),并将其转换为特征图层。  
                IFeatureClass pFC = pFL.FeatureClass;// 获取特征图层的特征类。 
                ISpatialFilter pSF = new SpatialFilterClass(); // 创建一个空间过滤器对象。
                pSF.WhereClause = "Population>2000000";     // 设置空间过滤器的查询条件,即人口大于2000000。  
                pSF.Geometry = pFeature.Shape;      // 设置空间过滤器的形状为选中的特征的形状。
                pSF.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;        // 设置空间关系为包含关系。 
                // 使用空间过滤器在特征类中搜索满足条件的特征。 
                IFeatureCursor pCursor;    
                pCursor = pFC.Search(pSF, true);
                // 显示满足条件的特征数量和“城市”文本的消息框。例如,如果搜索结果中有3个符合条件的城市,则消息框将显示“3 cities with population > 2000000”。
                MessageBox.Show(pFC.FeatureCount(pSF) + " cities with population > 2000000");

                }
                else MessageBox.Show("未选中Country");
        }

        #endregion


        #region 用于在地图控件中执行空间过滤操作,选择人口大于2000000的城市。
        private void SelectCities_Click(object sender, EventArgs e)//此方法从 AxMapControl1 的图层中获取特征层,  
                                                                   // 并查询选中区域中人口大于2000000的城市数量。如果选中了某个区域,那么该方法将选择该区域内所有符合条件(人口大于2000000)的城市。
        {

            ISelection pSelection = axMapControl1.Map.FeatureSelection;    // 获取地图控件中的特征选择对象。 
            IEnumFeatureSetup pEnumFeatureSetup = pSelection as IEnumFeatureSetup; // 将特征选择对象转换为枚举特征设置对象。 
            pEnumFeatureSetup.AllFields = true;    // 设置枚举特征设置对象以返回所有字段。
            IEnumFeature pEnumFeature = pSelection as IEnumFeature;    // 将特征选择对象转换为枚举特征对象。
            IFeature pFeature = pEnumFeature.Next();   // 获取第一个选中的特征。
            if (pFeature != null) // 检查选中的特征是否为空。如果为空,则显示“未选中Country”消息框。
            {

                IFeatureLayer pFL = (IFeatureLayer)axMapControl1.get_Layer(0);  // 从地图控件中获取第一个图层(索引从0开始),并将其转换为特征图层。  
                IFeatureClass pFC = pFL.FeatureClass;      // 获取特征图层的特征类。  
                ISpatialFilter pSF = new SpatialFilterClass();   // 创建一个空间过滤器对象。
                pSF.WhereClause = "Population>2000000"; // 设置空间过滤器的查询条件,即人口大于2000000。  
                pSF.Geometry = pFeature.Shape;     // 设置空间过滤器的形状为选中的特征的形状。  
                pSF.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;     // 设置空间关系为包含关系。 
                 // 使用空间过滤器在特征类中搜索满足条件的特征。                                                                 
                IFeatureCursor pCursor;
                pCursor = pFC.Search(pSF, true);
                // 获取特征选择对象,并选择符合空间过滤条件的特征。如果成功选择了特征,则将结果添加到地图控件中。  
                IFeatureSelection pFS = pFL as IFeatureSelection;
                pFS.SelectFeatures(pSF, esriSelectionResultEnum.esriSelectionResultAdd, false);
                axMapControl1.ActiveView.Refresh(); // 刷新地图控件的当前活动视图,以显示新的选择结果。

            }
                else MessageBox.Show("未选中Country");     
        }
        #endregion
    }
}

b.Program.cs  用的是默认的代码,并没有在此处编写代码

引入的命名空间

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ESRI.ArcGIS;
using ESRI.ArcGIS.esriSystem;

代码


namespace EX04
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            //ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);//ArcGIS的控件需要这行代码的绑定访问

            if (!RuntimeManager.Bind(ProductCode.Engine))
            {
                if (!RuntimeManager.Bind(ProductCode.Desktop))
                {
                    MessageBox.Show("Unable to bind to ArcGIS runtime. Application will be shut down.");
                    return;
                }
            }

           // //ESRI License Initializer generated code.
           // m_AOLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeEngine },
           // new esriLicenseExtensionCode[] { });


            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());



            ESRI License Initializer generated code.
            Do not make any call to ArcObjects after ShutDownApplication()
            //m_AOLicenseInitializer.ShutdownApplication();
        }
    }
}

三、作业成果

  1. 在Country图层中,以"LANDLOCKED = \'Y\'"为条件进行查询,并对查询结果汇总Country的个数及面积之和。
  2. 在Country中先选中一个Country(例如Brazil),而后以"Population > 2000000"为条件查询该Country中的所有Cities,统计其个数。
  3. 将2中满足条件的Cities置于被选中状态。

8c078964785d471bb14708ad31a0354f.png

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值