<template> <view> <!-- <image src="../../static/img/fj-qp.png" mode=" widthFix"></image> --> <addressSelector @closeFooterScroll='closeFooterScroll' ref='addressSelector' @mapEventListeners='mapEventListeners' :polyline="polyline" :Route="Route" /> <footerScroll @closeAddressSelector='closeAddressSelector' @openMapApp='openMapApp' ref='footerScroll' :selePrice='selePrice' @dragMap='dragMap' :details='details' :polyline="polyline" @mapEventListeners='mapEventListeners' :markers="markers" /> <view class="map_body"> <map @tap='poitap' @updated='mapUpdated' :scale='mapScale' @callouttap='callouttap' :enable-scroll='enableScroll' @markertap='markertap' :polyline="polyline" subkey="UTXBZ-BUH6D-TQD44-HCEG4-UKOFT-U2BDN" layer-style='2' id="map_Id" :show-location="true" :markers="markers" class="map_xx" :latitude="coordinate.latitude" :longitude="coordinate.longitude"> <cover-view slot="callout"> <cover-view v-for="(item,index) in markers" :key='index' class="customCallout" :marker-id="item.id"> <cover-image style="width: 150rpx;height: 78rpx;position: absolute;" :src="item.imgCustomCallout"> </cover-image> <cover-view class="customCallout_text">{{moneyIntercept(item.enterprisePrice) }}</cover-view> </cover-view> </cover-view> </map> </view> </view> </template> <script> import amapFile from '@/utils/qqmap-wx-jssdk.js' import addressSelector from './components/addressSelector.vue' import footerScroll from './components/footerScroll.vue' import oilSiteApi from '../../../api/oil-site.js' export default { components: { addressSelector, footerScroll }, /* * @property {Object} coordinate:当前位置坐标点 * @property {Object} markers:marker点 * @property {Object} Route:路线规划 起点,终点 起点默认我的位置 * @property {Array} polyline:路线 * @property {Function} amapFile || TXSDK :腾讯SDK实例 * @property {Function} mapContext:地图组件控制器 */ data() { return { myLocation: null, TXSDK: null, polyline: [], //路线规划 起点终点数据 //起点默认是我的位置 Route: { start: { longitude: '', latitude: '', title: '' }, midwayPointList: [], //途径点list end: { longitude: '', latitude: '', title: '' } }, enableScroll: true, coordinate: { longitude: '', latitude: '', title: '我的位置' }, markers: [], mapContext: null, details: {}, spareMarkers: [], selePrice: null, mapScale: 16, firstLocation: {} } }, onLoad(e) { this.initFn() }, created() { this.TXSDK = new amapFile({ key: 'UTXBZ-BUH6D-TQD44-HCEG4-UKOFT-U2BDN' }); }, watch: { enableScroll: function(n, o) { console.log('全局是否可拖动', n) } }, methods: { //监听更新位置事件 UpdateAddress() { let that = this uni.$on('UpdateAddress', (region, type, currentMidwayIndex, midwayPointList) => { if (type === 'midwayPoint') { let list = JSON.parse(midwayPointList) list[currentMidwayIndex].longitude = region.location.lng list[currentMidwayIndex].latitude = region.location.lat list[currentMidwayIndex].title = region.title; let addressSelector = this.$refs.addressSelector addressSelector.midwayPointList[currentMidwayIndex].longitude = region.location.lng addressSelector.midwayPointList[currentMidwayIndex].latitude = region.location.lat addressSelector.midwayPointList[currentMidwayIndex].title = region.title; this.Route.midwayPointList = list } else { this.Route[type].longitude = region.location.lng; this.Route[type].latitude = region.location.lat; this.Route[type].title = region.title; } this.Route['midwayPointList'].forEach((item, index) => { if (!item.longitude || !item.latitude) { this.$refs.addressSelector.midwayPointList.splice(index, 1) this.Route.midwayPointList.splice(index, 1) } }) this.mapEventListeners('updateRoute', this.Route.start, this.Route.end) this.mapEventListeners('UpdateLocation', this.Route, 'lately') }) }, passiveRedraw(midwayPointList) { this.Route.midwayPointList = midwayPointList this.mapEventListeners('updateRoute') }, perspectives(item) { let { latitude, longitude, siteId } = item setTimeout(() => { this.newMapMoveToLocation(longitude, latitude, 'reset') }, 500) }, mapUpdated(e) { this.mapContext.getScale({ success: function(e) { console.log('地图渲染回调,当前缩放系数:', e) } }) }, //初始化方法 initFn() { this.mapContext = uni.createMapContext("map_Id", this); this.getCurrentLocation(); this.UpdateAddress(); }, //地图更新事件监听 分发事件 async mapEventListeners(e) { switch (e) { case 'updateRoute': this.mapRoutePlanning(arguments[1] ? arguments[1] : this.Route.start, arguments[2] ? arguments[ 2] : this.Route.end, arguments[3] ? arguments[3] : 'LEAST_TIME') break; case 'UpdateLocation': this.UpdateLocation(arguments[1], arguments[2]) break; case 'cardPlanning': this.Route = arguments[1] this.mapRoutePlanning() break; case 'details': // this.details.a = 1 ; let d = arguments[1] this.details = d; this.newMapMoveToLocation(this.details.longitude, this.details.latitude) break; case 'apiScreen': //接口更新站点 let { oilProductCode, juLi, siteChannel } = arguments[1]; let markerList = await this.mapUpdateMarkers(this.polyline[2].points, oilProductCode, juLi, siteChannel); //处理站点数据回显 this.spareMarkers = this.locationProcessing(markerList); this.markers = await this.filterMarkers(JSON.parse(JSON.stringify(this.spareMarkers))); this.mapScale = 10 break; case 'localScreen': // 手动筛选 备份下数据 let markers = JSON.parse(JSON.stringify(this.spareMarkers)); this.markers = await this.filterMarkers(markers); /* 老版更新价格 this.markers = await this.filterMarkers(markers); if (arguments[1] !== 'footer') { if(filterData.highSpeed=='2'){ console.log('全部',this.spareMarkers) this.markers = JSON.parse(JSON.stringify(this.spareMarkers)) } let sort = this.markers.sort((a, b) => { return a.enterprisePrice - b.enterprisePrice }); console.log(sort,'排序之后的价格') if (sort.length !== 0) { this.selePrice = { middlePrice: sort[Number.isInteger((sort.length / 2)) ? (sort .length / 2) : ((sort.length + 1) / 2) - 1] .enterprisePrice, minPrice: sort[0].enterprisePrice } } else { this.selePrice = {} } }; setTimeout(()=>{ console.log('调整之后的价格',this.selePrice,arguments[1]!=='footer'); this.markers = this.filterMarkers(this.markers,this.$refs.footerScroll.filter()); },0) */ break; case 'MoveToLocation': arguments[1] ? (this.newMapMoveToLocation(this.Route.start.longitude, this.Route.start .latitude, 'MoveToLocation')) : (this.zoomRoutePlanning()); break; case 'reset': this.newMapMoveToLocation(this.myLocation.longitude, this.myLocation.latitude, 'reset') break; } }, closeFooterScroll() { this.$refs.footerScroll.screenClose(); this.$refs.footerScroll.mapIconClose(); }, // 更新路线规划 async mapRoutePlanning(start = this.Route.start, end = this.Route.end, strategy = 'LEAST_TIME') { // 获取路径 await this.routePlanning(start, end) // let res = await this.getMapRoutePlanning(start, end); //处理数据 // this.polyline = this.RoutePlanningHandle(res); //缩放显示所有经纬度 this.zoomRoutePlanning(); // 获取筛选数据 更新油站站点 let { oilProductCode, juLi, siteChannel } = this.$refs.addressSelector.datassFn(); let markerList = await this.mapUpdateMarkers(this.polyline[2].points, oilProductCode, juLi, siteChannel); //处理油站站点数据并显示 this.spareMarkers = this.locationProcessing(markerList); let markers = JSON.parse(JSON.stringify(this.spareMarkers)); this.markers = await this.filterMarkers(markers); }, // 更新最近搜索 UpdateLocation(Route, type) { let recentSearch = uni.getStorageSync('recentSearch') || []; let data = { ...Route, type: type, id: `${Route.start.latitude}${Route.start.longitude}${Route.end.latitude}${Route.end.longitude}` }; let key = recentSearch.map((item) => item.id); if (!key.includes(data.id)) { recentSearch.length !== 0 ? recentSearch[0].type == 'lately' ? recentSearch.splice(0, 1, data) : recentSearch.unshift(data) : recentSearch.push(data); uni.setStorageSync('recentSearch', recentSearch); } }, //。。。。。。 closeAddressSelector() { this.$refs.addressSelector.menuList.forEach(item => item.SublistOpen = false); }, //拉起导航 openMapApp() { let that = this wx.openLocation({ latitude: that.details.latitude, // 纬度 longitude: that.details.longitude, // 经度 name: that.details.siteName, // 地址名称 address: that.details.siteName, // 详细地址 success: function(r) { console.log(r) }, fail: function(res) { console.log('拉起失败啦', res) } }) }, //获取路线规划 getMapRoutePlanning(start, end) { // this.routePlanning(start, end) let { seleIndex } = this.$refs.footerScroll.$data var _this = this; return new Promise(function(res, rej) { _this.TXSDK.direction({ sig: 'mOPvEv4WmyaxymycTYy00pSiad2jnQil', mode: 'driving', from: start, to: end, policy: seleIndex || 'LEAST_TIME', success: function(e) { res(e) }, fail(e) { setTimeout(() => { uni.showToast({ title: e.msg, icon: "none" }); }, 1000) rej(e) } }) }) }, routePlanning(start, end) { let threeLines = [] let { seleIndex } = this.$refs.footerScroll.$data let waypoints = '' if (this.Route.midwayPointList.length) { this.Route.midwayPointList.forEach(item => { waypoints += `${waypoints.length ? ';' : ''}${item.latitude},${item.longitude}` }) } let _transfer = (policy) => { return new Promise((resolve, reject) => { this.TXSDK.direction({ sig: 'mOPvEv4WmyaxymycTYy00pSiad2jnQil', mode: 'driving', from: start, to: end, waypoints: waypoints, policy: policy, success: res => { resolve(res) } }) }) } let map = { // 顺序会影响线层叠关系,越往后层级越高 'LEAST_TIME': [1, 2, 0], 'LEAST_FEE': [0, 2, 1], 'AVOID_HIGHWAY': [0, 1, 2] } return Promise.all([_transfer('LEAST_TIME'), _transfer('LEAST_FEE'), _transfer('AVOID_HIGHWAY')]) .then(res => { let currentMap = map[seleIndex] currentMap.forEach((item, index) => { let currentRes = res[item] let [result] = this.RoutePlanningHandle(currentRes) if (index == 2) { result.color = '#FF6700' } else { result.color = '#00BFFF' } threeLines.push(result) }) this.polyline = threeLines }) }, //获取到的路线规划数据进行处理 RoutePlanningHandle(res) { let coors = res.result.routes[0].polyline let pl = []; //坐标解压(该方法为官方文档提供) let kr = 1000000; for (let i = 2; i < coors.length; i++) { coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr; } for (let i = 0; i < coors.length; i += 2) { pl.push({ latitude: coors[i], longitude: coors[i + 1], lat: coors[i], lon: coors[i + 1] }) } //设置polyline属性,将路线显示出来,将解压坐标第一个数据作为起点 return [{ points: pl, color: '#FF6700', width: 5, distance: res.result.routes[0].distance }] }, /* 缩放路线规划 includePoints方法 points:经纬度数组 padding:边距 参考 https://uniapp.dcloud.io/api/location/map?id=cdreatemapcontext */ zoomRoutePlanning(points, padding) { let that = this let system = uni.getSystemInfoSync().platform; try { let paddingTop = this.$refs.addressSelector.getElement(); this.mapContext.includePoints({ points: points ? points : that.polyline[0].points, padding: system == 'ios' ? [paddingTop + 90, 30, 150, 30] : [paddingTop - 25, 30, 50, 30], // padding: padding ? padding : [50, 10, 50, 10], success: function(e) {} }) } catch (e) { uni.showToast({ title: e, icon: 'none' }) //TODO handle the exception } }, // 点击地图 poitap() { if (this.polyline.length == 0) return; this.$refs.footerScroll.isShow.screen = true; this.$refs.footerScroll.isShow.serviceStation = false; this.enableScroll = true; this.$refs.addressSelector.menuList.forEach(item => item.SublistOpen = false); this.$refs.footerScroll.screenClose(); this.$refs.footerScroll.mapIconClose(); this.details = null; console.log('点击地图') }, //更新markers点 async mapUpdateMarkers(points = this.polyline[2].points, oilProductCode = '0#', juLi = '5', siteChannel = '') { //标记 let { latitude, longitude } = this.firstLocation let data = { geoList: points, oilProductCode: oilProductCode ? oilProductCode : '0#', juLi: juLi ? juLi : '5', siteChannel: siteChannel, countJuLi: points[0].distance, latitude: latitude || this.coordinate.latitude, longitude: longitude || this.coordinate.longitude } // let taht = this; return new Promise((re, rj) => { oilSiteApi.getSiteByGeoHashNew(data).then(markerList => { if (markerList.code !== 20000) { setTimeout(() => { uni.showToast({ title: 'Error' + markerList.code + markerList.msg, icon: 'none' }) }, 500) rj(markerList.code + markerList.msg) return } this.selePrice = { middlePrice: markerList.data.middlePrice, minPrice: markerList.data.minPrice } re(markerList.data.siteGeoVoList) }) }) }, //定位处理 locationProcessing(markerList) { markerList.forEach((item, index) => { let configure = { siteId: item.id, id: Number(`${index}`), //2023.08.30 在此处踩坑 一作这b竟然把id重新赋值了。 一作:去好好查一下官网的MAP中的marker的文档 id字段的注意事项,再看一下后台给的id, 补补课 imgCustomCallout: this.olitype(item.siteChannel), iconPath: '../../static/img/tt.png', width: 5, height: 5, customCallout: { anchorX: 0, anchorY: 8, display: "ALWAYS" } } item = Object.assign(item, configure) }); return markerList }, //地图组件控件 assembly() {}, //点击气泡事件 async callouttap(e) { let seleMark = this.markers.filter(item => item.id == e.detail.markerId); let details = await oilSiteApi.getSiteDetails({ latitude: String(this.firstLocation.latitude), longitude: String(this.firstLocation.longitude), siteId: seleMark[0].siteId }); if (details.code !== 20000) { uni.showToast({ title: details.msg, icon: 'none' }) return } this.mapEventListeners('details', Object.assign(details.data, { id: seleMark[0].siteId })) }, //点击定位点事件 markertap(e) { console.log('点击了markertap') }, //获取当前位置 getCurrentLocation() { uni.getLocation({ type: 'gcj02', success: (res) => { let { latitude, longitude } = res this.coordinate.latitude = latitude this.firstLocation.latitude = latitude this.coordinate.longitude = longitude this.firstLocation.longitude = longitude this.myLocation = res; this.Route.start = Object.assign(this.Route.start, this.coordinate); } }); }, //移动当前中心点 参数:经纬度 newMapMoveToLocation(longitude, latitude, type) { let that = this this.mapContext.moveToLocation({ longitude: longitude, latitude: latitude, success: (e) => { console.log(`移动 坐标→ ${longitude}-${latitude}`); if (type) { this.coordinate.latitude = latitude this.coordinate.longitude = longitude this.mapContext.getScale({ success: res => { this.mapScale = res.scale this.$nextTick(() => { this.mapScale = 13 }) } }) } } }) }, addfn(e) { if (e !== null) { setTimeout(() => { this.newMapMoveToLocation(this.markers[e].longitude, this.markers[e].latitude); this.addfn(e < this.markers.length ? e + 1 : null); }, 1500) } }, //价格排序 priceSort(list) { let sort = list.sort((a, b) => { return a.enterprisePrice - b.enterprisePrice }); return sort }, //手动筛选 filterMarkers(e, w) { let that = this return new Promise(function(re, rj) { w = that.$refs.addressSelector.datassFn(); let filterMarkers = []; //第一步筛选 是否高速 let highSpeedMarkers = Object.keys(w).includes('highSpeed') && w.highSpeed ? e.filter((item, index) => { return Number(w.highSpeed) == 2 ? item : item.highSpeedMark == Number(w.highSpeed) }) : e; let copy = JSON.parse(JSON.stringify(highSpeedMarkers)) let sort = that.priceSort(copy); that.selePrice = sort.length !== 0 ? { middlePrice: sort[Number.isInteger((sort.length / 2)) ? (sort.length / 2) : ((sort .length + 1) / 2) - 1].enterprisePrice, minPrice: sort[0].enterprisePrice, } : {}; // 获取更新之后的值 this.$nextTick()也行 setTimeout(() => { w = Object.assign(w, that.$refs.footerScroll.filter()); }, 0) //第二步筛选价格 setTimeout(() => { filterMarkers = Object.keys(w).includes('enterprisePrice') && w.enterprisePrice ? highSpeedMarkers.filter((item, index) => { return item.enterprisePrice <= Number(w.enterprisePrice) }) : highSpeedMarkers; re(filterMarkers) }, 0) }) }, copy(obj) { let newobj = null // 接受拷贝的新对象 if (typeof(obj) == 'object' && typeof(obj) !== null) { // 判断是否是引用类型 newobj = obj instanceof Array ? [] : {} // 判断是数组还是对象 for (var i in obj) { newobj[i] = this.copy(obj[i]) // 判断下一级是否还是引用类型 } } else { newobj = obj } return newobj }, //拖动辅助控件 dragMap(e, w) { let that = this this.enableScroll = w; console.log('辅助控件触发;是否可以拖动地图1>', that.enableScroll) this.newMapMoveToLocation(e.longitude, e.latitude) uni.$on('dragMap', function(e) { that.enableScroll = e console.log('辅助控件触发;是否可以拖动地图>', that.enableScroll) }) } } } </script> <style scoped> @import url("./map.css"); .map_xx { width: 100%; height: 100%; } </style>