├── .eslintrc.js ├── Components ├── IconButton │ ├── IconButton.js │ ├── IconButton.json │ ├── IconButton.wxml │ └── IconButton.wxss └── SOS │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── README.md ├── app.js ├── app.json ├── app.wxss ├── images ├── Emergency SOS.png ├── bmy.jpg ├── gg.jpg ├── icon/步数.png ├── sxdbg.jpeg ├── 向下.png ├── 导航.png ├── 楼层.png ├── 步数.png ├── 讲解.png ├── 讲解关闭.png ├── 讲解点.png ├── 运动健康.png └── 速度.png ├── pages ├── index │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── map1 │ ├── image │ │ └── location.png │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── map2 │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── map3 │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss └── sos │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── project.config.json ├── project.private.config.json ├── sitemap.json └── utils ├── qqmap ├── qqmap-wx-jssdk.js └── qqmap-wx-jssdk.min.js └── util.js /.eslintrc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Eslint config file 3 | * Documentation: https://eslint.org/docs/user-guide/configuring/ 4 | * Install the Eslint extension before using this feature. 5 | */ 6 | module.exports = { 7 | env: { 8 | es6: true, 9 | browser: true, 10 | node: true, 11 | }, 12 | ecmaFeatures: { 13 | modules: true, 14 | }, 15 | parserOptions: { 16 | ecmaVersion: 2018, 17 | sourceType: 'module', 18 | }, 19 | globals: { 20 | wx: true, 21 | App: true, 22 | Page: true, 23 | getCurrentPages: true, 24 | getApp: true, 25 | Component: true, 26 | requirePlugin: true, 27 | requireMiniProgram: true, 28 | }, 29 | // extends: 'eslint:recommended', 30 | rules: {}, 31 | } 32 | -------------------------------------------------------------------------------- /Components/IconButton/IconButton.js: -------------------------------------------------------------------------------- 1 | // Components/IconButton.js 2 | Component({ 3 | 4 | /** 5 | * 组件的属性列表 6 | */ 7 | properties: { 8 | 9 | }, 10 | 11 | /** 12 | * 组件的初始数据 13 | */ 14 | data: { 15 | 16 | }, 17 | 18 | /** 19 | * 组件的方法列表 20 | */ 21 | methods: { 22 | 23 | } 24 | }) -------------------------------------------------------------------------------- /Components/IconButton/IconButton.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /Components/IconButton/IconButton.wxml: -------------------------------------------------------------------------------- 1 | 2 | Components/IconButton.wxml -------------------------------------------------------------------------------- /Components/IconButton/IconButton.wxss: -------------------------------------------------------------------------------- 1 | /* Components/IconButton.wxss */ -------------------------------------------------------------------------------- /Components/SOS/index.js: -------------------------------------------------------------------------------- 1 | // pages/sos/index.js 2 | Page({ 3 | 4 | /** 5 | * 页面的初始数据 6 | */ 7 | data: { 8 | 9 | }, 10 | goSOS(){ 11 | wx.navigateTo({ 12 | url: '../../pages/sos/index' 13 | }) 14 | }, 15 | /** 16 | * 生命周期函数--监听页面加载 17 | */ 18 | onLoad(options) { 19 | 20 | }, 21 | 22 | /** 23 | * 生命周期函数--监听页面初次渲染完成 24 | */ 25 | onReady() { 26 | 27 | }, 28 | 29 | /** 30 | * 生命周期函数--监听页面显示 31 | */ 32 | onShow() { 33 | 34 | }, 35 | 36 | /** 37 | * 生命周期函数--监听页面隐藏 38 | */ 39 | onHide() { 40 | 41 | }, 42 | 43 | /** 44 | * 生命周期函数--监听页面卸载 45 | */ 46 | onUnload() { 47 | 48 | }, 49 | 50 | /** 51 | * 页面相关事件处理函数--监听用户下拉动作 52 | */ 53 | onPullDownRefresh() { 54 | 55 | }, 56 | 57 | /** 58 | * 页面上拉触底事件的处理函数 59 | */ 60 | onReachBottom() { 61 | 62 | }, 63 | 64 | /** 65 | * 用户点击右上角分享 66 | */ 67 | onShareAppMessage() { 68 | 69 | } 70 | }) -------------------------------------------------------------------------------- /Components/SOS/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | 4 | } -------------------------------------------------------------------------------- /Components/SOS/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Components/SOS/index.wxss: -------------------------------------------------------------------------------- 1 | /* pages/sos/index.wxss */ 2 | .sosControl{ 3 | display: block; 4 | position: fixed; 5 | left: 80rpx; 6 | top:5rpx; 7 | /* border:1px solid red; */ 8 | 9 | } 10 | .sosimg { 11 | display: block; 12 | width: 45rpx; 13 | height: 45rpx; 14 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 待完善…… 2 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | // app.js 2 | App({ 3 | onLaunch() { 4 | // 展示本地存储能力 5 | const logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | 9 | // 登录 10 | wx.login({ 11 | success: res => { 12 | // 发送 res.code 到后台换取 openId, sessionKey, unionId 13 | } 14 | }) 15 | }, 16 | globalData: { 17 | userInfo: null 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/index/index", 4 | "pages/map1/index", 5 | "pages/map2/index", 6 | "pages/map3/index", 7 | "pages/sos/index" 8 | ], 9 | "window": { 10 | "navigationBarTextStyle": "black", 11 | "navigationBarTitleText": "智能导航", 12 | "navigationBarBackgroundColor": "#ffffff" 13 | }, 14 | "usingComponents":{ 15 | "SOS":"Components/SOS/index" 16 | }, 17 | "requiredPrivateInfos":["getLocation"], 18 | "style": "v2", 19 | "componentFramework": "glass-easel", 20 | "sitemapLocation": "sitemap.json", 21 | "lazyCodeLoading": "requiredComponents" 22 | } 23 | -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | .container { 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: space-between; 8 | padding: 200rpx 0; 9 | box-sizing: border-box; 10 | } 11 | -------------------------------------------------------------------------------- /images/Emergency SOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/Emergency SOS.png -------------------------------------------------------------------------------- /images/bmy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/bmy.jpg -------------------------------------------------------------------------------- /images/gg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/gg.jpg -------------------------------------------------------------------------------- /images/icon/步数.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/icon/步数.png -------------------------------------------------------------------------------- /images/sxdbg.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/sxdbg.jpeg -------------------------------------------------------------------------------- /images/向下.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/向下.png -------------------------------------------------------------------------------- /images/导航.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/导航.png -------------------------------------------------------------------------------- /images/楼层.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/楼层.png -------------------------------------------------------------------------------- /images/步数.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/步数.png -------------------------------------------------------------------------------- /images/讲解.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/讲解.png -------------------------------------------------------------------------------- /images/讲解关闭.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/讲解关闭.png -------------------------------------------------------------------------------- /images/讲解点.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/讲解点.png -------------------------------------------------------------------------------- /images/运动健康.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/运动健康.png -------------------------------------------------------------------------------- /images/速度.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/images/速度.png -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | // index.js 4 | const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0' 5 | 6 | Page({ 7 | data: { 8 | motto: 'Hello World', 9 | userInfo: { 10 | avatarUrl: defaultAvatarUrl, 11 | nickName: '', 12 | }, 13 | hasUserInfo: false, 14 | canIUseGetUserProfile: wx.canIUse('getUserProfile'), 15 | canIUseNicknameComp: wx.canIUse('input.type.nickname'), 16 | }, 17 | bindViewTap() { 18 | wx.navigateTo({ 19 | url: '../map1/index' 20 | }) 21 | }, 22 | bindViewBmy() { 23 | wx.navigateTo({ 24 | url: '../map2/index' 25 | }) 26 | }, 27 | bindViewGg() { 28 | wx.navigateTo({ 29 | url: '../map3/index' 30 | }) 31 | }, 32 | more(){ 33 | wx.showToast({ 34 | title: '有待更新~', 35 | duration: 2000, 36 | icon:'none', 37 | }) 38 | }, 39 | onChooseAvatar(e) { 40 | const { avatarUrl } = e.detail 41 | const { nickName } = this.data.userInfo 42 | this.setData({ 43 | "userInfo.avatarUrl": avatarUrl, 44 | hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl, 45 | }) 46 | }, 47 | onInputChange(e) { 48 | const nickName = e.detail.value 49 | const { avatarUrl } = this.data.userInfo 50 | this.setData({ 51 | "userInfo.nickName": nickName, 52 | hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl, 53 | }) 54 | }, 55 | getUserProfile(e) { 56 | // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗 57 | wx.getUserProfile({ 58 | desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写 59 | success: (res) => { 60 | console.log(res) 61 | this.setData({ 62 | userInfo: res.userInfo, 63 | hasUserInfo: true 64 | }) 65 | } 66 | }) 67 | }, 68 | }) 69 | -------------------------------------------------------------------------------- /pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": { 3 | } 4 | } -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 11 | 14 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /**index.wxss**/ 2 | page { 3 | height: 100vh; 4 | display: flex; 5 | flex-direction: column; 6 | margin: 0; 7 | padding: 0; 8 | } 9 | 10 | .Container{ 11 | 12 | width: 100%; 13 | height:100%; 14 | 15 | } 16 | .sxdContainer{ 17 | display: block; 18 | width:50vh; 19 | height:48vh; 20 | background-color: rgb(100, 97, 97); 21 | margin:8rpx; 22 | 23 | } 24 | .sxdbg{ 25 | display: block; 26 | position:absolute; 27 | width:50vh; 28 | height:48vh; 29 | top:0; 30 | left:0; 31 | } 32 | .bmybg{ 33 | display: block; 34 | position:absolute; 35 | width:50vh; 36 | height:48vh; 37 | top:0; 38 | left:0; 39 | } 40 | .ggbg{ 41 | display: block; 42 | position:absolute; 43 | width:50vh; 44 | height:48vh; 45 | top:0; 46 | left:-170rpx; 47 | } 48 | .scrollarea { 49 | flex: 1; 50 | overflow-y: hidden; 51 | } 52 | .more{ 53 | display: flex; 54 | justify-content: center; 55 | align-items: center; 56 | font-size: 350rpx; 57 | color: white; 58 | width: 100%; 59 | height: 100%; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /pages/map1/image/location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lis313/Intelligent-scenic-spot-navigation/65af083fdcc2bedec7bb07c277e5f769222f7660/pages/map1/image/location.png -------------------------------------------------------------------------------- /pages/map1/index.js: -------------------------------------------------------------------------------- 1 | let QQMapWX = require("../../utils/qqmap/qqmap-wx-jssdk.min"); 2 | let qqmapsdk; 3 | Page({ 4 | data: { 5 | latitude: 31.002354, 6 | longitude: 104.22068, 7 | src: '', 8 | floors: ['F1', 'F2'], 9 | idChoosed: '-1', 10 | isPlay: false, 11 | isChoosed: '0', 12 | bg: '#ffffff',//'#99963f' 13 | audioUrl: [], 14 | album: [], 15 | albumSrc: '', 16 | iconUrl: '/images/讲解点.png', 17 | isTrue: true, 18 | textArry: [], 19 | text: '111', 20 | polygons: [ 21 | { 22 | fillColor: 'transparent', 23 | level: 'aboveroads', 24 | strokeColor:'#f48e4d', 25 | strokeWidth:4, 26 | points: [ 27 | { "latitude": 31.002975, "longitude": 104.218174 }, 28 | { "latitude": 31.002424, "longitude": 104.218394 }, 29 | { "latitude": 31.002405, "longitude": 104.218458 }, 30 | { "latitude": 31.002520, "longitude": 104.219161 }, 31 | { "latitude": 31.002488, "longitude": 104.219204 }, 32 | { "latitude": 31.002148, "longitude": 104.219322 }, 33 | { "latitude": 31.002125, "longitude": 104.219354 }, 34 | { "latitude": 31.002180, "longitude": 104.219569 }, 35 | { "latitude": 31.002157, "longitude": 104.219708 }, 36 | { "latitude": 31.002102, "longitude": 104.219735 }, 37 | { "latitude": 31.002042, "longitude": 104.219741 }, 38 | { "latitude": 31.002019, "longitude": 104.219789 }, 39 | { "latitude": 31.001968, "longitude": 104.219842 }, 40 | { "latitude": 31.001932, "longitude": 104.219864 }, 41 | { "latitude": 31.001913, "longitude": 104.219918 }, 42 | { "latitude": 31.001881, "longitude": 104.220020 }, 43 | { "latitude": 31.001890, "longitude": 104.220138 }, 44 | { "latitude": 31.001968, "longitude": 104.220475 }, 45 | { "latitude": 31.001798, "longitude": 104.222025 }, 46 | { "latitude": 31.002534, "longitude": 104.221778 } 47 | ] 48 | }, 49 | 50 | ], 51 | markers: [], 52 | showSport: false, 53 | showButtom: false, 54 | lastTimestamp: 0, 55 | lastLocation: null, 56 | speed: '0.00', 57 | }, 58 | 59 | chooseFloor(e) { 60 | console.log(e); 61 | this.setData({ 62 | isChoosed: e.currentTarget.id, 63 | showButtom: false, 64 | isPlay: false, 65 | 66 | }); 67 | this.makeMarks(); 68 | }, 69 | showS() { 70 | this.setData({ 71 | showSport: !this.data.showSport 72 | }); 73 | }, 74 | onReady: function (e) { 75 | console.log('111'); 76 | wx.showLoading({ 77 | title: '加载中', 78 | }) 79 | 80 | setTimeout(function () { 81 | wx.hideLoading() 82 | }, 2000) 83 | this.mapCtx = wx.createMapContext('myMap'); 84 | this.makeMarks(); 85 | console.log(this.data.markers); 86 | this.createAudio(); 87 | qqmapsdk = new QQMapWX({ 88 | key: 'U2YBZ-W4MEN-4NSFM-SYVGY-7KP4K-XQBWQ' // 必填 89 | }) 90 | setInterval(this.calculateSpeed, 5000); 91 | }, 92 | //创建语音示例进行播放 93 | createAudio(e) { 94 | //创建内部 audio 上下文 InnerAudioContext 对象。 95 | this.innerAudioContext = wx.createInnerAudioContext(); 96 | // 发生错误触发 97 | this.innerAudioContext.onError(function (res) { }) 98 | //设置音频地址 99 | this.innerAudioContext.src = this.data.src; 100 | }, 101 | daohang: function () { 102 | console.log('11122') 103 | const { idChoosed, markers } = this.data; 104 | this.setData({ 105 | showButtom: false, 106 | }) 107 | this.mapCtx.openMapApp({ 108 | longitude: markers[idChoosed - 1].longitude, 109 | latitude: markers[idChoosed - 1].latitude, 110 | destination: markers[idChoosed - 1].title, 111 | success: function (res) { console.log(res) }, 112 | fail: function (res) { console.log(res) }, 113 | complete: function (res) { console.log(res) }, 114 | 115 | } 116 | ) 117 | }, 118 | // 声明变量用于存储上一次获取位置信息的时间戳和位置信息 119 | 120 | 121 | 122 | 123 | // 获取位置信息并计算运动速率 124 | async calculateSpeed() { 125 | let { lastTimestamp, lastLocation } = this.data; 126 | wx.getLocation({ 127 | type: 'gcj02', // 使用国测局坐标系 128 | success: (res) => { 129 | const currentTimestamp = new Date().getTime(); // 获取当前时间戳 130 | const currentLocation = res; 131 | // 如果是第一次获取位置信息,或者距离上次获取位置信息时间超过5秒,则重新设置lastTimestamp和lastLocation 132 | if (lastTimestamp === 0 || currentTimestamp - lastTimestamp >= 5000) { 133 | this.setData({ 134 | lastTimestamp: currentTimestamp, 135 | lastLocation: currentLocation, 136 | }) 137 | console.log("尚未计算速率,等待下一次获取位置信息...", lastTimestamp, lastLocation); 138 | return; 139 | } 140 | wx.request({ 141 | url: 'https://apis.map.qq.com/ws/distance/v1/matrix?mode=walking', 142 | method: 'POST', 143 | data: { 144 | key: 'U2YBZ-W4MEN-4NSFM-SYVGY-7KP4K-XQBWQ', 145 | from: `${lastLocation.latitude},${lastLocation.longitude}`, //若起点有数据则采用起点坐标,若为空默认当前地址 146 | to: `${currentLocation.latitude},${currentLocation.longitude}`, //终点坐标 147 | }, 148 | header: { 149 | 'content-type': 'application/json' // 根据需求设置请求头 150 | }, 151 | success: (res) => { 152 | console.log(res.data.result); 153 | const { rows } = res.data.result; 154 | const distance = rows[0].elements[0].distance; 155 | // return res.data.result.rows[0].elements[0].distance 156 | // 计算速率(米/秒) 157 | const timeDifferenceInSeconds = (currentTimestamp - lastTimestamp) / 1000; 158 | const speed = distance / timeDifferenceInSeconds; 159 | 160 | // 更新lastTimestamp和lastLocation 161 | this.setData({ 162 | lastTimestamp: currentTimestamp, 163 | lastLocation: currentLocation, 164 | speed: speed.toFixed(2), 165 | }) 166 | 167 | console.log("当前速率为:" + speed.toFixed(2) + " 米/秒"); 168 | }, 169 | fail: function (err) { 170 | console.log(err); 171 | } 172 | }); 173 | }, 174 | fail: function (res) { 175 | console.log("获取位置信息失败:" + res.errMsg); 176 | } 177 | }); 178 | } 179 | , 180 | 181 | 182 | audio() { 183 | if (!this.data.isPlay) { 184 | // const id = Number(e.detail.markerId); 185 | this.setData({ 186 | iconUrl: '/images/讲解.png', 187 | 188 | }) 189 | this.audioPlay(); 190 | 191 | } 192 | else { 193 | this.setData({ 194 | iconUrl: '/images/讲解点.png', 195 | 196 | }) 197 | this.audioPause(); 198 | } 199 | }, 200 | mTap: function (e) { 201 | const id = Number(e.detail.markerId); 202 | const { showButtom, idChoosed } = this.data; 203 | this.end() 204 | if (showButtom && id !== idChoosed) { 205 | this.setData({ 206 | showButtom: true, 207 | src: this.data.audioUrl[id], 208 | albumSrc: this.data.album[id], 209 | text: this.data.textArry[id], 210 | idChoosed: id, 211 | isPlay: false, 212 | iconUrl: '/images/讲解点.png', 213 | }) 214 | } 215 | else { 216 | this.setData({ 217 | showButtom: !showButtom, 218 | src: this.data.audioUrl[id], 219 | albumSrc: this.data.album[id], 220 | text: this.data.textArry[id], 221 | idChoosed: id, 222 | isPlay: false, 223 | iconUrl: '/images/讲解点.png', 224 | }) 225 | } 226 | 227 | console.log(e.detail.markerId); 228 | 229 | }, 230 | makeMarks: function () { 231 | const isChoosed = Number(this.data.isChoosed); 232 | const { floors } = this.data; 233 | const { data } = this.getSXDData(); 234 | // console.log(floors,isChoosed) 235 | this.setData({ 236 | markers: [], 237 | }) 238 | if (data.length != 0) { 239 | const m = []; 240 | const audioUrl = []; 241 | const album = []; 242 | const textArry = []; 243 | data.map((item) => { 244 | if (item.floor == floors[isChoosed]) { 245 | // console.log(item.floor,floors[isChoosed]) 246 | const id = Number(item.info_id) 247 | const mark = { 248 | width: 36, 249 | height: 36, 250 | id: id, 251 | iconPath: item.icon, 252 | title: item.title, 253 | latitude: item.location.lat, 254 | longitude: item.location.lon, 255 | label:{ 256 | content:item.title, 257 | bgColor:'#efebe1', 258 | borderRadius:20, 259 | textAlign:'center', 260 | padding:5, 261 | } 262 | } 263 | m.push(mark); 264 | audioUrl[id] = item.audio.url; 265 | album[id] = item.album[0]; 266 | textArry[id] = item.title; 267 | } 268 | }) 269 | console.log('m', m) 270 | this.setData({ 271 | markers: m, 272 | audioUrl: audioUrl, 273 | album, 274 | textArry, 275 | }) 276 | } 277 | 278 | 279 | }, 280 | getSXDData: function () { 281 | return ({ 282 | "code": 0, 283 | "msg": "", 284 | "data": [{ 285 | "info_id": "1", 286 | "icon": "https://industry.map.qq.com/cloud/miniapp/museum/san/point/1.png", 287 | "title": "开场白", 288 | "floor": "F1", 289 | "location": { 290 | "lat": 31.002354, 291 | "lon": 104.22068 292 | }, 293 | "album": ["https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659642559_iXZFKZra.JPG"], 294 | "audio": { 295 | "url": "https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659609114_Qhc33Ns5.mp3", 296 | "time": 114 297 | } 298 | }, 299 | { 300 | "info_id": "2", 301 | "icon": "https://industry.map.qq.com/cloud/miniapp/museum/san/point/1.png", 302 | "title": "开场白2", 303 | "floor": "F1", 304 | "location": { 305 | "lat": 31.002354, 306 | "lon": 104.22098 307 | }, 308 | "album": ["https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659642559_iXZFKZra.JPG"], 309 | "audio": { 310 | "url": "https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659609114_Qhc33Ns5.mp3", 311 | "time": 114 312 | } 313 | }] 314 | }) 315 | }, 316 | //播放 317 | audioPlay: function () { 318 | this.createAudio(); 319 | //播放音频 320 | this.innerAudioContext.play(); 321 | //设置当前播放按钮状态切换 322 | this.setData({ 323 | isPlay: true 324 | }) 325 | }, 326 | 327 | // 停止播放 328 | audioPause() { 329 | //设置当前播放按钮状态切换 330 | this.setData({ 331 | isPlay: false 332 | }) 333 | //暂停音频 334 | this.innerAudioContext.pause(); 335 | 336 | }, 337 | 338 | // 结束音频 339 | end: function (e) { 340 | //暂停音频 341 | this.innerAudioContext.pause(); 342 | }, 343 | onHide: function () { 344 | // 结束音频 345 | this.end(); 346 | }, 347 | onUnload: function () { 348 | // 结束音频 349 | this.end(); 350 | }, 351 | 352 | 353 | calDis(start, end) { 354 | console.log(start, end); 355 | //调用距离计算接口 356 | wx.request({ 357 | url: 'https://apis.map.qq.com/ws/distance/v1/matrix?mode=walking', 358 | method: 'POST', 359 | data: { 360 | key: 'U2YBZ-W4MEN-4NSFM-SYVGY-7KP4K-XQBWQ', 361 | from: start, //若起点有数据则采用起点坐标,若为空默认当前地址 362 | to: end, //终点坐标 363 | }, 364 | header: { 365 | 'content-type': 'application/json' // 根据需求设置请求头 366 | }, 367 | success: function (res, data) { 368 | console.log(res.data.result); 369 | const { rows } = res.data.result; 370 | return (rows[0].elements[0].distance) 371 | // return res.data.result.rows[0].elements[0].distance 372 | }, 373 | fail: function (err) { 374 | console.log(err); 375 | } 376 | }); 377 | 378 | } 379 | }) 380 | -------------------------------------------------------------------------------- /pages/map1/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {}, 3 | "navigationBarTitleText": "三星堆", 4 | "navigationBarBackgroundColor": "#f2ece0", 5 | "navigationBarTextStyle":"black" 6 | 7 | } -------------------------------------------------------------------------------- /pages/map1/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2019 13 | 14 | 15 | 16 | 17 | {{speed}}米/秒 18 | 19 | 20 | 21 | 22 | 23 | 24 | {{item}} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {{text}} 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /pages/map1/index.wxss: -------------------------------------------------------------------------------- 1 | /* pages/map1/index.wxss */ 2 | .container { 3 | width: 100vh; 4 | height: 100vh; 5 | background-color: rgb(110, 106, 106); 6 | } 7 | 8 | .page-section-gap { 9 | box-sizing: border-box; 10 | padding: 0 30rpx; 11 | } 12 | 13 | .page-body-button { 14 | margin-bottom: 30rpx; 15 | } 16 | 17 | #myMap { 18 | width: 100vh; 19 | height: 100vh; 20 | } 21 | 22 | .leftControl { 23 | display: block; 24 | position: fixed; 25 | left: 0; 26 | top: 0; 27 | } 28 | 29 | .top { 30 | position: absolute; 31 | left: 0; 32 | display: block; 33 | width: 150rpx; 34 | height: 30px; 35 | border:1px solid white; 36 | /* border-bottom-right-radius: 40rpx; */ 37 | background-color: #fff; 38 | /* border-radius:40rpx; */ 39 | 40 | } 41 | 42 | .sportControl { 43 | display: block; 44 | position: fixed; 45 | left: 15rpx; 46 | top: 5rpx; 47 | /* border: 1px solid black; */ 48 | 49 | } 50 | 51 | .sportimg { 52 | display: block; 53 | width: 45rpx; 54 | height: 45rpx; 55 | } 56 | 57 | .sportText { 58 | position: absolute; 59 | width: 300rpx; 60 | right: 0rpx; 61 | top: 0rpx; 62 | /* border:1px solid red; */ 63 | /* left:-10rpx; */ 64 | background-color: #fff; 65 | z-index: 9999; 66 | } 67 | 68 | .floorControl { 69 | display: block; 70 | width: 120rpx; 71 | height: 440rpx; 72 | /* background-color: #fff; */ 73 | /* border-radius: 12rpx; */ 74 | position: fixed; 75 | left: 0; 76 | top: 0; 77 | } 78 | 79 | 80 | .select { 81 | box-sizing: border-box; 82 | width: 100%; 83 | height: 70rpx; 84 | border: 1px solid #efefef; 85 | border-radius: 8rpx; 86 | display: flex; 87 | align-items: center; 88 | padding: 0 20rpx; 89 | } 90 | 91 | .select_text { 92 | /* display: block; */ 93 | font-size: 30rpx; 94 | flex: 1; 95 | /* margin-right: 10rpx; */ 96 | } 97 | 98 | .select_img { 99 | width: 55rpx; 100 | height: 55rpx; 101 | display: block; 102 | transition: 0.9s; 103 | /* flex:1; */ 104 | } 105 | 106 | .select_img_rotate { 107 | transform: rotate(180deg); 108 | } 109 | 110 | .option_box { 111 | position: absolute; 112 | top: 70rpx; 113 | width: 100%; 114 | text-align: center; 115 | border: 1px solid #efefef; 116 | box-sizing: border-box; 117 | height: 0; 118 | overflow-y: auto; 119 | border-top: 0; 120 | transition: height 0.3s; 121 | } 122 | 123 | .option { 124 | display: block; 125 | line-height: 40rpx; 126 | font-size: 30rpx; 127 | background-color: #fff; 128 | border-bottom: 1px solid #efefef; 129 | padding: 10rpx; 130 | z-index: 999; 131 | } 132 | 133 | .bContent { 134 | position: absolute; 135 | display: flex; 136 | bottom: -10rpx; 137 | left: 0; 138 | width: 100%; 139 | height: 500rpx; 140 | margin: 0rpx auto; 141 | background-color:#f2ece0; 142 | /* border-radius: 20rpx; */ 143 | } 144 | 145 | .img-container { 146 | position: relative; 147 | /* display:inline; */ 148 | /* background-color: rgb(226, 154, 154); */ 149 | width: 20%; 150 | height: 100%; 151 | display: flex; 152 | justify-content: center; 153 | align-items: center; 154 | /* flex:1; */ 155 | } 156 | 157 | .albumImg { 158 | 159 | position: absolute; 160 | width: 80rpx; 161 | height: 80rpx; 162 | border-radius: 50%; 163 | } 164 | .icon-container{ 165 | width:40%; 166 | height: 100%; 167 | position: absolute; 168 | left:60%; 169 | top:0rpx; 170 | /* background-color: rgb(110, 104, 104); */ 171 | } 172 | .text-container{ 173 | width:40%; 174 | height: 100%; 175 | position: absolute; 176 | left:20%; 177 | top:0rpx; 178 | /* background-color: red; */ 179 | display: flex; 180 | align-items: center; 181 | } 182 | 183 | .text { 184 | 185 | 186 | } 187 | 188 | .icon1 { 189 | position: absolute; 190 | left:80rpx; 191 | top:20rpx; 192 | width:50rpx; 193 | height:50rpx; 194 | 195 | } 196 | 197 | .icon2 { 198 | width:55rpx; 199 | height:55rpx; 200 | position: absolute; 201 | left: 200rpx; 202 | top: 20rpx; 203 | 204 | } 205 | 206 | /* Components/Floor/Floor.wxss */ 207 | .floor-container { 208 | position: fixed; 209 | background-color: #fff; 210 | width: 80rpx; 211 | left: 0rpx; 212 | top: 300rpx; 213 | border-radius: 20rpx; 214 | } 215 | 216 | .box { 217 | display: flex; 218 | justify-content: center; 219 | align-items: center; 220 | text-align: center; 221 | width: 100%; 222 | height: 80rpx; 223 | border-bottom: 1rpx solid rgb(206, 208, 209); 224 | } -------------------------------------------------------------------------------- /pages/map2/index.js: -------------------------------------------------------------------------------- 1 | let QQMapWX = require("../../utils/qqmap/qqmap-wx-jssdk.min"); 2 | let qqmapsdk; 3 | Page({ 4 | data: { 5 | latitude: 34.383684, 6 | longitude: 109.281235, 7 | src: '', 8 | idChoosed: '-1', 9 | isPlay: false, 10 | isChoosed: '0', 11 | bg: '#ffffff',//'#99963f' 12 | audioUrl: [], 13 | album: [], 14 | albumSrc: '', 15 | iconUrl: '/images/讲解点.png', 16 | isTrue: true, 17 | textArry: [], 18 | text: '111', 19 | polygons: [ 20 | { 21 | fillColor: 'transparent', 22 | level: 'aboveroads', 23 | strokeColor:'#f48e4d', 24 | strokeWidth:4, 25 | points: [ 26 | { latitude: 34.392962, longitude: 109.284232 }, 27 | { latitude: 34.389704, longitude: 109.284317 }, 28 | { latitude: 34.389881, longitude: 109.284060 }, 29 | { latitude: 34.389633, longitude: 109.284489 }, 30 | { latitude: 34.389562, longitude: 109.282730 }, 31 | { latitude: 34.389066, longitude: 109.281313 }, 32 | { latitude: 34.385029, longitude: 109.281142 }, 33 | { latitude: 34.385170, longitude: 109.275563 }, 34 | { latitude: 34.383895, longitude: 109.275477 }, 35 | { latitude: 34.383754, longitude: 109.274189 }, 36 | { latitude: 34.383045, longitude: 109.274876 }, 37 | { latitude: 34.382975, longitude: 109.275649 }, 38 | { latitude: 34.381841, longitude: 109.275734 }, 39 | { latitude: 34.381629, longitude: 109.284060 }, 40 | { latitude: 34.382620, longitude: 109.284146 }, 41 | { latitude: 34.382620, longitude: 109.286635 }, 42 | { latitude: 34.390341, longitude: 109.286721 }, 43 | { latitude: 34.391049, longitude: 109.288352 }, 44 | { latitude: 34.393245, longitude: 109.288352 }, 45 | { latitude: 34.393032, longitude: 109.286978 }, 46 | { latitude: 34.392678, longitude: 109.286892 }, 47 | { latitude: 34.392678, longitude: 109.286721 }, 48 | { latitude: 34.393032, longitude: 109.286721 }, 49 | { latitude: 34.393032, longitude: 109.286463 }, 50 | { latitude: 34.392395, longitude: 109.286463 }, 51 | { latitude: 34.392395, longitude: 109.285691 }, 52 | { latitude: 34.392820, longitude: 109.285691 } 53 | ] 54 | }, 55 | 56 | ], 57 | markers: [], 58 | showSport: false, 59 | showButtom: false, 60 | lastTimestamp: 0, 61 | lastLocation: null, 62 | speed: '0.00', 63 | }, 64 | 65 | 66 | showS() { 67 | this.setData({ 68 | showSport: !this.data.showSport 69 | }); 70 | }, 71 | onReady: function (e) { 72 | console.log('111'); 73 | wx.showLoading({ 74 | title: '加载中', 75 | }) 76 | 77 | setTimeout(function () { 78 | wx.hideLoading() 79 | }, 2000) 80 | this.mapCtx = wx.createMapContext('myMap'); 81 | this.makeMarks(); 82 | console.log(this.data.markers); 83 | this.createAudio(); 84 | qqmapsdk = new QQMapWX({ 85 | key: 'U2YBZ-W4MEN-4NSFM-SYVGY-7KP4K-XQBWQ' // 必填 86 | }) 87 | setInterval(this.calculateSpeed, 5000); 88 | }, 89 | //创建语音示例进行播放 90 | createAudio(e) { 91 | //创建内部 audio 上下文 InnerAudioContext 对象。 92 | this.innerAudioContext = wx.createInnerAudioContext(); 93 | // 发生错误触发 94 | this.innerAudioContext.onError(function (res) { }) 95 | //设置音频地址 96 | this.innerAudioContext.src = this.data.src; 97 | }, 98 | daohang: function () { 99 | console.log('11122') 100 | const { idChoosed, markers } = this.data; 101 | this.setData({ 102 | showButtom: false, 103 | }) 104 | this.mapCtx.openMapApp({ 105 | longitude: markers[idChoosed - 1].longitude, 106 | latitude: markers[idChoosed - 1].latitude, 107 | destination: markers[idChoosed - 1].title, 108 | success: function (res) { console.log(res) }, 109 | fail: function (res) { console.log(res) }, 110 | complete: function (res) { console.log(res) }, 111 | 112 | } 113 | ) 114 | }, 115 | // 声明变量用于存储上一次获取位置信息的时间戳和位置信息 116 | 117 | 118 | 119 | 120 | // 获取位置信息并计算运动速率 121 | async calculateSpeed() { 122 | let { lastTimestamp, lastLocation } = this.data; 123 | wx.getLocation({ 124 | type: 'gcj02', // 使用国测局坐标系 125 | success: (res) => { 126 | const currentTimestamp = new Date().getTime(); // 获取当前时间戳 127 | const currentLocation = res; 128 | // 如果是第一次获取位置信息,或者距离上次获取位置信息时间超过5秒,则重新设置lastTimestamp和lastLocation 129 | if (lastTimestamp === 0 || currentTimestamp - lastTimestamp >= 5000) { 130 | this.setData({ 131 | lastTimestamp: currentTimestamp, 132 | lastLocation: currentLocation, 133 | }) 134 | console.log("尚未计算速率,等待下一次获取位置信息...", lastTimestamp, lastLocation); 135 | return; 136 | } 137 | wx.request({ 138 | url: 'https://apis.map.qq.com/ws/distance/v1/matrix?mode=walking', 139 | method: 'POST', 140 | data: { 141 | key: 'U2YBZ-W4MEN-4NSFM-SYVGY-7KP4K-XQBWQ', 142 | from: `${lastLocation.latitude},${lastLocation.longitude}`, //若起点有数据则采用起点坐标,若为空默认当前地址 143 | to: `${currentLocation.latitude},${currentLocation.longitude}`, //终点坐标 144 | }, 145 | header: { 146 | 'content-type': 'application/json' // 根据需求设置请求头 147 | }, 148 | success: (res) => { 149 | console.log(res.data.result); 150 | const { rows } = res.data.result; 151 | const distance = rows[0].elements[0].distance; 152 | // return res.data.result.rows[0].elements[0].distance 153 | // 计算速率(米/秒) 154 | const timeDifferenceInSeconds = (currentTimestamp - lastTimestamp) / 1000; 155 | const speed = distance / timeDifferenceInSeconds; 156 | 157 | // 更新lastTimestamp和lastLocation 158 | this.setData({ 159 | lastTimestamp: currentTimestamp, 160 | lastLocation: currentLocation, 161 | speed: speed.toFixed(2), 162 | }) 163 | 164 | console.log("当前速率为:" + speed.toFixed(2) + " 米/秒"); 165 | }, 166 | fail: function (err) { 167 | console.log(err); 168 | } 169 | }); 170 | }, 171 | fail: function (res) { 172 | console.log("获取位置信息失败:" + res.errMsg); 173 | } 174 | }); 175 | } 176 | , 177 | 178 | 179 | audio() { 180 | if (!this.data.isPlay) { 181 | // const id = Number(e.detail.markerId); 182 | this.setData({ 183 | iconUrl: '/images/讲解.png', 184 | 185 | }) 186 | this.audioPlay(); 187 | 188 | } 189 | else { 190 | this.setData({ 191 | iconUrl: '/images/讲解点.png', 192 | 193 | }) 194 | this.audioPause(); 195 | } 196 | }, 197 | mTap: function (e) { 198 | const id = Number(e.detail.markerId); 199 | const { showButtom, idChoosed } = this.data; 200 | this.end() 201 | if (showButtom && id !== idChoosed) { 202 | this.setData({ 203 | showButtom: true, 204 | src: this.data.audioUrl[id], 205 | albumSrc: this.data.album[id], 206 | text: this.data.textArry[id], 207 | idChoosed: id, 208 | isPlay: false, 209 | iconUrl: '/images/讲解点.png', 210 | }) 211 | } 212 | else { 213 | this.setData({ 214 | showButtom: !showButtom, 215 | src: this.data.audioUrl[id], 216 | albumSrc: this.data.album[id], 217 | text: this.data.textArry[id], 218 | idChoosed: id, 219 | isPlay: false, 220 | iconUrl: '/images/讲解点.png', 221 | }) 222 | } 223 | 224 | console.log(e.detail.markerId); 225 | 226 | }, 227 | makeMarks: function () { 228 | const isChoosed = Number(this.data.isChoosed); 229 | const { data } = this.getSXDData(); 230 | this.setData({ 231 | markers: [], 232 | }) 233 | if (data.length != 0) { 234 | const m = []; 235 | const audioUrl = []; 236 | const album = []; 237 | const textArry = []; 238 | data.map((item) => { 239 | 240 | 241 | const id = Number(item.info_id) 242 | const mark = { 243 | width: 36, 244 | height: 36, 245 | id: id, 246 | iconPath: item.icon, 247 | title: item.title, 248 | latitude: item.location.lat, 249 | longitude: item.location.lon, 250 | label:{ 251 | content:item.title, 252 | bgColor:'#efebe1', 253 | borderRadius:20, 254 | textAlign:'center', 255 | padding:5, 256 | } 257 | } 258 | m.push(mark); 259 | audioUrl[id] = item.audio.url; 260 | album[id] = item.album[0]; 261 | textArry[id] = item.title; 262 | 263 | }) 264 | console.log('m', m) 265 | this.setData({ 266 | markers: m, 267 | audioUrl: audioUrl, 268 | album, 269 | textArry, 270 | }) 271 | } 272 | 273 | 274 | }, 275 | getSXDData: function () { 276 | return ({ 277 | "code": 0, 278 | "msg": "", 279 | "data": [{ 280 | "info_id": "1", 281 | "icon": "https://industry.map.qq.com/cloud/miniapp/museum/san/point/1.png", 282 | "title": "开场白", 283 | 284 | "location": { 285 | "lat": 31.002354, 286 | "lon": 104.22068 287 | }, 288 | "album": ["https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659642559_iXZFKZra.JPG"], 289 | "audio": { 290 | "url": "https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659609114_Qhc33Ns5.mp3", 291 | "time": 114 292 | } 293 | }, 294 | { 295 | "info_id": "2", 296 | "icon": "https://industry.map.qq.com/cloud/miniapp/museum/san/point/1.png", 297 | "title": "开场白2", 298 | 299 | "location": { 300 | "lat": 31.002354, 301 | "lon": 104.22098 302 | }, 303 | "album": ["https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659642559_iXZFKZra.JPG"], 304 | "audio": { 305 | "url": "https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659609114_Qhc33Ns5.mp3", 306 | "time": 114 307 | } 308 | }] 309 | }) 310 | }, 311 | //播放 312 | audioPlay: function () { 313 | this.createAudio(); 314 | //播放音频 315 | this.innerAudioContext.play(); 316 | //设置当前播放按钮状态切换 317 | this.setData({ 318 | isPlay: true 319 | }) 320 | }, 321 | 322 | // 停止播放 323 | audioPause() { 324 | //设置当前播放按钮状态切换 325 | this.setData({ 326 | isPlay: false 327 | }) 328 | //暂停音频 329 | this.innerAudioContext.pause(); 330 | 331 | }, 332 | 333 | // 结束音频 334 | end: function (e) { 335 | //暂停音频 336 | this.innerAudioContext.pause(); 337 | }, 338 | onHide: function () { 339 | // 结束音频 340 | this.end(); 341 | }, 342 | onUnload: function () { 343 | // 结束音频 344 | this.end(); 345 | }, 346 | 347 | 348 | calDis(start, end) { 349 | console.log(start, end); 350 | //调用距离计算接口 351 | wx.request({ 352 | url: 'https://apis.map.qq.com/ws/distance/v1/matrix?mode=walking', 353 | method: 'POST', 354 | data: { 355 | key: 'U2YBZ-W4MEN-4NSFM-SYVGY-7KP4K-XQBWQ', 356 | from: start, //若起点有数据则采用起点坐标,若为空默认当前地址 357 | to: end, //终点坐标 358 | }, 359 | header: { 360 | 'content-type': 'application/json' // 根据需求设置请求头 361 | }, 362 | success: function (res, data) { 363 | console.log(res.data.result); 364 | const { rows } = res.data.result; 365 | return (rows[0].elements[0].distance) 366 | // return res.data.result.rows[0].elements[0].distance 367 | }, 368 | fail: function (err) { 369 | console.log(err); 370 | } 371 | }); 372 | 373 | } 374 | }) 375 | -------------------------------------------------------------------------------- /pages/map2/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {}, 3 | "navigationBarTitleText": "兵马俑博物馆", 4 | "navigationBarBackgroundColor": "#f2ece0", 5 | "navigationBarTextStyle":"black" 6 | 7 | } -------------------------------------------------------------------------------- /pages/map2/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2019 13 | 14 | 15 | 16 | 17 | {{speed}}米/秒 18 | 19 | 20 | 21 | 22 | 23 | 24 | {{item}} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {{text}} 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /pages/map2/index.wxss: -------------------------------------------------------------------------------- 1 | /* pages/map1/index.wxss */ 2 | .container { 3 | width: 100vh; 4 | height: 100vh; 5 | background-color: rgb(110, 106, 106); 6 | } 7 | 8 | .page-section-gap { 9 | box-sizing: border-box; 10 | padding: 0 30rpx; 11 | } 12 | 13 | .page-body-button { 14 | margin-bottom: 30rpx; 15 | } 16 | 17 | #myMap { 18 | width: 100vh; 19 | height: 100vh; 20 | } 21 | 22 | .leftControl { 23 | display: block; 24 | position: fixed; 25 | left: 0; 26 | top: 0; 27 | } 28 | 29 | .top { 30 | position: absolute; 31 | left: 0; 32 | display: block; 33 | width: 150rpx; 34 | height: 30px; 35 | border:1px solid white; 36 | /* border-bottom-right-radius: 40rpx; */ 37 | background-color: #fff; 38 | /* border-radius:40rpx; */ 39 | 40 | } 41 | 42 | .sportControl { 43 | display: block; 44 | position: fixed; 45 | left: 15rpx; 46 | top: 5rpx; 47 | /* border: 1px solid black; */ 48 | 49 | } 50 | 51 | .sportimg { 52 | display: block; 53 | width: 45rpx; 54 | height: 45rpx; 55 | } 56 | 57 | .sportText { 58 | position: absolute; 59 | width: 300rpx; 60 | right: 0rpx; 61 | top: 0rpx; 62 | /* border:1px solid red; */ 63 | /* left:-10rpx; */ 64 | background-color: #fff; 65 | z-index: 9999; 66 | } 67 | 68 | .floorControl { 69 | display: block; 70 | width: 120rpx; 71 | height: 440rpx; 72 | /* background-color: #fff; */ 73 | /* border-radius: 12rpx; */ 74 | position: fixed; 75 | left: 0; 76 | top: 0; 77 | } 78 | 79 | 80 | .select { 81 | box-sizing: border-box; 82 | width: 100%; 83 | height: 70rpx; 84 | border: 1px solid #efefef; 85 | border-radius: 8rpx; 86 | display: flex; 87 | align-items: center; 88 | padding: 0 20rpx; 89 | } 90 | 91 | .select_text { 92 | /* display: block; */ 93 | font-size: 30rpx; 94 | flex: 1; 95 | /* margin-right: 10rpx; */ 96 | } 97 | 98 | .select_img { 99 | width: 55rpx; 100 | height: 55rpx; 101 | display: block; 102 | transition: 0.9s; 103 | /* flex:1; */ 104 | } 105 | 106 | .select_img_rotate { 107 | transform: rotate(180deg); 108 | } 109 | 110 | .option_box { 111 | position: absolute; 112 | top: 70rpx; 113 | width: 100%; 114 | text-align: center; 115 | border: 1px solid #efefef; 116 | box-sizing: border-box; 117 | height: 0; 118 | overflow-y: auto; 119 | border-top: 0; 120 | transition: height 0.3s; 121 | } 122 | 123 | .option { 124 | display: block; 125 | line-height: 40rpx; 126 | font-size: 30rpx; 127 | background-color: #fff; 128 | border-bottom: 1px solid #efefef; 129 | padding: 10rpx; 130 | z-index: 999; 131 | } 132 | 133 | .bContent { 134 | position: absolute; 135 | display: flex; 136 | bottom: -10rpx; 137 | left: 0; 138 | width: 100%; 139 | height: 500rpx; 140 | margin: 0rpx auto; 141 | background-color:#f2ece0; 142 | /* border-radius: 20rpx; */ 143 | } 144 | 145 | .img-container { 146 | position: relative; 147 | /* display:inline; */ 148 | /* background-color: rgb(226, 154, 154); */ 149 | width: 20%; 150 | height: 100%; 151 | display: flex; 152 | justify-content: center; 153 | align-items: center; 154 | /* flex:1; */ 155 | } 156 | 157 | .albumImg { 158 | 159 | position: absolute; 160 | width: 80rpx; 161 | height: 80rpx; 162 | border-radius: 50%; 163 | } 164 | .icon-container{ 165 | width:40%; 166 | height: 100%; 167 | position: absolute; 168 | left:60%; 169 | top:0rpx; 170 | /* background-color: rgb(110, 104, 104); */ 171 | } 172 | .text-container{ 173 | width:40%; 174 | height: 100%; 175 | position: absolute; 176 | left:20%; 177 | top:0rpx; 178 | /* background-color: red; */ 179 | display: flex; 180 | align-items: center; 181 | } 182 | 183 | .text { 184 | 185 | 186 | } 187 | 188 | .icon1 { 189 | position: absolute; 190 | left:80rpx; 191 | top:20rpx; 192 | width:50rpx; 193 | height:50rpx; 194 | 195 | } 196 | 197 | .icon2 { 198 | width:55rpx; 199 | height:55rpx; 200 | position: absolute; 201 | left: 200rpx; 202 | top: 20rpx; 203 | 204 | } 205 | 206 | /* Components/Floor/Floor.wxss */ 207 | .floor-container { 208 | position: fixed; 209 | background-color: #fff; 210 | width: 80rpx; 211 | left: 0rpx; 212 | top: 300rpx; 213 | border-radius: 20rpx; 214 | } 215 | 216 | .box { 217 | display: flex; 218 | justify-content: center; 219 | align-items: center; 220 | text-align: center; 221 | width: 100%; 222 | height: 80rpx; 223 | border-bottom: 1rpx solid rgb(206, 208, 209); 224 | } -------------------------------------------------------------------------------- /pages/map3/index.js: -------------------------------------------------------------------------------- 1 | let QQMapWX = require("../../utils/qqmap/qqmap-wx-jssdk.min"); 2 | let qqmapsdk; 3 | Page({ 4 | data: { 5 | latitude: 39.91799, 6 | longitude: 116.397027, 7 | src: '', 8 | idChoosed: '-1', 9 | isPlay: false, 10 | isChoosed: '0', 11 | bg: '#ffffff',//'#99963f' 12 | audioUrl: [], 13 | album: [], 14 | albumSrc: '', 15 | iconUrl: '/images/讲解点.png', 16 | isTrue: true, 17 | textArry: [], 18 | text: '111', 19 | polygons: [ 20 | { 21 | fillColor: 'transparent', 22 | level: 'aboveroads', 23 | strokeColor:'#f48e4d', 24 | strokeWidth:4, 25 | points: [ 26 | { latitude: 39.922376, longitude: 116.392201 }, 27 | { latitude: 39.913489, longitude: 116.392545 }, 28 | { latitude: 39.913555, longitude: 116.396064 }, 29 | { latitude: 39.913028, longitude: 116.396150 }, 30 | { latitude: 39.913028, longitude: 116.398381 }, 31 | { latitude: 39.913555, longitude: 116.398467 }, 32 | { latitude: 39.913752, longitude: 116.401986 }, 33 | { latitude: 39.922902, longitude: 116.401557 } 34 | ] 35 | }, 36 | 37 | ], 38 | markers: [], 39 | showSport: false, 40 | showButtom: false, 41 | lastTimestamp: 0, 42 | lastLocation: null, 43 | speed: '0.00', 44 | }, 45 | 46 | 47 | showS() { 48 | this.setData({ 49 | showSport: !this.data.showSport 50 | }); 51 | }, 52 | onReady: function (e) { 53 | console.log('111'); 54 | wx.showLoading({ 55 | title: '加载中', 56 | }) 57 | 58 | setTimeout(function () { 59 | wx.hideLoading() 60 | }, 2000) 61 | this.mapCtx = wx.createMapContext('myMap'); 62 | this.makeMarks(); 63 | console.log(this.data.markers); 64 | this.createAudio(); 65 | qqmapsdk = new QQMapWX({ 66 | key: 'U2YBZ-W4MEN-4NSFM-SYVGY-7KP4K-XQBWQ' // 必填 67 | }) 68 | setInterval(this.calculateSpeed, 5000); 69 | }, 70 | //创建语音示例进行播放 71 | createAudio(e) { 72 | //创建内部 audio 上下文 InnerAudioContext 对象。 73 | this.innerAudioContext = wx.createInnerAudioContext(); 74 | // 发生错误触发 75 | this.innerAudioContext.onError(function (res) { }) 76 | //设置音频地址 77 | this.innerAudioContext.src = this.data.src; 78 | }, 79 | daohang: function () { 80 | console.log('11122') 81 | const { idChoosed, markers } = this.data; 82 | this.setData({ 83 | showButtom: false, 84 | }) 85 | this.mapCtx.openMapApp({ 86 | longitude: markers[idChoosed - 1].longitude, 87 | latitude: markers[idChoosed - 1].latitude, 88 | destination: markers[idChoosed - 1].title, 89 | success: function (res) { console.log(res) }, 90 | fail: function (res) { console.log(res) }, 91 | complete: function (res) { console.log(res) }, 92 | 93 | } 94 | ) 95 | }, 96 | // 声明变量用于存储上一次获取位置信息的时间戳和位置信息 97 | 98 | 99 | 100 | 101 | // 获取位置信息并计算运动速率 102 | async calculateSpeed() { 103 | let { lastTimestamp, lastLocation } = this.data; 104 | wx.getLocation({ 105 | type: 'gcj02', // 使用国测局坐标系 106 | success: (res) => { 107 | const currentTimestamp = new Date().getTime(); // 获取当前时间戳 108 | const currentLocation = res; 109 | // 如果是第一次获取位置信息,或者距离上次获取位置信息时间超过5秒,则重新设置lastTimestamp和lastLocation 110 | if (lastTimestamp === 0 || currentTimestamp - lastTimestamp >= 5000) { 111 | this.setData({ 112 | lastTimestamp: currentTimestamp, 113 | lastLocation: currentLocation, 114 | }) 115 | console.log("尚未计算速率,等待下一次获取位置信息...", lastTimestamp, lastLocation); 116 | return; 117 | } 118 | wx.request({ 119 | url: 'https://apis.map.qq.com/ws/distance/v1/matrix?mode=walking', 120 | method: 'POST', 121 | data: { 122 | key: 'U2YBZ-W4MEN-4NSFM-SYVGY-7KP4K-XQBWQ', 123 | from: `${lastLocation.latitude},${lastLocation.longitude}`, //若起点有数据则采用起点坐标,若为空默认当前地址 124 | to: `${currentLocation.latitude},${currentLocation.longitude}`, //终点坐标 125 | }, 126 | header: { 127 | 'content-type': 'application/json' // 根据需求设置请求头 128 | }, 129 | success: (res) => { 130 | console.log(res.data.result); 131 | const { rows } = res.data.result; 132 | const distance = rows[0].elements[0].distance; 133 | // return res.data.result.rows[0].elements[0].distance 134 | // 计算速率(米/秒) 135 | const timeDifferenceInSeconds = (currentTimestamp - lastTimestamp) / 1000; 136 | const speed = distance / timeDifferenceInSeconds; 137 | 138 | // 更新lastTimestamp和lastLocation 139 | this.setData({ 140 | lastTimestamp: currentTimestamp, 141 | lastLocation: currentLocation, 142 | speed: speed.toFixed(2), 143 | }) 144 | 145 | console.log("当前速率为:" + speed.toFixed(2) + " 米/秒"); 146 | }, 147 | fail: function (err) { 148 | console.log(err); 149 | } 150 | }); 151 | }, 152 | fail: function (res) { 153 | console.log("获取位置信息失败:" + res.errMsg); 154 | } 155 | }); 156 | } 157 | , 158 | 159 | 160 | audio() { 161 | if (!this.data.isPlay) { 162 | // const id = Number(e.detail.markerId); 163 | this.setData({ 164 | iconUrl: '/images/讲解.png', 165 | 166 | }) 167 | this.audioPlay(); 168 | 169 | } 170 | else { 171 | this.setData({ 172 | iconUrl: '/images/讲解点.png', 173 | 174 | }) 175 | this.audioPause(); 176 | } 177 | }, 178 | mTap: function (e) { 179 | const id = Number(e.detail.markerId); 180 | const { showButtom, idChoosed } = this.data; 181 | this.end() 182 | if (showButtom && id !== idChoosed) { 183 | this.setData({ 184 | showButtom: true, 185 | src: this.data.audioUrl[id], 186 | albumSrc: this.data.album[id], 187 | text: this.data.textArry[id], 188 | idChoosed: id, 189 | isPlay: false, 190 | iconUrl: '/images/讲解点.png', 191 | }) 192 | } 193 | else { 194 | this.setData({ 195 | showButtom: !showButtom, 196 | src: this.data.audioUrl[id], 197 | albumSrc: this.data.album[id], 198 | text: this.data.textArry[id], 199 | idChoosed: id, 200 | isPlay: false, 201 | iconUrl: '/images/讲解点.png', 202 | }) 203 | } 204 | 205 | console.log(e.detail.markerId); 206 | 207 | }, 208 | makeMarks: function () { 209 | const isChoosed = Number(this.data.isChoosed); 210 | const { data } = this.getSXDData(); 211 | this.setData({ 212 | markers: [], 213 | }) 214 | if (data.length != 0) { 215 | const m = []; 216 | const audioUrl = []; 217 | const album = []; 218 | const textArry = []; 219 | data.map((item) => { 220 | 221 | 222 | const id = Number(item.info_id) 223 | const mark = { 224 | width: 36, 225 | height: 36, 226 | id: id, 227 | iconPath: item.icon, 228 | title: item.title, 229 | latitude: item.location.lat, 230 | longitude: item.location.lon, 231 | label:{ 232 | content:item.title, 233 | bgColor:'#efebe1', 234 | borderRadius:20, 235 | textAlign:'center', 236 | padding:5, 237 | } 238 | } 239 | m.push(mark); 240 | audioUrl[id] = item.audio.url; 241 | album[id] = item.album[0]; 242 | textArry[id] = item.title; 243 | 244 | }) 245 | console.log('m', m) 246 | this.setData({ 247 | markers: m, 248 | audioUrl: audioUrl, 249 | album, 250 | textArry, 251 | }) 252 | } 253 | 254 | 255 | }, 256 | getSXDData: function () { 257 | return ({ 258 | "code": 0, 259 | "msg": "", 260 | "data": [{ 261 | "info_id": "1", 262 | "icon": "https://industry.map.qq.com/cloud/miniapp/museum/san/point/1.png", 263 | "title": "开场白", 264 | 265 | "location": { 266 | "lat": 31.002354, 267 | "lon": 104.22068 268 | }, 269 | "album": ["https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659642559_iXZFKZra.JPG"], 270 | "audio": { 271 | "url": "https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659609114_Qhc33Ns5.mp3", 272 | "time": 114 273 | } 274 | }, 275 | { 276 | "info_id": "2", 277 | "icon": "https://industry.map.qq.com/cloud/miniapp/museum/san/point/1.png", 278 | "title": "开场白2", 279 | 280 | "location": { 281 | "lat": 31.002354, 282 | "lon": 104.22098 283 | }, 284 | "album": ["https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659642559_iXZFKZra.JPG"], 285 | "audio": { 286 | "url": "https://sxd-tx-1315371622.cos.ap-nanjing.myqcloud.com/cloud/policy/1691659609114_Qhc33Ns5.mp3", 287 | "time": 114 288 | } 289 | }] 290 | }) 291 | }, 292 | //播放 293 | audioPlay: function () { 294 | this.createAudio(); 295 | //播放音频 296 | this.innerAudioContext.play(); 297 | //设置当前播放按钮状态切换 298 | this.setData({ 299 | isPlay: true 300 | }) 301 | }, 302 | 303 | // 停止播放 304 | audioPause() { 305 | //设置当前播放按钮状态切换 306 | this.setData({ 307 | isPlay: false 308 | }) 309 | //暂停音频 310 | this.innerAudioContext.pause(); 311 | 312 | }, 313 | 314 | // 结束音频 315 | end: function (e) { 316 | //暂停音频 317 | this.innerAudioContext.pause(); 318 | }, 319 | onHide: function () { 320 | // 结束音频 321 | this.end(); 322 | }, 323 | onUnload: function () { 324 | // 结束音频 325 | this.end(); 326 | }, 327 | 328 | 329 | calDis(start, end) { 330 | console.log(start, end); 331 | //调用距离计算接口 332 | wx.request({ 333 | url: 'https://apis.map.qq.com/ws/distance/v1/matrix?mode=walking', 334 | method: 'POST', 335 | data: { 336 | key: 'U2YBZ-W4MEN-4NSFM-SYVGY-7KP4K-XQBWQ', 337 | from: start, //若起点有数据则采用起点坐标,若为空默认当前地址 338 | to: end, //终点坐标 339 | }, 340 | header: { 341 | 'content-type': 'application/json' // 根据需求设置请求头 342 | }, 343 | success: function (res, data) { 344 | console.log(res.data.result); 345 | const { rows } = res.data.result; 346 | return (rows[0].elements[0].distance) 347 | // return res.data.result.rows[0].elements[0].distance 348 | }, 349 | fail: function (err) { 350 | console.log(err); 351 | } 352 | }); 353 | 354 | } 355 | }) 356 | -------------------------------------------------------------------------------- /pages/map3/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {}, 3 | "navigationBarTitleText": "故宫博物馆", 4 | "navigationBarBackgroundColor": "#f2ece0", 5 | "navigationBarTextStyle":"black" 6 | 7 | } -------------------------------------------------------------------------------- /pages/map3/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2019 13 | 14 | 15 | 16 | 17 | {{speed}}米/秒 18 | 19 | 20 | 21 | 22 | 23 | 24 | {{item}} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {{text}} 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /pages/map3/index.wxss: -------------------------------------------------------------------------------- 1 | /* pages/map1/index.wxss */ 2 | .container { 3 | width: 100vh; 4 | height: 100vh; 5 | background-color: rgb(110, 106, 106); 6 | } 7 | 8 | .page-section-gap { 9 | box-sizing: border-box; 10 | padding: 0 30rpx; 11 | } 12 | 13 | .page-body-button { 14 | margin-bottom: 30rpx; 15 | } 16 | 17 | #myMap { 18 | width: 100vh; 19 | height: 100vh; 20 | } 21 | 22 | .leftControl { 23 | display: block; 24 | position: fixed; 25 | left: 0; 26 | top: 0; 27 | } 28 | 29 | .top { 30 | position: absolute; 31 | left: 0; 32 | display: block; 33 | width: 150rpx; 34 | height: 30px; 35 | border:1px solid white; 36 | /* border-bottom-right-radius: 40rpx; */ 37 | background-color: #fff; 38 | /* border-radius:40rpx; */ 39 | 40 | } 41 | 42 | .sportControl { 43 | display: block; 44 | position: fixed; 45 | left: 15rpx; 46 | top: 5rpx; 47 | /* border: 1px solid black; */ 48 | 49 | } 50 | 51 | .sportimg { 52 | display: block; 53 | width: 45rpx; 54 | height: 45rpx; 55 | } 56 | 57 | .sportText { 58 | position: absolute; 59 | width: 300rpx; 60 | right: 0rpx; 61 | top: 0rpx; 62 | /* border:1px solid red; */ 63 | /* left:-10rpx; */ 64 | background-color: #fff; 65 | z-index: 9999; 66 | } 67 | 68 | .floorControl { 69 | display: block; 70 | width: 120rpx; 71 | height: 440rpx; 72 | /* background-color: #fff; */ 73 | /* border-radius: 12rpx; */ 74 | position: fixed; 75 | left: 0; 76 | top: 0; 77 | } 78 | 79 | 80 | .select { 81 | box-sizing: border-box; 82 | width: 100%; 83 | height: 70rpx; 84 | border: 1px solid #efefef; 85 | border-radius: 8rpx; 86 | display: flex; 87 | align-items: center; 88 | padding: 0 20rpx; 89 | } 90 | 91 | .select_text { 92 | /* display: block; */ 93 | font-size: 30rpx; 94 | flex: 1; 95 | /* margin-right: 10rpx; */ 96 | } 97 | 98 | .select_img { 99 | width: 55rpx; 100 | height: 55rpx; 101 | display: block; 102 | transition: 0.9s; 103 | /* flex:1; */ 104 | } 105 | 106 | .select_img_rotate { 107 | transform: rotate(180deg); 108 | } 109 | 110 | .option_box { 111 | position: absolute; 112 | top: 70rpx; 113 | width: 100%; 114 | text-align: center; 115 | border: 1px solid #efefef; 116 | box-sizing: border-box; 117 | height: 0; 118 | overflow-y: auto; 119 | border-top: 0; 120 | transition: height 0.3s; 121 | } 122 | 123 | .option { 124 | display: block; 125 | line-height: 40rpx; 126 | font-size: 30rpx; 127 | background-color: #fff; 128 | border-bottom: 1px solid #efefef; 129 | padding: 10rpx; 130 | z-index: 999; 131 | } 132 | 133 | .bContent { 134 | position: absolute; 135 | display: flex; 136 | bottom: -10rpx; 137 | left: 0; 138 | width: 100%; 139 | height: 500rpx; 140 | margin: 0rpx auto; 141 | background-color:#f2ece0; 142 | /* border-radius: 20rpx; */ 143 | } 144 | 145 | .img-container { 146 | position: relative; 147 | /* display:inline; */ 148 | /* background-color: rgb(226, 154, 154); */ 149 | width: 20%; 150 | height: 100%; 151 | display: flex; 152 | justify-content: center; 153 | align-items: center; 154 | /* flex:1; */ 155 | } 156 | 157 | .albumImg { 158 | 159 | position: absolute; 160 | width: 80rpx; 161 | height: 80rpx; 162 | border-radius: 50%; 163 | } 164 | .icon-container{ 165 | width:40%; 166 | height: 100%; 167 | position: absolute; 168 | left:60%; 169 | top:0rpx; 170 | /* background-color: rgb(110, 104, 104); */ 171 | } 172 | .text-container{ 173 | width:40%; 174 | height: 100%; 175 | position: absolute; 176 | left:20%; 177 | top:0rpx; 178 | /* background-color: red; */ 179 | display: flex; 180 | align-items: center; 181 | } 182 | 183 | .text { 184 | 185 | 186 | } 187 | 188 | .icon1 { 189 | position: absolute; 190 | left:80rpx; 191 | top:20rpx; 192 | width:50rpx; 193 | height:50rpx; 194 | 195 | } 196 | 197 | .icon2 { 198 | width:55rpx; 199 | height:55rpx; 200 | position: absolute; 201 | left: 200rpx; 202 | top: 20rpx; 203 | 204 | } 205 | 206 | /* Components/Floor/Floor.wxss */ 207 | .floor-container { 208 | position: fixed; 209 | background-color: #fff; 210 | width: 80rpx; 211 | left: 0rpx; 212 | top: 300rpx; 213 | border-radius: 20rpx; 214 | } 215 | 216 | .box { 217 | display: flex; 218 | justify-content: center; 219 | align-items: center; 220 | text-align: center; 221 | width: 100%; 222 | height: 80rpx; 223 | border-bottom: 1rpx solid rgb(206, 208, 209); 224 | } -------------------------------------------------------------------------------- /pages/sos/index.js: -------------------------------------------------------------------------------- 1 | // pages/sos/index.js 2 | Page({ 3 | 4 | /** 5 | * 页面的初始数据 6 | */ 7 | data: { 8 | 9 | }, 10 | 11 | /** 12 | * 生命周期函数--监听页面加载 13 | */ 14 | onLoad(options) { 15 | 16 | }, 17 | boda(){ 18 | wx.makePhoneCall({ 19 | phoneNumber: '110' //仅为示例,并非真实的电话号码 20 | }) 21 | }, 22 | /** 23 | * 生命周期函数--监听页面初次渲染完成 24 | */ 25 | onReady() { 26 | 27 | }, 28 | 29 | /** 30 | * 生命周期函数--监听页面显示 31 | */ 32 | onShow() { 33 | 34 | }, 35 | 36 | /** 37 | * 生命周期函数--监听页面隐藏 38 | */ 39 | onHide() { 40 | 41 | }, 42 | 43 | /** 44 | * 生命周期函数--监听页面卸载 45 | */ 46 | onUnload() { 47 | 48 | }, 49 | 50 | /** 51 | * 页面相关事件处理函数--监听用户下拉动作 52 | */ 53 | onPullDownRefresh() { 54 | 55 | }, 56 | 57 | /** 58 | * 页面上拉触底事件的处理函数 59 | */ 60 | onReachBottom() { 61 | 62 | }, 63 | 64 | /** 65 | * 用户点击右上角分享 66 | */ 67 | onShareAppMessage() { 68 | 69 | } 70 | }) -------------------------------------------------------------------------------- /pages/sos/index.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "navigationBarTitleText": "一键呼叫", 4 | "navigationBarBackgroundColor": "#d62323" 5 | } -------------------------------------------------------------------------------- /pages/sos/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /pages/sos/index.wxss: -------------------------------------------------------------------------------- 1 | .container{ 2 | width: 100%; 3 | height:100%; 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | } 8 | .call{ 9 | position: absolute; 10 | top:400rpx; 11 | display: flex; 12 | width: 400rpx; 13 | height:360rpx; 14 | font-size: 60rpx; 15 | border-radius:100%; 16 | background-color: rgb(214, 35, 35); 17 | color: white; 18 | justify-content: center; 19 | align-items: center; 20 | } -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileType": "miniprogram", 3 | "libVersion": "trial", 4 | "packOptions": { 5 | "ignore": [], 6 | "include": [] 7 | }, 8 | "setting": { 9 | "coverView": true, 10 | "es6": true, 11 | "postcss": true, 12 | "minified": true, 13 | "enhance": true, 14 | "showShadowRootInWxmlPanel": true, 15 | "packNpmRelationList": [], 16 | "babelSetting": { 17 | "ignore": [], 18 | "disablePlugins": [], 19 | "outputPath": "" 20 | } 21 | }, 22 | "condition": {}, 23 | "editorSetting": { 24 | "tabIndent": "auto", 25 | "tabSize": 2 26 | }, 27 | "appid": "wxf58f345c9f21d72d" 28 | } -------------------------------------------------------------------------------- /project.private.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", 3 | "projectname": "Intelligent%20scenic%20spot%20navigation", 4 | "setting": { 5 | "compileHotReLoad": true, 6 | "bigPackageSizeSupport": true 7 | } 8 | } -------------------------------------------------------------------------------- /sitemap.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", 3 | "rules": [{ 4 | "action": "allow", 5 | "page": "*" 6 | }] 7 | } -------------------------------------------------------------------------------- /utils/qqmap/qqmap-wx-jssdk.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 微信小程序JavaScriptSDK 3 | * 4 | * @version 1.2 5 | * @date 2019-03-06 6 | */ 7 | 8 | var ERROR_CONF = { 9 | KEY_ERR: 311, 10 | KEY_ERR_MSG: 'key格式错误', 11 | PARAM_ERR: 310, 12 | PARAM_ERR_MSG: '请求参数信息有误', 13 | SYSTEM_ERR: 600, 14 | SYSTEM_ERR_MSG: '系统错误', 15 | WX_ERR_CODE: 1000, 16 | WX_OK_CODE: 200 17 | }; 18 | var BASE_URL = 'https://apis.map.qq.com/ws/'; 19 | var URL_SEARCH = BASE_URL + 'place/v1/search'; 20 | var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion'; 21 | var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/'; 22 | var URL_CITY_LIST = BASE_URL + 'district/v1/list'; 23 | var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren'; 24 | var URL_DISTANCE = BASE_URL + 'distance/v1/'; 25 | var URL_DIRECTION = BASE_URL + 'direction/v1/'; 26 | var MODE = { 27 | driving: 'driving', 28 | transit: 'transit' 29 | }; 30 | var EARTH_RADIUS = 6378136.49; 31 | var Utils = { 32 | /** 33 | * md5加密方法 34 | * 版权所有©2011 Sebastian Tschan,https://blueimp.net 35 | */ 36 | safeAdd(x, y) { 37 | var lsw = (x & 0xffff) + (y & 0xffff); 38 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 39 | return (msw << 16) | (lsw & 0xffff); 40 | }, 41 | bitRotateLeft(num, cnt) { 42 | return (num << cnt) | (num >>> (32 - cnt)); 43 | }, 44 | md5cmn(q, a, b, x, s, t) { 45 | return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b); 46 | }, 47 | md5ff(a, b, c, d, x, s, t) { 48 | return this.md5cmn((b & c) | (~b & d), a, b, x, s, t); 49 | }, 50 | md5gg(a, b, c, d, x, s, t) { 51 | return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t); 52 | }, 53 | md5hh(a, b, c, d, x, s, t) { 54 | return this.md5cmn(b ^ c ^ d, a, b, x, s, t); 55 | }, 56 | md5ii(a, b, c, d, x, s, t) { 57 | return this.md5cmn(c ^ (b | ~d), a, b, x, s, t); 58 | }, 59 | binlMD5(x, len) { 60 | /* append padding */ 61 | x[len >> 5] |= 0x80 << (len % 32); 62 | x[((len + 64) >>> 9 << 4) + 14] = len; 63 | 64 | var i; 65 | var olda; 66 | var oldb; 67 | var oldc; 68 | var oldd; 69 | var a = 1732584193; 70 | var b = -271733879; 71 | var c = -1732584194; 72 | var d = 271733878; 73 | 74 | for (i = 0; i < x.length; i += 16) { 75 | olda = a; 76 | oldb = b; 77 | oldc = c; 78 | oldd = d; 79 | 80 | a = this.md5ff(a, b, c, d, x[i], 7, -680876936); 81 | d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586); 82 | c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819); 83 | b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330); 84 | a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897); 85 | d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426); 86 | c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341); 87 | b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983); 88 | a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416); 89 | d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417); 90 | c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063); 91 | b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162); 92 | a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682); 93 | d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101); 94 | c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290); 95 | b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329); 96 | 97 | a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510); 98 | d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632); 99 | c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713); 100 | b = this.md5gg(b, c, d, a, x[i], 20, -373897302); 101 | a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691); 102 | d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083); 103 | c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335); 104 | b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848); 105 | a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438); 106 | d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690); 107 | c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961); 108 | b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501); 109 | a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467); 110 | d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784); 111 | c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473); 112 | b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734); 113 | 114 | a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558); 115 | d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463); 116 | c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562); 117 | b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556); 118 | a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060); 119 | d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353); 120 | c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632); 121 | b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640); 122 | a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174); 123 | d = this.md5hh(d, a, b, c, x[i], 11, -358537222); 124 | c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979); 125 | b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189); 126 | a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487); 127 | d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835); 128 | c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520); 129 | b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651); 130 | 131 | a = this.md5ii(a, b, c, d, x[i], 6, -198630844); 132 | d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415); 133 | c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905); 134 | b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055); 135 | a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571); 136 | d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606); 137 | c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523); 138 | b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799); 139 | a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359); 140 | d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744); 141 | c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380); 142 | b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649); 143 | a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070); 144 | d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379); 145 | c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259); 146 | b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551); 147 | 148 | a = this.safeAdd(a, olda); 149 | b = this.safeAdd(b, oldb); 150 | c = this.safeAdd(c, oldc); 151 | d = this.safeAdd(d, oldd); 152 | } 153 | return [a, b, c, d]; 154 | }, 155 | binl2rstr(input) { 156 | var i; 157 | var output = ''; 158 | var length32 = input.length * 32; 159 | for (i = 0; i < length32; i += 8) { 160 | output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff); 161 | } 162 | return output; 163 | }, 164 | rstr2binl(input) { 165 | var i; 166 | var output = []; 167 | output[(input.length >> 2) - 1] = undefined; 168 | for (i = 0; i < output.length; i += 1) { 169 | output[i] = 0; 170 | } 171 | var length8 = input.length * 8; 172 | for (i = 0; i < length8; i += 8) { 173 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32); 174 | } 175 | return output; 176 | }, 177 | rstrMD5(s) { 178 | return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8)); 179 | }, 180 | rstrHMACMD5(key, data) { 181 | var i; 182 | var bkey = this.rstr2binl(key); 183 | var ipad = []; 184 | var opad = []; 185 | var hash; 186 | ipad[15] = opad[15] = undefined; 187 | if (bkey.length > 16) { 188 | bkey = this.binlMD5(bkey, key.length * 8); 189 | } 190 | for (i = 0; i < 16; i += 1) { 191 | ipad[i] = bkey[i] ^ 0x36363636; 192 | opad[i] = bkey[i] ^ 0x5c5c5c5c; 193 | } 194 | hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8); 195 | return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128)); 196 | }, 197 | rstr2hex(input) { 198 | var hexTab = '0123456789abcdef'; 199 | var output = ''; 200 | var x; 201 | var i; 202 | for (i = 0; i < input.length; i += 1) { 203 | x = input.charCodeAt(i); 204 | output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f); 205 | } 206 | return output; 207 | }, 208 | str2rstrUTF8(input) { 209 | return unescape(encodeURIComponent(input)); 210 | }, 211 | rawMD5(s) { 212 | return this.rstrMD5(this.str2rstrUTF8(s)); 213 | }, 214 | hexMD5(s) { 215 | return this.rstr2hex(this.rawMD5(s)); 216 | }, 217 | rawHMACMD5(k, d) { 218 | return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d)); 219 | }, 220 | hexHMACMD5(k, d) { 221 | return this.rstr2hex(this.rawHMACMD5(k, d)); 222 | }, 223 | 224 | md5(string, key, raw) { 225 | if (!key) { 226 | if (!raw) { 227 | return this.hexMD5(string); 228 | } 229 | return this.rawMD5(string); 230 | } 231 | if (!raw) { 232 | return this.hexHMACMD5(key, string); 233 | } 234 | return this.rawHMACMD5(key, string); 235 | }, 236 | /** 237 | * 得到md5加密后的sig参数 238 | * @param {Object} requestParam 接口参数 239 | * @param {String} sk签名字符串 240 | * @param {String} featrue 方法名 241 | * @return 返回加密后的sig参数 242 | */ 243 | getSig(requestParam, sk, feature, mode) { 244 | var sig = null; 245 | var requestArr = []; 246 | Object.keys(requestParam).sort().forEach(function(key){ 247 | requestArr.push(key + '=' + requestParam[key]); 248 | }); 249 | if (feature == 'search') { 250 | sig = '/ws/place/v1/search?' + requestArr.join('&') + sk; 251 | } 252 | if (feature == 'suggest') { 253 | sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk; 254 | } 255 | if (feature == 'reverseGeocoder') { 256 | sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk; 257 | } 258 | if (feature == 'geocoder') { 259 | sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk; 260 | } 261 | if (feature == 'getCityList') { 262 | sig = '/ws/district/v1/list?' + requestArr.join('&') + sk; 263 | } 264 | if (feature == 'getDistrictByCityId') { 265 | sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk; 266 | } 267 | if (feature == 'calculateDistance') { 268 | sig = '/ws/distance/v1/?' + requestArr.join('&') + sk; 269 | } 270 | if (feature == 'direction') { 271 | sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk; 272 | } 273 | sig = this.md5(sig); 274 | return sig; 275 | }, 276 | /** 277 | * 得到终点query字符串 278 | * @param {Array|String} 检索数据 279 | */ 280 | location2query(data) { 281 | if (typeof data == 'string') { 282 | return data; 283 | } 284 | var query = ''; 285 | for (var i = 0; i < data.length; i++) { 286 | var d = data[i]; 287 | if (!!query) { 288 | query += ';'; 289 | } 290 | if (d.location) { 291 | query = query + d.location.lat + ',' + d.location.lng; 292 | } 293 | if (d.latitude && d.longitude) { 294 | query = query + d.latitude + ',' + d.longitude; 295 | } 296 | } 297 | return query; 298 | }, 299 | 300 | /** 301 | * 计算角度 302 | */ 303 | rad(d) { 304 | return d * Math.PI / 180.0; 305 | }, 306 | /** 307 | * 处理终点location数组 308 | * @return 返回终点数组 309 | */ 310 | getEndLocation(location){ 311 | var to = location.split(';'); 312 | var endLocation = []; 313 | for (var i = 0; i < to.length; i++) { 314 | endLocation.push({ 315 | lat: parseFloat(to[i].split(',')[0]), 316 | lng: parseFloat(to[i].split(',')[1]) 317 | }) 318 | } 319 | return endLocation; 320 | }, 321 | 322 | /** 323 | * 计算两点间直线距离 324 | * @param a 表示纬度差 325 | * @param b 表示经度差 326 | * @return 返回的是距离,单位m 327 | */ 328 | getDistance(latFrom, lngFrom, latTo, lngTo) { 329 | var radLatFrom = this.rad(latFrom); 330 | var radLatTo = this.rad(latTo); 331 | var a = radLatFrom - radLatTo; 332 | var b = this.rad(lngFrom) - this.rad(lngTo); 333 | var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2))); 334 | distance = distance * EARTH_RADIUS; 335 | distance = Math.round(distance * 10000) / 10000; 336 | return parseFloat(distance.toFixed(0)); 337 | }, 338 | /** 339 | * 使用微信接口进行定位 340 | */ 341 | getWXLocation(success, fail, complete) { 342 | wx.getLocation({ 343 | type: 'gcj02', 344 | success: success, 345 | fail: fail, 346 | complete: complete 347 | }); 348 | }, 349 | 350 | /** 351 | * 获取location参数 352 | */ 353 | getLocationParam(location) { 354 | if (typeof location == 'string') { 355 | var locationArr = location.split(','); 356 | if (locationArr.length === 2) { 357 | location = { 358 | latitude: location.split(',')[0], 359 | longitude: location.split(',')[1] 360 | }; 361 | } else { 362 | location = {}; 363 | } 364 | } 365 | return location; 366 | }, 367 | 368 | /** 369 | * 回调函数默认处理 370 | */ 371 | polyfillParam(param) { 372 | param.success = param.success || function () { }; 373 | param.fail = param.fail || function () { }; 374 | param.complete = param.complete || function () { }; 375 | }, 376 | 377 | /** 378 | * 验证param对应的key值是否为空 379 | * 380 | * @param {Object} param 接口参数 381 | * @param {String} key 对应参数的key 382 | */ 383 | checkParamKeyEmpty(param, key) { 384 | if (!param[key]) { 385 | var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误'); 386 | param.fail(errconf); 387 | param.complete(errconf); 388 | return true; 389 | } 390 | return false; 391 | }, 392 | 393 | /** 394 | * 验证参数中是否存在检索词keyword 395 | * 396 | * @param {Object} param 接口参数 397 | */ 398 | checkKeyword(param){ 399 | return !this.checkParamKeyEmpty(param, 'keyword'); 400 | }, 401 | 402 | /** 403 | * 验证location值 404 | * 405 | * @param {Object} param 接口参数 406 | */ 407 | checkLocation(param) { 408 | var location = this.getLocationParam(param.location); 409 | if (!location || !location.latitude || !location.longitude) { 410 | var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误'); 411 | param.fail(errconf); 412 | param.complete(errconf); 413 | return false; 414 | } 415 | return true; 416 | }, 417 | 418 | /** 419 | * 构造错误数据结构 420 | * @param {Number} errCode 错误码 421 | * @param {Number} errMsg 错误描述 422 | */ 423 | buildErrorConfig(errCode, errMsg) { 424 | return { 425 | status: errCode, 426 | message: errMsg 427 | }; 428 | }, 429 | 430 | /** 431 | * 432 | * 数据处理函数 433 | * 根据传入参数不同处理不同数据 434 | * @param {String} feature 功能名称 435 | * search 地点搜索 436 | * suggest关键词提示 437 | * reverseGeocoder逆地址解析 438 | * geocoder地址解析 439 | * getCityList获取城市列表:父集 440 | * getDistrictByCityId获取区县列表:子集 441 | * calculateDistance距离计算 442 | * @param {Object} param 接口参数 443 | * @param {Object} data 数据 444 | */ 445 | handleData(param,data,feature){ 446 | if (feature == 'search') { 447 | var searchResult = data.data; 448 | var searchSimplify = []; 449 | for (var i = 0; i < searchResult.length; i++) { 450 | searchSimplify.push({ 451 | id: searchResult[i].id || null, 452 | title: searchResult[i].title || null, 453 | latitude: searchResult[i].location && searchResult[i].location.lat || null, 454 | longitude: searchResult[i].location && searchResult[i].location.lng || null, 455 | address: searchResult[i].address || null, 456 | category: searchResult[i].category || null, 457 | tel: searchResult[i].tel || null, 458 | adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null, 459 | city: searchResult[i].ad_info && searchResult[i].ad_info.city || null, 460 | district: searchResult[i].ad_info && searchResult[i].ad_info.district || null, 461 | province: searchResult[i].ad_info && searchResult[i].ad_info.province || null 462 | }) 463 | } 464 | param.success(data, { 465 | searchResult: searchResult, 466 | searchSimplify: searchSimplify 467 | }) 468 | } else if (feature == 'suggest') { 469 | var suggestResult = data.data; 470 | var suggestSimplify = []; 471 | for (var i = 0; i < suggestResult.length; i++) { 472 | suggestSimplify.push({ 473 | adcode: suggestResult[i].adcode || null, 474 | address: suggestResult[i].address || null, 475 | category: suggestResult[i].category || null, 476 | city: suggestResult[i].city || null, 477 | district: suggestResult[i].district || null, 478 | id: suggestResult[i].id || null, 479 | latitude: suggestResult[i].location && suggestResult[i].location.lat || null, 480 | longitude: suggestResult[i].location && suggestResult[i].location.lng || null, 481 | province: suggestResult[i].province || null, 482 | title: suggestResult[i].title || null, 483 | type: suggestResult[i].type || null 484 | }) 485 | } 486 | param.success(data, { 487 | suggestResult: suggestResult, 488 | suggestSimplify: suggestSimplify 489 | }) 490 | } else if (feature == 'reverseGeocoder') { 491 | var reverseGeocoderResult = data.result; 492 | var reverseGeocoderSimplify = { 493 | address: reverseGeocoderResult.address || null, 494 | latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null, 495 | longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null, 496 | adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null, 497 | city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null, 498 | district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null, 499 | nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null, 500 | province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null, 501 | street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null, 502 | street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null, 503 | recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null, 504 | rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null 505 | }; 506 | if (reverseGeocoderResult.pois) {//判断是否返回周边poi 507 | var pois = reverseGeocoderResult.pois; 508 | var poisSimplify = []; 509 | for (var i = 0;i < pois.length;i++) { 510 | poisSimplify.push({ 511 | id: pois[i].id || null, 512 | title: pois[i].title || null, 513 | latitude: pois[i].location && pois[i].location.lat || null, 514 | longitude: pois[i].location && pois[i].location.lng || null, 515 | address: pois[i].address || null, 516 | category: pois[i].category || null, 517 | adcode: pois[i].ad_info && pois[i].ad_info.adcode || null, 518 | city: pois[i].ad_info && pois[i].ad_info.city || null, 519 | district: pois[i].ad_info && pois[i].ad_info.district || null, 520 | province: pois[i].ad_info && pois[i].ad_info.province || null 521 | }) 522 | } 523 | param.success(data,{ 524 | reverseGeocoderResult: reverseGeocoderResult, 525 | reverseGeocoderSimplify: reverseGeocoderSimplify, 526 | pois: pois, 527 | poisSimplify: poisSimplify 528 | }) 529 | } else { 530 | param.success(data, { 531 | reverseGeocoderResult: reverseGeocoderResult, 532 | reverseGeocoderSimplify: reverseGeocoderSimplify 533 | }) 534 | } 535 | } else if (feature == 'geocoder') { 536 | var geocoderResult = data.result; 537 | var geocoderSimplify = { 538 | title: geocoderResult.title || null, 539 | latitude: geocoderResult.location && geocoderResult.location.lat || null, 540 | longitude: geocoderResult.location && geocoderResult.location.lng || null, 541 | adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null, 542 | province: geocoderResult.address_components && geocoderResult.address_components.province || null, 543 | city: geocoderResult.address_components && geocoderResult.address_components.city || null, 544 | district: geocoderResult.address_components && geocoderResult.address_components.district || null, 545 | street: geocoderResult.address_components && geocoderResult.address_components.street || null, 546 | street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null, 547 | level: geocoderResult.level || null 548 | }; 549 | param.success(data,{ 550 | geocoderResult: geocoderResult, 551 | geocoderSimplify: geocoderSimplify 552 | }); 553 | } else if (feature == 'getCityList') { 554 | var provinceResult = data.result[0]; 555 | var cityResult = data.result[1]; 556 | var districtResult = data.result[2]; 557 | param.success(data,{ 558 | provinceResult: provinceResult, 559 | cityResult: cityResult, 560 | districtResult: districtResult 561 | }); 562 | } else if (feature == 'getDistrictByCityId') { 563 | var districtByCity = data.result[0]; 564 | param.success(data, districtByCity); 565 | } else if (feature == 'calculateDistance') { 566 | var calculateDistanceResult = data.result.elements; 567 | var distance = []; 568 | for (var i = 0; i < calculateDistanceResult.length; i++){ 569 | distance.push(calculateDistanceResult[i].distance); 570 | } 571 | param.success(data, { 572 | calculateDistanceResult: calculateDistanceResult, 573 | distance: distance 574 | }); 575 | } else if (feature == 'direction') { 576 | var direction = data.result.routes; 577 | param.success(data,direction); 578 | } else { 579 | param.success(data); 580 | } 581 | }, 582 | 583 | /** 584 | * 构造微信请求参数,公共属性处理 585 | * 586 | * @param {Object} param 接口参数 587 | * @param {Object} param 配置项 588 | * @param {String} feature 方法名 589 | */ 590 | buildWxRequestConfig(param, options, feature) { 591 | var that = this; 592 | options.header = { "content-type": "application/json" }; 593 | options.method = 'GET'; 594 | options.success = function (res) { 595 | var data = res.data; 596 | if (data.status === 0) { 597 | that.handleData(param, data, feature); 598 | } else { 599 | param.fail(data); 600 | } 601 | }; 602 | options.fail = function (res) { 603 | res.statusCode = ERROR_CONF.WX_ERR_CODE; 604 | param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); 605 | }; 606 | options.complete = function (res) { 607 | var statusCode = +res.statusCode; 608 | switch(statusCode) { 609 | case ERROR_CONF.WX_ERR_CODE: { 610 | param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); 611 | break; 612 | } 613 | case ERROR_CONF.WX_OK_CODE: { 614 | var data = res.data; 615 | if (data.status === 0) { 616 | param.complete(data); 617 | } else { 618 | param.complete(that.buildErrorConfig(data.status, data.message)); 619 | } 620 | break; 621 | } 622 | default:{ 623 | param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG)); 624 | } 625 | 626 | } 627 | }; 628 | return options; 629 | }, 630 | 631 | /** 632 | * 处理用户参数是否传入坐标进行不同的处理 633 | */ 634 | locationProcess(param, locationsuccess, locationfail, locationcomplete) { 635 | var that = this; 636 | locationfail = locationfail || function (res) { 637 | res.statusCode = ERROR_CONF.WX_ERR_CODE; 638 | param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); 639 | }; 640 | locationcomplete = locationcomplete || function (res) { 641 | if (res.statusCode == ERROR_CONF.WX_ERR_CODE) { 642 | param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); 643 | } 644 | }; 645 | if (!param.location) { 646 | that.getWXLocation(locationsuccess, locationfail, locationcomplete); 647 | } else if (that.checkLocation(param)) { 648 | var location = Utils.getLocationParam(param.location); 649 | locationsuccess(location); 650 | } 651 | } 652 | }; 653 | 654 | 655 | class QQMapWX { 656 | 657 | /** 658 | * 构造函数 659 | * 660 | * @param {Object} options 接口参数,key 为必选参数 661 | */ 662 | constructor(options) { 663 | if (!options.key) { 664 | throw Error('key值不能为空'); 665 | } 666 | this.key = options.key; 667 | }; 668 | 669 | /** 670 | * POI周边检索 671 | * 672 | * @param {Object} options 接口参数对象 673 | * 674 | * 参数对象结构可以参考 675 | * @see http://lbs.qq.com/webservice_v1/guide-search.html 676 | */ 677 | search(options) { 678 | var that = this; 679 | options = options || {}; 680 | 681 | Utils.polyfillParam(options); 682 | 683 | if (!Utils.checkKeyword(options)) { 684 | return; 685 | } 686 | 687 | var requestParam = { 688 | keyword: options.keyword, 689 | orderby: options.orderby || '_distance', 690 | page_size: options.page_size || 10, 691 | page_index: options.page_index || 1, 692 | output: 'json', 693 | key: that.key 694 | }; 695 | 696 | if (options.address_format) { 697 | requestParam.address_format = options.address_format; 698 | } 699 | 700 | if (options.filter) { 701 | requestParam.filter = options.filter; 702 | } 703 | 704 | var distance = options.distance || "1000"; 705 | var auto_extend = options.auto_extend || 1; 706 | var region = null; 707 | var rectangle = null; 708 | 709 | //判断城市限定参数 710 | if (options.region) { 711 | region = options.region; 712 | } 713 | 714 | //矩形限定坐标(暂时只支持字符串格式) 715 | if (options.rectangle) { 716 | rectangle = options.rectangle; 717 | } 718 | 719 | var locationsuccess = function (result) { 720 | if (region && !rectangle) { 721 | //城市限定参数拼接 722 | requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")"; 723 | if (options.sig) { 724 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'search'); 725 | } 726 | } else if (rectangle && !region) { 727 | //矩形搜索 728 | requestParam.boundary = "rectangle(" + rectangle + ")"; 729 | if (options.sig) { 730 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'search'); 731 | } 732 | } else { 733 | requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")"; 734 | if (options.sig) { 735 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'search'); 736 | } 737 | } 738 | wx.request(Utils.buildWxRequestConfig(options, { 739 | url: URL_SEARCH, 740 | data: requestParam 741 | }, 'search')); 742 | }; 743 | Utils.locationProcess(options, locationsuccess); 744 | }; 745 | 746 | /** 747 | * sug模糊检索 748 | * 749 | * @param {Object} options 接口参数对象 750 | * 751 | * 参数对象结构可以参考 752 | * http://lbs.qq.com/webservice_v1/guide-suggestion.html 753 | */ 754 | getSuggestion(options) { 755 | var that = this; 756 | options = options || {}; 757 | Utils.polyfillParam(options); 758 | 759 | if (!Utils.checkKeyword(options)) { 760 | return; 761 | } 762 | 763 | var requestParam = { 764 | keyword: options.keyword, 765 | region: options.region || '全国', 766 | region_fix: options.region_fix || 0, 767 | policy: options.policy || 0, 768 | page_size: options.page_size || 10,//控制显示条数 769 | page_index: options.page_index || 1,//控制页数 770 | get_subpois : options.get_subpois || 0,//返回子地点 771 | output: 'json', 772 | key: that.key 773 | }; 774 | //长地址 775 | if (options.address_format) { 776 | requestParam.address_format = options.address_format; 777 | } 778 | //过滤 779 | if (options.filter) { 780 | requestParam.filter = options.filter; 781 | } 782 | //排序 783 | if (options.location) { 784 | var locationsuccess = function (result) { 785 | requestParam.location = result.latitude + ',' + result.longitude; 786 | if (options.sig) { 787 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest'); 788 | } 789 | wx.request(Utils.buildWxRequestConfig(options, { 790 | url: URL_SUGGESTION, 791 | data: requestParam 792 | }, "suggest")); 793 | }; 794 | Utils.locationProcess(options, locationsuccess); 795 | } else { 796 | if (options.sig) { 797 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest'); 798 | } 799 | wx.request(Utils.buildWxRequestConfig(options, { 800 | url: URL_SUGGESTION, 801 | data: requestParam 802 | }, "suggest")); 803 | } 804 | }; 805 | 806 | /** 807 | * 逆地址解析 808 | * 809 | * @param {Object} options 接口参数对象 810 | * 811 | * 请求参数结构可以参考 812 | * http://lbs.qq.com/webservice_v1/guide-gcoder.html 813 | */ 814 | reverseGeocoder(options) { 815 | var that = this; 816 | options = options || {}; 817 | Utils.polyfillParam(options); 818 | var requestParam = { 819 | coord_type: options.coord_type || 5, 820 | get_poi: options.get_poi || 0, 821 | output: 'json', 822 | key: that.key 823 | }; 824 | if (options.poi_options) { 825 | requestParam.poi_options = options.poi_options 826 | } 827 | 828 | var locationsuccess = function (result) { 829 | requestParam.location = result.latitude + ',' + result.longitude; 830 | if (options.sig) { 831 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder'); 832 | } 833 | wx.request(Utils.buildWxRequestConfig(options, { 834 | url: URL_GET_GEOCODER, 835 | data: requestParam 836 | }, 'reverseGeocoder')); 837 | }; 838 | Utils.locationProcess(options, locationsuccess); 839 | }; 840 | 841 | /** 842 | * 地址解析 843 | * 844 | * @param {Object} options 接口参数对象 845 | * 846 | * 请求参数结构可以参考 847 | * http://lbs.qq.com/webservice_v1/guide-geocoder.html 848 | */ 849 | geocoder(options) { 850 | var that = this; 851 | options = options || {}; 852 | Utils.polyfillParam(options); 853 | 854 | if (Utils.checkParamKeyEmpty(options, 'address')) { 855 | return; 856 | } 857 | 858 | var requestParam = { 859 | address: options.address, 860 | output: 'json', 861 | key: that.key 862 | }; 863 | 864 | //城市限定 865 | if (options.region) { 866 | requestParam.region = options.region; 867 | } 868 | 869 | if (options.sig) { 870 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder'); 871 | } 872 | 873 | wx.request(Utils.buildWxRequestConfig(options, { 874 | url: URL_GET_GEOCODER, 875 | data: requestParam 876 | },'geocoder')); 877 | }; 878 | 879 | 880 | /** 881 | * 获取城市列表 882 | * 883 | * @param {Object} options 接口参数对象 884 | * 885 | * 请求参数结构可以参考 886 | * http://lbs.qq.com/webservice_v1/guide-region.html 887 | */ 888 | getCityList(options) { 889 | var that = this; 890 | options = options || {}; 891 | Utils.polyfillParam(options); 892 | var requestParam = { 893 | output: 'json', 894 | key: that.key 895 | }; 896 | 897 | if (options.sig) { 898 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList'); 899 | } 900 | 901 | wx.request(Utils.buildWxRequestConfig(options, { 902 | url: URL_CITY_LIST, 903 | data: requestParam 904 | },'getCityList')); 905 | }; 906 | 907 | /** 908 | * 获取对应城市ID的区县列表 909 | * 910 | * @param {Object} options 接口参数对象 911 | * 912 | * 请求参数结构可以参考 913 | * http://lbs.qq.com/webservice_v1/guide-region.html 914 | */ 915 | getDistrictByCityId(options) { 916 | var that = this; 917 | options = options || {}; 918 | Utils.polyfillParam(options); 919 | 920 | if (Utils.checkParamKeyEmpty(options, 'id')) { 921 | return; 922 | } 923 | 924 | var requestParam = { 925 | id: options.id || '', 926 | output: 'json', 927 | key: that.key 928 | }; 929 | 930 | if (options.sig) { 931 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId'); 932 | } 933 | 934 | wx.request(Utils.buildWxRequestConfig(options, { 935 | url: URL_AREA_LIST, 936 | data: requestParam 937 | },'getDistrictByCityId')); 938 | }; 939 | 940 | /** 941 | * 用于单起点到多终点的路线距离(非直线距离)计算: 942 | * 支持两种距离计算方式:步行和驾车。 943 | * 起点到终点最大限制直线距离10公里。 944 | * 945 | * 新增直线距离计算。 946 | * 947 | * @param {Object} options 接口参数对象 948 | * 949 | * 请求参数结构可以参考 950 | * http://lbs.qq.com/webservice_v1/guide-distance.html 951 | */ 952 | calculateDistance(options) { 953 | var that = this; 954 | options = options || {}; 955 | Utils.polyfillParam(options); 956 | 957 | if (Utils.checkParamKeyEmpty(options, 'to')) { 958 | return; 959 | } 960 | 961 | var requestParam = { 962 | mode: options.mode || 'walking', 963 | to: Utils.location2query(options.to), 964 | output: 'json', 965 | key: that.key 966 | }; 967 | 968 | if (options.from) { 969 | options.location = options.from; 970 | } 971 | 972 | //计算直线距离 973 | if(requestParam.mode == 'straight'){ 974 | var locationsuccess = function (result) { 975 | var locationTo = Utils.getEndLocation(requestParam.to);//处理终点坐标 976 | var data = { 977 | message:"query ok", 978 | result:{ 979 | elements:[] 980 | }, 981 | status:0 982 | }; 983 | for (var i = 0; i < locationTo.length; i++) { 984 | data.result.elements.push({//将坐标存入 985 | distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng), 986 | duration:0, 987 | from:{ 988 | lat: result.latitude, 989 | lng:result.longitude 990 | }, 991 | to:{ 992 | lat: locationTo[i].lat, 993 | lng: locationTo[i].lng 994 | } 995 | }); 996 | } 997 | var calculateResult = data.result.elements; 998 | var distanceResult = []; 999 | for (var i = 0; i < calculateResult.length; i++) { 1000 | distanceResult.push(calculateResult[i].distance); 1001 | } 1002 | return options.success(data,{ 1003 | calculateResult: calculateResult, 1004 | distanceResult: distanceResult 1005 | }); 1006 | }; 1007 | 1008 | Utils.locationProcess(options, locationsuccess); 1009 | } else { 1010 | var locationsuccess = function (result) { 1011 | requestParam.from = result.latitude + ',' + result.longitude; 1012 | if (options.sig) { 1013 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance'); 1014 | } 1015 | wx.request(Utils.buildWxRequestConfig(options, { 1016 | url: URL_DISTANCE, 1017 | data: requestParam 1018 | },'calculateDistance')); 1019 | }; 1020 | 1021 | Utils.locationProcess(options, locationsuccess); 1022 | } 1023 | }; 1024 | 1025 | /** 1026 | * 路线规划: 1027 | * 1028 | * @param {Object} options 接口参数对象 1029 | * 1030 | * 请求参数结构可以参考 1031 | * https://lbs.qq.com/webservice_v1/guide-road.html 1032 | */ 1033 | direction(options) { 1034 | var that = this; 1035 | options = options || {}; 1036 | Utils.polyfillParam(options); 1037 | 1038 | if (Utils.checkParamKeyEmpty(options, 'to')) { 1039 | return; 1040 | } 1041 | 1042 | var requestParam = { 1043 | output: 'json', 1044 | key: that.key 1045 | }; 1046 | 1047 | //to格式处理 1048 | if (typeof options.to == 'string') { 1049 | requestParam.to = options.to; 1050 | } else { 1051 | requestParam.to = options.to.latitude + ',' + options.to.longitude; 1052 | } 1053 | //初始化局部请求域名 1054 | var SET_URL_DIRECTION = null; 1055 | //设置默认mode属性 1056 | options.mode = options.mode || MODE.driving; 1057 | 1058 | //设置请求域名 1059 | SET_URL_DIRECTION = URL_DIRECTION + options.mode; 1060 | 1061 | if (options.from) { 1062 | options.location = options.from; 1063 | } 1064 | 1065 | if (options.mode == MODE.driving) { 1066 | if (options.from_poi) { 1067 | requestParam.from_poi = options.from_poi; 1068 | } 1069 | if (options.heading) { 1070 | requestParam.heading = options.heading; 1071 | } 1072 | if (options.speed) { 1073 | requestParam.speed = options.speed; 1074 | } 1075 | if (options.accuracy) { 1076 | requestParam.accuracy = options.accuracy; 1077 | } 1078 | if (options.road_type) { 1079 | requestParam.road_type = options.road_type; 1080 | } 1081 | if (options.to_poi) { 1082 | requestParam.to_poi = options.to_poi; 1083 | } 1084 | if (options.from_track) { 1085 | requestParam.from_track = options.from_track; 1086 | } 1087 | if (options.waypoints) { 1088 | requestParam.waypoints = options.waypoints; 1089 | } 1090 | if (options.policy) { 1091 | requestParam.policy = options.policy; 1092 | } 1093 | if (options.plate_number) { 1094 | requestParam.plate_number = options.plate_number; 1095 | } 1096 | } 1097 | 1098 | if (options.mode == MODE.transit) { 1099 | if (options.departure_time) { 1100 | requestParam.departure_time = options.departure_time; 1101 | } 1102 | if (options.policy) { 1103 | requestParam.policy = options.policy; 1104 | } 1105 | } 1106 | 1107 | var locationsuccess = function (result) { 1108 | requestParam.from = result.latitude + ',' + result.longitude; 1109 | if (options.sig) { 1110 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction',options.mode); 1111 | } 1112 | wx.request(Utils.buildWxRequestConfig(options, { 1113 | url: SET_URL_DIRECTION, 1114 | data: requestParam 1115 | }, 'direction')); 1116 | }; 1117 | 1118 | Utils.locationProcess(options, locationsuccess); 1119 | } 1120 | }; 1121 | 1122 | module.exports = QQMapWX; -------------------------------------------------------------------------------- /utils/qqmap/qqmap-wx-jssdk.min.js: -------------------------------------------------------------------------------- 1 | var ERROR_CONF = { KEY_ERR: 311, KEY_ERR_MSG: 'key格式错误', PARAM_ERR: 310, PARAM_ERR_MSG: '请求参数信息有误', SYSTEM_ERR: 600, SYSTEM_ERR_MSG: '系统错误', WX_ERR_CODE: 1000, WX_OK_CODE: 200 }; var BASE_URL = 'https://apis.map.qq.com/ws/'; var URL_SEARCH = BASE_URL + 'place/v1/search'; var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion'; var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/'; var URL_CITY_LIST = BASE_URL + 'district/v1/list'; var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren'; var URL_DISTANCE = BASE_URL + 'distance/v1/'; var URL_DIRECTION = BASE_URL + 'direction/v1/'; var MODE = { driving: 'driving', transit: 'transit' }; var EARTH_RADIUS = 6378136.49; var Utils = { safeAdd(x, y) { var lsw = (x & 0xffff) + (y & 0xffff); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xffff) }, bitRotateLeft(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)) }, md5cmn(q, a, b, x, s, t) { return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b) }, md5ff(a, b, c, d, x, s, t) { return this.md5cmn((b & c) | (~b & d), a, b, x, s, t) }, md5gg(a, b, c, d, x, s, t) { return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t) }, md5hh(a, b, c, d, x, s, t) { return this.md5cmn(b ^ c ^ d, a, b, x, s, t) }, md5ii(a, b, c, d, x, s, t) { return this.md5cmn(c ^ (b | ~d), a, b, x, s, t) }, binlMD5(x, len) { x[len >> 5] |= 0x80 << (len % 32); x[((len + 64) >>> 9 << 4) + 14] = len; var i; var olda; var oldb; var oldc; var oldd; var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; for (i = 0; i < x.length; i += 16) { olda = a; oldb = b; oldc = c; oldd = d; a = this.md5ff(a, b, c, d, x[i], 7, -680876936); d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586); c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819); b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330); a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897); d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426); c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341); b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983); a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416); d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417); c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063); b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162); a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682); d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101); c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290); b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329); a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510); d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632); c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713); b = this.md5gg(b, c, d, a, x[i], 20, -373897302); a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691); d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083); c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335); b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848); a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438); d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690); c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961); b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501); a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467); d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784); c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473); b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734); a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558); d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463); c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562); b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556); a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060); d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353); c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632); b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640); a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174); d = this.md5hh(d, a, b, c, x[i], 11, -358537222); c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979); b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189); a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487); d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835); c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520); b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651); a = this.md5ii(a, b, c, d, x[i], 6, -198630844); d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415); c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905); b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055); a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571); d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606); c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523); b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799); a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359); d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744); c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380); b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649); a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070); d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379); c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259); b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551); a = this.safeAdd(a, olda); b = this.safeAdd(b, oldb); c = this.safeAdd(c, oldc); d = this.safeAdd(d, oldd) } return [a, b, c, d] }, binl2rstr(input) { var i; var output = ''; var length32 = input.length * 32; for (i = 0; i < length32; i += 8) { output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff) } return output }, rstr2binl(input) { var i; var output = []; output[(input.length >> 2) - 1] = undefined; for (i = 0; i < output.length; i += 1) { output[i] = 0 } var length8 = input.length * 8; for (i = 0; i < length8; i += 8) { output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32) } return output }, rstrMD5(s) { return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8)) }, rstrHMACMD5(key, data) { var i; var bkey = this.rstr2binl(key); var ipad = []; var opad = []; var hash; ipad[15] = opad[15] = undefined; if (bkey.length > 16) { bkey = this.binlMD5(bkey, key.length * 8) } for (i = 0; i < 16; i += 1) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5c5c5c5c } hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8); return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128)) }, rstr2hex(input) { var hexTab = '0123456789abcdef'; var output = ''; var x; var i; for (i = 0; i < input.length; i += 1) { x = input.charCodeAt(i); output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f) } return output }, str2rstrUTF8(input) { return unescape(encodeURIComponent(input)) }, rawMD5(s) { return this.rstrMD5(this.str2rstrUTF8(s)) }, hexMD5(s) { return this.rstr2hex(this.rawMD5(s)) }, rawHMACMD5(k, d) { return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d)) }, hexHMACMD5(k, d) { return this.rstr2hex(this.rawHMACMD5(k, d)) }, md5(string, key, raw) { if (!key) { if (!raw) { return this.hexMD5(string) } return this.rawMD5(string) } if (!raw) { return this.hexHMACMD5(key, string) } return this.rawHMACMD5(key, string) }, getSig(requestParam, sk, feature, mode) { var sig = null; var requestArr = []; Object.keys(requestParam).sort().forEach(function (key) { requestArr.push(key + '=' + requestParam[key]) }); if (feature == 'search') { sig = '/ws/place/v1/search?' + requestArr.join('&') + sk } if (feature == 'suggest') { sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk } if (feature == 'reverseGeocoder') { sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk } if (feature == 'geocoder') { sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk } if (feature == 'getCityList') { sig = '/ws/district/v1/list?' + requestArr.join('&') + sk } if (feature == 'getDistrictByCityId') { sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk } if (feature == 'calculateDistance') { sig = '/ws/distance/v1/?' + requestArr.join('&') + sk } if (feature == 'direction') { sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk } sig = this.md5(sig); return sig }, location2query(data) { if (typeof data == 'string') { return data } var query = ''; for (var i = 0; i < data.length; i++) { var d = data[i]; if (!!query) { query += ';' } if (d.location) { query = query + d.location.lat + ',' + d.location.lng } if (d.latitude && d.longitude) { query = query + d.latitude + ',' + d.longitude } } return query }, rad(d) { return d * Math.PI / 180.0 }, getEndLocation(location) { var to = location.split(';'); var endLocation = []; for (var i = 0; i < to.length; i++) { endLocation.push({ lat: parseFloat(to[i].split(',')[0]), lng: parseFloat(to[i].split(',')[1]) }) } return endLocation }, getDistance(latFrom, lngFrom, latTo, lngTo) { var radLatFrom = this.rad(latFrom); var radLatTo = this.rad(latTo); var a = radLatFrom - radLatTo; var b = this.rad(lngFrom) - this.rad(lngTo); var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2))); distance = distance * EARTH_RADIUS; distance = Math.round(distance * 10000) / 10000; return parseFloat(distance.toFixed(0)) }, getWXLocation(success, fail, complete) { wx.getLocation({ type: 'gcj02', success: success, fail: fail, complete: complete }) }, getLocationParam(location) { if (typeof location == 'string') { var locationArr = location.split(','); if (locationArr.length === 2) { location = { latitude: location.split(',')[0], longitude: location.split(',')[1] } } else { location = {} } } return location }, polyfillParam(param) { param.success = param.success || function () { }; param.fail = param.fail || function () { }; param.complete = param.complete || function () { } }, checkParamKeyEmpty(param, key) { if (!param[key]) { var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key + '参数格式有误'); param.fail(errconf); param.complete(errconf); return true } return false }, checkKeyword(param) { return !this.checkParamKeyEmpty(param, 'keyword') }, checkLocation(param) { var location = this.getLocationParam(param.location); if (!location || !location.latitude || !location.longitude) { var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误'); param.fail(errconf); param.complete(errconf); return false } return true }, buildErrorConfig(errCode, errMsg) { return { status: errCode, message: errMsg } }, handleData(param, data, feature) { if (feature == 'search') { var searchResult = data.data; var searchSimplify = []; for (var i = 0; i < searchResult.length; i++) { searchSimplify.push({ id: searchResult[i].id || null, title: searchResult[i].title || null, latitude: searchResult[i].location && searchResult[i].location.lat || null, longitude: searchResult[i].location && searchResult[i].location.lng || null, address: searchResult[i].address || null, category: searchResult[i].category || null, tel: searchResult[i].tel || null, adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null, city: searchResult[i].ad_info && searchResult[i].ad_info.city || null, district: searchResult[i].ad_info && searchResult[i].ad_info.district || null, province: searchResult[i].ad_info && searchResult[i].ad_info.province || null }) } param.success(data, { searchResult: searchResult, searchSimplify: searchSimplify }) } else if (feature == 'suggest') { var suggestResult = data.data; var suggestSimplify = []; for (var i = 0; i < suggestResult.length; i++) { suggestSimplify.push({ adcode: suggestResult[i].adcode || null, address: suggestResult[i].address || null, category: suggestResult[i].category || null, city: suggestResult[i].city || null, district: suggestResult[i].district || null, id: suggestResult[i].id || null, latitude: suggestResult[i].location && suggestResult[i].location.lat || null, longitude: suggestResult[i].location && suggestResult[i].location.lng || null, province: suggestResult[i].province || null, title: suggestResult[i].title || null, type: suggestResult[i].type || null }) } param.success(data, { suggestResult: suggestResult, suggestSimplify: suggestSimplify }) } else if (feature == 'reverseGeocoder') { var reverseGeocoderResult = data.result; var reverseGeocoderSimplify = { address: reverseGeocoderResult.address || null, latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null, longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null, adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null, city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null, district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null, nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null, province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null, street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null, street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null, recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null, rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null }; if (reverseGeocoderResult.pois) { var pois = reverseGeocoderResult.pois; var poisSimplify = []; for (var i = 0; i < pois.length; i++) { poisSimplify.push({ id: pois[i].id || null, title: pois[i].title || null, latitude: pois[i].location && pois[i].location.lat || null, longitude: pois[i].location && pois[i].location.lng || null, address: pois[i].address || null, category: pois[i].category || null, adcode: pois[i].ad_info && pois[i].ad_info.adcode || null, city: pois[i].ad_info && pois[i].ad_info.city || null, district: pois[i].ad_info && pois[i].ad_info.district || null, province: pois[i].ad_info && pois[i].ad_info.province || null }) } param.success(data, { reverseGeocoderResult: reverseGeocoderResult, reverseGeocoderSimplify: reverseGeocoderSimplify, pois: pois, poisSimplify: poisSimplify }) } else { param.success(data, { reverseGeocoderResult: reverseGeocoderResult, reverseGeocoderSimplify: reverseGeocoderSimplify }) } } else if (feature == 'geocoder') { var geocoderResult = data.result; var geocoderSimplify = { title: geocoderResult.title || null, latitude: geocoderResult.location && geocoderResult.location.lat || null, longitude: geocoderResult.location && geocoderResult.location.lng || null, adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null, province: geocoderResult.address_components && geocoderResult.address_components.province || null, city: geocoderResult.address_components && geocoderResult.address_components.city || null, district: geocoderResult.address_components && geocoderResult.address_components.district || null, street: geocoderResult.address_components && geocoderResult.address_components.street || null, street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null, level: geocoderResult.level || null }; param.success(data, { geocoderResult: geocoderResult, geocoderSimplify: geocoderSimplify }) } else if (feature == 'getCityList') { var provinceResult = data.result[0]; var cityResult = data.result[1]; var districtResult = data.result[2]; param.success(data, { provinceResult: provinceResult, cityResult: cityResult, districtResult: districtResult }) } else if (feature == 'getDistrictByCityId') { var districtByCity = data.result[0]; param.success(data, districtByCity) } else if (feature == 'calculateDistance') { var calculateDistanceResult = data.result.elements; var distance = []; for (var i = 0; i < calculateDistanceResult.length; i++) { distance.push(calculateDistanceResult[i].distance) } param.success(data, { calculateDistanceResult: calculateDistanceResult, distance: distance }) } else if (feature == 'direction') { var direction = data.result.routes; param.success(data, direction) } else { param.success(data) } }, buildWxRequestConfig(param, options, feature) { var that = this; options.header = { "content-type": "application/json" }; options.method = 'GET'; options.success = function (res) { var data = res.data; if (data.status === 0) { that.handleData(param, data, feature) } else { param.fail(data) } }; options.fail = function (res) { res.statusCode = ERROR_CONF.WX_ERR_CODE; param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)) }; options.complete = function (res) { var statusCode = +res.statusCode; switch (statusCode) { case ERROR_CONF.WX_ERR_CODE: { param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); break } case ERROR_CONF.WX_OK_CODE: { var data = res.data; if (data.status === 0) { param.complete(data) } else { param.complete(that.buildErrorConfig(data.status, data.message)) } break } default: { param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG)) } } }; return options }, locationProcess(param, locationsuccess, locationfail, locationcomplete) { var that = this; locationfail = locationfail || function (res) { res.statusCode = ERROR_CONF.WX_ERR_CODE; param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)) }; locationcomplete = locationcomplete || function (res) { if (res.statusCode == ERROR_CONF.WX_ERR_CODE) { param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)) } }; if (!param.location) { that.getWXLocation(locationsuccess, locationfail, locationcomplete) } else if (that.checkLocation(param)) { var location = Utils.getLocationParam(param.location); locationsuccess(location) } } }; class QQMapWX { constructor(options) { if (!options.key) { throw Error('key值不能为空') } this.key = options.key }; search(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (!Utils.checkKeyword(options)) { return } var requestParam = { keyword: options.keyword, orderby: options.orderby || '_distance', page_size: options.page_size || 10, page_index: options.page_index || 1, output: 'json', key: that.key }; if (options.address_format) { requestParam.address_format = options.address_format } if (options.filter) { requestParam.filter = options.filter } var distance = options.distance || "1000"; var auto_extend = options.auto_extend || 1; var region = null; var rectangle = null; if (options.region) { region = options.region } if (options.rectangle) { rectangle = options.rectangle } var locationsuccess = function (result) { if (region && !rectangle) { requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")"; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'search') } } else if (rectangle && !region) { requestParam.boundary = "rectangle(" + rectangle + ")"; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'search') } } else { requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")"; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'search') } } wx.request(Utils.buildWxRequestConfig(options, { url: URL_SEARCH, data: requestParam }, 'search')) }; Utils.locationProcess(options, locationsuccess) }; getSuggestion(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (!Utils.checkKeyword(options)) { return } var requestParam = { keyword: options.keyword, region: options.region || '全国', region_fix: options.region_fix || 0, policy: options.policy || 0, page_size: options.page_size || 10, page_index: options.page_index || 1, get_subpois: options.get_subpois || 0, output: 'json', key: that.key }; if (options.address_format) { requestParam.address_format = options.address_format } if (options.filter) { requestParam.filter = options.filter } if (options.location) { var locationsuccess = function (result) { requestParam.location = result.latitude + ',' + result.longitude; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_SUGGESTION, data: requestParam }, "suggest")) }; Utils.locationProcess(options, locationsuccess) } else { if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_SUGGESTION, data: requestParam }, "suggest")) } }; reverseGeocoder(options) { var that = this; options = options || {}; Utils.polyfillParam(options); var requestParam = { coord_type: options.coord_type || 5, get_poi: options.get_poi || 0, output: 'json', key: that.key }; if (options.poi_options) { requestParam.poi_options = options.poi_options } var locationsuccess = function (result) { requestParam.location = result.latitude + ',' + result.longitude; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_GET_GEOCODER, data: requestParam }, 'reverseGeocoder')) }; Utils.locationProcess(options, locationsuccess) }; geocoder(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (Utils.checkParamKeyEmpty(options, 'address')) { return } var requestParam = { address: options.address, output: 'json', key: that.key }; if (options.region) { requestParam.region = options.region } if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_GET_GEOCODER, data: requestParam }, 'geocoder')) }; getCityList(options) { var that = this; options = options || {}; Utils.polyfillParam(options); var requestParam = { output: 'json', key: that.key }; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_CITY_LIST, data: requestParam }, 'getCityList')) }; getDistrictByCityId(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (Utils.checkParamKeyEmpty(options, 'id')) { return } var requestParam = { id: options.id || '', output: 'json', key: that.key }; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_AREA_LIST, data: requestParam }, 'getDistrictByCityId')) }; calculateDistance(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (Utils.checkParamKeyEmpty(options, 'to')) { return } var requestParam = { mode: options.mode || 'walking', to: Utils.location2query(options.to), output: 'json', key: that.key }; if (options.from) { options.location = options.from } if (requestParam.mode == 'straight') { var locationsuccess = function (result) { var locationTo = Utils.getEndLocation(requestParam.to); var data = { message: "query ok", result: { elements: [] }, status: 0 }; for (var i = 0; i < locationTo.length; i++) { data.result.elements.push({ distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng), duration: 0, from: { lat: result.latitude, lng: result.longitude }, to: { lat: locationTo[i].lat, lng: locationTo[i].lng } }) } var calculateResult = data.result.elements; var distanceResult = []; for (var i = 0; i < calculateResult.length; i++) { distanceResult.push(calculateResult[i].distance) } return options.success(data, { calculateResult: calculateResult, distanceResult: distanceResult }) }; Utils.locationProcess(options, locationsuccess) } else { var locationsuccess = function (result) { requestParam.from = result.latitude + ',' + result.longitude; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_DISTANCE, data: requestParam }, 'calculateDistance')) }; Utils.locationProcess(options, locationsuccess) } }; direction(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (Utils.checkParamKeyEmpty(options, 'to')) { return } var requestParam = { output: 'json', key: that.key }; if (typeof options.to == 'string') { requestParam.to = options.to } else { requestParam.to = options.to.latitude + ',' + options.to.longitude } var SET_URL_DIRECTION = null; options.mode = options.mode || MODE.driving; SET_URL_DIRECTION = URL_DIRECTION + options.mode; if (options.from) { options.location = options.from } if (options.mode == MODE.driving) { if (options.from_poi) { requestParam.from_poi = options.from_poi } if (options.heading) { requestParam.heading = options.heading } if (options.speed) { requestParam.speed = options.speed } if (options.accuracy) { requestParam.accuracy = options.accuracy } if (options.road_type) { requestParam.road_type = options.road_type } if (options.to_poi) { requestParam.to_poi = options.to_poi } if (options.from_track) { requestParam.from_track = options.from_track } if (options.waypoints) { requestParam.waypoints = options.waypoints } if (options.policy) { requestParam.policy = options.policy } if (options.plate_number) { requestParam.plate_number = options.plate_number } } if (options.mode == MODE.transit) { if (options.departure_time) { requestParam.departure_time = options.departure_time } if (options.policy) { requestParam.policy = options.policy } } var locationsuccess = function (result) { requestParam.from = result.latitude + ',' + result.longitude; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction', options.mode) } wx.request(Utils.buildWxRequestConfig(options, { url: SET_URL_DIRECTION, data: requestParam }, 'direction')) }; Utils.locationProcess(options, locationsuccess) } }; module.exports = QQMapWX; -------------------------------------------------------------------------------- /utils/util.js: -------------------------------------------------------------------------------- 1 | const formatTime = date => { 2 | const year = date.getFullYear() 3 | const month = date.getMonth() + 1 4 | const day = date.getDate() 5 | const hour = date.getHours() 6 | const minute = date.getMinutes() 7 | const second = date.getSeconds() 8 | 9 | return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}` 10 | } 11 | 12 | const formatNumber = n => { 13 | n = n.toString() 14 | return n[1] ? n : `0${n}` 15 | } 16 | 17 | module.exports = { 18 | formatTime 19 | } 20 | --------------------------------------------------------------------------------