【WEBGL】谷歌瓦片图加载从原理到实现
年前为 NothingJs
实现了一个扩展 NJ_lod_ground
,目标是简单实现加载谷歌瓦片。为了让读者更加容易的理解,我直接改成了 WebGL
实例(总代码800行左右、依赖glMatrix)。并且把相关内容整理到本文,希望能帮助到刚刚入门的同学。
工程地址在文章结尾。
WGS84 大地坐标系 和 Web 墨卡托投影
GIS
领域最离不开的就是坐标变换,首先要搞清楚的就是地球上的一个点如何变换成地图上的一个点。文章不会详细讲解变换方法,因为本文重点并不是算法。但是还是要说清楚整个过程,我们已经清楚地球本身不是一个规则的球体,为了计算方便,需要有一个标准的大地坐标系来简化计算,而 WGS84(World Geodetic System一1984 Coordinate System)
就是这样一个坐标系。但是大地坐标系是三维坐标系,要映射到二维地图上还需要一步,就是投影变换(仿射变换),比如墨卡托投影。
Web 墨卡托
定义的大地坐标系是 WGS84
坐标系,投影方式与墨卡托投影类似,但是投影时地球不再当做是椭球体而是半径是6378137米的标准球体。
首先我们先简单了解一下 Web 墨卡托投影
的历史:
- 2005年 - 谷歌在谷歌地图中首次使用,当时的
Web墨卡托
使用者还称其为世界墨卡托(World Mercator)- Spherical Mercator (unofficial deprecated ESRI)
,代号WKID 54004
。 - 2006年 -
OSGeo
在提出的TMS - Tile Map Service
标准中使用代号OSGEO:41001(WGS84 / Simple Mercator)- Spherical Mercator (unofficial deprecated OSGEO / Tile Map Service)
。 - 2007年 -
Christopher Schmidt(OpenLayers的重要贡献者之一)
在通过一次GIS
讨论中为了在OpenLayers
中使用谷歌投影,提出给Web墨卡托
使用一个统一的代号900913 - 形似 Google
,并在OpenLayers的OpenLayers/Layer/SphericalMercator.js
中正式使用代号900913
。 - 2008年 -
EPSG
在6.15版本中正式给谷歌地图投影赋予 CRS 代号EPSG:3785(Popular Visualisation CRS / Mercator)
,这也是Web墨卡托
正式被EPSG
组织承认。 - 2009年 -
EPSG
使用新代号EPSG:3857
代替之前的EPSG:3785
,给谷歌地图投影方法命名为“公共可视化伪墨卡托投影(PVPM)”
。 - 至今 -
EPSG:3857(WGS 84 / Pseudo-Mercator)
代号是web墨卡托
的正式代号。
谷歌瓦片
经过投影变换后,地理坐标就变成了平面地图坐标。考虑到需要地图的精度有大有小(缩放),所以将地图分级:顶层为0级,由一张256像素见方的图片存储,向后每多一级,像素是当前级别的4倍。由此便组成了一个金字塔式的地图瓦片层级结构,每张瓦片的大小固定为256像素的方形。
有了地图瓦片还需要对地图瓦片进行编号才行,谷歌采用XYZ表示瓦片的坐标和显示级别(缩放级别),其中XY的原点在左上角,X从左向右,Y从上向下,Z则表示显示级别(缩放级别)。
假如我们需要一张256像素的世界卫星地图,我们可以在浏览器访问:http://mt2.google.cn/vt/lyrs=s&hl=zh-CN&gl=cn&x=0&y=0&z=0
如何决定缩放级别
了解了投影和瓦片获取方式,还是不能实现一个简单的地图,我们还需要知道什么条件下加载哪些瓦片图。我程序里处理方式比较简单,需要知道当前显示级别,然后根据显示级别和摄像机与地平面的交点推导出中心瓦片坐标,然后在按中心瓦片坐标计算当前需要加载的全部瓦片坐标。
最重要的一点就是,如何获取当前级别呢?我并没有去想计算级别的方法,因为 WebGIS
领域里,开源的 Cesium
发展非常不错,于是就在 Cesium
源码中搜索了一下,找到了相关代码,借鉴这部分代码很快就完成了我们需要的方法。
不多说,上代码:
| |
核心代码就这些,getCurrentLevel
就是获取当前显示级别的方法(当然我对原始方法稍微修改了一下以适应本地代码)。
通过代码以及注释不难理解,实际上缩放级别是通过 显示级别0下的纹素间距 和 摄像机位置与其朝向同地面的交点间距离上的纹素间距 比值决定的。
坐标转换
知道了当前级别还是不能实现一个简单的地图,因为是使用 WebGL
绘制的,所以还需要知道如何通过级别确定需要绘制的顶点坐标,这个就涉及到坐标转换的问题了。
假如我们知道了一个瓦片的 XYZ
,如何获取一个瓦片所涉及到的正方形在世界坐标系下的顶点信息呢?有了目标我们再查看 Cesium
,就能很快找到需要的代码,然后借鉴之。
| |
由源码可知,通过 tileXYToRadians
可以根据当前瓦片信息转换成边界弧度信息,再通过 tileLonlatRadians2world
由弧度信息可以获取世界坐标信息。
预备知识
好了,我们了解了投影,瓦片,级别和坐标之后,我们就可以着手写这个瓦片加载程序了。
但是再看源码之前还需要了解一些相关知识:
- WebGL API。
- 前端鼠标事件相关操作,可以查看源码了解。
- 前端类的封装以及闭包方式(为了简化开发环境和提高兼容性,源码并没有采用es6编写)。
工程文件说明
路径 | 说明 |
---|---|
css/main.css | 全局样式 |
js/Camera.js | 摄像机对象 |
js/gl-matrix-min.js | 数学计算库压缩版 |
js/gl-matrix.js | 数学计算库 |
js/mouse-utils.js | 鼠标事件工具类 |
js/Quad.js | 瓦片对象 |
js/tiles-utils.js | 瓦片相关工具类 |
js/webgl-utils.js | gl相关工具类 |
index.html | html页面 |
main.js | 主要运行过程 |
实例
已知问题
这部分是因为工程本身是为了简化代码说明瓦片加载过程,所以就忽略了部分问题,如果读者有兴趣可以自己着手解决这部分问题。
- 采样 - 目前使用的是前向渲染,用的是默认硬件采样方式。
- 坐标抖动 - 这个是坐标计算精度的问题。
- 摄像机操作 - 摄像机操作还比较生硬,平移速度没有根据缩放而变化;嵌入iframe鼠标操作并没有兼容。
- 瓦片加载方式 - 瓦片加载方式是按级别加载的, 并不会平滑过渡,也不会按照需要加载不同级别的瓦片。
引用
- GCJ02/BD09/80/54/2000常用坐标系详解-第六节(二)
- 瓦片地图原理
- WebGIS前端瓦片地图显示原理及实现
- 从底层谈,WebGIS 原理、设计、实现
- Web墨卡托投影
- Web Mercator投影与反投影计算公式
- 墨卡托投影坐标系(Mercator Projection)原理及实现C代码
- OpenStreetMap/Google/百度/Bing瓦片地图服务(TMS)
源码
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
02月22日云栖号头条:阿里发“助农五条”准则,让爱心成为最好的助农质检员
云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 今日最新云头条快讯: 近日,阿里巴巴集团向平台商家发布公告,强调平台会持续从商家准入、商品抽检和品控等五条“爱心助农”准则入手,严控产品品质关,同时呼吁所有参与“爱心助农”项目的商家拿出最好的产品,用真心回馈广大消费者的爱心;23日下午举行的上海市新冠肺炎疫情防控新闻发布会上,上海市公积金管理中心主任浦建华表示,对于受疫情影响的缴存职工,市公积金中心将加大支持力度,全面做好服务工作。 一起来看最新的资讯: 阿里发“助农五条”准则:让爱心成为最好的助农质检员 以彼心换我心,大家同心。2月21日,阿里巴巴集团向平台商家发布公告,强调平台会持续从商家准入、商品抽检和品控等五条“爱心助农”准则入手,严控产品品质关,同时呼吁所有参与“爱心助农”项目的商家拿出最好的产品,用真心回馈广大消费者的爱心。受当前物流、人力和成本等因素影响,一些地方出现农产品滞销的情况,社会各方都在力所能及地帮助解决滞销问题。自2月6日启动“爱心助农”项目,平台不到两周时...
- 下一篇
多图预警——从 RAID 到分布式系统中的副本分布
原文首发于个人博客「tobe的呓语」欢迎大家的访问收藏啊~ 我们知道,在面对大规模数据的计算和存储时,有两种处理思路: 垂直扩展(scale up):通过升级单机的硬件,如 CPU、内存、磁盘等,提高计算机的处理能力。 水平扩展(scale out):通过添加更多的机器到分布式系统中,提高整个系统的处理能力。 在分布式技术尚未成熟的时候,小型机、中型机、大型机、超级计算机逐步升级的方案几乎是大型公司的唯一选择,但是这种垂直扩展是有天花板的,硬件升级的速度远远比不上数据规模的增速,即使是超级计算机也无法满足人们对计算资源的需求。 水平扩展方案,也就是在一个系统里不断添加机器的方案,就这么走上了历史舞台。这就是现在的分布式技术。 在这篇文章里,我将分别介绍单机系统下的 RAID 存储技术以及分布式系统下的存储分布技术,这两种技术在思想上有很相近的地方,希望读者慢慢体会。 RAID RAID,全称是Redundant Array of Inexpensive/Independent Disks,也就是磁盘冗余阵列,这里的 I 有两种说法,一种是 Inexpensive,廉价,另一种是Inde...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7,CentOS8安装Elasticsearch6.8.6