navto.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <template>
  2. <view class="container">
  3. <map
  4. id="map"
  5. class="map"
  6. :latitude="querys.latitude"
  7. :longitude="querys.longitude"
  8. :polyline="polyline"
  9. :markers="markers"
  10. scale="15"
  11. show-compass
  12. show-traffic
  13. show-locate
  14. >
  15. </map>
  16. <cover-view class="map-info">
  17. <cover-view class="title">{{ distance }}</cover-view>
  18. <cover-view class="sub-title">{{ taxi_cost }}</cover-view>
  19. <cover-view class="go" @click="goSystem">其他导航</cover-view>
  20. </cover-view>
  21. </view>
  22. </template>
  23. <script setup lang="ts">
  24. import { showError } from '@/common/composeabe/ErrorDisplay';
  25. import { useLoadQuerys } from '@/common/composeabe/LoadQuerys';
  26. import AppCofig from '@/common/config/AppCofig';
  27. import { back } from '@/common/utils/PageAction';
  28. import { ref } from 'vue';
  29. import amapFile from '@/libs/amap-wx.130';
  30. import { toast } from '@/common/utils/DialogAction';
  31. const mapCtx = uni.createMapContext('map');
  32. const polyline = ref();
  33. const markers = ref();
  34. const distance = ref('');
  35. const taxi_cost = ref('');
  36. const { querys } = useLoadQuerys({
  37. latitude: 0,
  38. longitude: 0,
  39. }, async (querys) => {
  40. uni.showLoading({ title: '加载中...' });
  41. try {
  42. if (querys.latitude == 0 || querys.longitude == 0) {
  43. throw new Error('传入参数不正确');
  44. }
  45. const curretLocation = await new Promise<{ latitude: number, longitude: number }>((resolve, reject) => {
  46. uni.getLocation({
  47. type: 'gcj02',
  48. success: function(res) {
  49. const latitude = res.latitude;
  50. const longitude = res.longitude;
  51. resolve({ latitude, longitude });
  52. },
  53. fail: (err) => {
  54. let message = err.errMsg
  55. if (err.errMsg.includes('auth deny')) {
  56. message = '请允许定位后,才能为您导航哦';
  57. } else if (err.errMsg.includes('location service off')) {
  58. message = '请未开启定位服务,才能为您导航哦';
  59. }
  60. reject(message);
  61. },
  62. })
  63. })
  64. markers.value = [
  65. {
  66. id: 1,
  67. latitude: querys.latitude,
  68. longitude: querys.longitude,
  69. iconPath: '/static/images/icon_marker.png',
  70. width: 40,
  71. height: 40,
  72. },
  73. {
  74. id: 2,
  75. latitude: curretLocation.latitude,
  76. longitude: curretLocation.longitude,
  77. iconPath: '/static/images/icon_marker2.png',
  78. width: 50,
  79. height: 50,
  80. }
  81. ];
  82. function colorTrans(color1: number[], color2: number[], pec: number) {
  83. return [
  84. Math.round(color1[0] + (color2[0] - color1[0]) * pec),
  85. Math.round(color1[1] + (color2[1] - color1[1]) * pec),
  86. Math.round(color1[2] + (color2[2] - color1[2]) * pec),
  87. ]
  88. }
  89. polyline.value = await new Promise((resolve, reject) => {
  90. const color1 = [223, 53, 51];
  91. const color2 = [0, 145, 255];
  92. const myAmapFun = new amapFile.AMapWX({key: AppCofig.amapKey});
  93. myAmapFun.getDrivingRoute({
  94. origin: `${curretLocation.longitude.toFixed(5)},${curretLocation.latitude.toFixed(5)}`,
  95. destination: `${querys.longitude.toFixed(5)},${querys.latitude.toFixed(5)}`,
  96. nosteps: 1,
  97. success: function(data: any){
  98. let points = [];
  99. let colorList : string[] = [];
  100. if(data.paths && data.paths[0] && data.paths[0].steps){
  101. var steps = data.paths[0].steps;
  102. for(var i = 0; i < steps.length; i++){
  103. var poLen = steps[i].polyline.split(';');
  104. for(var j = 0;j < poLen.length; j++){
  105. points.push({
  106. longitude: parseFloat(poLen[j].split(',')[0]),
  107. latitude: parseFloat(poLen[j].split(',')[1])
  108. })
  109. }
  110. }
  111. }
  112. for (let j = 0; j < points.length; j++) {
  113. colorList.push('rgb(' + colorTrans(color1, color2, j / points.length).join(',') + ')');
  114. }
  115. distance.value = '距离您约 ' + formatMeter(data.paths[0].distance) + '米'
  116. taxi_cost.value = '打车约' + parseInt(data.taxi_cost) + '元'
  117. resolve([{
  118. points: points,
  119. color: "#0091ff",
  120. colorList: colorList,
  121. width: 6
  122. }]);
  123. },
  124. fail: function(info: any) {
  125. reject('路线规划失败:' + info);
  126. }
  127. })
  128. });
  129. mapCtx.includePoints({
  130. points: [
  131. { latitude: querys.latitude, longitude: querys.longitude },
  132. { latitude: curretLocation.latitude, longitude: curretLocation.longitude }
  133. ],
  134. padding: [20, 20, 20, 20],
  135. });
  136. } catch (e) {
  137. showError(e, undefined, () => back());
  138. } finally {
  139. uni.hideLoading();
  140. }
  141. });
  142. function goSystem() {
  143. uni.openLocation({
  144. latitude: querys.value.latitude,
  145. longitude: querys.value.longitude,
  146. scale: 15,
  147. name: '目标位置',
  148. success() {},
  149. fail(error) {
  150. toast('导航启动失败');
  151. },
  152. });
  153. }
  154. function formatMeter(n: number) {
  155. if (n > 1000) {
  156. return (n / 1000).toFixed(1) + '千';
  157. }
  158. return n + '';
  159. }
  160. </script>
  161. <style lang="scss">
  162. .container {
  163. position: relative;
  164. display: flex;
  165. flex-direction: column;
  166. height: 100vh;
  167. padding-bottom: 0;
  168. #map {
  169. width: 100%;
  170. height: 100%;
  171. }
  172. .map-info {
  173. position: absolute;
  174. bottom: 50px;
  175. left: 40rpx;
  176. right: 40rpx;
  177. display: flex;
  178. flex-direction: column;
  179. background-color: #fff;
  180. border-radius: 8px;
  181. padding: 20rpx;
  182. box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  183. .title {
  184. font-size: 34rpx;
  185. font-weight: bold;
  186. color: #333;
  187. }
  188. .sub-title {
  189. font-size: 26rpx;
  190. margin-top: 10rpx;
  191. color: #666;
  192. }
  193. .go {
  194. position: absolute;
  195. padding: 15rpx;
  196. background-color: #bdbdbd;
  197. border-radius: 10rpx;
  198. top: 50%;
  199. right: 20rpx;
  200. transform: translateY(-50%);
  201. }
  202. }
  203. }
  204. </style>