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.

RoamingPath.js 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /**
  2. * @Author: Caven
  3. * @Date: 2021-06-08 20:41:51
  4. */
  5. import { Cesium } from '@dc-modules/namespace'
  6. import State from '@dc-modules/state/State'
  7. import Parse from '@dc-modules/parse/Parse'
  8. import { PathEventType, PathEvent } from '@dc-modules/event'
  9. import { Util } from '@dc-modules/utils'
  10. import { Transform } from '@dc-modules/transform'
  11. import { heading, distance } from '@dc-modules/math'
  12. class RoamingPath {
  13. constructor(positions, duration, pathMode) {
  14. this._id = Util.uuid()
  15. this._bid = undefined
  16. this._positions = Parse.parsePositions(positions)
  17. this._duration = duration || 20
  18. this._pathMode = pathMode || 'speed'
  19. this._timeLine = []
  20. this._sampledPosition = undefined
  21. this._actived = false
  22. this._endTime = Cesium.JulianDate.now()
  23. this._pathEvent = new PathEvent()
  24. this._pathEvent.on(PathEventType.ADD, this._onAdd, this)
  25. this._pathEvent.on(PathEventType.REMOVE, this._onRemove, this)
  26. this._pathEvent.on(PathEventType.POST_RENDER, this._onPostRender, this)
  27. this._pathEvent.on(PathEventType.RESET_TIME_LINE, this._resetTimeLine, this)
  28. this._state = State.INITIALIZED
  29. }
  30. get pathId() {
  31. return this._id
  32. }
  33. set id(id) {
  34. this._bid = id
  35. return this
  36. }
  37. get id() {
  38. return this._bid
  39. }
  40. set positions(postions) {
  41. this._positions = Parse.parsePositions(postions)
  42. return this
  43. }
  44. get positions() {
  45. return this._positions
  46. }
  47. set duration(duration) {
  48. this._duration = duration
  49. return this
  50. }
  51. get duration() {
  52. return this._duration
  53. }
  54. set pathMode(pathMode) {
  55. this._pathMode = pathMode
  56. return this
  57. }
  58. get pathMode() {
  59. return this._pathMode
  60. }
  61. get pathEvent() {
  62. return this._pathEvent
  63. }
  64. set actived(actived) {
  65. this._actived = actived
  66. return this
  67. }
  68. get actived() {
  69. return this._actived
  70. }
  71. get state() {
  72. return this._state
  73. }
  74. _onAdd() {
  75. this._state = State.ADDED
  76. }
  77. _onRemove() {
  78. this._state = State.REMOVED
  79. }
  80. /**
  81. *
  82. * @param viewer
  83. * @param viewOption
  84. * @private
  85. */
  86. _onPostRender({ viewer, viewOption }) {
  87. if (!this.actived) {
  88. return false
  89. }
  90. let now = Cesium.JulianDate.now()
  91. if (
  92. Cesium.JulianDate.lessThan(now, this._endTime) &&
  93. this._sampledPosition
  94. ) {
  95. let p = this._sampledPosition.getValue(now)
  96. let next_p = this._sampledPosition.getValue(
  97. Cesium.JulianDate.addSeconds(now, 0.001, new Cesium.JulianDate())
  98. )
  99. if (p && next_p) {
  100. viewer.camera.lookAt(
  101. p,
  102. new Cesium.HeadingPitchRange(
  103. heading(p, next_p),
  104. Cesium.Math.toRadians(viewOption?.pitch || -20),
  105. viewOption?.range || 2000
  106. )
  107. )
  108. }
  109. } else {
  110. viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
  111. this._actived = false
  112. }
  113. }
  114. /**
  115. *
  116. * @private
  117. */
  118. _resetTimeLine() {
  119. if (!this._positions || !this._positions.length) {
  120. return false
  121. }
  122. let now = Cesium.JulianDate.now()
  123. let interval = 0
  124. let timeLine = []
  125. if (this._pathMode === 'speed') {
  126. let v = distance(this._positions) / this._duration
  127. timeLine = this._positions.map((item, index, arr) => {
  128. if (index !== 0) {
  129. interval += distance([arr[index - 1], item]) / v
  130. }
  131. return Cesium.JulianDate.addSeconds(
  132. now,
  133. interval,
  134. new Cesium.JulianDate()
  135. )
  136. })
  137. } else {
  138. let len = this._positions.length
  139. let interval = (this._duration - (this._duration % len)) / len
  140. timeLine = this._positions.map((item, index) => {
  141. return Cesium.JulianDate.addSeconds(
  142. now,
  143. index * interval,
  144. new Cesium.JulianDate()
  145. )
  146. })
  147. }
  148. this._sampledPosition = new Cesium.SampledPositionProperty()
  149. this._sampledPosition.addSamples(
  150. timeLine,
  151. Transform.transformWGS84ArrayToCartesianArray(this._positions)
  152. )
  153. this._sampledPosition.forwardExtrapolationType =
  154. Cesium.ExtrapolationType.HOLD
  155. this._sampledPosition.setInterpolationOptions({
  156. interpolationDegree: 2,
  157. interpolationAlgorithm: Cesium.HermitePolynomialApproximation
  158. })
  159. this._endTime = timeLine[timeLine.length - 1]
  160. this._actived = true
  161. }
  162. }
  163. export default RoamingPath