创建项目
- 使用VS2019创建.NET Framework的控制台应用项目。
- 默认使用.NET Framework4.7.2框架。
添加引用
- 需先安装好ArcGIS Desktop。
- 添加目录
C:\Windows\Microsoft.NET\assembly\GAC_MSIL
下的五个dll:
- 修改添加的五个dll的嵌入互操作类型为
False
:
若未修改为False
,后续创建对象时,会报“无法嵌入互操作类型”的错误:
创建多面体
代码
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using System;
using System.Collections.Generic;
namespace AOTest0209
{
class Program
{
static void Main(string[] args)
{
//初始化AO许可
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
new AoInitializeClass().Initialize(esriLicenseProductCode.esriLicenseProductCodeAdvanced);
//保存路径和文件名
string filePath = System.IO.Path.GetDirectoryName(@"C:\AATemp\temp2\");
string fileName = DateTime.Now.ToUniversalTime().Ticks + ".shp";
MultiPatchTool.Create(filePath, fileName);
}
}
class MultiPatchTool
{
public static void Create(string FileDir, string FileName)
{
//确保在OpenFromFile前已经引入Geometry库,否则会报错
new Point();
//shp文件工厂
IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactoryClass();
//打开文件夹作为要素工作空间
IFeatureWorkspace pFeatureWorkSpace = pWorkspaceFactory.OpenFromFile(FileDir, 0) as IFeatureWorkspace;
//总的字段管理
IFields pFields = new FieldsClass();
IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;
//添加FID字段
IField pField = new Field();
pFieldsEdit.AddField(pField);//加入到总的字段中
IFieldEdit pFieldEdit = (IFieldEdit)pField;
pFieldEdit.Name_2 = "FID";
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeOID;
//添加几何字段
pField = new FieldClass();
pFieldsEdit.AddField(pField);//加入到总的字段中
pFieldEdit = pField as IFieldEdit;
IGeometryDef geoDef = new GeometryDefClass();
IGeometryDefEdit geoDefEdit = (IGeometryDefEdit)geoDef;
geoDefEdit.SpatialReference_2 = new UnknownCoordinateSystemClass();
geoDefEdit.AvgNumPoints_2 = 5;
geoDefEdit.GeometryType_2 = esriGeometryType.esriGeometryMultiPatch;//esriGeometryPolyline;
geoDefEdit.GridCount_2 = 1;
geoDefEdit.HasM_2 = true;//支持M字段
geoDefEdit.HasZ_2 = true;//设置为true以支持存储高程
pFieldEdit.Name_2 = "SHAPE";
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
pFieldEdit.GeometryDef_2 = geoDef;
pFieldEdit.IsNullable_2 = true;
pFieldEdit.Required_2 = true;
//添加一个非必需的字段,用于添加额外的属性
pField = new Field();
pFieldsEdit.AddField(pField);//加入到总的字段中
pFieldEdit = (IFieldEdit)pField;
pFieldEdit.Name_2 = "Name";
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
//由工作空间创建空的多面体shp文件
IFeatureClass pFeatureClass = pFeatureWorkSpace.CreateFeatureClass(FileName, pFields, null, null, esriFeatureType.esriFTSimple, "shape", null);
//创建一条多面体记录(创建一个多面体)
//创建多面体几何集合,后续将其写入到前面创建的空白shp文件中
IGeometryCollection multiPatchGeometryCollection = new MultiPatchClass();
IMultiPatch multiPatch = multiPatchGeometryCollection as IMultiPatch;
//构成面的点数据
List<double[][]> coords = new List<double[][]>()
{
new double[][]{ new double[] { 0,0,0},new double[] { 1,0,0},new double[] { 1,1,0}, new double[] { 0, 1, 0 } },
new double[][]{ new double[] { 0,0,0},new double[] { 0,1,0},new double[] { 0,1,1}, new double[] { 0,0,1 } },
};
//将点数据添加到多面体中
foreach (var arr in coords)
{
var ring = new RingClass();
foreach (var coord in arr)
{
var pt = new Point();
pt.X = coord[0];
pt.Y = coord[1];
pt.Z = coord[2];
ring.AddPoint(pt);
}
multiPatchGeometryCollection.AddGeometry(ring);
}
//获取前面创建的空白shp文件的要素缓冲区,用于写入数据
IFeatureBuffer pFeatureBuffer = pFeatureClass.CreateFeatureBuffer();
//将上述创建的一条多面体记录添加到缓冲区中
pFeatureBuffer.Shape = multiPatch;
//添加属性
pFeatureBuffer.set_Value(pFeatureBuffer.Fields.FindField("Name"),"AA");
//获取前面创建的空白shp文件的文件写入的游标
var pPolygonFeatureCursor = pFeatureClass.Insert(true);
//通过游标插入要素缓冲区
pPolygonFeatureCursor.InsertFeature(pFeatureBuffer);
//将游标中的缓冲数据全部推出写入到文件
pPolygonFeatureCursor.Flush();
Console.WriteLine("Success!");
Console.ReadLine();
}
}
}
多面体效果
- 生成shp文件:
- 将shp拖入ArcScene软件中:
解决的bug
未添加AO许可
System.Runtime.InteropServices.COMException:“检索 COM 类工厂中 CLSID 为 {00A5CB41-52DA-11D0-A8F2-00608C85EDE5} 的组件失败,原因是出现以下错误: 80040111 ClassFactory 无法供应请求的类 (异常来自 HRESULT:0x80040111 (CLASS_E_CLASSNOTAVAILABLE))。”
需要添加AO许可初始化的代码:
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
new AoInitializeClass().Initialize(esriLicenseProductCode.esriLicenseProductCodeAdvanced);
一种互操作异常
System.Runtime.InteropServices.COMException:“异常来自 HRESULT:0x80040228”
来源:
//确保在OpenFromFile前已经引入Geometry库,否则会报错
//new Point();
//shp文件工厂
IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactoryClass();
//打开文件夹作为要素工作空间
IFeatureWorkspace pFeatureWorkSpace = pWorkspaceFactory.OpenFromFile(FileDir, 0) as IFeatureWorkspace;
当注释掉new Point();
时,会报上面这个错误。
原因在于调用pWorkspaceFactory.OpenFromFile
这个方法会自动引入using ESRI.ArcGIS.Geodatabase;
,但是using ESRI.ArcGIS.Geometry;
莫名未加载好。
因此,通过调用new Point();
(也可以是Geometry
库中的其他方法),确保在调用OpenFromFile
方法前,using ESRI.ArcGIS.Geometry;
处于正常状态。
这个帖子中可能提到了这个问题,但没有解决:
https://bbs.csdn.net/topics/380188534