三調的項目中,由於二調時調查的各種地物為線狀,而在實際生產生活中(包括自然資源的調查過程中)都會有弊端,因而三調過程中要求將曾經的線狀地物擴展為面狀區域,一般來說手動矢量化可以最大的程度上保證精度但卻浪費人力,簡單的處理方法就是對線狀地物進行緩沖區分析。使用arcgis engine中的gp工具在緩沖分析的過程中,設置緩沖區 的end_type為flat時程序老是閃退,因而自己根據arcobjects的文檔中,利用IBufferConstruct接口,照着arcmap中的gp工具重寫了一下,代碼如下:
private List<IGeometry> CreateBuffer(IFeatureLayer bufferLayer)
{
//基本邏輯:
//首先創建與輸入圖層具有相同空間參考的shp文件
//通過IBufferConstruction接口來實現平頭緩沖區、按字段設置緩沖距離
//QI獲取圖層內所有要素,遍歷要素放入GeometryCollection(容器)中,bufferConstruction實現接口中的相應方法
//使用IBufferConstruction中的ConstructBuffersByDistances2 方法對要素逐個創建緩沖區
//要素緩沖完之后,將要素寫入shp文件中
IBufferConstruction bufferConstruct = new BufferConstructionClass();
IBufferConstructionProperties bufferProper = bufferConstruct as IBufferConstructionProperties;
//獲取要素圖層中的所有要素
IFeatureClass pFeatureClass = bufferLayer.FeatureClass;
//QI獲取Geometry
IQueryFilter filter = new QueryFilterClass();
filter.WhereClause = "";
IFeatureCursor pFeatureCursor = pFeatureClass.Search(filter, false);
IFeature pFeature = pFeatureCursor.NextFeature();
IEnumGeometry originalGeometryEnum;
IEnumGeometry resultGeometryEnum;
//緩沖區輸出要素,並使用List泛型,將幾何要素放入list中
IGeometry resultSingleGeo = null;
List<IGeometry> resultGeoList = new List<IGeometry>();
IGeometryCollection originalGeometryBag = new GeometryBagClass();
IGeometryCollection outBufferGeometryBag = new GeometryBagClass();
string fieldName = cboBufferField.SelectedItem.ToString();
int fieldIndex = pFeatureClass.FindField(fieldName);
//存放字段值的IDoubleArray
IDoubleArray fieldValue = new DoubleArray();
while (pFeature != null)
{
//將要素放入容器內,獲取要素的某個字段所有值,放入doublearray容器中
IGeometry polyline = pFeature.ShapeCopy;
originalGeometryBag.AddGeometry(polyline);
double fieldSingleValue = (double)pFeature.get_Value(fieldIndex);
Console.WriteLine(fieldSingleValue); //測試使用
fieldValue.Add(fieldSingleValue);
//循環將要素的屬性值加入IDoubleArray中
pFeature = pFeatureCursor.NextFeature();
}
originalGeometryEnum = originalGeometryBag as IEnumGeometry;
if (originalGeometryEnum != null)
{
//設置緩沖選項
//設置平頭緩沖
bufferProper.EndOption = esriBufferConstructionEndEnum.esriBufferFlat;
//緩沖區是否保留重疊
bufferProper.UnionOverlappingBuffers = true;
bufferConstruct.ConstructBuffersByDistances2(originalGeometryEnum, fieldValue, outBufferGeometryBag);
if (outBufferGeometryBag != null)
{
resultGeometryEnum = outBufferGeometryBag as IEnumGeometry;
if (resultGeometryEnum != null)
resultSingleGeo = resultGeometryEnum.Next();
//開始單個要素寫入
while (resultSingleGeo != null)
{
resultGeoList.Add(resultSingleGeo);
resultSingleGeo = resultGeometryEnum.Next();
}
}
return resultGeoList;
}
else
{
MessageBox.Show("程序錯誤!");
return null;
}
}