# cesium-动态扩散点效果

# 介绍

有些时候我们需要标记一些重要的点和事件,比如某地发生了地震,我们需要实时在cesium中高亮显示,实时消息可以使用websocket从后台推送到前台(这里暂时就不展开说了)

# 实现效果

效果如下:

image-20220214173039232

# 完整代码

这里使用vue实现

<template>
  <div class="home">
    <el-row type="flex" :gutter="20">
      <el-col :span="24">
        <div class="grid-content bg-purple">
          <el-breadcrumb separator="/">
            <el-breadcrumb-item>cesium</el-breadcrumb-item>
            <el-breadcrumb-item>效果</el-breadcrumb-item>
            <el-breadcrumb-item>动态扩散点</el-breadcrumb-item>
          </el-breadcrumb>
        </div>
      </el-col>
    </el-row>
    <el-row type="flex" :gutter="20">
      <el-col :span="24">
        <div class="grid-content bg-purple">
          <cesiumComponent id="cesium" ref="refCesium"/>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import cesiumComponent from '../cesium.vue'

export default {
  name: "dynamic_diffusion_point",
  data() {
    return {
      _viewer: undefined,
      _camera: undefined,
    };
  },
  components: {
    cesiumComponent
  },
  mounted() {
    this.init();
    this.addPoint();
  },
  methods: {
    init() {
      let that = this;
      that.$refs.refCesium.initMap();
      that._viewer = that.$refs.refCesium._viewer;
      that._camera = that._viewer.camera;
      that._viewer.scene.globe.depthTestAgainstTerrain = true;
    },
    addPoint() {
      let that = this;
      let viewer = that._viewer;
      //关闭深度检测
      viewer.scene.globe.depthTestAgainstTerrain = true;
      //取消双击事件
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
      //设置homebutton的位置
      Cesium.Camera.DEFAULT_VIEW_RECTANGLE =
          Cesium.Rectangle.fromDegrees(110.15, 34.54, 110.25, 34.56);//Rectangle(west, south, east, north)
      //设置初始位置
      viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(110.20, 34.55, 3000000)
      });

      /*
      流动纹理线
      color 颜色
      duration 持续时间 毫秒
      */
      function EllipsoidFadeMaterialProperty(color, duration) {
        this._definitionChanged = new Cesium.Event();
        this._color = undefined;
        this._colorSubscription = undefined;
        this.color = color;
        this.duration = duration;
        this._time = (new Date()).getTime();
      }

      Object.defineProperties(EllipsoidFadeMaterialProperty.prototype, {
        isConstant: {
          get: function () {
            return false;
          }
        },
        definitionChanged: {
          get: function () {
            return this._definitionChanged;
          }
        },
        color: Cesium.createPropertyDescriptor('color')
      });
      EllipsoidFadeMaterialProperty.prototype.getType = function (time) {
        return 'EllipsoidFade';
      }
      EllipsoidFadeMaterialProperty.prototype.getValue = function (time, result) {
        if (!Cesium.defined(result)) {
          result = {};
        }
        result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);

        result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
        return result;

        // return Cesium.defined(result) || (result = {}),
        //     result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color),
        //     void 0 === this._time && (this._time = time.secondsOfDay),
        //     result.time = time.secondsOfDay - this._time,
        //     result
      }
      EllipsoidFadeMaterialProperty.prototype.equals = function (other) {
        return this === other ||
            (other instanceof EllipsoidFadeMaterialProperty &&
                Property.equals(this._color, other._color))
      }
      Cesium.EllipsoidFadeMaterialProperty = EllipsoidFadeMaterialProperty;
      Cesium.Material.EllipsoidFadeType = 'EllipsoidFade';
      Cesium.Material.EllipsoidFadeSource =
          "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
          "{\n" +
          "czm_material material = czm_getDefaultMaterial(materialInput);\n" +
          "material.diffuse = 1.5 * color.rgb;\n" +
          "vec2 st = materialInput.st;\n" +
          "float dis = distance(st, vec2(0.5, 0.5));\n" +
          "float per = fract(time);\n" +
          "if(dis > per * 0.5){\n" +
          "material.alpha = 0.0;\n" +
          "discard;\n" +
          "}else {\n" +
          "material.alpha = color.a  * dis / per / 1.0;\n" +
          "}\n" +
          "return material;\n" +
          "}";
      Cesium.Material._materialCache.addMaterial(Cesium.Material.EllipsoidFadeType, {
        fabric: {
          type: Cesium.Material.EllipsoidFadeType,
          uniforms: {
            color: new Cesium.Color(1.0, 0.0, 0.0, 1),
            time: 0
          },
          source: Cesium.Material.EllipsoidFadeSource
        },
        translucent: function (material) {
          return true;
        }
      });

      viewer.entities.add({
        name: 'EllipsoidFade',
        position: Cesium.Cartesian3.fromDegrees(104.0, 30.0, 100.0),
        ellipse: {
          height: 0,
          semiMinorAxis: 3000.0,
          semiMajorAxis: 3000.0,
          material: new Cesium.EllipsoidFadeMaterialProperty(Cesium.Color.ORANGE, 2000)
        },
        point:{
          show: true,
          pixelSize: 30,
          // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          color: Cesium.Color.RED,
          outlineColor: Cesium.Color.YELLOW,
          outlineWidth: 10,
          scaleByDistance: new Cesium.NearFarScalar(1500, 1, 20000, 0.3),
          translucencyByDistance: new Cesium.NearFarScalar(1500, 1, 20000, 0.2),
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 20000)
        }
      });


      viewer.zoomTo(viewer.entities);
    }
  },
  created() {

  },
}
</script>

