23 资源环境信息系统(GIS07)C#4_第1页
23 资源环境信息系统(GIS07)C#4_第2页
23 资源环境信息系统(GIS07)C#4_第3页
23 资源环境信息系统(GIS07)C#4_第4页
23 资源环境信息系统(GIS07)C#4_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、简单图层控制功能的实现数据的转换和可视化表达图层属性表的添加和显示图层的添加和移除图层间关系的调整步骤1:设计图层控制的菜单。响应ContextMenuStrip菜单控件,为图层控件添加菜单项(显示属性表菜单和删除图层菜单)。该菜单是在鼠标右键点击图层时弹出的快捷菜单。添加的菜单项修改菜单name属性步骤2:实现图层与图层控制菜单间的关联。响应TOCControl控件的OnMouseDown事件,添加相关代码。using ESRI.ArcGIS.Carto; /因为程序中用到ILayer和 /IBasicMap 接口,所以需要添加命名空间ILayer layer = new FeatureLa

2、yerClass();private void axTOCControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.ITOCControlEvents_OnMouseDownEvent e) this.axTOCControl1.ContextMenuStrip = null; IBasicMap map = new MapClass(); System.Object other = null; System.Object index = null; ESRI.ArcGIS.Controls.esriTOCControlItem item

3、 = ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemNone;this.axTOCControl1.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index); if (item = ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemLayer & e.button = 2) System.Drawing.Point pt = new System.Drawing.Poin

4、t(); pt.X = e.x; pt.Y = e.y; pt = this.axTOCControl1.PointToScreen(pt); this.图层控制菜单.Show(pt); 运行程序显示结果如下:步骤3:设计一个属性表窗体。1添加一个属性表窗体。2 为属性表窗体添加DataGridView控件,并修改控件Anchor属性为(Top, Bottom, Left, Right)。3 为属性表窗体编写相关代码,实现图层属性信息往属性表中的添加。 public partial class 属性表 : Form private ILayer layer; public 属性表(ILayer

5、 lyr) /对属性表窗口进行初始化 InitializeComponent(); layer = lyr; this.Text = + layer.Name + 属性表; private void 属性表_Load(object sender, EventArgs e) try ITable lyrtable = (ITable)layer; DataTable table = new DataTable(); IField field; for (int i = 0; i lyrtable.Fields.FieldCount; i+) field = lyrtable.Fields.get

6、_Field(i); table.Columns.Add(field.Name); object values = new objectlyrtable.Fields.FieldCount; IQueryFilter queryFilter = new QueryFilterClass(); ICursor cursor = lyrtable.Search(queryFilter, true); IRow row; while (row = cursor.NextRow() != null) for (int j = 0; j lyrtable.Fields.FieldCount; j+) o

7、bject ob = row.get_Value(j); valuesj = ob; table.Rows.Add(values); this.dataGridView1.DataSource = table; catch (Exception e1) MessageBox.Show(无法显示属性表!); this.Close(); 由于该段代码中用到了ILayer接口,所以要在属性表.cs开头添加命名空间ESRI.ArcGIS.Carto。同时也用到ITable, IQueryFilter, ICursor, IRow接口,所以要添加命名空间ESRI.ArcGIS.Geodatabase。即

8、添加如下代码:using ESRI.ArcGIS.Carto;using ESRI.ArcGIS.Geodatabase;但此时运行程序会报错:命名空间ESRI.ArcGIS中不存在类型名或命名空间名称Geodatabase(是缺少程序集引用吗?)。这时需要在资源管理器中将该程序集添加进来。右键点击引用,从弹出的菜单中点击“添加引用”菜单项,再在弹出的对话框中将ESRI.ArcGIS.Geodatabase命名空间添加进来步骤4:建立图层控制菜单与属性表的连接,实现属性表界面的显示。双击图层控制菜单上的“显示属性表”菜单项,在响应的Click事件中添加如下代码: private void 显示

9、属性表ToolStripMenuItem_Click(object sender, EventArgs e) 属性表 form = new 属性表(layer); form.Show(); 步骤5:运行程序,查看图层属性。右键点击该图层,从弹出快捷菜单中选择“显示属性表”菜单项。弹出该图层的属性表界面步骤6:这里实现一个通过属性表中属性查找图形要素的小功能。响应datagridView1控件的SelectionChanged事件。先在主窗口中编写一个公有函数,以获取主窗口的MapControl控件,因为该控件是Private类型。在其它窗体中不能直接调用。 public ESRI.ArcGIS

