算法的思路是按照下面的帖子中来的 :
http://www.cnblogs.com/gisoracle/archive/2013/04/09/3009285.html
目的是将点数据批量匹配到离他最近的线数据上面,其他的都没什么问题,代码如下
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 System.Threading.Tasks;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Output;
using stdole;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.DataSourcesFile;
namespace shujujicheng
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void toolStripContainer1_TopToolStripPanel_Click(object sender, EventArgs e)
{
}
private void POI_Click(object sender, EventArgs e)
{
//查询缓冲区图层
IFeatureLayer ptLayer = queryFeatureLayer("point1");
//得到指定图层上距point最近的feature上的最近点
IFeatureClass ptFeatClass = ptLayer.FeatureClass;
// IFeatureCursor featureCursor = featureCursor = ptFeatClass.Search(null, false);
IFeatureCursor featureCursor = ptFeatClass.Search(null, false);
IFeature feature = featureCursor.NextFeature();
IPoint point = new PointClass();
while (feature != null)
{
point = feature.Shape as IPoint;
//查找离点最近的线
IFeature nearFea = GetNearestFeature(point, 1.2);
IPoint neaPoint = GetNearestPoint(point,nearFea);
neaPoint.Z = point.Z;
//移动点
MoveToNeaPoint(feature,point,neaPoint);
if (featureCursor == null || feature == null)
{
return;
}
feature = featureCursor.NextFeature();
}
MessageBox.Show("ok--");
}
//查询给定名称的图层
private IFeatureLayer queryFeatureLayer(string name)
{
// axMapControl1.AddShapeFile();
for (int i = 0; i < axMapControl1.LayerCount; i++)
{
ILayer layer = axMapControl1.get_Layer(i);
string nname = layer.Name; //新增
if (layer.Name.Equals(name))
{
return (IFeatureLayer)layer;
}
}
return null;
}
//得到指定图层上距point最近的feature上的最近点
public IPoint GetNearestPoint(IPoint point, IFeature nearFea) // private to public
{
IProximityOperator Proximity = (IProximityOperator)point;
IFeatureLayer FeaLyr = queryFeatureLayer("Line");
IFeatureClass FeaCls = FeaLyr.FeatureClass;
IQueryFilter queryFilter = null;
ITopologicalOperator topoOper = (ITopologicalOperator)point;
IGeometry geo = topoOper.Buffer(1.2);
ISpatialFilter sf = new SpatialFilterClass();
sf.Geometry = geo;
sf.GeometryField = FeaCls.ShapeFieldName;
sf.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
IFeatureCursor FeaCur = FeaCls.Search(queryFilter, false);
IFeature Fea = nearFea = FeaCur.NextFeature();
double minDistince, Distance;
if (Fea == null)
return null;
minDistince = Distance = Proximity.ReturnDistance((IGeometry)Fea.Shape); //最近的距离值
//保存距离最近的feature
Fea = FeaCur.NextFeature();
while (Fea != null)
{
Distance = Proximity.ReturnDistance((IGeometry)Fea.Shape);
if (Distance < minDistince)
{
minDistince = Distance;
nearFea = Fea;
}
Fea = FeaCur.NextFeature();
} //end while
Proximity = (IProximityOperator)nearFea.Shape;
return Proximity.ReturnNearestPoint(point, esriSegmentExtension.esriNoExtension);
}
//查找最近的线
public IFeature GetNearestFeature(IPoint p, double rongcha) // private to public
{
IFeature nearFea;
IProximityOperator Proximity = (IProximityOperator)p;
IFeatureLayer FeaLyr = queryFeatureLayer("Line");
IFeatureClass FeaCls = FeaLyr.FeatureClass;
IQueryFilter queryFilter = null;
IFeatureCursor FeaCur = FeaCls.Search(queryFilter, false);
IFeature Fea = nearFea = FeaCur.NextFeature();
double minDistince, Distance;
if (Fea == null)
return null;
minDistince = Distance = Proximity.ReturnDistance((IGeometry)Fea.Shape); //最近的距离值
//保存距离最近的feature
Fea = FeaCur.NextFeature();
while (Fea != null)
{
Distance = Proximity.ReturnDistance((IGeometry)Fea.Shape);
if (Distance < minDistince)
{
minDistince = Distance;
nearFea = Fea;
}
Fea = FeaCur.NextFeature();
} //end while
return nearFea;
}
private void MoveToNeaPoint(IFeature feature, IPoint point, IPoint neaPoint)
{
//IGeometry toGeometry = null;
IPoint geomType = new PointClass();
feature.Shape = neaPoint as IGeometry;
feature.Store();
}
private void Input_Click(object sender, EventArgs e)
{
AddShapefileUsingOpenFileDialog(this.axMapControl1.ActiveView);
}
public void AddShapefileUsingOpenFileDialog(ESRI.ArcGIS.Carto.IActiveView activeView)
{ //parameter check
if (activeView == null) { return; }
// Use the OpenFileDialog Class to choose which shapefile to load.
System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog();
//openFileDialog.InitialDirectory = "c:\\";
openFileDialog.InitialDirectory = "D:\\data";
// openFileDialog.InitialDirectory = "D:\\data";
openFileDialog.Filter = "Shapefiles (*.shp)|*.shp";
openFileDialog.FilterIndex = 2;
openFileDialog.RestoreDirectory = true;
openFileDialog.Multiselect = false;
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// The user chose a particular shapefile.
// The returned string will be the full path,
//filename and file-extension for the chosen shapefile.
//Example: "C:\test\cities.shp"
string shapefileLocation = openFileDialog.FileName;
if (shapefileLocation != "")
{
// Ensure the user chooses a shapefile
// Create a new ShapefileWorkspaceFactory CoClass to create a new workspace
IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactoryClass();
// System.IO.Path.GetDirectoryName(shapefileLocation)
//returns the directory part of the string. Example: "C:\test"
string dir = System.IO.Path.GetDirectoryName(shapefileLocation);
workspaceFactory.OpenFromFile(dir, 0);
IFeatureWorkspace featureWorkspace = (ESRI.ArcGIS.Geodatabase.IFeatureWorkspace)
workspaceFactory.OpenFromFile(dir, 0);
ESRI.ArcGIS.Geodatabase.IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(System.IO.Path.GetFileNameWithoutExtension(shapefileLocation));
ESRI.ArcGIS.Carto.IFeatureLayer featureLayer = new ESRI.ArcGIS.Carto.FeatureLayerClass();
featureLayer.FeatureClass = featureClass;
featureLayer.Name = featureClass.AliasName;
featureLayer.Visible = true;
activeView.FocusMap.AddLayer(featureLayer);
// Zoom the display to the full extent of all layers in the map
activeView.Extent = activeView.FullExtent;
activeView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeography, null, null);
}
else
{ // The user did not choose a shapefile.
// Do whatever remedial actions as necessary
System.Windows.Forms.MessageBox.Show("No shapefile chosen");
// System.Windows.Forms.MessageBoxButtons.OK,
// System.Windows.Forms.MessageBoxIcon.Exclamation);
}
}
}
运行结果在 minDistince = Distance = Proximity.ReturnDistance((IGeometry)Fea.Shape); 这句中提示未处理COMException,异常来自HRESULT:0x80040215
查阅了很多文档都不知到解决的办法,请各位指教。