当前位置:   article > 正文

从零开始学GeoServer源码九(如何集成Cesium以实现预览3dtiles和terrain服务?)_geoserver 3dtiles

geoserver 3dtiles

快速导航

从零开始学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微服务版本初体验)

点我去AIGIS公众号查看本文

1.前言

  在第七篇中我们讲了如何使用 GeoServer 发布 3dtilesterrain 文件,在那一篇中,我们最终实现了发布功能,但预览功能还是需要在 Cesium 的工程里去手动添加预览,对使用者来说还是不太方便,这一期我们就讲讲如何把 Cesium 集成进来,在 GeoServer 中实现三维的预览,就像预览二维那样。

2.思路

在这里插入图片描述
  在第七篇中我们已经实现了访问一个静态页面,还不知道如何实现的同学可以先移步去看下:从零开始学GeoServer源码七(如何注册服务并发布3dtiles和cesium的地形terrain?)。那么预览页面就可以在这个静态页面中放一个 a 标签,然后跳转到预览页面去,预览页面我们就使用 Cesium 中提供的 HelloWorld 就行。跳转的过程中,把服务对应的信息给传过去就可以了。

3.准备一个预览页面

  这个预览页面我管他叫 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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

4.在静态页面准备一个a标签跳转并传值

  这个静态页面我是用 vue 写的, vuea 标签跳转很简单,我们直接上图:
在这里插入图片描述
  这是我们的预览按钮及 a 标签跳转时如何传值的写法,如果页面不是用 vue 写的话,那传值更简单了,读者自行询问度娘便是。我们可以看到传了一个 previewId 给预览页面,这是一个唯一编号,那么接下来就是如何在预览页面获取值。

5.完善静态页面

5.1 获取要预览服务的唯一编号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);
  • 1
  • 2

5.2 准备加载3dtiles和terrain的函数

  因为我们预览的是这两种服务,所以准备两个函数来分别实现。
首先是加载 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);
      });
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

然后是加载 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;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5.3 发ajax获取服务的url

  这里有两种方式。第一,通过 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
        });
      }
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

这里需要说明的是,加载 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,所以要替换为空。

6. 补全预览页面需要的Cesium依赖

  那么 CesiumHelloWorld 需要什么依赖呢,答案就是 Build 文件夹中所有内容,我们直接给拷贝过去,我这里把源码 Source 文件夹也拷贝过去了,方便调试。最终的项目结构如下图
在这里插入图片描述
如果需要开启源码,这样设置:

  import * as Cesium from './Source/Cesium.js';
  window.CESIUM_BASE_URL='./Source';
  window.Cesium=Cesium;
  • 1
  • 2
  • 3

7.看看预览时的效果

先看下 terrain
在这里插入图片描述
再看下 3dtiles
在这里插入图片描述
用金星的话说就是,完美,perfect,哈哈哈~~~~

8.总结

  本文我们成功的将 Cesium 集成到 GeoServer 里来,实现了 3dtilesterrain 服务的预览效果,弥补了 GeoServer 只有二维预览效果缺憾。本文中的操作都不难,只要细心,都可以实现。本期就讲到这里了,下期我们讲一讲,怎么修改 GeoServer 的菜单。
更多精彩内容见公众号AIGIS

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/758088
推荐阅读
  

闽ICP备14008679号