您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

WindLayer.js 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /**
  2. * @Author: Caven
  3. * @Date: 2021-01-18 20:13:30
  4. */
  5. import { Cesium } from '@dc-modules/namespace'
  6. import State from '@dc-modules/state/State'
  7. import { Layer } from '@dc-modules/layer'
  8. import Field from './Field'
  9. import WindCanvas from './WindCanvas'
  10. const DEF_OPTS = {
  11. globalAlpha: 0.9,
  12. lineWidth: 1,
  13. colorScale: '#fff',
  14. velocityScale: 1 / 25,
  15. maxAge: 90,
  16. paths: 800,
  17. frameRate: 20,
  18. useCoordsDraw: true,
  19. gpet: true
  20. }
  21. class WindLayer extends Layer {
  22. constructor(id, options = {}) {
  23. super(id)
  24. this._options = {
  25. ...DEF_OPTS,
  26. ...options
  27. }
  28. this._data = undefined
  29. this._canvas = document.createElement('canvas')
  30. this.type = Layer.getLayerType('wind')
  31. this._state = State.INITIALIZED
  32. }
  33. set show(show) {
  34. this._show = show
  35. this._canvas.style.visibility = show ? 'visible' : 'hidden'
  36. }
  37. get show() {
  38. return this._show
  39. }
  40. /**
  41. *
  42. * @param data
  43. * @returns {Field|undefined}
  44. * @private
  45. */
  46. _formatData(data) {
  47. let uComp
  48. let vComp
  49. data.forEach(function(record) {
  50. switch (
  51. record.header.parameterCategory +
  52. ',' +
  53. record.header.parameterNumber
  54. ) {
  55. case '1,2':
  56. case '2,2':
  57. uComp = record
  58. break
  59. case '1,3':
  60. case '2,3':
  61. vComp = record
  62. break
  63. }
  64. })
  65. if (!vComp || !uComp) {
  66. return undefined
  67. }
  68. let header = uComp.header
  69. return new Field({
  70. xmin: header.lo1,
  71. ymin: header.la1,
  72. xmax: header.lo2,
  73. ymax: header.la2,
  74. deltaX: header.dx,
  75. deltaY: header.dy,
  76. cols: header.nx,
  77. rows: header.ny,
  78. us: uComp.data,
  79. vs: vComp.data
  80. })
  81. }
  82. /**
  83. *
  84. * @private
  85. */
  86. _mountCanvas() {
  87. if (!this._viewer || !this._canvas) {
  88. return
  89. }
  90. this._canvas.style.cssText =
  91. 'position:absolute; left:0; top:0;user-select:none;pointer-events: none;'
  92. this._canvas.className = 'dc-wind-layer'
  93. const { width, height } = this._viewer.canvas
  94. this._canvas.width = width
  95. this._canvas.height = height
  96. this._canvas.style.width = width + 'px'
  97. this._canvas.style.height = height + 'px'
  98. this._viewer.dcContainer.appendChild(this._canvas)
  99. }
  100. /**
  101. *
  102. * @private
  103. */
  104. _addedHook() {
  105. let scene = this._viewer.scene
  106. let camera = this._viewer.camera
  107. let ellipsoid = Cesium.Ellipsoid.WGS84
  108. this._delegate.intersectsCoordinate = coordinate => {
  109. let occluder = new Cesium.EllipsoidalOccluder(ellipsoid, camera.position)
  110. let point = Cesium.Cartesian3.fromDegrees(coordinate[0], coordinate[1])
  111. return occluder.isPointVisible(point)
  112. }
  113. this._delegate.project = coordinate => {
  114. let position = Cesium.Cartesian3.fromDegrees(coordinate[0], coordinate[1])
  115. let coord = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
  116. scene,
  117. position
  118. )
  119. return [coord.x, coord.y]
  120. }
  121. this._delegate.unProject = pixel => {
  122. let pick = new Cesium.Cartesian2(pixel[0], pixel[1])
  123. let cartesian = undefined
  124. if (scene.mode === Cesium.SceneMode.SCENE3D) {
  125. cartesian = scene.globe.pick(camera.getPickRay(pick), scene)
  126. } else {
  127. cartesian = scene.camera.pickEllipsoid(pick, ellipsoid)
  128. }
  129. if (!cartesian) {
  130. return null
  131. }
  132. let cartographic = ellipsoid.cartesianToCartographic(cartesian)
  133. let lat = Cesium.Math.toDegrees(cartographic.latitude)
  134. let lng = Cesium.Math.toDegrees(cartographic.longitude)
  135. return [lng, lat]
  136. }
  137. }
  138. /**
  139. *
  140. * @param viewer
  141. * @private
  142. */
  143. _onAdd(viewer) {
  144. this._viewer = viewer
  145. this._mountCanvas()
  146. let ctx = this._canvas.getContext('2d')
  147. if (!this._delegate) {
  148. this._delegate = new WindCanvas(ctx)
  149. this._delegate.setOptions(this._options)
  150. this._addedHook()
  151. }
  152. if (this._data) {
  153. this._delegate.setData(this._data)
  154. this._delegate.prerender()
  155. this._delegate.render()
  156. }
  157. }
  158. /**
  159. *
  160. * @private
  161. */
  162. _onRemove() {
  163. if (this._delegate) {
  164. this._delegate.stop()
  165. }
  166. if (this._canvas) {
  167. this._viewer.dcContainer.removeChild(this._canvas)
  168. }
  169. delete this._canvas
  170. }
  171. /**
  172. *
  173. * @param data
  174. * @param options
  175. * @returns {WindLayer}
  176. */
  177. setData(data, options) {
  178. if (data && data.checkFields && data.checkFields()) {
  179. this._data = data
  180. } else if (Array.isArray(data)) {
  181. this._data = this._formatData(data)
  182. }
  183. if (this._delegate) {
  184. this._delegate.setData(this._data)
  185. if (options) {
  186. this._options = {
  187. ...this._options,
  188. ...options
  189. }
  190. this._delegate.setOptions(this._options)
  191. }
  192. this._delegate.prerender()
  193. this._delegate.render()
  194. }
  195. return this
  196. }
  197. /**
  198. *
  199. * @param options
  200. * @returns {WindLayer}
  201. */
  202. setOptions(options) {
  203. this._options = {
  204. ...this._options,
  205. ...options
  206. }
  207. if (this._delegate) {
  208. this._delegate.setOptions(this._options)
  209. this._delegate.prerender()
  210. this._delegate.render()
  211. }
  212. return this
  213. }
  214. }
  215. Layer.registerType('wind')
  216. export default WindLayer