cesium实现高亮动态楼栋路线效果

效果图如下

vue文件如下 ,主要是调用如下方法

mapMixin._c_add_tileset('./mapdata/cesium/ccbuild/tileset.json') // 添加楼栋模型

mapMixin._c_add_hight_line(lightLine)    // 添加动态路线

<template>
  <div class="mapBox">
    <div id="cesium" ref="cesium"></div>
  </div>
</template>

<script>
import lightLine from "./js/data/lightLine";
import mapMixin from "./js/mapMixin";
import geojson from "./js/data/town.json";
export default {
  data() {
    return {
      viewer:null,
      tilesets:null
    }
  },
  mounted() {
    this.mapInit();
  },
  methods: {
    mapInit() {
      Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees( 90, -20, 110, 90); //西南东北,默认显示中国
      this.viewer = new Cesium.Viewer("cesium", {
        animation: false, //是否显示动画控件
        homeButton: false, //是否显示home键
        geocoder: false,// 查询
        baseLayerPicker: false, //是否显示图层选择控件
        timeline: false, //是否显示时间线控件
        fullscreenButton: false, //是否全屏显示
        scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
        infoBox: false, //是否显示点击要素之后显示的信息
        sceneModePicker: false, //是否显示投影方式控件  三维/二维
        navigationHelpButton: false, //是否显示帮助信息控件
        imageryProvider: new Cesium.UrlTemplateImageryProvider({
          url: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
        }),
        terrainProvider: new Cesium.CesiumTerrainProvider({ 
          url: "http://data.marsgis.cn/terrain"
        }),
        skyAtmosphere:false,
        // orderIndependentTranslucency: false,
        contextOptions: {
          webgl: {
            alpha: true,
          },
        },
      });
      // 设置基本属性
      this.viewer.scene.sun.show = false; 
      this.viewer.scene.moon.show = false;
      this.viewer.scene.skyBox.show = false; //关闭天空盒,否则会显示天空颜色
      this.viewer.scene.undergroundMode = true; 
      this.viewer.scene.globe.show = true; 
      this.viewer.scene.backgroundColor = new Cesium.Color(0, 0, 0, 0);
      this.viewer.scene.screenSpaceCameraController.minimumZoomDistance = 1000;
      this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 5600000;
      if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
        //判断是否支持图像渲染像素化处理
        this.viewer.resolutionScale = window.devicePixelRatio;
      }
      this.viewer.scene.fxaa = true;
      this.viewer.scene.postProcessStages.fxaa.enabled = true;
      // 隐藏版权
      this.viewer._cesiumWidget._creditContainer.style.display = "none";

      this.viewer.scene.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(
          120.952811,31.854272,
          6000
        ),
        orientation: {
          heading: Cesium.Math.toRadians(0),
          pitch: Cesium.Math.toRadians(-40),
          roll: Cesium.Math.toRadians(0), //heading、pitch和roll就是镜头相对于xyz轴的角度,比如pitch为-90°而另外两个为0时,就是90°向下俯视地球。
        },
      });
      mapMixin.viewer = this.viewer

      mapMixin._c_add_tileset('./mapdata/cesium/ccbuild/tileset.json') // 添加楼栋模型
      mapMixin._c_add_hight_line(lightLine)    // 添加动态路线
      mapMixin._c_add_geojson_area(geojson)   // 只显示区域地图
    },
  },
  }
</script>
<style lang='scss'>
.mapBox{
  width: 100%;
  height: 100%;
  #cesium{
    width: 100%;
    height: 100%;
    padding:20px;
    box-sizing: border-box;
  }
  .cesium-selection-wrapper,.cesium-selection-wrapper-visible{
    display: none!important;
  }
}
</style>

mapMixin.js如下:楼栋数据没有的话就用

测试数据:'https://lab.earthsdk.com/model/702aa950d03c11e99f7ddd77cbe22fea/tileset.json

线路数据结构如下: 可自己随意点几个点测试

 

