let pixel = 1500;
|
function WaterMesh() {
|
this.meshPoint = [];
|
this.pixelPoint = [];
|
this.meshIndex = [];
|
this.time = [];
|
this.meshValue = {};
|
|
this.canvas = null;
|
this.ctx = null;
|
this.canvasInfo = {};
|
|
this.meshIndexLoad = false;
|
this.meshPointLoad = false;
|
this.meshValueLoad = false;
|
this.extent = {
|
minx: Number.MAX_VALUE,
|
maxx: Number.MIN_VALUE,
|
miny: Number.MAX_VALUE,
|
maxy: Number.MIN_VALUE,
|
width: 0,
|
height: 0,
|
};
|
this.loadData();
|
this.getExtent();
|
|
this.pointsToPixels();
|
this.createCanvas();
|
|
this.drawDepthTexture();
|
|
|
console.log(this.extent);
|
}
|
WaterMesh.prototype.pointsToPixels = function() {
|
for (let i = 0; i < this.meshPoint.length; i += 4) {
|
let x = this.meshPoint[i + 1];
|
let y = this.meshPoint[i + 2];
|
let _pixel = this.pointToPixel({ x, y });
|
|
this.pixelPoint.push(_pixel.x);
|
this.pixelPoint.push(_pixel.y);
|
}
|
}
|
|
WaterMesh.prototype.createGeometry = function(rect) {
|
|
let geometry = new Cesium.Geometry({
|
attributes: {
|
position: new Cesium.GeometryAttribute({
|
componentDatatype: Cesium.ComponentDatatype.DOUBLE,
|
componentsPerAttribute: 3,
|
values: rect.positions,
|
}),
|
st: new Cesium.GeometryAttribute({
|
componentDatatype: Cesium.ComponentDatatype.FLOAT,
|
componentsPerAttribute: 2,
|
values: rect.st,
|
}),
|
},
|
//索引
|
indices: rect.indexs,
|
//绘制类型
|
primitiveType: Cesium.PrimitiveType.TRIANGLES,
|
boundingSphere: Cesium.BoundingSphere.fromVertices(rect.positions),
|
});
|
return geometry;
|
}
|
|
WaterMesh.prototype.calcST = function(pos) {
|
let x = 0;
|
let y = 0;
|
x = (pos.x - this.extent.minx) / this.extent.width;
|
y = (pos.y - this.extent.miny) / this.extent.height;
|
return { x, y };
|
}
|
WaterMesh.prototype.createTerraMesh = function() {
|
let positions = [];
|
let st = [];
|
let indexs = [];
|
//0,1,2,3,
|
//1,4,5,2,
|
for (let i = 0; i < this.meshIndex.length; i += 4) {
|
indexs.push(
|
this.meshIndex[i],
|
this.meshIndex[i + 1],
|
|
this.meshIndex[i + 2],
|
);
|
indexs.push(
|
this.meshIndex[i + 3],
|
this.meshIndex[i],
|
|
this.meshIndex[i + 2],
|
);
|
}
|
for (let i = 0; i < this.meshPoint.length; i += 4) {
|
let x = this.meshPoint[i + 1];
|
let y = this.meshPoint[i + 2];
|
let z = this.meshPoint[i + 3];
|
let point = Cesium.Cartesian3.fromDegrees(x, y, (z * 10));
|
let uv = this.calcST({ x, y });
|
|
positions.push(point.x, point.y, point.z);
|
|
st.push(uv.x, uv.y);
|
|
}
|
return {
|
positions,
|
st,
|
indexs,
|
};
|
}
|
|
WaterMesh.prototype.createWaterMesh = function(offsetZ) {
|
let positions = [];
|
let st = [];
|
let indexs = [];
|
let _time = this.time[0];
|
//0,1,2,3,
|
//1,4,5,2,
|
for (let i = 0; i < this.meshPoint.length; i += 4) {
|
let x = this.meshPoint[i + 1];
|
let y = this.meshPoint[i + 2];
|
let z = this.meshPoint[i + 3];
|
let point = Cesium.Cartesian3.fromDegrees(x, y, ((z + offsetZ) * 10));
|
let uv = this.calcST({ x, y });
|
|
positions.push(point.x, point.y, point.z);
|
|
st.push(uv.x, uv.y);
|
|
}
|
for (let i = 0; i < this.meshValue[_time].length; i += 5) {
|
|
let index = this.meshValue[_time][i];
|
let depth = this.meshValue[_time][i + 1];
|
|
index = index * 4;
|
|
for (let j = 0; j < 4; j++) {
|
let pIndex = this.meshIndex[index + j];
|
|
let x = this.meshPoint[pIndex * 4 + 1];
|
let y = this.meshPoint[pIndex * 4 + 2];
|
let z = (depth + offsetZ) * 10;
|
let point = Cesium.Cartesian3.fromDegrees(x, y, z);
|
positions[pIndex * 3 + 2] = point.z;
|
}
|
|
|
|
indexs.push(
|
this.meshIndex[index],
|
this.meshIndex[index + 1],
|
this.meshIndex[index + 2],
|
);
|
indexs.push(
|
this.meshIndex[index + 3],
|
this.meshIndex[index],
|
this.meshIndex[index + 2],
|
);
|
|
}
|
|
|
return {
|
positions,
|
st,
|
indexs,
|
};
|
}
|
|
WaterMesh.prototype.pointToPixel = function(point) {
|
let x = 0;
|
let y = 0;
|
x = Math.round(this.canvasInfo.width * (point.x - this.extent.minx) / this.extent.width);
|
y = Math.round(this.canvasInfo.height * (point.y - this.extent.miny) / this.extent.height);
|
y = this.canvasInfo.height - y;
|
return { x, y }
|
}
|
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];
|
};
|
};
|
/**
|
* @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 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);
|
};
|
};
|
var RD_OVERLAY_ALPHA = Math.floor(0.8 * 255); // 默认覆盖透明度 ([0, 255])
|
var colorTable = [
|
[0, [10, 25, 68]],
|
[2, [10, 25, 250]],
|
[4, [24, 255, 93]],
|
[6, [255, 233, 102]],
|
[8, [255, 233, 15]],
|
[30, [255, 15, 15]],
|
];
|
function colorRGB2Hex(r, g, b) {
|
|
let hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
|
return hex;
|
}
|
|
WaterMesh.prototype.drawDepthTexture = function() {
|
this.ctx.clearRect(0, 0, this.canvasInfo.width, this.canvasInfo.height);
|
|
var colorgradient = segmentedColorScale(colorTable);
|
|
|
let _time = this.time[0];
|
for (let i = 0; i < this.meshValue[_time].length; i += 5) {
|
|
|
let index = this.meshValue[_time][i];
|
let depth = this.meshValue[_time][i + 2];
|
var rgba = colorgradient(depth, RD_OVERLAY_ALPHA);
|
|
this.ctx.fillStyle = colorRGB2Hex(rgba[0], rgba[1], rgba[2]);
|
|
|
index = index * 4;
|
let index1 = this.meshIndex[index];
|
let index2 = this.meshIndex[index + 1];
|
let index3 = this.meshIndex[index + 2];
|
let index4 = this.meshIndex[index + 3];
|
|
let x1 = this.pixelPoint[index1 * 2];
|
let y1 = this.pixelPoint[index1 * 2 + 1];
|
let x2 = this.pixelPoint[index2 * 2];
|
let y2 = this.pixelPoint[index2 * 2 + 1];
|
let x3 = this.pixelPoint[index3 * 2];
|
let y3 = this.pixelPoint[index3 * 2 + 1];
|
let x4 = this.pixelPoint[index4 * 2];
|
let y4 = this.pixelPoint[index4 * 2 + 1];
|
|
|
// 填充三角形
|
this.ctx.beginPath();
|
this.ctx.moveTo(x1, y1);
|
this.ctx.lineTo(x2, y2);
|
this.ctx.lineTo(x3, y3);
|
this.ctx.lineTo(x4, y4);
|
this.ctx.fill();
|
}
|
}
|
WaterMesh.prototype.drawTexture = function() {
|
this.ctx.clearRect(0, 0, this.canvasInfo.width, this.canvasInfo.height);
|
this.ctx.fillStyle = "black";
|
for (let i = 0; i < this.meshIndex.length; i += 4) {
|
let index1 = this.meshIndex[i];
|
let index2 = this.meshIndex[i + 1];
|
let index3 = this.meshIndex[i + 2];
|
let index4 = this.meshIndex[i + 3];
|
|
let x1 = this.pixelPoint[index1 * 2];
|
let y1 = this.pixelPoint[index1 * 2 + 1];
|
let x2 = this.pixelPoint[index2 * 2];
|
let y2 = this.pixelPoint[index2 * 2 + 1];
|
let x3 = this.pixelPoint[index3 * 2];
|
let y3 = this.pixelPoint[index3 * 2 + 1];
|
let x4 = this.pixelPoint[index4 * 2];
|
let y4 = this.pixelPoint[index4 * 2 + 1];
|
|
|
// 填充三角形
|
this.ctx.beginPath();
|
this.ctx.moveTo(x1, y1);
|
this.ctx.lineTo(x2, y2);
|
this.ctx.lineTo(x3, y3);
|
this.ctx.lineTo(x4, y4);
|
this.ctx.fill();
|
|
}
|
this.ctx.fillStyle = "red";
|
let _time = this.time[0];
|
for (let i = 0; i < this.meshValue[_time].length; i += 5) {
|
|
let index = this.meshValue[_time][i];
|
index = index * 4;
|
let index1 = this.meshIndex[index];
|
let index2 = this.meshIndex[index + 1];
|
let index3 = this.meshIndex[index + 2];
|
let index4 = this.meshIndex[index + 3];
|
|
let x1 = this.pixelPoint[index1 * 2];
|
let y1 = this.pixelPoint[index1 * 2 + 1];
|
let x2 = this.pixelPoint[index2 * 2];
|
let y2 = this.pixelPoint[index2 * 2 + 1];
|
let x3 = this.pixelPoint[index3 * 2];
|
let y3 = this.pixelPoint[index3 * 2 + 1];
|
let x4 = this.pixelPoint[index4 * 2];
|
let y4 = this.pixelPoint[index4 * 2 + 1];
|
|
|
// 填充三角形
|
this.ctx.beginPath();
|
this.ctx.moveTo(x1, y1);
|
this.ctx.lineTo(x2, y2);
|
this.ctx.lineTo(x3, y3);
|
this.ctx.lineTo(x4, y4);
|
this.ctx.fill();
|
}
|
}
|
WaterMesh.prototype.createCanvas = function() {
|
var canvas = document.createElement('canvas');
|
canvas.id = "overlay";
|
canvas.class = "fill-screen";
|
canvas.width = this.canvasInfo.width;
|
canvas.height = this.canvasInfo.height;
|
this.canvas = canvas;
|
this.ctx = this.canvas.getContext("2d");
|
document.body.appendChild(canvas);
|
}
|
WaterMesh.prototype.getExtent = function() {
|
for (let i = 0; i < this.meshPoint.length; i += 4) {
|
let tx = this.meshPoint[i + 1];
|
let ty = this.meshPoint[i + 2];
|
if (tx > this.extent.maxx) {
|
this.extent.maxx = tx;
|
}
|
if (tx < this.extent.minx) {
|
this.extent.minx = tx;
|
}
|
if (ty > this.extent.maxy) {
|
this.extent.maxy = ty;
|
}
|
if (ty < this.extent.miny) {
|
this.extent.miny = ty;
|
}
|
}
|
this.extent.width = this.extent.maxx - this.extent.minx;
|
this.extent.height = this.extent.maxy - this.extent.miny;
|
let ratio = this.extent.height / this.extent.width;
|
this.canvasInfo = {
|
width: ratio > 1 ? pixel / ratio : pixel,
|
height: ratio < 1 ? pixel * ratio : pixel,
|
}
|
}
|
WaterMesh.prototype.loadFinish = function() {
|
return this.meshIndexLoad && this.meshPointLoad && this.meshValueLoad;
|
}
|
WaterMesh.prototype.loadData = function(callback) {
|
|
let that = this;
|
request({
|
url: "./data/mesh.json",
|
type: "application/json",
|
success: function(result) {
|
that.meshIndexLoad = true;
|
|
that.meshIndex = JSON.parse(result).data;
|
|
if (that.loadFinish() && typeof callback == "function")
|
callback();
|
},
|
error: function() {
|
|
}
|
});
|
request({
|
url: "./data/point.json",
|
type: "application/json",
|
success: function(result) {
|
that.meshPointLoad = true;
|
|
that.meshPoint = JSON.parse(result).data;
|
|
if (that.loadFinish() && typeof callback == "function")
|
callback();
|
},
|
error: function() {
|
|
}
|
});
|
request({
|
url: "./data/permesh.json",
|
type: "application/json",
|
success: function(result) {
|
that.meshValueLoad = true;
|
that.meshValue = JSON.parse(result).data;
|
for (let key in that.meshValue) {
|
that.time.push(key);
|
}
|
|
if (that.loadFinish() && typeof callback == "function")
|
callback();
|
},
|
error: function() {
|
|
}
|
});
|
}
|