您的位置:首页 > 移动开发 > 微信开发

实习期间第一个小程序

2016-05-16 13:02 911 查看
程序主要实现的功能是:判断点在哪个面内,并显示该面的相关信息

实现思路:

1)从点图层读取点,通过空间查询,查找它位于哪个面内

2)获取面对象的NAME字段,通过属性查询,查找另一张面图层的“地形”属性

3)用NAME和地形替换文本元素的相应位置

第一次

问题:代码混乱,没有释放cursor,效率低(重复操作太多)

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.Geodatabase;
using ESRI.ArcGIS.Geometry;

namespace 地形信息查询new
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//查询与点相交的面是哪个
//找点
IFeatureLayer pPointLayer = axMapControl1.get_Layer(0) as IFeatureLayer;
IFeatureCursor pFeatureCursor = pPointLayer.Search(null, false);
IFeature pFeature = pFeatureCursor.NextFeature();
System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);
//元素
IMap pMap = axMapControl1.Map;
IActiveView pActiveView = pMap as IActiveView;
IGraphicsContainer pGraphicsContainer = pMap as IGraphicsContainer;
pGraphicsContainer.Reset();
IElement pElem = new TextElement();
pElem = pGraphicsContainer.Next();
ITextElement pTextElem = pElem as ITextElement;
string elemText = pTextElem.Text;

while (pFeature != null)
{
//空间查询
ISpatialFilter pSpatialFilter1 = new SpatialFilter();
pSpatialFilter1.Geometry = pFeature.Shape;
pSpatialFilter1.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin;//.esriSpatialRelIntersect;
IFeatureLayer pCountyPolygonLayer = axMapControl1.get_Layer(2) as IFeatureLayer;
IFeatureCursor pFeatureCusor1 = pCountyPolygonLayer.Search(pSpatialFilter1, false);//查询结果赋给指针
IFeature pCountyFeature = pFeatureCusor1.NextFeature();//获得县
string pCountyName = null;
IFields pCountyFields = pCountyPolygonLayer.FeatureClass.Fields;//获取字段值
IField pCountyField;
for (int j = 0; j < pCountyFields.FieldCount; j++)
{
pCountyField = pCountyFields.get_Field(j);
if (pCountyField.Name.ToUpper() == "NAME")
{
pCountyName = pCountyFeature.get_Value(j);
break;
}
}

//属性查询,获取地形信息
IFeatureLayer pTerrainLayer = axMapControl1.get_Layer(1) as IFeatureLayer;
IQueryFilter pQueryFiler = new QueryFilter();
pQueryFiler.WhereClause = "NAME=" + "'" + pCountyName + "'";
IFeatureCursor pFeatureCursor2 = pTerrainLayer.Search(pQueryFiler, false);
IFeature pTerrainFeature = pFeatureCursor2.NextFeature();
IFields pTerrainFields = pTerrainLayer.FeatureClass.Fields;
IField pTerrainField;
string pTerrain = null;//地形信息TXT
for (int k = 0; k < pTerrainFields.FieldCount; k++)
{
//pTerrain += pTerrainFields.get_Field(k).AliasName;
pTerrainField = pTerrainFields.get_Field(k);
if (pTerrainField.Name == "地形")
{
pTerrain = pTerrainFeature.get_Value(k);
break;
}
}
//string pMessage = pCountyName +":"+ pTerrain;
//MessageBox.Show(pTextElem.Text);

//TextElement显示
//元素

if (elemText.Contains('X'))
{
elemText = elemText.Replace("X", pCountyName);
if (elemText.Contains('Y'))
{
elemText = elemText.Replace("Y", pTerrain);
}
}

else if (elemText.Contains("W"))
{
elemText = elemText.Replace("W", pCountyName);
if (elemText.Contains('Z'))
{
elemText = elemText.Replace("Z", pTerrain);
}
}

pFeature = pFeatureCursor.NextFeature();
}
pTextElem.Text = elemText;
pActiveView.Refresh();
}

