赞
踩
从零开始学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微服务版本初体验)
在第七篇中我们讲了如何使用 GeoServer 发布 3dtiles 和 terrain 文件,在那一篇中,我们最终实现了发布功能,但预览功能还是需要在 Cesium 的工程里去手动添加预览,对使用者来说还是不太方便,这一期我们就讲讲如何把 Cesium 集成进来,在 GeoServer 中实现三维的预览,就像预览二维那样。
在第七篇中我们已经实现了访问一个静态页面,还不知道如何实现的同学可以先移步去看下:从零开始学GeoServer源码七(如何注册服务并发布3dtiles和cesium的地形terrain?)。那么预览页面就可以在这个静态页面中放一个 a 标签,然后跳转到预览页面去,预览页面我们就使用 Cesium 中提供的 HelloWorld 就行。跳转的过程中,把服务对应的信息给传过去就可以了。
这个预览页面我管他叫 preview.html ,为了简单,直接使用 Cesium 中提供的 HelloWorld 。
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Use correct character set. -->
<meta charset="utf-8" />
<!-- Tell IE to use the latest, best version. -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>
<title>Hello World!</title>
<script src="../Build/Cesium/Cesium.js"></script>
<style>
@import url(../Build/Cesium/Widgets/widgets.css);
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
var viewer = new Cesium.Viewer("cesiumContainer");
</script>
</body>
</html>
这个静态页面我是用 vue 写的, vue 的 a 标签跳转很简单,我们直接上图:
这是我们的预览按钮及 a 标签跳转时如何传值的写法,如果页面不是用 vue 写的话,那传值更简单了,读者自行询问度娘便是。我们可以看到传了一个 previewId 给预览页面,这是一个唯一编号,那么接下来就是如何在预览页面获取值。
这也很简单,因为我们传值是会表现在 url 里的,我们直接从 url 获取就是了。先看下预览页面中的 url 长什么样子:
http://localhost:8090/geoserver/www/preview.html?1f1bc035-4143-4c0f-b040-53dfb2219f0b
那么获取就水到渠成了,一行代码搞定。
var serviceid = location.search.split("?")[1];
console.log(serviceid);
因为我们预览的是这两种服务,所以准备两个函数来分别实现。
首先是加载 3dtiles 的
function add3dtiles(url) {
let tileset = new Cesium.Cesium3DTileset({
url: url // 这里就是服务地址,切记 在服务地址后面加上 tileset.json 不然就报错 平铺失败
});
viewer.scene.primitives.add(tileset); // 到这儿就加载完成了
tileset.readyPromise.then(function (tileset) {
var boundingSphere = tileset.boundingSphere;
var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height - 30);
var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
viewer.zoomTo(tileset);
});
}
然后是加载 terrain 的
function addTerrain(url,extension) {
//加载本地terrain
var terrain = new Cesium.CesiumTerrainProvider({
url:url,
requestVertexNormals: extension.vertexNormals=="true" ? true : false,
requestWaterMask: extension.waterMask=="true" ? true : false,
});
viewer.terrainProvider = terrain;
}
这里有两种方式。第一,通过 serviceId 调用后台接口返回。第二,细心的读者会发现访问的 url 在静态页面不就有吗?传下值就可以了,是的。但是我觉的这种传值方式在 sessionStorage 里存的数据会随着点击量的增多而增多,并且页面又没有使用 vuex ,不太方便,那就走后台接口吧。
$.ajax({
//请求方式
type: "post",
//请求地址
url: server + "/geoserver/terrain/GetInfoById",
//数据,json字符串
data: {id:serviceid},
}).then(function (result) {
console.log(result);
if(result.serviceType=="3dtiles"){
add3dtiles(result.href);
}else if(result.serviceType=="quantized-mesh"){
var url=result.href.replace("/layer.json","");
addTerrain(url,{
vertexNormals:result.vertexNormals,
waterMask:result.waterMask
});
}
});
这里需要说明的是,加载 3dtiles 时,需要的路径是直接给到某个tileset.json,如:http://192.168.0.115:8090/geoserver/tiles/335ba201-c432-4d3b-b056-0f3f74a939ad/tileset.json
而加载terrain时,虽然访问的 url 里带有 layer.json ,如:http://192.168.0.115:8090/geoserver/terrain/1f1bc035-4143-4c0f-b040-53dfb2219f0b/layer.json
但 cesium 并不需要这个 layer.json,所以要替换为空。
那么 Cesium 的 HelloWorld 需要什么依赖呢,答案就是 Build 文件夹中所有内容,我们直接给拷贝过去,我这里把源码 Source 文件夹也拷贝过去了,方便调试。最终的项目结构如下图
如果需要开启源码,这样设置:
import * as Cesium from './Source/Cesium.js';
window.CESIUM_BASE_URL='./Source';
window.Cesium=Cesium;
先看下 terrain 的
再看下 3dtiles 的
用金星的话说就是,完美,perfect,哈哈哈~~~~
本文我们成功的将 Cesium 集成到 GeoServer 里来,实现了 3dtiles 和 terrain 服务的预览效果,弥补了 GeoServer 只有二维预览效果缺憾。本文中的操作都不难,只要细心,都可以实现。本期就讲到这里了,下期我们讲一讲,怎么修改 GeoServer 的菜单。
更多精彩内容见公众号AIGIS
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。