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

  1. 工作内容,改造引擎,支持wgs84投影

改造原因:目前投影是墨卡托投影(与Google Map一致) 目前的GIS系统是二维的采用这个坐标系是没有问题的

但不支持wgs84瓦片数据以及高程数据,工作中很多数据是wgs84格式的,尤其很多三维GIS都是采用wgs84投影

wgs84 与mercator 从数据上看,就是跟节点是一个与两个的区别(长方形)

下图Mercator 投影(zhengfangxing)

  1. 对现有接口进行抽象,目的是向下兼容原有的引擎(Mercator)投影

抽象类如下定义:

复制代码
    class   CELLSpRef
    {
    public:

        /// <summary>
        /// 经纬度转化为世界坐标
        /// </summary>
        virtual real2   longLatToWorld(const real2& longLatx)   =   0;
        /// <summary>
        /// 世界坐标转化为经纬度
        /// </summary>
        virtual real2   worldToLongLat(const real2& world)   =   0;
        /// <summary>
        /// 给定经纬度返回对应的瓦片Id
        /// </summary>
        virtual int3    getKey(unsigned l,real rLong,real rLat)  =   0;
        
    };
  1. wgs84投影类实现如下:

复制代码
 1     class   CELLWgs842d :public CELLSpRef
 2     {
 3     public:
 4         /// <summary>
 5         /// 经纬度转化为世界坐标
 6         /// </summary>
 7         virtual real2   longLatToWorld(const real2& longLatx) override
 8         {
 9             real2   world;
10             world.x =   longLatx.x * WGS_84_RADIUS_EQUATOR;
11             world.y =   longLatx.y * WGS_84_RADIUS_EQUATOR;
12             return  world;
13         }
14 
15         /// <summary>
16         /// 世界坐标转化为经纬度
17         /// </summary>
18         virtual real2   worldToLongLat(const real2& world) override
19         {
20             real2   lonlat;
21             lonlat.x =   world.x  / WGS_84_RADIUS_EQUATOR;
22             lonlat.y =   world.y  / WGS_84_RADIUS_EQUATOR;
23             return  lonlat;
24         }
25 
26         /// <summary>
27         /// 给定经纬度返回对应的瓦片Id
28         /// </summary>
29         virtual int3    getKey(unsigned level, real rLong,real rLat) override
30         {
31             /// 当下版本还在实现中
32             return  int3(0,0,level);
33         }
34     };

4. 适配引擎代码

引擎中原来直接调用了Mercator投影,现在需要统一接口,在引擎类中增加一个获取投影接口的类

复制代码
 1     class   CELLTerrainInterface
 2     {
 3     public:
 4         virtual ~CELLTerrainInterface()
 5         {}
 6         /// <summary>
 7         /// 创建纹理
 8         /// </summary>
 9         virtual uint    createTexture(const TileId& id) =   0;
10         /// <summary>
11         /// 释放纹理
12         /// </summary>
13         virtual void    request(CELLQuadTree* node)  =   0;
14 
15         /// <summary>
16         /// 释放纹理
17         /// </summary>
18         virtual void    cancelRequest(CELLQuadTree* node) = 0;
19 
20         /// <summary>
21         /// 释放纹理
22         /// </summary>
23         virtual void    releaseTexture(uint texId) = 0;
24 
25         /// <summary>
26         /// 获取统计信息
27         /// </summary>
28 
29         virtual Counts& getCounts() =   0;
30 
31         /// <summary>
32         /// 获取投影,具体使用什么类型的投影,由具体实现决定
33         /// </summary>
34         virtual CELLSpRef*  spRef() =   0;
35 
36 
37     };

5. 改造调用了投影接口的代码

主要集中在四叉树部分,四叉树根据输入的世界坐标创建瓦片,同时根据也是子节点以及其他后代节点裂分的根据。

  1. 改造引擎根节点

墨卡托投影下,四叉树的根节点只有一个,现在有两个(wgs84投影)

代码如下:

复制代码
 1 auto    root0 = new CELLQuadTree(     this
 2                                             , 0
 3                                             , real2(-PI * WGS_84_RADIUS_EQUATOR,    -HALF_PI * WGS_84_RADIUS_EQUATOR)
 4                                             , real2(0,                              +HALF_PI * WGS_84_RADIUS_EQUATOR)
 5                                             , 0
 6                                             , CELLQuadTree::CHILD_LT
 7                                             );
 8         auto    root1 = new CELLQuadTree(     this
 9                                             , 0
10                                             , real2(0,                              -HALF_PI * WGS_84_RADIUS_EQUATOR)
11                                             , real2(-PI * WGS_84_RADIUS_EQUATOR,    +HALF_PI * WGS_84_RADIUS_EQUATOR)
12                                             , 0
13                                             , CELLQuadTree::CHILD_LT
14                                         );
15 
16         _roots.push_back(root0);
17         _roots.push_back(root1);
相关推荐
快乐的划水a8 小时前
组合模式及优化
c++·设计模式·组合模式
星星火柴9369 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
迈火9 小时前
ComfyUI-3D-Pack:3D创作的AI神器
人工智能·gpt·3d·ai·stable diffusion·aigc·midjourney
艾莉丝努力练剑10 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
阿巴~阿巴~12 小时前
深入解析C++ STL链表(List)模拟实现
开发语言·c++·链表·stl·list
旺小仔.13 小时前
双指针和codetop复习
数据结构·c++·算法
jingfeng51413 小时前
C++ STL-string类底层实现
前端·c++·算法
郝学胜-神的一滴13 小时前
基于C++的词法分析器:使用正则表达式的实现
开发语言·c++·程序人生·正则表达式·stl
努力努力再努力wz15 小时前
【c++深入系列】:万字详解模版(下)
java·c++·redis
瓦特what?16 小时前
关于C++的#include的超超超详细讲解
java·开发语言·数据结构·c++·算法·信息可视化·数据挖掘