importScripts("config.js");
|
importScripts("transform.js");
|
importScripts("omcommand.js");
|
|
var uvInfo = {
|
rCount: 0,
|
uData: null,
|
vData: null,
|
oData: null,
|
offset: 0,
|
minx: 0.0,
|
miny: 0.0,
|
dx: 0.0,
|
dy: 0.0,
|
width: 0.0,
|
height: 0.0,
|
uMax: 0.0,
|
uMin: 0.0,
|
vMax: 0.0,
|
vMin: 0.0,
|
valMax: 0.0,
|
valMin: 0.0,
|
drawData: [],
|
};
|
|
var myScene = null;
|
var columns = []; //数据存储数组。每次刷新更新这个数组
|
|
var τ = 2 * Math.PI; //他不是一个π。。是两个。。
|
var VSCALE = 0.00036666666666666667; //速度
|
|
var H = 0.000036; // 0.0000360°φ ~= 4m 随便给的值,为了平面数据到球面产生的偏移计算
|
|
var HOLE_VECTOR = [NaN, NaN, null]; // 向量不存在时存储的值
|
var velocityScale = 0;
|
var oceanCancel = false; //是否取消加载
|
|
/**
|
* 海洋流场图线程
|
* 金磊
|
* @param {any} start
|
* @param {any} end
|
*/
|
self.addEventListener("message", function (e) {
|
var option = e.data;
|
|
if (e.data.colorEqually != undefined) {
|
colorEqually = e.data.colorEqually;
|
}
|
myScene = option.scene;
|
if (myScene && myScene.height) {
|
velocityScale = myScene.height * VSCALE;
|
}
|
clear();
|
switch (option.type) {
|
case "init":
|
initData(option);
|
break;
|
case "update":
|
if (uvInfo.uData != null && uvInfo.vData != null) {
|
dataProcess();
|
}
|
break;
|
case "stop":
|
break;
|
default:
|
break;
|
}
|
});
|
function clear() {
|
oceanCancel = true;
|
}
|
function initData(option) {
|
uvInfo.uData = null;
|
uvInfo.vData = null;
|
getData(
|
{
|
id: "u",
|
url: option.upath,
|
},
|
function (id, byteArray) {
|
uvInfo.uData = byteArray;
|
if (uvInfo.vData != null) {
|
oceanLineCalc();
|
}
|
}
|
);
|
getData(
|
{
|
id: "v",
|
url: option.vpath,
|
},
|
function (id, byteArray) {
|
uvInfo.vData = byteArray;
|
if (uvInfo.uData != null) {
|
oceanLineCalc();
|
}
|
}
|
);
|
// getCacheInfo(
|
// {
|
// id: "u",
|
// ncpath: option.uncpath,
|
// variable: option.uvariable,
|
// depth: option.depth,
|
// },
|
// function (id, byteArray) {
|
// uvInfo.uData = byteArray;
|
// if (uvInfo.vData != null) {
|
// oceanLineCalc();
|
// }
|
// }
|
// );
|
// getCacheInfo(
|
// {
|
// id: "v",
|
// ncpath: option.vncpath,
|
// variable: option.vvariable,
|
// depth: option.depth,
|
// },
|
// function (id, byteArray) {
|
// uvInfo.vData = byteArray;
|
// if (uvInfo.uData != null) {
|
// oceanLineCalc();
|
// }
|
// }
|
// );
|
}
|
function distort(λ, φ, x, y, wind) {
|
var u = wind[0] * velocityScale;
|
var v = wind[1] * velocityScale;
|
|
var hλ = λ < 0 ? H : -H;
|
var hφ = φ < 0 ? H : -H;
|
var pλ = projection([λ + hλ, φ]);
|
var pφ = projection([λ, φ + hφ]);
|
var k = Math.cos((φ / 360) * τ);
|
|
var d = [
|
(pλ.x - x) / hλ / k,
|
(pλ.y - y) / hλ / k,
|
(pφ.x - x) / hφ,
|
(pφ.y - y) / hφ,
|
];
|
|
// Scale distortion vectors by u and v, then add.
|
wind[0] = d[0] * u + d[2] * v;
|
wind[1] = d[1] * u + d[3] * v;
|
return wind;
|
}
|
function getDataByIndex(i, j) {
|
var index = i * uvInfo.width + j + uvInfo.offset;
|
if (index > uvInfo.uData.length) return [undefined, undefined];
|
return [uvInfo.uData[index], uvInfo.vData[index]];
|
}
|
function floorMod(a, n) {
|
var f = a - n * Math.floor(a / n);
|
return f === n ? 0 : f;
|
}
|
function isValue(x) {
|
if (
|
x[0] != undefined &&
|
x[1] != undefined &&
|
x[0] != -9999 &&
|
x[1] != -9999
|
) {
|
return true;
|
}
|
return false;
|
}
|
function getDegreesData(x, y) {
|
var i = floorMod(x - uvInfo.minx, 360) / uvInfo.dx;
|
var j = (y - uvInfo.miny) / uvInfo.dy;
|
|
// 1 2
|
// fi i ci
|
// | =1.4 |
|
// ---G--|---G--- fj 8
|
// j ___|_ . |
|
// =8.3 | |
|
// ---G------G--- cj 9
|
// | |
|
if (i > uvInfo.width || j > uvInfo.height || j < 0 || i < 0) return null;
|
var fi = Math.floor(i),
|
ci = fi + 1;
|
var fj = Math.floor(j),
|
cj = fj + 1;
|
var g00 = getDataByIndex(cj, fi);
|
var g10 = getDataByIndex(cj, ci);
|
var g01 = getDataByIndex(fj, fi);
|
var g11 = getDataByIndex(fj, ci);
|
if (isValue(g00) && isValue(g10) && isValue(g01) && isValue(g11)) {
|
return bilinearInterpolateVector(i - fi, cj - j, g00, g10, g01, g11);
|
}
|
return null;
|
}
|
|
//获取数据信息,这里以u数据为准。正常数据u、v数据信息应该是相同的。
|
function getDataInfo() {
|
var offset = 0;
|
var direction = uvInfo.uData[offset];
|
offset += 1;
|
var width = uvInfo.uData[offset];
|
offset += 1;
|
var minx = 999;
|
var maxx = -999;
|
for (var i = 0; i < width; i++) {
|
if (minx > uvInfo.uData[offset + i]) {
|
minx = uvInfo.uData[offset + i];
|
}
|
if (maxx < uvInfo.uData[offset + i]) {
|
maxx = uvInfo.uData[offset + i];
|
}
|
}
|
offset += width;
|
uvInfo.dx = (maxx - minx) / (width - 1);
|
uvInfo.minx = minx;
|
uvInfo.width = width;
|
|
var height = uvInfo.uData[offset];
|
offset += 1;
|
var miny = 999;
|
var maxy = -999;
|
for (var i = 0; i < height; i++) {
|
if (miny > uvInfo.uData[offset + i]) {
|
miny = uvInfo.uData[offset + i];
|
}
|
if (maxy < uvInfo.uData[offset + i]) {
|
maxy = uvInfo.uData[offset + i];
|
}
|
}
|
offset += height;
|
|
uvInfo.dy = (maxy - miny) / (height - 1);
|
uvInfo.miny = miny;
|
uvInfo.height = height;
|
|
var dataCount = uvInfo.uData[offset];
|
offset += 1;
|
uvInfo.offset = offset;
|
|
var uMax = uvInfo.uData[uvInfo.uData.length - 1];
|
var uMin = uvInfo.uData[uvInfo.uData.length - 2];
|
var vMax = uvInfo.vData[uvInfo.vData.length - 1];
|
var vMin = uvInfo.vData[uvInfo.vData.length - 2];
|
|
uvInfo.uMax = Math.max(Math.abs(uMax), Math.abs(uMin));
|
uvInfo.uMin = 0;
|
uvInfo.vMax = Math.max(Math.abs(vMax), Math.abs(vMin));
|
uvInfo.vMin = 0;
|
//console.time("111");
|
var valMax = -999;
|
var valMin = 999;
|
for (var i = offset; i < uvInfo.uData.length - 3; i++) {
|
var uVal = uvInfo.uData[i];
|
var vVal = uvInfo.vData[i];
|
if (uVal != -9999 && vVal != -9999) {
|
var val = Math.sqrt(uVal * uVal + vVal * vVal);
|
if (valMax < val) valMax = val;
|
if (valMin > val) valMin = val;
|
}
|
}
|
uvInfo.valMax = valMax;
|
uvInfo.valMin = valMin;
|
//console.timeEnd("111");
|
}
|
function dataProcess() {
|
if (myScene) {
|
for (var i = 0; i < myScene.width; i += 2) {
|
var column = [];
|
for (var j = 0; j < myScene.height; j += 2) {
|
var coord = tempgetCoord(i, j);
|
if (coord != null) {
|
var wind = null;
|
if (coord) {
|
var λ = coord[0],
|
φ = coord[1];
|
if (isFinite(λ)) {
|
wind = getDegreesData(λ, φ);
|
if (wind) {
|
wind = distort(λ, φ, i, j, wind);
|
}
|
}
|
}
|
column[j + 1] = column[j] = wind || HOLE_VECTOR;
|
}
|
}
|
columns[i + 1] = columns[i] = column;
|
}
|
//animate();
|
uvInfo.drawData = columns;
|
self.postMessage({
|
type: "draw",
|
data: uvInfo,
|
});
|
}
|
}
|
function colorStyles(val) {
|
var i;
|
for (i = 0; i < colorInfo.length; i++) {
|
if (Math.abs(val) <= colorInfo[i][0]) {
|
break;
|
}
|
}
|
var color = colorInfo[i][1];
|
return (
|
"rgba(" +
|
color[0] +
|
", " +
|
color[1] +
|
", " +
|
color[2] +
|
", " +
|
RD_OVERLAY_ALPHA +
|
")"
|
);
|
}
|
|
function oceanLineCalc() {
|
if (uvInfo.uData == null || uvInfo.vData == null) {
|
return;
|
}
|
getDataInfo();
|
dataProcess();
|
}
|