var mapMixin = {
    _m_uuid: function(){
      return Math.random().toString(36).substr(3, 10)
    },
    // 批量添加高亮路线动态
    _c_add_hight_line: function(data){
      data.forEach(item => {
        this._c_add_line(item,Cesium.Color.YELLOW,'indexRoute')
      });
    },
    // 添加光亮线段
    _c_add_line: function(positions,color,type) {
      this.viewer.entities.add({
        id:type+this._m_uuid(),
        name: "polyline",
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArray([
            ...positions
          ]),
          width: 4,
          material: new Cesium.PolylineTrailLinkMaterialProperty(color,4000),
          show: true,
          clampToGround: true,
        },
      });
    },
    // 展示楼栋特效
    _c_add_tileset: function(url) { 
      // 特效 默认开启
      Cesium.TILE_EFFECT_STAYE = true;
      // 加载3dtileset
      this.tilesets = this.viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
        url: url
        // url: 'https://lab.earthsdk.com/model/702aa950d03c11e99f7ddd77cbe22fea/tileset.json'
      }))

      this.tilesets.readyPromise.then( (tileset)=> {
        tileset.style = new Cesium.Cesium3DTileStyle({
          color: {
            conditions: [
              ["true", "color('#00b2b8')"]
            ]
          }
        });

        // this.viewer.flyTo(tileset)
      })
    },
}
export default mapMixin

其中PolylineTrailLinkMaterialProperty,Cesium3DTileStyle为后的样式,内容如下:

cesium-tilesetEffect.js

; if (typeof Cesium !== 'undefined') (function (Cesium) {

    /**
     * 通过重写模型每一帧渲染着色逻辑注入自定义着色器
     * 性能以及通用性较差,建议单独写一套3dtiles加载逻辑,自定义着色程序
     */
    Cesium.TILE_EFFECT_STATE = true;
    // 带光环的
    Cesium.TILE_FS_BODY = ` float stc_pl = fract(czm_frameNumber / 120.0) * 3.14159265 * 2.0;
                float stc_sd = v_stcVertex.z / 60.0 + sin(stc_pl) * 0.1;
                gl_FragColor *= vec4(stc_sd, stc_sd, stc_sd, 1.0);
                float stc_a13 = fract(czm_frameNumber / 360.0);
                float stc_h = clamp(v_stcVertex.z / 450.0, 0.0, 1.0);
                stc_a13 = abs(stc_a13 - 0.5) * 2.0;
                float stc_diff = step(0.005, abs(stc_h - stc_a13));
                gl_FragColor.rgb += gl_FragColor.rgb * (1.0 - stc_diff);`;
    // 不带光环的
    // Cesium.TILE_FS_BODY = ` float stc_pl = fract(czm_frameNumber / 120.0) * 3.14159265 * 2.0;
    //             float stc_sd = v_stcVertex.z / 60.0 + sin(stc_pl) * 0.1;
    //             gl_FragColor *= vec4(stc_sd, stc_sd, stc_sd, 1.0);
    //             float stc_a13 = fract(czm_frameNumber / 360.0);
    //             float stc_h = clamp(v_stcVertex.z / 450.0, 0.0, 1.0);
    //             stc_a13 = abs(stc_a13 - 0.5) * 2.0;`;

    function install() {

        Cesium.ModelUtility.updateForwardAxis = function (model) {
            this._model = model;
            var cachedSourceVersion = model.gltf.extras.sourceVersion;

            if (
                (Cesium.defined(cachedSourceVersion) && cachedSourceVersion !== "2.0") ||
                Cesium.ModelUtility.getAssetVersion(model.gltf) !== "2.0"
            ) {
                model._gltfForwardAxis = Cesium.Axis.X;
            }
        };

        Cesium.ModelUtility.modifyFragmentShaderForLogDepth = function (shader) {
            let state = false;
            if (Cesium.TILE_EFFECT_STATE && this._model && this._model._resource._url.indexOf('b3dm') !== -1) state = true;
            shader = Cesium.ShaderSource.replaceMain(shader, "czm_depth_main");

            if (state) {
                shader += `
                varying vec3 v_stcVertex;
                void main(){
                    czm_depth_main();
                    `+ Cesium.TILE_FS_BODY + `
                    czm_writeLogDepth();
                }
                `;
            } else {
                shader += `
                    varying vec3 v_stcVertex;
                    void main(){
                        czm_depth_main();
                        czm_writeLogDepth();
                    }
                    `;
            }
            return shader;
        };

        Cesium.ModelUtility.modifyVertexShaderForLogDepth = function (
            shader,
            toClipCoordinatesGLSL
        ) {
            shader = Cesium.ShaderSource.replaceMain(shader, "czm_depth_main");
            shader +=
                "\n" +
                "varying vec3 v_stcVertex;\n" +
                "void main() \n" +
                "{ \n" +
                "    czm_depth_main(); \n" +
                "    v_stcVertex = a_position;\n" +
                "    czm_vertexLogDepth(" +
                toClipCoordinatesGLSL +
                "); \n" +
                "} \n";
            return shader;
        };
    }
    install();
    
})(Cesium)

 materialLine.js

