Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

WindLayer.js 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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. if (scene.mode === Cesium.SceneMode.SCENE3D) {
  112. let occluder = new Cesium.EllipsoidalOccluder(
  113. ellipsoid,
  114. camera.position
  115. )
  116. let point = Cesium.Cartesian3.fromDegrees(coordinate[0], coordinate[1])
  117. return occluder.isPointVisible(point)
  118. } else if (scene.mode === Cesium.SceneMode.SCENE2D) {
  119. return !(coordinate[0] === -180 || coordinate[0] === 180)
  120. }
  121. return true
  122. }
  123. this._delegate.project = coordinate => {
  124. let position = Cesium.Cartesian3.fromDegrees(coordinate[0], coordinate[1])
  125. let coord = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
  126. scene,
  127. position
  128. )
  129. return [coord.x, coord.y]
  130. }
  131. this._delegate.unProject = pixel => {
  132. let pick = new Cesium.Cartesian2(pixel[0], pixel[1])
  133. let cartesian = undefined
  134. if (scene.mode === Cesium.SceneMode.SCENE3D) {
  135. cartesian = scene.globe.pick(camera.getPickRay(pick), scene)
  136. } else {
  137. cartesian = scene.camera.pickEllipsoid(pick, ellipsoid)
  138. }
  139. if (!cartesian) {
  140. return null
  141. }
  142. let cartographic = ellipsoid.cartesianToCartographic(cartesian)
  143. let lat = Cesium.Math.toDegrees(cartographic.latitude)
  144. let lng = Cesium.Math.toDegrees(cartographic.longitude)
  145. return [lng, lat]
  146. }
  147. }
  148. /**
  149. *
  150. * @param viewer
  151. * @private
  152. */
  153. _onAdd(viewer) {
  154. this._viewer = viewer
  155. this._mountCanvas()
  156. let ctx = this._canvas.getContext('2d')
  157. if (!this._delegate) {
  158. this._delegate = new WindCanvas(ctx)
  159. this._delegate.setOptions(this._options)
  160. this._addedHook()
  161. }
  162. if (this._data) {
  163. this._delegate.setData(this._data)
  164. this._delegate.prerender()
  165. this._delegate.render()
  166. }
  167. }
  168. /**
  169. *
  170. * @private
  171. */
  172. _onRemove() {
  173. if (this._delegate) {
  174. this._delegate.stop()
  175. }
  176. if (this._canvas) {
  177. this._viewer.dcContainer.removeChild(this._canvas)
  178. }
  179. delete this._canvas
  180. }
  181. /**
  182. *
  183. * @param data
  184. * @param options
  185. * @returns {WindLayer}
  186. */
  187. setData(data, options) {
  188. if (data && data.checkFields && data.checkFields()) {
  189. this._data = data
  190. } else if (Array.isArray(data)) {
  191. this._data = this._formatData(data)
  192. }
  193. if (this._delegate) {
  194. this._delegate.setData(this._data)
  195. if (options) {
  196. this._options = {
  197. ...this._options,
  198. ...options
  199. }
  200. this._delegate.setOptions(this._options)
  201. }
  202. this._delegate.prerender()
  203. this._delegate.render()
  204. }
  205. return this
  206. }
  207. /**
  208. *
  209. * @param options
  210. * @returns {WindLayer}
  211. */
  212. setOptions(options) {
  213. this._options = {
  214. ...this._options,
  215. ...options
  216. }
  217. if (this._delegate) {
  218. this._delegate.setOptions(this._options)
  219. this._delegate.prerender()
  220. this._delegate.render()
  221. }
  222. return this
  223. }
  224. }
  225. Layer.registerType('wind')
  226. export default WindLayer