【VS2019+ArcGIS AO】创建多面体shp

创建项目

  • 使用VS2019创建.NET Framework的控制台应用项目。
  • 默认使用.NET Framework4.7.2框架。

添加引用

  1. 需先安装好ArcGIS Desktop。
  2. 添加目录C:\Windows\Microsoft.NET\assembly\GAC_MSIL下的五个dll:
    在这里插入图片描述
  3. 修改添加的五个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();

        }
    }
}

多面体效果

  1. 生成shp文件:
    在这里插入图片描述
  2. 将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

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值