Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

DoubleArrow.js 8.1KB

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