cesium-examples/VisualTool/Apps/Libs/wind/Windy.js

157 lines
5.5 KiB
JavaScript
Raw Normal View History

//define([ 'windy/Particle', 'windy/WindField'], function ( Particle, WindField) {
var _primitives = null;
var SPEED_RATE = 0.15;
var PARTICLES_NUMBER =2000;//默认2000
var MAX_AGE = 10;
var BRIGHTEN = 1.5;
var Windy = function (json, cesiumViewer) {
this.windData = json;
this.windField = null;
this.particles = [];
this.lines = null;
_primitives = cesiumViewer.scene.primitives;
this._init();
};
Windy.prototype = {
constructor: Windy,
_init: function () {
// 创建风场网格
this.windField = this.createField();
// 创建风场粒子
for (var i = 0; i < PARTICLES_NUMBER; i++) {
this.particles.push(this.randomParticle(new Particle()));
}
},
createField: function () {
var data = this._parseWindJson();
return new WindField(data);
},
animate: function () {
var self = this,
field = self.windField,
particles = self.particles;
var instances = [],
nextX = null,
nextY = null,
xy = null,
uv = null;
particles.forEach(function (particle) {
if (particle.age <= 0) {
self.randomParticle(particle);
}
if (particle.age > 0) {
var x = particle.x,
y = particle.y;
if (!field.isInBound(x, y)) {
particle.age = 0;
} else {
uv = field.getIn(x, y);
nextX = x + SPEED_RATE * uv[0];
nextY = y + SPEED_RATE * uv[1];
particle.path.push(nextX, nextY);
particle.x = nextX;
particle.y = nextY;
instances.push(self._createLineInstance(self._map(particle.path), particle.age / particle.birthAge));
particle.age--;
}
}
});
if (instances.length <= 0) this.removeLines();
self._drawLines(instances);
},
_parseWindJson: function () {
var uComponent = null,
vComponent = null,
header = null;
this.windData.forEach(function (record) {
var type = record.header.parameterCategory + "," + record.header.parameterNumber;
switch (type) {
case "2,2":
uComponent = record['data'];
header = record['header'];
break;
case "2,3":
vComponent = record['data'];
break;
default:
break;
}
});
return {
header: header,
uComponent: uComponent,
vComponent: vComponent
};
},
removeLines: function () {
if (this.lines) {
_primitives.remove(this.lines);
this.lines.destroy();
}
},
//求路径上点
_map: function (arr) {
var length = arr.length,
field = this.windField,
dx = field.dx,
dy = field.dy,
west = field.west,
south = field.north,
newArr = [];
for (var i = 0; i <= length - 2; i += 2) {
newArr.push(
west + arr[i] * dx,
south - arr[i + 1] * dy
)
}
return newArr;
},
_createLineInstance: function (positions, ageRate) {
var colors = [],
length = positions.length,
count = length / 2;
for (var i = 0; i < length; i++) {
colors.push(Cesium.Color.WHITE.withAlpha(i / count * ageRate * BRIGHTEN));
}
return new Cesium.GeometryInstance({
geometry: new Cesium.PolylineGeometry({
positions: Cesium.Cartesian3.fromDegreesArray(positions),
colors: colors,
width: 1.5,
colorsPerVertex: true
})
});
},
_drawLines: function (lineInstances) {
this.removeLines();
var linePrimitive = new Cesium.Primitive({
appearance: new Cesium.PolylineColorAppearance({
translucent: true
}),
geometryInstances: lineInstances,
asynchronous: false
});
this.lines = _primitives.add(linePrimitive);
},
randomParticle: function (particle) {
var safe = 30,x, y;
do {
x = Math.floor(Math.random() * (this.windField.cols - 2));
y = Math.floor(Math.random() * (this.windField.rows - 2));
} while (this.windField.getIn(x, y)[2] <= 0 && safe++ < 30);
particle.x = x;
particle.y = y;
particle.age = Math.round(Math.random() * MAX_AGE);//每一次生成都不一样
particle.birthAge = particle.age;
particle.path = [x, y];
return particle;
}
};
//return Windy;
//})