10、.Controls.AxMapControl getMapControl() return axMapControl1; 再在SelectionChanged事件中添加如下代码: private void dataGridView1_SelectionChanged(object sender, EventArgs e) DataGridViewSelectedRowCollection SelRows = this.dataGridView1.SelectedRows; DataGridViewRow row; 主窗口 form = (主窗口)Application.OpenForms0;

11、IMap m = form.getMapControl().Map; m.ClearSelection(); for (int i = 0; i SelRows.Count; i+) row = SelRowsi; int ID = Convert.ToInt32(row.CellsFID.Value.ToString(); IFeatureLayer flyr = (IFeatureLayer)layer; IFeatureClass featurecls = flyr.FeatureClass; IFeature feature = featurecls.GetFeature(ID); m

12、.SelectFeature(layer, feature); /获取属性表中选中行对应的图形要素 form.getMapControl().Refresh(); 运行程序,显示结果如下:属性表中选择一个点要素时,将其高亮显示属性表中拖动选择多个点要素时,将其高亮显示步骤1:在ToolBarControl控件中直接添加“图层添加”按钮,即可以实现图层添加功能(搭建的框架中已有该按钮)。步骤2:前面建立的图层控制菜单中已经包含了删除图层的菜单,此时只需要响应该菜单,编辑相关程序代码,即可以实现图层删除功能。双击该菜单项,响应Click事件在响应的Click事件中添加相关代码: private v

13、oid 删除此图层ToolStripMenuItem_Click(object sender, EventArgs e) for (int i = 0; i this.axMapControl1.Map.LayerCount; i+) if (this.axMapControl1.Map.get_Layer(i) = layer) this.axMapControl1.DeleteLayer(i); 运行程序,显示如下:删除biaozhidian图层前删除biaozhidian图层后在ArcMap中,要调整图层的现实顺序,只需要简单的鼠标拖拽就可以完成,既简单又直观。但是TOCControl控

14、件并未实现此功能。本实例即实现此功能。在本实例中主要利用TOCControl控件的OnMouseDown、OnMouseUp两个时间和HitTest()、Update()方法。OnMouseDown事件方法的主要功能是获取源图层pMovelayer。OnMouseUp事件方法的主要功能是:1) 获取目标图层及其索引号;2) 利用IMap提供的Movelayer(pMoveLayer, Toindex)将源图层pMoveLayer移到目标图层(Toindex)的下方;3)使用ITOCControl提供的Update()方法更新TOCControl控件中显示的内容。步骤1:在主窗口.cs中申明两个

15、全局变量,并响应TOCControl控件的OnMouseDown事件(前面已响应此事件),添加相关代码。/申明全局变量ILayer pMoveLayer;int Toindex;private void axTOCControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.ITOCControlEvents_OnMouseDownEvent e) /前面已添加代码,这里不需要再添加 this.axTOCControl1.ContextMenuStrip = null; IBasicMap map = new MapClass(); Syst

16、em.Object other = null; System.Object index = null; ESRI.ArcGIS.Controls.esriTOCControlItem item = ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemNone; this.axTOCControl1.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index); if (item = ESRI.ArcGIS.Controls.esriTOCControlI

17、tem.esriTOCControlItemLayer & e.button = 2) System.Drawing.Point pt = new System.Drawing.Point(); pt.X = e.x; pt.Y = e.y; pt = this.axTOCControl1.PointToScreen(pt); this.图层控制菜单.Show(pt); /该步骤要添加的代码,获取源图层 if (item = ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemLayer & e.button =

18、1) if (layer is IAnnotationSublayer) return; else pMoveLayer = layer; /layer是前面申明的一个全局变量 步骤2:响应TOCControl控件的OnMouseUp事件,并添加相关代码。双击OnMouseUp事件 private void axTOCControl1_OnMouseUp(object sender, ESRI.ArcGIS.Controls.ITOCControlEvents_OnMouseUpEvent e) if (e.button = 1) ESRI.ArcGIS.Controls.esriTOCCon

19、trolItem item = ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemNone; IBasicMap map = null; layer = null; object other = null; object index = null; this.axTOCControl1.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index); /HitTest是返回特定坐标下/的TOCControl控件的item IMap pMap = axMa

