前言
刚进目前所在的这家公司之前,其实我没有做过 webgis 方面的开发工作的,所以对于 gis 开发,我算是个完完全全的新手。
那时候,我甚至连 wmts、wms 服务都不太能分得清。更不要说什么 openlayers、cesium、geoserver 这些了,统统都没怎么用过。
想想,人对于未知的东西,就会产生恐惧。
而客服恐惧的最好方式,就是不停的学习。
很多时候,有了好的学习资料,有了好的学习方式,甚至于有了好的老师,完全可以让你事半功倍。
相反,如果这些都没有,也只能让你事倍功半了。
回过头来想想,对于 webgis 方面的学习,真可谓是一路坎坷,甚至于比自学前端的经历更让人难忘。
虽然很多人都说前端简单,但是如果你只是写写 html、css,而且只满足于应付日常的工作,确实简单。
但是,在众多的前端领域中,如果你选择的是我之前做过的数据可视化方向,以及现在做的 webgis 方向,你会真真切切的感受到,那些口口声声说简单的人简直是睁着眼睛说瞎话。
对于前端数据可视化工程师和 webgis 工程师来说,首先,你得是个优秀的前端工程师,也就是说,大部分前端的会的东西,你都要会,并且需要你掌握的游刃有余,这样才能不至于与前端这个岗位脱节。
除了这些以外,你还要学习掌握一些 canvas、webgl 等知识,如果你是做 webgis 方向,你还要了解 gis 方面的一些专业知识。
这几个方面的知识,除了 canvas 稍微简单好啃点,其他都是一些难啃的硬骨头。
初识 webgis
很多东西,你只有接触了,思考了,并在实际的工作中运用了,才会开始慢慢掌握,了解其应用场景,否则,即使是学习了,也很难融会贯通。
就比如我今天要讲的这个话题,就让我深切的感受到了这一点。
通常情况下,在 web 端,加载影像图都是通过影像切片的方式进行的。
在这里,我不想引用一大段专业的术语,来枯燥的讲述什么是影像切片,因为这毫无意义。
我写并非科普文,只是想从一个外行的从业者,谈谈自己对 webgis 的理解,如果完全“照本宣科”,就背离了我写这篇文章的初衷了。
当然以下的内容,完全是我一家之言,如果有讲的不对的地方,希望更专业的童鞋能像我提出自己的意见,大家一起讨论讨论。
个人理解,之所以出现影像切片,纯粹是由于,对于 web 端来说,需要一个更加合适的方式,来展示影像图。
那么为什么不能直接展示影像图呢?原因显而易见,数据量太大,没法直接在 web 端展示。
一般按照我们通俗的理解来说,一张照片要想越清晰,分辨率就得越高,分辨率越高同时也意味照片越大。
这个道理放在影像图,也就是 geotiff 上,同样适用。
通常情况下,一景数据(也就是卫星拍摄的一张影像),所包含的面积,少则几千平方公里,多则上万平方公里。
试想想,范围这么大,又想看得清晰,geotiff 文件大也可以了理解了。
更别说,我们通常用的影像图,都是用好多景的数据拼凑而成,形成某个区域或地方的某一时期的影像图。
这么大的文件,不可能通过网络直接传输,进而显示到用户的浏览器上的。
那么就有了一些别的方法,可以帮助我们,实现直接远程通过浏览器来查看影像图的目的。
其中 OSGeo 制定的 Web地图服务(WMS) — OGC e-Learning 2.0.0 文档、Web地图平铺服务(WMTS) — OGC e-Learning 2.0.0 文档 等地图可视化服务标准,就是通过一定的分层规则和投影方式,对影像进行分层切割。
使用的时候再按照对应的规则,根据层级请求瓦片资源,进行地图还原。
详细的定义和使用方式,在这里,我就不想过多的赘述了。我想能阅读这篇文章的人,多半对这些知识有过一些了解。
当然,据我了解,也还有一些别的影像使用方式,比如谷歌的 xyz 方式、bing 地图的 QuadTree 方式,甚至于还有不切片的 Cloud Optimized GeoTIFF 的方案。
这些不在我们这里的讨论范围之内,有兴趣的童鞋,可以自行了解下相关知识。
geoserver
谈到了 wmts、wms 以后,一个不能避开的一个话题就是 GeoServer 了。
geoserver 是一款开源的地图服务软件,允许用户共享和编辑地理空间数据。
对 geoserver 不了解的童鞋,可以去官网看下介绍:GeoServer Documentation。要是觉得英文阅读存在障碍的童鞋,还有对应的中文文档:GeoServer用户手册 — GeoServer 2.19.x User Manual。
一般情况下,我们会用 geoserver 发布矢量和栅格图,然后通过调用其提供的 wmts 或者 wms 服务接口来加载地图。
具体如何发布以及如何使用发布的影像,可以查看相关文档进行了解。
最近在使用 geoserver 的时候,突然发现它支持一种很奇怪的 format:
当然,之前也并不是没发现,可以选择很多不同的格式来查看发布的数据,只不过以前没去探究原因而已。
这次,刚好需要对项目做一些优化工作,所以就开始注意到这个地方了。
我们知道,png 格式支持 alpha 通道,所以一般情况下,我们会用 png 格式来存储可能会存在透明区域的图。当然,还有 webp 等图片格式,支持 alpha 通道,但是由于 geoserver 默认不支持,就不再这里讨论了。
当改用 image/vnd.jpeg-png
这个方式的时候,wms 请求里,参数发生了一些变化:
为了了解清楚其作用,在官方文档 WMS output formats — GeoServer 2.21.x User Manual 找到如下描述。
简而言之,这个格式的作用的就是,如果影像中存在透明的区域,就会返回 png 图像;如果不存在,则返回 jpg 格式的图像。
可以说,这种方案,一举解决了,之前项目中的种种弊端。
- 影像图不能用 jpeg 格式,因为会存在透明区域,叠加在底图上效果会很难看。所以,以前默认情况下,都是用 png 格式的瓦片。
- 但是 png 由于编码的原因,单张瓦片占用内存太大,浪费存储空间。
- 一般我们都会用 gwc 的方式来访问影像切片,为了加速访问,我们一般会提前预切好到一定层级的影像瓦片。
- 正常情况下,一帮 256 * 256 大小的瓦片,如果内容丰富,jpeg 格式和 png 格式,所占存储空间大小相差十倍之多,导致如果全用 png 格式,对服务器来说,带宽压力很大;对客户端来说,表现的性能也要差的多。
- 改用 webp,默认 geosever 不支持该格式; openlayers、cesium 等前端 gis 框架的支持度也有待考证;某些系统的浏览器,默认对 webp 的支持度不高。
基于以上种种因素,这种自动决定使用 jpeg 或者 png 的瓦片方案,简直就是太优秀了。
实际应用
稍微研究了下,改改之前的加载方式,就能很平滑的应用到实际的项目中去了:
// 在 openlayers 中使用
new WMTS({
name: option.name,
url: `${config.wmtsPrefix}?transparent=TRUE`,
layer: option.layerName,
style: '',
matrixSet: 'EPSG:4326',
format: 'image/vnd.jpeg-png',
wrapX: true,
tileGrid: new WMTSTileGrid({
tileSize: [tileSize, tileSize],
extent: option.extent || [-180.0, -90.0, 180.0, 90.0], // 范围
origin,
resolutions,
matrixIds,
}),
})
//在 cesium 中使用
new WebMapTileServiceImageryProvider({
url: `${url}?transparent=TRUE`,
layer,
style,
format: 'image/vnd.jpeg-png',
rectangle: Rectangle.fromDegrees(
...rectangle,
),
tilingScheme: new GeographicTilingScheme({
numberOfLevelZeroTilesX: 2,
numberOfLevelZeroTilesY: 1,
}),
tileMatrixSetID: 'EPSG:4326',
tileMatrixLabels: [...Array(zoomMax - zoomMin + 1)].map((_, index) => `EPSG:4326:${zoomMin + index}`),
minimumLevel: zoomMin,
maximumLevel: zoomMax,
});
当然,以上两段代码,都是没法正常运行的,需要结合实际的情况,补齐对应的变量方能正常的将 wmts 服务请求的瓦片格式设置为 image/vnd.jpeg-png
。
当然,如果你不是用 geoserver 作为地图服务器,就不能直接这么用了,这是 geoserver 特有的功能。
如果你也像我们一样,用 gwc 对瓦片做缓存,那么你需要开启对 vnd.jpeg-png
格式的支持,默认 gwc 是没开启对该格式的支持的。
结语
老实说,这篇文章,前前后后写了很多次,每次想一鼓作气地写完,却每每半途而废。
本想不落窠臼,却无奈对于 webgis 了解的并不是太透彻,最后难免还是落入了俗套。
不过好歹也是写完了,对自己也算是有了一个交代吧。
世上无难事,只怕有心人。
这句谚语,你越是品味,越是觉得其中蕴涵了丰富的人生经验。
现在回过头去看看,不知不觉,在很多以前看来是未知的领域,已经探索了很久了。
从陌生到熟悉,从畏惧到从容,从一知半解到现在的渐入佳境,这又何尝不是一种美妙的体验呢。
越是深入研究,就越是明白一个道理,其实技术不分高低贵贱,更不分对错,什么场景使用什么技术,也只不过是一种取舍而已。