【超图】SuperMap iObjects .NET之批量导出含坐标信息模型

作者:taco

前言:在使用超图桌面产品的时候,会发现我的模型只能导入成超图的格式,也就是模型数据集格式,在处理成缓存后也不是通用的模型格式,再想导出成通用的时候就发了愁了。模型数据集中的对象确实可以导出成标准的格式,但是每次导出却只能导出一个,我是一个一个的导出呢?还是全都合并后再去导出呢?而且最要命的是,导出后的模型竟然没有了坐标信息!地理信息中最重要的就是模型的坐标信息,导出后竟然都消失不见了。那我后面怎么继续使用呢。基于这个问题,其实靠iObjects提供的组件产品是完完全全可以实现的。只不过暂时桌面并没有提供类似功能而已。本篇文章结合SuperMap iObjects .NET组件产品介绍一下两种导出含坐标信息通用模型的方式。


虽然分为两种方式去导出,但是导出的接口是统一的。都是通过ModelConvertor类去进行导出。这个类是在SuperMap.Realspace.ThreeDDesigner这个命名空间下的,需要引入该dll。

ModelConvertor类:模型转换类。该类用于模型转换成指定格式的文件来存储数据。

目前支持导出的格式包括

OFFOff文件格式
OSGB倾斜摄影模型文件格式
S3M全称是“Spatial 3D Model”,是团体标准“空间三维模型数据格式”的简称
STLSTL格式,可用以3D打印
DAEDAE 即 Digital Asset Exchange 也称COLLADA模型,是Khronos旗下核心的可交换型3D模型格式
GLTFGLTF代表 Graphics Language Transmission Format(图形语言传输格式)。这种跨平台格式已成为Web上的3D对象标准。可通过实体直接加载该类型数据。
FBXFBX 作为公开交换格式,除Autodesk外,许多软件支持导入
OBJOBJ文件是一种标准的3D模型文件格式,很适合用于3D软件模型之间的互导
S3MBS3M压缩数据格式

那么接下来说一下,如何将模型导出。

一,导出模型数据并将模型位置信息写入xml文件

        先说一个比较通用的方法,我们不去将位置信息写入我们需要导出的模型中。而是以xml的格式将模型的位置信息与模型一一对应的导出。这种方式的简便之处在于二次开发的时候,仅需要去读取我们输出的xml文件即可,不需要再去读取模型本身的属性信息了。废话不多说,直接上类。

主要使用到的类以GeoModel3DModelModelFileSettingModelConvertor 这四个为主。

GeoModel3D:三维模型对象类,用于支持处理外挂模型为数据集模型对象。

Model: 模型数据集。该类为用于存储三维几何模型对象(GeoModel3D)的数据集。

ModelFileSetting:模型文件设置类。该类提供了获取或设置模型文件路径、是否忽略LOD(仅对osgb起作用)、获取模型文件类型。

转换的类我们上面已经介绍过了呢。

首先我们去读取我们已有的模型数据集,读取记录集也就是数据集中的对象。并且创建一个xml文档对象,用于存储我们所需要的信息(坐标系,模型名称,模型位置等)


DatasetVector datasetVector = ds.Datasets[comboBox1.Text] as DatasetVector;
//读取记录集
Recordset recordset = datasetVector.GetRecordset(false, CursorType.Static);

//创建xml文档对象
XmlDocument doc = new XmlDocument();
//创建第一个行描述信息, 并且添加到doc文档中

XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "utf-8", null);
doc.AppendChild(dec);

//创建models节点
XmlElement exportmodels = doc.CreateElement("ExportModels");
doc.AppendChild(exportmodels);
PrjCoordSys prjcoordsys = datasetVector.PrjCoordSys;

//导出坐标系信息
XmlElement epsgcode = doc.CreateElement("EpsgCode");
epsgcode.InnerText = prjcoordsys.EPSGCode.ToString();
exportmodels.AppendChild(epsgcode);