function PolylineTrailLinkMaterialProperty(color, duration) {
  this._definitionChanged = new Cesium.Event();
  this._color = undefined;
  this._colorSubscription = undefined;
  this.color = color;
  this.duration = duration || 3000;
  this._time = (new Date()).getTime();
  this.isTranslucent = function () {
      return true;
  }
}
//1.69版本使用这个,感谢LEARNER GEX
// Object.defineProperties(PolylineTrailLinkMaterialProperty.prototype, {
Cesium.defineProperties(PolylineTrailLinkMaterialProperty.prototype, {
  isConstant: {
      get: function () {
          return false;
      }
  },
  definitionChanged: {
      get: function () {
          return this._definitionChanged;
      }
  },
  color: Cesium.createPropertyDescriptor('color')
});
PolylineTrailLinkMaterialProperty.prototype.getType = function (time) {
  return 'PolylineTrailLink';
}
PolylineTrailLinkMaterialProperty.prototype.getValue = function (time, result) {
  if (!Cesium.defined(result)) {
      result = {};
  }
  result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
  result.image = Cesium.Material.PolylineTrailLinkImage;
  result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
  return result;
}
PolylineTrailLinkMaterialProperty.prototype.equals = function (other) {
  return this === other ||
      (other instanceof PolylineTrailLinkMaterialProperty &&
          Cesium.Property.equals(this._color, other._color))
}
Cesium.PolylineTrailLinkMaterialProperty = PolylineTrailLinkMaterialProperty;
Cesium.Material.PolylineTrailLinkType = 'PolylineTrailLink';
Cesium.Material.PolylineTrailLinkImage = "./Cesium1.64/style/img/line3.png";
Cesium.Material.PolylineTrailLinkSource = "czm_material czm_getMaterial(czm_materialInput materialInput)\n\
                                              {\n\
                                                  czm_material material = czm_getDefaultMaterial(materialInput);\n\
                                                  vec2 st = materialInput.st;\n\
                                                  vec4 colorImage = texture2D(image, vec2(fract(st.s - time), st.t));\n\
                                                  material.alpha = colorImage.a * color.a;\n\
                                                  material.diffuse = (colorImage.rgb+color.rgb)/2.0;\n\
                                                  return material;\n\
                                              }";
Cesium.Material._materialCache.addMaterial(Cesium.Material.PolylineTrailLinkType, {
  fabric: {
      type: Cesium.Material.PolylineTrailLinkType,
      uniforms: {
          color: new Cesium.Color(0.0, 0.0, 1.0, 0.5),
          image: Cesium.Material.PolylineTrailLinkImage,
          time: 20
      },
      source: Cesium.Material.PolylineTrailLinkSource
  },
  translucent: function (material) {
      return true;
  }
})

这里是有一张透明图片的-------------------

 这中间是有一张透明图片的-------------------

在index.html内引入,文件目录如下

 至此效果应该就可以看到了

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值