实习期间第一个小程序

程序主要实现的功能是:判断点在哪个面内,并显示该面的相关信息

实现思路:

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 pTerrainFeature ;
            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();
                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,写程序前可以将任务分解,理清执行顺序,一步一步实现程序



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值