这是一份关于ArcGIS Engine 二次开发 的一份报告总结,在这份报告中包含了简单的ArcGIS功能。包含的功能如下:
首先会先对各个功能分别进行介绍,我之前做也是一个功能一个功能写过来的,最后会放出集成的界面和代码。
在开始正式书写代码之前,我们需要了解一些基本知识。
License是进行AE开发必须加入的功能,我们创建一个窗体项目后首先加入 LicenseControl控件,然后在Program.cs中添加如下橙色部分代码(注意不要加错位置):
Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop); Application.Run(new mapForm());

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


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


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


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



双击按钮默认使用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); } } }栅格数据比矢量数据复杂,这里我并没有将栅格数据和矢量数据的加载放在同一个按钮上实现,而是通过一个新的按钮进行添加。
这里对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); } } }至此便可完成对矢量数据和栅格数据的加载。
地图浏览功能包含:矩形拉框放大、矩形拉框缩小、平移(漫游)、全图显示、逐级放大、逐级缩小、历史视图浏览(撤销、重做)
在ToolStrip中分别八个功能进行添加,分别设置好图片内容和鼠标悬浮显示文字。

双击按钮默认使用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; }至此便可实现地图浏览的“矩形拉框放大、矩形拉框缩小、平移(漫游)、全图显示、逐级放大、逐级缩小、历史视图浏览(撤销、重做)”八个功能。
点线面的绘制要求能分别设置颜色、样式、大小及多边形面的填充方式
如图所示是我设计的绘制界面,有点潦草,朋友们自己做的时候可以设计的好看一点哈哈哈。

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

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

这个与其说是“绘制面”,不如说是“绘制圆”,代码引用的也是axMapControl1.TrackCircle(),命名的时候可以改一下。
这个圆有九种填充方式,分别是实心填充、不填充、空心填充、水平线填充、垂直线填充、45度下斜线填充、45度上斜线填充、水平十字线填充和45度交叉线填充,其中不填充和空心填充的表现形式是一样的。
经过测试,面边框宽度、填充样式、填充颜色和边框线功能都正常,测试结果如图所示。

“绘制矩形”功能同样有九种填充样式,分别是实心填充、不填充、空心填充、水平线填充、垂直线填充、45度下斜线填充、45度上斜线填充、水平十字线填充和45度交叉线填充,其中不填充和空心填充的表现形式是一样的。
经过测试,矩形边框宽度、填充样式、填充颜色和边框线功能都正常,测试结果如图所示。

绘制矩形”功能同样有九种填充样式,分别是实心填充、不填充、空心填充、水平线填充、垂直线填充、45度下斜线填充、45度上斜线填充、水平十字线填充和45度交叉线填充,其中不填充和空心填充的表现形式是一样的。
经过测试,矩形边框宽度、填充样式、填充颜色和边框线功能都正常,测试结果如图所示。

所以呢,除了“绘制线”功能有点问题之外,其他功能都正常,下面是点线面绘制的整体代码。
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; } } }}书签这一部分功能涉及到两个窗口,一个是主窗口,一个是副窗口。主窗口就是我们浏览地图的主界面,副窗口是创建书签时弹出来的界面,自然也就涉及到了主副窗口之间的交互。
主窗口界面如下所示,窗口命名为frmMain,注意是代码里的名称,不是窗口显示的名字。

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

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

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


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


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


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

经测试,添加书签功能正常。
首先展示主窗口的代码,大家直接看代码里的注释就好,这里就不再赘述。
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(); } } }}由于副窗口是要根据主窗口展示的内容进行运行的,所以肯定有两个窗口之间的交互,这里我用到了类和构造函数,不是很能理解的小伙伴建议补一下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(); } }}这里先放几个会用到的图标,颜色的图标小伙伴们可以自己百度找一下,其实我有一整套的ArcGIS图标,但是还不知道咋个上传。






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



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

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

每次选择后都有在清除,这里就不展示了。
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(); //刷新,清空之后刷新视图才能看到元素被清除 } }}


加载一副矢量地图

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

弹出如下界面

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

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

点击应用

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

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

顾名思义就是在已选择的要素中再进行选择,现在已选择的要素有龙城街道和大渔街道,我们选择大渔街道。
可以看到留下了大渔街道,原来的龙城街道被剔除了。

显然,属性查询功能也有主副窗口,主窗口即地图,代码中命名为mapShow,副窗口即属性查询,代码中命名为attributeQuery。
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(); } }}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(); } }}

这部分有点复杂,光目标图层要素的空间选择方法就有九种,我自己的数据也有点问题,就不进行测试了,直接上代码。
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(); } }}我记得这部分代码有个地方我好像改过,后面一会儿会放一个我做的以上所有功能的一个集成代码,里面有修改后的代码,总之是进行了功能上的提升的。
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) { } } }}
这个集成包含了很多窗口,有显示地图的主窗口mapForm,属性查询的窗口attributeQueryForm,属性表窗口attributeTable,书签窗口bookMarkForm,和空间查询窗口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; //IWorkspaceFactoryusing ESRI.ArcGIS.Geodatabase;//RasterWorkspaceFactory()using ESRI.ArcGIS.DataSourcesRaster;//IRasterLayerusing 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).如何在缓冲区中进行查询(已解决) }}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(); } }}做的有点粗糙,大概是这个样子。

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) { } }}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(); } }}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(); } }}基于C#的ArcEngine二次开发是ArcGIS中很有趣的一部分,C#本身是面向对象语言,也有相关帮助文档查看,很多功能都是现有的,可以通过帮助文档查找,而我们要做的就是将这些功能组装成我们需要的产品。可能做出来没有WebGIS开发那么高大上,但我觉得这里面的学习思路是很值得借鉴的,至少,通过这一部分的研究学习,更了解了ArcGIS的运作原理。
我也在努力完善这方面的开发知识,总之,没有白走的路,希望这篇文章能对你有用,同时感谢看到这里的您,给个赞再走吧(✯ᴗ✯)。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删