You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
571 lines
17 KiB
571 lines
17 KiB
<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 @bindregionchange='bindregionchange' @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: '' |
|
}, |
|
end: { |
|
longitude: '', |
|
latitude: '', |
|
title: '' |
|
} |
|
|
|
}, |
|
enableScroll: true, |
|
coordinate: { |
|
longitude: '', |
|
latitude: '', |
|
title: '我的位置' |
|
}, |
|
markers: [], |
|
mapContext: null, |
|
details: {}, |
|
spareMarkers: [], |
|
selePrice: null, |
|
mapScale: 16 |
|
} |
|
}, |
|
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: { |
|
perspectives(item) { |
|
let { |
|
latitude, |
|
longitude |
|
} = item |
|
setTimeout(() => { |
|
this.newMapMoveToLocation(longitude, latitude, 'reset') |
|
},500) |
|
}, |
|
bindregionchange(e) { |
|
console.log(e, '***********') |
|
}, |
|
mapUpdated(e) { |
|
let that = this |
|
console.log('更新', e); |
|
that.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[0].points, oilProductCode, juLi, |
|
siteChannel); |
|
//处理站点数据回显 |
|
|
|
this.spareMarkers = this.locationProcessing(markerList); |
|
this.markers = await this.filterMarkers(JSON.parse(JSON.stringify(this.spareMarkers))); |
|
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') { |
|
// 获取路径 |
|
let res = await this.getMapRoutePlanning(start, end, strategy); |
|
//处理数据 |
|
this.polyline = this.RoutePlanningHandle(res); |
|
//缩放显示所有经纬度 |
|
this.zoomRoutePlanning(); |
|
// 获取筛选数据 更新油站站点 |
|
let { |
|
oilProductCode, |
|
juLi, |
|
siteChannel |
|
} = this.$refs.addressSelector.datassFn(); |
|
let markerList = await this.mapUpdateMarkers(this.polyline[0].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); |
|
}, |
|
//监听更新位置事件 |
|
UpdateAddress() { |
|
let that = this |
|
uni.$on('UpdateAddress', function(region, type) { |
|
// console.log(`%c ${(type=='start'?'起点更新':'终点更新')} 地址→ ${region.title}`,'color:red;font-size:50px') |
|
that.Route[type].longitude = region.location.lng; |
|
that.Route[type].latitude = region.location.lat; |
|
that.Route[type].title = region.title; |
|
that.mapEventListeners('updateRoute', that.Route.start, that.Route.end) |
|
that.mapEventListeners('UpdateLocation', that.Route, 'lately') |
|
}) |
|
}, |
|
//拉起导航 |
|
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, strategy = 'LEAST_TIME') { |
|
var _this = this; |
|
return new Promise(function(res, rej) { |
|
_this.TXSDK.direction({ |
|
sig: 'mOPvEv4WmyaxymycTYy00pSiad2jnQil', |
|
mode: 'driving', |
|
from: start, |
|
to: end, |
|
policy: strategy, |
|
success: function(e) { |
|
console.log('获取路线规划成功') |
|
res(e) |
|
}, |
|
fail(e) { |
|
setTimeout(() => { |
|
uni.showToast({ |
|
title: e.msg, |
|
icon: "none" |
|
}); |
|
}, 1000) |
|
rej(e) |
|
console.log('获取路线规划失败', e) |
|
} |
|
}) |
|
}) |
|
}, |
|
//获取到的路线规划数据进行处理 |
|
RoutePlanningHandle(res) { |
|
var _this = this; |
|
var ret = res; |
|
var coors = ret.result.routes[0].polyline, |
|
pl = []; |
|
//坐标解压(返回的点串坐标,通过前向差分进行压缩) |
|
var kr = 1000000; |
|
for (var i = 2; i < coors.length; i++) { |
|
coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr; |
|
} |
|
//将解压后的坐标放入点串数组pl中 |
|
for (var 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: 4, |
|
distance: ret.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; |
|
// setTimeout(()=>{ |
|
// uni.showToast({ |
|
// title: system, |
|
// icon: 'none' |
|
// }) |
|
// },1000) |
|
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[0].points, oilProductCode = '0#', juLi = '5', siteChannel = '') { |
|
let data = { |
|
geoList: points, |
|
oilProductCode: oilProductCode ? oilProductCode : '0#', |
|
juLi: juLi ? juLi : '5', |
|
siteChannel: siteChannel, |
|
countJuLi: points[0].distance, |
|
latitude: this.coordinate.latitude, |
|
longitude: this.coordinate.longitude |
|
} |
|
console.log(JSON.stringify(data)) |
|
let taht = this; |
|
return new Promise(function(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 |
|
} |
|
taht.selePrice = { |
|
middlePrice: markerList.data.middlePrice, |
|
minPrice: markerList.data.minPrice |
|
} |
|
re(markerList.data.siteGeoVoList) |
|
}) |
|
}) |
|
}, |
|
//定位处理 |
|
locationProcessing(markerList) { |
|
// console.log(markerList, '----') |
|
markerList.forEach((item, index) => { |
|
let configure = { |
|
siteId: item.id, |
|
id: Number(`${index}`), |
|
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); |
|
// this.enableScroll = true |
|
let details = await oilSiteApi.getSiteDetails({ |
|
latitude: String(this.coordinate.latitude), |
|
longitude: String(this.coordinate.longitude), |
|
siteId: seleMark[0].siteId |
|
}); |
|
// console.log(details, '***') |
|
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(e, '点击了ma') |
|
}, |
|
//获取当前位置 |
|
getCurrentLocation() { |
|
let that = this |
|
uni.getLocation({ |
|
type: 'gcj02', |
|
success: function(res) { |
|
({ |
|
latitude: that.coordinate.latitude, |
|
longitude: that.coordinate.longitude |
|
} = res); |
|
that.myLocation = res; |
|
that.Route.start = Object.assign(that.Route.start, that.coordinate); |
|
} |
|
}); |
|
}, |
|
//移动当前中心点 参数:经纬度 |
|
newMapMoveToLocation(longitude, latitude, type) { |
|
console.log('newMapMoveToLocation') |
|
let that = this |
|
this.mapContext.moveToLocation({ |
|
longitude: longitude, |
|
latitude: latitude, |
|
success(e) { |
|
console.log(`移动 坐标→ ${longitude}-${latitude}`); |
|
if (type) { |
|
that.coordinate.latitude = latitude |
|
that.coordinate.longitude = longitude |
|
that.mapContext.getScale({ |
|
success: function(e) { |
|
setTimeout(() => { |
|
that.mapScale = e.scale; |
|
setTimeout(() => { |
|
that.mapScale = 13 |
|
}, 500) |
|
}, 500) |
|
} |
|
}) |
|
} |
|
}, |
|
fail(ee) { |
|
console.log('ee',ee) |
|
} |
|
}) |
|
}, |
|
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>
|
|
|