map.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. if(this.markers.length>0){
  75. this.onCalculateDistance() // 计算距离
  76. }
  77. }
  78. })
  79. },
  80. // 将所有标注点与当前位置进行距离计算
  81. onCalculateDistance(){
  82. const _this = this
  83. const startPos = { latitude: _this.latitude, longitude: _this.longitude }
  84. let destPos = []
  85. _this.markers.map(item => {
  86. destPos.push({ latitude: item.latitude, longitude: item.longitude })
  87. })
  88. //调用距离计算接口
  89. qqmapsdk.calculateDistance({
  90. mode: 'driving', //可选值:'driving'(驾车)、'walking'(步行),不填默认:'walking',可不填
  91. //from参数不填默认当前地址
  92. //获取表单提交的经纬度并设置from和to参数(示例为string格式)
  93. from: startPos, //若起点有数据则采用起点坐标,若为空默认当前地址
  94. to: destPos, //终点坐标
  95. success: function(res) {//成功后的回调
  96. var res = res.result
  97. _this.distanceMark = []
  98. for (var i = 0; i < res.elements.length; i++) {
  99. // 将距离值加入标注点信息中
  100. _this.distanceMark.push({
  101. latitude: res.elements[i].to.lat,
  102. longitude: res.elements[i].to.lng,
  103. distance: res.elements[i].distance
  104. })
  105. }
  106. // 数组升序排序
  107. _this.distanceMark.sort(_this.compare( 'distance', true ))
  108. _this.onDirection() // 路线规划
  109. },
  110. fail: function(error) {
  111. console.error(error)
  112. },
  113. complete: function(res) {
  114. // console.log(res)
  115. }
  116. })
  117. },
  118. // 数组排序
  119. compare(property, desc){
  120. return function (a, b) {
  121. var value1 = a[property]
  122. var value2 = b[property]
  123. if(desc==true){ // 升序排列
  124. return value1 - value2
  125. }else{ // 降序排列
  126. return value2 - value1
  127. }
  128. }
  129. },
  130. // 路线规划
  131. onDirection(){
  132. const _this = this
  133. _this.polyline = []
  134. // 将所有标注点都按距离进行路线规划
  135. _this.distanceMark.map((item,index) => {
  136. var position = null
  137. if(index==0){
  138. position = [
  139. { latitude: _this.latitude, longitude: _this.longitude },
  140. { latitude: item.latitude, longitude: item.longitude }
  141. ]
  142. // 当前位置到第一个标注点的路线规划
  143. _this.getDirection(position)
  144. }else{
  145. position = [
  146. { latitude: _this.distanceMark[index-1].latitude, longitude: _this.distanceMark[index-1].longitude },
  147. { latitude: item.latitude, longitude: item.longitude }
  148. ]
  149. // 第index-1个标注点到第index个标注点的路线规划
  150. _this.getDirection(position)
  151. }
  152. })
  153. },
  154. // 路线规划
  155. getDirection(position){
  156. const _this = this
  157. qqmapsdk.direction({
  158. mode: 'driving',//可选值:'driving'(驾车)、'walking'(步行)、'bicycling'(骑行),不填默认:'driving',可不填
  159. //from参数不填默认当前地址
  160. from: {
  161. latitude: position[0].latitude,
  162. longitude: position[0].longitude
  163. },
  164. to: {
  165. latitude: position[1].latitude,
  166. longitude: position[1].longitude
  167. },
  168. success: function (res) {
  169. var ret = res
  170. var coors = ret.result.routes[0].polyline, pl = []
  171. //坐标解压(返回的点串坐标,通过前向差分进行压缩)
  172. var kr = 1000000
  173. for (var i = 2; i < coors.length; i++) {
  174. coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr;
  175. }
  176. //将解压后的坐标放入点串数组pl中
  177. for (var i = 0; i < coors.length; i += 2) {
  178. pl.push({ latitude: coors[i], longitude: coors[i + 1] })
  179. }
  180. //设置polyline属性,将路线显示出来,将解压坐标第一个数据作为起点
  181. _this.polyline.push({
  182. points: pl,
  183. arrowLine: true,
  184. width: 8,
  185. color: '#07c160'
  186. })
  187. },
  188. fail: function (error) {
  189. console.error(error)
  190. },
  191. complete: function (res) {
  192. // console.log(res)
  193. }
  194. })
  195. },
  196. // 点击标注点,调用第三方地图查看规划路线
  197. markertap(e){
  198. this.markers.map(item => {
  199. if(item.id == e.detail.markerId){
  200. uni.openLocation({
  201. latitude: item.latitude,
  202. longitude: item.longitude,
  203. success: function () {
  204. }
  205. })
  206. }
  207. })
  208. }
  209. }
  210. }
  211. </script>
  212. <style lang="scss" scoped>
  213. .map-container {
  214. width: 100%;
  215. height: 100vh;
  216. }
  217. </style>