private void axToolbarControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IToolbarControlEvents_OnMouseDownEvent e)
{

}
}
}

第二次

问题:没有利用现有的函数实现查找字段的功能;没有进行异常捕获;没有分函数

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.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System.Runtime.InteropServices;

namespace 地形信息查询new
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{

//找点
IFeatureLayer pPointLayer = axMapControl1.get_Layer(0) as IFeatureLayer;
IFeatureCursor pFeatureCursor0 = pPointLayer.Search(null, false);
IFeature pFeature = pFeatureCursor0.NextFeature();

//找NAME字段所在的位置
IFeatureLayer pCountyPolygonLayer = axMapControl1.get_Layer(2) as IFeatureLayer;
IFields pCountyFields = pCountyPolygonLayer.FeatureClass.Fields;//获取字段值
IField pCountyField;
int countyIndex = 0;
for (int j = 0; j < pCountyFields.FieldCount; j++)//找字段所在位置,不需要每次执行
{
pCountyField = pCountyFields.get_Field(j);
if (pCountyField.Name.ToUpper() == "NAME")
{
countyIndex = j;
break;
}
}

//找“地形”字段所在位置
IFeatureLayer pTerrainLayer = axMapControl1.get_Layer(1) as IFeatureLayer;
IFields pTerrainFields = pTerrainLayer.FeatureClass.Fields;
IField pTerrainField;
int terrainIndex = 0;
for (int k = 0; k < pTerrainFields.FieldCount; k++)
{
pTerrainField = pTerrainFields.get_Field(k);
if (pTerrainField.Name == "地形")
{
terrainIndex = k;
//pTerrain = pTerrainFeature.get_Value(k);
break;
}
}

//元素
IMap pMap = axMapControl1.Map;
IActiveView pActiveView = pMap as IActiveView;
IGraphicsContainer pGraphicsContainer = pMap as IGraphicsContainer;
pGraphicsContainer.Reset();
IElement pElem = new TextElement();
pElem = pGraphicsContainer.Next();
ITextElement pTextElem = pElem as ITextElement;
string elemText = pTextElem.Text;

IFeatureCursor pCountyCursor1;
IFeature pCountyFeature ;//获得县
IFeatureCursor pTerrainCursor2;
IFeature pT
4000
errainFeature ;
string pCountyName = null;
string pTerrain = null;//地形信息TXT
ISpatialFilter pSpatialFilter = new SpatialFilter();
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
IQueryFilter pQueryFiler = new QueryFilter();

while (pFeature != null)
{
//空间查询
pSpatialFilter.Geometry = pFeature.Shape;
pCountyCursor1 = pCountyPolygonLayer.Search(pSpatialFilter, false);
pCountyFeature = pCountyCursor1.NextFeature();
pCountyName = pCountyFeature.get_Value(countyIndex);
Marshal.ReleaseComObject(pCountyCursor1);
Marshal.ReleaseComObject(pCountyFeature);

//属性查询,获取地形信息
pQueryFiler.WhereClause = "NAME=" + "'" + pCountyName + "'";
pTerrainCursor2 = pTerrainLayer.Search(pQueryFiler, false);
pTerrainFeature = pTerrainCursor2.NextFeature();
pTerrain = pTerrainFeature.get_Value(terrainIndex);
Marshal.ReleaseComObject(pTerrainCursor2);
Marshal.ReleaseComObject(pTerrainFeature);

//TextElement显示

if (elemText.Contains('X'))
{
elemText = elemText.Replace("X", pCountyName);
if (elemText.Contains('Y'))
{
elemText = elemText.Replace("Y", pTerrain);
}
}

else if (elemText.Contains("W"))
{
elemText = elemText.Replace("W", pCountyName);
if (elemText.Contains('Z'))
{
elemText = elemText.Replace("Z", pTerrain);
}
}
Marshal.ReleaseComObject(pFeature);
pFeature = pFeatureCursor0.NextFeature();
}
pTextElem.Text = elemText;
pActiveView.Refresh();
}

private void axToolbarControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IToolbarControlEvents_OnMouseDownEvent e)
{

}
}
}

