Page({ data: { // 地图初始中心坐标(北京市中心) longitude: 116.404, latitude: 39.915, scale: 14, markers: [], polyline: [], startLocation: {}, endLocation: {}, showTripInfo: true, distance: 0, estimatedPrice: 0, showCallButton: true, showDriverInfo: false, carsNearby: 0, // 司机信息 driverAvatar: 'https://esos-iot.bjdexn.cn/myminio/project/a0d245bf00c6493d949c3be82a6d2b98.png', driverName: '王师傅', carNumber: '京A88888', estimatedArrival: 5 }, onLoad() { // 初始化地图 this.initMap(); // 加载附近车辆数据 this.loadNearbyCars(); }, // 初始化地图,获取用户位置 initMap() { const that = this; // 获取用户当前位置 wx.getLocation({ type: 'gcj02', // 国测局坐标系,微信地图使用该坐标系 success(res) { const longitude = res.longitude; const latitude = res.latitude; // 更新地图中心位置 that.setData({ longitude, latitude, startLocation: { longitude, latitude, name: '我的位置' }, // 添加起点标记 markers: [{ id: 0, longitude, latitude, iconPath: 'https://esos-iot.bjdexn.cn/myminio/project/a0d245bf00c6493d949c3be82a6d2b98.png', width: 40, height: 40, anchor: {x: 0.5, y: 1} }] }); // 逆地址解析,获取位置名称 that.reverseGeocoder(longitude, latitude, 'start'); }, fail() { wx.showToast({ title: '无法获取位置,请检查权限', icon: 'none' }); } }); }, // 逆地址解析,将经纬度转换为地址名称 reverseGeocoder(longitude, latitude, type) { wx.request({ url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=VRGBZ-ZFRHB-SKIUP-NHHJ3-TXGJT-ZIFG3`, success(res) { if (res.data.status === 0) { const address = res.data.result.address; if (type === 'start') { this.setData({ 'startLocation.name': address }); } else if (type === 'end') { this.setData({ 'endLocation.name': address }); } } }, fail() { wx.showToast({ title: '地址解析失败', icon: 'none' }); } }); }, // 选择起点位置 chooseStartLocation() { this.chooseLocation('start'); }, // 选择终点位置 chooseEndLocation() { this.chooseLocation('end'); }, // 选择位置通用方法 chooseLocation(type) { console.log(type); const that = this; wx.chooseLocation({ success(res) { console.log(res); const locationData = { longitude: res.longitude, latitude: res.latitude, name: res.name }; // 更新对应位置信息 if (type === 'start') { that.setData({ 'startLocation': locationData }); } else if (type === 'end') { that.setData({ 'endLocation': locationData }); } // 更新标记和路线 that.updateMarkersAndRoute(); }, fail() { wx.showToast({ title: '选择位置失败', icon: 'none' }); } }); }, // 更新地图标记和路线 updateMarkersAndRoute() { const { startLocation, endLocation } = this.data; // 如果起点和终点都存在 if (startLocation.longitude && endLocation.longitude) { // 更新标记 const markers = [ { id: 0, longitude: startLocation.longitude, latitude: startLocation.latitude, iconPath: 'https://esos-iot.bjdexn.cn/myminio/project/a0d245bf00c6493d949c3be82a6d2b98.png', width: 40, height: 40, anchor: {x: 0.5, y: 1} }, { id: 1, longitude: endLocation.longitude, latitude: endLocation.latitude, iconPath: 'https://esos-iot.bjdexn.cn/myminio/project/9efa1691f71a48b6ae20648c0a2dae56.png', width: 40, height: 40, anchor: {x: 0.5, y: 1} } ]; // 绘制路线 const polyline = [{ points: [ { longitude: startLocation.longitude, latitude: startLocation.latitude }, { longitude: endLocation.longitude, latitude: endLocation.latitude } ], color: "#2C85FF", width: 6, dottedLine: false }]; // 计算距离和费用 const distance = this.calculateDistance( startLocation.latitude, startLocation.longitude, endLocation.latitude, endLocation.longitude ); // 简单的费用计算模型:起步价13元,超过3公里后每公里2.3元 let price = 13; if (distance > 3) { price += (distance - 3) * 2.3; } this.setData({ markers, polyline, distance: distance.toFixed(1), estimatedPrice: Math.round(price), showTripInfo: true, showCallButton: true }); } else if (startLocation.longitude) { // 只有起点 this.setData({ markers: [{ id: 0, longitude: startLocation.longitude, latitude: startLocation.latitude, iconPath: 'https://esos-iot.bjdexn.cn/myminio/project/a0d245bf00c6493d949c3be82a6d2b98.png', width: 40, height: 40, anchor: {x: 0.5, y: 1} }], polyline: [], showTripInfo: false, showCallButton: false }); } }, // 计算两点之间的距离(公里) calculateDistance(lat1, lon1, lat2, lon2) { const R = 6371; // 地球半径(公里) const dLat = this.deg2rad(lat2 - lat1); const dLon = this.deg2rad(lon2 - lon1); const a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(this.deg2rad(lat1)) * Math.cos(this.deg2rad(lat2)) * Math.sin(dLon/2) * Math.sin(dLon/2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); const distance = R * c; return distance; }, // 角度转弧度 deg2rad(deg) { return deg * (Math.PI/180); }, // 地图区域变化时触发 onRegionChange(e) { // 可以在这里处理地图移动后的逻辑,如重新加载附近车辆 if (e.type === 'end' && e.causedBy === 'drag') { this.loadNearbyCars(); } }, // 加载附近车辆 loadNearbyCars() { const { longitude, latitude } = this.data; // 模拟获取附近车辆数据 // 实际应用中应该调用后端API获取真实数据 const cars = []; const count = Math.floor(Math.random() * 10) + 1; // 1-10辆随机 for (let i = 0; i < count; i++) { // 在当前位置附近随机生成车辆位置 const offsetLon = (Math.random() - 0.5) * 0.02; const offsetLat = (Math.random() - 0.5) * 0.02; cars.push({ id: 100 + i, longitude: longitude + offsetLon, latitude: latitude + offsetLat, iconPath: 'https://esos-iot.bjdexn.cn/myminio/project/a0d245bf00c6493d949c3be82a6d2b98.png', width: 30, height: 30, anchor: {x: 0.5, y: 0.5} }); } // 将车辆标记添加到现有标记中 const updatedMarkers = [...this.data.markers]; // 先移除之前的车辆标记 const filteredMarkers = updatedMarkers.filter(marker => marker.id < 100); // 添加新的车辆标记 filteredMarkers.push(...cars); this.setData({ markers: filteredMarkers, carsNearby: count }); }, // 呼叫车辆 callCar() { wx.showLoading({ title: '正在呼叫车辆...', mask: true }); // 模拟呼叫过程 setTimeout(() => { wx.hideLoading(); // 显示司机信息 this.setData({ showDriverInfo: true, showCallButton: false }); // 模拟司机接近动画 this.simulateDriverApproach(); }, 2000); }, // 模拟司机接近 simulateDriverApproach() { const { startLocation, endLocation, markers } = this.data; let driverMarker = markers.find(marker => marker.id === 999); // 如果司机标记不存在,则创建一个 if (!driverMarker) { // 从终点附近开始 driverMarker = { id: 999, longitude: endLocation.longitude + (Math.random() - 0.5) * 0.01, latitude: endLocation.latitude + (Math.random() - 0.5) * 0.01, iconPath: 'https://esos-iot.bjdexn.cn/myminio/project/a0d245bf00c6493d949c3be82a6d2b98.png', width: 40, height: 40, anchor: {x: 0.5, y: 0.5} }; this.setData({ markers: [...markers, driverMarker] }); } // 计算司机到起点的每一步 const steps = 20; // 分20步接近 const lonStep = (startLocation.longitude - driverMarker.longitude) / steps; const latStep = (startLocation.latitude - driverMarker.latitude) / steps; let currentStep = 0; // 更新司机位置的定时器 const timer = setInterval(() => { currentStep++; if (currentStep >= steps) { clearInterval(timer); // 到达起点,更新到达时间 this.setData({ estimatedArrival: 0 }); return; } // 更新司机标记位置 const updatedMarkers = this.data.markers.map(marker => { if (marker.id === 999) { return { ...marker, longitude: marker.longitude + lonStep, latitude: marker.latitude + latStep }; } return marker; }); // 更新预计到达时间 const newArrivalTime = Math.max(0, 5 - Math.floor(currentStep / 4)); this.setData({ markers: updatedMarkers, estimatedArrival: newArrivalTime }); }, 500); }, // 取消订单 cancelOrder() { // 移除司机标记 const updatedMarkers = this.data.markers.filter(marker => marker.id !== 999); this.setData({ showDriverInfo: false, showCallButton: true, markers: updatedMarkers }); } });