20、pControl1.ActiveView.FocusMap; /获取当前窗口中地图 if (item = ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemLayer | layer != null) if (pMoveLayer != layer) ILayer pTempLayer; for (int i = 0; i pMap.LayerCount; i+) pTempLayer = pMap.get_Layer(i); if (pTempLayer = layer) Toindex = i; pMap.MoveLayer

21、(pMoveLayer, Toindex); axMapControl1.ActiveView.Refresh(); this.axTOCControl1.Update(); /这里可以添加命名空间using ESRI.ArcGIS.Controls;这样就可以在编写一些代码时简化程序。如:ESRI.ArcGIS.Controls.esriTOCControlItem item = ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemNone;中:ESRI.ArcGIS.Controls.就可以省略。步骤3:运行程序,显示结果。图

22、层位置调整前图层位置调整后根据环保局、规划局等部门的需求分析,我们往往需要能在地形图上直观查看一些污染源信息,即要实现重点污染源、一般污染源数信息(数值数据)的可视化表达(图形数据)。本实例中即需要实现重点污染源信息的可视化表达。这是一个典型的将数值型数据转换为图形数据的过程。点击“查看重点污染源”菜单后,G101表中的重点污染源信息(主要是由经纬度标志的位置信息)生成点图层显示在图形显示窗口中。 新生成的点图层新生成点图层在地图上的显示1添加一个查看重点污染源的菜单;2点击该菜单时,生成一个“重点污染源”点图层,并在地图显示区域显示出来。 (1) 从数据源(G101表)中获取重点污染源的代码

23、、名称、 中心经度(度)、中心经度(分)、中心经度(秒)、中心纬度(度)、中心纬度(分)、中心纬度(秒)字段信息; (2)利用坐标转换公式将重点污染源的地理坐标(经纬度坐标)转换为高斯坐标(这里是北京54投影坐标系)。 (3)将转换坐标后的数据生成点图层,显示在图层显示区,并为该图层添加属性表信息。步骤1:添加数据显示菜单以及查看重点污染源菜单项。步骤2:双击“查看重点污染源”菜单项,响应该菜单命令,并编辑相关代码。(获取G101表中重点污染源的经纬度信息,通过相关坐标转换公式将经纬度转换为高斯坐标,并生成点图层在地图显示区显示出来。)/在主窗口.cs开头添加如下命名空间。其中/ESRI.Ar

24、cGIS.Geodatabase、/ESRI.ArcGIS.DataSourcesGDB等需要在引用中/添加进来using ESRI.ArcGIS.Geodatabase;using System.Data.OleDb;using ESRI.ArcGIS.Geometry;using ESRI.ArcGIS.esriSystem;using ESRI.ArcGIS.DataSourcesGDB;/一个创建图层的函数 public IFeatureLayer CreateFeatureLayerInmemeory(string DataSetName, string AliaseName, IS

25、patialReference SpatialRef, esriGeometryType GeometryType, IFields PropertyFields) IWorkspaceFactory workspaceFactory = new InMemoryWorkspaceFactoryClass(); ESRI.ArcGIS.Geodatabase.IWorkspaceName workspaceName = workspaceFactory.Create(, MyWorkspace, null, 0); ESRI.ArcGIS.esriSystem.IName name = (IN

26、ame)workspaceName; ESRI.ArcGIS.Geodatabase.IWorkspace inmemWor = (IWorkspace)name.Open(); IField oField = new FieldClass(); IFields oFields = new FieldsClass(); IFieldsEdit oFieldsEdit = null; IFieldEdit oFieldEdit = null; IFeatureClass oFeatureClass = null; IFeatureLayer oFeatureLayer = null; try o

