快速导航
从零开始学GeoServer源码一(开篇)
从零开始学GeoServer源码二(搭建开发环境)
从零开始学GeoServer源码三(断点应该打在哪?)
从零开始学GeoServer源码四(自定义插件或拓展数据源)
从零开始学GeoServer源码五(切片原理及自定义插件支持wms、wmts、tms)
从零开始学GeoServer源码六(如何打包发布?)
从零开始学GeoServer源码七(如何注册服务并发布3dtiles和cesium的地形terrain?)
从零开始学GeoServer源码八(内存溢出?Out of Memory Error ?)
从零开始学GeoServer源码九(如何集成Cesium以实现预览3dtiles和terrain服务?)
从零开始学GeoServer源码十(如何修改菜单项以整合我们的功能?)
从零开始学GeoServer源码十一(如何解决No Multipart-config for Servlet错误)
从零开始学GeoServer源码十二(GeoServer中的切片规则)
从零开始学GeoServer源码十三(GeoServer生成的矢量切片缺失问题)
从零开始学GeoServer源码十四(GeoServer Cloud微服务版本初体验)
目录
1.前言
本来发布 3dtiles 和 cesium 的 terrain 文件并不是一定要依赖于 GeoServer ,使用 IIS 或者 Tomcat 都可以,但是发布服务,我习惯了使用 GeoServer ,因此,也就将这些功能整合到 GeoServer 里,方便自己使用。
2.思路
发布 3dtiles 和 terrain 文件的本质,都是可以通过浏览器访问静态资源,我们知道 3dtiles 有四种格式,分别为 i3dm 、b3dm、pnts、cmpt。而 terrain 文件则是 cesium 的 quantized-mesh 所使用的格式。因此,我们要解决的是两个问题:
1.如何能够通过 GeoServer 访问静态文件?
2.如何能够让某个请求,比如 /terrain 或者 /tiles 通过 GeoServer 的过滤器?
3.实现访问静态文件
其实 GeoServer 中是可以访问静态文件的,我们只需要将静态文件放在 GEOSERVER_DATA_DIR 所指向的路径中的 www 文件夹下,就可以通过 localhost://8080/geoserver/www/xxx.xxx 来访问了,我们以一个 home.html 文件为例说明一下。
3.1查看 GEOSERVER_DATA_DIR 的指向
或者如果没有在这里设置的话,可以看一下模块【gs-web-app】下面的 web.xml
如果 web.xml 中也没有设置的话,看 GeoServer 的启动日志
3.2 将静态文件放入www文件夹
如果没有 www 文件夹,右键新建一个即可。
可以看到,我们在 www 文件夹下放了一个 home.html ,接下来启动 GeoServer,访问一下看看,大功告成
访问地址为:http://localhost:8090/geoserver/www/home.html
3.3 怎么实现的?
也许你会好奇为什么这样操作以后就可以了?肯定是配置了,那么配置文件在哪?答案是,配置文件在【gs-main】包中的 applicationContext.xml 文件中,我们来看下:
4.开启GeoServer注解扫描
这一步是为了后面的工作做准备,因为 GeoServer 中的 SpringMVC 默认使用的是配置文件的方式,但是我还是习惯使用注解。因为将来我们要通过 tms 的请求(/0/1/0.terrain)来访问资源,使用注解 @RequestParam 或者 @PathVariable 可以很容易的获取访问路径中参数。
首先我们在【gs-web-app】包中 WEB-INF 下找到 dispatcher-servlet.xml ,添加 annotation-driven 和 component-scan 。
这样就开启了注解扫描和包扫描,但是我们 dispatcher-servlet.xml 还没有被扫描,因此需要在 web.xml 中加上。web.xml 的 contextConfigLocation 默认只扫描了 applicationContext.xml 和 applicationSecurityContext.xml,我们把 dispatcher-servlet.xml 也加上,变成这样:
5.注册服务
注册服务即让 GeoServer 的 SpringMVC 的 DispatcherServlet 能够通过特定 url 访问到我们自己的 Controller 里的方法。具体的原理大家可以参考索夫特威尔的博文,我这里直接给出结果,在此之前我们已经新建了一个 maven 工程,它的包名叫 org.geoserver.terrain ,在这个工程下,我们新建一个applicationContext.xml ,开始注册我们的服务。配置文件修改如下,注意划出来的地方是重点:
6.编写Controller写具体的逻辑
配置好 Controller 和 method 匹配的 URL ,给出我的 terrain 和 3dtiles 的访问接口配置
这里需要注意的是,如果访问的是terrain数据,那么当terrain里包含水面、光照信息或者terrain是经过gzip压缩的,那么后端返回的数据中也要能包括这些信息,具体就是设置相应的responseHeader,读者务必注意这里的小细节。
7.测试接口
到这里我们的配置就全部完成了,只需要 cesium 里加载一下进行测试,看是否能够进入断点就行了。这里放上 cesium 里的测试代码
//加载本地terrain
var terrain=new Cesium.CesiumTerrainProvider({
url:"http://localhost:8090/geoserver/terrain/cesium3",
requestVertexNormals : true,
requestWaterMask : true,
});
viewer.terrainProvider=terrain;
运行以后看断点
断点进来了,大功告成!
8.可能遇到的问题及解决办法
8.1 断点进不去
这个问题首先要检查前端的请求是否正确,如果正确,断点进不来,就要检查后端的配置是否正确,将我上面的步骤挨个检查一遍
8.2 断点进去了,前端出不来图
这个问题一般是遇到最多的情况,一般是由于后端响应和前端请求不对应造成的。什么叫做不对应?比如:
前端没有请求水面和光照,但是后端返回的数据里包含光照和水面,并且前端拿到的 responseHeader 里的 extension 里也没有说明数据中包含这两个拓展,那么前端就会显示不出来,但是不报错,会在浏览器控制台里 console.log,而不是 console.error.
9.总结
本篇博文,我们介绍了如何注册服务,如何发布 3dtiles 和 terrain ,拓展了 GeoServer 能够发布的服务类型,但是这个程序还可以进行完善,比如,如果 terrain 中包含水面和光照,如何进行文件的解析,如何向前端进行返回等等。不过目前为止,可以满足我们发布服务并在前端加载的需求,这些功能就留着后续完善吧,下一篇我们讲一下如何把 cesium 集成到 GeoServer 里来,以实现三维的预览功能,回见~。
————————————————————————————————————————————————
补充:不少小伙伴问我要 TileService 和 TerrainService 的源码,这两个文件的源码实在太简单了,没啥好值得研究的,这两种服务都是做文件的二进制下载,网上代码一搜一大把,所以我这里直接给出思路,:
TileService:
实现的功能是根据前端请求的文件的路径,去寻找对应的文件,相当于做文件的下载。不需要做任何多余的操作。
TerrainService:
实现的功能也是根据前端请求的文件的路径,去寻找对应的文件,相当于做文件的下载。这里唯一和 TileService 不同的是,要根据 terrain 文件中是否包含水面或者法线返回不同的 HttpResponseHeader里的 extension ,就这么简单。如果文件中既没有水面也没有法线,那就不要返回 extension 就行了。
更多精彩内容见公众号AIGIS