经纬度格网类LatLongGrid继承自可渲染对象类RenderableObject,是WorldWind中用来在星球外表绘制经纬度格网的封装类。其类图如下所示。

绘制经纬网格的主体函数为Render(),其内部主要调用以下函数完成绘制:

ComputeGridValues()//计算格网值

RenderTropicLine()//绘制回归线

计算格网值ComputeGridValues()内部通过相机的真实视场角drawArgs.WorldCamera.TrueViewRange.Radians来指定经纬网格的纬度分割间隔为1、2、5、10四类,然后指定经度分割间隔等于纬度间隔。接下来,判断当前相机的视景体是否包含南北极点,如果包含,则将指定经度分割间隔等于10度,从而使极点部分的经纬网格分割间隔比较大,而不用绘制的非常密集。接着,计算相机可视场景的最大/小可见经度值,最大/小可见纬度值,均取整型。且当经度分割间隔等于10度时,最小可见经度等于-180度,最大可见经度等于180度。接着,计算沿经度方向分割时每一行分割点数,沿纬度方向分割时每一列分割点数,均比分割出来的单元格行数、列数大1,这和我先前一篇博客文章《基于DirectX的半球形天空类的C++和C#实现》中的做法是一样的,这样做都是为了使球体首尾互相衔接。然后求出经度点数(行向)和纬度点数(列向)之间的较大值,然后利用该值来申请星球体划分时所需要的存储的三维坐标点空间:

if (lineVertices == null || vertexPointCount > lineVertices.Length)

  lineVertices = new CustomVertex.PositionColored[Math.Max(LatitudePointCount, LongitudePointCount)];

接着,设置星球的经纬网格所在的球体半径为为构造该类对象时传入的星球对象World所携带的半径值。 接下来要判断当前相机的高度是否小于0.1*WorldRadius;如果是则不开启Zbuffer深度测试。如果否则开启Zbuffer深度测试,且设置1.01* WorldRadius和(WorldRadius + 0.015f * drawArgs.WorldCamera.Altitude)两个值之间的较大者,最终为星球的经纬网格所在的球体半径。

接下来,就按照DirectX 3D的固定图形渲染管线设置是否开启Zbuffer深度测试、设置纹理阶段颜色操作ColorOperation、设置顶点格式VertexFormat、设置世界变换矩阵drawArgs.device.Transform.World、设置关闭渲染状态光照效果drawArgs.device.RenderState.Lighting。经纬网格每一个交点都是通过将格网点的球面坐标转换为笛卡尔控件直角坐标得到的,通过下面的公式将网格定点的球面坐标转换为空间直角坐标来获得逼近的半球面格网剖分模型。

其中,其中B和L分别为球体的经度和纬度,取值范围为:-PI/2≤B≤PI/2,-PI≤L≤PI,R为设定的球体半径。可以使用、、、坐标来生成所需要的球面格网。根据不同的精度要求,可对纬向和经向剖分间隔设置不同的值。

纹理坐标可以首先根据纬向和经向剖分间隔分别计算出纬向和经向剖分网格点数,然后根据当前球面坐标计算出格网点所在的纬向和经向网格行列号,最后根据下面公式计算出云彩贴图的纹理坐标。其中,先将当前行号和列号强制取浮点型是为了保证除法运算按浮点型运算,使最终结果落在[0.0,1.0]之间。详细代码请参照我先前的一篇博客文章《基于DirectX的半球形天空类的C++和C#实现》。

最后,通过两个双重循环依次绘制经度格网线、经度值标签、纬度格网线、纬度值标签。绘制经纬格网时指定的图元类型为线条带PrimitiveType.LineStrip,分别是沿经线方向和纬线方向绘制。详细实现代码请参见PluginSDK工程下面的LatLongGrid.cs文件。

注意:(1)经度是由经度线和经度标签构成。(2)纬度是由纬度线和纬度标签构成。