27、FieldsEdit = oFields as IFieldsEdit; oFieldEdit = oField as IFieldEdit; for (int i = 0; i PropertyFields.FieldCount; i+) oFieldsEdit.AddField(PropertyFields.get_Field(i); IGeometryDef geometryDef = new GeometryDefClass(); IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef; geometryDefE

28、dit.AvgNumPoints_2 = 5; geometryDefEdit.GeometryType_2 = GeometryType; geometryDefEdit.GridCount_2 = 1; geometryDefEdit.HasM_2 = false; geometryDefEdit.HasZ_2 = false; geometryDefEdit.SpatialReference_2 = SpatialRef; /创建Shape字段 oFieldEdit.Name_2 = SHAPE; oFieldEdit.Type_2 = esriFieldType.esriFieldTy

29、peGeometry; oFieldEdit.GeometryDef_2 = geometryDef; oFieldEdit.IsNullable_2 = true; oFieldEdit.Required_2 = true; oFieldsEdit.AddField(oField); oFeatureClass = (inmemWor as IFeatureWorkspace).CreateFeatureClass(DataSetName, oFields, null, null, esriFeatureType.esriFTSimple, SHAPE, ); (oFeatureClass

30、as IDataset).BrowseName = DataSetName; oFeatureLayer = new FeatureLayerClass(); oFeatureLayer.Name = AliaseName; oFeatureLayer.FeatureClass = oFeatureClass; catch finally try System.Runtime.InteropServices.Marshal.ReleaseComObject(oField); System.Runtime.InteropServices.Marshal.ReleaseComObject(oFie

31、lds); System.Runtime.InteropServices.Marshal.ReleaseComObject(oFieldsEdit); System.Runtime.InteropServices.Marshal.ReleaseComObject(oFieldEdit); System.Runtime.InteropServices.Marshal.ReleaseComObject(name); System.Runtime.InteropServices.Marshal.ReleaseComObject(workspaceFactory); System.Runtime.In

32、teropServices.Marshal.ReleaseComObject(workspaceName); System.Runtime.InteropServices.Marshal.ReleaseComObject(inmemWor); System.Runtime.InteropServices.Marshal.ReleaseComObject(oFeatureClass); catch GC.Collect(); return oFeatureLayer; /响应查看重点污染源菜单项的Click事件private void 查看重点污染源ToolStripMenuItem_Click

33、(object sender, EventArgs e) /创建图层 IFields PropertyFields = new FieldsClass(); IFieldsEdit FieldsEdit = (IFieldsEdit)PropertyFields; /创建属性表,添加属性字段并编辑列名 IField Field = new FieldClass(); IFieldEdit FieldEdit = (IFieldEdit)Field; FieldEdit.Name_2 = FID; FieldEdit.AliasName_2 = FID; FieldEdit.Type_2 = e

34、sriFieldType.esriFieldTypeOID; FieldsEdit.AddField(FieldEdit); Field = new FieldClass(); FieldEdit = (IFieldEdit)Field; FieldEdit.Name_2 = 代码; FieldEdit.AliasName_2 = 代码; FieldEdit.Type_2 = esriFieldType.esriFieldTypeString; FieldsEdit.AddField(FieldEdit); Field = new FieldClass(); FieldEdit = (IFie

35、ldEdit)Field; FieldEdit.Name_2 = x; FieldEdit.AliasName_2 = x; FieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble; FieldsEdit.AddField(FieldEdit); Field = new FieldClass(); FieldEdit = (IFieldEdit)Field; FieldEdit.Name_2 = y; FieldEdit.AliasName_2 = y; FieldEdit.Type_2 = esriFieldType.esriFieldTyp

36、eDouble; FieldsEdit.AddField(FieldEdit);/添加点特征图层 IFeatureLayer PointFeatureLyr = CreateFeatureLayerInmemeory(重点污染源, 重点污染源, this.axMapControl1.Map.SpatialReference, esriGeometryType.esriGeometryPoint, PropertyFields); ITable table = (ITable)PointFeatureLyr; /图层属性表中各个属性的索引 int index_名称 = table.FindFie

37、ld(名称); int index_代码 = table.FindField(代码); int index_x = table.FindField(x); int index_y = table.FindField(y); int index_shape = table.FindField(shape);/建立与数据库的连接,通过SQL获取需要属性字段值 string sql = SELECT G101.代码, G101.名称, G101.中心经度(度), G101.中心经度(分), G101.中心经度(秒), G101.中心纬度(度), G101.中心纬度(分), G101.中心纬度(秒)

38、FROM G101; OleDbConnection conn = new OleDbConnection(Provider=Microsoft.Jet.OLEDB.4.0;Data Source= + Application.StartupPath + Database.mdb); OleDbCommand cmd = new OleDbCommand(sql, conn); int index_code = 0, index_name = 0, index_jd_D = 0, index_jd_F = 0, index_jd_M = 0, index_wd_D = 0, index_wd_

39、F = 0, index_wd_M = 0; int jd_D = 0, jd_F = 0, jd_M = 0, wd_D = 0, wd_F = 0, wd_M = 0; double jd_exp_M; /经度用秒表示 double wd_exp_M; /纬度用秒表示 double result_x = 0, result_y = 0; /转换之后的北京54投影坐标 string field_Name; try conn.Open(); OleDbDataReader reader = cmd.ExecuteReader(); int cols = reader.FieldCount; o

40、bject values = new objectcols; for (int index_Field = 0; index_Field cols; index_Field+) field_Name = reader.GetName(index_Field); switch (field_Name) case 代码: index_code = index_Field; break; case 名称: index_name = index_Field; break; case 中心经度(度): index_jd_D = index_Field; break; case 中心经度(分): inde

41、x_jd_F = index_Field; break; case 中心经度(秒): index_jd_M = index_Field; break; case 中心纬度(度): index_wd_D = index_Field; break; case 中心纬度(分): index_wd_F = index_Field; break; case 中心纬度(秒): index_wd_M = index_Field; break; IPoint pt; while (reader.Read() reader.GetValues(values); IRow row = table.CreateRo

42、w(); row.set_Value(index_名称, valuesindex_name); row.set_Value(index_代码, valuesindex_code); try jd_D = Convert.ToInt32(valuesindex_jd_D.ToString(); catch (Exception e1) jd_D = 0; try jd_F = Convert.ToInt32(valuesindex_jd_F.ToString(); catch (Exception e1) jd_F = 0; try jd_M = Convert.ToInt32(valuesin

43、dex_jd_M.ToString(); catch (Exception e1) jd_M = 0; try wd_D = Convert.ToInt32(valuesindex_wd_D.ToString(); catch (Exception e1) wd_D = 0; try wd_F = Convert.ToInt32(valuesindex_wd_F.ToString(); catch (Exception e1) wd_F = 0; try wd_M = Convert.ToInt32(valuesindex_wd_M.ToString(); catch (Exception e

44、1) wd_M = 0; jd_exp_M = jd_D * 3600 + jd_F * 60 + jd_M; wd_exp_M = wd_D * 3600 + wd_F * 60 + wd_M; GeoToGauss(jd_exp_M, wd_exp_M, 20, 6, ref result_y, ref result_x); row.set_Value(index_x, result_x); row.set_Value(index_y, result_y); pt = new PointClass(); pt.X = result_y; pt.Y = result_x; row.set_V

45、alue(index_shape, pt); row.Store(); reader.Close(); catch (Exception ex) MessageBox.Show(ex.Message, , MessageBoxButtons.OK, MessageBoxIcon.Error); finally conn.Close(); this.axMapControl1.AddLayer(ILayer)PointFeatureLyr); /*GeoToGauss函数功能说明: (1)将地理坐标(wd,jd)转换成绝对的高斯坐标(y,x) (2)本函数支持基于六度带(或三度带)、克拉索夫斯基

46、椭球进行转换 */ /* 适用范围: 本函数适用于将地球东半球中北半球(即东经0度到东经180度,北纬0度至90度)范围 内所有地理坐标到高斯坐标的转换 */ /* 使用说明: 调用本函数后返回的结果应在满足精度的条件下进行四舍五入 */ / double jd; 输入参数: 地理坐标的经度,以秒为单位 / double wd; 输入参数: 地理坐标的纬度,以秒为单位 / short DH; 输入参数: 三度带或六度带的带号 /* 六度带(三度带)的带号是这样得到的:从东经0度到东经180度自西向东按每6度(3度)顺序编号 (编号从1开始),这个顺序编号就称为六度带(三度带)的带号。因此,六度

47、带的带号的范围是1-30, 三度带的带号的范围是1-60。 如果一个点在图号为TH的图幅中,那麽该点所处的六度带的带号就可以这样得到:将该图号的 第3、4位组成的字符串先转换成数字,再减去30。例如某点在图幅06490701中,该点所在的带号就 是49-30,即19。 如果调用本函数去进行一般的从地理坐标到基于六度带高斯坐标的变换(非邻带转换),则参 数DH的选取按前一段的方法去确定。 如果调用本函数去进行基于六度带邻带转换,则参数DH的选取先按上述方法去确定,然后看是 往前一个带还是后一个带进行邻带转换再确定是加1还是减1。 */ public void GeoToGauss(double jd, double wd, short DH, short DH_width, ref do

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论