研发三维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);
相关推荐
双叶8363 分钟前
(C++)学生管理系统(正式版)(map数组的应用)(string应用)(引用)(文件储存的应用)(C++教学)(C++项目)
c语言·开发语言·数据结构·c++
源代码•宸17 分钟前
C++高频知识点(二)
开发语言·c++·经验分享
jyan_敬言2 小时前
【C++】string类(二)相关接口介绍及其使用
android·开发语言·c++·青少年编程·visual studio
liulilittle2 小时前
SNIProxy 轻量级匿名CDN代理架构与实现
开发语言·网络·c++·网关·架构·cdn·通信
tan77º3 小时前
【Linux网络编程】Socket - UDP
linux·服务器·网络·c++·udp
SDUERPANG3 小时前
三维目标检测|Iou3D 代码解读一
人工智能·目标检测·3d
菠萝加点糖3 小时前
Android Camera2 + OpenGL离屏渲染示例
android·opengl·camera
GiraKoo3 小时前
【GiraKoo】C++14的新特性
c++
悠悠小茉莉3 小时前
Win11 安装 Visual Studio(保姆教程 - 更新至2025.07)
c++·ide·vscode·python·visualstudio·visual studio
坏柠4 小时前
C++ Qt 基础教程:信号与槽机制详解及 QPushButton 实战
c++·qt