根据你的解决方案,开发一个应用型GIS系统,该系统需要具备以下功能:
a. 打开地图文档功能(地图文档位于AirQuality文件夹下)。(3分)
b. 退出程序并保存地图文档功能。(3分)
c. 在地图上点击,选择一个监测站点,并显示该监测站点的属性信息。(3分)
d. 在监测站点列表中选择一个监测站点后,在地图上高亮显示,缩放至该监测站点,并显示该监测站点的属性信息。(3分)
e. 在地图上选择一个多边形,统计该多边形内部的监测站点内数量,并高亮显示。(3分)
f. 将Excel中的数据匹配到监测站点。(3分)
g. 在地图上显示北京各个区县的名称。(3分)
h. 为北京各个区县匹配一个符号。(3分)
i. 导出北京区县图层为一个新的数据。(3分)
j. 在监测站点图层添加一个新站点。(5分)
主窗体界面:
界面详情请查看:https://blog.csdn.net/H48662654/article/details/102980068
主窗体代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.DataSourcesOleDB;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.SystemUI;
using System.Data.OleDb;
namespace Ex1
{
public partial class Form1 : Form
{
public Form1()
{
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
InitializeComponent();
axTOCControl1.SetBuddyControl(axMapControl1);
}
#region 输入输出模块
//文件路径
string path = null;
private void 打开文档ToolStripMenuItem_Click(object sender, EventArgs e)
{
openFileDialog1.Title = "打开文件";
openFileDialog1.Filter = "ArcMap Document(*.mxd)|*.mxd";
openFileDialog1.Multiselect = false;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
path = openFileDialog1.FileName;
axMapControl1.LoadMxFile(path);
}
}
private void 保存文档ToolStripMenuItem_Click(object sender, EventArgs e)
{
IMxdContents content = axMapControl1.Map as IMxdContents;
IMapDocument mapDocumnet = new MapDocumentClass();
mapDocumnet.Open(path);
mapDocumnet.ReplaceContents(content);
mapDocumnet.Save();
MessageBox.Show("文档已保存");
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
//窗体关闭自动保存
保存文档ToolStripMenuItem_Click(sender, e);
}
private void 导出图层ToolStripMenuItem_Click(object sender, EventArgs e)
{
//导出北京区县图层为Shapefile文件
saveFileDialog1.Title = "导出图层";
saveFileDialog1.Filter = "LayerFile(*.lyr)|*.lyr";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
ILayerFile layerFile = new LayerFileClass();
layerFile.New(saveFileDialog1.FileName);
ILayer layer = axMapControl1.get_Layer(1);
layerFile.ReplaceContents(layer);
layerFile.Save();
MessageBox.Show("保存成功");
}
}
#endregion
#region 属性查询模块
//点击站点显示属性表
private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
axMapControl1.Map.ClearSelection();
//在地图上点击 点作缓冲分析,即对该点进行扩大 方便接下来的空间查询
IPoint pt = new PointClass();
pt = axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
ITopologicalOperator topo = pt as ITopologicalOperator;
IGeometry buffer = topo.Buffer(0.01) as IGeometry;
//在检测站点图层上进行空间查询
IFeatureLayer layer = axMapControl1.get_Layer(0) as IFeatureLayer;
IFeatureSelection featureSelection = layer as IFeatureSelection;
ISpatialFilter filter = new SpatialFilterClass();
//查询集合体设为缓冲点
filter.Geometry = buffer;
filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
//高亮显示
featureSelection.SelectFeatures(filter, esriSelectionResultEnum.esriSelectionResultNew, true);
axMapControl1.Refresh();
ISelectionSet set = featureSelection.SelectionSet;
//将查询属性的ID值作为属性表的构造函数
IEnumIDs ids = set.IDs;
//显示属性表
属性表 table = new 属性表(ids,layer);
table.Show();
}
private void 开启状态ToolStripMenuItem_Click(object sender, EventArgs e)
{
axMapControl1.OnMouseDown += axMapControl1_OnMouseDown;
}
private void 关闭状态ToolStripMenuItem_Click(object sender, EventArgs e)
{
axMapControl1.OnMouseDown -= axMapControl1_OnMouseDown;
}
//在属性表中选择站点缩放到对应站点
private void 打开监测站列表ToolStripMenuItem_Click(object sender, EventArgs e)
{
//根据情况调用不同的构造函数
IFeatureLayer layer = axMapControl1.get_Layer(0) as IFeatureLayer;
属性表 table = new 属性表(layer,axMapControl1.ActiveView);
table.Show();
}
//在地图上画多边形统计数量
private void draw(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
axMapControl1.Map.ClearSelection();
IFeatureLayer layer = axMapControl1.get_Layer(0) as IFeatureLayer;
IFeatureSelection featureSelection = layer as IFeatureSelection;
ISpatialFilter spatialFilter = new SpatialFilterClass();
//设置空间查询条件为相交
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
//查询几何体为从地图上获取的多边形
spatialFilter.Geometry = axMapControl1.TrackPolygon();
//高亮选择
featureSelection.SelectFeatures(spatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
ISelectionSet set = featureSelection.SelectionSet;
axMapControl1.Refresh();
IEnumIDs ids = set.IDs;
int id = ids.Next();
int n = 0;
//通过ID统计个数
while(id !=-1)
{
n++;
id = ids.Next();
}
MessageBox.Show("该区域共有" + n + "个检测站");
}
private void 开启状态ToolStripMenuItem1_Click(object sender, EventArgs e)
{
axMapControl1.OnMouseDown += draw;
}
private void 关闭状态ToolStripMenuItem1_Click(object sender, EventArgs e)
{
axMapControl1.OnMouseDown -= draw;
}
//Excel数据匹配到站点
private void excel数据匹配站点ToolStripMenuItem_Click(object sender, EventArgs e)
{
openFileDialog1.Title = "打开Excel表";
openFileDialog1.Filter = "Excel2003(*.xls)|*.xls";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//Excel路径
string path = openFileDialog1.FileName;
//数据库连接字符串
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + path + ";" + "Extended Properties='Excel 4.0;HDR=NO;IMEX=1';";
//表名
string sheetName = "Sheet1";
//选择语句
string select = "Select * from [" + sheetName + "$]";
//创建连接
OleDbConnection conn = new OleDbConnection(strConn);
//开启连接
conn.Open();
//创建适配器
OleDbDataAdapter adapter = new OleDbDataAdapter(select, strConn);
DataTable dt = new DataTable();
//填充数据
adapter.Fill(dt);
//关闭连接
conn.Close();
//显示属性表
属性表 table = new 属性表(dt, axMapControl1.get_Layer(0) as IFeatureLayer);
table.Show();
}
}
#endregion
#region 画图
//显示区县名称
private void 区县名称ToolStripMenuItem_Click(object sender, EventArgs e)
{
IFeatureLayer layer = axMapControl1.get_Layer(1) as IFeatureLayer;
IFeatureCursor cursor = layer.FeatureClass.Search(null, true);
IFeature feature = cursor.NextFeature();
while(feature != null)
{
IPoint pt = new PointClass();
IGeometry geo = feature.Shape;
IGeometry5 geo5 = geo as IGeometry5;
//以要素中心的位置作为名称文本显示的位置
pt.X = geo5.CentroidEx.X;
pt.Y = geo5.CentroidEx.Y;
ITextElement ele = new TextElementClass();
ele.Symbol = new TextSymbol();
//获取值
ele.Text = feature.get_Value(feature.Fields.FindField("Name")).ToString();
IElement elem = ele as IElement;
elem.Geometry = pt;
IGraphicsContainer gra = axMapControl1.ActiveView.FocusMap as IGraphicsContainer;
gra.AddElement(elem,0);
feature = cursor.NextFeature();
}
axMapControl1.Refresh();
}
//为每个区县匹配唯一的符号
//创建随机颜色 参数为随机数种子 确保唯一
private IColor CreateRandomColor(int i)
{
Random ran = new Random(i);
IRgbColor color = new RgbColorClass();
color.Red = ran.Next(256);
color.Green = ran.Next(256);
color.Blue = ran.Next(256);
return color;
}
private void 匹配符号ToolStripMenuItem_Click(object sender, EventArgs e)
{
//唯一值渲染器
IUniqueValueRenderer renderer = new UniqueValueRendererClass();
//设置用与渲染的字段数目 最多3个
renderer.FieldCount = 1;
//设置字段
renderer.set_Field(0, "FID");
IFeatureLayer layer = axMapControl1.get_Layer(1) as IFeatureLayer;
IFeatureCursor cursor = layer.FeatureClass.Search(null, true);
IFeature feature =cursor.NextFeature();
while (feature != null)
{
//获取要素的FID 充当随机数种子
int i = Convert.ToInt16(feature.get_Value(0).ToString());
//获取FID值 充当渲染值
string value = feature.get_Value(feature.Fields.FindField("FID")).ToString();
ISimpleFillSymbol symbol = new SimpleFillSymbolClass();
symbol.Color = CreateRandomColor(i);
symbol.Style = esriSimpleFillStyle.esriSFSSolid;
//添加值
renderer.AddValue(value, "FID", symbol as ISymbol);
feature = cursor.NextFeature();
}
IGeoFeatureLayer geoLayer = layer as IGeoFeatureLayer;
geoLayer.Renderer = renderer as IFeatureRenderer;
axMapControl1.Refresh();
}
//添加点
private void add(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
IFeatureLayer layer = axMapControl1.get_Layer(0) as IFeatureLayer;
IPoint pt = new PointClass();
pt = axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
IFeature feature = layer.FeatureClass.CreateFeature();
feature.Shape = pt;
feature.Store();
axMapControl1.Refresh();
}
private void 开启状态ToolStripMenuItem2_Click(object sender, EventArgs e)
{
axMapControl1.OnMouseDown += add;
}
private void 关闭状态ToolStripMenuItem2_Click(object sender, EventArgs e)
{
axMapControl1.OnMouseDown -= add;
}
#endregion
}
}
属性表窗体界面:
属性表窗体代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
namespace Ex1
{
public partial class 属性表 : Form
{
IEnumIDs ids = null;
IFeatureLayer layer = null;
IActiveView act = null;
DataTable dataTable = null;
//不同的构造函数对应不同要求
public 属性表(IEnumIDs ids,IFeatureLayer layer)
{
InitializeComponent();
this.ids = ids;
this.layer = layer;
}
public 属性表(IFeatureLayer layer,IActiveView act)
{
InitializeComponent();
this.layer = layer;
this.act = act;
}
public 属性表(DataTable dt, IFeatureLayer layer)
{
InitializeComponent();
this.dataTable = dt;
this.layer = layer;
}
private void 属性表_Load(object sender, EventArgs e)
{
if (ids != null)
{
IFeatureClass featureClass = layer.FeatureClass;
int id = ids.Next();
DataTable dt = new DataTable();
DataColumn dc;
//每个字段一列
for (int i = 0; i < featureClass.Fields.FieldCount; i++)
{
dc = new DataColumn(featureClass.Fields.get_Field(i).Name);
dt.Columns.Add(dc);
}
DataRow dr = dt.NewRow();
//循环添加数据行
while (id != -1)
{
IFeature feature = featureClass.GetFeature(id);
for (int i = 0; i < featureClass.Fields.FieldCount; i++)
{
//Shapez字段单独赋值
if (feature.Fields.get_Field(i).Name.Equals("Shape"))
{
switch (feature.Shape.GeometryType)
{
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
dr[i] = "Point";
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
dr[i] = "Polygon";
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
dr[i] = "Polyline";
break;
default:
dr[i] = "Other";
break;
}
continue;
}
dr[i] = feature.get_Value(i).ToString();
}
dt.Rows.Add(dr);
dataGridView1.DataSource = dt;
}
}
else if (dataTable != null)//匹配Excel数据到检测站点
{
IFeatureClass featureClass = layer.FeatureClass;
//添加Excel中字段,防止重复添加
if (featureClass.Fields.FieldCount < 6)
{
//PM2.5字段
IFieldEdit edit = new FieldClass();
edit.AliasName_2 = "PM2.5";
edit.Name_2 = "PM2.5";
edit.Type_2 = esriFieldType.esriFieldTypeString;
edit.Length_2 = 100;
featureClass.AddField(edit);
//SO2字段
IFieldEdit edit2 = new FieldClass();
edit2.Type_2 = esriFieldType.esriFieldTypeInteger;
edit2.AliasName_2 = "SO2";
edit2.Name_2 = "SO2";
featureClass.AddField(edit2);
//NO2字段
IFieldEdit edit3 = new FieldClass();
edit3.AliasName_2 = "NO2";
edit3.Name_2 = "NO2";
edit3.Type_2 = esriFieldType.esriFieldTypeInteger;
featureClass.AddField(edit3);
}
//创建属性表类似上一步 这里有代码冗余的缺点 是为了方便理解
IFeatureCursor cursor = featureClass.Search(null, true);
IFeature feature = cursor.NextFeature();
DataTable dt = new DataTable();
DataColumn dc;
for (int i = 0; i < featureClass.Fields.FieldCount; i++)
{
dc = new DataColumn(featureClass.Fields.get_Field(i).Name);
dt.Columns.Add(dc);
}
int j = 1;
while (feature != null)
{
DataRow dr = dt.NewRow();
for (int i = 0; i < featureClass.Fields.FieldCount; i++)
{
if (i < featureClass.Fields.FieldCount - 3)
{
if (feature.Fields.get_Field(i).Name.Equals("Shape"))
{
switch (feature.Shape.GeometryType)
{
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
dr[i] = "Point";
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
dr[i] = "Polygon";
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
dr[i] = "Polyline";
break;
default:
dr[i] = "Other";
break;
}
continue;
}
dr[i] = feature.get_Value(i).ToString();
}
else
{
dr[i] = dataTable.Rows[j].ItemArray[i - 1];
}
}
dt.Rows.Add(dr);
feature = cursor.NextFeature();
j++;
}
dataGridView1.DataSource = dt;
}
else
{
//类似
IFeatureCursor cursor = layer.FeatureClass.Search(null, true);
IFeature feature = cursor.NextFeature();
DataTable dt = new DataTable();
DataColumn dc;
for (int i = 0; i < layer.FeatureClass.Fields.FieldCount; i++)
{
dc = new DataColumn(layer.FeatureClass.Fields.get_Field(i).Name);
dt.Columns.Add(dc);
}
while (feature != null)
{
DataRow dr = dt.NewRow();
for (int i = 0; i < layer.FeatureClass.Fields.FieldCount; i++)
{
if (feature.Fields.get_Field(i).Name.Equals("Shape"))
{
switch (feature.Shape.GeometryType)
{
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
dr[i] = "Point";
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
dr[i] = "Polygon";
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
dr[i] = "Polyline";
break;
default:
dr[i] = "Other";
break;
}
continue;
}
dr[i] = feature.get_Value(i).ToString();
}
dt.Rows.Add(dr);
feature = cursor.NextFeature();
}
dataGridView1.DataSource = dt;
}
}
//双击要素属性表行号放缩至该要素区域
private void dataGridView1_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
act.FocusMap.ClearSelection();
//获取行号
int i = e.RowIndex;
//根据行号获取要素
IFeature feature = layer.FeatureClass.GetFeature(i);
IPoint pt = new PointClass();
IGeometry geo = feature.Shape;
IGeometry5 geo5 = geo as IGeometry5;
//获取该要素的中心点坐标
pt.X = geo5.CentroidEx.X;
pt.Y = geo5.CentroidEx.Y;
IEnvelope env = new EnvelopeClass();
//以该坐标为基础创建包络线
env.XMax = pt.X + 0.01;
env.XMin = pt.X - 0.01;
env.YMax = pt.Y + 0.01;
env.YMin = pt.Y - 0.01;
env.CenterAt(pt);
env.Expand(0.01, 0.01, false);
//将地图的显示区域设置为创建的包络线 即放缩至该要素
act.Extent = env;
//同时高亮
act.FocusMap.SelectByShape(pt as IGeometry, null, true);
act.Refresh();
}
}
}
//双击要素属性表行号放缩至该要素区域
private void dataGridView1_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
act.FocusMap.ClearSelection();
//获取行号
int i = e.RowIndex;
//根据行号获取要素
IFeature feature = layer.FeatureClass.GetFeature(i);
IPoint pt = new PointClass();
IGeometry geo = feature.Shape;
IGeometry5 geo5 = geo as IGeometry5;
//获取该要素的中心点坐标
pt.X = geo5.CentroidEx.X;
pt.Y = geo5.CentroidEx.Y;
IEnvelope env = new EnvelopeClass();
//以该坐标为基础创建包络线
env.XMax = pt.X + 0.01;
env.XMin = pt.X - 0.01;
env.YMax = pt.Y + 0.01;
env.YMin = pt.Y - 0.01;
env.CenterAt(pt);
env.Expand(0.01, 0.01, false);
//将地图的显示区域设置为创建的包络线 即放缩至该要素
act.Extent = env;
//同时高亮
act.FocusMap.SelectByShape(pt as IGeometry, null, true);
act.Refresh();
}
}
}
历届GIS应用技能大赛开发题答案点这里,尚在不定期更新中