1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>轨迹移动</title>
    6. <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
    7. <link rel="stylesheet" href="https://js.arcgis.com/4.17/esri/themes/light/main.css"/>
    8. <script src="https://js.arcgis.com/4.17/"></script>
    9. </head>
    10. <style>
    11. html, body, #mapContainer {
    12. margin: 0px auto;
    13. padding: 0px;
    14. width: 100%;
    15. height: 100%;
    16. }
    17. .btn {
    18. position: absolute;
    19. top: 5%;
    20. right: 2%;
    21. }
    22. </style>
    23. <body>
    24. <div id="mapContainer"></div>
    25. <div class="btn">
    26. <button id="start">开始</button>
    27. <button id="pause">暂停</button>
    28. <button id="continue">继续</button>
    29. <button id="back">返回</button>
    30. </div>
    31. </body>
    32. <script>
    33. require([
    34. 'esri/Map',
    35. 'esri/views/MapView',
    36. 'esri/layers/FeatureLayer',
    37. 'esri/layers/GraphicsLayer',
    38. "esri/Graphic",
    39. "dojo/domReady!"
    40. ], function (Map, MapView, FeatureLayer, GraphicsLayer, Graphic) {
    41. var map = new Map({
    42. basemap: 'satellite'
    43. });
    44. var view = new MapView({
    45. container: 'mapContainer',
    46. center: [115.22908458010747, 32.636000827586614],
    47. zoom: 11,
    48. map: map
    49. });
    50. view.when(function () {
    51. view.on('click', function (evt) {
    52. console.log(evt)
    53. console.log(view)
    54. })
    55. })
    56. const polyline = {
    57. type: 'polyline',
    58. paths: [
    59. [115.21947154300005,32.735979284000052],
    60. [115.22809709000001, 32.746389426000064],
    61. [115.24980967100009, 32.749958617000061],
    62. [115.26616846600007, 32.749363752000079],
    63. [115.29739889100006, 32.74876888700004],
    64. [115.3241678280001, 32.746686858000032],
    65. [115.33398310400003, 32.737763880000045],
    66. [115.33130621100008, 32.713374404000035],
    67. [115.32089606900001, 32.699395071000026],
    68. [115.28279788700002, 32.69116676200008],
    69. [115.22660992600004, 32.703856560000077],
    70. [115.20162558600009, 32.705046291000031],
    71. [115.18913341600012, 32.69047209200005],
    72. [115.19567693300007, 32.66994924100004],
    73. [115.20251788400003, 32.66459545400005],
    74. [115.25516345900007, 32.657457071000067],
    75. [115.35809497600007, 32.659182180000073],
    76. [115.36332979000008, 32.647760767000079],
    77. [115.34572177900009, 32.639670600000045],
    78. [115.29622899000003, 32.63015275600003],
    79. [115.22056213000008, 32.633959893000053],
    80. [115.18344253800001, 32.62682151000007],
    81. [115.17154523300007, 32.603502792000029],
    82. [115.18058718500004, 32.583991212000058],
    83. [115.20628536400011, 32.575425152000037],
    84. [115.26719956500006, 32.575425152000037],
    85. [115.30669861800004, 32.574473368000042],
    86. [115.36095032900005, 32.584942997000041],
    87. [115.38807618500005, 32.611117068000055],
    88. [115.39664224400008, 32.630628648000027],
    89. [115.39664224400008, 32.673934838000037],
    90. [115.3885520770001, 32.702488370000026],
    91. [115.38093780200006, 32.755788297000038],
    92. [115.38046190900002, 32.77625166100006],
    93. [115.36190211400003, 32.794811457000037],
    94. [115.30527094200011, 32.808612331000063],
    95. [115.22436926700004, 32.809564115000057],
    96. [115.14489527000001, 32.793383781000045],
    97. [115.10254086400005, 32.760547219000046],
    98. [115.0863605290001, 32.727710657000046],
    99. [115.08160160700004, 32.694398203000048],
    100. [115.09207123500005, 32.64918844400006],
    101. [115.1030167560001, 32.631104540000024],
    102. [115.14584705400011, 32.64490541400005],
    103. [115.16250328100011, 32.635863462000032],
    104. [115.14203991700003, 32.610165283000072],
    105. [115.11538995300009, 32.588750134000065],
    106. [115.11824530700005, 32.558293033000041],
    107. [115.14299170100003, 32.537353776000032],
    108. [115.19533984300006, 32.530691286000035],
    109. [115.27433794900003, 32.530691286000035],
    110. [115.31526467800006, 32.544492159000072],
    111. [115.32716198300011, 32.579708182000047],
    112. [115.32145127600006, 32.61206885200005],
    113. [115.27528973300002, 32.623490265000044],
    114. [115.24340495500007, 32.632532217000062],
    115. [115.19914698100001, 32.657754503000035],
    116. [115.17154523300007, 32.674886623000077],
    117. [115.16821398800005, 32.684880359000033],
    118. [115.17344880200005, 32.701536586000032],
    119. [115.20485768700007, 32.714385675000074],
    120. [115.15393722200008, 32.741035639000074],
    121. [115.12395601300011, 32.727710657000046],
    122. [115.12205244400002, 32.71057853800005],
    123. [115.13918456300007, 32.711054430000047],
    124. [115.15917203600009, 32.722951735000038],
    125. [115.17297291000011, 32.739132070000039],
    126. [115.18820146000007, 32.74341510000005],
    127. [115.21947154300005, 32.735979284000052]
    128. ],
    129. // spatialReference: view.spatialReference
    130. }
    131. //初始化路线符号
    132. var lineSymbol = {
    133. type: 'cim',
    134. data: {
    135. type: 'CIMSymbolReference',
    136. symbol: {
    137. type: 'CIMLineSymbol',
    138. symbolLayers: [{
    139. //箭头符号
    140. type: 'CIMVectorMarker',
    141. enable: true,
    142. size: 4,
    143. markerPlacement: {
    144. type: 'CIMMarkerPlacementAlongLineSameSize',
    145. endings: 'WithMarkers',
    146. placementTemplate: [100] //箭头距离
    147. },
    148. frame: {
    149. xmin: -5,
    150. ymin: -5,
    151. xmax: 5,
    152. ymax: 5
    153. },
    154. //箭头图形
    155. markerGraphics: [{
    156. type: "CIMMarkerGraphic",
    157. geometry: {
    158. rings: [
    159. [
    160. [-8, -5.47],
    161. [-8, 5.6],
    162. [1.96, -0.03],
    163. [-8, -5.47]
    164. ]
    165. ]
    166. },
    167. symbol: {
    168. //箭头的颜色填充
    169. type: 'CIMPolygonSymbol',
    170. symbolLayers: [{
    171. type: 'CIMSolidFill',
    172. enable: true,
    173. color: [238, 238, 238, 255]
    174. }]
    175. }
    176. }]
    177. }, {
    178. //线符号
    179. type: 'CIMSolidStroke',
    180. enable: true,
    181. width: 3,
    182. color: [103, 165, 245, 255]
    183. }]
    184. }
    185. }
    186. }
    187. //已行驶的路线符号
    188. var lineSymboled = {
    189. type: 'cim',
    190. data: {
    191. type: 'CIMSymbolReference',
    192. symbol: {
    193. type: 'CIMLineSymbol',
    194. symbolLayers: [{
    195. //箭头符号
    196. type: 'CIMVectorMarker',
    197. enable: true,
    198. size: 4,
    199. markerPlacement: {
    200. type: 'CIMMarkerPlacementAlongLineSameSize',
    201. endings: 'WithMarkers',
    202. placementTemplate: [100] //箭头距离
    203. },
    204. frame: {
    205. xmin: -5,
    206. ymin: -5,
    207. xmax: 5,
    208. ymax: 5
    209. },
    210. //箭头图形
    211. markerGraphics: [{
    212. type: "CIMMarkerGraphic",
    213. geometry: {
    214. rings: [
    215. [
    216. [-8, -5.47],
    217. [-8, 5.6],
    218. [1.96, -0.03],
    219. [-8, -5.47]
    220. ]
    221. ]
    222. },
    223. symbol: {
    224. //箭头的颜色填充
    225. type: 'CIMPolygonSymbol',
    226. symbolLayers: [{
    227. type: 'CIMSolidFill',
    228. enable: true,
    229. color: [238, 238, 238, 255]
    230. }]
    231. }
    232. }]
    233. }, {
    234. //线符号
    235. type: 'CIMSolidStroke',
    236. enable: true,
    237. width: 3,
    238. color: [254, 166, 0, 255]
    239. }]
    240. }
    241. }
    242. }
    243. var lineLaye = new GraphicsLayer({
    244. id: 'lineLaye'
    245. })
    246. map.add(lineLaye);
    247. lineLaye.add(new Graphic({
    248. geometry: polyline,
    249. symbol: lineSymbol
    250. }));
    251. //已跑过的路线图层
    252. var lineLayed = new GraphicsLayer({
    253. id: 'lineLayed'
    254. })
    255. map.add(lineLayed);
    256. //创建起点
    257. var startP = {
    258. type: 'point',
    259. longitude: 115.21947154300005,
    260. latitude: 32.735979284000052
    261. }
    262. var startS = {
    263. type: 'picture-marker',
    264. url: 'http://47.110.79.226:8384/img/fj.png',
    265. width: '32px',
    266. height: '32px'
    267. }
    268. var moveLayer = new GraphicsLayer({
    269. id: 'moveLayer'
    270. })
    271. map.add(moveLayer);
    272. let moveGra = new Graphic({
    273. geometry: startP,
    274. symbol: startS
    275. });
    276. moveLayer.add(moveGra);
    277. var startNum, endNum, moving;
    278. function move(start, end) {
    279. let x1 = polyline.paths[start][0];
    280. let y1 = polyline.paths[start][1];
    281. let x2 = polyline.paths[end][0];
    282. let y2 = polyline.paths[end][1];
    283. //斜率
    284. let p = (y2 - y1) / (x2 - x1);
    285. //速度
    286. let v = 0.001;
    287. moving = setInterval(function () {
    288. startNum = start;
    289. endNum = end;
    290. //分别计算 x,y轴的方向和速度
    291. if (Math.abs(p) == Number.POSITIVE_INFINITY) {//垂直的时候斜率无穷大
    292. moveGra.geometry.y += v;
    293. } else {
    294. if (x2 < x1) {
    295. moveGra.geometry.x -= (1 / Math.sqrt(1 + p * p)) * v;
    296. moveGra.geometry.y -= (p / Math.sqrt(1 + p * p)) * v;
    297. //计算角度
    298. moveGra.symbol.angle = calcAngle(x1, y1, x2, y2);//(Math.PI / 2 - Math.atan(p)) * 180 / Math.PI+180
    299. } else {
    300. moveGra.geometry.x += (1 / Math.sqrt(1 + p * p)) * v;
    301. moveGra.geometry.y += (p / Math.sqrt(1 + p * p)) * v;
    302. //计算角度
    303. moveGra.symbol.angle = calcAngle(x1, y1, x2, y2);
    304. }
    305. }
    306. //重新绘制
    307. moveLayer.add(moveGra);
    308. //画线
    309. if(start==0){
    310. addLineSYmboled(0);
    311. }else{
    312. addLineSYmboled(end);
    313. }
    314. console.log(Math.abs(moveGra.geometry.x - x2))
    315. if (Math.abs(moveGra.geometry.x - x2) <= v && Math.abs(moveGra.geometry.y - y2) <= v) {
    316. clearInterval(moving);
    317. startNum = start++;
    318. endNum = end++;
    319. if (end < polyline.paths.length) {
    320. move(start, end);
    321. }
    322. }
    323. }, 50)
    324. }
    325. function calcAngle(x1, y1, x2, y2) {
    326. let tan = Math.atan(Math.abs((y2 - y1) / (x2 - x1))) * 180 / Math.PI + 90;
    327. if (x2 > x1 && y2 > y1) {
    328. return -tan + 180;
    329. } else if (x2 > x1 && y2 < y1) {
    330. return tan;
    331. } else if (x2 < x1 && y2 > y1) {
    332. return tan - 180;
    333. } else {
    334. return -tan;
    335. }
    336. }
    337. function addLineSYmboled(end) {
    338. lineLayed.removeAll();
    339. let path=null;
    340. if(end==0){
    341. path = polyline.paths.slice(0, 1);
    342. }else{
    343. path = polyline.paths.slice(0, end);
    344. }
    345. path.push(
    346. [moveGra.geometry.x,moveGra.geometry.y]
    347. )
    348. let polylined = {
    349. type: 'polyline',
    350. paths:path,
    351. // spatialReference: view.spatialReference
    352. };
    353. lineLayed.add(new Graphic({
    354. geometry: polylined,
    355. symbol: lineSymboled
    356. }));
    357. }
    358. $(':button').click(function () {
    359. let value = $(this).attr('id');
    360. switch (value) {
    361. case 'start': {
    362. //开始
    363. if (moving != undefined) {
    364. clearInterval(moving); //清除移动
    365. }
    366. moveGra.geometry = startP;
    367. console.log(moveGra.geometry)
    368. move(0, 1);
    369. lineLayed.removeAll();
    370. break;
    371. }
    372. case 'pause': {
    373. //暂停
    374. clearInterval(moving);
    375. break;
    376. }
    377. case 'continue': {
    378. if (moving != undefined) {
    379. clearInterval(moving); //清除移动
    380. }
    381. move(startNum, endNum);
    382. break;
    383. }
    384. case'back' : {
    385. if (moving != undefined) {
    386. clearInterval(moving); //清除移动
    387. }
    388. lineLayed.removeAll();
    389. moveGra.geometry = startP;
    390. moveGra.symbol.angle = 0;
    391. break;
    392. }
    393. }
    394. })
    395. })
    396. </script>
    397. </html>