研发三维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);
相关推荐
Justinyh21 小时前
1、CUDA 编程基础
c++·人工智能
white-persist1 天前
差异功能定位解析:C语言与C++(区别在哪里?)
java·c语言·开发语言·网络·c++·安全·信息可视化
ShineWinsu1 天前
对于数据结构:链式二叉树的超详细保姆级解析—中
数据结构·c++·算法·面试·二叉树·校招·递归
liu****1 天前
20.传输层协议TCP
服务器·网络·数据结构·c++·网络协议·tcp/ip·udp
沐怡旸1 天前
【穿越Effective C++】条款20:宁以pass-by-reference-to-const替换pass-by-value——参数传递的效率与语义
c++·面试
八个程序员1 天前
c++音乐——《两只老虎》
c++·游戏
..空空的人1 天前
C++基于websocket的多用户网页五子棋 ---- 模块介绍1
开发语言·c++·websocket
多恩Stone1 天前
【3DV 进阶-7】Hunyuan3D2.1-ShapeVAE 整体流程
3d
叫我龙翔1 天前
【数据结构】从零开始认识B树 --- 高效外查找的数据结构
数据结构·c++·b树
zzzsde1 天前
【C++】红黑树:使用及实现
开发语言·c++·算法