Cesium-Examples/examples/cesiumEx/ocean/layers/LayerOceanCurrent/current/RenderDynamicCurrent.js

507 lines
15 KiB
JavaScript
Raw Permalink Normal View History

2025-03-11 08:25:45 +00:00
import { currentData } from './CurrentData.js'
function RenderDynamicCurrent(viewer, Cesium) {
this.particles = []
this.particleCount = []
this._field = undefined
this._scale = 1// 1.0 //生成粒子的缩放因子
this._imageMask = undefined
this._particleNum = undefined
this._mapCenter = undefined
this._mapScale = undefined
this._windowWidth = undefined
this._windowheight = undefined
this._bounds = {
x: 0,
y: 0,
xMax: 0,
yMax: 0,
width: 0,
height: 0
}
this._viewer = viewer
this._cancel = false
this._centerPnt = new Cesium.Cartographic()
this.densityScale = 1// 1 //密度比例系数
this.velocityScale = 1 //1 //速度比例系数
this.builder = null
}
RenderDynamicCurrent.prototype.parseData = function (data) {
this.uvData = data
}
RenderDynamicCurrent.prototype.setData = (renderObject, data) => {
var bounds = data.params.bounds
var columns = data.columns
var maskImageData = data.pixels
var mask = maskImageData
const that = renderObject
that._imageMask = mask
that._field = currentData.createField(columns, bounds, false)
//lxl发现粒子在原位置时没生成移到此位置
that.particleCount = Math.round(
data.params.clientHeight *
data.params.clientWidth *
currentData.PARTICLE_MULTIPLIER *
that._scale
)
if (that._field != null) {
for (var i = 0; i < that.particleCount; i++) {
that.particles.push(
that._field.randomize({
age: currentData.random(0, currentData.MAX_PARTICLE_AGE)
})
)
}
}
var canvas, canvasOverLay
if (document.getElementById('fullScreen')) {
canvas = document.getElementById('fullScreen')
canvasOverLay = document.getElementById('image-canvas')
} else {
canvasOverLay = document.createElement('CANVAS')
// document.body.appendChild(canvasOverLay);
that._viewer.container.appendChild(canvasOverLay)
canvasOverLay.id = 'image-canvas'
canvasOverLay.width = bounds.width
canvasOverLay.height = bounds.height
canvasOverLay.style.position = 'absolute'
canvasOverLay.style.top = 0
canvasOverLay.style.left = 0
canvasOverLay.style.zIndex = 100
canvasOverLay.style.pointerEvents = 'none'
canvas = document.createElement('CANVAS')
// document.body.appendChild(canvas);
that._viewer.container.appendChild(canvas)
canvas.id = 'fullScreen'
canvas.style.position = 'absolute'
canvas.style.top = 0
canvas.style.left = 0
canvas.style.right = 0
canvas.style.bottom = 0
canvas.style.width = '100%'
canvas.style.height = '100%'
canvas.style.zIndex = 100
canvas.style.pointerEvents = 'none'
canvas.width = bounds.width
canvas.height = bounds.height
}
var g = canvas.getContext('2d')
g.clearRect(0, 0, canvas.width, canvas.height)
that._lineCanvas = canvas
that._lineCanvas.style.display = 'block'
that._g = g
that._g.lineWidth = that.lineWidth || 1
that._g.fillStyle = currentData.fadeFillStyle
var gOverlay = canvasOverLay.getContext('2d')
gOverlay.clearRect(0, 0, canvasOverLay.width, canvasOverLay.height)
that._imageCanvas = canvasOverLay
that._imageCanvas.style.display = 'none'
that._imageG = gOverlay
}
RenderDynamicCurrent.prototype.dealData = (renderObject, params) => {
if (!renderObject.builder) {
let uvData = params.uvData
let [header, uData, vData] = uvData
renderObject.builder = new currentData.buildGrid({
header,
data: function (i) {
return [uData[i], vData[i]]
},
interpolate: currentData.bilinearInterpolateVector
})
}
if (params.velocityScale_o)
currentData.velocityScale_o = params.velocityScale_o
let result = currentData.reCreate(params, renderObject.builder, true)
let data = {
params,
columns: result.columns,
pixels: result.mask.imageData
}
return data
}
RenderDynamicCurrent.prototype.reCreate = function (renderObject) {
var scene = this._viewer.scene
var canvas = scene.canvas
var camera = scene.camera
var width = renderObject._viewer.scene.canvas.clientWidth
var height = renderObject._viewer.scene.canvas.clientHeight
renderObject._windowWidth = width
renderObject._windowheight = height
renderObject._bounds.xMax = width
renderObject._bounds.yMax = height
renderObject._bounds.width = width
renderObject._bounds.height = height
if (renderObject._field != null) {
renderObject._field.release()
}
var params = {}
params.clientWidth = canvas.clientWidth
params.clientHeight = canvas.clientHeight
params.viewMatrix = camera.viewMatrix
params.projectionMatrix = camera.frustum.projectionMatrix
params.fovy = camera.frustum.fovy
params.aspectRatio = camera.frustum.aspectRatio
params.near = camera.frustum.near
params.positionWC = camera.positionWC
params.directionWC = camera.directionWC
params.rightWC = camera.rightWC
params.upWC = camera.upWC
params.center = renderObject._centerPnt
params.bounds = renderObject._bounds
params.uvData = this.uvData
params.velocityScale_o = renderObject.velocityScale_o
const data = renderObject.dealData(renderObject, params)
renderObject.setData(renderObject, data)
}
RenderDynamicCurrent.prototype.getVelocityScaleByHeight = function (height) {
let extent = this.getCurrentExtent()
let mapBounds = {
south: this.deg2rad(extent[1]),
north: this.deg2rad(extent[3]),
east: this.deg2rad(extent[2]),
west: this.deg2rad(extent[0])
}
let mapArea =
(mapBounds.south - mapBounds.north) * (mapBounds.west - mapBounds.east)
let scale = 0.0001 * this.velocityScale
if (height < 630000) scale = 0.00005 * this.velocityScale
let velocityScale_o =
scale *
(Math.pow(window.devicePixelRatio, 1 / 3) || 1) *
Math.pow(mapArea, 0.2)
return velocityScale_o
}
RenderDynamicCurrent.prototype.getScaleByHeight = function (height) {
// console.log('当前相机高度', height)
if (height <= 7798950) {
return this.densityScale * 0.5
} else {
return this.densityScale * 0.9
}
}
RenderDynamicCurrent.prototype.getCurrentExtent = function () {
let _self = this
//获取当前三维地图范围
var Rectangle = _self._viewer.camera.computeViewRectangle()
//地理坐标(弧度)转经纬度坐标
var extent = [
(Rectangle.west / Math.PI) * 180,
(Rectangle.south / Math.PI) * 180,
(Rectangle.east / Math.PI) * 180,
(Rectangle.north / Math.PI) * 180
]
return extent
}
RenderDynamicCurrent.prototype.deg2rad = function (deg) {
return (deg / 180) * Math.PI
}
RenderDynamicCurrent.prototype.Render = function () {
var scene = this._viewer.scene
var renderObject = this
renderObject.start = true
renderObject.velocityScale_o = renderObject.getVelocityScaleByHeight(
scene.camera.positionCartographic.height
)
renderObject._isRender = true
this.reCreate(renderObject)
renderObject._scale = renderObject.getScaleByHeight(
scene.camera.positionCartographic.height
)
scene.camera.moveEnd.addEventListener(function () {
//获取当前相机高度
renderObject.start1 = true
//获取当前相机高度
var newCenter = scene.camera.positionCartographic
// if (newCenter.height < 1263951.9408551503) {
// for (let i = window.aalayers.length - 1; i >= 0; i--) {
// let layers = window.aalayers[i]
// if (layers._opt.name === '海流场信息') {
// if (layers.visible === true) {
// layers.visible = false
// }
// }
// }
// } else {
// for (let i = window.aalayers.length - 1; i >= 0; i--) {
// let layers = window.aalayers[i]
// if (layers._opt.name === '海流场信息') {
// if (layers.visible === false) {
// layers.visible = true
// }
// }
// }
// }
if (!renderObject.start) return
if (newCenter != renderObject._centerPnt) {
renderObject.velocityScale_o = renderObject.getVelocityScaleByHeight(
scene.camera.positionCartographic.height
)
renderObject.reCreate(renderObject)
renderObject._isRender = true
renderObject._scale = renderObject.getScaleByHeight(newCenter.height)
renderObject.particles = []
renderObject.particleCount = Math.round(
renderObject._windowheight *
currentData.PARTICLE_MULTIPLIER *
renderObject._windowWidth *
renderObject._scale
)
if (renderObject._field != null) {
for (var i = 0; i < renderObject.particleCount; i++) {
if (!renderObject.start1) {
i = renderObject.particleCount - 1
return
}
renderObject.particles.push(
renderObject._field.randomize({
age: currentData.random(0, currentData.MAX_PARTICLE_AGE)
})
)
}
}
}
})
scene.camera.moveStart.addEventListener(function () {
//获取当前相机高度
var newCenter = scene.camera.positionCartographic
if (newCenter != renderObject._centerPnt) {
if (renderObject._field != null) {
renderObject._field.release()
}
renderObject.start1 = false
renderObject._isRender = false
if (renderObject._imageG) {
renderObject._imageG.clearRect(
0,
0,
renderObject._windowWidth,
renderObject._windowheight
)
renderObject._g.clearRect(
0,
0,
renderObject._windowWidth,
renderObject._windowheight
)
}
}
})
// currentData.maxIntensity is the velocity at which particle color intensity is maximum
var colorStyles = currentData.windIntensityColorScale(
currentData.INTENSITY_SCALE_STEP,
currentData.maxIntensity
)
var buckets = colorStyles.map(function () {
return []
})
function evolve() {
buckets.forEach(function (bucket) {
bucket.length = 0
})
renderObject.particles.forEach(function (particle) {
if (particle.age > currentData.MAX_PARTICLE_AGE) {
renderObject._field.randomize(particle).age = 0
}
var x = particle.x
var y = particle.y
var v = renderObject._field(x, y) // vector at current position
var m = v[2]
if (m === null) {
particle.age = currentData.MAX_PARTICLE_AGE // particle has escaped the grid, never to return...
} else {
var xt = x + v[0] * currentData.WindScale
var yt = y + v[1] * currentData.WindScale
if (renderObject._field.isDefined(xt, yt)) {
// Path from (x,y) to (xt,yt) is visible, so add this particle to the appropriate draw bucket.
particle.xt = xt
particle.yt = yt
buckets[colorStyles.indexFor(m)].push(particle)
} else {
// Particle isn't visible, but it still moves through the field.
particle.x = xt
particle.y = yt
}
}
particle.age += 1
})
}
function draw() {
if (!renderObject.start) return
var g = renderObject._g
if (g == null || renderObject._imageMask == null) {
return
}
var bounds = renderObject._bounds
var prev = g.globalCompositeOperation
g.globalCompositeOperation = 'destination-in'
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height)
//g.putImageData(renderObject._imageMask.imageData,0,0)
g.globalCompositeOperation = prev
// Draw new particle trails.
buckets.forEach(function (bucket, i) {
if (bucket.length > 0) {
g.beginPath()
g.strokeStyle = colorStyles[i]
bucket.forEach(function (particle) {
g.moveTo(particle.x, particle.y)
g.lineTo(particle.xt, particle.yt)
particle.x = particle.xt
particle.y = particle.yt
})
g.stroke()
}
})
}
;(function frame() {
evolve()
draw()
if (renderObject._isRender && renderObject._imageMask) {
//renderObject._imageG.putImageData(renderObject._imageMask,0,0);
}
if (renderObject.start) {
setTimeout(frame, 10 / 0.8)
}
})()
}
RenderDynamicCurrent.prototype.remove = function () {
var renderObject = this
if (
renderObject._lineCanvas != undefined &&
renderObject._lineCanvas.style != null
) {
renderObject._lineCanvas.style.display = 'none'
}
if (
renderObject._imageCanvas != undefined &&
renderObject._imageCanvas.style != null
) {
renderObject._imageCanvas.style.display = 'none'
}
renderObject.start = false
if (document.getElementById('image-canvas'))
document.getElementById('image-canvas').remove()
if (document.getElementById('fullScreen'))
document.getElementById('fullScreen').remove()
this.particles = []
}
RenderDynamicCurrent.prototype.clone = function () {}
RenderDynamicCurrent.prototype.update = function () {
var RTOD = 180.0 / 3.1415926
var canvas = document.getElementById('animation')
var g = canvas.getContext('2d')
g.fillStyle = 'rgba(0, 0, 0, 0.97)'
g.lineWidth = 20
function draw() {
// Fade existing particle trails.
var prev = 'source-over'
g.globalCompositeOperation = 'destination-in'
g.fillRect(0, 0, 800, 600)
g.globalCompositeOperation = prev
g.beginPath()
g.strokeStyle = 0x111111
for (var i = 0; i < 100; i++) {
var x = Math.floor(Math.random() * 800)
var y = Math.floor(Math.random() * 600)
g.moveTo(x, y)
g.lineTo(x + 5, y + 5)
}
g.stroke()
}
;(function frame() {
try {
draw()
setTimeout(frame, 40)
} catch (e) {}
})()
}
RenderDynamicCurrent.prototype.updateO = function (options) {
const renderObject = this
var scene = renderObject._viewer.scene
renderObject.lineWidth = options.lineWidth || renderObject.lineWidth
renderObject.densityScale = options.densityScale || renderObject.densityScale
renderObject.velocityScale =
options.velocityScale || renderObject.velocityScale
if (renderObject._field != null) {
renderObject._field.release()
}
renderObject.start1 = false
renderObject._isRender = false
if (renderObject._imageG) {
renderObject._imageG.clearRect(
0,
0,
renderObject._windowWidth,
renderObject._windowheight
)
renderObject._g.clearRect(
0,
0,
renderObject._windowWidth,
renderObject._windowheight
)
}
if (!renderObject.start) return
//获取当前相机高度
renderObject.start1 = true
renderObject._isRender = true
renderObject._height = scene.camera.positionCartographic.height
renderObject._scale = renderObject.getScaleByHeight(renderObject._height)
renderObject.velocityScale_o = renderObject.getVelocityScaleByHeight(
renderObject._height
)
renderObject.reCreate(renderObject)
renderObject.particles = []
renderObject.particleCount = Math.round(
renderObject._windowheight *
currentData.PARTICLE_MULTIPLIER *
renderObject._windowWidth *
renderObject._scale
)
if (renderObject._field != null) {
for (var i = 0; i < renderObject.particleCount; i++) {
if (!renderObject.start1) {
i = renderObject.particleCount - 1
return
}
renderObject.particles.push(
renderObject._field.randomize({
age: currentData.random(0, currentData.MAX_PARTICLE_AGE)
})
)
}
}
}
export default RenderDynamicCurrent