Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

WindLayer.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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 = scene.globe.pick(camera.getPickRay(pick), scene)
  124. if (!cartesian) {
  125. return null
  126. }
  127. let cartographic = ellipsoid.cartesianToCartographic(cartesian)
  128. let lat = Cesium.Math.toDegrees(cartographic.latitude)
  129. let lng = Cesium.Math.toDegrees(cartographic.longitude)
  130. return [lng, lat]
  131. }
  132. }
  133. /**
  134. *
  135. * @param viewer
  136. * @private
  137. */
  138. _onAdd(viewer) {
  139. this._viewer = viewer
  140. this._mountCanvas()
  141. let ctx = this._canvas.getContext('2d')
  142. if (!this._delegate) {
  143. this._delegate = new WindCanvas(ctx)
  144. this._delegate.setOptions(this._options)
  145. this._addedHook()
  146. }
  147. if (this._data) {
  148. this._delegate.setData(this._data)
  149. this._delegate.prerender()
  150. this._delegate.render()
  151. }
  152. }
  153. /**
  154. *
  155. * @private
  156. */
  157. _onRemove() {
  158. if (this._delegate) {
  159. this._delegate.stop()
  160. }
  161. if (this._canvas) {
  162. this._viewer.dcContainer.removeChild(this._canvas)
  163. }
  164. delete this._canvas
  165. }
  166. /**
  167. *
  168. * @param data
  169. * @param options
  170. * @returns {WindLayer}
  171. */
  172. setData(data, options) {
  173. if (data && data.checkFields && data.checkFields()) {
  174. this._data = data
  175. } else if (Array.isArray(data)) {
  176. this._data = this._formatData(data)
  177. }
  178. if (this._delegate) {
  179. this._delegate.setData(this._data)
  180. if (options) {
  181. this._options = {
  182. ...this._options,
  183. ...options
  184. }
  185. this._delegate.setOptions(this._options)
  186. }
  187. this._delegate.prerender()
  188. this._delegate.render()
  189. }
  190. return this
  191. }
  192. /**
  193. *
  194. * @param options
  195. * @returns {WindLayer}
  196. */
  197. setOptions(options) {
  198. this._options = {
  199. ...this._options,
  200. ...options
  201. }
  202. if (this._delegate) {
  203. this._delegate.setOptions(this._options)
  204. this._delegate.prerender()
  205. this._delegate.render()
  206. }
  207. return this
  208. }
  209. }
  210. Layer.registerType('wind')
  211. export default WindLayer