|
@@ -0,0 +1,164 @@
|
|
|
+
|
|
|
+var Cesium = require("cesium/Cesium");
|
|
|
+import WindField from "./WindField";
|
|
|
+import Particle from "./Particle";
|
|
|
+//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;
|
|
|
+ //})
|
|
|
+
|
|
|
+
|
|
|
+ export default Windy
|