You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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