webgis —— geoserver 更优秀的瓦片格式

前言

刚进目前所在的这家公司之前,其实我没有做过 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:

20220706145136.png

当然,之前也并不是没发现,可以选择很多不同的格式来查看发布的数据,只不过以前没去探究原因而已。

这次,刚好需要对项目做一些优化工作,所以就开始注意到这个地方了。

我们知道,png 格式支持 alpha 通道,所以一般情况下,我们会用 png 格式来存储可能会存在透明区域的图。当然,还有 webp 等图片格式,支持 alpha 通道,但是由于 geoserver 默认不支持,就不再这里讨论了。

当改用 image/vnd.jpeg-png 这个方式的时候,wms 请求里,参数发生了一些变化:

20220706150752.png

为了了解清楚其作用,在官方文档 WMS output formats — GeoServer 2.21.x User Manual 找到如下描述。

20220706151325.png

简而言之,这个格式的作用的就是,如果影像中存在透明的区域,就会返回 png 图像;如果不存在,则返回 jpg 格式的图像。

可以说,这种方案,一举解决了,之前项目中的种种弊端。

  1. 影像图不能用 jpeg 格式,因为会存在透明区域,叠加在底图上效果会很难看。所以,以前默认情况下,都是用 png 格式的瓦片。
  2. 但是 png 由于编码的原因,单张瓦片占用内存太大,浪费存储空间。
  3. 一般我们都会用 gwc 的方式来访问影像切片,为了加速访问,我们一般会提前预切好到一定层级的影像瓦片。
  4. 正常情况下,一帮 256 * 256 大小的瓦片,如果内容丰富,jpeg 格式和 png 格式,所占存储空间大小相差十倍之多,导致如果全用 png 格式,对服务器来说,带宽压力很大;对客户端来说,表现的性能也要差的多。
  5. 改用 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 是没开启对该格式的支持的。

20220706154406.png

结语

老实说,这篇文章,前前后后写了很多次,每次想一鼓作气地写完,却每每半途而废。

本想不落窠臼,却无奈对于 webgis 了解的并不是太透彻,最后难免还是落入了俗套。

不过好歹也是写完了,对自己也算是有了一个交代吧。

世上无难事,只怕有心人。

这句谚语,你越是品味,越是觉得其中蕴涵了丰富的人生经验。

现在回过头去看看,不知不觉,在很多以前看来是未知的领域,已经探索了很久了。

从陌生到熟悉,从畏惧到从容,从一知半解到现在的渐入佳境,这又何尝不是一种美妙的体验呢。

越是深入研究,就越是明白一个道理,其实技术不分高低贵贱,更不分对错,什么场景使用什么技术,也只不过是一种取舍而已。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容