ArcEngine 开发点批量移动到线上小程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArcEngine 开发点批量移动到线上小程序相关的知识,希望对你有一定的参考价值。
算法的思路是按照下面的帖子中来的 :
http://www.cnblogs.com/gisoracle/archive/2013/04/09/3009285.html
查找相关资料是因为在做供水管网的时候,发现很多CAD转到ArcGIS中的数据,有很多管件与管线有一定的偏差。这个程序的功能就是批量的将管件点移动到管线上。
界面设计:
用到了winform和devexpress的控件库。
代码如下:
1 using ESRI.ArcGIS.Carto; 2 using ESRI.ArcGIS.Geodatabase; 3 using ESRI.ArcGIS.Geometry; 4 using System; 5 using System.Collections.Generic; 6 using System.ComponentModel; 7 using System.Data; 8 using System.Drawing; 9 using System.Linq; 10 using System.Text; 11 using System.Windows.Forms; 12 13 namespace MovePointToLine 14 { 15 public partial class FrmMain1 : DevExpress.XtraEditors.XtraForm 16 { 17 public FrmMain1() 18 { 19 InitializeComponent(); 20 } 21 22 private IFeatureLayer pointFlayer; 23 private IFeatureLayer LineFlayer; 24 //初始化图层列表 25 private void cmbSelectLineLayer_MouseClick(object sender, MouseEventArgs e) 26 { 27 DevExpress.XtraEditors.ComboBoxEdit c = sender as DevExpress.XtraEditors.ComboBoxEdit; 28 c.Properties.Items.Clear(); 29 30 IMap map = axMapControl1.Map; 31 if (map != null) 32 { 33 for (int i = 0; i < map.LayerCount; i++) 34 { 35 c.Properties.Items.Add(map.get_Layer(i).Name); 36 } 37 } 38 } 39 private void cmbSelectPointLayer_MouseClick(object sender, MouseEventArgs e) 40 { 41 DevExpress.XtraEditors.ComboBoxEdit c = sender as DevExpress.XtraEditors.ComboBoxEdit; 42 c.Properties.Items.Clear(); 43 44 IMap map = axMapControl1.Map; 45 if (map != null) 46 { 47 for (int i = 0; i < map.LayerCount; i++) 48 { 49 c.Properties.Items.Add(map.get_Layer(i).Name); 50 } 51 } 52 } 53 //获取线图层 54 private void cmbSelectLineLayer_SelectedIndexChanged(object sender, EventArgs e) 55 { 56 try 57 { 58 ILayer layer = getLayerFromName(cmbSelectLineLayer.SelectedItem.ToString()); 59 LineFlayer = layer as IFeatureLayer; 60 } 61 catch (Exception ex) 62 { 63 MessageBox.Show(ex.Message); 64 } 65 } 66 //获取点图层 67 private void cmbSelectPointLayer_SelectedIndexChanged(object sender, EventArgs e) 68 { 69 ILayer layer = getLayerFromName(cmbSelectPointLayer.SelectedItem.ToString()); 70 pointFlayer = layer as IFeatureLayer; 71 } 72 73 private void Run_Click(object sender, EventArgs e) 74 { 75 splashScreenManager1.ShowWaitForm(); 76 try 77 { 78 //查询缓冲区图层 79 IFeatureLayer ptLayer = pointFlayer; 80 //得到指定图层上距point最近的feature上的最近点 81 IFeatureClass ptFeatClass = ptLayer.FeatureClass; 82 IFeatureCursor featureCursor = featureCursor = ptFeatClass.Search(null, false); 83 IFeature feature = featureCursor.NextFeature(); 84 IPoint point = new PointClass(); 85 while (feature != null) 86 { 87 point = feature.Shape as IPoint; 88 //查找离点最近的线 89 IFeature nearFea = GetNearestFeature(point); 90 IPoint neaPoint = GetNearestPoint(point, nearFea); 91 neaPoint.Z = point.Z; 92 //移动点 93 MoveToNeaPoint(feature, point, neaPoint); 94 if (featureCursor == null || feature == null) 95 { 96 return; 97 } 98 feature = featureCursor.NextFeature(); 99 } 100 axMapControl1.Refresh(); 101 102 memoEdit1.Text = memoEdit1.Text + "\\r\\n" + "恭喜你,执行成功!"; 103 memoEdit1.SelectionStart = memoEdit1.Text.Length; 104 memoEdit1.ScrollToCaret(); 105 } 106 catch (Exception ex) 107 { 108 memoEdit1.Text = memoEdit1.Text + "\\r\\n" + "处理失败,请检查!" + "\\r\\n" + ex.Message; 109 memoEdit1.SelectionStart = memoEdit1.Text.Length; 110 memoEdit1.ScrollToCaret(); 111 } 112 splashScreenManager1.CloseWaitForm(); 113 } 114 115 //查找最近的线 116 public IFeature GetNearestFeature(IPoint p) 117 { 118 IFeature nearFea; 119 IProximityOperator Proximity = (IProximityOperator)p; 120 IFeatureLayer FeaLyr = LineFlayer; 121 IFeatureClass FeaCls = FeaLyr.FeatureClass; 122 IQueryFilter queryFilter = null; 123 IFeatureCursor FeaCur = FeaCls.Search(queryFilter, false); 124 IFeature Fea = nearFea = FeaCur.NextFeature(); 125 double minDistince, Distance; 126 if (Fea == null) 127 return null; 128 minDistince = Distance = Proximity.ReturnDistance((IGeometry)Fea.Shape); //最近的距离值 129 //保存距离最近的feature 130 Fea = FeaCur.NextFeature(); 131 while (Fea != null) 132 { 133 Distance = Proximity.ReturnDistance((IGeometry)Fea.Shape); 134 if (Distance < minDistince) 135 { 136 minDistince = Distance; 137 nearFea = Fea; 138 } 139 Fea = FeaCur.NextFeature(); 140 } //end while 141 return nearFea; 142 } 143 144 //point最近的feature上的最近点 145 public IPoint GetNearestPoint(IPoint point, IFeature nearFea) 146 { 147 IProximityOperator Proximity = (IProximityOperator)point; 148 IFeatureLayer FeaLyr = LineFlayer; 149 IFeatureClass FeaCls = FeaLyr.FeatureClass; 150 IQueryFilter queryFilter = null; 151 ITopologicalOperator topoOper = (ITopologicalOperator)point; 152 IGeometry geo = topoOper.Buffer(1.2); 153 ISpatialFilter sf = new SpatialFilterClass(); 154 sf.Geometry = geo; 155 sf.GeometryField = FeaCls.ShapeFieldName; 156 sf.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses; 157 IFeatureCursor FeaCur = FeaCls.Search(queryFilter, false); 158 IFeature Fea = nearFea = FeaCur.NextFeature(); 159 double minDistince, Distance; 160 if (Fea == null) 161 return null; 162 minDistince = Distance = Proximity.ReturnDistance((IGeometry)Fea.Shape); //最近的距离值 163 //保存距离最近的feature 164 Fea = FeaCur.NextFeature(); 165 while (Fea != null) 166 { 167 Distance = Proximity.ReturnDistance((IGeometry)Fea.Shape); 168 if (Distance < minDistince) 169 { 170 minDistince = Distance; 171 nearFea = Fea; 172 } 173 Fea = FeaCur.NextFeature(); 174 } //end while 175 Proximity = (IProximityOperator)nearFea.Shape; 176 return Proximity.ReturnNearestPoint(point, esriSegmentExtension.esriNoExtension); 177 178 } 179 /// <summary> 180 /// 移动点 181 /// </summary> 182 /// <param name="feature"></param> 183 /// <param name="point"></param> 184 /// <param name="neaPoint"></param> 185 private void MoveToNeaPoint(IFeature feature, IPoint point, IPoint neaPoint) 186 { 187 IPoint geomType = new PointClass(); 188 feature.Shape = neaPoint as IGeometry; 189 feature.Store(); 190 } 191 192 /// <summary> 193 /// 通过图层名得到图层 194 /// </summary> 195 /// <param name="layerName"></param> 196 /// <returns></returns> 197 private ILayer getLayerFromName(string layerName) 198 { 199 ILayer layer; 200 IMap map = axMapControl1.Map; 201 for (int i = 0; i < map.LayerCount; i++) 202 { 203 layer = map.get_Layer(i); 204 if (layerName == layer.Name) 205 return layer; 206 } 207 return null; 208 } 209 210 } 211 }
以上是关于ArcEngine 开发点批量移动到线上小程序的主要内容,如果未能解决你的问题,请参考以下文章