一、作业要求
- 在Country图层中,以"LANDLOCKED = \'Y\'"为条件进行查询,并对查询结果汇总Country的个数及面积之和。
- 在Country中先选中一个Country(例如Brazil),而后以"Population > 2000000"为条件查询该Country中的所有Cities,统计其个数。
- 将2中满足条件的Cities置于被选中状态。
二、作业过程
本来已经打算都删了,可还不是因为自己fanjian,又都放上了
1.新建MapControl Application
2.窗体布局
属性查询,空间查询,城市选择的翻译的可能不太对,大家可以根据自己习惯采用英文。
3.引用的类库
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();
}
}
}
三、作业成果
- 在Country图层中,以"LANDLOCKED = \'Y\'"为条件进行查询,并对查询结果汇总Country的个数及面积之和。
- 在Country中先选中一个Country(例如Brazil),而后以"Population > 2000000"为条件查询该Country中的所有Cities,统计其个数。
- 将2中满足条件的Cities置于被选中状态。