目录
1 前言
这是一份关于ArcGIS Engine二次开发的一份报告总结,在这份报告中包含了简单的ArcGIS功能。包含的功能如下:
- 对数据的加载,包括矢量数据和栅格数据
- 地图浏览功能:拉框放大、拉框缩小、平移、全图、逐级放大、逐级缩小、历史视图浏览(撤销、重做)
-
点线面的绘制:点、圆、多边形、矩形,能分别设置颜色、样式、大小及面填充方式
-
书签功能
-
选择要素:拉框选择、按多边形选择、按圆选择、按线选择,并能设置选择颜色
-
属性查询
-
空间查询
首先会先对各个功能分别进行介绍,我之前做也是一个功能一个功能写过来的,最后会放出集成的界面和代码。
2 准备工作
在开始正式书写代码之前,我们需要了解一些基本知识。
2.1 License的加入
License是进行AE开发必须加入的功能,我们创建一个窗体项目后首先加入 LicenseControl控件,然后在Program.cs中添加如下橙色部分代码(注意不要加错位置):
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
Application.Run(new mapForm());
2.2 ToolStrip控件
ToolStrip控件位于工具箱的菜单和工具栏中,可以添加图中所示的几个功能:Button、Label、SplitButton、DropDownButton、Separator、ComboBox、TextBox、ProgressBar。这里用到了Button功能,前九个功能通过添加Button来完成,图片可以自行添加。
2.3 MenuStrip控件
menustrip可以进行下拉菜单的创建,比如查询功能中包含两个功能,一个是属性查询,一个是空间查询,通过menustrip将二者放到一个下拉菜单中,可以保证界面的整洁舒适,以及功能的方便使用。
2.4 帮助文档的查看
在开始中找到ArcGIS,找到对应的帮助文档,我的Visual Studio是2012版的,用的是第二个。打开帮助我们可以对需要使用的功能进行查询,比如OpenFileDialog,右边是对其用法的介绍。
3 数据加载
3.1 矢量数据的加载
首先在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);
}
}
}
3.2 栅格数据的加载
栅格数据比矢量数据复杂,这里我并没有将栅格数据和矢量数据的加载放在同一个按钮上实现,而是通过一个新的按钮进行添加。
这里对jpg、img、tiff三种格式的栅格数据进行了添加。
双击按钮默认使用click事件,双击按钮,加入以下代码:
//打开栅格数据
private void btnRasterOpen_Click(object sender, EventArgs e)
{
//实例化对象
OpenFileDialog openRaster = new OpenFileDialog();
//命名弹窗名称
openRaster.Title=("加载栅格数据");
//允许选择多项
openRaster.Multiselect = true;
//过滤栅格数据
openRaster.Filter = "栅格文件jpg|*.jpg|栅格文件tiff|*.tiff|栅格文件img|*.img";
//定义整型位置intPosition
int intPosition;
//定义字符型路径stringFilePath和名字stringFileName
string stringFilePath, stringFileName;
if (openRaster.ShowDialog() == DialogResult.OK)
{
//foreach访问
foreach (String file in openRaster.FileNames)
{
//intPosition的1位置在最后一个\\处
intPosition = file.LastIndexOf("\\");
//路径
stringFilePath = file.Substring(0, intPosition);
//文件名
stringFileName = file.Substring(intPosition + 1);
//IWorkSpace是一个容器,存放空间数据与非空间数据
//如:FeatureClass、RasterDataset、table等
//IWorkSpace有三种类型:FileSystemWorkspace、LocalDatsbaseWorkspace,RemoteDatabaseWorkspace
//WorkSpace类不能直接实例化,必须由IWorkSpaceFactory的Create方法创建
//WorkspaceFactory:create workspace
//IRasterWorkspace Interfece:provides access to members that control a raster workspace
//含OpenRasterDataset:Opens a rasterdataset in the workspace given its name
//通过IworkSpaceFactory创建工作空间,将其在RasterWorkspaceFactory中实例化
IWorkspaceFactory prasterWorspaceFactory = new RasterWorkspaceFactory();
//创建一个栅格工作空间,将其在工作空间中的栅格文件在栅格工作空间中打开
IRasterWorkspace rasterWorkSpace = prasterWorspaceFactory.OpenFromFile(stringFilePath, 0) as IRasterWorkspace;
//将栅格空间中的空间数据打开
IRasterDataset pRasterDataset = rasterWorkSpace.OpenRasterDataset(stringFileName);
//IRasterLayer:provide access to members that create or modify a raster layer
//RasterLayerClass:raster layer source and display options
IRasterLayer pRasterLayer = new RasterLayerClass();
//在图层中创建栅格数据
pRasterLayer.CreateFromDataset(pRasterDataset);
//ILayer:provide access to members that work with all layers
//将栅格图层转换为图层形式
ILayer pLayer = pRasterLayer as ILayer;
//显示栅格图层
axMapControl1.AddLayer(pLayer);
}
}
}
至此便可完成对矢量数据和栅格数据的加载。
4 地图浏览功能
地图浏览功能包含:矩形拉框放大、矩形拉框缩小、平移(漫游)、全图显示、逐级放大、逐级缩小、历史视图浏览(撤销、重做)
在ToolStrip中分别八个功能进行添加,分别设置好图片内容和鼠标悬浮显示文字。
双击按钮默认使用click事件,双击按钮,加入以下代码:
注:由于全图显示、逐级放大、逐级缩小、历史视图浏览(撤销、重做)五个功能只需要点击对应按钮,触发Click事件即可实现,因此不对其进行功能标识;而矩形拉框放大、矩形拉框缩小、平移(漫游)在触发Click事件之后还要在axMapControl1中进行鼠标点击以实现功能,故需通过flag对其进行标识。
//地图浏览
int flag;
//放大
private void enLarge_Click(object sender, EventArgs e)
{
flag = 1;
axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomIn;
}
//缩小
private void Suoxiao_Click(object sender, EventArgs e)
{
flag = 2;
axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomOut;
}
//平移
private void Pingyi_Click(object sender, EventArgs e)
{
flag = 3;
axMapControl1.MousePointer = esriControlsMousePointer.esriPointerPan;
}
//逐级放大
private void EnlargeByStep_Click(object sender, EventArgs e)
{
IEnvelope yEnvelop = axMapControl1.Extent;
yEnvelop.Expand(0.5, 0.5, true);
axMapControl1.Extent = yEnvelop;
axMapControl1.ActiveView.Refresh();
}
//逐级缩小
private void SuoxiaoBystep_Click(object sender, EventArgs e)
{
IEnvelope yEnvelop = axMapControl1.Extent;
yEnvelop.Expand(2, 2, true);
axMapControl1.Extent = yEnvelop;
axMapControl1.ActiveView.Refresh();
}
//全图显示
private void Entire_Click(object sender, EventArgs e)
{
axMapControl1.Extent = axMapControl1.FullExtent;
}
IExtentStack yExtentStack;
//上一级视图
private void before_Click(object sender, EventArgs e)
{
yExtentStack = axMapControl1.ActiveView.ExtentStack;
//判断是否可返回
if (yExtentStack.CanUndo())
{
yExtentStack.Undo();
before.Enabled = true;
if (!yExtentStack.CanUndo())
{
before.Enabled = false;
}
}
axMapControl1.ActiveView.Refresh();
}
//下一级视图
private void after_Click(object sender, EventArgs e)
{
yExtentStack = axMapControl1.ActiveView.ExtentStack;
if (yExtentStack.CanRedo())
{
yExtentStack.Redo();
after.Enabled = true;
if (!yExtentStack.CanRedo())
{
after.Enabled = false;
}
}
axMapControl1.ActiveView.Refresh();
}
在axMapControl1_OnMouseDown中加入以下代码:
*地图浏览
//激活
IActiveView yActiveView = axMapControl1.ActiveView;
//框架
IEnvelope yEnvelope = new EnvelopeClass();
switch (flag)
{
case 1:
//框架为矩形
yEnvelope = axMapControl1.TrackRectangle();
//视图范围为框架选择范围
yActiveView.Extent = yEnvelope;
//刷新
yActiveView.Refresh();
break;
case 2:
//框架为矩形缩小
yEnvelope = axMapControl1.TrackRectangle();
//两倍缩小
yEnvelope.Expand(2, 2, true);
//视图范围为框架范围
yActiveView.Extent = yEnvelope;
//刷新
yActiveView.Refresh();
break;
case 3:
//漫游
axMapControl1.Pan();
break;
default:
break;
}
至此便可实现地图浏览的“矩形拉框放大、矩形拉框缩小、平移(漫游)、全图显示、逐级放大、逐级缩小、历史视图浏览(撤销、重做)”八个功能。
5.点线面的绘制:点、线、圆、多边形、矩形,
点线面的绘制要求能分别设置颜色、样式、大小及多边形面的填充方式
如图所示是我设计的绘制界面,有点潦草,朋友们自己做的时候可以设计的好看一点哈哈哈。
5.1 测试
(1)对“绘制点”功能进行测试
点的样式共有四种,分别是正方形、圆形、十字型、X型和棱形,分别对这些样式进行颜色和大小的测试,总体上没问题。
(2)对“绘制线”功能进行测试
这个功能稍微有点问题,一个是绘制的线条无法完成绘制,鼠标总是拖着线走,还有一个是线的样式、粗细和颜色都无法改变,这一块稍微有点问题,我也在积极解决中,虽然这个没有做出来但并不影响后面的噢。
(3)对“绘制面”功能进行测试
这个与其说是“绘制面”,不如说是“绘制圆”,代码引用的也是axMapControl1.TrackCircle(),命名的时候可以改一下。
这个圆有九种填充方式,分别是实心填充、不填充、空心填充、水平线填充、垂直线填充、45度下斜线填充、45度上斜线填充、水平十字线填充和45度交叉线填充,其中不填充和空心填充的表现形式是一样的。
经过测试,面边框宽度、填充样式、填充颜色和边框线功能都正常,测试结果如图所示。
(4)对“绘制矩形”功能进行测试
“绘制矩形”功能同样有九种填充样式,分别是实心填充、不填充、空心填充、水平线填充、垂直线填充、45度下斜线填充、45度上斜线填充、水平十字线填充和45度交叉线填充,其中不填充和空心填充的表现形式是一样的。
经过测试,矩形边框宽度、填充样式、填充颜色和边框线功能都正常,测试结果如图所示。
(5)对“绘制多边形”功能进行测试
绘制矩形”功能同样有九种填充样式,分别是实心填充、不填充、空心填充、水平线填充、垂直线填充、45度下斜线填充、45度上斜线填充、水平十字线填充和45度交叉线填充,其中不填充和空心填充的表现形式是一样的。
经过测试,矩形边框宽度、填充样式、填充颜色和边框线功能都正常,测试结果如图所示。
5.2 代码
所以呢,除了“绘制线”功能有点问题之外,其他功能都正常,下面是点线面绘制的整体代码。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
namespace Drwaing
{
public partial class frmDrawShape : Form
{
public frmDrawShape()
{
InitializeComponent();
btnDrawPoint.Text = "绘制点"; //设置按钮的名称
btnDrawLine.Text = "绘制线"; //设置按钮的名称
btnDrawSurface.Text = "绘制面"; //设置按钮的名称
btnDrawRectangle.Text = "绘制矩形"; //设置按钮的名称
nbtnDrawPolygon.Text = "绘制多边形";
btnDrawText.Text = "输入文字";
label1.Text = "边框颜色";
}
int flag = 0; //默认状态
IRgbColor pColor; //用pColor调用颜色
IRgbColor rColor;
private void btnDrawPoint_Click(object sender, EventArgs e)
{
//画点
flag = 1;
setPoint();
}
private void setPoint()
{
//设置相关标签名称和点的可选样式
lblSize.Text = "点的大小";
txtSize.Text = "3";
txtSize.Visible = true;
lblStyle.Text = "点的样式";
lblColor.Text = "颜色";
cmbStyle.Items.Clear(); //进行下拉框内容的清楚,防止重复出现
cmbStyle.Items.Add("正方形");
cmbStyle.Items.Add("圆");
cmbStyle.Items.Add("十字形");
cmbStyle.Items.Add("X形");
cmbStyle.Items.Add("菱形");
cmbStyle.SelectedIndex = 0; //默认选择第一个样式
}
private void btnDrawLine_Click(object sender, EventArgs e)
{
//画线
flag = 2;
lblSize.Text = "线的宽度";
lblStyle.Text = "线的样式";
txtSize.Visible = true;
txtSize.Text = "1";
cmbStyle.Items.Clear(); //进行下拉框内容的清除,防止重复出现
cmbStyle.Items.Add("实线");
cmbStyle.Items.Add("短横线");
cmbStyle.Items.Add("点线");
cmbStyle.Items.Add("短横线和点线");
cmbStyle.Items.Add("短横线两点线");
cmbStyle.Items.Add("不可见的线");
cmbStyle.Items.Add("矩形边界线");
cmbStyle.SelectedIndex = 0; //默认为实线
}
private void btnDrawSurface_Click(object sender, EventArgs e)
{
flag = 3;
setSurface();
}
private void btnDrawRectangle_Click(object sender, EventArgs e)
{
flag = 4;
setSurface();
}
private void nbtnDrawPolygon_Click(object sender, EventArgs e)
{
flag = 5;
setSurface();
}
private void setSurface()
{
lblSize.Text = "面边框的宽度";
txtSize.Text = "1";
txtSize.Visible = true;
lblStyle.Visible = true;
cmbStyle.Items.Clear();
cmbStyle.Items.Add("实心填充");
cmbStyle.Items.Add("不填充");
cmbStyle.Items.Add("空心填充");
cmbStyle.Items.Add("水平线填充");
cmbStyle.Items.Add("垂直线填充");
cmbStyle.Items.Add("45度下斜线填充");
cmbStyle.Items.Add("45度上斜线填充");
cmbStyle.Items.Add("水平十字线填充");
cmbStyle.Items.Add("45度交叉线填充");
cmbStyle.SelectedIndex = 0;
}
private void btnDrawText_Click(object sender, EventArgs e)
{
flag = 6;
lblSize.Text = "字的大小";
txtSize.Text = "16";
txtSize.Visible = true;
lblStyle.Visible = false;
cmbStyle.Visible = false;
}
private void drawMapText(IGeometry geometry)
{
setColor();
ITextSymbol txtSymbol;
stdole.IFontDisp pFont;
pFont = new stdole.StdFontClass() as stdole.IFontDisp;
txtSymbol = new TextSymbol();
object symbol = txtSymbol;
double pDouble, pWith;
bool isNum = System.Double.TryParse(txtSize.Text, System.Globalization.NumberStyles.Integer, null, out pDouble);
if (isNum == false)
{
MessageBox.Show("您输入的不是一个数字,请输入一个数字。", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
}
else
{
pWith = Convert.ToDouble(txtSize.Text);
pFont.Size = (decimal)pWith;
}
txtSymbol.Color = pColor;
txtSymbol.Font = pFont;
axMapControl1.DrawText(geometry, txtSymbol.Text, ref symbol);
}
private void setColor()
{
//默认颜色,黑色
if (pColor == null)
{
pColor = new RgbColor();
pColor.Red = 0;
pColor.Blue = 0;
pColor.Green = 0;
}
if (rColor == null)
{
rColor = new RgbColor();
rColor.Red = 0;
rColor.Blue = 0;
rColor.Green = 0;
}
}
private void frmDrawShape_Load(object sender, EventArgs e)
{
setPoint();
}
private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
IGeometry geometry = null; //geometry初始为空
IPoint point = new ESRI.ArcGIS.Geometry.Point(); //point为ArcGIS中的point
if (flag == 1 || flag == 0)
{
point.X = e.mapX; //屏幕X坐标为地图X坐标
point.Y = e.mapY; //屏幕Y坐标为地图Y坐标
geometry = point as IGeometry;
}
else if (flag == 2)
{
geometry = axMapControl1.TrackLine();
}
else if (flag == 3)
{
geometry = axMapControl1.TrackCircle();
}
else if (flag == 4)
{
geometry = axMapControl1.TrackRectangle();
}
else if (flag == 5)
{
geometry = axMapControl1.TrackPolygon();
}
else if (flag == 6)
{
point.X = e.mapX;
point.Y = e.mapY;
geometry = point as IGeometry;
}
if (flag >= 0 && flag <= 5)
{
drawMapShape(geometry);
}
else if (flag == 6)
{
drawMapText(geometry);
}
}
private void drawMapShape(IGeometry pGeometry)
{
object symbol = null; //符号初始为空值
setColor(); //调用setColor方法,使用默认颜色值
double pWith; //定义一个双精度型的pWith,用来存放符号大小
double pDouble; //定义一个pDouble用来输出输入的大小
bool isNum; //用于判别输入的是否为数字
isNum = System.Double.TryParse(txtSize.Text, System.Globalization.NumberStyles.Integer, null,out pDouble);
if (isNum == false)
{
MessageBox.Show("这不是一个数字,请输入一个数字。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
else
{
pWith = Convert.ToDouble(txtSize.Text); //将文本型的字符转换为双精度数字
if (pGeometry.GeometryType == esriGeometryType.esriGeometryPoint)
{
ISimpleMarkerSymbol pmarkerSymbol = new SimpleMarkerSymbol(); //实例化一个pmarkerSymbol用来存放点的符号类型
pmarkerSymbol.Color = pColor; //将默认的颜色赋给pmarkerSymbol
pmarkerSymbol.Size = pWith; //将转换后得到的符号大小赋给pmarkerSymbol
if (cmbStyle.SelectedItem.ToString() == "正方形")
{
pmarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSSquare;
}
if (cmbStyle.SelectedItem.ToString() == "圆")
{
pmarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
}
if (cmbStyle.SelectedItem.ToString() == "十字形")
{
pmarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCross;
}
if (cmbStyle.SelectedItem.ToString() == "X形")
{
pmarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSX;
}
if (cmbStyle.SelectedItem.ToString() == "菱形")
{
pmarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSDiamond;
}
symbol = pmarkerSymbol; //将各类情况下的pmarkerSymbol赋给symbol
}
else if (pGeometry.GeometryType == esriGeometryType.esriGeometryLine)
{
ISimpleLineSymbol pSLS;
pSLS = new SimpleLineSymbol();
pSLS.Color = pColor;
pSLS.Width = pWith;
if (cmbStyle.SelectedItem.ToString() == "实线")
{
pSLS.Style = esriSimpleLineStyle.esriSLSSolid;
}
else if (cmbStyle.SelectedItem.ToString() == "短横线")
{
pSLS.Style = esriSimpleLineStyle.esriSLSDash;
}
else if (cmbStyle.SelectedItem.ToString() == "点线")
{
pSLS.Style = esriSimpleLineStyle.esriSLSDot;
}
else if (cmbStyle.SelectedItem.ToString() == "短横线和点线")
{
pSLS.Style = esriSimpleLineStyle.esriSLSDashDot;
}
else if (cmbStyle.SelectedItem.ToString() == "短横线两点线")
{
pSLS.Style = esriSimpleLineStyle.esriSLSDashDotDot;
}
else if (cmbStyle.SelectedItem.ToString() == "不可见的线")
{
pSLS.Style = esriSimpleLineStyle.esriSLSNull;
}
else if (cmbStyle.SelectedItem.ToString() == "矩形边界线")
{
pSLS.Style = esriSimpleLineStyle.esriSLSInsideFrame;
}
symbol = pSLS;
}
else
{
ISimpleFillSymbol psimpleFillSymbol;
psimpleFillSymbol=new SimpleFillSymbol();
psimpleFillSymbol.Color = pColor; //内部颜色
ILineSymbol pLineSymbol = new SimpleLineSymbol();
pLineSymbol.Width = pWith;
pLineSymbol.Color = rColor; //边框颜色
psimpleFillSymbol.Outline = pLineSymbol;
if (cmbStyle.SelectedItem.ToString() == "实心填充")
{
psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
}
else if (cmbStyle.SelectedItem.ToString() == "不填充")
{
psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSNull;
}
else if (cmbStyle.SelectedItem.ToString() == "空心填充")
{
psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSHollow;
}
else if (cmbStyle.SelectedItem.ToString() == "水平线填充")
{
psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSHorizontal;
}
else if (cmbStyle.SelectedItem.ToString() == "垂直线填充")
{
psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSVertical;
}
else if (cmbStyle.SelectedItem.ToString() == "45度下斜线填充")
{
psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSForwardDiagonal;
}
else if (cmbStyle.SelectedItem.ToString() == "45度上斜线填充")
{
psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSBackwardDiagonal;
}
else if (cmbStyle.SelectedItem.ToString() == "水平十字线填充")
{
psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSCross;
}
else if (cmbStyle.SelectedItem.ToString() == "45度交叉线填充")
{
psimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSDiagonalCross;
}
symbol = psimpleFillSymbol;
}
axMapControl1.DrawShape(pGeometry, ref symbol);
}
}
private void pictureBox1_Click(object sender, EventArgs e)
{
//设置可选颜色
ColorDialog pColorDialog = new ColorDialog();
if (pColorDialog.ShowDialog() == DialogResult.OK)
{
pColor = new RgbColor();
pColor.Red = pColorDialog.Color.R;
pColor.Green = pColorDialog.Color.G;
pColor.Blue = pColorDialog.Color.B;
}
}
private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
{
if (flag >=1&&flag<7)
{
axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
}
}
private void pictureBox2_Click(object sender, EventArgs e)
{
ColorDialog pColorDialog = new ColorDialog();
if (pColorDialog.ShowDialog() == DialogResult.OK)
{
rColor = new RgbColor();
rColor.Red = pColorDialog.Color.R;
rColor.Green = pColorDialog.Color.G;
rColor.Blue = pColorDialog.Color.B;
}
}
}
}
6.书签功能
书签这一部分功能涉及到两个窗口,一个是主窗口,一个是副窗口。主窗口就是我们浏览地图的主界面,副窗口是创建书签时弹出来的界面,自然也就涉及到了主副窗口之间的交互。
主窗口界面如下所示,窗口命名为frmMain,注意是代码里的名称,不是窗口显示的名字。
副窗口界面如下所示,窗口命名为frmSub
6.1 测试
对正常大小,放大,缩小三种状态进行书签标记测试,任意添加一层矢量图层。
添加书签,标记正常大小视图。
添加书签,标记放大视图。
添加书签,标记缩小视图。
点开书签,打开所建书签,可以看到之前记录的三个书签,分别打开,可以还原到所记录时的视图。
经测试,添加书签功能正常。
6.2 代码
(1)主窗口代码
首先展示主窗口的代码,大家直接看代码里的注释就好,这里就不再赘述。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geometry;
namespace bookMark
{
public partial class frmMain : Form
{
//主窗体
public frmMain()
{
InitializeComponent(); //初始化
}
//添加书签
private void addBookMark_Click(object sender, EventArgs e)
{
frmSub bookMark = new frmSub(this); //this引用frmSub中的mainFrm
bookMark.Show(); //显示添加书签的副窗体
}
//书签功能用到的三个接口
//1.IMapBookmarks
// 属性:Bookmarks,用于得到地图文档中已经存在的所有书签对象
// 方法一:AddBookmark,用于添加书签
// 方法二:RemoveBookmark,用于删除书签
//2.ISpatialBookmark
// 属性:Name,用于定义书签的名字
// 方法:ZoomTo,用于跳转到书签位置
//3.IAOIBookmark(继承于ISpatialBookmark)
// 属性:Location,用于存储地图中感兴趣的范围
//添加函数CreatBookmark用于创建书签,内涵一个字符型参数sBookmarkName
public void createBookmark(string sBookmarkName)
{
IAOIBookmark aoiBookmark = new AOIBookmarkClass();
if (aoiBookmark != null)
{
//将地图中的范围赋给aoiBookmark中的位置属性
aoiBookmark.Location = axMapControl1.ActiveView.Extent;
//将书签名字赋给aoiBookmark的Name
aoiBookmark.Name = sBookmarkName;
}
//得到书签
IMapBookmarks bookmarks = axMapControl1.Map as IMapBookmarks;
//如果bookmarks不为空,也就是有书签
if (bookmarks != null)
{ //将aoiBookmark添加到书签
bookmarks.AddBookmark(aoiBookmark);
}
//在cmbBookMark中添加变量aoiBookmark中的名称
cmbBookMark.Items.Add(aoiBookmark.Name);
}
//选中组合框中的标签,显示所选标签范围
private void cmbBookMark_SelectedIndexChanged(object sender, EventArgs e)
{
//获得书签列表
IMapBookmarks bookmarks = axMapControl1.Map as IMapBookmarks;
IEnumSpatialBookmark enumSpatialBookmark = bookmarks.Bookmarks;
enumSpatialBookmark.Reset(); //重置标签顺序
//Next 返回下一空间书签
ISpatialBookmark spatialBookmark = enumSpatialBookmark.Next();
while (spatialBookmark != null)
{
if (cmbBookMark.SelectedItem.ToString() == spatialBookmark.Name)
{
//将选中标签范围进行显示
spatialBookmark.ZoomTo((IMap)axMapControl1.ActiveView);
axMapControl1.ActiveView.Refresh(); //刷新窗口
break;
}
spatialBookmark = enumSpatialBookmark.Next();
}
}
}
}
(2)副窗口代码
由于副窗口是要根据主窗口展示的内容进行运行的,所以肯定有两个窗口之间的交互,这里我用到了类和构造函数,不是很能理解的小伙伴建议补一下C#的相关内容,我当时也琢磨了很久。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace bookMark
{
//副窗体
public partial class frmSub : Form
{
public frmMain mainFrm; //创建一个frmMain类下的mainFrm,用于接收副窗体的内容
static int count=1; //定义一个静态整形变量count
//副窗体,用于存储书签
public frmSub(frmMain frmB) //构造函数,frmMain,frmB为两个参数
{
InitializeComponent(); //初始化
if (frmB != null) //如果frmB不是空值
{
mainFrm = frmB; //将副窗体中的内容赋给主窗体
}
txtBookMark.Text = "书签" + count;
}
//点击取消键
private void btnCancel_Click(object sender, EventArgs e)
{
//关闭窗口
this.Close();
}
//点击确定键
private void btnOK_Click_1(object sender, EventArgs e)
{
if (mainFrm != null || txtBookMark.Name == "")
{
mainFrm.createBookmark(txtBookMark.Text);
}
count++; //通过确定键的点击次数来计算书签的变化数
this.Close();
}
}
}
7.选择要素(拉框选择、按多边形选择、按圆选择、按线选择)
7.1 图标
这里先放几个会用到的图标,颜色的图标小伙伴们可以自己百度找一下,其实我有一整套的ArcGIS图标,但是还不知道咋个上传。
7.2 测试
选择要素这一部分所包含的功能有通过拉框、圆、多边形和线选择矢量数据,改变所选要素颜色和清除所选要素。
首先点开一份矢量数据。
(1)按矩形选择
(2)按圆选择
(3)按多边形选择
同时更改所选要素颜色为粉色
(4)按线选择
同时更改所选要素颜色为绿色。
(5)清除所选要素
每次选择后都有在清除,这里就不展示了。
7.3 代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
namespace selectFeature
{
//选择要素
//1.按矩形选择
//2.按圆选择
//3.按多边形选择
//4.按线选择
public partial class selectFeatureForm : Form
{
public selectFeatureForm()
{
InitializeComponent();
}
int flag = 0; //定义一个整型变量flag,用以判断情况
private void axMapControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e)
{
IGeometry pGeometry = null; //因多个条件语句中都要用到,故定义在外
ISelectionEnvironment pSelect = null; 因多个条件语句中都要用到,故定义在外
if (flag == 1)
{
//按矩形选择
pGeometry = axMapControl1.TrackRectangle(); //动态绘制矩形
pSelect = new SelectionEnvironment(); //用于调用DefaultColor,改变选择要素的显示颜色
axMapControl1.Map.SelectByShape(pGeometry, pSelect, false); //SelectedByShape方法
}
else if (flag == 2)
{
//按圆选择
pGeometry = axMapControl1.TrackCircle(); //动态绘制圆形
pSelect = new SelectionEnvironment(); //用于调用DefaultColor,改变选择要素的显示颜色
axMapControl1.Map.SelectByShape(pGeometry, pSelect, false); //SelectedByShape方法
}
else if (flag == 3)
{
//按多边形选择
pGeometry = axMapControl1.TrackPolygon(); //动态绘制多边形
pSelect = new SelectionEnvironment(); //用于调用DefaultColor,改变选择要素的显示颜色
axMapControl1.Map.SelectByShape(pGeometry, pSelect, false); //SelectedByShape方法
}
else if (flag == 4)
{
//按线选择
pGeometry = axMapControl1.TrackLine(); //动态绘制线
pSelect = new SelectionEnvironment(); //用于调用DefaultColor,改变选择要素的显示颜色
axMapControl1.Map.SelectByShape(pGeometry, pSelect, false); //SelectedByShape方法
}
//颜色
if (flag >= 1 && flag <= 4)
{
IActiveView pActive = (IActiveView)(axMapControl1.Map);
pActive.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null); //部分刷新
pSelect.DefaultColor = pColor;
}
}
IRgbColor pColor; //因两个事件都要用到pColor,故将其定义在事件之外
private void tsbColor_Click(object sender, EventArgs e)
{
//设置颜色
pColor = new RgbColor(); //实例化一个颜色变量
ColorDialog pColorDialog = new ColorDialog();
if (pColorDialog.ShowDialog() == DialogResult.OK)
{
pColor.Red = pColorDialog.Color.R;
pColor.Green = pColorDialog.Color.G;
pColor.Blue = pColorDialog.Color.B;
}
}
private void selectByRectangle_Click(object sender, EventArgs e)
{
//按矩形选择
flag = 1;
}
private void tsbSelecByCircle_Click(object sender, EventArgs e)
{
//按圆形选择
flag = 2;
}
private void tbsSelectByPolygon_Click(object sender, EventArgs e)
{
//按多边形选择
flag = 3;
}
private void tsbSelectByLine_Click(object sender, EventArgs e)
{
//按线选择
flag = 4;
}
private void tsbClear_Click(object sender, EventArgs e)
{
//清空所选元素
axMapControl1.Map.ClearSelection(); //清空
axMapControl1.ActiveView.Refresh(); //刷新,清空之后刷新视图才能看到元素被清除
}
}
}
8.属性查询
8.1界面设计
(1)地图显示界面
(2)属性查询界面
8.2 测试
加载一副矢量地图
点击查询,选择按属性查询
弹出如下界面
查询方法有四种,分别是创建一个新的选择、添加到现有选择中、从已有选择中移除和从已有选择中选择。
(1)创建一个新的选择
在查询框中输入Name = ‘雨花街道’,这里最好通过直接选择字段,运算符和字段值来组成查询语句,自己输容易出错,典型的错误是格式不对,这在平常的ArcGIS中进行查询时也是需要注意的。
点击应用
(2)添加到现有选择中
将查询方法切换到添加到现有选择中,添加龙城街道和大渔街道。该方法可以在已有选择的基础上再添加新的选择,而第一种方法,也就是创建一个新的选择只能选择一个新的要素,再选择会清除原来选择的要素。
(3)从已有选择中移除
我们选择移除雨花街道,移除结果如图所示。
(4)从已有选择中选择
顾名思义就是在已选择的要素中再进行选择,现在已选择的要素有龙城街道和大渔街道,我们选择大渔街道。
可以看到留下了大渔街道,原来的龙城街道被剔除了。
8.3 代码
显然,属性查询功能也有主副窗口,主窗口即地图,代码中命名为mapShow,副窗口即属性查询,代码中命名为attributeQuery。
(1)主窗口代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
namespace Query
{
public partial class Map : Form
{
public Map()
{
InitializeComponent();
}
private void 按属性查询ToolStripMenuItem_Click(object sender, EventArgs e)
{
//显示按属性查询窗口
attributeQuery aQ = new attributeQuery();
//将主窗体图层的属性通过子窗体窗口mainMap输入
aQ.mainMap = axMapControl1.Map;
aQ.Show();
}
}
}
(2)副窗口代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
namespace Query
{
public partial class attributeQuery : Form
{
public attributeQuery()
{
InitializeComponent();
}
//1.通过属性访问器传值
//定义一个属性pMap
private IMap pMap;
//定义一个接口 mainMap,用于接收图层属性
public IMap mainMap
{
//将主窗体中的值赋予属性pMap
set { pMap = value; }
}
//2.加载图层到combBox中
private void attributeQuery_Load(object sender, EventArgs e)
{
for(int i=0;i<pMap.LayerCount;i++)
{
//将pMap获得的图层名称添加到显示图层的组合框queryLayer中
queryLayer.Items.Add(pMap.get_Layer(i).Name);
}
//3.默认显示选中图层名称
if (queryLayer.Items.Count > 0) //如果图层不为0的话
{
queryLayer.SelectedIndex = 0; //显示选中的第一个图层
}
//向selectMethod中添加选项
selectMethod.Items.Add("创建一个新的选择");
selectMethod.Items.Add("添加到现有选择中");
selectMethod.Items.Add("从已有选择中移除");
selectMethod.Items.Add("从已有选择中选择");
//使SQL运算上方的文字随图层而变化
labMath.Text = "SELECT * FROM "+queryLayer.Text+" WHERE:";
}
//4.选中图层的同时显示相应的字段
int selectedLayer = 0; //用于判断
IField pField = null;
private void queryLayer_SelectedIndexChanged(object sender, EventArgs e)
{
//判断哪一个图层被选中
//int selectedLayer = 0; //用于判断
for (int i = 0; i < pMap.LayerCount; i++)
{
if (queryLayer.Text == pMap.get_Layer(i).Name) //如果查询框显示的图层名称是选中的图层
{
selectedLayer = i;
}
}
//获得相应图层字段
ITable pTable = pMap.get_Layer(selectedLayer) as ITable; //将所获图层的属性转换为ITable形并将其存于pTable中
IField pField = null;
//避免字段累加
listField.Items.Clear();
for (int i = 0; i < pTable.Fields.FieldCount; i++)
{
pField = pTable.Fields.get_Field(i); //将从源表中获得的字段付给变量pField
//不显示矢量和栅格形字段
if (pField.Type != esriFieldType.esriFieldTypeGeometry && pField.Type != esriFieldType.esriFieldTypeRaster)
{
//将字段显示到字段显示框中
listField.Items.Add(pField.Name);
}
}
}
private void listField_Click(object sender, EventArgs e)
{
//两个接口
//IFeatureLayer,对应矢量图层
//IRasterLayer,对应栅格图层
//强制转换
//两种方法
//IFeatureLayer pFeatureLayer = pMap.get_Layer(selectedLayer) as IFeatureLayer;
//IFeatureLayer pFeatureLayer = (IFeatureLayer)pMap.get_Layer(selectedLayer);
//将选中图层转换为IFeatureLayer格式,并赋给pFeatureLayer
IFeatureLayer pFeatureLayer = pMap.get_Layer(selectedLayer) as IFeatureLayer;
//获得对应矢量图层的字段
IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
//search表示将符合条件的查询出来
//该代码类似于打开属性表
IFeatureCursor pFeatureCursor=pFeatureClass.Search(null,false);
//用于获取唯一值
IDataStatistics pDataStatistic = new DataStatistics();
//pFeatureCursor是IFeatureCursor型,要使用pDataStatistic.Cursor,要将其转换为Cursor型
pDataStatistic.Cursor = (ICursor)pFeatureCursor;
//用于记录所取字段的顺序
int recordField = 0;
//如果选中的是第一个字段
if (listField.SelectedIndex == 0)
{
pDataStatistic.Field = pFeatureClass.Fields.get_Field(listField.SelectedIndex).Name;
recordField = listField.SelectedIndex;
}
else
{
pDataStatistic.Field = pFeatureClass.Fields.get_Field(listField.SelectedIndex+1).Name;
recordField = listField.SelectedIndex + 1;
}
System.Collections.IEnumerator pEnumrator = pDataStatistic.UniqueValues;
//避免重复
listFieldValue.Items.Clear();
while (pEnumrator.MoveNext())
{
object pObject = pEnumrator.Current;
string pFieldValue;
if (pFeatureClass.Fields.get_Field(recordField).Type == esriFieldType.esriFieldTypeString)
{
pFieldValue = "'" + pObject.ToString() + "'";
}
else
{
pFieldValue = pObject.ToString();
}
listFieldValue.Items.Add(pFieldValue);
}
}
//构建表达式
//当双击listField中的字段时,将其显示到进行SQL运算的文本框里
private void listField_DoubleClick(object sender, EventArgs e)
{
//将字段中的内容转换为字符型赋给运算SQL文本框的文本内容
txtSQL.Text = txtSQL.Text + listField.SelectedItem.ToString();
}
//当点击数学运算符时,将其显示到进行SQL运算的文本框里
private void btnXiangden_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " = ";
}
private void btnKuohao_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " <> ";
}
private void btnDayu_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " = ";
}
private void btnDayuDenyu_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " >= ";
}
private void btnXiaoyu_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " < ";
}
private void btnXiaoyudenyu_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " <= ";
}
private void btn__Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " _ ";
}
private void btnPercentage_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " % ";
}
private void btnYuankuo_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " () ";
}
//当点击逻辑运算符时,将其显示到进行SQL运算的文本框里
private void btnLike_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " LIKE ";
}
private void btnAnd_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " AND ";
}
private void btnOr_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " OR ";
}
private void btnNot_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " NOT ";
}
private void btnIs_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + " IS ";
}
//当点击字段值时,将其显示到进行SQL运算的文本框里
private void listFieldValue_SelectedIndexChanged(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + listFieldValue.Text;
}
//当点击应用的时候,进行属性查询,将所选择内容高亮显示
private void btnApplication_Click(object sender, EventArgs e)
{
SQL_Query();
}
private void SQL_Query()
{
//selectedLayer表示选中的图层
IFeatureLayer pFeatureLayer = pMap.get_Layer(selectedLayer) as IFeatureLayer;
IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
IQueryFilter pQueryFilter = new QueryFilter();
//建立SQL查询框与查询过滤器的联系
pQueryFilter.WhereClause = txtSQL.Text;
//esriSelectionResultEnum.esriSelectionResultNew包含and,add,new,substruct,XOR
//创建一个新的选择
if (selectMethod.SelectedIndex == 0)
{
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
}
//添加到现有选择中
if (selectMethod.SelectedIndex == 1)
{
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
}
//从已有选择中移除
if (selectMethod.SelectedIndex == 2)
{
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultXOR, false);
}
//从已有选择中选择
if (selectMethod.SelectedIndex == 3)
{
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultAnd, false);
}
IActiveView pActiveView = pMap as IActiveView;
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, pActiveView.Extent);
}
//当点击取消时关闭窗体
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
//当点击清除时清楚内容
private void btnClear_Click(object sender, EventArgs e)
{
txtSQL.Text = "";
}
//当点击确定时,进行属性查询功能并关闭窗口
//由于该功能是在应用的基础上添加一个关闭窗口的功能
//故将应用中的代码放到外面,写成一个方法,然后分别调用即可
private void btnOK_Click(object sender, EventArgs e)
{
SQL_Query();
this.Close();
}
}
}
9 空间查询
9.1 界面设计
(1)主界面
(2)空间查询界面
9.2 代码
这部分有点复杂,光目标图层要素的空间选择方法就有九种,我自己的数据也有点问题,就不进行测试了,直接上代码。
(1)主窗口mapForm
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;
//空间查询思路
//构建基本的地图显示窗体,也就是主窗体,命名为mapForm
//当点击查询中的空间查询时,弹出空间查询副窗体,命名为spatialQueryForm
//选择方法中默认选择从以下图层中选择要素,将其对应内容使用Items.Add添入,在图层加载时即添加
//目标图层组合框中,采用传值的方式,将主窗体中的图层信息显示到副窗体中
//两种传值方式:其一,使用属性的读写功能;其二,使用函数/方法传值
//此处选用属性的读写功能进行传值
//首先在副窗体中定义一个公共的IMap接口的mainMap,用于接收主窗体中的图层信息
//然后定义一个私有的pMap用于进行副窗体内部的读写
//最后在主窗体中将图层信息传递给副窗体 【注】先传值,再显示副窗体,否则会无法添加图层信息
//由于目标图层有多个,在副窗体中使用for循环将其加入
//源图层的图层信息添加方式也是在for循环中完成
//
namespace Query
{
public partial class mapForm : Form
{
public mapForm()
{
InitializeComponent();
}
//当点击查询中的空间查询时,弹出空间查询窗口
private void 属性查询ToolStripMenuItem_Click(object sender, EventArgs e)
{
//实例化一个空间查询窗体下的对象
spatialQueryForm spatialForm = new spatialQueryForm();
//传值
spatialForm.mainMap = axMapControl1.Map;
//显示该对象
spatialForm.Show();
}
}
}
(2)副窗口spatialQueryForm
我记得这部分代码有个地方我好像改过,后面一会儿会放一个我做的以上所有功能的一个集成代码,里面有修改后的代码,总之是进行了功能上的提升的。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.AnalysisTools;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Controls;
namespace Query
{
public partial class spatialQueryForm : Form
{
public spatialQueryForm()
{
InitializeComponent();
}
//pMap用于副窗体内部接收
private IMap pMap;
//mainMap用于主副窗体之间的值传递
public IMap mainMap
{
//写入功能
set
{
pMap = value;
}
}
public void addMethoodAndLayer()
{
//添加选择方法
cmbSelectMethod.Items.Add("从以下图层中选择要素");
cmbSelectMethod.Items.Add("添加到已选择的要素中");
cmbSelectMethod.Items.Add("从已选择的要素中移除");
cmbSelectMethod.Items.Add("从已选择的要素中选择");
cmbSelectMethod.SelectedIndex = 0;
//添加空间查询方法
cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体相交");
cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体的矩形选框相交");
cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体的索引项相交(主索引筛选器)");
cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体接触");
cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体重叠");
cmbTargetSelectedMethod.Items.Add("查询几何体与目标几何体交叉");
cmbTargetSelectedMethod.Items.Add("查询几何体在目标几何体中");
cmbTargetSelectedMethod.Items.Add("查询几何体包含在目标几何体中");
cmbTargetSelectedMethod.Items.Add("查询几何体IBE(内边界--外部)与目标几何体的关系");
cmbTargetSelectedMethod.SelectedIndex = 0;
//添加图层
for (int i = 0; i < pMap.LayerCount; i++)
{
ILayer pLayer = pMap.get_Layer(i);
//如果图层是矢量图层则对其进行添加
if (pLayer is IFeatureLayer)
{
//将图层名称添加到目标图层显示框中
clbTarget.Items.Add(pMap.get_Layer(i).Name);
//默认显示第一个图层名称
clbTarget.SelectedIndex = 0;
//将图层名称添加到源图层组合框中
cmbSourceLayer.Items.Add(pMap.get_Layer(i).Name);
//默认显示第一个图层名称
cmbSourceLayer.SelectedIndex = 0;
}
//问题一:如何判断矢量图层和栅格图层,空间查询只针对矢量图层
}
}
public void unitTrans()
{
//将英文转换为中文
string unitType = null;
unitType = pMap.MapUnits.ToString();
if (unitType == esriUnits.esriMeters.ToString())
{
lblUnit.Text = "米";
}
else if (unitType == esriUnits.esriCentimeters.ToString())
{
lblUnit.Text = "厘米";
}
else if (unitType == esriUnits.esriDecimalDegrees.ToString())
{
lblUnit.Text = "十进制度";
}
else if (unitType == esriUnits.esriDecimeters.ToString())
{
lblUnit.Text = "分米";
}
else if (unitType == esriUnits.esriFeet.ToString())
{
lblUnit.Text = "尺";
}
else if (unitType == esriUnits.esriInches.ToString())
{
lblUnit.Text = "英尺";
}
else if (unitType == esriUnits.esriKilometers.ToString())
{
lblUnit.Text = "千米";
}
else if (unitType == esriUnits.esriMiles.ToString())
{
lblUnit.Text = "英里";
}
else if (unitType == esriUnits.esriMillimeters.ToString())
{
lblUnit.Text = "毫米";
}
else if (unitType == esriUnits.esriNauticalMiles.ToString())
{
lblUnit.Text = "海里";
}
else if (unitType == esriUnits.esriUnknownUnits.ToString())
{
lblUnit.Text = "未知单位";
}
else if (unitType == esriUnits.esriPoints.ToString())
{
lblUnit.Text = "点";
}
else if (unitType == esriUnits.esriYards.ToString())
{
lblUnit.Text = "码";
}
else if (unitType == esriUnits.esriUnitsLast.ToString())
{
lblUnit.Text = "无单位";
}
}
private void spatialQueryForm_Load(object sender, EventArgs e)
{
addMethoodAndLayer();
cbSelectedFeature.Enabled = true;
txtImportBuffer.Enabled = false;
lblUnit.Enabled = false;
//将地图单位赋予标签
lblUnit.Text = pMap.MapUnits.ToString();
lblFeatureCount.Enabled = false;
unitTrans();
}
private void cbDistance_CheckedChanged(object sender, EventArgs e)
{
//如果“应用搜索范围”复选框被选中,则可输入数值
if (cbDistance.Checked == true)
{
txtImportBuffer.Enabled = true;
lblUnit.Enabled = true;
}
if (cbDistance.Checked == false)
{
txtImportBuffer.Enabled = false;
lblUnit.Enabled = false;
}
txtImportBuffer.Text = "1";
}
private void lblUnit_Click(object sender, EventArgs e)
{
MessageBox.Show(lblUnit.Text);
}
private void btnApply_Click(object sender, EventArgs e)
{
spatialQueryApply();
}
public void spatialQueryApply()
{
//ISpatialFilter的两个属性:Geometry,spatialRel
//将源图层的要素合并为一个几何体
ISpatialFilter pSpatialFilter = new SpatialFilter();
IFeatureLayer pFeatureLayer = new FeatureLayer();
//for循环得到源图层
for (int i = 0; i < pMap.LayerCount; i++)
{
//如果所得图层名字与框内选择的图层名相同
if (pMap.get_Layer(i).Name == cmbSourceLayer.SelectedItem.ToString())
{
//将该图层赋予要素图层
pFeatureLayer = pMap.get_Layer(i) as IFeatureLayer;
}
}
//当没有缓冲区时
if (txtImportBuffer.Enabled==false)
{
//搜寻所有要素
IFeatureCursor pFeatureCursor = pFeatureLayer.Search(null, false);
IFeature pFeature = pFeatureCursor.NextFeature();
//*建立拓扑关系
ITopologicalOperator pTopo;
//存放要素形状
IGeometry pGeometry = null;
while (pFeature != null)
{
if (pGeometry != null)
{
pTopo = (ITopologicalOperator)pGeometry;
pGeometry = pTopo.Union(pFeature.Shape);
}
else
{
pGeometry = pFeature.Shape;
}
pFeature = pFeatureCursor.NextFeature();
}
pSpatialFilter.Geometry = pGeometry;
}
//有缓冲区,当有要素集合时
if (pFeatureLayer.FeatureClass != null)
{
//得到所有要素
IFeatureCursor pFeatureCursor = pFeatureLayer.FeatureClass.Search(null, false);
IFeature pFeature = pFeatureCursor.NextFeature();
IGeometry pGeometry = pFeature.Shape;
//当要素不为空时
while (pFeature != null)
{
if (txtImportBuffer.Enabled == true)
{
ITopologicalOperator pItopo = pGeometry as ITopologicalOperator;
IGeometry pBuffer = pItopo.Buffer(Double.Parse(txtImportBuffer.Text));
pGeometry = pBuffer;
}
pFeature = pFeatureCursor.NextFeature();
}
pSpatialFilter.Geometry = pGeometry;
}
//对目标图层选择列表进行for循环
for (int i = 0; i < clbTarget.CheckedItems.Count; i++)
{
//对地图图层数量进行for循环
for (int j = 0; j < pMap.LayerCount; j++)
{
//如果所得到的地图图层名称等于目标图层所选图层名称
if (pMap.get_Layer(j).Name == clbTarget.CheckedItems[i].ToString())
{
//将地图图层赋予要素图层
pFeatureLayer = pMap.get_Layer(j) as IFeatureLayer;
}
}
}
//空间选择方法
switch (cmbSelectMethod.SelectedIndex)
{
case 0:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
break;
case 1:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelEnvelopeIntersects;
break;
case 2:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIndexIntersects;
break;
case 3:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelTouches;
break;
case 4:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelOverlaps;
break;
case 5:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
break;
case 6:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
break;
case 7:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
break;
case 8:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelRelation;
break;
}
//选择方法
IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
switch (cmbTargetSelectedMethod.SelectedIndex)
{
case 0:
pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
break;
case 1:
pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
break;
case 2:
pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultSubtract, false);
break;
case 3:
pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultAnd, false);
break;
}
//如果源图层被选择
IFeatureSelection pFeatureS = pFeatureLayer as IFeatureSelection;
ISelectionSet pSelectionSet = pFeatureS.SelectionSet;
ISelectionEnvironment pSelectionEnvironment = null;
lblFeatureCount.Text = "已选要素: " + pSelectionSet.Count + " 个";
IActiveView pActiveView = pMap as IActiveView;
//刷新
//pActiveView.Refresh();
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, pActiveView.Extent);
}
private void btnOK_Click(object sender, EventArgs e)
{
spatialQueryApply();
this.Close();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void cbSelectedFeature_CheckedChanged(object sender, EventArgs e)
{
if (cbSelectedFeature.Checked == true)
{
}
}
}
}
10 集成
10.1 界面设计
这个集成包含了很多窗口,有显示地图的主窗口mapForm,属性查询的窗口attributeQueryForm,属性表窗口attributeTable,书签窗口bookMarkForm,和空间查询窗口spatialQueryForm。因为我后面有做过修改,主要是名称之类的,但写的思路和前面的一样,但是为了避免争议,这里把整个的代码都再放一次。
10.2 代码
(1)主窗口mapForm
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
//IWorkspaceFactory
using ESRI.ArcGIS.Geodatabase;
//RasterWorkspaceFactory()
using ESRI.ArcGIS.DataSourcesRaster;
//IRasterLayer
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Display;
namespace gatherLast
{
//GIS系统集成
//1.数据加载:矢量数据,栅格数据;
//2.地图浏览:拉框放大、拉框缩小、平移、全图、逐级放大、逐级缩小、历史视图浏览(撤销、重做)
//3.点线面的绘制:点、线、圆、多边形、矩形、文字的绘制,能分别设置颜色、样式、大小及面填充方式;
//4.书签功能:能设置、输入书签名字,通过下拉选择框浏览书签;
//5.选择要素:拉框选择、按多边形选择、按圆选择、按线选择,并能设置选择颜色;
//6.打开属性表
//7.属性查询功能实现:界面设计,实现图层选择,字段选择,字段值唯一值显示功能,构建查询语句并实现查询功能
public partial class mapForm : Form
{
public mapForm()
{
InitializeComponent();
}
//打开矢量数据
private void btnShpOpen_Click(object sender, EventArgs e)
{
//实例化一个对象
OpenFileDialog openShipFile = new OpenFileDialog();
//打开窗体名称
openShipFile.Title = "加载矢量数据";
//允许选择多项
openShipFile.Multiselect = true;
//过滤选择矢量数据
openShipFile.Filter = "ShapeFile数据|*.shp";
//定义整型intPosition,用于存放位置
int intPosition;
//定义字符型stringFilePath和stringFileName,用于存放文件路径和文件名
string stringFilePath, stringFileName;
if (openShipFile.ShowDialog() == DialogResult.OK)
{
//定义字符型file表示打开文件中的文件名,用foreach进行访问
foreach (String file in openShipFile.FileNames)
{
//将\\的最后一个位置赋予intPosition
intPosition = file.LastIndexOf("\\");
//将intPosition前的路径存入stringFilePath中
stringFilePath = file.Substring(0, intPosition);
//将intPosition后的文件名存入stringFileName中
stringFileName = file.Substring(intPosition + 1);
//显示数据
axMapControl1.AddShapeFile(stringFilePath, stringFileName);
//弹框显示数据路径和名称
//MessageBox.Show(stringFilePath, stringFileName);
}
}
}
//打开栅格数据
private void btnRasterOpen_Click(object sender, EventArgs e)
{
//实例化对象
OpenFileDialog openRaster = new OpenFileDialog();
//命名弹窗名称
openRaster.Title=("加载栅格数据");
//允许选择多项
openRaster.Multiselect = true;
//过滤栅格数据
openRaster.Filter = "栅格文件jpg|*.jpg|栅格文件tiff|*.tiff|栅格文件img|*.img";
//定义整型位置intPosition
int intPosition;
//定义字符型路径stringFilePath和名字stringFileName
string stringFilePath, stringFileName;
if (openRaster.ShowDialog() == DialogResult.OK)
{
//foreach访问
foreach (String file in openRaster.FileNames)
{
//intPosition的1位置在最后一个\\处
intPosition = file.LastIndexOf("\\");
//路径
stringFilePath = file.Substring(0, intPosition);
//文件名
stringFileName = file.Substring(intPosition + 1);
//IWorkSpace是一个容器,存放空间数据与非空间数据
//如:FeatureClass、RasterDataset、table等
//IWorkSpace有三种类型:FileSystemWorkspace、LocalDatsbaseWorkspace,RemoteDatabaseWorkspace
//WorkSpace类不能直接实例化,必须由IWorkSpaceFactory的Create方法创建
//WorkspaceFactory:create workspace
//IRasterWorkspace Interfece:provides access to members that control a raster workspace
//含OpenRasterDataset:Opens a rasterdataset in the workspace given its name
//通过IworkSpaceFactory创建工作空间,将其在RasterWorkspaceFactory中实例化
IWorkspaceFactory prasterWorspaceFactory = new RasterWorkspaceFactory();
//创建一个栅格工作空间,将其在工作空间中的栅格文件在栅格工作空间中打开
IRasterWorkspace rasterWorkSpace = prasterWorspaceFactory.OpenFromFile(stringFilePath, 0) as IRasterWorkspace;
//将栅格空间中的空间数据打开
IRasterDataset pRasterDataset = rasterWorkSpace.OpenRasterDataset(stringFileName);
//IRasterLayer:provide access to members that create or modify a raster layer
//RasterLayerClass:raster layer source and display options
IRasterLayer pRasterLayer = new RasterLayerClass();
//在图层中创建栅格数据
pRasterLayer.CreateFromDataset(pRasterDataset);
//ILayer:provide access to members that work with all layers
//将栅格图层转换为图层形式
ILayer pLayer = pRasterLayer as ILayer;
//显示栅格图层
axMapControl1.AddLayer(pLayer);
}
}
}
//地图浏览
//用于标识功能状态
int flag;
private void btnEnlarge_Click(object sender, EventArgs e)
{
//放大
flag = 1;
axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomIn;
}
private void btnNarrow_Click(object sender, EventArgs e)
{
//缩小
flag = 2;
axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomOut;
}
private void button1_Click(object sender, EventArgs e)
{
//漫游、平移
flag = 3;
axMapControl1.MousePointer = esriControlsMousePointer.esriPointerPan;
}
//鼠标点击地图时
private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
//激活视图
IActiveView pActiveView = axMapControl1.ActiveView;
//实例框架
IEnvelope pEnvelope = new EnvelopeClass();
switch (flag)
{
case 1:
//框架为矩形
pEnvelope = axMapControl1.TrackRectangle();
//视图范围为框架选择范围
pActiveView.Extent = pEnvelope;
//刷新
pActiveView.Refresh();
break;
case 2:
//框架为矩形缩小
pEnvelope = axMapControl1.TrackRectangle();
//两倍缩小
pEnvelope.Expand(2, 2, true);
//视图范围为框架范围
pActiveView.Extent = pEnvelope;
//刷新
pActiveView.Refresh();
break;
case 3:
//漫游
axMapControl1.Pan();
break;
default:
break;
}
//***********************************************************************
//绘制地图要素
//这是在 private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)中
IGeometry pgeometry = null;
//避免与System中的point()方法混淆
IPoint point = new ESRI.ArcGIS.Geometry.Point();
//绘制点要素
//思路:
//1.在Map窗口中布设好绘制点的按钮,点大小的标签和输入的textBox
// 点颜色的标签,和一个pictureBox用于表示点击此处可以改变颜色
// 点样式的标签,用comBox来列出各类型的点样式
// 设置默认的颜色,该颜色同样适用于其他类型的绘制
// 设置默认的点的大小
// 添加点样式到comBox中
// 当点击“绘制点”时,相应的标签、大小、样式自动调到点模式下
// 当点击修改颜色图片时,可以更改颜色
// 当点击点样式时,可以显示各类点类型
// 当点击地图区域时可以进行点的绘制
if (shapeFileFlag == 1 || shapeFileFlag == 0)
{
point.X = e.mapX;
point.Y = e.mapY;
pgeometry = point as IGeometry;
//调用drawMapShape方法,以便进行点的绘制
drawMapShape(pgeometry);
}
//绘制线要素
if (shapeFileFlag == 2)
{
pgeometry = axMapControl1.TrackLine();
drawMapShape(pgeometry);
}
//绘制面要素
//圆
if (shapeFileFlag == 3)
{
pgeometry = axMapControl1.TrackCircle();
drawMapShape(pgeometry);
}
//矩形
if (shapeFileFlag == 4)
{
pgeometry = axMapControl1.TrackRectangle();
drawMapShape(pgeometry);
}
//多边形
if (shapeFileFlag == 5)
{
pgeometry = axMapControl1.TrackPolygon();
drawMapShape(pgeometry);
}
//字体
if (shapeFileFlag == 6)
{
point.X = e.mapX;
point.Y = e.mapY;
pgeometry = point as IGeometry;
drawText(pgeometry);
}
//***************************************************************************
//选择地图要素
IGeometry bmGeometry = null;
ISelectionEnvironment bmSelect = null;
if (selectFeatureFlag == 1)
{
//按矩形选择
bmGeometry = axMapControl1.TrackRectangle();
//调用颜色
bmSelect = new SelectionEnvironment();
axMapControl1.Map.SelectByShape(bmGeometry, bmSelect, false);
}
else if (selectFeatureFlag == 2)
{
//按圆选择
bmGeometry = axMapControl1.TrackCircle();
bmSelect = new SelectionEnvironment();
axMapControl1.Map.SelectByShape(bmGeometry, bmSelect, false);
}
else if (selectFeatureFlag == 3)
{
//按多边形选择
bmGeometry = axMapControl1.TrackPolygon();
bmSelect = new SelectionEnvironment();
axMapControl1.Map.SelectByShape(bmGeometry, bmSelect, false);
}
else if (selectFeatureFlag == 4)
{
//按线选择
bmGeometry = axMapControl1.TrackLine();
bmSelect = new SelectionEnvironment();
axMapControl1.Map.SelectByShape(bmGeometry, bmSelect, false);
}
//颜色
if (selectFeatureFlag >= 1 && selectFeatureFlag <= 4)
{
IActiveView bmActive = (IActiveView)(axMapControl1.Map);
//部分刷新
bmActive.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
bmSelect.DefaultColor = bmColor;
}
}
//逐级放大
private void btnEnlargeBystep_Click(object sender, EventArgs e)
{
//实例化框架为地图显示范围
IEnvelope pEnvelop = axMapControl1.Extent;
//以0.5倍放大
pEnvelop.Expand(0.5, 0.5, true);
//显示放大范围
axMapControl1.Extent = pEnvelop;
//刷新
axMapControl1.ActiveView.Refresh();
}
//逐级缩小
private void btnNarrowBystep_Click(object sender, EventArgs e)
{
//将地图范围赋予框架
IEnvelope pEnvelope = axMapControl1.Extent;
//设置缩小倍数
pEnvelope.Expand(2, 2, true);
//将缩小后的视图赋予地图
axMapControl1.Extent = pEnvelope;
//刷新
axMapControl1.ActiveView.Refresh();
}
//全图显示
private void btnAll_Click(object sender, EventArgs e)
{
axMapControl1.Extent = axMapControl1.FullExtent;
}
//用于连接各视图的范围堆
IExtentStack pExtentStack;
//上一级视图
private void btnBefore_Click(object sender, EventArgs e)
{
//判断当前视图是否可以撤回,第一个视图无法撤回
pExtentStack = axMapControl1.ActiveView.ExtentStack;
if (pExtentStack.CanUndo())
{
//撤回到上一级视图
pExtentStack.Undo();
//前一视图按钮可用
btnBefore.Enabled = true;
if (!pExtentStack.CanUndo())
{
//前一视图不可返回
btnBefore.Enabled = false;
}
}
//刷新显示
axMapControl1.ActiveView.Refresh();
}
//下一级视图
private void btnNext_Click(object sender, EventArgs e)
{
pExtentStack = axMapControl1.ActiveView.ExtentStack;
//如果可以下一级
if (pExtentStack.CanRedo())
{
//下一级
pExtentStack.Redo();
//下一级按钮可用
btnNext.Enabled = true;
//如果不可下一级视图
if (!pExtentStack.CanRedo())
{
btnNext.Enabled = false;
}
}
axMapControl1.ActiveView.Refresh();
}
//*******************************************************************
//绘制矢量要素
int shapeFileFlag = 0;
//调用颜色
//内部颜色
IRgbColor pColor;
//边框颜色
IRgbColor rColor;
//点击图片改变内部颜色
private void pictureBox1_Click_1(object sender, EventArgs e)
{
ColorDialog pColorDialog = new ColorDialog();
if (pColorDialog.ShowDialog() == DialogResult.OK)
{
pColor = new RgbColor();
pColor.Red = pColorDialog.Color.R;
pColor.Green = pColorDialog.Color.G;
pColor.Blue = pColorDialog.Color.B;
}
}
//点击图片改变边框颜色
private void pBlayout_Click(object sender, EventArgs e)
{
ColorDialog rColrDialog = new ColorDialog();
if (rColrDialog.ShowDialog() == DialogResult.OK)
{
rColor = new RgbColor();
rColor.Red = rColrDialog.Color.R;
rColor.Green = rColrDialog.Color.G;
rColor.Blue = rColrDialog.Color.B;
}
}
//设置颜色
private void setColor()
{
//当没有设置颜色时
//默认颜色为黑色
if (pColor == null)
{
pColor = new RgbColor();
pColor.Red = 0;
pColor.Green = 0;
pColor.Blue = 0;
}
if (rColor == null)
{
rColor = new RgbColor();
rColor.Red = 0;
rColor.Green = 0;
rColor.Blue = 0;
}
}
//对点的绘制
//定义一个函数用于绘制点
private void setPoint()
{
//设置相关标签名称
lblSize.Text = "点的大小:";
lblColor.Text = "点的颜色:";
lblStyle.Text = "点的样式:";
//点的默认大小
txtSize.Text = "3";
txtSize.Visible = true;
//下拉框内容的清除刷新
cmbStyle.Items.Clear();
//点的样式
cmbStyle.Items.Add("正方形");
cmbStyle.Items.Add("圆形");
cmbStyle.Items.Add("十字形");
cmbStyle.Items.Add("X形");
cmbStyle.Items.Add("棱形");
//默认选择第一个点样式
cmbStyle.SelectedIndex = 0;
}
//当点击“绘制点”时,对应的大小和样式标签进行变化
private void btnPoint_Click(object sender, EventArgs e)
{
shapeFileFlag = 1;
setPoint();
}
//当一打开程序时,便默认加载点的相关样式大小标签
private void mapForm_Load(object sender, EventArgs e)
{
setPoint();
}
//对线的绘制
//当点击绘制线时
private void btnLine_Click(object sender, EventArgs e)
{
shapeFileFlag = 2;
//修改线宽度标签
lblSize.Text = "线的宽度";
//线的样式
lblStyle.Text = "线的样式";
//线宽度输入框可见
lblColor.Text = "线的颜色";
txtSize.Visible = true;
//线宽度默认值为1
txtSize.Text = "1";
//避免点样式重复出现
cmbStyle.Items.Clear();
//添加线类型
cmbStyle.Items.Add("实线");
cmbStyle.Items.Add("短横线");
cmbStyle.Items.Add("点线");
cmbStyle.Items.Add("短横线和点线");
cmbStyle.Items.Add("短横线两点线");
cmbStyle.Items.Add("不可见的线");
cmbStyle.Items.Add("矩形边界线");
//默认线类型为实线
cmbStyle.SelectedIndex = 0;
}
//对面的绘制,含圆、矩形、多边形
//单独定义一个函数
private void setSurface()
{
//面边框粗细
lblSize.Text = "边框粗细:";
//默认显示粗细
txtSize.Text = "1";
//大小文本框可见
txtSize.Visible = true;
//类型标签可见
lblStyle.Visible = true;
//边框颜色标签可见
lblColorLayout.Visible = true;
//边框图片颜色可见
pBlayout.Visible = true;
//填充颜色
lblColor.Text = "填充颜色";
//填充样式
lblStyle.Text = "填充样式";
//清除之前的cmb下拉框中的内容
cmbStyle.Items.Clear();
//添加类型
cmbStyle.Items.Add("实心填充");
cmbStyle.Items.Add("不填充");
cmbStyle.Items.Add("空心填充");
cmbStyle.Items.Add("水平线填充");
cmbStyle.Items.Add("垂直线填充");
cmbStyle.Items.Add("45度下斜线填充");
cmbStyle.Items.Add("45度上斜线填充");
cmbStyle.Items.Add("水平十字线填充");
cmbStyle.Items.Add("45度交叉线填充");
//默认第一个样式
cmbStyle.SelectedIndex = 0;
}
//面-圆
private void btnFace_Click(object sender, EventArgs e)
{
shapeFileFlag = 3;
setSurface();
}
//面-矩形
private void btnRectangle_Click(object sender, EventArgs e)
{
shapeFileFlag = 4;
setSurface();
}
//面-多边形
private void btnMul_Click(object sender, EventArgs e)
{
shapeFileFlag = 5;
setSurface();
}
//对文字的绘制
private void drawText(IGeometry txtGeometry)
{
//存放符号
object symbol;
//存放输入符号大小
double pWith;
//存放输出符号大小
double pDouble;
//判断输入大小是否为数字
bool isNumber;
//调用颜色
setColor();
//实例化一个txtSymbol
ITextSymbol txtSymbol = new TextSymbol();
//实例化一个pFont
stdole.IFontDisp pFont = new stdole.StdFontClass() as stdole.IFontDisp;
//字符串转换为整型
isNumber = System.Double.TryParse
(txtSize.Text, System.Globalization.NumberStyles.Integer, null, out pDouble);
//如果输入的不是数字
if (isNumber == false)
{
MessageBox.Show("您输入的不是一个数字,请输入一个数字!", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
}
//如果是一个数字
else
{
//将输入的字符型数字转换为双精度
pWith = Convert.ToDouble(txtSize.Text);
//将字符大小赋予字体大小
pFont.Size = (decimal)pWith;
}
//字体颜色
txtSymbol.Color = pColor;
//字体类型
txtSymbol.Font = pFont;
symbol = txtSymbol;
axMapControl1.DrawText(txtGeometry, txtSymbol.Text, ref symbol);
}
private void btnText_Click(object sender, EventArgs e)
{
shapeFileFlag = 6;
lblSize.Text = "字体大小";
txtSize.Text = "16";
lblColor.Text = "字体颜色";
lblStyle.Visible = false;
cmbStyle.Visible = false;
}
private void drawMapShape(IGeometry drawGeometry)
{
//定义符号初始值为空
//symbol用于存放各种符号
object symbol = null;
//调用默认符号颜色
setColor();
//存放符号大小
double pWith;
//输出对应大小的符号
double pOutput;
//判断是否为数字
bool isNumber;
//将输入的文本数字进行转换
isNumber = System.Double.TryParse
(txtSize.Text, System.Globalization.NumberStyles.Integer, null, out pOutput);
//如果输入大小不是数字,进行提示
if (isNumber == false)
{
MessageBox.Show
("这不是一个数字,请输入一个数字!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
//如果输入是一个数字
else
{
//将文本型的字符大小转换为双精度
pWith = Convert.ToDouble(txtSize.Text);
//如果geometry的一个类型是esri中的点
if (drawGeometry.GeometryType == esriGeometryType.esriGeometryPoint)
{
//存放点符号类型
ISimpleMarkerSymbol pSimplePoint = new SimpleMarkerSymbol();
//点符号默认颜色为黑色
pSimplePoint.Color = pColor;
//将输入转换后的符号大小赋予点符号
pSimplePoint.Size = pWith;
//设置对应的符号类型
if (cmbStyle.SelectedItem.ToString() == "正方形")
{
pSimplePoint.Style = esriSimpleMarkerStyle.esriSMSSquare;
}
if (cmbStyle.SelectedItem.ToString() == "圆")
{
pSimplePoint.Style = esriSimpleMarkerStyle.esriSMSCircle;
}
if (cmbStyle.SelectedItem.ToString() == "十字形")
{
pSimplePoint.Style = esriSimpleMarkerStyle.esriSMSCross;
}
if (cmbStyle.SelectedItem.ToString() == "X形")
{
pSimplePoint.Style = esriSimpleMarkerStyle.esriSMSX;
}
if (cmbStyle.SelectedItem.ToString() == "棱形")
{
pSimplePoint.Style = esriSimpleMarkerStyle.esriSMSDiamond;
}
symbol = pSimplePoint;
}
else if (drawGeometry.GeometryType == esriGeometryType.esriGeometryLine)
{
//存放线符号类型
ISimpleLineSymbol pSimpleLine = new SimpleLineSymbol();
//存放线宽度
pSimpleLine.Width = pWith;
//设置线默认颜色为黑色
pSimpleLine.Color = pColor;
if (cmbStyle.SelectedItem.ToString() == "实线")
{
pSimpleLine.Style = esriSimpleLineStyle.esriSLSSolid;
}
else if (cmbStyle.SelectedItem.ToString() == "短横线")
{
pSimpleLine.Style = esriSimpleLineStyle.esriSLSDash;
}
else if (cmbStyle.SelectedItem.ToString() == "点线")
{
pSimpleLine.Style = esriSimpleLineStyle.esriSLSDashDot;
}
else if (cmbStyle.SelectedItem.ToString() == "短横线和点线")
{
pSimpleLine.Style = esriSimpleLineStyle.esriSLSDashDot;
}
else if (cmbStyle.SelectedItem.ToString() == "不可见的线")
{
pSimpleLine.Style = esriSimpleLineStyle.esriSLSNull;
}
else if (cmbStyle.SelectedItem.ToString() == "矩形边界线")
{
pSimpleLine.Style = esriSimpleLineStyle.esriSLSInsideFrame;
}
symbol = pSimpleLine;
}
else
{
//存放面符号类型
ISimpleFillSymbol pSimpleSurface = new SimpleFillSymbol();
//面颜色
pSimpleSurface.Color = pColor;
//存放面边框
ILineSymbol pSurfaceLine=new SimpleLineSymbol();
//面边框宽度
pSurfaceLine.Width = pWith;
//面边框颜色
pSurfaceLine.Color = rColor;
//将面边框赋给SimpleFillSymbol下的OutLine
pSimpleSurface.Outline = pSurfaceLine;
if (cmbStyle.SelectedItem.ToString() == "实心填充")
{
pSimpleSurface.Style = esriSimpleFillStyle.esriSFSSolid;
}
if (cmbStyle.SelectedItem.ToString() == "不填充")
{
pSimpleSurface.Style = esriSimpleFillStyle.esriSFSNull;
}
if (cmbStyle.SelectedItem.ToString() == "空心填充")
{
pSimpleSurface.Style = esriSimpleFillStyle.esriSFSHollow;
}
if (cmbStyle.SelectedItem.ToString() == "水平线填充")
{
pSimpleSurface.Style = esriSimpleFillStyle.esriSFSHorizontal;
}
if (cmbStyle.SelectedItem.ToString() == "垂直线填充")
{
pSimpleSurface.Style = esriSimpleFillStyle.esriSFSVertical;
}
if (cmbStyle.SelectedItem.ToString() == "45度下斜线填充")
{
pSimpleSurface.Style = esriSimpleFillStyle.esriSFSForwardDiagonal;
}
if (cmbStyle.SelectedItem.ToString() == "45度上斜线填充")
{
pSimpleSurface.Style = esriSimpleFillStyle.esriSFSBackwardDiagonal;
}
if (cmbStyle.SelectedItem.ToString() == "水平十字线填充")
{
pSimpleSurface.Style = esriSimpleFillStyle.esriSFSCross;
}
if (cmbStyle.SelectedItem.ToString() == "45度交叉线填充")
{
pSimpleSurface.Style = esriSimpleFillStyle.esriSFSDiagonalCross;
}
symbol = pSimpleSurface;
}
axMapControl1.DrawShape(drawGeometry, ref symbol);
}
}
//在地图上移动鼠标
private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
{
if (shapeFileFlag >= 1 && shapeFileFlag <= 6)
{
axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
}
}
//*******************************************************************************
//添加书签
private void 添加书签ToolStripMenuItem_Click(object sender, EventArgs e)
{
//传参
bookMarkForm bookMark = new bookMarkForm(this);
//显示书签窗体
bookMark.Show();
}
//定义一个函数用于创建书签
public void createBookMark(string BMName)
{
IAOIBookmark aoiBM = new AOIBookmarkClass();
if (aoiBM != null)
{
//将所需标签范围赋给aoiBM中的位置
aoiBM.Location = axMapControl1.ActiveView.Extent;
//将书签名称赋予aoiBM中的name
aoiBM.Name = BMName;
}
//获得书签
IMapBookmarks bookMarks = axMapControl1.Map as IMapBookmarks;
//如果有书签
if (bookMarks != null)
{
//将aoiBM添加到书签
bookMarks.AddBookmark(aoiBM);
}
//在管理书签中添加书签名
tscHeldMark.Items.Add(aoiBM.Name);
}
//选中已有标签,显示标签的范围
private void tscHeldMark_SelectedIndexChanged(object sender, EventArgs e)
{
IMapBookmarks bookMarks = axMapControl1.Map as IMapBookmarks;
IEnumSpatialBookmark enumSpatialBookMark = bookMarks.Bookmarks;
//重置标签顺序
enumSpatialBookMark.Reset();
//返回下一标签
ISpatialBookmark spatialBookMark = enumSpatialBookMark.Next();
while (spatialBookMark != null)
{
if (tscHeldMark.SelectedItem.ToString() == spatialBookMark.Name)
{
//显示标签范围
spatialBookMark.ZoomTo((IMap)axMapControl1.ActiveView);
//刷新窗口
axMapControl1.ActiveView.Refresh();
break;
}
spatialBookMark = enumSpatialBookMark.Next();
}
}
//*****************************************************************************
//选择要素:按矩形选择;按圆选择;按多边形选择;按线选择
//判断
int selectFeatureFlag = 0;
private void tsbRectabgle_Click(object sender, EventArgs e)
{
//按矩形选择
selectFeatureFlag = 1;
}
private void tsbCircle_Click(object sender, EventArgs e)
{
//按圆形选择
selectFeatureFlag = 2;
}
private void tsbPolygon_Click(object sender, EventArgs e)
{
//按多边形选择
selectFeatureFlag = 3;
}
private void tsbLine_Click(object sender, EventArgs e)
{
//按线选择
selectFeatureFlag = 4;
}
private void tsbClear_Click(object sender, EventArgs e)
{
//清除所选要素
axMapControl1.Map.ClearSelection();
//刷新
axMapControl1.ActiveView.Refresh();
}
IRgbColor bmColor;
private void tsbColor_Click(object sender, EventArgs e)
{
//设置颜色
bmColor = new RgbColor();
ColorDialog bmColorDialog = new ColorDialog();
if (bmColorDialog.ShowDialog() == DialogResult.OK)
{
bmColor.Red = bmColorDialog.Color.R;
bmColor.Green = bmColorDialog.Color.G;
bmColor.Blue = bmColorDialog.Color.B;
}
}
//****************************************
//打开属性表
ILayer aTLayer = null;
private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{
//当点击鼠标右键
if (e.button == 2)
{
//MessageBox.Show("yeach!");
esriTOCControlItem aTItem = esriTOCControlItem.esriTOCControlItemNone;
IBasicMap aTBasicMap = null;
object unk = null, data = null;
axTOCControl1.HitTest(e.x, e.y, ref aTItem, ref aTBasicMap, ref aTLayer, ref unk, ref data);
//如果点击的是图层
if (aTItem == esriTOCControlItem.esriTOCControlItemLayer)
{
//将屏幕上的点转换到坐标上
System.Drawing.Point p = new System.Drawing.Point();
p.X = e.x;
p.Y = e.y;
//显示菜单
contextMenuStrip1.Show(axTOCControl1, p);
}
}
}
private void 打开属性表ToolStripMenuItem_Click(object sender, EventArgs e)
{
attributeTable aTShow = new attributeTable();
aTShow.createAT(aTLayer);
aTShow.Show();
}
//********************************************************************
//属性查询
private void 属性查询ToolStripMenuItem_Click(object sender, EventArgs e)
{
attributeQueryForm aQshow = new attributeQueryForm();
aQshow.mainMap = axMapControl1.Map;
aQshow.Show();
}
//****************************************************************
private void 空间查询ToolStripMenuItem_Click(object sender, EventArgs e)
{
spatialQueryForm spQF = new spatialQueryForm();
spQF.mainMap = axMapControl1.Map;
spQF.Show();
}
//空间查询路线
//1.设置空间查询界面
//2.添加选择方法
//3.添加空间选择方法
//4.添加目标图层
//5.添加源图层
//6.当勾选应用搜索距离时listbox和lable可用
//7.显示地图单位,并进行中英文转换
//8.当点击取消按钮,关闭窗口
//9.当点击确定按钮,进行空间查询,并关闭窗口
//10.当点击应用按钮,进行空间查询,不关闭窗口
//两个问题:(1).如何在已选择要素中进行要素查询;(2).如何在缓冲区中进行查询(已解决)
}
}
(2)属性查询的窗口attributeQueryForm
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
namespace gatherLast
{
public partial class attributeQueryForm : Form
{
private IMap pMap;
public IMap mainMap
{
set { pMap = value; }
}
public attributeQueryForm()
{
InitializeComponent();
}
//加载图层名称
private void attributeQueryForm_Load(object sender, EventArgs e)
{
for (int i = 0; i < pMap.LayerCount; i++)
{
cmbQueryLayer.Items.Add(pMap.get_Layer(i).Name);
}
//默认显示第一个图层名称
if (cmbQueryLayer.Items.Count > 0)
{
cmbQueryLayer.SelectedIndex = 0;
}
//添加查询方法
cmbQueryMethod.Items.Add("创建一个新的选择");
cmbQueryMethod.Items.Add("添加到现有选择中");
cmbQueryMethod.Items.Add("从已有选择中移除");
cmbQueryMethod.Items.Add("从已有选择中选择");
//默认选择第一个方法
cmbQueryMethod.SelectedIndex = 0;
//运算框上方文字变化
lblSQL.Text = "SELECT * FROM " + cmbQueryLayer.Text + " WHERES:";
}
//选中图层显示字段
int selectedLayer = 0;
IField queryField = null;
private void cmbQueryLayer_SelectedIndexChanged(object sender, EventArgs e)
{
//判断选中图层
for (int i = 0; i < pMap.LayerCount; i++)
{
if (cmbQueryLayer.Text == pMap.get_Layer(i).Name)
selectedLayer = i;
}
//获取选中图层字段
ITable pTabel = pMap.get_Layer(selectedLayer) as ITable;
IField pField = null;
//避免累加
listField.Items.Clear();
for (int i = 0; i < pTabel.Fields.FieldCount; i++)
{
pField = pTabel.Fields.get_Field(i);
//不显示矢量和栅格型字段
if (pField.Type != esriFieldType.esriFieldTypeGeometry && pField.Type != esriFieldType.esriFieldTypeRaster)
listField.Items.Add(pField.Name);
}
}
private void listField_Click(object sender, EventArgs e)
{
IFeatureLayer pFeatryeLayer = pMap.get_Layer(selectedLayer) as IFeatureLayer;
//获取字段
IFeatureClass pFeatureClass = pFeatryeLayer.FeatureClass;
//查询符合条件的字段值
IFeatureCursor pFeatureCursor = pFeatureClass.Search(null, false);
//获取唯一值
IDataStatistics pDataStatistic = new DataStatistics();
pDataStatistic.Cursor = (ICursor)pFeatureCursor;
//记录所取字段顺序
int recordField = 0;
//如果选中第一个字段
if (listField.SelectedIndex == 0)
{
pDataStatistic.Field = pFeatureClass.Fields.get_Field(listField.SelectedIndex).Name;
recordField = listField.SelectedIndex;
}
else
{
pDataStatistic.Field = pFeatureClass.Fields.get_Field(listField.SelectedIndex + 1).Name;
recordField = listField.SelectedIndex + 1;
}
System.Collections.IEnumerator pEnumerator = pDataStatistic.UniqueValues;
listFieldValue.Items.Clear();
while (pEnumerator.MoveNext())
{
object pO = pEnumerator.Current;
string pFieldValue;
if (pFeatureClass.Fields.get_Field(recordField).Type == esriFieldType.esriFieldTypeString)
pFieldValue = "'" + pO.ToString() + "'";
else
pFieldValue = pO.ToString();
listFieldValue.Items.Add(pFieldValue);
}
}
//显示表达式符号表达式
private void listField_DoubleClick(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + listField.SelectedItem.ToString();
}
private void btnDengyu_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "=";
}
private void btnDX_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "<>";
}
private void btnDayu_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + ">";
}
private void btnDayuDengyu_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + ">=";
}
private void btnXiaoyu_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "<";
}
private void btnXioayuDengyu_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "<=";
}
private void btnXiahuaxian_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "_";
}
private void btnPercentage_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "%";
}
private void btnKuohao_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "%";
}
private void btnLike_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "LIKE";
}
private void btnAnd_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "AND";
}
private void btnOr_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "OR";
}
private void btnNot_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "NOT";
}
private void btnIs_Click(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + "IS";
}
private void listFieldValue_SelectedIndexChanged(object sender, EventArgs e)
{
txtSQL.Text = txtSQL.Text + listFieldValue.Text;
}
//构建表达式
private void sqlQuery()
{
IFeatureLayer pFeatureLayer = pMap.get_Layer(selectedLayer) as IFeatureLayer;
IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
IQueryFilter pQueryFilter = new QueryFilter();
//建立查询框与过滤器的关系
pQueryFilter.WhereClause = txtSQL.Text;
//属性选择方法
//创建一个新的选择
if (cmbQueryMethod.SelectedIndex == 0)
{
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
}
//添加到已有选择中
if (cmbQueryMethod.SelectedIndex == 1)
{
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
}
//从已有选择中移除
if (cmbQueryMethod.SelectedIndex == 2)
{
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultXOR,false);
}
//从已有选择中选择
if (cmbQueryMethod.SelectedIndex == 3)
{
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultAnd, false);
}
IActiveView pActiveView = pMap as IActiveView;
//局部刷新
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphicSelection, null, pActiveView.Extent);
pActiveView.Refresh();
}
//当点击“确定”时,应用且关闭
private void btnOK_Click(object sender, EventArgs e)
{
sqlQuery();
this.Close();
}
private void btnApply_Click(object sender, EventArgs e)
{
sqlQuery();
}
private void btnClear_Click(object sender, EventArgs e)
{
txtSQL.Text = "";
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
(3)属性表窗口attributeTable
做的有点粗糙,大概是这个样子。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
namespace gatherLast
{
public partial class attributeTable : Form
{
public attributeTable()
{
InitializeComponent();
}
//构造函数
public void createAT(ILayer aTLayer)
{
//MessageBox.Show(aTLayer.Name);
//创建图层虚拟表
DataTable pDataTable = new DataTable(aTLayer.Name);
//将图层中的表进行转移
ITable pTable = aTLayer as ITable;
//属性字段
IField pField = null;
//创建表中数据列
DataColumn pDataColumn;
//使用for将原表中的字段分别赋予新表
for (int i = 0; i < pTable.Fields.FieldCount; i++)
{
pField = pTable.Fields.get_Field(i);
//MessageBox.Show(pField.Name);
pDataColumn = new DataColumn(pField.Name);
pDataColumn.Caption = pField.Name;
pDataTable.Columns.Add(pDataColumn);
}
//显示新表中的内容
ICursor pCur = pTable.Search(null, false);
//行
DataRow pDataRow = null;
//获取行
IRow pRow = pCur.NextRow();
while (pRow != null)
{
//将虚拟表中的行赋给行
pDataRow = pDataTable.NewRow();
for (int i=0; i < pTable.Fields.FieldCount; i++)
{
pDataRow[i] = pRow.get_Value(i);
}
pDataTable.Rows.Add(pDataRow);
pRow = pCur.NextRow();
}
//清空
pRow = null;
pField = null;
//接受数据源
dataGridView1.DataSource = pDataTable;
transShape(aTLayer);
//显示数据
this.Text = "属性表 [" + aTLayer.Name + "] 记录数: " + pDataTable.Rows.Count;
}
//类型转换
public static string transShape(ILayer tranLayer)
{
object tLayer = null;
IFeatureLayer pFeature = tranLayer as IFeatureLayer;
switch (pFeature.FeatureClass.ShapeType)
{
case esriGeometryType.esriGeometryPoint:
return "点";
case esriGeometryType.esriGeometryLine:
return "线";
case esriGeometryType.esriGeometryPolygon:
return "面";
default:
return " ";
}
}
private void attributeTable_Load(object sender, EventArgs e)
{
}
}
}
(4)书签窗口bookMarkForm
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace gatherLast
{
public partial class bookMarkForm : Form
{
//传参
public mapForm mainForm;
//定义静态变量count
static int count = 1;
public bookMarkForm(mapForm frmA)
{
InitializeComponent();
//如果frmA不是空值
if (frmA != null)
{
//将副窗体中的内容赋给主窗体,也就是将书签标志地图赋给主
mainForm = frmA;
}
//默认显示
txtBM.Text = "书签" + count;
}
//点击确定键
private void btnOK_Click(object sender, EventArgs e)
{
if (mainForm != null||txtBM.Name=="")
{
mainForm.createBookMark(txtBM.Text);
}
//通过确定键的次数计算书签数
count++;
//关闭窗口
this.Close();
}
//点击取消键
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
(5)空间查询窗口spatialQueryForm
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
namespace gatherLast
{
public partial class spatialQueryForm : Form
{
//用于副窗体内部传参
private IMap pMap;
//用于主副窗体传参
public IMap mainMap
{
set { pMap = value; }
}
public spatialQueryForm()
{
InitializeComponent();
}
private void cbDistance_CheckedChanged(object sender, EventArgs e)
{
if (cbDistance.Checked == true)
{
txtBuffer.Enabled = true;
lblUnit.Enabled = true;
}
if (cbDistance.Checked == false)
{
txtBuffer.Enabled = false;
lblUnit.Enabled = false;
}
}
private void spatialQueryForm_Load(object sender, EventArgs e)
{
//添加选择方法
cmbSelectedMethod.Items.Add("从以下图层中选择要素");
cmbSelectedMethod.Items.Add("添加到已选择的要素中");
cmbSelectedMethod.Items.Add("从已选择的要素中移除");
cmbSelectedMethod.Items.Add("从已选择的要素中选择");
//默认选择第一个选择方法
cmbSelectedMethod.SelectedIndex = 0;
//添加空间查询方法
cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体相交");
cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体矩形选框相交");
cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体索引项相交");
cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体接触");
cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体重叠");
cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体交叉");
cmbSpatialSelectMethod.Items.Add("查询几何体位于目标几何体中");
cmbSpatialSelectMethod.Items.Add("查询几何体含于目标几何体中");
cmbSpatialSelectMethod.Items.Add("查询几何体与目标几何体的IBE(内边界-外部)关系");
//默认
cmbSpatialSelectMethod.SelectedIndex = 0;
//添加目标图层和源图层,需要将空间查询窗体与地图窗体进行联系,传值
for (int i = 0; i < pMap.LayerCount; i++)
{
//判断是否为矢量图层
ILayer pLayer = pMap.get_Layer(i);
if (pLayer is IFeatureLayer)
{
clbTargetLayer.Items.Add(pMap.get_Layer(i).Name);
clbTargetLayer.SelectedIndex = 0;
cmbSourceLayer.Items.Add(pMap.get_Layer(i).Name);
cmbSourceLayer.SelectedIndex = 0;
}
}
txtBuffer.Text = "1.00";
lblFeatureCount.Text = "已选要素: 0 个";
//得到地图单位
lblUnit.Text = pMap.MapUnits.ToString();
//中英文转换
string unitType = null;
unitType = pMap.MapUnits.ToString();
if (unitType == esriUnits.esriUnknownUnits.ToString())
{
lblUnit.Text = "未知单位";
}
else if (unitType == esriUnits.esriMeters.ToString())
{
lblUnit.Text = "米";
}
else if (unitType == esriUnits.esriDecimalDegrees.ToString())
{
lblUnit.Text = "十进度制";
}
}
private void btnOK_Click(object sender, EventArgs e)
{
spatialQueryWay();
this.Close();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnApply_Click(object sender, EventArgs e)
{
spatialQueryWay();
}
//查询方法,便于在应用和确定中调用
public void spatialQueryWay()
{
//调用ISpatialFilter下的Geometry和SpatialRel
ISpatialFilter pSpatialFilter = new SpatialFilter();
//要素图层
IFeatureLayer pFeatureLayer = new FeatureLayer();
//for循环得到源图层
for (int i = 0; i < pMap.LayerCount; i++)
{
if (pMap.get_Layer(i).Name == cmbSourceLayer.SelectedItem.ToString())
{
pFeatureLayer = pMap.get_Layer(i) as IFeatureLayer;
}
}
if (pFeatureLayer.FeatureClass!=null)
{
//当没有缓冲区时
if (txtBuffer.Enabled==true)
{
//游标,搜寻图层所有要素
//(null,false)表示搜寻看所有要素
IFeatureCursor pFeatureCursor = pFeatureLayer.Search(null, false);
//NextFeature获得所有要素
IFeature pFeature = pFeatureCursor.NextFeature();
//建立拓扑关系
ITopologicalOperator pTO;
IGeometry pGeometry = null;
//目的:将所有的要素集合在一个几何上,以便于调用ISpatialFilter中的Geometry
//当要素不为空时
//while循环,满足条件进入循环,直到条件不满足才跳出循环
while (pFeature != null)
{
//几何不为空时
if (pGeometry != null)
{
//为几何建立拓扑关系
pTO = pGeometry as ITopologicalOperator;
pGeometry = pTO.Union(pFeature.Shape);
}
//几何为空时,也就是图层只有一个几何时
else
{
//只有一个几何,无需建立拓扑关系
pGeometry = pFeature.Shape;
}
//避免死循环
pFeature = pFeatureCursor.NextFeature();
}
//得到具有拓扑关系的几何集合
pSpatialFilter.Geometry = pGeometry;
}
//当有缓冲区时
if (txtBuffer.Enabled == true)
{
if (pFeatureLayer.FeatureClass != null)
{
//游标,搜寻图层所有要素
//(null,false)表示搜寻看所有要素
IFeatureCursor pFeatureCursor = pFeatureLayer.FeatureClass.Search(null, false);
//NextFeature获得所有要素
IFeature pFeature = pFeatureCursor.NextFeature();
IGeometry pGeometry = pFeature.Shape;
//目的:将所有的要素集合在一个几何上,以便于调用ISpatialFilter中的Geometry
//当要素不为空时
//while循环,满足条件进入循环,直到条件不满足才跳出循环
while (pFeature != null)
{
//为几何建立拓扑关系
if (pGeometry != null)
{
ITopologicalOperator pTO;
pTO = pGeometry as ITopologicalOperator;
IGeometry pBuffer = pTO.Buffer(Double.Parse(txtBuffer.Text));
pGeometry = pBuffer;
}
//避免死循环
pFeature = pFeatureCursor.NextFeature();
}
//得到具有拓扑关系的几何集合
pSpatialFilter.Geometry = pGeometry;
}
}
}
//空间查询方法
switch (cmbSpatialSelectMethod.SelectedIndex)
{
case 0:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
break;
case 1:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelEnvelopeIntersects;
break;
case 2:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIndexIntersects;
break;
case 3:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelTouches;
break;
case 4:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelOverlaps;
break;
case 5:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
break;
case 6:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
break;
case 7:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
break;
case 8:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelRelation;
break;
}
//得到目标图层
for (int i = 0; i < clbTargetLayer.CheckedItems.Count; i++)
{
for (int j = 0; j < pMap.LayerCount; j++)
{
if (pMap.get_Layer(j).Name == clbTargetLayer.CheckedItems[i].ToString())
{
//要素图层
pFeatureLayer = pMap.get_Layer(j) as IFeatureLayer;
}
}
}
IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
//选择方法
switch (cmbSelectedMethod.SelectedIndex)
{
case 0:
pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
break;
case 1:
pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
break;
case 2:
pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultSubtract, false);
break;
case 3:
pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultAnd, false);
break;
}
IFeatureSelection pFeatureS = pFeatureLayer as IFeatureSelection;
ISelectionSet pSelectionSet = pFeatureS.SelectionSet;
//显示所选要素个数
lblFeatureCount.Text = "已选要素: " + pSelectionSet.Count + " 个";
//刷新
IActiveView pActiveView = pMap as IActiveView;
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, pActiveView.Extent);
//pActiveView.Refresh();
}
}
}
11 总结
基于C#的ArcEngine二次开发是ArcGIS中很有趣的一部分,C#本身是面向对象语言,也有相关帮助文档查看,很多功能都是现有的,可以通过帮助文档查找,而我们要做的就是将这些功能组装成我们需要的产品。可能做出来没有WebGIS开发那么高大上,但我觉得这里面的学习思路是很值得借鉴的,至少,通过这一部分的研究学习,更了解了ArcGIS的运作原理。
我也在努力完善这方面的开发知识,总之,没有白走的路,希望这篇文章能对你有用,同时感谢看到这里的您,给个赞再走吧(✯ᴗ✯)。