flinfo/dc-App/pages/busNavigation/busNavigation.nvue
2025-03-03 14:31:40 +08:00

721 lines
18 KiB
Plaintext

<template>
<view class="container">
<map id="map" :show-compass="true" :include-points="points" :polyline="polyline" lang="en" :longitude="center.longitude" :latitude="center.latitude"
:markers="markers" bindmarkertap="handleMarkerTap" show-location
:style="'width:' + windowWidth + 'px;' + 'height:'+ '540rpx;' ">
</map>
<image src="/static/chatImg/fy.png" @click="changeLan" mode="" class="fy_icon" ></image>
<view class="contenr_" v-if="lang=='en'" >
<view class="contenr_top">
<!-- 顶部 全程 时间-->
<view class="c_t_box">
<view>
<text class="text_1">{{Number.parseInt(allData.duration/60)||0}}min</text>
</view>
<view class="ds_">
<text class="text_2">walk distance</text>
<text class="text_1">{{allData.walkingDistance?Number.parseFloat(allData.walkingDistance/1000).toFixed(2):0}}km</text>
</view>
</view>
<!-- -->
<view class="c_c_box">
<view class="ds_" style="flex-wrap: wrap;">
<image src="/static/imgs/icon2.png" style="height: 48rpx;width: 48rpx;"></image>
<view v-for="(item,index) in allData.segments">
<view class="c_c_title" :style="'background-color:' + colorList[index] " v-for="(it,idx) in item.bus" :key="idx" >
<text class="text_line">{{it.enName.split('(')[0]||''}}</text>
</view>
</view>
</view>
</view>
<!-- 下方注释 -->
<view class="ds_">
<text class="text_4">all cost</text>
<text class="text_4">¥{{allData.cost=='[]'?0:allData.cost}}</text>
</view>
</view>
<scroll-view scroll-y :show-scrollbar="false" @scrolltoupper="upper" @scrolltolower="lower"
:refresher-enabled="true" style="height: 620rpx;" lower-threshold="50">
<view class="contenr_bottom">
<view class="c_b_title">
<image src="/static/imgs/icon3.png" style="height: 40rpx;width: 40rpx;margin-right: 20rpx;"></image>
<text class="text_1">My Location</text>
</view>
</view>
<!-- -- 我需要把循环包在这 这两块一起循环 下面的循环不需要 -->
<view class="c_box" v-for="(item,index) in allData.segments" :key="index">
<view class="c_b_box" v-if="item.walking">
<view class="ds_">
<view class="qiu_"></view>
<text class="text_4">Walk {{item.walking.distance}} meters ({{Number.parseInt(item.walking.duration/60)}} minutes)</text>
</view>
<view class="b_walk">
<text class="text_3" @click="walkLine(item.walking)">Walk</text>
</view>
</view>
<view class="contenr_bottom_d" v-if="item.bus&&item.bus.length>0" v-for="(it) in item.bus">
<view class="bz_left">
<view class="l_t_i" :style="'background-color:' + colorList[index] " >
<image src="/static/imgs/icon4.png" style="height: 32rpx;width: 32rpx;"></image>
</view>
<view class="l_t_z" :style="'background-color:' + colorList[index] " ></view>
<view class="l_t_i" :style="'background-color:' + colorList[index] "></view>
</view>
<view class="bz_right">
<text class="text_1" style="margin-bottom: 32rpx;">{{it.departureStop.enName}} station</text>
<view class="ds_">
<view class="bz_icon" :style="'background-color:' + colorList[index] ">
<text class="text_3">{{it.enName}}</text>
</view>
</view>
<view class="botton_size">
<text class="text_4">{{it.viaStops.length}} station ({{Number.parseInt(it.duration/60)}} min)</text>
</view>
<text class="text_1" style="margin-top: 39rpx;">{{it.arrivalStop.enName}} station</text>
</view>
</view>
</view>
<view class="contenr_bottom">
<view class="c_b_title">
<image src="/static/imgs/end.png" style="height: 50rpx;width: 45rpx;margin-right: 20rpx;"></image>
<text class="text_1">destination</text>
</view>
</view>
</scroll-view>
</view>
<view class="contenr_" v-else >
<view class="contenr_top">
<!-- 顶部 全程 时间-->
<view class="c_t_box">
<view>
<text class="text_1">{{Number.parseInt(allData.duration/60)||0}}分钟</text>
</view>
<view class="ds_">
<text class="text_2">步行距离</text>
<text class="text_1">{{allData.walkingDistance?Number.parseFloat(allData.walkingDistance/1000).toFixed(2):0}}km</text>
</view>
</view>
<!-- -->
<view class="c_c_box">
<view class="ds_" style="flex-wrap: wrap;">
<image src="/static/imgs/icon2.png" style="height: 48rpx;width: 48rpx;"></image>
<view v-for="(item,index) in allData.segments">
<view class="c_c_title" :style="'background-color:' + colorList[index] " v-for="(it,idx) in item.bus" :key="idx" >
<text class="text_line">{{it.name.split('(')[0]||''}}</text>
</view>
</view>
</view>
</view>
<!-- 下方注释 -->
<view class="ds_">
<text class="text_4">总花费</text>
<text class="text_4">¥{{allData.cost}}</text>
</view>
</view>
<scroll-view scroll-y :show-scrollbar="false" @scrolltoupper="upper" @scrolltolower="lower"
:refresher-enabled="true" style="height: 620rpx;" lower-threshold="50">
<view class="contenr_bottom">
<view class="c_b_title">
<image src="/static/imgs/icon3.png" style="height: 40rpx;width: 40rpx;margin-right: 20rpx;"></image>
<text class="text_1">我的位置</text>
</view>
</view>
<!-- -- 我需要把循环包在这 这两块一起循环 下面的循环不需要 -->
<view class="c_box" v-for="(item,index) in allData.segments" :key="index">
<view class="c_b_box" v-if="item.walking">
<view class="ds_">
<view class="qiu_"></view>
<text class="text_4">步行 {{item.walking.distance}} 米 ({{Number.parseInt(item.walking.duration/60)}} 分钟)</text>
</view>
<view class="b_walk">
<text class="text_3" @click="walkLine(item.walking)">导航</text>
</view>
</view>
<view class="contenr_bottom_d" v-if="item.bus&&item.bus.length>0" v-for="(it) in item.bus">
<view class="bz_left">
<view class="l_t_i" :style="'background-color:' + colorList[index] " >
<image src="/static/imgs/icon4.png" style="height: 32rpx;width: 32rpx;"></image>
</view>
<view class="l_t_z" :style="'background-color:' + colorList[index] " ></view>
<view class="l_t_i" :style="'background-color:' + colorList[index] "></view>
</view>
<view class="bz_right">
<text class="text_1" style="margin-bottom: 32rpx;">{{it.departureStop.name}} 站点</text>
<view class="ds_">
<view class="bz_icon" :style="'background-color:' + colorList[index] ">
<text class="text_3">{{it.name}}</text>
</view>
</view>
<view class="botton_size">
<text class="text_4">{{it.viaStops.length}} 站 ({{Number.parseInt(it.duration/60)}} 分钟)</text>
</view>
<text class="text_1" style="margin-top: 39rpx;">{{it.arrivalStop.name}} 站点</text>
</view>
</view>
</view>
<view class="contenr_bottom">
<view class="c_b_title">
<image src="/static/imgs/end.png" style="height: 50rpx;width: 45rpx;margin-right: 20rpx;"></image>
<text class="text_1">终点</text>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import request from '../../utils/request'
import config from '@/config'
export default {
data() {
return {
lang:'en',
translateY: 0,
longPressTimer: null, // 长按定时器
isDragging: false, // 是否正在拖动
colorList:[
"#f9d402",
"#009bc2",
"#000000",
"#c34100",
"#006a00",
],
//打车预估路线
polyline: [],
center: {
latitude: null,
longitude: null
},
mapContext: null,
controls: [],
markers: [],
startPoint: [],
endPoint: [],
// 接口返回
container: {},
routeTitle:'',
distance: 0,
duration: 0,
cost:0,
points:[],
allData:{}
}
},
onLoad(option) {
this.startPoint = option.startPoint.split(',')
this.endPoint = option.endPoint.split(',')
this.startExecution()
},
mounted() {
// 设置初始的触摸起始点坐标,用于计算移动距离
this.startY = 0;
},
computed: {
windowHeight() {
return uni.getSystemInfoSync().windowHeight/3;
},
windowWidth() {
return uni.getSystemInfoSync().windowWidth;
}
},
methods: {
changeLan(){
if(this.lang == 'en'){
this.lang = 'zh'
}else{
this.lang = 'en'
}
},
walkLine(data){
let endInfo = {}
endInfo.location = [data.endLocationLng, data.endLocationLat]
uni.getLocation({
// 谷歌使用wgs84 其他使用gcj02
type: 'gcj02', // 使用国测局坐标系
geocode: true,
success: function(res) {
let staInfo = {}
staInfo.location = [res.longitude, res.latitude]
uni.navigateTo({
url: '/pages/index/PedestrianNavigation?startPoint=' + staInfo
.location +
'&endPoint=' + endInfo.location
})
},
fail: function(err) {
uni.showToast({
title: 'Failed to get location',
icon: 'none'
})
}
});
},
upper(e) {
console.log('Scroll to top');
},
lower(e) {
setTimeout(() => {
this.items.push(...Array.from({ length: 10 }, (_, i) =>
'New Item ' + (this.items.length + i + 1)
));
if (this.items.length >= 50) this.hasMore = false;
}, 1000);
},
startExecution() {
let that = this
uni.showLoading({
title: 'Loading...'
});
request({
url: 'walkApi/getIntegratedRouteInfo',
method: 'post',
data: {
startLocationLng: this.startPoint[0],
startLocationLat: this.startPoint[1],
endLocationLng: this.endPoint[0],
endLocationLat: this.endPoint[1],
}
}).then(res => {
that.allData = res.data
that.duration = res.data.duration/60
that.distance = res.data.walkingDistance/1000
that.cost = res.data.cost
let segments = res.data.segments
that.points = []
//先进行步行的线路展示
that.polyline = []
for (var item of segments) {
let walking = item.walking
if(walking&&walking.polyline){
let item = {}
item.color = '#787878'
item.points = walking.polyline
item.width = 11
item.dottedLine = true
that.polyline.push(item)
//that.points=that.points.concat(item.points)
}
}
//再进行公交的线路展示
for (var item of segments) {
let bus = item.bus
if(bus&&bus.length>0){
for (var busIt of bus){
let item = {}
item.color = '#5500ff'
item.points = busIt.polyline
item.width = 18
item.arrowLine = true
that.polyline.push(item)
//that.points=that.points.concat(item.points)
}
}
}
//进行标记点处理
that.markers = []
//起点和终点处理
that.markers.push({
id:1,
label:{
content:'Start Point',
fontSize:8,
color:'#145e07'
},
iconPath:config.startStopIcon,
latitude: this.startPoint[1],
longitude: this.startPoint[0],
width: 20,
height: 20,
})
that.markers.push({
id:2,
label:{
content:'End Point',
fontSize:8,
color:'#145e07'
},
iconPath:config.endStopIcon,
latitude: this.endPoint[1],
longitude: this.endPoint[0],
width: 20,
height: 20,
})
let i=1;
for (var item of segments) {
let bus = item.bus
if(bus&&bus.length>0){
for (var busIt of bus){
//途径上车点
that.markers.push({
id:busIt.departureStop.id,
label:{
content:busIt.enName,
fontSize:8,
color:'#145e07'
},
iconPath:config.varStop,
latitude: busIt.departureStop.locationLat,
longitude: busIt.departureStop.locationLng,
width: 20,
height: 20,
})
that.points.push({
latitude: that.offsetLatitude1(busIt.departureStop.locationLat,30000),
longitude: busIt.departureStop.locationLng
})
that.points.push({
latitude: that.offsetLatitude2(busIt.departureStop.locationLat,30000),
longitude: busIt.departureStop.locationLng
})
that.points.push({
latitude: busIt.departureStop.locationLat,
longitude: that.offsetLongitude1(busIt.departureStop.locationLng,30000)
})
that.points.push({
latitude: busIt.departureStop.locationLat,
longitude: that.offsetLongitude2(busIt.departureStop.locationLng,30000)
})
that.points.push({
latitude: that.offsetLatitude1(busIt.arrivalStop.locationLat,30000),
longitude: busIt.arrivalStop.locationLng
})
that.points.push({
latitude: that.offsetLatitude2(busIt.arrivalStop.locationLat,30000),
longitude: busIt.arrivalStop.locationLng
})
that.points.push({
latitude: busIt.arrivalStop.locationLat,
longitude: that.offsetLongitude1(busIt.arrivalStop.locationLng,30000)
})
that.points.push({
latitude: busIt.arrivalStop.locationLat,
longitude: that.offsetLongitude2(busIt.arrivalStop.locationLng,30000)
})
}
}
}
console.log(that.points);
}).finally(()=>{
uni.hideLoading()
})
},
offsetLongitude1(oldValue,num) {
oldValue =Number.parseFloat(oldValue)
const R = 6371000; // 地球半径,单位为米
const latRad = oldValue * Math.PI / 180;
const deltaLon = num / (R * Math.cos(latRad));
return oldValue + deltaLon;
},
offsetLongitude2(oldValue,num) {
oldValue =Number.parseFloat(oldValue)
const R = 6371000; // 地球半径,单位为米
const latRad = oldValue * Math.PI / 180;
const deltaLon = num / (R * Math.cos(latRad));
return oldValue - deltaLon;
},
offsetLatitude1(oldValue,num) {
oldValue =Number.parseFloat(oldValue)
const R = 6371000; // 地球半径,单位为米
const deltaLat = num / R;
return oldValue + deltaLat;
},
offsetLatitude2(oldValue,num) {
oldValue =Number.parseFloat(oldValue)
const R = 6371000; // 地球半径,单位为米
const deltaLat = num / R;
return oldValue - deltaLat;
},
goback() {
uni.navigateBack()
},
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
// 对于 TabBar 类型页面还需要额外关注 onHide 钩子
onHide() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
}
}
}
</script>
<style scoped lang="scss">
.container {
width: 750rpx;
flex: 1;
}
.ds_{
flex-direction: row;
align-items: center;
}
.bottom_pr {
min-height: 160rpx;
position: fixed;
bottom: 0rpx;
width: 750rpx;
background: #fff;
box-shadow: 0rpx -2rpx 3rpx 0rpx rgba(50,113,79,0.3);
overflow: hidden;
box-sizing: border-box;
padding: 30rpx;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.draggable {
width: 100px;
height: 100px;
background-color: blue;
color: white;
display: flex;
justify-content: center;
align-items: center;
z-index: 99999;
}
.bz_icon{
box-sizing: border-box;
padding: 18rpx 18rpx;
border-radius: 8rpx ;
display: flex;
justify-content: center;
align-items: center;
margin-right: 20rpx;
}
.b_walk{
width: 80rpx;
height: 40rpx;
background: #32714F;
border-radius: 32rpx 32rpx 32rpx 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
.button_{
width: 686rpx;
height: 96rpx;
background: #32714F;
border-radius: 12rpx 12rpx 12rpx 12rpx;
display: flex;
justify-content: center;
align-items: center;
z-index: 99999;
}
.qiu_{
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background: #e8e8e8;
margin-right: 32rpx;
}
.c_b_box{
margin: 10rpx 0rpx;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.c_b_title{
flex-direction: row;
align-items: center;
}
.button_text{
color: #FFFFFF;
font-size: 38rpx;
}
.contenr_{
min-height: 160rpx;
position: fixed;
bottom: 0rpx;
width: 750rpx;
background: #fff;
}
.contenr_top{
width: 686rpx;
background: #FFFFFF;
box-shadow: 0rpx 8rpx 20rpx 0rpx rgba(0,0,0,0.1);
border-radius: 32rpx 32rpx 32rpx 32rpx;
margin-left: 32rpx;
box-sizing: border-box;
padding: 32rpx;
}
.c_t_box{
box-sizing: border-box;
padding-bottom: 16rpx;
border-bottom: 2rpx solid #F2F2F2;;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-bottom: 16rpx;
}
.c_c_box{
margin-bottom: 16rpx;
}
.c_box{
box-sizing: border-box;
padding: 0px 32rpx;
}
.text_1{
font-size: 32rpx;
color: #333333;
font-weight: 600;
}
.text_2{
font-size: 32rpx;
color: #999999;
margin-right: 5px;
}
.text_3{
font-weight: 500;
font-size: 28rpx;
color: #FFFFFF;
}
.text_line{
font-weight: 500;
font-size: 23rpx;
color: #FFFFFF;
}
.text_4{
font-weight: 400;
font-size: 24rpx;
color: #999999;
margin-right: 10rpx;
}
.text_5{
font-size: 24rpx;
color: #333333;
margin-right: 10rpx;
}
.c_c_title{
width: 260rpx;
height: 48rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
background: #fcd702;
flex-direction: row;
align-items: center;
justify-content: center;
margin: 0px 5rpx;
}
.contenr_bottom{
// margin-top: 40rpx;
box-sizing: border-box;
padding: 32rpx;
padding-bottom: 0px;
}
.contenr_bottom_d{
box-sizing: border-box;
padding: 11rpx;
padding-top: 0px;
flex-direction: row;
}
.bz_left{
position: relative;
margin-right: 20rpx;
}
.bz_right{
}
.l_t_i{
width: 40rpx;
height: 40rpx;
border-radius: 50%;
flex-direction: row;
align-items: center;
justify-content: center;
border: 1rpx solid #fff;
}
.l_t_z{
width: 24rpx;
height: 240rpx;
margin: 4rpx 0rpx;
margin-left: 8rpx;
border-radius: 16rpx ;
}
.po_box{
height: 360rpx;
overflow: auto;
}
.botton_size{
margin-top: 100rpx;
}
.fy_icon{
position: fixed;
right: 15px;
top: 15px;
width: 80rpx;
height: 80rpx;
}
::v-deep .amap-logo {
opacity: 0 !important;
}
::v-deep .amap-copyright {
opacity: 0 !important;
}
::v-deep .BMap_cpyCtrl {
display: none !important;
}
::v-deep .anchorBL {
display: none !important;
}
</style>