基于北京SDK的方案预演功能
surprise
2024-04-24 2891e19c690853fa6542502bcd230b6130e95810
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
/**
 *   海洋环境可视化工具类代码
 *
 *          金磊
 */
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)];
}