这里不讨论如何用OsgEarth加载天地图,只记录一下在加载天地图过程中的失败原因及解决方案。OsgEarth加载天地图其实有两个问题,一个是请求头问题,一个是mineType问题。
- 请求头问题
- 首先我们加载天地图时的token是使用浏览器端的(服务器token如何使用我也不知道)。
- 我们可以随便拼接一个url,把url放在浏览器上是可以正常请求的,但是我们自己写代码去请求的时候会返回类似token不匹配的错误:
https://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX=1&TILEROW=1&TILECOL=1&tk={你的token}
- 如果会抓包的同学可以通过抓包来对比浏览器请求和我们自己写代码请求的http头的差异。因为我对http比较熟悉了,所以这里就已经猜到是没有加请求头的缘故。直接打开浏览器控制台找到我们请求的url,把所有的请求头全部加到我们自己代码里面(其实最主要的是User-Agent,这是用来标识客户端类型的)。
- 反映到代码里面就是将请求头添加到osgEarth::URIContext里面
osgEarth::URIContext context;
context.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/"
"*;q=0.8,application/signed-exchange;v=b3;q=0.9");
context.addHeader("Accept-Encoding", "gzip, deflate");
context.addHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6");
context.addHeader("Cache-Control", "max-age=0");
context.addHeader("Connection", "keep-alive");
context.addHeader("Upgrade-Insecure-Requests", "1");
context.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39");
osgEarth::URI uri("https://t[01234567].tianditu.gov.cn/img_w/"
"wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&"
"FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=84bc0519f3fca639eb891cbd0703cd50",
context);
- mineType问题
- 这个问题分析起来比较麻烦,我也是偶然找到osgEarth源码中的
HTTPClient.cpp
文件,在里面打断点一步步调试找到的,这里只说结果。 - 如果调试过这部分代码的同学可以发现里面(不是上面提到的这个类,是osgDB::Registry)有装一个MineType的容器,这个容器里面有
image/jpeg;
和image/jpg;
两个key,但是天地图给我们的响应体却是image/jpeg;charset=utf8
,多了个后缀。 - 我们要做的就是注册这个key,反映到代码里如下
- 这个问题分析起来比较麻烦,我也是偶然找到osgEarth源码中的
osgDB::Registry::instance()->addMimeTypeExtensionMapping("image/jpg;charset=utf8", "jpg");
osgDB::Registry::instance()->addMimeTypeExtensionMapping("image/jpeg;charset=utf8", "jpg");