├── .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 |
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 |
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 |
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 |
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 |
--------------------------------------------------------------------------------