WorldWind源码剖析系列:经纬度格网类LatLongGrid的更多相关文章

  1. WorldWind源码剖析系列:表面影像类SurfaceImage

    表面影像类SurfaceImage描述星球类(如地球)表面纹理影像.该类的类图如下. 表面影像类SurfaceImage包含的主要的字段.属性和方法如下: string m_ImageFilePath ...

  2. WorldWind源码剖析系列:影像图层类ImageLayer

    影像图层类ImageLayer 影像图层类ImageLayer将单张影像作为纹理映射到星球表面上去.源影像必须是平面笛卡尔坐标系.该类的类图如下. 影像图层类ImageLayer提供的主要字段.属性和 ...

  3. WorldWind源码剖析系列:影像存储类ImageStore、Nlt影像存储类NltImageStore和WMS影像存储类WmsImageStore

    影像存储类ImageStore 影像存储类ImageStore提供了计算本地影像路径和远程影像影像URL访问的各种接口,是WmsImageStore类和NltImageStore类的基类.当划分完层次 ...

  4. WorldWind源码剖析系列:数学引擎类MathEngine

    PluginSDK中的MathEngine类是密封类.不可继承,主要完成通用的数学计算功能.由于按平面展开层层划分,所以在WW里用到一个row,col的概念,类MathEngine封装了从行/列到经/ ...

  5. WorldWind源码剖析系列:表面瓦片类SurfaceTile

    表面瓦片类SurfaceTile描述星球类(如地球)表面纹理影像的瓦片模型.其类图如下. 表面瓦片类SurfaceTile包含的主要的字段.属性和方法如下: int m_Level;//该瓦片所属金字 ...

  6. WorldWind源码剖析系列:四叉树瓦片类QuadTile

    四叉树瓦片类QuadTile提供了对影像和地形数据的四叉树访问模型.该类的类图如下. 四叉树瓦片类QuadTile提供的主要字段.属性和方法简要描述如下: public QuadTileSet Qua ...

  7. WorldWind源码剖析系列:下载请求类DownloadRequest

    下载请求类DownloadRequest是各种下载请求的抽象基类,先派生出网络下载请求类WebDownloadRequest,再派生出地理空间下载请求类GeoSpatialDownloadReques ...

  8. WorldWind源码剖析系列:绘制参数类DrawArgs

    绘制参数类DrawArgs主要对绘制时需要的对象如:设备对象Microsoft.DirectX.Direct3D.Device.Microsoft.DirectX.Direct3D.Font字体对象. ...

  9. WorldWind源码剖析系列:代理助手类ProxyHelper

    代理助手类ProxyHelper通过平台调用的互操作技术封送了若干Win32结构体和函数.该类类图如下. 提供的主要处理方法基本上都是静态函数,简要描述如下: 内嵌类型WINHTTP_AUTOPROX ...

  10. WorldWind源码剖析系列:网络下载类WebDownload

    网络下载类WebDownload封装了对请求的瓦片进行网络下载的相关操作.该类使用了两个委托类型和一个枚举类型. 该类的类图如下. 网络下载类WebDownload各个字段和属性的含义说明如下: st ...

随机推荐

  1. php魔术方法__tostring的应用

    当echo一个对象的时候,会报错误 Object of class Person could not be converted to string 我们可以通过魔术方法__tostring()  把对 ...

  2. pts/0代表什么意思?

    在linux命令行中经常看到pts/0,这是什么意思呢??妈蛋!! 先说pts/0吧,man里面是这样说的:ptmx and pts - pseudo-terminal master and slav ...

  3. cakephp搭建配置完成后怎么关闭cake标识

    在新搭建好cakephp矿建时,准备开发的时候我们会发现页面上有cakephp的标识,影响美观,和开发任务.那么怎么去掉呢? 1.找到FrontDesk\app\View\Layouts\defaul ...

  4. django-强大的ORM

    一.ORM简介 (对象关系映射:object relationship mapping) MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的 ...

  5. Spring Boot系列学习文章(二) -- 配置多数据源

    前言: 在上一章中,我们已经搭建好项目,现在来讲一下如何配置数据源. 由于在有的项目中,用的数据源可能会涉及多个,且是不同类型的,我们接下来就讲解多数据源的配置. 情景描述: 现有项目需要访问不同的数 ...

  6. RBAC用户角色权限设计方案【转载】

    RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成“用户-角色- ...

  7. Oracle EBS 用户职责人员取值

    SELECT fu.user_name 用户名, fu.description 用户说明, fu.start_date 用户启用日期, fu.end_date 用户终止日期 --,fu.employe ...

  8. VScode开发Vue项目,关闭eslint代码检查,以及相关配置

    Vue初始化项目时如果不小心安装了js 语法检测 功能,撸码时一个空格不对就会各种报错 个人感觉这个语法检测功能很有点过于严格,用起来十分难受,所以果断关闭eslint,找到webpack.base. ...

  9. mysql主从不同步问题 Error_code: 1236

    第一种情况,开启GTID,从库与主库不同步. 1.在从库上查看从的状态   mysql> show slave status \G *************************** 1. ...

  10. 清空数据库错误:因为该表正由 FOREIGN KEY 约束引用 解决办法

    如下解决了五个问题 1. 清空数据 2. 有外键也可以, 因为是逆向删除, 从最后一张表删除. 且使用的是delete, 因为truncate不能对有外键的表 3. 种子问题, 如果表存在种子重设为0 ...