在要素檢查中,我們經常遇到線段打折的情形,本文要解決的就是如何和快速監測出這些折角;主要內容包含如下內容:
- 計算相鄰三點的夾角公式
- 從線狀要素中獲取其折點座標
- 由折點座標,逐點判定是否有不滿足閾值要求的折角出現,如有則輸出記錄
目錄
目錄
1. 計算兩個向量之間的夾角
1.1 基礎數學理論:
1.2 代碼實現
權限許可與環境搭建參見博文:
C#編程學習10:ArcGIS、ArcEngine安裝簡要教程及C#程序創建
可能用到名稱空間:
using ESRI.ArcGIS.Carto;
using System.Data.OleDb;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.DataManagementTools;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Geodatabase;
反餘弦曲線
引子:兩種shape文件數據庫操作的方法
- 通過FeatureLayer 找到數據庫
IfeatureClass featClass = featureLayer.FeatureClass;
IDataSet dataset = featClass as IDataset;
IWorkspace ws = dataset.Workspace;
- 通過數據庫文件讀取數據
IWorkspaceFactory wsf = new ShapefileWorkspaceFactory();
IWorkspace pWorkspace = wsf.Open(filePath, 0) ;//filePath爲shapefile所在的文件夾
IFeatureWorkspace pFeatureWorkspace = pWorkspace ;
IFeatureClass pFeatureClass = pFeatureWorkspace.OpenFeatureClass("parcels");//parcels爲shapefile文件名pacels.shp
兩個重載版本:
- 基於IPoint接口的版本
- 基於System.Drawing.PointF的版本
/// <summary>
/// 計算連續三點構成的兩個向量的夾角
/// </summary>
/// <param name="pt1">起點1</param>
/// <param name="pt2">連接點2</param>
/// <param name="pt3">終點3</param>
/// <returns>向量夾角</returns>
public double calAngleVectors(IPoint pt1, IPoint pt2, IPoint pt3)
{
IPoint vec1 = new ESRI.ArcGIS.Geometry.Point();
vec1.X = pt2.X - pt1.X;
vec1.Y = pt2.Y - pt1.Y;
IPoint vec2 = new ESRI.ArcGIS.Geometry.Point();
vec2.X = pt3.X - pt2.X;
vec2.Y = pt3.Y - pt2.Y;
double len1 = Math.Sqrt(vec1.X * vec1.X + vec1.Y * vec1.Y);
double len2 = Math.Sqrt(vec2.X * vec2.X + vec2.Y * vec2.Y);
double v12 = vec1.X*vec2.X + vec1.Y*vec2.Y;
double cos = v12 / (len1 * len2);
return Math.Acos(cos) * 180 / Math.PI;
}
/// <summary>
/// 計算連續三點構成的兩個向量的夾角
/// </summary>
/// <param name="pt1">起點1</param>
/// <param name="pt2">連接點2</param>
/// <param name="pt3">終點3</param>
/// <returns>向量夾角</returns>
public double calAngleVectors(System.Drawing.PointF pt1, System.Drawing.PointF pt2, System.Drawing.PointF pt3)
{
System.Drawing.PointF vec1 = new System.Drawing.PointF();
vec1.X = pt2.X - pt1.X;
vec1.Y = pt2.Y - pt1.Y;
System.Drawing.PointF vec2 = new System.Drawing.PointF();
vec2.X = pt3.X - pt2.X;
vec2.Y = pt3.Y - pt2.Y;
double len1 = Math.Sqrt(vec1.X * vec1.X + vec1.Y * vec1.Y);
double len2 = Math.Sqrt(vec2.X * vec2.X + vec2.Y * vec2.Y);
double v12 = vec1.X * vec2.X + vec1.Y * vec2.Y;
double cos = v12 / (len1 * len2);
double arc = Math.Acos(cos);
return Math.Acos(cos) * 180 / Math.PI;
}
1.3 測試代碼
float tmp = (float)(Math.Sqrt(3.0));
double re = calAngleVectors(new PointF(1-tmp,0), new PointF(1,1), new PointF(0,0));
//連續三個點座標爲(1-sqrt(3), 0), (1,1), (0,0),構成夾角爲15度
2. 對數據集中的線要素進行檢測
步驟如下:
- 獲取要處理的數據庫、線要素層
- 線要素層節點提取
- 逐三點監測其夾角是否滿足閾值
- 小於規定閾值的,將其中點座標加入到監測列表中
2.1 逐點檢查
注意:折角的cos值爲負,如果你要檢查小於15度的折角,判斷條件應爲180-15=165
第二個參數dsPath不要也行
/// <summary>
/// 檢測當前線層是否包含小於指定閾值的折角
/// </summary>
/// <param name="wsPath">工作空間路徑</param>
/// <param name="dsPath">數據集路徑</param>
/// <param name="feaPath">要素層名稱</param>
/// <param name="angleLimit">折角界限</param>
/// <returns>夾角在指定閾值內的點集</returns>
public List<IPoint> checkAngle(string wsPath, string dsPath, string feaPath, double angleLimit)
{
//1. 打開工作空間
// Open the workspace and the required datasets.
Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.AccessWorkspaceFactory");
//ESRI.ArcGIS.DataSourcesGDB
IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactory();
IWorkspace workspace = workspaceFactory.OpenFromFile(wsPath, 0);
IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
//2. 打開數據集,這一步可以省略不要,這樣就不用傳遞第二個參數了
IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(dsPath);
//3. 打開要素層
IFeatureClass pFeaterClass = featureWorkspace.OpenFeatureClass(feaPath);
//4. 查詢所有要素
string where = "";
IQueryFilter filter = new QueryFilterClass();
filter.WhereClause = where;
//5.定義查詢遊標並循環迭代
IFeatureCursor pFeatcursor = pFeaterClass.Search(filter, false);
IFeature pFeature = pFeatcursor.NextFeature();
//6. 運算結果存儲
List<IPoint> liPts = new List<IPoint>();
//7. 循環遍歷
while (pFeature != null)
{
int cnt = pFeature.Fields.FieldCount;
esriFeatureType type = pFeature.FeatureType;//獲取要素的類型
IPointCollection pPc = pFeature.Shape as IPointCollection;
int ptCnt = pPc.PointCount;//獲取當前要素中的點數
//7.1 跳過沒有折點的線段
if (ptCnt >= 2)
{
string coors = string.Empty;
for (int i = 0; i < ptCnt - 2; i++)
{
double angle = calAngleVectors(pPc.Point[i], pPc.Point[i + 1], pPc.Point[i + 2]);
if (angle >= (180 - angleLimit))
{
liPts.Add(pPc.Point[i+1]);
//sw.WriteLine(pPc.Point[i + 1].X.ToString() + "," + pPc.Point[i + 1].Y.ToString());
}
//獲取線要素所有折點座標並顯示
//coors += pPc.Point[i].X +", "+ pPc.Point[i].Y + "\n";
//coors += angle.ToString() + "\n";
}
//MessageBox.Show(coors, "當前要素的節點座標集合");
}
//將遊標移動到下一個要素
pFeature = pFeatcursor.NextFeature();
}
return liPts;
}
2.2 調用執行
private void buttonExecute_Click(object sender, EventArgs e)
{
try
{
string inPath = textBoxInput.Text;
string ouPath = textBoxOutput.Text;
if (System.IO.File.Exists(inPath) && System.IO.Path.GetFileName(ouPath) != "")
{
System.IO.StreamWriter sw = new System.IO.StreamWriter(ouPath);
List<IPoint> pts = checkAngle(inPath, "Topology", "LRDL", 15);
foreach (IPoint pt in pts)
{
sw.WriteLine(pt.X.ToString() + ", " + pt.Y.ToString());
}
sw.Close();
sw.Dispose();
}
MessageBox.Show("折角檢查完畢", "完成提示");
}
catch (Exception ex)
{
MessageBox.Show("觸發異常操作:" + ex.ToString(), "執行失敗");
}
}
2.3 結果展示
步驟:
- 添加導出的txt數據
- 右鍵,顯示XY數據
小於閾值的折點被顯示出來,之後右鍵-->數據-->導出數據,輸出爲shp要素類
3 ArcGIS提取線要素的折點座標並顯示的方法
3.1 要素折點轉點
ArcToolBox --> 數據管理工具 --> 要素 --> 要素折點轉點
拖入要轉點的要素,確定
添加xy座標,將剛纔轉的要素層拖入,確定
打開屬性表,即可看到折點座標:
3.2 AE+C# 代碼獲取線要素的折點座標集
/// <summary>
/// 獲取當前線層所有折點座標
/// </summary>
/// <param name="wsPath">工作空間路徑</param>
/// <param name="dsPath">數據集路徑</param>
/// <param name="feaPath">要素層名稱</param>
/// <returns>折點集</returns>
public List<IPoint> getAllPointFromLine(string wsPath, string dsPath, string feaPath)
{
//1. 打開工作空間
// Open the workspace and the required datasets.
Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.AccessWorkspaceFactory");
//ESRI.ArcGIS.DataSourcesGDB
IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactory();
IWorkspace workspace = workspaceFactory.OpenFromFile(wsPath, 0);
IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
//2. 打開數據集
IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(dsPath);
//3. 打開要素層
IFeatureClass pFeaterClass = featureWorkspace.OpenFeatureClass(feaPath);
//4. 查詢所有要素
string where = "";
IQueryFilter filter = new QueryFilterClass();
filter.WhereClause = where;
//5.定義查詢遊標並循環迭代
IFeatureCursor pFeatcursor = pFeaterClass.Search(filter, false);
IFeature pFeature = pFeatcursor.NextFeature();
//6. 運算結果存儲
List<IPoint> liPts = new List<IPoint>();
//7. 循環遍歷
while (pFeature != null)
{
int cnt = pFeature.Fields.FieldCount;
esriFeatureType type = pFeature.FeatureType;//獲取要素的類型
IPointCollection pPc = pFeature.Shape as IPointCollection;
int ptCnt = pPc.PointCount;//獲取當前要素中的點數
string coors = string.Empty;
for (int i = 0; i < ptCnt; i++)
{
liPts.Add(pPc.Point[i]);
}
//將遊標移動到下一個要素
pFeature = pFeatcursor.NextFeature();
}
return liPts;
}
測試代碼:
private void buttonExecute_Click(object sender, EventArgs e)
{
try
{
string inPath = textBoxInput.Text;
string ouPath = textBoxOutput.Text;
if (System.IO.File.Exists(inPath) && System.IO.Path.GetFileName(ouPath) != "")
{
System.IO.StreamWriter sw = new System.IO.StreamWriter(ouPath);
List<IPoint> pts = getAllPointFromLine(inPath, "Topology", "LRDL");
foreach (IPoint pt in pts)
{
sw.WriteLine(pt.X.ToString() + ", " + pt.Y.ToString());
}
sw.Close();
sw.Dispose();
}
MessageBox.Show("折角檢查完畢", "完成提示");
}
catch (Exception ex)
{
MessageBox.Show("觸發異常操作:" + ex.ToString(), "執行失敗");
}
}
3.3 測試結果:
3.4 面要素折角
面折角監測與線折角監測的區別:
- 線要素是開放的,面要素的是封閉的
- 提取的線要素點集,個數等於線要素包含的實際節點數
- 提取的面要素的點集,個數爲面要素節點數目+1;也就是說,面要素的第一個點算了兩次;我們在進行面折角檢查時,由於我們選擇的是連續的三個節點,因此需要把第二個點再加入進行計算
如下圖,提取的面要素的點集提取的0,1,2,3,4,5;其中的5和0是同一個點;現在我們要將點集改成0,1,2,3,4,5,1,也就是把倒數第二個點加到最後。
/// <summary>
/// 檢測當前線層是否包含小於指定閾值的折角
/// </summary>
/// <param name="wsPath">工作空間路徑</param>
/// <param name="feaPath">要素層名稱</param>
/// <param name="angleLimit">折角界限</param>
/// <returns>夾角在指定閾值內的點集</returns>
public List<IPoint> checkAngle(string wsPath, string feaPath, double angleLimit)
{
//1. 打開工作空間
// Open the workspace and the required datasets.
Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.AccessWorkspaceFactory");
//ESRI.ArcGIS.DataSourcesGDB
IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactory();
IWorkspace workspace = workspaceFactory.OpenFromFile(wsPath, 0);
IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
//2. 打開數據集
//IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(dsPath);
//3. 打開要素層
IFeatureClass pFeaterClass = featureWorkspace.OpenFeatureClass(feaPath);
//4. 查詢所有要素
string where = "";
IQueryFilter filter = new QueryFilterClass();
filter.WhereClause = where;
//5.定義查詢遊標並循環迭代
IFeatureCursor pFeatcursor = pFeaterClass.Search(filter, false);
IFeature pFeature = pFeatcursor.NextFeature();
//6. 運算結果存儲
List<IPoint> liPts = new List<IPoint>();
//7. 循環遍歷
while (pFeature != null)
{
int cnt = pFeature.Fields.FieldCount;
esriFeatureType type = pFeature.FeatureType;//獲取要素的類型
IPointCollection pPc = pFeature.Shape as IPointCollection;
//獲取幾何要素的類型
//注意,由於面狀要素是封閉的,故得到的點集中第一個點座標和最後一個點座標是一樣的
//在面折角檢查時,需要檢查時在需要在提取點集的最後位置添加點集中的第二個點
esriGeometryType geoType = pFeature.Shape.GeometryType;
if (geoType == esriGeometryType.esriGeometryPolygon)
{
//面是封閉的,因此將第二個點加入加進去參與計算
pPc.AddPoint(pPc.Point[1]);
}
int ptCnt = pPc.PointCount;//獲取當前要素中的點數
//7.1 跳過只有起點和終點的線段
if (ptCnt >= 2)
{
//string coors = string.Empty;
for (int i = 0; i < ptCnt - 2; i++)
{
double angle = calAngleVectors(pPc.Point[i], pPc.Point[i + 1], pPc.Point[i + 2]);
if (angle >= (180 - angleLimit))
{
liPts.Add(pPc.Point[i + 1]);
}
}
}
//將遊標移動到下一個要素
pFeature = pFeatcursor.NextFeature();
}
return liPts;
}
3.5 改進版本
對於面中包含房屋等漏洞的情形,可能存在內外邊界銜接點處計算出本不必要的面折角
因此需要對面的折角識別進行必要的拆分,即先提取出構成面幾何圖形,然後逐個幾何圖形進行檢查
此部分代碼參見文末公衆號:
4 將結果導出爲shp文件
注意事項:
- 在給定的結果目錄下指定工作空間
- 設置shape文件的字段集合,包括幾何類型、座標系統、以及自己定義的字段
- 字段值的設置
- 圖形賦值,即將點要素賦值給shape文件的要素當中
4.1 點集導出爲shape文件的自定義函數
本函數獲取投影座標的操作比較蹩腳,若以後找到更好的辦法,在進行修改
/// <summary>
/// 將點集導出爲shp文件
/// </summary>
/// <param name="inPath">輸入數據集</param>
/// <param name="liPts">要導出的點集</param>
/// <param name="checkLayerName">點集的來源圖層</param>
/// <param name="ouPath">導出的shape文件的結果保存路徑</param>
public void ExportPtsToShapefile(string inPath, List<IPoint> liPts, string checkLayerName, string ouPath)
{
//1. 打開工作空間
string strShapeFolder = System.IO.Path.GetDirectoryName(ouPath);
const string strShapeFieldName = "shape";
IWorkspaceFactory pWSF = new ShapefileWorkspaceFactoryClass();
IFeatureWorkspace pWS = (IFeatureWorkspace)pWSF.OpenFromFile(strShapeFolder,0);
//2. 設置字段集
IFields pFields = new FieldsClass();
IFieldsEdit pFieldsEdit = (IFieldsEdit)pFields;
//3. 設置字段
IField pField = new FieldClass();
IFieldEdit pFieldEdit = (IFieldEdit)pField;
//4. 創建類型爲幾何類型的字段
pFieldEdit.Name_2 = strShapeFieldName;
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
//爲esriFieldTypeGeometry類型的字段創建幾何定義,包括類型和空間參照
IGeometryDef pGeoDef = new GeometryDefClass(); //The geometry definition for the field if IsGeometry is TRUE.
IGeometryDefEdit pGeoDefEdit = (IGeometryDefEdit)pGeoDef;
//4.1 將原始數據的投影信息賦值給新的檢查結果圖層
IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactory();
IWorkspace workspace = workspaceFactory.OpenFromFile(inPath, 0);
IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
IFeatureClass pFeaterClass = featureWorkspace.OpenFeatureClass(checkLayerName);//這個地方可以繼續研究如何更簡便的獲取工作空間的座標系統
IGeoDataset geoDatabase = pFeaterClass as IGeoDataset;
//設置座標系統
IProjectedCoordinateSystem tProjectedCoordinateSystem = geoDatabase.SpatialReference as IProjectedCoordinateSystem;
pGeoDefEdit.SpatialReference_2 = tProjectedCoordinateSystem;
pGeoDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;
pFieldEdit.GeometryDef_2 = pGeoDef;
pFieldsEdit.AddField(pField);
//添加其他的字段
pField = new FieldClass();
pFieldEdit = (IFieldEdit)pField;
pFieldEdit.Name_2 = "X";
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
//pFieldEdit.Precision_2 = 7;//數值精度
//pFieldEdit.Scale_2 = 6;//小數點位數
pFieldsEdit.AddField(pField);
pField = new FieldClass();
pFieldEdit = (IFieldEdit)pField;
pFieldEdit.Name_2 = "Y";
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
//pFieldEdit.Precision_2 = 7;//數值精度
//pFieldEdit.Scale_2 = 6;//小數點位數
pFieldsEdit.AddField(pField);
//創建shapefile
string strShapeName = System.IO.Path.GetFileName(ouPath);
IFeatureClass shpFeatureClass = pWS.CreateFeatureClass(strShapeName, pFields, null, null, esriFeatureType.esriFTSimple, strShapeFieldName, "");
//5. 向shape中添加要素
IPoint pPoint = new PointClass();
foreach (IPoint pt in liPts)
{
IFeature pFeature = shpFeatureClass.CreateFeature();
//5.1 將點座標設置到屬性表中
//獲取字段,並對字段值進行屬性賦值
IFields fields = pFeature.Fields;//獲取該對象的字段
int xIdx = fields.FindFieldByAliasName("X");
pFeature.set_Value(xIdx, pt.X);
int yIdx = fields.FindFieldByAliasName("Y");
pFeature.set_Value(yIdx, pt.Y);
//5.2 將點設置爲shp文件的圖形要素
pFeature.Shape = pt;//這一句十分重要,不然點顯示不出來
//如果導出的其他類型的元素(IPolygon,IPolyline)
pFeature.Store();
}
}
測試函數的修改:
private void buttonExecute_Click(object sender, EventArgs e)
{
try
{
//---------------------------檢查小於15度角的代碼------------------------------------
string inPath = textBoxInput.Text;
string ouPath = textBoxOutput.Text;
if (System.IO.File.Exists(inPath) && System.IO.Path.GetFileName(ouPath) != "")
{
//string extend = System.IO.Path.GetExtension(ouPath);
if (System.IO.Path.GetExtension(ouPath) == ".txt")
{
System.IO.StreamWriter sw = new System.IO.StreamWriter(ouPath);
List<IPoint> pts = checkAngle(inPath, "Topology", "LRDL", 15);
//List<IPoint> pts = getAllPointFromLine(inPath, "Topology", "LRDL");
foreach (IPoint pt in pts)
{
sw.WriteLine(pt.X.ToString() + ", " + pt.Y.ToString());
}
sw.Close();
sw.Dispose();
}
else
{
List<IPoint> pts = checkAngle(inPath, "Topology", "LRDL", 15);
ExportPtsToShapefile(inPath, pts, "LRDL", ouPath);
}
}
MessageBox.Show("折角檢查完畢", "完成提示");
//------------------------------------------------------------------------
}
catch (Exception ex)
{
MessageBox.Show("觸發異常操作:" + ex.ToString(), "執行失敗");
}
}
4.2 參考材料
4.2.1 思路
根據點座標創建Shapefile文件大致思路是這樣的:
(1)創建表的工作空間,通過 IField、IFieldsEdit、IField 等接口創建屬性字段,添加到要素集中。
(2)根據獲取點的座標信息爲屬性字段賦值,進而得到圖層的要素集
4.2.2 必要元素
將創建 Shapefile 文件代碼封裝成方法如下,這裏說明一下創建一 個 Shapefile 文件至少需要配置的元素:
- 首先,當我們創建一個shp文件時,ArcMap會自動生成如下字段:
其中shp表示幾何字段,我們需要設置 IFile.Name 和 IField.Type 來定義這個字段
- 如果我們沒有設置空間座標時,會彈出如下對話框:
因此第二步我們需要設置shp文件的空間座標。 這裏是通過設置 IField.GeometryDef 實現的。這個屬性其實是IGeometryDef接口,通過對這個接口的 GeometryType 和 SpatialReference 屬性進行設置即可完成對空間座標的定義。
4.2.2 代碼說明
封裝的這段代碼裏,發現對於 IFeature 和 IFeatureClass 還是不怎麼理解,通過查閱資料發現, IFeature 繼承自 IRow 和 IObject ,由於IFeature 可以通過 IFeatureClass 創建而成,因此可以知道的是IFeatureClass 是和ITable處於同一個級別,IFeature 相當於是屬性表中的一行。
注:此代碼未做驗證,目測正確,僅共學習參考
private IFeatureLayer CreateShpFromPoints(List<CPoint> cPointList,string filePath)
{
//其中,CPoint爲存儲點數據的結構體,包含name,x,y屬性
//利用IWorkspaceFactory打開工作空間
int index = filePath.LastIndexOf('\\');
string folder = filePath.Substring(0, index);
string shapeName = filePath.Substring(index + 1);
IWorkspaceFactory pWSF = new ShapefileWorkspaceFactoryClass();
IFeatureWorkspace pFWS = (IFeatureWorkspace)pWSF.OpenFromFile(folder, 0);
//創建字段編輯所需要的接口
IFields pFields = new FieldsClass();
IFieldsEdit pFieldsEdit;
pFieldsEdit = (IFieldsEdit)pFields;
//給字段屬性、類型賦值
IField pField = new FieldClass();
IFieldEdit pFieldEdit = (IFieldEdit)pField;
pFieldEdit.Name_2 = "Shape";
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
IGeometryDef pGeometryDef = new GeometryDefClass();
IGeometryDefEdit pGDefEdit = (IGeometryDefEdit)pGeometryDef;
pGDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;
//定義座標系
ISpatialReferenceFactory pSRF = new SpatialReferenceEnvironmentClass();
ISpatialReference pSpatialReference = pSRF.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_Beijing1954);
pGDefEdit.SpatialReference_2 = pSpatialReference;
pFieldEdit.GeometryDef_2 = pGeometryDef;
pFieldsEdit.AddField(pField);
IFeatureClass pFeatureClass;
pFeatureClass = pFWS.CreateFeatureClass(shapeName, pFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");
IPoint pPoint = new PointClass();
for (int j = 0; j < cPointList.Count; j++)
{
pPoint.X = cPointList[j].X;
pPoint.Y = cPointList[j].Y;
IFeature pFeature = pFeatureClass.CreateFeature();
pFeature.Shape = pPoint;
pFeature.Store();
}
IFeatureLayer pFeatureLayer = new FeatureLayerClass();
pFeatureLayer.Name = shapeName;
pFeatureLayer.FeatureClass = pFeatureClass;
return pFeatureLayer;
}
喜歡作者可以關注個人公衆號,純屬愛好,不定時更新;
關於代碼的改進請關注【運籌優化與圖像處理算法編程】公衆號《ArcEngine實現線(面)折角監測》