栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

SuperMap iObjects .NET 电力模型与实例化图层的碰撞

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SuperMap iObjects .NET 电力模型与实例化图层的碰撞

作者:翔翔


文章目录
  • 背景
  • 主题
    • 数据准备
    • 联动更新模型位置信息
    • 更新模型旋转
    • 更新模型缩放
    • 模型查询
  • 注意事项


背景

在电力行业中,由设计院或者数据生产商提供成果数据。成果数据有的是GIM、有的是模型+姿态矩阵、有的是模型+模型对应的绕轴旋转值、轴缩放值和平移值。但是并不是所有的成果数据就绝对正确或一层不变。当杆塔所在位置地形变了,此时杆塔模型便会根据实际的地形来微调,比如旋转、缩放、平移等。微调杆塔时也需要将绝缘子串的状态实时改变。微调后还能将当前模型的矩阵导出以便做成新的成果数据提交。如何在SuperMap iObjects .Net产品中实现该流程?这就是本文要讲的主题。


主题

首先可能大家会问什么是实例化?如果大家对实例化不熟悉的话可以参考博客中的简单说明:
模型数据处理之实例化处理


数据准备
  1. 杆塔点位数据集
  2. 杆塔和绝缘子串S3MB模型文件
  3. 绝缘子串相对杆塔的矩阵信息

联动更新模型位置信息

通过编辑二维地图中的点位信息,将更改后的点位信息传入到对应的模型上,实现杆塔及其绝缘子串的位置更新。

关键代码如下::

	/// 
    /// 更新模型位置信息,
    /// 
    /// 杆塔smid
    /// 更新位置
    public void UpdatePosition(int smid, Point3D position)
    {
        ///获取smid的对象
        List queryLink = 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任意轴旋转角度,计算出杆塔和绝缘子串的旋转矩阵。绝缘子串旋转矩阵更新主要流程:

  1. 获取串的偏移值
  2. 根据旋转值计算串的新偏移
  3. 将串原始矩阵的偏移值归零,得到新的原始矩阵
  4. 通过新的旋转值构建矩阵,然后乘新的原始矩阵
  5. 将步骤2中的偏移值设置给步骤4得到的矩阵。最后将矩阵赋给对象

关键代码如下:

/// 
    /// 更新模型旋转
    /// 
    /// 杆塔smid
    /// X轴旋转角度
    /// Y轴旋转角度
    /// Z轴旋转角度
    public void UpdateRotation(int smid, double rx, double ry, double rz)
    {
        ///获取smid的对象
        List queryLink = 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. 先将缩放矩阵乘原始矩阵得到新矩阵
  2. 获取步骤1中的偏移值
  3. 计算偏移值缩放后的新偏移值
  4. 将步骤3中获取的值设置给步骤1中的偏移值

关键代码如下:

	/// 
    /// 更新模型缩放
    /// 
    /// 杆塔smid
    /// X缩方比例
    /// Y缩方比例
    /// Z缩方比例
    public void UpdateScale(int smid, double sx, double sy, double sz)
    {
        ///获取smid的对象
        List queryLink = 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

注意事项
  1. 上文主要讲的是绝缘字串的矩阵是相对于杆塔的,如果绝缘子串是独立的矩阵,那么新矩阵的算法可能会有改变。
  2. 需要demo和超图组件包的请给一个邮箱
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/954974.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号