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.

curve.js 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /**
  2. * @Author: Caven
  3. * @Date: 2020-08-16 11:14:23
  4. */
  5. /**
  6. * Some of the code borrows from MAPV
  7. * https://github.com/huiyan-fe/mapv/blob/3292c7c25dbbf29af3cf7b3acb48108d60b3eed8/src/utils/curve.js
  8. */
  9. export default function curve(points, options) {
  10. options = options || {}
  11. let curvePoints = []
  12. for (let i = 0; i < points.length - 1; i++) {
  13. let p = getCurveByTwoPoints(points[i], points[i + 1], options.count)
  14. if (p && p.length > 0) {
  15. curvePoints = curvePoints.concat(p)
  16. }
  17. }
  18. return curvePoints
  19. }
  20. /**
  21. * Get a curvilinear coordinate set of points based on two points
  22. * @param obj1
  23. * @param obj2
  24. * @param count
  25. * @returns {null|[]}
  26. */
  27. function getCurveByTwoPoints(obj1, obj2, count) {
  28. if (!obj1 || !obj2) {
  29. return null
  30. }
  31. let curveCoordinates = []
  32. count = count || 40 // 曲线是由一些小的线段组成的,这个表示这个曲线所有到的折线的个数
  33. let B1 = function(x) {
  34. return 1 - 2 * x + x * x
  35. }
  36. let B2 = x => {
  37. return 2 * x - 2 * x * x
  38. }
  39. let B3 = x => {
  40. return x * x
  41. }
  42. let t, h, h2, lat3, lng3, t2
  43. let inc = 0
  44. let lat1 = parseFloat(obj1.lat)
  45. let lat2 = parseFloat(obj2.lat)
  46. let lng1 = parseFloat(obj1.lng)
  47. let lng2 = parseFloat(obj2.lng)
  48. // 计算曲线角度的方法
  49. if (lng2 > lng1) {
  50. if (lng2 - lng1 > 180) {
  51. if (lng1 < 0) {
  52. lng1 = 180 + 180 + lng1
  53. lng2 = 180 + 180 + lng2
  54. }
  55. }
  56. }
  57. // 此时纠正了 lng1 lng2
  58. t2 = 0
  59. // 纬度相同
  60. if (lat2 === lat1) {
  61. t = 0
  62. h = lng1 - lng2
  63. // 经度相同
  64. } else if (lng2 === lng1) {
  65. t = Math.PI / 2
  66. h = lat1 - lat2
  67. } else {
  68. t = Math.atan((lat2 - lat1) / (lng2 - lng1))
  69. h = (lat2 - lat1) / Math.sin(t)
  70. }
  71. if (t2 === 0) {
  72. t2 = t + Math.PI / 5
  73. }
  74. h2 = h / 2
  75. lng3 = h2 * Math.cos(t2) + lng1
  76. lat3 = h2 * Math.sin(t2) + lat1
  77. for (let i = 0; i < count + 1; i++) {
  78. let x = lng1 * B1(inc) + lng3 * B2(inc) + lng2 * B3(inc)
  79. let y = lat1 * B1(inc) + lat3 * B2(inc) + lat2 * B3(inc)
  80. let lng1_src = obj1.lng
  81. let lng2_src = obj2.lng
  82. curveCoordinates.push([lng1_src < 0 && lng2_src > 0 ? x - 360 : x, y])
  83. inc = inc + 1 / count
  84. }
  85. return curveCoordinates
  86. }