研发三维GIS系统笔记/实现wgs84投影-002

四叉树代码修改完善

原来的代码中,没有使用投影转换,直接使用的是世界坐标(单位是米),

复制代码
    CELLQuadTree::CELLQuadTree(
         CELLTerrainInterface* pInterface
        ,CELLQuadTree* parent
        ,const real2 vStart
        ,const real2 vEnd
        ,int level
        ,ChildId corner)
    {
        _terrain    =   pInterface;
    ///  这里使用y作为高度,因为如果是三维,后续初始化后应该使用高程数据填充
    ///  初始化用0,
        _aabb.setExtents(vStart.x, 0, vStart.y, vEnd.x, 0, vEnd.y);
        real3   vXenter =   _aabb.getCenter();
    /// 这里计算经纬度,输入世界坐标转换成经纬度
        real2   vLonLat  =   pInterface->spRef()->worldToLongLat(real2(vLonLat.x,vLonLat.z));
    /// 调用接口根据经纬度计算出来瓦片的Id,加载瓦片会根据该id访问 网络/磁盘瓦片,例如 d:/data/vTileId.z/vTileId.x/vTileId.y.jpg
        int3    vTileId =   pInterface->spRef()->getKey(level,vWorld.x,vWorld.y);
        _tileId._lev    =   level;
        _tileId._col    =   vTileId.x;
        _tileId._row    =   vTileId.y;
        _cornerId   =   corner;
        _parent     =   parent;
        _vStart     =   vStart;
        _vEnd       =   vEnd;
        _childs[0]  =   0;
        _childs[1]  =   0;
        _childs[2]  =   0;
        _childs[3]  =   0;
        _uvStart    =   float2(0.0f, 0.0f);
        _uvEnd      =   float2(1.0f, 1.0f);
        
        _terrain->getCounts()._nodes ++;
        _flag       =   0;
        _flag       &=  ~FLAG_HAS_IMAGE;
    /// 如果是没有父点,则说明是根节点,直接请求瓦片,不做处理
        if (_parent == nullptr)
        {
            _terrain->request(this);
            return;
        }
    /// 如果不是根节点,那么默认情况下是没有瓦片数据的,则使用父亲节点数据作为子节点的输入
    /// 需要重新计算UV坐标,子节点的坐标应该是父节点的一半

        float2  vHalf   =   (_parent->_uvEnd - _parent->_uvStart) * 0.5f;
        float2  vCenter =   (_parent->_uvStart + _parent->_uvEnd) * 0.5f;
        _textureId      =   _parent->_textureId;
    /// 不同的子节点,UV计算是不一样的
        switch (corner)
        {
        case CHILD_LT:
            _uvStart    =   vCenter - float2(vHalf.x,0);
            _uvEnd      =   vCenter + float2(0,vHalf.y);
            break;
        case CHILD_RT:
            _uvStart    =   vCenter;
            _uvEnd      =   vCenter + vHalf;
            break;
        case CHILD_LB:
            _uvStart    =   vCenter - vHalf;
            _uvEnd      =   vCenter ;
            break;
        case CHILD_RB:
            _uvStart    =   vCenter - float2(0,vHalf.y);
            _uvEnd      =   vCenter + float2(vHalf.x,0);
            break;
        default:
            break;
        }
        if (_parent->hasFlag(FLAG_HAS_IMAGE))
        {
            _flag   |=  FLAG_RENDER;
        }
    /// 重点:引用父节点数据
        _textureId  =   _parent->_textureId;
        _terrain->request(this);
    }
  上图:
  ![](https://file.jishuzhan.net/article/1711184845738086401/69efa169d24ec3e2bcf139c8412e62cc.webp)
  
当一张瓦片被分裂成四张后,会存一个问题,瓦片是否有数据,默认情况下,使用父节点的书作为子节点输入
![](https://file.jishuzhan.net/article/1711184845738086401/9e77628f030488b43ddc9b23baff7ff2.webp)

纹理坐标如下代码:
复制代码
        switch (corner)
        {
        case CHILD_LT:
            _uvStart    =   vCenter - float2(vHalf.x,0);
            _uvEnd      =   vCenter + float2(0,vHalf.y);
            break;
        case CHILD_RT:
            _uvStart    =   vCenter;
            _uvEnd      =   vCenter + vHalf;
            break;
        case CHILD_LB:
            _uvStart    =   vCenter - vHalf;
            _uvEnd      =   vCenter ;
            break;
        case CHILD_RB:
            _uvStart    =   vCenter - float2(0,vHalf.y);
            _uvEnd      =   vCenter + float2(vHalf.x,0);
            break;
        default:
            break;
        }
复制代码

瓦片裂分流程代码:

复制代码
 1           vSize   =   _aabb.getHalfSize();
 2                 _childs[CHILD_LT]   =   new CELLQuadTree(
 3                     _terrain
 4                     , this
 5                     ,real2(vCenter.x - vSize.x,vCenter.z)
 6                     ,real2(vCenter.x,vCenter.z + vSize.z)
 7                     ,(int)_tileId._lev + 1
 8                     ,CHILD_LT
 9                 );
10 
11                 _childs[CHILD_RT] = new CELLQuadTree(
12                     _terrain
13                     ,this
14                     , real2(vCenter.x, vCenter.z)
15                     , real2(vCenter.x + vSize.x, vCenter.z + vSize.z)
16                     , (int)_tileId._lev + 1
17                     , CHILD_RT
18                 );
19 
20                 _childs[CHILD_LB] = new CELLQuadTree(
21                     _terrain
22                     , this
23                     , real2(vCenter.x - vSize.x, vCenter.z - vSize.z)
24                     , real2(vCenter.x, vCenter.z)
25                     , (int)_tileId._lev + 1
26                     , CHILD_LB
27                 );
28                 _childs[CHILD_RB] = new CELLQuadTree(
29                     _terrain
30                     , this
31                     , real2(vCenter.x, vCenter.z - vSize.z)
32                     , real2(vCenter.x + vSize.x, vCenter.z)
33                     , (int)_tileId._lev + 1
34                     , CHILD_RB
35                 );
复制代码
 
相关推荐
yuyanjingtao2 分钟前
CCF-GESP 等级考试 2023年9月认证C++四级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试
闻缺陷则喜何志丹18 分钟前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
charlie11451419129 分钟前
C++ STL CookBook
开发语言·c++·stl·c++20
小林熬夜学编程40 分钟前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
倔强的石头1061 小时前
【C++指南】类和对象(九):内部类
开发语言·c++
A懿轩A2 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
机器视觉知识推荐、就业指导2 小时前
C++设计模式:享元模式 (附文字处理系统中的字符对象案例)
c++
半盏茶香2 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
Ronin3053 小时前
11.vector的介绍及模拟实现
开发语言·c++
✿ ༺ ོIT技术༻3 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++