第三次

仍然可以进一步优化,封装成类,提高可用性

try-catch的使用还需要继续学习

子类-父类,即面向对象掌握的不好

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.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.Controls;

namespace 地形信息查询new
{
//public class CanNotFindFieldException : Exception
//{
//}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//找点
try
{
IFeatureLayer pPointLayer = axMapControl1.get_Layer(0) as IFeatureLayer;
IFeatureLayer pTerrainLayer = axMapControl1.get_Layer(1) as IFeatureLayer;
IFeatureLayer pCountyPolygonLayer = axMapControl1.get_Layer(2) as IFeatureLayer;
IFeatureCursor pFeatureCursor0 = pPointLayer.Search(null, false);
IFeature pFeature = pFeatureCursor0.NextFeature();
IFeature pCountyFeature;
IFeature pTerrainFeature;
string pCountyName = null;
string pTerrain = null;
string whereClause = null;
string elemText = null;
int countyIndex = FindIndex(pCountyPolygonLayer, "NAME");
int terrainIndex = FindIndex(pTerrainLayer, "地形");
while (pFeature != null)
{
pCountyFeature = SpatialQuery(pFeature, pCountyPolygonLayer, esriSpatialRelEnum.esriSpatialRelWithin);
pCountyName = GetFieldValue(pCountyFeature, countyIndex);
whereClause = "NAME=" + "'" + pCountyName + "'";
pTerrainFeature = Query(pTerrainLayer, whereClause);
pTerrain = GetFieldValue(pTerrainFeature,terrainIndex);
elemText = "地震发生在" + pCountyName + ",地形信息为:" + pTerrain;
ShowElement(elemText, axMapControl1,pFeature);
pFeature = pFeatureCursor0.NextFeature();
}
}
catch (ex1)
{
MessageBox.Show("找不到字段");
}
catch (ex2)
{
MessageBox.Show("输入的空间查询信息有误,查询失败");
}
catch (ex3)
{
MessageBox.Show("输入的属性查询信息有误,查询失败");
}
catch (Exception exc)
{
MessageBox.Show("错误");
}

}
// 获得指定字段的位置索引
private int FindIndex(IFeatureLayer pLayer, string fieldString)
{
int pIndex = -1;

IFields pFields = pLayer.FeatureClass.Fields;
pIndex = pFields.FindField(fieldString);
if (pIndex < 0)
throw new ex1();
return pIndex;

}
// 通过空间查询,得到满足查询条件的要素
private IFeature SpatialQuery(IFeature pFeatureInput, IFeatureLayer pFeatureLayer,esriSpatialRelEnum pSpatialRel)
{
ISpatialFilter pSpatialFilter=new SpatialFilter();
pSpatialFilter.SpatialRel=pSpatialRel;
pSpatialFilter.Geometry = pFeatureInput.Shape;
IFeatureCursor pFLCursor =null;
pFLCursor = pFeatureLayer.Search(pSpatialFilter, false);
if (pFLCursor == null)
throw new ex3();
IFeature pFeatureNew = pFLCursor.NextFeature();
Marshal.ReleaseComObject(pFLCursor);
return pFeatureNew;
}
//属性查询要素
private IFeature Query(IFeatureLayer pFeatureLayer, string filterWhereClause)
{
IQueryFilter pQueryFilter = new QueryFilter();
pQueryFilter.WhereClause = filterWhereClause;
IFeatureCursor pFLCursor=null;
pFLCursor = pFeatureLayer.Search(pQueryFilter, false);
if (pFLCursor==null)
throw new ex2();
IFeature pFeature = pFLCursor.NextFeature();
Marshal.ReleaseComObject(pFLCursor);
return pFeature;
}
//查询要素值
private string GetFieldValue(IFeature pFeature,int fieldIndex)
{

string fieldValue=null;
try
{
fieldValue = pFeature.get_Value(fieldIndex).ToString();
return fieldValue;
}
catch(Exception ex)
{
MessageBox.Show("字段索引值超出范围,字段查询失败");
return null;
}

}
// 添加文本元素
private void ShowElement(string textString,AxMapControl ax,IFeature pFeature)
{
IMap pMap;
IActiveView pActiveView;
pMap = ax.Map;
pActiveView = pMap as IActiveView;

IEnvelope pEnvelope;
pEnvelope = pFeature.Extent;
IPoint pPoint = new PointClass();
pPoint.PutCoords(pEnvelope.XMin , pEnvelope.YMin);
ITextElement pTextElement;
IElement pElement;
pTextElement = new TextElementClass();
pTextElement.Text = textString;
pElement = pTextElement as IElement;

pElement.Geometry =(IGeometry) pPoint;
IGraphicsContainer pGraphicsContainer = ax.Map as IGraphicsContainer;
pGraphicsContainer.AddElement(pElement, 0);
pActiveView.Refresh();

//MessageBox.Show(textString);

}
private void axToolbarControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IToolbarControlEvents_OnMouseDownEvent e)
{

}
}
}

