map.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <template>
  2. <view class="map-container">
  3. <map
  4. id="map"
  5. :latitude="latitude"
  6. :longitude="longitude"
  7. scale="12"
  8. show-compass
  9. show-location
  10. :markers="markers"
  11. :polyline="polyline"
  12. @markertap="markertap"
  13. style="width: 100%; height:100%;">
  14. </map>
  15. </view>
  16. </template>
  17. <script>
  18. import { getCleanWay } from '@/api/unclear.js'
  19. var QQMapWX = require('@/libs/qqmap-wx-jssdk.min.js')
  20. var qqmapsdk
  21. export default{
  22. data(){
  23. return{
  24. latitude: null, // 纬度
  25. longitude: null, // 经度
  26. markers: [], // 所有网点标注点
  27. distanceMark: [], // 按距离计算远近后的网点标注点
  28. polyline: null, // 路线
  29. }
  30. },
  31. onLoad() {
  32. // 实例化API核心类
  33. qqmapsdk = new QQMapWX({
  34. key: 'FRCBZ-IDZWW-FGDRR-O3SQM-ZW5C2-LRBDM'
  35. })
  36. },
  37. onShow() {
  38. this.getLocation()
  39. },
  40. methods: {
  41. // 获取当前位置
  42. getLocation(){
  43. const _this = this
  44. uni.getLocation({
  45. type: 'gcj02',
  46. success: function (res) {
  47. _this.latitude = res.latitude // 纬度
  48. _this.longitude = res.longitude // 经度
  49. _this.getCleanWay() // 获取个人待清运清单
  50. }
  51. })
  52. },
  53. // 标注点信息
  54. getCleanWay(){
  55. getCleanWay({ lng: this.longitude, lat: this.latitude }).then(res => {
  56. if(res.status == 200){
  57. this.markers = []
  58. res.data.map((item, index) => {
  59. if(item.lat && item.lng){
  60. this.markers.push({
  61. id: index+1,
  62. latitude: item.lat,
  63. longitude: item.lng,
  64. width: '60rpx',
  65. height: '60rpx',
  66. iconPath: '/static/store.png',
  67. label: {
  68. content: item.stationName || '--',
  69. bgColor: '#fff',
  70. }
  71. })
  72. }
  73. })
  74. this.onCalculateDistance() // 计算距离
  75. }
  76. })
  77. },
  78. // 将所有标注点与当前位置进行距离计算
  79. onCalculateDistance(){
  80. const _this = this
  81. const startPos = { latitude: _this.latitude, longitude: _this.longitude }
  82. let destPos = []
  83. _this.markers.map(item => {
  84. destPos.push({ latitude: item.latitude, longitude: item.longitude })
  85. })
  86. //调用距离计算接口
  87. qqmapsdk.calculateDistance({
  88. mode: 'driving', //可选值:'driving'(驾车)、'walking'(步行),不填默认:'walking',可不填
  89. //from参数不填默认当前地址
  90. //获取表单提交的经纬度并设置from和to参数(示例为string格式)
  91. from: startPos, //若起点有数据则采用起点坐标,若为空默认当前地址
  92. to: destPos, //终点坐标
  93. success: function(res) {//成功后的回调
  94. var res = res.result
  95. _this.distanceMark = []
  96. for (var i = 0; i < res.elements.length; i++) {
  97. // 将距离值加入标注点信息中
  98. _this.distanceMark.push({
  99. latitude: res.elements[i].to.lat,
  100. longitude: res.elements[i].to.lng,
  101. distance: res.elements[i].distance
  102. })
  103. }
  104. // 数组升序排序
  105. _this.distanceMark.sort(_this.compare( 'distance', true ))
  106. _this.onDirection() // 路线规划
  107. },
  108. fail: function(error) {
  109. console.error(error)
  110. },
  111. complete: function(res) {
  112. // console.log(res)
  113. }
  114. })
  115. },
  116. // 数组排序
  117. compare(property, desc){
  118. return function (a, b) {
  119. var value1 = a[property]
  120. var value2 = b[property]
  121. if(desc==true){ // 升序排列
  122. return value1 - value2
  123. }else{ // 降序排列
  124. return value2 - value1
  125. }
  126. }
  127. },
  128. // 路线规划
  129. onDirection(){
  130. const _this = this
  131. _this.polyline = []
  132. // 将所有标注点都按距离进行路线规划
  133. _this.distanceMark.map((item,index) => {
  134. var position = null
  135. if(index==0){
  136. position = [
  137. { latitude: _this.latitude, longitude: _this.longitude },
  138. { latitude: item.latitude, longitude: item.longitude }
  139. ]
  140. // 当前位置到第一个标注点的路线规划
  141. _this.getDirection(position)
  142. }else{
  143. position = [
  144. { latitude: _this.distanceMark[index-1].latitude, longitude: _this.distanceMark[index-1].longitude },
  145. { latitude: item.latitude, longitude: item.longitude }
  146. ]
  147. // 第index-1个标注点到第index个标注点的路线规划
  148. _this.getDirection(position)
  149. }
  150. })
  151. },
  152. // 路线规划
  153. getDirection(position){
  154. const _this = this
  155. qqmapsdk.direction({
  156. mode: 'driving',//可选值:'driving'(驾车)、'walking'(步行)、'bicycling'(骑行),不填默认:'driving',可不填
  157. //from参数不填默认当前地址
  158. from: {
  159. latitude: position[0].latitude,
  160. longitude: position[0].longitude
  161. },
  162. to: {
  163. latitude: position[1].latitude,
  164. longitude: position[1].longitude
  165. },
  166. success: function (res) {
  167. var ret = res
  168. var coors = ret.result.routes[0].polyline, pl = []
  169. //坐标解压(返回的点串坐标,通过前向差分进行压缩)
  170. var kr = 1000000
  171. for (var i = 2; i < coors.length; i++) {
  172. coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr;
  173. }
  174. //将解压后的坐标放入点串数组pl中
  175. for (var i = 0; i < coors.length; i += 2) {
  176. pl.push({ latitude: coors[i], longitude: coors[i + 1] })
  177. }
  178. //设置polyline属性,将路线显示出来,将解压坐标第一个数据作为起点
  179. _this.polyline.push({
  180. points: pl,
  181. arrowLine: true,
  182. width: 8,
  183. color: '#07c160'
  184. })
  185. },
  186. fail: function (error) {
  187. console.error(error)
  188. },
  189. complete: function (res) {
  190. // console.log(res)
  191. }
  192. })
  193. },
  194. // 点击标注点,调用第三方地图查看规划路线
  195. markertap(e){
  196. this.markers.map(item => {
  197. if(item.id == e.detail.markerId){
  198. uni.openLocation({
  199. latitude: item.latitude,
  200. longitude: item.longitude,
  201. success: function () {
  202. }
  203. })
  204. }
  205. })
  206. }
  207. }
  208. }
  209. </script>
  210. <style lang="scss" scoped>
  211. .map-container {
  212. width: 100%;
  213. height: 100vh;
  214. }
  215. </style>