Cesium通过加载geoserver发布的数据进行渲染水面(Primitive方式)

Posted hpugisers

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cesium通过加载geoserver发布的数据进行渲染水面(Primitive方式)相关的知识,希望对你有一定的参考价值。

本文主要是通过加载geoserver的geojson数据来获取Primitive的坐标来渲染水面,我将效果封装一个类,方面调用

一、效果
二、封装类

import Cesium from 'cesium/Cesium'
export default class PrimitiveWaterFace 
  constructor (viewer, options) 
    this.viewer = viewer
    // 水面范围坐标
    this.degreesArrayHeights = options.DegreesArrayHeights
    // 水面的图片
    this.normalMapUrl = options.normalMapUrl
    // geomtry
    this.geometry = undefined
    this.appearance = undefined
    this.primitive = undefined
    // 仅在通过geoserver方式加载geojson使用
    this.primitiveArray = []
    // geojson的地址
    this.geojsonUrl = options.geojsonUrl
    // 拉伸高度
    this.extrudedHeight = options.extrudedHeight == null ? 0 : options.extrudedHeight
    this.CreateAppearence = this.CreateAppearence.bind(this)
    this.CreateGeometry = this.CreateGeometry.bind(this)
    this.FSWaterFace = this.FSWaterFace.bind(this)
    this.GetDegreesArrayHeightsByGeojson = this.GetDegreesArrayHeightsByGeojson.bind(this)
    this.fragmentShader = this.FSWaterFace()
    this.initWater()
  
  initWater () 
    // 初始化appearance
    this.appearance = this.CreateAppearence(this.fragmentShader, this.normalMapUrl)
    if (this.degreesArrayHeights != null && this.geojsonUrl == null) 
      // 初始化geometry
      this.geometry = this.CreateGeometry(this.degreesArrayHeights, this.extrudedHeight)
      this.primitive = this.viewer.scene.primitives.add(new Cesium.Primitive(
        allowPicking: false,
        geometryInstances: new Cesium.GeometryInstance(
          geometry: this.geometry
        ),
        appearance: this.appearance,
        asynchronous: false
      ))
     else if (this.degreesArrayHeights == null && this.geojsonUrl != null) 
      this.GetDegreesArrayHeightsByGeojson(this.geojsonUrl)
    
  
  // 通过geojson初始化水面
  GetDegreesArrayHeightsByGeojson (geojsonUrl) 
    var promise = Cesium.GeoJsonDataSource.load(geojsonUrl)
    let polygonHierarchyArray = []
    let viewer = this.viewer
    promise.then((dataSource) => 
      let entities = dataSource.entities.values
      for (var i = 0; i < entities.length; i++) 
        let entity = entities[i]
        let polygonHierarchy = entity.polygon.hierarchy.getValue().positions
        for (let j = 0; j < polygonHierarchy.length; j++) 
          // 将笛卡尔三维坐标转为地图坐标(弧度)
          let cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(polygonHierarchy[j])
          // 将地图坐标(弧度)转为十进制的度数
          let lat = parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(6))
          let lng = parseFloat(Cesium.Math.toDegrees(cartographic.longitude).toFixed(6))
          let alt = parseFloat((viewer.camera.positionCartographic.height / 100000).toFixed(2))
          polygonHierarchyArray.push(lng)
          polygonHierarchyArray.push(lat)
          polygonHierarchyArray.push(alt)
        
      
      this.degreesArrayHeights = polygonHierarchyArray
      this.geometry = this.CreateGeometry(this.degreesArrayHeights, this.extrudedHeight)
      let primitive = this.viewer.scene.primitives.add(new Cesium.Primitive(
        allowPicking: false,
        geometryInstances: new Cesium.GeometryInstance(
          geometry: this.geometry
        ),
        appearance: this.appearance,
        asynchronous: false
      ))
      this.primitiveArray.push(primitive)
    ).otherwise(function (error) 
      window.alert(error)
    )
  
  CreateGeometry (_degreesArrayHeights, _extrudedHeight) 
    return new Cesium.PolygonGeometry(
      polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(_degreesArrayHeights)),
      extrudedHeight: _extrudedHeight,
      perPositionHeight: true
    )
  
  CreateAppearence (fs, url) 
    return new Cesium.EllipsoidSurfaceAppearance(
      material: new Cesium.Material(
        fabric: 
          type: 'Water',
          uniforms: 
            normalMap: url,
            frequency: 1000.0,
            animationSpeed: 0.05,
            amplitude: 10.0
          
        
      ),
      fragmentShaderSource: fs
    )
  
  FSWaterFace () 
    return 'varying vec3 v_positionMC;\\n' +
       'varying vec3 v_positionEC;\\n' +
       'varying vec2 v_st;\\n' +
       'void main()\\n' +
     '\\n' +
      'czm_materialInput materialInput;\\n' +
      'vec3 normalEC = normalize(czm_normal3D * czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)));\\n' +
      '#ifdef FACE_FORWARD\\n' +
      'normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\\n' +
      '#endif\\n' +
      'materialInput.s = v_st.s;\\n' +
      'materialInput.st = v_st;\\n' +
      'materialInput.str = vec3(v_st, 0.0);\\n' +
      'materialInput.normalEC = normalEC;\\n' +
      'materialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, materialInput.normalEC);\\n' +
      'vec3 positionToEyeEC = -v_positionEC;\\n' +
      'materialInput.positionToEyeEC = positionToEyeEC;\\n' +
      'czm_material material = czm_getMaterial(materialInput);\\n' +
      '#ifdef FLAT\\n' +
      'gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\\n' +
      '#else\\n' +
      'gl_FragColor = czm_phong(normalize(positionToEyeEC), material,czm_lightDirectionEC);\\n' +
      'gl_FragColor.a = 0.5;\\n' +
      '#endif\\n' +
     '\\n'
  


两种调用方式示例
1、自定义范围

  var lat = 30.10932;
  var lon = 116.04437;
  let waterFace = [116.04437, 30.10932, 10,
                         116.04537, 31.10932, 10,
                         117.04537, 35.11032, 10,
                         116.04437, 32.11032, 10,
                         115.04437, 33.10932, 10];
  let options=
    'normalMapUrl': '../static/waterNormals.png',
    'DegreesArrayHeights':waterFace,
    'extrudedHeight':0,
    'geojsonUrl':'null'
   
   let waterface=new PrimitiveWaterFace(this.viewer,options);

2、通过geoserver加载geojson

  let options=
    'normalMapUrl': '../static/waterNormals.png',
    'DegreesArrayHeights': null,
    'extrudedHeight':0,
    'geojsonUrl':'http://localhost:8080/geoserver/cite/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=cite%3AbeijingBoundary&maxFeatures=1000&outputFormat=application%2Fjson'
   
   let waterface=new PrimitiveWaterFace(this.viewer,options);

参考文献
http://blog.sina.com.cn/s/blog_15e866bbe0102y0ql.html

以上是关于Cesium通过加载geoserver发布的数据进行渲染水面(Primitive方式)的主要内容,如果未能解决你的问题,请参考以下文章

Cesium加载各种类型数据的图层(JS实现)

cesium加载geoserver 发布的wmts服务

Cesium加载服务

Cesium展示dem数据踩坑记录

cesium 结合 geoserver 实现地图属性查询(附源码下载)

cesium结合geoserver实现地图空间查询(附源码下载)