环境:Windows10专业版 + ArcGIS10.2 + ArcEngine10.2 + Visual Studio 2019
因每个人电脑版本和软件版本不同,运行的结果可能不同
系列文章:
目录
三、功能实现
3.16 栅格计算器
3.16.1 实现思想
(1)添加“栅格计算器”控件。
(2)添加“栅格计算器窗口”,并设置好相关布局,为各个按钮生成点击事件响应函数。读取输入的表达式,读入相关数据,并将计算结果输出。
(3)为“栅格计算器”控件生成点击事件响应函数。
3.16.2 实现的主体代码及注释
using System;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.SpatialAnalyst;
using ESRI.ArcGIS.GeoAnalyst;
using System.Collections;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.Geometry;
using System.IO;
/// <summary>
/// 使mapcontrolMain中的部分图层添加到listBox中
/// </summary>
/// <param name="bLayer"></param>
/// <remarks></remarks>
private void PopulateListBoxWithMapLayers(bool bLayer)
{
int i = 0;
ILayer pLayer = default(ILayer);
listBoxLayer.Items.Clear();
for (i = 0; i <= pCurMap.LayerCount - 1; i++)
{
//获取图层名字,并且加到listbox中
pLayer = pCurMap.get_Layer(i);
if (pLayer.Valid == true)
{
if (bLayer == true)
{
if (pLayer is IRasterLayer)
{
listBoxLayer.Items.Add(pLayer.Name);
}
}
}
}
}
/// <summary>
/// 获取指定图层的范围大小
/// </summary>
/// <returns></returns>
/// <remarks></remarks>
private IEnvelope GetLayerExtend(string sLayerName)
{
ILayer pLayer = default(ILayer);
IEnvelope pEnvelope = default(IEnvelope);
int i = 0;
pEnvelope = new Envelope() as IEnvelope;
for (i = 0; i <= pCurMap.LayerCount - 1; i++)
{
pLayer = pCurMap.get_Layer(i);
if (pLayer.Name == sLayerName.ToString())
{
if (pLayer.Valid == true)
{
//获取分析范围的Envelope对象
pEnvelope = pLayer.AreaOfInterest;
}
}
}
return pEnvelope;
}
/// <summary>
/// 该函数获得栅格影像分辨率大小
/// </summary>
/// <param name="sLayerName"></param>
/// <returns></returns>
/// <remarks></remarks>
private double GetRasterCellSize(string sLayerName)
{
double dCellSize = 0;
int i = 0;
ILayer pLyr = default(ILayer);
IRasterLayer pRlyr = default(IRasterLayer);
IRaster pRaster = default(IRaster);
IRasterProps pRasterProp = default(IRasterProps);
double cellX;
double cellY;
for (i = 0; i <= pCurMap.LayerCount - 1; i++)
{
pLyr = pCurMap.get_Layer(i);
if ((pLyr != null))
{
if (pLyr is IRasterLayer)
{
if (pLyr.Name == sLayerName)
{
pRlyr = (IRasterLayer)pLyr;
pRaster = pRlyr.Raster;
pRasterProp = (IRasterProps)pRaster;
cellX = pRasterProp.MeanCellSize().X;
cellY = pRasterProp.MeanCellSize().Y;
dCellSize = (cellX + cellY) / 2.0;
}
}
}
}
return dCellSize;
}
/// <summary>
/// 通过名称在MAP中找到图层
/// </summary>
/// <param name="pMap"></param>
/// <param name="sName"></param>
/// <returns></returns>
/// <remarks></remarks>
private ILayer FindLayerByName(IMap pMap, string sName)
{
int i = 0;
ILayer pSelectedLayer = null;
for (i = 0; i <= pMap.LayerCount - 1; i++)
{
if (pMap.get_Layer(i).Name == sName)
{
pSelectedLayer = pMap.get_Layer(i);
break; // TODO: might not be correct. Was : Exit For
}
}
return pSelectedLayer;
}
#region "栅格运算"
/// <summary>
/// 在listBox中选择某一个数据名称,双击,该数据名称添加到计算器文本框中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
private void listBoxLayer_DoubleClick(object sender, System.EventArgs e)
{
txtCalculate.SelectedText = "[" + listBoxLayer.SelectedItem.ToString() + "]";
string tmpstr = listBoxLayer.SelectedItem.ToString();
bool blnItm = false;
int i;
for (i = 0; i < LayerList.Count; i++)
{
if (LayerList[i].ToString() == tmpstr)
{
blnItm = true;
}
}
if (blnItm == false)
{
LayerList.Add(listBoxLayer.SelectedItem.ToString());
}
for (i = 0; i < LayerList.Count; i++)
{
MessageBox.Show(LayerList[i].ToString());
}
}
private void btnCalculate_Click(System.Object sender, System.EventArgs e)
{
IRasterLayer pRasLayer = default(IRasterLayer);
IRaster pRaster = default(IRaster);
IEnvelope layExtend = default(IEnvelope);
double AnalysisExtentLeft = 0;
double AnalysisExtentRight = 0;
double AnalysisExtentTop = 0;
double AnalysisExtentBottom = 0;
string layerNameFir = null;
try
{
if (LayerList.Count != 0)
{
if (txtResultFullName.Text.ToString().Length != 0)
{
layerNameFir = LayerList[0].ToString();
layExtend = GetLayerExtend(layerNameFir);
AnalysisExtentLeft = layExtend.XMin;
AnalysisExtentRight = layExtend.XMax;
AnalysisExtentTop = layExtend.YMax;
AnalysisExtentBottom = layExtend.YMin;
pMapAlgebraOp = new RasterMapAlgebraOp() as IMapAlgebraOp;
//设置栅格计算分析环境
IRasterAnalysisEnvironment pRasAnaEnv = default(IRasterAnalysisEnvironment);
pRasAnaEnv = (IRasterAnalysisEnvironment)pMapAlgebraOp;
pRasAnaEnv.VerifyType = esriRasterVerifyEnum.esriRasterVerifyOn;
object dddd;
dddd = GetRasterCellSize(layerNameFir);
pRasAnaEnv.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, ref dddd);
//设置分析范围pAnaExtent
IEnvelope pAnaExtent = default(IEnvelope);
pAnaExtent = new Envelope() as IEnvelope;
pAnaExtent.XMin = System.Convert.ToDouble(AnalysisExtentLeft);
pAnaExtent.XMax = System.Convert.ToDouble(AnalysisExtentRight);
pAnaExtent.YMax = System.Convert.ToDouble(AnalysisExtentTop);
pAnaExtent.YMin = System.Convert.ToDouble(AnalysisExtentBottom);
object dd1 = pAnaExtent;
object dd2 = null;
pRasAnaEnv.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ref dd1, ref dd2);
foreach (string LayerName in LayerList)
{
pRasLayer = (IRasterLayer)FindLayerByName(pCurMap, LayerName);
//MsgBox(LayerName)
pRaster = pRasLayer.Raster;
RasterList.Add(pRaster);
}
//将容量设置为 ArrayList 中元素的实际数目
LayerList.TrimToSize();
RasterList.TrimToSize();
//绑定
int i = 0;
if (LayerList.Count == RasterList.Count)
{
for (i = 0; i <= LayerList.Count - 1; i++)
{
pMapAlgebraOp.BindRaster((IGeoDataset)RasterList[i], LayerList[i].ToString());
}
}
//获取文本框中的运算表达式()
string sCalExpression = null;
sCalExpression = txtCalculate.Text;
//执行地图代数运算
IRaster pOutRasterDS = default(IRaster);
pOutRasterDS = (IRaster)pMapAlgebraOp.Execute(sCalExpression);
//解除绑定
if (LayerList.Count == RasterList.Count)
{
for (i = 0; i <= LayerList.Count - 1; i++)
{
pMapAlgebraOp.UnbindRaster(LayerList[i].ToString());
}
}
//保存到工作空间
IWorkspaceFactory pWsFact = default(IWorkspaceFactory);
IWorkspace pWS = default(IWorkspace);
int hwnd = 0;
pWsFact = new RasterWorkspaceFactory();
pWS = pWsFact.OpenFromFile(sOutRasPath, hwnd);
IRasterBandCollection pRasterbandCollection = default(IRasterBandCollection);
pRasterbandCollection = (IRasterBandCollection)pOutRasterDS;
IDataset pDataset = default(IDataset);
pDataset = pRasterbandCollection.SaveAs(sOutRasName, pWS, "IMAGINE Image");
//输出到mapcontrol中
IRasterDataset pOutResultDS = default(IRasterDataset);
pOutResultDS = (IRasterDataset)pDataset;
IRasterLayer pOutRasterLayer = default(IRasterLayer);
pOutRasterLayer = new RasterLayer();
pOutRasterLayer.CreateFromDataset(pOutResultDS);
//MapControlMain.AddLayer(pOutRasterLayer)
pCurMap.AddLayer(pOutRasterLayer);
this.Close();
}
else
{
MessageBox.Show("保存计算结果为空,请输入结果文件名!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
//Interaction.MsgBox(ex.ToString);
}
}
#endregion
#region "保存栅格运算后的结果"
private void btnSaveResult_Click(System.Object sender, System.EventArgs e)
{
string pOutDSName = null;
int iOutIndex = 0;
var _with1 = SaveFileDialog1;
_with1.Title = "保存栅格运算结果";
_with1.Filter = "(*.img)|*.img";
_with1.OverwritePrompt = false;
_with1.InitialDirectory = Application.StartupPath;
if (_with1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
pOutDSName = _with1.FileName;
FileInfo fFile = new FileInfo(pOutDSName);
//判断文件名是否已经存在,如果存在,则弹出提示
if (fFile.Exists == true)
{
MessageBox.Show("文件名已存在,请重新输入", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
txtResultFullName.Text = "";
}
else
{
iOutIndex = pOutDSName.LastIndexOf("\\");
sOutRasPath = pOutDSName.Substring(0, iOutIndex + 1);
sOutRasName = pOutDSName.Substring(iOutIndex + 1, pOutDSName.Length - iOutIndex - 1);
txtResultFullName.Text = pOutDSName;
}
}
}
//栅格计算器
private void miRasterCalculator_Click(object sender, EventArgs e)
{
FrmRasterCalculatornew frmRstCalDlg = new FrmRasterCalculatornew(this, axMapControl1.Map);
frmRstCalDlg.Show();
}
3.17 缓冲区分析
3.17.1 实现思想
(1)添加“缓冲区分析”控件。
(2)添加“地图分析”类,调用Buffer()函数进行缓冲区查询。
(3)为“缓冲区分析”控件生成点击事件响应函数。
3.17.2 实现的主体代码及注释
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
//缓冲区查询
public bool Buffer(string layerName, string sWhere, int iSize, IMap iMap)
{
//根据过滤条件获取城市名称为北京的城市要素的几何
IFeatureClass featClass;
IFeature feature;
IGeometry iGeom;
DataOperator dataOperator = new DataOperator(iMap);
IFeatureLayer featLayer = (IFeatureLayer)dataOperator.GetLayerByName(layerName);
featClass = featLayer.FeatureClass;
IQueryFilter queryFilter = new QueryFilter();
queryFilter.WhereClause = sWhere;//设置过滤条件
IFeatureCursor featCursor;
featCursor = (IFeatureCursor)featClass.Search(queryFilter, false);
int count = featClass.FeatureCount(queryFilter);
feature = featCursor.NextFeature();
iGeom = feature.Shape;
//设置空间的缓冲区作为空间查询的几何范围
ITopologicalOperator ipTO = (ITopologicalOperator)iGeom;
IGeometry iGeomBuffer = ipTO.Buffer(iSize);
//根据缓冲区几何对城市图层进行空间过滤
ISpatialFilter spatialFilter = new SpatialFilter();
spatialFilter.Geometry = iGeomBuffer;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIndexIntersects;
//定义要素选择对象,以要素搜索图层进行实例化
IFeatureSelection featSelect = (IFeatureSelection)featLayer;
//以空间过滤器对要素进行选择,并建立新选择集
featSelect.SelectFeatures(spatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
return true;
}
//缓冲区查询
private void miBuffer_Click(object sender, EventArgs e)
{
MapAnalysis mapAnalysis = new MapAnalysis();
mapAnalysis.Buffer("World Cities", "CITY_NAME='Beijing'", 1, axMapControl1.Map);
IActiveView activeView;
activeView = axMapControl1.ActiveView;
activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, 0, axMapControl1.Extent);
}
3.18 叠加分析
3.18.1 实现思想
(1)添加“叠加分析”控件。
(2)添加“叠加分析”窗口,设置相应布局和控件,为控件生成点击事件响应函数,选择“裁剪或者相交叠加分析”,若选择“裁剪”,利用BasicGeoprocessorClass.Clip()方法进行裁剪分析,若选择“相交”,利用BasicGeoprocessorClass.Intersect()方法进行相交分析。
(3)为“叠加分析”控件生成点击事件响应函数。
3.18.2 实现的主体代码及注释
using System;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DataSourcesFile;
namespace GISAE
{
public partial class OverlayAnalysis : Form
{
//定义全局变量
public IMap pMap { get; set; }
public AxMapControl axMapControl1 { get; set; }
public OverlayAnalysis(ESRI.ArcGIS.Controls.AxMapControl basicControl)
{
InitializeComponent();
axMapControl1 = basicControl;
}
//窗体加载事件
private void OverlayAnalysis_Load(object sender, EventArgs e)
{
try
{
pMap = axMapControl1.Map;
if (pMap == null)
return;
//清空combobox
cbInputDataset.Items.Clear();
cbOverlayDataset.Items.Clear();
string layerName; //用于储存图层名字
for (int i = 0; i < pMap.LayerCount; i++)
{
layerName = pMap.Layer[i].Name;
cbInputDataset.Items.Add(layerName);
cbOverlayDataset.Items.Add(layerName);
}
cbOverlayWays.Items.Add("裁剪");
cbOverlayWays.Items.Add("相交");
cbOverlayWays.SelectedIndex = 0;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private ILayer GetLayerByName(IMap pMap, string layerName)
{
ILayer pLayer = null;
ILayer tempLayer = null;
try
{
for (int i = 0; i < pMap.LayerCount; i++)
{
tempLayer = pMap.Layer[i];
if (tempLayer.Name.ToUpper() == layerName.ToUpper()) //判断名字大写是否一致
{
pLayer = tempLayer;
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return pLayer;
}
private void OK_Click(object sender, EventArgs e)
{
if (pMap == null)
return;
//获取数据集
ILayer inputDataset = GetLayerByName(pMap, cbInputDataset.Text.Trim());
ILayer clipDataset = GetLayerByName(pMap, cbOverlayDataset.Text.Trim());
//裁剪
if (inputDataset != null && clipDataset != null && cbOverlayWays.Text == "裁剪")
{
IFeatureLayer inputLayer = inputDataset as IFeatureLayer;
IFeatureLayer clipLayer = clipDataset as IFeatureLayer;
IBasicGeoprocessor bGP = new BasicGeoprocessorClass();
bGP.SpatialReference = pMap.SpatialReference; //设置空间参考
IFeatureClassName pOutput = new FeatureClassNameClass(); //创建FeatureClassNameClass对象,用于获取输入数据集的一些基本信息
pOutput.FeatureType = inputLayer.FeatureClass.FeatureType;
pOutput.ShapeFieldName = inputLayer.FeatureClass.ShapeFieldName;
pOutput.ShapeType = inputLayer.FeatureClass.ShapeType;
//利用IDataset获得IWorkspaceName
string fileDirectory = System.IO.Path.GetDirectoryName(tbOutputPath.Text.Trim());
string fileName = System.IO.Path.GetFileName(tbOutputPath.Text.Trim());
IWorkspaceFactory pWsFc = new ShapefileWorkspaceFactoryClass();
IWorkspace pWs = pWsFc.OpenFromFile(fileDirectory, 0); //创建一个工作空间对象
IDataset pDataset = pWs as IDataset;
IWorkspaceName pWsN = pDataset.FullName as IWorkspaceName; //获取工作空间的信息(获取输出路径)
IDatasetName pDatasetName = pOutput as IDatasetName; //获取或设置数据集中成员的名称信息
pDatasetName.Name = fileName; //设置数据集中的数据成员的名字
pDatasetName.WorkspaceName = pWsN; //设置输出的工作空间(输出路径)
//利用裁剪方法来进行叠加分析
IFeatureClass featureClass = bGP.Clip(inputLayer.FeatureClass as ITable, false, clipLayer.FeatureClass as ITable, false, 0.01, pOutput);
if (featureClass != null)
{
IFeatureLayer featLayer = new FeatureLayerClass();
featLayer.FeatureClass = featureClass;
featLayer.Name = featureClass.AliasName;
//将结果添加到控件中
axMapControl1.AddLayer(featLayer);
axMapControl1.Refresh();
}
}
//相交
if (inputDataset != null && clipDataset != null && cbOverlayWays.Text == "相交")
{
IFeatureLayer inputLayer = inputDataset as IFeatureLayer;
IFeatureLayer clipLayer = clipDataset as IFeatureLayer;
IBasicGeoprocessor bGP = new BasicGeoprocessorClass();
bGP.SpatialReference = pMap.SpatialReference; // 设置空间参考
IFeatureClassName pOutput = new FeatureClassNameClass(); // 创建FeatureClassNameClass对象,用于获取输入数据集的一些基本信息
pOutput.FeatureType = inputLayer.FeatureClass.FeatureType;
pOutput.ShapeFieldName = inputLayer.FeatureClass.ShapeFieldName;
pOutput.ShapeType = inputLayer.FeatureClass.ShapeType;
// 利用IDataset获得IWorkspaceName
string fileDirectory = System.IO.Path.GetDirectoryName(tbOutputPath.Text.Trim());
string fileName = System.IO.Path.GetFileName(tbOutputPath.Text.Trim());
IWorkspaceFactory pWsFc = new ShapefileWorkspaceFactoryClass();
IWorkspace pWs = pWsFc.OpenFromFile(fileDirectory, 0); // 创建一个工作空间对象
IDataset pDataset = pWs as IDataset;
IWorkspaceName pWsN = pDataset.FullName as IWorkspaceName; // 获取工作空间的信息(获取输出路径)
IDatasetName pDatasetName = pOutput as IDatasetName; // 获取或设置数据集中成员的名称信息
pDatasetName.Name = fileName; // 设置数据集中的数据成员的名字
pDatasetName.WorkspaceName = pWsN; // 设置输出的工作空间(输出路径)
// 利用相交方法来进行叠加分析
IFeatureClass featureClass = bGP.Intersect(inputLayer.FeatureClass as ITable, false, clipLayer.FeatureClass as ITable, false, 0.01, pOutput);
if (featureClass != null)
{
IFeatureLayer featLayer = new FeatureLayerClass();
featLayer.FeatureClass = featureClass;
featLayer.Name = featureClass.AliasName;
// 将结果添加到控件中
axMapControl1.AddLayer(featLayer);
axMapControl1.Refresh();
}
}
}
private void Cancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btOutputPath_Click(object sender, EventArgs e)
{
SaveFileDialog flg = new SaveFileDialog();
flg.Title = "保存路径";
flg.Filter = "ShpFile(*shp)|*.shp";
flg.ShowDialog();
tbOutputPath.Text = flg.FileName;
}
}
}
//叠加分析
private void btnOverlayAnalysis_Click(object sender, EventArgs e)
{
OverlayAnalysis overlayAnalysis = new OverlayAnalysis(axMapControl1);
overlayAnalysis.ShowDialog();
}
3.19 创建点
3.19.1 实现思想
(1)添加“创建点”控件。
(2)添加“创建点”类,利用DrawPoint()方法画点。
(3)为“创建点”控件生成点击事件响应函数。
3.19.2 实现的主体代码及注释
public DrawPoint()
{
//
// TODO: Define values for the public properties
//
base.m_category = ""; //localizable text
base.m_caption = ""; //localizable text
base.m_message = ""; //localizable text
base.m_toolTip = ""; //localizable text
base.m_name = ""; //unique id, non-localizable (e.g. "MyCategory_MyTool")
try
{
//
// TODO: change resource name if necessary
//
string bitmapResourceName = GetType().Name + ".bmp";
base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
base.m_cursor = new System.Windows.Forms.Cursor(GetType(), GetType().Name + ".cur");
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
}
}
//创建点
private void miCreatePoint_Click(object sender, EventArgs e)
{
ICommand command = new DrawPointTool.DrawPoint();
command.OnCreate(axMapControl1.Object);
axMapControl1.CurrentTool = command as ITool;
}
3.20 创建线
3.20.1 实现思想
(1)添加“创建线”控件。
(2)添加“创建线”类,利用DrawPolylineTool()方法画线。
(3)为“创建线”控件生成点击事件响应函数。
3.20.2 实现的主体代码及注释
public DrawPolylineTool()
{
//
// TODO: Define values for the public properties
//
base.m_category = ""; //localizable text
base.m_caption = ""; //localizable text
base.m_message = ""; //localizable text
base.m_toolTip = ""; //localizable text
base.m_name = ""; //unique id, non-localizable (e.g. "MyCategory_MyTool")
try
{
//
// TODO: change resource name if necessary
//
string bitmapResourceName = GetType().Name + ".bmp";
base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
base.m_cursor = new System.Windows.Forms.Cursor(GetType(), GetType().Name + ".cur");
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
}
}
//创建线
private void miCreatePolyline_Click(object sender, EventArgs e)
{
ICommand command = new DrawPolyline.DrawPolylineTool();
command.OnCreate(axMapControl1.Object);
axMapControl1.CurrentTool = command as ITool;
}
3.21 创建面
3.21.1 实现思想
(1)添加“创建多边形”控件。
(2)添加“创建多边形”类,利用DrawPolygonTool()方法画线。
(3)为“创建多边形”控件生成点击事件响应函数。
3.21.2 实现的主体代码及注释
public DrawPolygonTool()
{
//
// TODO: Define values for the public properties
//
base.m_category = ""; //localizable text
base.m_caption = ""; //localizable text
base.m_message = ""; //localizable text
base.m_toolTip = ""; //localizable text
base.m_name = ""; //unique id, non-localizable (e.g. "MyCategory_MyTool")
try
{
//
// TODO: change resource name if necessary
//
string bitmapResourceName = GetType().Name + ".bmp";
base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
base.m_cursor = new System.Windows.Forms.Cursor(GetType(), GetType().Name + ".cur");
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
}
}
//创建多边形
private void miCreatePolygon_Click(object sender, EventArgs e)
{
ICommand command = new DrawPolygonTool();
command.OnCreate(axMapControl1.Object);
axMapControl1.CurrentTool = command as ITool;
}
3.22 视图切换
3.22.1 实现思想
(1)创建“显示地图”和“显示页面布局”控件。
(2)为“显示地图”和“显示页面布局”按钮生成点击事件响应函数,并在此函数实现页面切换功能,并用copyToPageLayout()实现页面联动。
3.22.2 实现的主体代码及注释
//显示地图
private void miMap_Click(object sender, EventArgs e)
{
if (miMap.Checked == false)
{
axToolbarControl1.SetBuddyControl(axMapControl1.Object);
axTOCControl1.SetBuddyControl(axMapControl1.Object);
axMapControl1.Show();
axPageLayoutControl1.Hide();
miMap.Checked = true;
miPageLayout.Checked = false;
miPrint.Enabled = false;
}
else
{
axToolbarControl1.SetBuddyControl(axPageLayoutControl1.Object);
axTOCControl1.SetBuddyControl(axPageLayoutControl1.Object);
axMapControl1.Hide();
axPageLayoutControl1.Show();
miMap.Checked = false;
miPageLayout.Checked = true;
miPrint.Enabled = true;
}
}
//显示页面布局
private void miPageLayout_Click(object sender, EventArgs e)
{
if (miPageLayout.Checked == false)
{
axToolbarControl1.SetBuddyControl(axPageLayoutControl1.Object);
axTOCControl1.SetBuddyControl(axPageLayoutControl1.Object);
axPageLayoutControl1.Show();
axMapControl1.Hide();
miPageLayout.Checked = true;
miMap.Checked = false;
miPrint.Enabled = true;
}
else
{
axToolbarControl1.SetBuddyControl(axMapControl1.Object);
axTOCControl1.SetBuddyControl(axMapControl1.Object);
axPageLayoutControl1.Hide();
axMapControl1.Show();
miPageLayout.Checked = false;
miMap.Enabled = true;
miPrint.Enabled = false;
}
}
public void copyToPageLayout()
{
IObjectCopy objectCopy = new ObjectCopy();//对象拷贝接口
object copyFromMap = axMapControl1.Map;//地图对象
object copyMap = objectCopy.Copy(copyFromMap);//将axMapControl1的地图对象拷贝
object copyToMap = axPageLayoutControl1.ActiveView.FocusMap;//axPageLayoutControl1活动视图中的地图
objectCopy.Overwrite(copyMap, ref copyToMap);//将axMapControl1地图对象覆盖axPageLayout1当前地图
}
private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
{
IMap pMap;
pMap = axMapControl1.Map;
for (int i = 0; i < pMap.LayerCount; i++)
{
axMapControl2.Map.AddLayer(pMap.get_Layer(i));
}
//使鹰眼视图中显示加载地图的全图
axMapControl2.Extent = axMapControl2.FullExtent;
copyToPageLayout();
}
private void axMapControl1_OnAfterScreenDraw(object sender, IMapControlEvents2_OnAfterScreenDrawEvent e)
{
IActiveView activeView = (IActiveView)axPageLayoutControl1.ActiveView.FocusMap;//axPageLayoutControl1的活动视图的地图
IDisplayTransformation displayTransformation = activeView.ScreenDisplay.DisplayTransformation;//活动视图的屏幕显示的显示信息
displayTransformation.VisibleBounds = axMapControl1.Extent;//将axMapControl1的范围赋值给axPageLayoutControl1的范围
axPageLayoutControl1.ActiveView.Refresh();//刷新axPageLayoutControl1的活动视图
copyToPageLayout();//将axMapControl1的地图拷贝到axPageLayoutControl1中
}
3.23 插入标题
3.23.1 实现思想
(1)创建“插入标题”控件。
(2)为“插入标题”按钮生成点击事件响应函数,调用AddTitle()函数实现插入标题。
3.23.2 实现的主体代码及注释
//插入标题
private void miAddTittle_Click(object sender, EventArgs e)
{
string str = Interaction.InputBox("请输入图名", "提示", "示例地图", -1, -1);
AddTitle(axPageLayoutControl1.PageLayout, str);
}
public void AddTitle(IPageLayout pageLayout, String s)
{
//找到PageLayout
IPageLayout pPageLayout = axPageLayoutControl1.PageLayout;
//找到元素容器
IGraphicsContainer pGraphicsContainer = pPageLayout as IGraphicsContainer;
//创建元素
ITextElement pTextElement = new TextElementClass();
pTextElement.Text = s;
ITextSymbol pTextSymbol = new TextSymbolClass();//Text的符号样式
pTextSymbol.Font.Name = "宋体";
IRgbColor pColor = new RgbColorClass();
pColor.Blue = 255;
pColor.Red = 255;
pColor.Green = 0;
pTextSymbol.Size = 30;
pTextSymbol.Color = pColor;
pTextSymbol.Font.Bold = true;
pTextElement.Symbol = pTextSymbol;
//设置位置
IElement pElement = pTextElement as IElement;
pElement.Geometry = axPageLayoutControl1.TrackRectangle();
//将元素添加到容器中
pGraphicsContainer.AddElement(pElement, 0);
//刷新
axPageLayoutControl1.Refresh();
}
3.24 插入指北针
3.24.1 实现思想
(1)创建“插入指北针”控件。
(2)为“插入标题”按钮生成点击事件响应函数,调用AddElement()函数插入指北针元素。
3.24.2 实现的主体代码及注释
//插入指北针
private void miAddNorthArrows_Click(object sender, EventArgs e)
{
//获取axPageLayoutControl1的图形容器
IGraphicsContainer graphicsContainer = axPageLayoutControl1.GraphicsContainer;
//获取axPageLayoutControl1空间里面显示的地图图层
IMapFrame mapFrame = (IMapFrame)graphicsContainer.FindFrame(axPageLayoutControl1.ActiveView.FocusMap);
UID uID = new UIDClass();
uID.Value = "esriCore.MarkerNorthArrow";
if (mapFrame == null) return;
IMapSurroundFrame mapSurroundFrame = mapFrame.CreateSurroundFrame(uID, null);
if (mapSurroundFrame == null) return;
IEnvelope envelope = new EnvelopeClass();
envelope.PutCoords(1000, 1000, 18, 25);
IElement element = (IElement)mapSurroundFrame;
element.Geometry = envelope;
mapSurroundFrame.MapSurround.Name = "MarkerNorthArrow";
INorthArrow pNorthArrow = mapSurroundFrame.MapSurround as INorthArrow;
axPageLayoutControl1.AddElement(element, Type.Missing, Type.Missing, "MarkerNorthArrow", 0);
axPageLayoutControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
3.25 插入比例尺
3.25.1 实现思想
(1)创建“插入比例尺”控件。
(2)创建“ScaleBarTool”类,设置比例尺的相关属性,调用AddElement()函数插入比例尺元素。
(3)为“插入比例尺”按钮生成点击事件响应函数。
3.25.2 实现的主体代码及注释
using System;
using System.Windows.Forms;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;
namespace GISAE
{
class ScaleBarTool
{
public static int count = 0;
public void AddSacleBar(AxPageLayoutControl axPageLayoutControl1, IEnvelope pEnv, int strBarType = 0)
{
if (count > 0)
return;
IScaleBar pScaleBar;
IMapFrame pMapFrame;
IMapSurroundFrame pMapSurroundFrame;
IMapSurround pMapSurround;
IElementProperties pElementPro;
//产生一个UID对象,使用它产生不同的MapSurround对象
UID pUID = new UIDClass();
pUID.Value = " esriCarto.scalebar";
IPageLayout pPageLayout;
pPageLayout = axPageLayoutControl1.PageLayout;
IGraphicsContainer pGraphicscontainer;
pGraphicscontainer = pPageLayout as IGraphicsContainer;
IActiveView pActiveView;
pActiveView = pGraphicscontainer as IActiveView;
IMap pMap;
pMap = pActiveView.FocusMap;
//获得与地图相关的MapFrame
pMapFrame = pGraphicscontainer.FindFrame(pMap) as IMapFrame;
pMapSurroundFrame = pMapFrame.CreateSurroundFrame(pUID, null);
//依据传入参数不同使用不同类型的比例尺
//MessageBox.Show(strBarType.ToString());
switch (strBarType)
{
case 0:
pScaleBar = new AlternatingScaleBarClass();//西安交互式比例尺
break;
case 1:
pScaleBar = new DoubleAlternatingScaleBarClass();//双线交互比例尺
break;
case 2:
pScaleBar = new HollowScaleBarClass();//中空式比例尺
break;
case 3:
pScaleBar = new ScaleLineClass();//线式比例尺
break;
case 4:
pScaleBar = new SingleDivisionScaleBarClass();//分割式比例尺
break;
case 5:
pScaleBar = new SteppedScaleLineClass();//阶梯式比例尺
break;
default:
pScaleBar = new ScaleLineClass();
break;
}
pScaleBar.Division = 5;
pScaleBar.Divisions = 5;
pScaleBar.LabelGap = 5;
pScaleBar.LabelPosition = esriVertPosEnum.esriAbove;
pScaleBar.Map = pMap;
pScaleBar.Name = "myscaleBar";
pScaleBar.Subdivisions = 3;
pScaleBar.UnitLabel = "千米";
pScaleBar.UnitLabelGap = 5;
pScaleBar.UnitLabelPosition = esriScaleBarPos.esriScaleBarAbove;
pScaleBar.Units = esriUnits.esriKilometers;
pMapSurround = pScaleBar;
pMapSurroundFrame.MapSurround = pMapSurround;
pElementPro = pMapSurroundFrame as IElementProperties;
pElementPro.Name = "my scalebar";
//将MapSurroundFrame对象添加到控件中
axPageLayoutControl1.AddElement(pMapSurroundFrame as IElement, pEnv, Type.Missing, Type.Missing, 0);
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
}
}
//插入比例尺
private void miAddScaleBar_Click(object sender, EventArgs e)
{
ScaleBarTool scaleBarTool = new ScaleBarTool();
IEnvelope pEnv = new EnvelopeClass();
pEnv.PutCoords(20, 3, 10, 2);
scaleBarTool.AddSacleBar(axPageLayoutControl1, pEnv, 0);
}
3.26 插入图例
3.26.1 实现思想
(1)创建“插入图例”控件。
(2)为“插入比例尺”按钮生成点击事件响应函数,调用AddElement()函数插入比例尺元素。
3.26.2 实现的主体代码及注释
//插入图例
private void miAddLegend_Click(object sender, EventArgs e)
{
//获取axPageLayoutControl1的图形容器
IGraphicsContainer graphicsContainer = axPageLayoutControl1.GraphicsContainer;
//获取axPageLayoutControl1空间里面显示的地图图层
IMapFrame mapFrame = (IMapFrame)graphicsContainer.FindFrame(axPageLayoutControl1.ActiveView.FocusMap);
if (mapFrame == null) return;
//创建图例
UID uID = new UIDClass();//创建UID作为该图例的唯一标识符,方便创建之后进行删除、移动等操作
uID.Value = "esriCarto.Legend";
IMapSurroundFrame mapSurroundFrame = mapFrame.CreateSurroundFrame(uID, null);
if (mapSurroundFrame == null) return;
if (mapSurroundFrame.MapSurround == null) return;
mapSurroundFrame.MapSurround.Name = "Legend";
IEnvelope envelope = new EnvelopeClass();
envelope.PutCoords(1, 3, 20, 8);//设置图例摆放位置(原点在axPageLayoutControl左下角)
IElement element = (IElement)mapSurroundFrame;
element.Geometry = envelope;
//将图例转化为几何要素添加到axPageLayoutControl1,并刷新页面显示
axPageLayoutControl1.AddElement(element, Type.Missing, Type.Missing, "图例", 0);
axPageLayoutControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
四、课程设计的收获与感悟
4.1收获
首先,通过这门课程设计,我学会了如何使用 ArcEngine 10.2 这一强大的 GIS 开发工具。我学会了①鹰眼、空间书签、数据列表显示、创建 shapefile 文件与编辑要素;②文件(新建地图文档、打开地图文档、保存、另存为、添加数据(添加.shp、添加.lyr、添加栅格数据、退出));③栅格数据处理功能(获取栅格目录、创建栅格数据集、添加栅格数据、格式转换、影像镶嵌、栅格数据计算器(由用户定义计算表达式));④空间分析功能,包括据缓冲区分析、叠加分析、裁剪分析(要求采用对话框方式实现,通过对话框选择数据对象与相应的设置);⑤几何对象的绘制(点绘制、线绘制、面绘制)并保存到指定图层;⑥视图切换(页面视图、数据视图)且实现两者的数据联动;⑦制图(插入标题、插入指北针、插入比例尺、插入图例、文字编辑)。
其次,这门课程设计让我对地理信息系统的应用有了更深入的了解。我学会了如何利用GIS技术进行地理数据的采集、处理和分析。我了解了如何使用ArcEngine的工具和功能来进行地理数据的查询、空间分析和栅格数据分析等,这些技能对于解决实际的地理问题和进行地理决策具有重要的意义。
此外,这门课程设计还培养了我得到交流能力。在课程设计中,与同学们一起讨论Bug,并解决这些问题,并提高了自己的沟通和组织能力。
最后,这门课程设计为我未来的工作发展打下了坚实的基础。面向对象,软件工程的思想,让我对开发流程更为熟悉。GIS技术在许多领域都有广泛的应用,包括城市规划、环境保护、农业和物流等。通过学习GIS设计与开发,我具备了一定的开发和应用GIS技术的能力,这对于从事与GIS开发相关的工作或研究具有重要的竞争优势。
4.2感悟
完成课程设计后,我深深感悟到地理信息系统的无限可能和广泛应用的重要性。通过这门课程设计,我对地理信息的价值和作用有了更深入的理解。首先,我意识到地理信息系统在解决实际问题和支持决策方面的巨大潜力。GIS技术可以帮助我们收集、管理和分析大量的地理数据,从而揭示地理现象的模式和趋势。无论是城市规划、环境保护还是农业生产,都可以通过地理信息系统来优化决策过程,提高效率和效果。这种对地理信息的深入应用,使我对GIS技术的重要性有了更深刻的认识。
最重要的是,这门课程设计让我意识到学习是一个持续不断的过程。GIS技术不断发展和更新,新的工具和方法不断涌现。我意识到需要不断学习和保持更新的知识,以适应快速变化的技术环境。这让我明白到,只有不断学习和提升自己,才能不断适应新的需求和挑战。
总而言之,完成课程设计让我对地理信息系统有了更深入的认识和体会。我明白了地理信息系统在实际问题解决和决策支持中的重要性,体验了同学交流合作的力量,也意识到学习的持续性和重要性。这些感悟将成为我在未来学术和职业发展中的重要指导,帮助我不断进步和取得更大的成就。