第四次

代码格式较为合理,冗余量小,异常捕捉比较到位

注意:初始赋值和是否成功执行以及条件判断的统一

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geometry;

namespace 地形信息查询new
{
public class MessageDisplay
{
#region 字段
private IMap _pMap;
#endregion

#region 属性
public IMap pMap
{
set { _pMap = value; }
get { return _pMap; }

}
#endregion

#region 方法
//找点
public void TerrainMessageDisplay(string pointLayerName,string countyLayerName,string terrainLayerName,
string selectedCountyField,string selectedTerrainField)
{
if (pMap == null)
{
MessageBox.Show("请加载地图");
}
try
{
IFeatureLayer pPointLayer = new FeatureLayerClass();//这里赋值为null更为合理
IFeatureLayer pTerrainLayer = new FeatureLayerClass();
IFeatureLayer pCountyPolygonLayer =new FeatureLayerClass();
for (int i = 0; i < pMap.LayerCount; i++)
{
if(pMap.get_Layer(i).Name==pointLayerName)
{
pPointLayer=pMap.get_Layer(i) as IFeatureLayer;
}
else if(pMap.get_Layer(i).Name==countyLayerName)
{
pCountyPolygonLayer=pMap.get_Layer(i) as IFeatureLayer;
}
else if(pMap.get_Layer(i).Name==terrainLayerName)
{
pTerrainLayer=pMap.get_Layer(i) as IFeatureLayer;
}
}
IFeatureCursor pFeatureCursor0 = pPointLayer.Search(null, false);
IFeature pFeature = pFeatureCursor0.NextFeature();
IFeature pCountyFeature;
IFeature pTerrainFeature;
string pCountyName = null;
string pTerrain = null;
string whereClause = null;
string elemText = null;
int countyIndex = FindIndex(pCountyPolygonLayer, selectedCountyField);
int terrainIndex = FindIndex(pTerrainLayer, selectedTerrainField);
while (pFeature != null)
{
pCountyFeature = SpatialQuery(pFeature, pCountyPolygonLayer, esriSpatialRelEnum.esriSpatialRelWithin);
pCountyName = GetFieldValue(pCountyFeature, countyIndex);
whereClause = selectedCountyField+"="+ "'" + pCountyName + "'";
pTerrainFeature = Query(pTerrainLayer, whereClause);
pTerrain = GetFieldValue(pTerrainFeature, terrainIndex);
elemText = "地震发生在" + pCountyName + ",地形信息为:" + pTerrain;
ShowElement(elemText, pMap, pFeature);
pFeature = pFeatureCursor0.NextFeature();
}
}
catch(Exception e)
{
MessageBox.Show("错啦");
}
}
// 获得指定字段的位置索引
private int FindIndex(IFeatureLayer pLayer, string fieldString)
{
if (pLayer == null)
{
MessageBox.Show("图层为空");
}
int pIndex = -1;
try
{
IFields pFields = pLayer.FeatureClass.Fields;
pIndex = pFields.FindField(fieldString);
return pIndex;
}
catch (Exception e)
{
MessageBox.Show("我错啦");
return pIndex;
}

}
// 通过空间查询,得到满足查询条件的要素
private IFeature SpatialQuery(IFeature pFeatureInput, IFeatureLayer pFeatureLayer, esriSpatialRelEnum pSpatialRel)
{
if (pFeatureInput == null || pFeatureLayer == null)
{
MessageBox.Show("空间查询要素为空");
}
if ( pFeatureLayer == null)
{
MessageBox.Show("空间查询目标图层为空");
}
if (pSpatialRel != esriSpatialRelEnum.esriSpatialRelWithin)
{
MessageBox.Show("请选择正确的空间查询关系");
//return null;
}
try
{
ISpatialFilter pSpatialFilter = new SpatialFilter();
pSpatialFilter.SpatialRel = pSpatialRel;
pSpatialFilter.Geometry = pFeatureInput.Shape;
IFeatureCursor pFLCursor = null;
pFLCursor = pFeatureLayer.Search(pSpatialFilter, false);
IFeature pFeatureNew = pFLCursor.NextFeature();
Marshal.ReleaseComObject(pFLCursor);
return pFeatureNew;
}
catch(Exception e)
{
MessageBox.Show("空间查询失败");
return null;
}
}
//属性查询要素
private IFeature Query(IFeatureLayer pFeatureLayer, string filterWhereClause)
{
if (pFeatureLayer == null)
{
MessageBox.Show("图层为空");
}
try
{
IQueryFilter pQueryFilter = new QueryFilter();
pQueryFilter.WhereClause = filterWhereClause;
IFeatureCursor pFLCursor = null;
pFLCursor = pFeatureLayer.Search(pQueryFilter, false);
IFeature pFeature = pFLCursor.NextFeature();
Marshal.ReleaseComObject(pFLCursor);
return pFeature;
}
catch(Exception e)
{
MessageBox.Show("属性查询失败");
return null;
}
}
//查询要素值
private string GetFieldValue(IFeature pFeature, int fieldIndex)
{

string fieldValue = null;
if(pFeature==null)
{
MessageBox.Show("要素为空,无法获取字段值");
}
if (fieldIndex >= pFeature.Fields.FieldCount)
{
MessageBox.Show("索引超出范围");
}
try
{
fieldValue = pFeature.get_Value(fieldIndex).ToString();
return fieldValue;
}
catch (Exception ex)
{
MessageBox.Show("字段查询失败");
return null;
}

}
// 添加文本元素
private void ShowElement(string textString,IMap pMap, IFeature pFeature)
{
if (pFeature == null)
{
MessageBox.Show("要素为空,无法添加文本元素");
}
try
{
IActiveView pActiveView;
pActiveView = pMap as IActiveView;

IEnvelope pEnvelope;
pEnvelope = pFeature.Extent;
IPoint pPoint = new PointClass();
pPoint.PutCoords(pEnvelope.XMin, pEnvelope.YMin);

ITextElement pTextElement;
IElement pElement;
pTextElement = new TextElementClass();
927b

pTextElement.Text = textString;
pElement = pTextElement as IElement;
pElement.Geometry = (IGeometry)pPoint;
IGraphicsContainer pGraphicsContainer =pMap as IGraphicsContainer;
pGraphicsContainer.AddElement(pElement, 0);
pActiveView.Refresh();
}
catch(Exception e)
{
MessageBox.Show("我怎么了");
}
//MessageBox.Show(textString);

}
#endregion

}
}


总结:
1,质量比数量重要

2,规范写程序的格式、方法

3,其实还可以再优化,优化也挺麻烦的,包括效率和结构的优化

4,注意异常捕捉,尽量减少程序崩溃的可能性,后期要学习将异常写入到日志文件当中

5,自定义函数中,通常要对传进来的参数进行判断

6,自定义的不需要返回值的函数可以把返回值设定为bool类型,以判断是否成功完成相应操作

7,写程序前可以将任务分解,理清执行顺序,一步一步实现程序
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: