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


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

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

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

      

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

    下图Mercator 投影(zhengfangxing)

     

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

      抽象类如下定义:

    复制代码
        class   CELLSpRef
        {
        public:
    
            /// 
            /// 经纬度转化为世界坐标
            /// 
            virtual real2   longLatToWorld(const real2& longLatx)   =   0;
            /// 
            /// 世界坐标转化为经纬度
            /// 
            virtual real2   worldToLongLat(const real2& world)   =   0;
            /// 
            /// 给定经纬度返回对应的瓦片Id
            /// 
            virtual int3    getKey(unsigned l,real rLong,real rLat)  =   0;
            
        };
    复制代码

    3. wgs84投影类实现如下:

      

    复制代码
     1     class   CELLWgs842d :public CELLSpRef
     2     {
     3     public:
     4         /// 
     5         /// 经纬度转化为世界坐标
     6         /// 
     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         /// 
    16         /// 世界坐标转化为经纬度
    17         /// 
    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         /// 
    27         /// 给定经纬度返回对应的瓦片Id
    28         /// 
    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         /// 
     7         /// 创建纹理
     8         /// 
     9         virtual uint    createTexture(const TileId& id) =   0;
    10         /// 
    11         /// 释放纹理
    12         /// 
    13         virtual void    request(CELLQuadTree* node)  =   0;
    14 
    15         /// 
    16         /// 释放纹理
    17         /// 
    18         virtual void    cancelRequest(CELLQuadTree* node) = 0;
    19 
    20         /// 
    21         /// 释放纹理
    22         /// 
    23         virtual void    releaseTexture(uint texId) = 0;
    24 
    25         /// 
    26         /// 获取统计信息
    27         /// 
    28 
    29         virtual Counts& getCounts() =   0;
    30 
    31         /// 
    32         /// 获取投影,具体使用什么类型的投影,由具体实现决定
    33         /// 
    34         virtual CELLSpRef*  spRef() =   0;
    35 
    36 
    37     };
    复制代码

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

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

    6.  改造引擎根节点

      墨卡托投影下,四叉树的根节点只有一个,现在有两个(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);
    复制代码

     

  • 相关阅读:
    全球与中国数字万用表市场:增长趋势、竞争格局与前景展望
    springboot快速搭建ftpserver服务端
    如何使用 PHP 的内置 Web 服务器快速测试网站
    计算机毕设 python opencv 机器视觉图像拼接算法
    876. Middle of the Linked List
    vue3-vant4-vite-pinia-axios-less学习日记
    rabbitMq 针对于当前监听的队列,来控制消费者并发数量,不影响其他队列,代码示例
    emqx 启动正常,但是1883端口无法telnet,emqx无法正常工作
    (1)paddle---在anaconda中安装paddle环境
    字符函数、字符串函数和内存函数
  • 原文地址:https://www.cnblogs.com/FastEarth/p/17748016.html