//创建model节点
XmlElement modles = doc.CreateElement("Models");
exportmodels.AppendChild(models);
//从头开始
recordset.MoveFirst();

我们遍历记录集中的对象去提取数据中信息并写入xml文件。

for (int i = 0; i < recordset.RecordCount; i++)
            {
                GeoModel3D geoModel3D = recordset.GetGeometry() as GeoModel3D;
                
                Model model = geoModel3D.Model;
               
                //输出模型对象名称
                XmlElement modelname = doc.CreateElement("ModelName");
                modelname.InnerText = comboBox1.Text+"_"+i;
                models.AppendChild(modelname);

                //输出模型对象位置
                XmlElement modelfile = doc.CreateElement("ModelFile");
                modelfile.InnerText = textBox2.Text + "\\" + comboBox1.Text + i + "." + comboBox2.Text;
                models.AppendChild(modelfile);
                //添加Position节点
                XmlElement position = doc.CreateElement("Position");
                models.AppendChild(position);
                //输出x
                XmlElement positionx = doc.CreateElement("PositionX");
                positionx.InnerText = geoModel3D.Position.X.ToString();
                position.AppendChild(positionx);
                //输出y
                XmlElement positiony = doc.CreateElement("PositionY");
                positiony.InnerText = geoModel3D.Position.Y.ToString();
                position.AppendChild(positiony);
                //输出z
                XmlElement positionz = doc.CreateElement("PositionZ");
                positionz.InnerText = geoModel3D.Position.Z.ToString();
                position.AppendChild(positionz);

                //根据给定的Model对象构造一个与之完全一样的新Model对象
                Model model2 = new Model(model);
                
                
                //构造一个新的ModelFileSetting对象
                ModelFileSetting modelFileSetting = new ModelFileSetting();

                //根据不同类型导出
                modelFileSetting.FilePath = textBox2.Text + "\\" + comboBox1.Text + i + "." + comboBox2.Text;
                
                //导出模型及导出位置并转换
                ModelConvertor.ToFile(model2, modelFileSetting);
                string xmlpath = textBox2.Text + "\\" + comboBox1.Text + ".xml";

                //xml文件输出位置
                doc.Save(xmlpath);

                recordset.MoveNext();
            }

这样我们就将模型文件中的每一个对象均导出成我们所需要的格式了,并将其对应信息输出成xml格式供给后续使用。

二,导出包含坐标信息模型

        由于我们上面那种方式是构造了一个新的模型数据去导出的,所以我们导出的模型是再原点也就是0点附近,再通过插入点去配置其位置。那么为什么有些网上下载到的数据导入后它就有位置了呢?其实部分格式的模型是可以将位置信息写入模型的。那SuperMap iObjects .NET组件是否提供类似功能呢?答案当然是有的!

Matrix类:4*4矩阵类。可用于模型骨架缩放、旋转、平移。

模型的缩放、旋转、平移一系列操作总是少不了矩阵的。在这4*4之中我们可以平移他的位置。也就是我们可以从零点直接将模型平移过去再去导出。

                double[] array = new double[16]
                {
                1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                1.0
                };
                array[12] = geoModel3D.Position.X;
                array[13] = geoModel3D.Position.Y;
                array[14] = geoModel3D.Position.Z;
                double[] matrix = array;

我们定义了一个新的矩阵,并将原始模型的位置获取写入这个矩阵之中。这样就得到了一个平移矩阵。

 Model model2 = new Model(model);
 model2.SetMatrix(matrix);

与此同时,我们定义的是不能白白定义的。在Model的方法中,提供了SetMatrix的方法。可以直接将我们的模型平移到我们想要的位置。为了配合这种类型的模型导出,就没有必要再去导出一个xml文件去记录了,这里选择去直接导出一个坐标文件去与它打一个配合,方便后续使用。

prjcoordsys.ToFile(prjcoordsys.Name, PrjFileVersion.UGC60);

这样我们就完成了另一种方式的导出,即含坐标信息的模型文件导出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老孟爱吃Taco

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值