作者:翔翔
文章目录
- 背景
- 主题
- 数据准备
- 联动更新模型位置信息
- 更新模型旋转
- 更新模型缩放
- 模型查询
- 注意事项
背景
在电力行业中,由设计院或者数据生产商提供成果数据。成果数据有的是GIM、有的是模型+姿态矩阵、有的是模型+模型对应的绕轴旋转值、轴缩放值和平移值。但是并不是所有的成果数据就绝对正确或一层不变。当杆塔所在位置地形变了,此时杆塔模型便会根据实际的地形来微调,比如旋转、缩放、平移等。微调杆塔时也需要将绝缘子串的状态实时改变。微调后还能将当前模型的矩阵导出以便做成新的成果数据提交。如何在SuperMap iObjects .Net产品中实现该流程?这就是本文要讲的主题。
主题
首先可能大家会问什么是实例化?如果大家对实例化不熟悉的话可以参考博客中的简单说明:
模型数据处理之实例化处理
数据准备
- 杆塔点位数据集
- 杆塔和绝缘子串S3MB模型文件
- 绝缘子串相对杆塔的矩阵信息
联动更新模型位置信息
通过编辑二维地图中的点位信息,将更改后的点位信息传入到对应的模型上,实现杆塔及其绝缘子串的位置更新。
关键代码如下::
////// 更新模型位置信息, /// /// 杆塔smid /// 更新位置 public void UpdatePosition(int smid, Point3D position) { ///获取smid的对象 ListqueryLink = m_linkSource.FindAll(o => o.SmID == smid); m_towerInstance.States.ForEach(item => { if (queryLink.Find(o => o.Guid == item.ID) != null) { item.Longitude = position.X; item.Latitude = position.Y; item.Altitude = position.Z; } }); }
示意gif如下
更新模型旋转
通过设置模型绕XYZ任意轴旋转角度,计算出杆塔和绝缘子串的旋转矩阵。绝缘子串旋转矩阵更新主要流程:
- 获取串的偏移值
- 根据旋转值计算串的新偏移
- 将串原始矩阵的偏移值归零,得到新的原始矩阵
- 通过新的旋转值构建矩阵,然后乘新的原始矩阵
- 将步骤2中的偏移值设置给步骤4得到的矩阵。最后将矩阵赋给对象
关键代码如下:
////// 更新模型旋转 /// /// 杆塔smid /// X轴旋转角度 /// Y轴旋转角度 /// Z轴旋转角度 public void UpdateRotation(int smid, double rx, double ry, double rz) { ///获取smid的对象 ListqueryLink = m_linkSource.FindAll(o => o.SmID == smid); ///计算杆塔矩阵 m_towerInstance.States.ForEach(item => { if (queryLink.Find(o => o.Guid == item.ID) != null) { item.LocalMatrix = item.LocalMatrix.Multipy(Matrix.RotateXYZ(rx, ry, rz)); } }); ///计算绝缘子串矩阵信息 m_stringInstanceS35.States.ForEach(item => { if (queryLink.Find(o => o.Guid == item.ID) != null) { Matrix matrix = item.LocalMatrix; ///获取矩阵偏移值 Point3D p1 = new Point3D(matrix.ArrayValue[12], matrix.ArrayValue[13], matrix.ArrayValue[14]); ///串旋转后的挂点 Point3D p2 = CDUtil.Matrix.Matrix.removeP(p1, new Dictionary () { { 1, rx }, { 2, ry }, { 3, rz } }, new Point3D(), new Point3D(1, 1, 1)); ///先将原始矩阵偏移归零 double[] temp = matrix.ArrayValue; temp[12] = 0; temp[13] = 0; temp[14] = 0; matrix.ArrayValue = temp; ///旋转矩阵乘归零矩阵 matrix = Matrix.RotateXYZ(rx, ry, rz).Multipy(matrix); ///重新设置矩阵的偏移值,值为串旋转后的挂点 double[] ma = matrix.ArrayValue; ma[12] = p2.X; ma[13] = p2.Y; ma[14] = p2.Z; matrix.ArrayValue = ma; //item.Altitude += 0.0001; item.LocalMatrix = matrix; } }); }
更新模型缩放示意gif
通过设置模型绕XYZ任意轴缩放比例,计算出杆塔和绝缘子串的旋转矩阵。绝缘子串缩放矩阵更新主要流程:
- 先将缩放矩阵乘原始矩阵得到新矩阵
- 获取步骤1中的偏移值
- 计算偏移值缩放后的新偏移值
- 将步骤3中获取的值设置给步骤1中的偏移值
关键代码如下:
////// 更新模型缩放 /// /// 杆塔smid /// X缩方比例 /// Y缩方比例 /// Z缩方比例 public void UpdateScale(int smid, double sx, double sy, double sz) { ///获取smid的对象 ListqueryLink = m_linkSource.FindAll(o => o.SmID == smid); ///计算杆塔矩阵 m_towerInstance.States.ForEach(item => { if (queryLink.Find(o => o.Guid == item.ID) != null) { item.LocalMatrix = Matrix.Scale(sx, sy, sz).Multipy(item.LocalMatrix); } }); ///计算绝缘子串矩阵信息 m_stringInstanceS35.States.ForEach(item => { if (queryLink.Find(o => o.Guid == item.ID) != null) { ///用缩放矩阵乘原始矩阵 Matrix matrix = Matrix.Scale(sx, sy, sz).Multipy(item.LocalMatrix); ///获取矩阵偏移值 Point3D p1 = new Point3D(matrix.ArrayValue[12], matrix.ArrayValue[13], matrix.ArrayValue[14]); Point3D Spoint = new Point3D(sx, sy, sz); ///计算偏移值缩放后的新偏移值 Point3D p2 = CDUtil.Matrix.Matrix.removeP(p1, new Dictionary (), new Point3D(), Spoint); ///设置矩阵偏移值 double[] ma = matrix.ArrayValue; ma[12] = p2.X; ma[13] = p2.Y; ma[14] = p2.Z; matrix.ArrayValue = ma; item.LocalMatrix = matrix; } }); }
模型查询示意gif
将模型的唯一ID和对应的数据集SMID对应起来,同时也可存储其他的一些信息。当点击杆塔时,可以获取到该对象的唯一ID。在存储的属性中查询到唯一ID即可获取到该对象的信息。如果还有外挂了一些信息,可通过SMID去查询对应的信息并展示出来。
关键代码如下:
////// 添加对象到实例化图层 /// /// /// /// public void AddGeometry(int smid, Point3D position, string description) { InstanceObjectState tower = new InstanceObjectState(); ///设置唯一guid,值的范围1-2^24之间 int guid = GetGuid(); LinkSource linkSource = m_linkSource.Find(o => o.Guid == guid); while (linkSource != null) { guid = GetGuid(); linkSource = m_linkSource.Find(o => o.Guid == guid); } tower.ID = guid; tower.Longitude = position.X; tower.Latitude = position.Y; tower.Altitude = position.Z; m_towerInstance.States.Add(tower); m_linkSource.Add(new LinkSource() { Guid = guid, SmID = smid, Description = description, IsTower = true }); }
注意事项示意gif
- 上文主要讲的是绝缘字串的矩阵是相对于杆塔的,如果绝缘子串是独立的矩阵,那么新矩阵的算法可能会有改变。
- 需要demo和超图组件包的请给一个邮箱