<style scoped>
.home {
  height: 100%;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  overflow-x: hidden;
}

.el-breadcrumb {
  margin: 10px;
  font-size: 15px;
}

#cesium {
  max-height: 700px;
}
</style>
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196

# 核心代码

addPoint() {
      let that = this;
      let viewer = that._viewer;
      //关闭深度检测
      viewer.scene.globe.depthTestAgainstTerrain = true;
      //取消双击事件
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
      //设置homebutton的位置
      Cesium.Camera.DEFAULT_VIEW_RECTANGLE =
          Cesium.Rectangle.fromDegrees(110.15, 34.54, 110.25, 34.56);//Rectangle(west, south, east, north)
      //设置初始位置
      viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(110.20, 34.55, 3000000)
      });

      /*
      流动纹理线
      color 颜色
      duration 持续时间 毫秒
      */
      function EllipsoidFadeMaterialProperty(color, duration) {
        this._definitionChanged = new Cesium.Event();
        this._color = undefined;
        this._colorSubscription = undefined;
        this.color = color;
        this.duration = duration;
        this._time = (new Date()).getTime();
      }

      Object.defineProperties(EllipsoidFadeMaterialProperty.prototype, {
        isConstant: {
          get: function () {
            return false;
          }
        },
        definitionChanged: {
          get: function () {
            return this._definitionChanged;
          }
        },
        color: Cesium.createPropertyDescriptor('color')
      });
      EllipsoidFadeMaterialProperty.prototype.getType = function (time) {
        return 'EllipsoidFade';
      }
      EllipsoidFadeMaterialProperty.prototype.getValue = function (time, result) {
        if (!Cesium.defined(result)) {
          result = {};
        }
        result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);

        result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
        return result;

        // return Cesium.defined(result) || (result = {}),
        //     result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color),
        //     void 0 === this._time && (this._time = time.secondsOfDay),
        //     result.time = time.secondsOfDay - this._time,
        //     result
      }
      EllipsoidFadeMaterialProperty.prototype.equals = function (other) {
        return this === other ||
            (other instanceof EllipsoidFadeMaterialProperty &&
                Property.equals(this._color, other._color))
      }
      Cesium.EllipsoidFadeMaterialProperty = EllipsoidFadeMaterialProperty;
      Cesium.Material.EllipsoidFadeType = 'EllipsoidFade';
      Cesium.Material.EllipsoidFadeSource =
          "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
          "{\n" +
          "czm_material material = czm_getDefaultMaterial(materialInput);\n" +
          "material.diffuse = 1.5 * color.rgb;\n" +
          "vec2 st = materialInput.st;\n" +
          "float dis = distance(st, vec2(0.5, 0.5));\n" +
          "float per = fract(time);\n" +
          "if(dis > per * 0.5){\n" +
          "material.alpha = 0.0;\n" +
          "discard;\n" +
          "}else {\n" +
          "material.alpha = color.a  * dis / per / 1.0;\n" +
          "}\n" +
          "return material;\n" +
          "}";
      Cesium.Material._materialCache.addMaterial(Cesium.Material.EllipsoidFadeType, {
        fabric: {
          type: Cesium.Material.EllipsoidFadeType,
          uniforms: {
            color: new Cesium.Color(1.0, 0.0, 0.0, 1),
            time: 0
          },
          source: Cesium.Material.EllipsoidFadeSource
        },
        translucent: function (material) {
          return true;
        }
      });

      viewer.entities.add({
        name: 'EllipsoidFade',
        position: Cesium.Cartesian3.fromDegrees(104.0, 30.0, 100.0),
        ellipse: {
          height: 0,
          semiMinorAxis: 3000.0,
          semiMajorAxis: 3000.0,
          material: new Cesium.EllipsoidFadeMaterialProperty(Cesium.Color.ORANGE, 2000)
        },
        point:{
          show: true,
          pixelSize: 30,
          // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          color: Cesium.Color.RED,
          outlineColor: Cesium.Color.YELLOW,
          outlineWidth: 10,
          scaleByDistance: new Cesium.NearFarScalar(1500, 1, 20000, 0.3),
          translucencyByDistance: new Cesium.NearFarScalar(1500, 1, 20000, 0.2),
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 20000)
        }
      });

      viewer.zoomTo(viewer.entities);
    }
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

# 在线示例

DEMO (opens new window)

上次更新时间: 2022年5月20日星期五上午11点16分