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.

DoubleArrow.js 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /**
  2. * @Author: Caven
  3. * @Date: 2020-08-29 22:15:47
  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 { Util, PlotUtil } from '@dc-modules/utils'
  9. import { Transform } from '@dc-modules/transform'
  10. import Overlay from '../Overlay'
  11. const HALF_PI = Math.PI / 2
  12. class DoubleArrow extends Overlay {
  13. constructor(positions) {
  14. super()
  15. this._positions = Parse.parsePositions(positions)
  16. this._delegate = new Cesium.Entity({ polygon: {} })
  17. this.headHeightFactor = 0.25
  18. this.headWidthFactor = 0.3
  19. this.neckHeightFactor = 0.85
  20. this.neckWidthFactor = 0.15
  21. this._state = State.INITIALIZED
  22. }
  23. get type() {
  24. return Overlay.getOverlayType('double_arrow')
  25. }
  26. set positions(positions) {
  27. this._positions = Parse.parsePositions(positions)
  28. this._delegate.polygon.hierarchy = this._getHierarchy()
  29. return this
  30. }
  31. get positions() {
  32. return this._positions
  33. }
  34. _getArrowPoints(pnt1, pnt2, pnt3, clockWise) {
  35. let midPnt = PlotUtil.mid(pnt1, pnt2)
  36. let len = PlotUtil.distance(midPnt, pnt3)
  37. let midPnt1 = PlotUtil.getThirdPoint(pnt3, midPnt, 0, len * 0.3, true)
  38. let midPnt2 = PlotUtil.getThirdPoint(pnt3, midPnt, 0, len * 0.5, true)
  39. midPnt1 = PlotUtil.getThirdPoint(
  40. midPnt,
  41. midPnt1,
  42. HALF_PI,
  43. len / 5,
  44. clockWise
  45. )
  46. midPnt2 = PlotUtil.getThirdPoint(
  47. midPnt,
  48. midPnt2,
  49. HALF_PI,
  50. len / 4,
  51. clockWise
  52. )
  53. let points = [midPnt, midPnt1, midPnt2, pnt3]
  54. // 计算箭头部分
  55. let arrowPnts = this._getArrowHeadPoints(points)
  56. let neckLeftPoint = arrowPnts[0]
  57. let neckRightPoint = arrowPnts[4]
  58. // 计算箭身部分
  59. let tailWidthFactor =
  60. PlotUtil.distance(pnt1, pnt2) / PlotUtil.getBaseLength(points) / 2
  61. let bodyPnts = this._getArrowBodyPoints(
  62. points,
  63. neckLeftPoint,
  64. neckRightPoint,
  65. tailWidthFactor
  66. )
  67. let n = bodyPnts.length
  68. let lPoints = bodyPnts.slice(0, n / 2)
  69. let rPoints = bodyPnts.slice(n / 2, n)
  70. lPoints.push(neckLeftPoint)
  71. rPoints.push(neckRightPoint)
  72. lPoints = lPoints.reverse()
  73. lPoints.push(pnt2)
  74. rPoints = rPoints.reverse()
  75. rPoints.push(pnt1)
  76. return lPoints.reverse().concat(arrowPnts, rPoints)
  77. }
  78. _getArrowHeadPoints(points) {
  79. let len = PlotUtil.getBaseLength(points)
  80. let headHeight = len * this.headHeightFactor
  81. let headPnt = points[points.length - 1]
  82. let headWidth = headHeight * this.headWidthFactor
  83. let neckWidth = headHeight * this.neckWidthFactor
  84. let neckHeight = headHeight * this.neckHeightFactor
  85. let headEndPnt = PlotUtil.getThirdPoint(
  86. points[points.length - 2],
  87. headPnt,
  88. 0,
  89. headHeight,
  90. true
  91. )
  92. let neckEndPnt = PlotUtil.getThirdPoint(
  93. points[points.length - 2],
  94. headPnt,
  95. 0,
  96. neckHeight,
  97. true
  98. )
  99. let headLeft = PlotUtil.getThirdPoint(
  100. headPnt,
  101. headEndPnt,
  102. HALF_PI,
  103. headWidth,
  104. false
  105. )
  106. let headRight = PlotUtil.getThirdPoint(
  107. headPnt,
  108. headEndPnt,
  109. HALF_PI,
  110. headWidth,
  111. true
  112. )
  113. let neckLeft = PlotUtil.getThirdPoint(
  114. headPnt,
  115. neckEndPnt,
  116. HALF_PI,
  117. neckWidth,
  118. false
  119. )
  120. let neckRight = PlotUtil.getThirdPoint(
  121. headPnt,
  122. neckEndPnt,
  123. HALF_PI,
  124. neckWidth,
  125. true
  126. )
  127. return [neckLeft, headLeft, headPnt, headRight, neckRight]
  128. }
  129. _getArrowBodyPoints(points, neckLeft, neckRight, tailWidthFactor) {
  130. let allLen = PlotUtil.wholeDistance(points)
  131. let len = PlotUtil.getBaseLength(points)
  132. let tailWidth = len * tailWidthFactor
  133. let neckWidth = PlotUtil.distance(neckLeft, neckRight)
  134. let widthDif = (tailWidth - neckWidth) / 2
  135. let tempLen = 0
  136. let leftBodyPnts = []
  137. let rightBodyPnts = []
  138. for (let i = 1; i < points.length - 1; i++) {
  139. let angle =
  140. PlotUtil.getAngleOfThreePoints(
  141. points[i - 1],
  142. points[i],
  143. points[i + 1]
  144. ) / 2
  145. tempLen += PlotUtil.distance(points[i - 1], points[i])
  146. let w = (tailWidth / 2 - (tempLen / allLen) * widthDif) / Math.sin(angle)
  147. let left = PlotUtil.getThirdPoint(
  148. points[i - 1],
  149. points[i],
  150. Math.PI - angle,
  151. w,
  152. true
  153. )
  154. let right = PlotUtil.getThirdPoint(
  155. points[i - 1],
  156. points[i],
  157. angle,
  158. w,
  159. false
  160. )
  161. leftBodyPnts.push(left)
  162. rightBodyPnts.push(right)
  163. }
  164. return leftBodyPnts.concat(rightBodyPnts)
  165. }
  166. _getTempPoint4(linePnt1, linePnt2, point) {
  167. let midPnt = PlotUtil.mid(linePnt1, linePnt2)
  168. let len = PlotUtil.distance(midPnt, point)
  169. let angle = PlotUtil.getAngleOfThreePoints(linePnt1, midPnt, point)
  170. let symPnt, distance1, distance2, mid
  171. if (angle < HALF_PI) {
  172. distance1 = len * Math.sin(angle)
  173. distance2 = len * Math.cos(angle)
  174. mid = PlotUtil.getThirdPoint(linePnt1, midPnt, HALF_PI, distance1, false)
  175. symPnt = PlotUtil.getThirdPoint(midPnt, mid, HALF_PI, distance2, true)
  176. } else if (angle >= HALF_PI && angle < Math.PI) {
  177. distance1 = len * Math.sin(Math.PI - angle)
  178. distance2 = len * Math.cos(Math.PI - angle)
  179. mid = PlotUtil.getThirdPoint(linePnt1, midPnt, HALF_PI, distance1, false)
  180. symPnt = PlotUtil.getThirdPoint(midPnt, mid, HALF_PI, distance2, false)
  181. } else if (angle >= Math.PI && angle < Math.PI * 1.5) {
  182. distance1 = len * Math.sin(angle - Math.PI)
  183. distance2 = len * Math.cos(angle - Math.PI)
  184. mid = PlotUtil.getThirdPoint(linePnt1, midPnt, HALF_PI, distance1, true)
  185. symPnt = PlotUtil.getThirdPoint(midPnt, mid, HALF_PI, distance2, true)
  186. } else {
  187. distance1 = len * Math.sin(Math.PI * 2 - angle)
  188. distance2 = len * Math.cos(Math.PI * 2 - angle)
  189. mid = PlotUtil.getThirdPoint(linePnt1, midPnt, HALF_PI, distance1, true)
  190. symPnt = PlotUtil.getThirdPoint(midPnt, mid, HALF_PI, distance2, false)
  191. }
  192. return symPnt
  193. }
  194. _getHierarchy() {
  195. let count = this._positions.length
  196. let tempPoint4 = undefined
  197. let connPoint = undefined
  198. let pnts = Parse.parsePolygonCoordToArray(this._positions)[0]
  199. let pnt1 = pnts[0]
  200. let pnt2 = pnts[1]
  201. let pnt3 = pnts[2]
  202. if (count === 3) tempPoint4 = this._getTempPoint4(pnt1, pnt2, pnt3)
  203. else tempPoint4 = pnts[3]
  204. if (count === 3 || count === 4) connPoint = PlotUtil.mid(pnt1, pnt2)
  205. else connPoint = pnts[4]
  206. let leftArrowPnts, rightArrowPnts
  207. if (PlotUtil.isClockWise(pnt1, pnt2, pnt3)) {
  208. leftArrowPnts = this._getArrowPoints(pnt1, connPoint, tempPoint4, false)
  209. rightArrowPnts = this._getArrowPoints(connPoint, pnt2, pnt3, true)
  210. } else {
  211. leftArrowPnts = this._getArrowPoints(pnt2, connPoint, pnt3, false)
  212. rightArrowPnts = this._getArrowPoints(connPoint, pnt1, tempPoint4, true)
  213. }
  214. let m = leftArrowPnts.length
  215. let t = (m - 5) / 2
  216. let llBodyPnts = leftArrowPnts.slice(0, t)
  217. let lArrowPnts = leftArrowPnts.slice(t, t + 5)
  218. let lrBodyPnts = leftArrowPnts.slice(t + 5, m)
  219. let rlBodyPnts = rightArrowPnts.slice(0, t)
  220. let rArrowPnts = rightArrowPnts.slice(t, t + 5)
  221. let rrBodyPnts = rightArrowPnts.slice(t + 5, m)
  222. rlBodyPnts = PlotUtil.getBezierPoints(rlBodyPnts)
  223. let bodyPnts = PlotUtil.getBezierPoints(
  224. rrBodyPnts.concat(llBodyPnts.slice(1))
  225. )
  226. lrBodyPnts = PlotUtil.getBezierPoints(lrBodyPnts)
  227. return new Cesium.PolygonHierarchy(
  228. Transform.transformWGS84ArrayToCartesianArray(
  229. Parse.parsePositions(
  230. rlBodyPnts.concat(rArrowPnts, bodyPnts, lArrowPnts, lrBodyPnts)
  231. )
  232. )
  233. )
  234. }
  235. _mountedHook() {
  236. /**
  237. * set the location
  238. */
  239. this.positions = this._positions
  240. }
  241. /**
  242. *
  243. * @param text
  244. * @param textStyle
  245. * @returns {DoubleArrow}
  246. */
  247. setLabel(text, textStyle) {
  248. return this
  249. }
  250. /**
  251. * Sets Style
  252. * @param style
  253. * @returns {DoubleArrow}
  254. */
  255. setStyle(style) {
  256. if (Object.keys(style).length === 0) {
  257. return this
  258. }
  259. delete style['positions']
  260. Util.merge(this._style, style)
  261. Util.merge(this._delegate.polygon, style)
  262. return this
  263. }
  264. }
  265. Overlay.registerType('double_arrow')
  266. export default DoubleArrow