/**
|
* 海洋环境可视化工具类代码
|
*
|
* 金磊
|
*/
|
importScripts("pako_inflate.min.js");
|
|
function request(options) {
|
var oReq = new XMLHttpRequest();
|
oReq.open("GET", options.url, true);
|
oReq.responseType = options.type;
|
oReq.onload = function (result) {
|
if (result) {
|
var _data = null;
|
if (oReq.responseType == "text" || oReq.responseType == "") {
|
_data = result.target.responseText;
|
} else {
|
_data = result.target.response;
|
}
|
if (result.target.status == 200) {
|
if (typeof options.success == "function")
|
options.success(_data);
|
} else {
|
if (typeof options.error == "function") options.error(_data);
|
}
|
}
|
};
|
oReq.send(null);
|
oReq.onloadend = function () {
|
oReq = null;
|
};
|
}
|
function getCacheInfo(options, callback) {
|
var id = options.id;
|
var fullUrl = "";
|
fullUrl =
|
serviceUrl +
|
"?ncpath=" +
|
options.ncpath +
|
"&type=" +
|
options.variable +
|
"&depth=" +
|
options.depth;
|
request({
|
url: fullUrl,
|
type: "text",
|
success: function (data) {
|
var json = JSON.parse(data);
|
if (json.path) {
|
var cachePath = cacheUrl + json.path;
|
getData(
|
{
|
id: id,
|
url: cachePath,
|
},
|
callback
|
);
|
}
|
},
|
error: function () {},
|
});
|
}
|
function getData(options, callback) {
|
var id = options.id;
|
request({
|
url: options.url,
|
type: "arraybuffer",
|
success: function (arrayBuffer) {
|
if (typeof callback == "function") {
|
var binData = new Uint8Array(arrayBuffer);
|
var data = pako.inflate(binData);
|
var byteArray = new Float32Array(data.buffer);
|
callback(id, byteArray);
|
}
|
},
|
error: function () {},
|
});
|
}
|
function colorInterpolator(start, end) {
|
var r = start[0],
|
g = start[1],
|
b = start[2];
|
var Δr = end[0] - r,
|
Δg = end[1] - g,
|
Δb = end[2] - b;
|
return function (i, a) {
|
return [
|
Math.floor(r + i * Δr),
|
Math.floor(g + i * Δg),
|
Math.floor(b + i * Δb),
|
a,
|
];
|
};
|
}
|
|
/**
|
* Creates a color scale composed of the specified segments. Segments is an array of two-element arrays of the
|
* form [value, color], where value is the point along the scale and color is the [r, g, b] color at that point.
|
* For example, the following creates a scale that smoothly transitions from red to green to blue along the
|
* points 0.5, 1.0, and 3.5:
|
*
|
* [ [ 0.5, [255, 0, 0] ],
|
* [ 1.0, [0, 255, 0] ],
|
* [ 3.5, [0, 0, 255] ] ]
|
*
|
* @param segments array of color segments
|
* @returns {Function} a function(point, alpha) that returns the color [r, g, b, alpha] for the given point.
|
*/
|
function segmentedColorScale(segments) {
|
var points = [],
|
interpolators = [],
|
ranges = [];
|
for (var i = 0; i < segments.length - 1; i++) {
|
points.push(segments[i + 1][0]);
|
interpolators.push(
|
colorInterpolator(segments[i][1], segments[i + 1][1])
|
);
|
ranges.push([segments[i][0], segments[i + 1][0]]);
|
}
|
|
return function (point, alpha) {
|
var i;
|
for (i = 0; i < points.length - 1; i++) {
|
if (point <= points[i]) {
|
break;
|
}
|
}
|
var range = ranges[i];
|
return interpolators[i](proportion(point, range[0], range[1]), alpha);
|
};
|
}
|
|
/**
|
* @returns {Number} the value x clamped to the range [low, high].
|
*/
|
function clamp(x, low, high) {
|
return Math.max(low, Math.min(x, high));
|
}
|
|
/**
|
* @returns {number} the fraction of the bounds [low, high] covered by the value x, after clamping x to the
|
* bounds. For example, given bounds=[10, 20], this method returns 1 for x>=20, 0.5 for x=15 and 0
|
* for x<=10.
|
*/
|
function proportion(x, low, high) {
|
return (clamp(x, low, high) - low) / (high - low);
|
}
|
/**
|
*
|
* 双线性插值算法
|
*
|
*/
|
function bilinearInterpolate(x, y, g00, g10, g01, g11) {
|
var rx = 1 - x;
|
var ry = 1 - y;
|
var a = rx * ry,
|
b = x * ry,
|
c = rx * y,
|
d = x * y;
|
var u = g00 * a + g10 * b + g01 * c + g11 * d;
|
return u;
|
}
|
function bilinearInterpolateVector(x, y, g00, g10, g01, g11) {
|
var rx = 1 - x;
|
var ry = 1 - y;
|
var a = rx * ry,
|
b = x * ry,
|
c = rx * y,
|
d = x * y;
|
var u = g00[0] * a + g10[0] * b + g01[0] * c + g11[0] * d;
|
var v = g00[1] * a + g10[1] * b + g01[1] * c + g11[1] * d;
|
return [u, v, Math.sqrt(u * u + v * v)];
|
}
|