当前位置:   article > 正文

C#Winform+AE开发 空间连接(SpatialJoin)以及字段映射(FieldMapping)(新手记录)_空间连接添加输入字段属性代码

空间连接添加输入字段属性代码

1,布局

连接要素的字段映射控件使用的是列表框ListBox

2,获取目标要素和连接要素

使用两种方式,一是自动获取当前地图加载的图层

  1.             #region 获取主窗口图层并添加到控件中
  2.             IMap myMap = form.getMapControl().Map;
  3.             IFeatureLayer pFeatLayer;
  4.             IFeatureClass pFeatureClass;
  5.             ICompositeLayer pCompLayer;
  6.             //遍历地图
  7.             for (int i = 0; i < myMap.LayerCount; i++)
  8.             {
  9.                 if (myMap.get_Layer(i) is IFeatureLayer)
  10.                 {
  11.                     //获得图层要素
  12.                     pFeatLayer = myMap.get_Layer(i) as IFeatureLayer;
  13.                     pFeatureClass = pFeatLayer.FeatureClass;
  14.                     if (pFeatureClass.ShapeType == esriGeometryType.esriGeometryPoint || pFeatureClass.ShapeType == esriGeometryType.esriGeometryLine || pFeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
  15.                     {
  16.                         ComboxTarget.Items.Add(pFeatLayer.Name);
  17.                     }
  18.                     if (pFeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon)
  19.                     {
  20.                         ComboxJoin.Items.Add(pFeatLayer.Name);
  21.                     }
  22.                 }
  23.                 else if (myMap.get_Layer(i) is IGroupLayer)
  24.                 {
  25.                     string name = myMap.get_Layer(i).Name;
  26.                     //遍历图层组
  27.                     pCompLayer = myMap.get_Layer(i) as ICompositeLayer;
  28.                     for (int j = 0; j < pCompLayer.Count; j++)
  29.                     {
  30.                         if (pCompLayer.get_Layer(j) is IFeatureLayer)
  31.                         {
  32.                             pFeatLayer = pCompLayer.get_Layer(j) as IFeatureLayer;
  33.                             pFeatureClass = pFeatLayer.FeatureClass;
  34.                             if (pFeatureClass.ShapeType == esriGeometryType.esriGeometryPoint || pFeatureClass.ShapeType == esriGeometryType.esriGeometryLine || pFeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
  35.                             {
  36.                                 ComboxTarget.Items.Add(name + @"\" + pFeatLayer.Name);
  37.                             }
  38.                             if (pFeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon)
  39.                             {
  40.                                 ComboxJoin.Items.Add(name + @"\" + pFeatLayer.Name);
  41.                             }
  42.                         }
  43.                     }
  44.                 }
  45.             }
  46.             #endregion

二是,从文件中选择图层并添加

  1. #region 从文件中选择输入图层添加到控件中
  2.             openFileDialog1.FileName = "";
  3.             openFileDialog1.Filter = "要素类|*.shp;*.dwg";
  4.             openFileDialog1.FilterIndex = 1;
  5.             if (openFileDialog1.ShowDialog() == DialogResult.OK)
  6.             {
  7.                 if (System.IO.Path.GetExtension(openFileDialog1.FileName) == ".DWG" || System.IO.Path.GetExtension(openFileDialog1.FileName) == ".dwg")
  8.                 {
  9.                     FileInfo fileInfo = new FileInfo(openFileDialog1.FileName);
  10.                     string path = fileInfo.Directory.ToString();
  11.                     string fileName = fileInfo.Name;
  12.                     IWorkspaceFactory pCadWorkspaceFactory = new CadWorkspaceFactoryClass();
  13.                     IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)pCadWorkspaceFactory.OpenFromFile(path, 0);
  14.                     IFeatureDataset pFeatureDataset = pFeatureWorkspace.OpenFeatureDataset(fileName);
  15.                     IFeatureClassContainer pFeatureClassContainer = pFeatureDataset as IFeatureClassContainer;
  16.                     //遍历CAD文件中的每个要素
  17.                     for (int i = 0; i < pFeatureClassContainer.ClassCount; i++)
  18.                     {
  19.                         IFeatureClass pFeatureClass = pFeatureClassContainer.get_Class(i);
  20.                         if (pFeatureClass.FeatureType != esriFeatureType.esriFTCoverageAnnotation)
  21.                         {
  22.                             IFeatureLayer pFeatureLayer = new FeatureLayerClass();
  23.                             pFeatureLayer.Name = pFeatureClass.AliasName;
  24.                             pFeatureLayer.FeatureClass = pFeatureClass;
  25.                             if (pFeatureClass.ShapeType == esriGeometryType.esriGeometryPoint || pFeatureClass.ShapeType == esriGeometryType.esriGeometryLine || pFeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
  26.                             {
  27.                                 this.ComboxTarget.Items.Add(openFileDialog1.FileName + @"\" + pFeatureLayer.Name);
  28.                             }
  29.                         }
  30.                     }
  31.                 }
  32.                 else
  33.                 {
  34.                     this.ComboxTarget.Items.Add(openFileDialog1.FileName);
  35.                 }
  36.             }
  37.             #endregion

3,关于字段映射

返回输入图层的完整路径

  1. #region 返回输入图层路径
  2. public string getInputLayerValue(string textValue)
  3. {
  4. #region 参数定义
  5. string InputValue = null;
  6. string mValue = textValue;
  7. IMap myMap = form.getMapControl().Map;
  8. IFeatureLayer[] pFeatureLayers = MyFeatureLayer.GetMyFeatureLayers(myMap);
  9. #endregion
  10. #region 获取输入点图层
  11. if (mValue.Contains(":"))//来自文件选择
  12. {
  13. InputValue = mValue;
  14. }
  15. else //来自主窗口加载图层
  16. {
  17. if (mValue.Contains(@"\")) //CAD要素类
  18. {
  19. int m = mValue.LastIndexOf(@"\");
  20. string pValue = mValue.Substring(m + 1);
  21. for (int i = 0; i < pFeatureLayers.Length; i++)//选择地图控件中与下拉框同名的地图图层
  22. {
  23. if (pFeatureLayers[i].Name == pValue)
  24. {
  25. ILayer mLayer = pFeatureLayers[i];
  26. IDataLayer dataLayer = mLayer as IDataLayer;
  27. IDatasetName pDsName = (IDatasetName)(dataLayer.DataSourceName);
  28. IWorkspaceName wsName = pDsName.WorkspaceName;
  29. string pathStr = wsName.PathName;
  30. string fileName = mValue;
  31. string fullName = System.IO.Path.Combine(pathStr, fileName);
  32. InputValue = fullName;
  33. break;
  34. }
  35. }
  36. }
  37. else //shp图层
  38. {
  39. for (int i = 0; i < pFeatureLayers.Length; i++)//选择地图控件中与下拉框同名的地图图层
  40. {
  41. if (pFeatureLayers[i].Name == mValue)
  42. {
  43. ILayer mLayer = pFeatureLayers[i];
  44. IDataLayer dataLayer = mLayer as IDataLayer;
  45. IDatasetName pDsName = (IDatasetName)(dataLayer.DataSourceName);
  46. IWorkspaceName wsName = pDsName.WorkspaceName;
  47. string pathStr = wsName.PathName;
  48. string fileName = pDsName.Name + ".shp";
  49. string fullName = System.IO.Path.Combine(pathStr, fileName);
  50. InputValue = fullName;
  51. break;
  52. }
  53. }
  54. }
  55. }
  56. return InputValue;
  57. #endregion
  58. }
  59. #endregion

添加字段映射,显示的模式是:图层名.字段名(字段类型)

  1. IGPUtilities gputilities = new GPUtilitiesClass();//gp应用程序类
  2. IGPFieldMapping mFieldMapping = new GPFieldMappingClass();
  3. IArray Tables = new ArrayClass();
  4. string pathA = "";
  5. string pathB = "";
  6. string TargetValue = null;
  7. string JoinValue = null;
  8. List<string> TargetFNlist = new List<string>();
  9. private void ComboxTarget_TextChanged(object sender, EventArgs e)
  10. {
  11. TargetFNlist.Clear();
  12. IDETable TargetTable;
  13. if (ComboxTarget.Text.Length > 0)
  14. {
  15. TargetValue = getInputLayerValue(ComboxTarget.Text);
  16. string tName = System.IO.Path.GetFileName(ComboxTarget.Text);
  17. //添加字段映射
  18. pathA = TargetValue;
  19. TargetTable = (IDETable)gputilities.MakeDataElement(pathA, null, null);
  20. Tables.Add(TargetTable);
  21. mFieldMapping.Initialize(Tables, null);
  22. for (int i = 0; i < mFieldMapping.Fields.FieldCount; i++)
  23. {
  24. IField pField = mFieldMapping.Fields.get_Field(i);
  25. IFieldEdit pEditField = (IFieldEdit)pField;
  26. TargetFNlist.Add(tName + "." + pField.Name + "(" + MyFieldType.SetMyFieldType(pEditField.Type) + ")");
  27. }
  28. }
  29. else
  30. {
  31. MessageBox.Show("还没有选择目标要素,请选择!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
  32. return;
  33. }
  34. }

 关于MyFieldType.SetMyFieldType(pEditField.Type),自定义的一个类,用来将英文的字段类型转为中文显示

  1. public static string SetMyFieldType(esriFieldType fieldType)//将EsriType 转换为String
  2. {
  3. switch (fieldType)
  4. {
  5. case esriFieldType.esriFieldTypeSmallInteger:
  6. return "短整型";
  7. case esriFieldType.esriFieldTypeInteger:
  8. return "长整型";
  9. case esriFieldType.esriFieldTypeSingle:
  10. return "浮点型";
  11. case esriFieldType.esriFieldTypeDouble:
  12. return "双精度";
  13. case esriFieldType.esriFieldTypeString:
  14. return "文本";
  15. case esriFieldType.esriFieldTypeDate:
  16. return "日期";
  17. case esriFieldType.esriFieldTypeOID:
  18. return "对象ID";
  19. case esriFieldType.esriFieldTypeGeometry:
  20. return "几何";
  21. default:
  22. return "文本";
  23. }
  24. }

重命名映射字段

  1. //定义一个文本框
  2. TextBox txtEdit = new TextBox();
  3. public SpatialJoinForm()
  4. {
  5. InitializeComponent();
  6. txtEdit.KeyDown += new KeyEventHandler(txtEdit_KeyDown);
  7. }
  8. /// <summary>
  9. /// 点击其它项 隐藏编辑框
  10. /// </summary>
  11. private void ListboxFields_MouseClick(object sender, MouseEventArgs e)
  12. {
  13. txtEdit.Visible = false;
  14. }
  15. /// <summary>
  16. /// 双击项时显示编辑框
  17. /// </summary>
  18. private void ListboxFields_DoubleClick(object sender, EventArgs e)
  19. {
  20. if (ListboxFields.Items.Count > 0)
  21. {
  22. int itemSelected = ListboxFields.SelectedIndex;
  23. string itemText = ListboxFields.Items[itemSelected].ToString();
  24. string TXT = mFieldMapping.Fields.get_Field(ListboxFields.SelectedIndex).Name;
  25. Rectangle rect = ListboxFields.GetItemRectangle(itemSelected);
  26. txtEdit.Parent = ListboxFields;
  27. txtEdit.Bounds = rect;
  28. txtEdit.Multiline = true;
  29. txtEdit.Visible = true;
  30. txtEdit.Text = TXT;
  31. txtEdit.Focus();
  32. txtEdit.SelectAll();
  33. }
  34. }
  35. /// <summary>  
  36. /// KeyDown事件定义  重命名字段
  37. /// </summary>  
  38. private void txtEdit_KeyDown(object sender, KeyEventArgs e)
  39. {
  40. //Enter键 更新项并隐藏编辑框  
  41. if (e.KeyCode == Keys.Enter)
  42. {
  43. IField ifd = mFieldMapping.Fields.get_Field(ListboxFields.SelectedIndex);
  44. IFieldEdit ife = (IFieldEdit)ifd;
  45. ife.Name_2 = txtEdit.Text;
  46. IGPFieldMap mFieldMap = mFieldMapping.GetFieldMap(ListboxFields.SelectedIndex);
  47. mFieldMap.OutputField = ife;
  48. mFieldMapping.ReplaceFieldMap(ListboxFields.SelectedIndex, mFieldMap);//修改字段名
  49. string path = mFieldMapping.GetFieldMap(ListboxFields.SelectedIndex).Fields.get_Field(0).Name.ToString();
  50. string name = System.IO.Path.GetFileName(path);
  51. int r = name.LastIndexOf(".shp");
  52. string filename = name.Substring(0, r);
  53. string type = MyFieldType.SetMyFieldType(mFieldMapping.Fields.get_Field(ListboxFields.SelectedIndex).Type);
  54. ListboxFields.Items[ListboxFields.SelectedIndex] = filename + "." + txtEdit.Text + "(" + type + ")";
  55. txtEdit.Visible = false;
  56. }
  57. //Esc键 直接隐藏编辑框  
  58. if (e.KeyCode == Keys.Escape)
  59. txtEdit.Visible = false;
  60. }

删除字段

  1. //删除字段
  2. private void BtnDelete_Click(object sender, EventArgs e)
  3. {
  4. if (ListboxFields.SelectedIndex > -1)
  5. {
  6. mFieldMapping.RemoveFieldMap(ListboxFields.SelectedIndex);
  7. ListboxFields.Items.RemoveAt(ListboxFields.SelectedIndex);
  8. }
  9. }

字段映射中所选字段的合并规则,使用了列表框的右键菜单contextMenuStrip1

  1. //右键点击ListBox的Item选中并弹出菜单
  2. private void ListboxFields_MouseDown(object sender, MouseEventArgs e)
  3. {
  4. if (e.Button == MouseButtons.Right)
  5. {
  6. System.Drawing.Point p = e.Location;//获取点击的位置
  7. int currentIndex = ListboxFields.IndexFromPoint(p);//根据位置获取右键点击项的索引
  8. if (ListboxFields.Items.Count > 0)
  9. {
  10. this.ListboxFields.SetSelected(currentIndex, true);
  11. if (currentIndex == ListboxFields.SelectedIndex)
  12. {
  13. this.ListboxFields.ContextMenuStrip = contextMenuStrip1;
  14. }
  15. else
  16. {
  17. this.ListboxFields.ContextMenuStrip = null;
  18. }
  19. }
  20. else
  21. {
  22. this.ListboxFields.ContextMenuStrip = null;
  23. }
  24. }
  25. }

关于选中一个item时,前面显示对号,使用了最死板的方法,代码重复性很高,有待改进。关于图片,使用的是资源文件,解决方案右击,选择属性,打开后按图选择,添加现有文件,添加下载的PNG之类的图片(16 * 16)即可

   

  1. #region 字段映射中所选字段的合并规则
  2. IGPFieldMap mrFieldmap;
  3. private void firstToolStripMenuItem_Click(object sender, EventArgs e)
  4. {
  5. firstToolStripMenuItem.Image = Properties.Resources.对号;
  6. lastToolStripMenuItem.Image = null;
  7. joinToolStripMenuItem.Image = null;
  8. sumToolStripMenuItem.Image = null;
  9. meanToolStripMenuItem.Image = null;
  10. medianToolStripMenuItem.Image = null;
  11. modeToolStripMenuItem.Image = null;
  12. minToolStripMenuItem.Image = null;
  13. maxToolStripMenuItem.Image = null;
  14. standardDeviationToolStripMenuItem.Image = null;
  15. countToolStripMenuItem.Image = null;
  16. //MessageBox.Show(ListboxFields.SelectedIndex.ToString());//所选行的Index
  17. //MessageBox.Show(ListboxFields.SelectedItem.ToString());//所选行的值
  18. mrFieldmap= mFieldMapping.GetFieldMap(ListboxFields.SelectedIndex);
  19. mrFieldmap.MergeRule =esriGPFieldMapMergeRule.esriGPFieldMapMergeRuleFirst;
  20. mFieldMapping.ReplaceFieldMap(ListboxFields.SelectedIndex, mrFieldmap);
  21. }
  22. 依次响应点击事件,修改Image和MergeRule,代码省略……
  23. ……………………………………………………………………………………………………………………………………………………
  24. #endregion

重置字段映射,即重新获取图层的全部字段,发生在不小心删除了不该删除的字段之后

  1. //重置字段
  2. private void BtnReset_Click(object sender, EventArgs e)
  3. {
  4. ListboxFields.Items.Clear();
  5. mFieldMapping.RemoveAll();
  6. mFieldMapping.Initialize(Tables, null);
  7. for (int i = 0; i < TargetFNlist.Count; i++)
  8. {
  9. ListboxFields.Items.Add(TargetFNlist[i]);
  10. }
  11. }

执行空间连接,并返回执行进度或错误提示

  1. Geoprocessor gp = new Geoprocessor();
  2. ESRI.ArcGIS.AnalysisTools.SpatialJoin sj = new ESRI.ArcGIS.AnalysisTools.SpatialJoin();
  3. IGeoProcessorResult2 JSresult = null;
  4. //关于获取输入图层和判断输出图层名称是否有误代码省略……
  5. ……………………………………………………
  6. sj.target_features = TargetValue;
  7. sj.join_features = JoinValue;
  8. sj.out_feature_class = TextBoxOutput.Text;
  9. sj.join_operation = JoinOperation.Text;
  10. sj.join_type = "KEEP_ALL";
  11. sj.match_option = ComboxMatchOption.Text;
  12. sj.field_mapping = mFieldMapping;
  13. //执行并返回错误信息
  14. try
  15. {
  16. JSresult = gp.Execute(sj, null) as IGeoProcessorResult2;
  17. }
  18. catch (Exception ex)
  19. {
  20. MessageBox.Show(ex.Message, "GP Error");
  21. }
  22. finally
  23. {
  24. System.Text.StringBuilder sb = new System.Text.StringBuilder();
  25. for (int i = 0; i < gp.MessageCount; i++)
  26. sb.AppendLine(gp.GetMessage(i));
  27. if (sb.Capacity > 0) MessageBox.Show(sb.ToString(), "GP Messages");
  28. }

总结到此为止。还有添加字段到字段映射中,不想写了,等到需要用的时候再写吧。
           

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/253616
推荐阅读
相关标签
  

闽ICP备14008679号