├── .gitignore ├── 1554866393022686.mp4 ├── app.js ├── app.json ├── app.wxss ├── images ├── back.png ├── idcard_1.png ├── idcard_2.png ├── img_add.png ├── img_del.png ├── login_bg.png ├── login_logo.png ├── login_wechat.png ├── my_marker.png └── store2_img.png ├── lib └── css │ └── iconfont.wxss ├── pages └── shopMap │ ├── shopMap.js │ ├── shopMap.json │ ├── shopMap.wxml │ └── shopMap.wxss ├── project.config.json └── utils ├── qqmap-wx-jssdk1.2 ├── qqmap-wx-jssdk.js └── qqmap-wx-jssdk.min.js └── util.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows 2 | [Dd]esktop.ini 3 | Thumbs.db 4 | $RECYCLE.BIN/ 5 | 6 | # macOS 7 | .DS_Store 8 | .fseventsd 9 | .Spotlight-V100 10 | .TemporaryItems 11 | .Trashes 12 | 13 | # Node.js 14 | node_modules/ 15 | -------------------------------------------------------------------------------- /1554866393022686.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/1554866393022686.mp4 -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | }, 5 | globalData: { 6 | userInfo: null 7 | } 8 | }) -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages":[ 3 | "pages/shopMap/shopMap" 4 | ], 5 | "window":{ 6 | "backgroundTextStyle":"light", 7 | "navigationBarBackgroundColor": "#fff", 8 | "navigationBarTitleText": "WeChat", 9 | "navigationBarTextStyle":"black" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /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/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/images/back.png -------------------------------------------------------------------------------- /images/idcard_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/images/idcard_1.png -------------------------------------------------------------------------------- /images/idcard_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/images/idcard_2.png -------------------------------------------------------------------------------- /images/img_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/images/img_add.png -------------------------------------------------------------------------------- /images/img_del.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/images/img_del.png -------------------------------------------------------------------------------- /images/login_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/images/login_bg.png -------------------------------------------------------------------------------- /images/login_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/images/login_logo.png -------------------------------------------------------------------------------- /images/login_wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/images/login_wechat.png -------------------------------------------------------------------------------- /images/my_marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/images/my_marker.png -------------------------------------------------------------------------------- /images/store2_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcky1928/map/02854b6300dfc92e6066c537ff6d382d7ecf7db5/images/store2_img.png -------------------------------------------------------------------------------- /lib/css/iconfont.wxss: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('//at.alicdn.com/t/font_1120834_hvoztl864h6.eot?t=1554258412999'); /* IE9 */ 3 | src: url('//at.alicdn.com/t/font_1120834_hvoztl864h6.eot?t=1554258412999#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAgQAAsAAAAADnAAAAfAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCEIAqOMIwEATYCJAMoCxYABCAFhG0HgRsbZQxRlG9SkOzjMG74SoiyxOJKUQ6m+GaJv3j4fr//rb3Puf7FEE2iUTWqZhKe6QwJGo1EowRIJKYTkmfym3/ctJ8wScURvVFxQm2q0AnUsDdqSBIoEnSiYcrKRJQyE0dmdpyI9Ofv92oXzfKu7buc91//yqZV86fheECRDT6QAB0gzH3LdJLMDLxi+q3XExhtJwJdlIxTAERFeQEpT8yEDiA+uZrSGnpRG3NsFe9Bo8+38D0AvDM/H/9AZSCkpqAHXXs8ygiG/hRvpFGdFFUCiPq0uG5EwQFAvQo/xUo+AuDHu51mzK5eAdakI1vxN0iJp8Wz4py4MD4mfjf+qLOTmNFp8bDG9EAZ67+8Kg06rYZoIX8OKl8HBn4CMULhZ8oIPT/TRgh+Zo1Q+ckZIfkpxOsQjAGpDgRqkGpB0Aj4vtAzqmPWAPuBPAqUbajwksmvUtgK2i/nCnlmmenJyRnJKXwkgcNBUhGELiVJqQ6cXSlIMsI/LqELKyMlRRfk4geiUCymjkSUVFhkXItj0KoAi4hB0agqHFZQOkMkHRQOj78WFm6LjLoZy90etVyxCO+qXYEO1u/e0ajmRjRnR0x6PZK9NWwg8PUXe2GrKLrxxIGp26OVXCJVJeb2ssOUklNECiXdrbyjMdxlFfGMRub71Mq1FEcL5dES+gZsFa9sDYs1gDVWSaUKrOWxKG4rBHR6lgcnrT9TAF2PoAqIy1ULOAI2n61i8ZT7wiOhjrM8pbLFKOhmbATEo1gydithAOr5Cn7DBxyISlQgb2ReNX0cXUQfptfoi5Upu4jFslivLqRmoMWy/PzRjFEQYEpWM5ljBjOVTqxm0LJ8a2l7YkGQ5tzq1y1m5DMYvPYzR3ZcvGnH7NpP7TulmWKsKwepVbweuT24OWKuOkLZVc141Ud8CubgC1hK+j4KZYwPRlXp9oUTQf7o1kQoKRArS9GFw6pAlmpfuBkEIuiM+5TMA9HENH9EydBfD35B5a7HazFjHUEs25M69vr2tIeo3cqkLokTV7fTjarVQTp95VqGchVjtbVrfMRiRYXamfhqn29AYDdFN6wsUUn3BjI0UCPZPcXOsZLqHOz4CJnnczRi2qKr51fQGCiw7yFmq+fDbR+FyyETyEVyIXOppB6efqBjFoyAgBn1PZ0yiCAg2SojcAZC3M0gZJLHtXV8gRjw6FJdnYCfATo7rblkCXxaRzvxW8X6aYs/WzxNg2OBtbA1KtI6rba6umtXIaw17wEGjyrvLx21fWyR3UIwCLNlayoYCFHdudbDSwfqr5BuGp2DBseytA/2Ablhl8MNg8v5DnOtxz7YaKfb+jfJRah0SYMSfnzS1uRJNp7+zAPGYGWwKR1UVOb7pyV++93DQzJ061b//AkP69eu2LZMte0enJH38yulMbh6Zf3OHUdc1CztT78iX+1pP/cptEybqSjf3dcC99HL0MdkRtmylTJRc0W/lt2K8kztstCnlt4ytHj4fHkNrNU395oJddSPKOaVVOlDclHf4E0zPydz1PvkRzXwfHnxcBn6prmXPuu2tvzlhHOV0zqjveWi/k2n2yqDvTn45o+maGwQQIc2c/CtnoF8yrwv/QzEsqP8D1JLEdtWzFp/acT8BW98cnTKxTf/rhnZrNVVw2i0HMesIzt21q9cHTQqR/z0USZSga+6/3J5heAH5ck1k/e6GwOVgVDaOK0SXtKASls89/8v5KIfvp3TPXFXj+VytEoXNUZbe5eM23eCU8YVl+SralR+BLaodg7THLQe1LTRJvKBctEy6zLf04u6/gPJ8WCFunQ0d1/i7MQ+Tb0fSh1Ds69ep6m1a4d6oaG55EBd/4utvUtHr1Br49KHTb37vLXadZp6pYJh8yV6M3kbgWvT1qVnrsvIzMgwmeD3kulwqAOewbSh0HQNZ9yN63gaTJ+Yd3r/gXuUe5Xgj/K1XCX4abQb7VPmBdODJguxPzMHrOOuy85ewAGLZ6amfc9Zm3MXRc/lnJPsXdznHri6wc/yv3s3kQ1Yb/SWk1jIJLZ/82Y/K4NFLgBmfgWYXS5NtCEA5ZTFrDNf0boZyaUCeFxHfoPvbk2V3EIBlMwTRP8Zfu43PoFtx5HtfNhPZbSkDfzfJ/23rPhxp/+3xj6jKiiv72WSIThqEDmn1Q9F2fG7YAIv1TPGS8CXphvGlnGsMK94U7dwXW7i8CRc56LU2YaK3o7SWnkANSYHUat3Bo32k548WeVCE3XAPnMJCksOorTgCyqW3AcAqHyNGut9h1pLQUOjO5F1zsmuMCeOcGE6D2YU6icLzQbSjnOVJ9FKrccIr1Xn8lKmU4W53GaXsEJcHgxJMTvmquMA9wSi0uPBhbiLtAkl5GaY1UoKHS6yDTN4xCaPx9G/rAyPO1BsIG0g0QUuGB2PGmwkpDeZ08yAZIcX90gMfX89DMHLSseVMuqbUwXj4mZeu1AFsfIcpVK+Pdeofcl2m4BQyYNanFB4XUg2Wyg5aTFW5icJOeK3aoMx8BAzlfA69FeGs+F5+eL2hbatTf0TjUFvO0ZGiRpNtNFFH0OMMdm4ButMMZmneEm9WUfat/XaK3ojVtKg85hJe3ejbrLXpCOT2hKNHi8SVlZ0Px+LTDFhdsLpxbrhOrvJa94ErOuiQwEAAAAA') format('woff2'), 5 | url('//at.alicdn.com/t/font_1120834_hvoztl864h6.woff?t=1554258412999') format('woff'), 6 | url('//at.alicdn.com/t/font_1120834_hvoztl864h6.ttf?t=1554258412999') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('//at.alicdn.com/t/font_1120834_hvoztl864h6.svg?t=1554258412999#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-iconfontzhizuobiaozhun16:before { 19 | content: "\e60f"; 20 | } 21 | 22 | .icon-location:before { 23 | content: "\e619"; 24 | } 25 | 26 | .icon-dayuhao:before { 27 | content: "\e600"; 28 | } 29 | 30 | .icon-jizuobiaotu:before { 31 | content: "\e613"; 32 | } 33 | 34 | .icon-dayuhao1:before { 35 | content: "\e65c"; 36 | } 37 | 38 | .icon-zuobiao:before { 39 | content: "\e657"; 40 | } 41 | 42 | .icon-zhengque:before { 43 | content: "\e64a"; 44 | } 45 | 46 | .icon-fanhui:before { 47 | content: "\e60d"; 48 | } 49 | 50 | .icon-iconfront-:before { 51 | content: "\e620"; 52 | } 53 | -------------------------------------------------------------------------------- /pages/shopMap/shopMap.js: -------------------------------------------------------------------------------- 1 | var QQMapWX = require('../../utils/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.min.js'); 2 | var qqmapsdk; 3 | Page({ 4 | data: { 5 | addListShow: false, 6 | chooseCity: false, 7 | regionShow: { 8 | province: false, 9 | city: false, 10 | district: true 11 | }, 12 | regionData: {}, 13 | currentRegion: { 14 | province: '选择城市', 15 | city: '选择城市', 16 | district: '选择城市', 17 | }, 18 | currentProvince: '选择城市', 19 | currentCity: '选择城市', 20 | currentDistrict: '选择城市', 21 | latitude: '', 22 | longitude: '', 23 | centerData: {}, 24 | nearList: [], 25 | suggestion: [], 26 | selectedId: 0, 27 | defaultKeyword: '房产小区', 28 | keyword: '' 29 | }, 30 | onLoad: function () { 31 | let self =this; 32 | self.mapCtx = wx.createMapContext('myMap') 33 | // 实例化API核心类 34 | qqmapsdk = new QQMapWX({ 35 | key: 'W57BZ-JDB6X-XPA4H-Z76MI-73FF2-24BT4' 36 | }); 37 | wx.showLoading({ 38 | title: '加载中' 39 | }); 40 | //定位 41 | wx.getLocation({ 42 | type: 'wgs84', 43 | success(res) { 44 | //console.log(res) 45 | const latitude = res.latitude 46 | const longitude = res.longitude 47 | const speed = res.speed 48 | const accuracy = res.accuracy 49 | //你地址解析 50 | qqmapsdk.reverseGeocoder({ 51 | location: { 52 | latitude: latitude, 53 | longitude: longitude 54 | }, 55 | success: function (res) { 56 | //console.log(res) 57 | self.setData({ 58 | latitude: latitude, 59 | longitude: longitude, 60 | currentRegion: res.result.address_component, 61 | keyword: self.data.defaultKeyword 62 | }) 63 | // 调用接口 64 | self.nearby_search(); 65 | }, 66 | }); 67 | }, 68 | fail(err) { 69 | //console.log(err) 70 | wx.hideLoading({}); 71 | wx.showToast({ 72 | title: '定位失败', 73 | icon: 'none', 74 | duration: 1500 75 | }) 76 | setTimeout(function () { 77 | wx.navigateBack({ 78 | delta: 1 79 | }) 80 | }, 1500) 81 | } 82 | }) 83 | }, 84 | onReady: function () { 85 | 86 | }, 87 | //监听拖动地图,拖动结束根据中心点更新页面 88 | mapChange: function (e) { 89 | let self = this; 90 | if (e.type == 'end' && (e.causedBy == 'scale' || e.causedBy == 'drag')){ 91 | self.mapCtx.getCenterLocation({ 92 | success: function (res) { 93 | //console.log(res) 94 | self.setData({ 95 | nearList:[], 96 | latitude: res.latitude, 97 | longitude: res.longitude, 98 | }) 99 | self.nearby_search(); 100 | } 101 | }) 102 | } 103 | 104 | }, 105 | //重新定位 106 | reload: function () { 107 | this.onLoad(); 108 | }, 109 | //整理目前选择省市区的省市区列表 110 | getRegionData: function () { 111 | let self = this; 112 | //调用获取城市列表接口 113 | qqmapsdk.getCityList({ 114 | success: function (res) {//成功后的回调 115 | //console.log(res) 116 | let provinceArr = res.result[0]; 117 | let cityArr = []; 118 | let districtArr = []; 119 | for (var i = 0; i < provinceArr.length; i++) { 120 | var name = provinceArr[i].fullname; 121 | if (self.data.currentRegion.province == name) { 122 | if (name == '北京市' || name == '天津市' || name == '上海市' || name == '重庆市') { 123 | cityArr.push(provinceArr[i]) 124 | } else { 125 | qqmapsdk.getDistrictByCityId({ 126 | // 传入对应省份ID获得城市数据,传入城市ID获得区县数据,依次类推 127 | id: provinceArr[i].id, 128 | success: function (res) {//成功后的回调 129 | //console.log(res); 130 | cityArr = res.result[0]; 131 | self.setData({ 132 | regionData: { 133 | province: provinceArr, 134 | city: cityArr, 135 | district: districtArr 136 | } 137 | }) 138 | }, 139 | fail: function (error) { 140 | //console.error(error); 141 | }, 142 | complete: function (res) { 143 | //console.log(res); 144 | } 145 | }); 146 | } 147 | } 148 | } 149 | for (var i = 0; i < res.result[1].length; i++) { 150 | var name = res.result[1][i].fullname; 151 | if (self.data.currentRegion.city == name) { 152 | qqmapsdk.getDistrictByCityId({ 153 | // 传入对应省份ID获得城市数据,传入城市ID获得区县数据,依次类推 154 | id: res.result[1][i].id, 155 | success: function (res) {//成功后的回调 156 | //console.log(res); 157 | districtArr = res.result[0]; 158 | self.setData({ 159 | regionData: { 160 | province: provinceArr, 161 | city: cityArr, 162 | district: districtArr 163 | } 164 | }) 165 | }, 166 | fail: function (error) { 167 | //console.error(error); 168 | }, 169 | complete: function (res) { 170 | //console.log(res); 171 | } 172 | }); 173 | } 174 | } 175 | }, 176 | fail: function (error) { 177 | //console.error(error); 178 | }, 179 | complete: function (res) { 180 | //console.log(res); 181 | } 182 | }); 183 | }, 184 | onShow: function () { 185 | let self = this; 186 | }, 187 | //地图标记点 188 | addMarker: function (data) { 189 | //console.log(data) 190 | //console.log(data.title) 191 | var mks = []; 192 | mks.push({ // 获取返回结果,放到mks数组中 193 | title: data.title, 194 | id: data.id, 195 | addr: data.addr, 196 | province: data.province, 197 | city: data.city, 198 | district: data.district, 199 | latitude: data.latitude, 200 | longitude: data.longitude, 201 | iconPath: "/images/my_marker.png", //图标路径 202 | width: 25, 203 | height: 25 204 | }) 205 | this.setData({ //设置markers属性,将搜索结果显示在地图中 206 | markers: mks, 207 | currentRegion: { 208 | province: data.province, 209 | city: data.city, 210 | district: data.district, 211 | } 212 | }) 213 | wx.hideLoading({}); 214 | }, 215 | //点击选择搜索结果 216 | backfill: function (e) { 217 | var id = e.currentTarget.id; 218 | let name = e.currentTarget.dataset.name; 219 | for (var i = 0; i < this.data.suggestion.length; i++) { 220 | if (i == id) { 221 | //console.log(this.data.suggestion[i]) 222 | this.setData({ 223 | centerData: this.data.suggestion[i], 224 | addListShow: false, 225 | latitude: this.data.suggestion[i].latitude, 226 | longitude: this.data.suggestion[i].longitude 227 | }); 228 | this.nearby_search(); 229 | return; 230 | //console.log(this.data.centerData) 231 | } 232 | } 233 | }, 234 | //点击选择地图下方列表某项 235 | chooseCenter: function (e) { 236 | var id = e.currentTarget.id; 237 | let name = e.currentTarget.dataset.name; 238 | for (var i = 0; i < this.data.nearList.length; i++) { 239 | if (i == id) { 240 | this.setData({ 241 | selectedId: id, 242 | centerData: this.data.nearList[i], 243 | latitude: this.data.nearList[i].latitude, 244 | longitude: this.data.nearList[i].longitude, 245 | }); 246 | this.addMarker(this.data.nearList[id]); 247 | return; 248 | //console.log(this.data.centerData) 249 | } 250 | } 251 | }, 252 | //显示搜索列表 253 | showAddList: function () { 254 | this.setData({ 255 | addListShow: true 256 | }) 257 | }, 258 | // 根据关键词搜索附近位置 259 | nearby_search: function () { 260 | var self = this; 261 | wx.hideLoading(); 262 | wx.showLoading({ 263 | title: '加载中' 264 | }); 265 | // 调用接口 266 | qqmapsdk.search({ 267 | keyword: self.data.keyword, //搜索关键词 268 | //boundary: 'nearby(' + self.data.latitude + ', ' + self.data.longitude + ', 1000, 16)', 269 | location: self.data.latitude + ',' + self.data.longitude, 270 | page_size: 20, 271 | page_index: 1, 272 | success: function (res) { //搜索成功后的回调 273 | //console.log(res.data) 274 | var sug = []; 275 | for (var i = 0; i < res.data.length; i++) { 276 | sug.push({ // 获取返回结果,放到sug数组中 277 | title: res.data[i].title, 278 | id: res.data[i].id, 279 | addr: res.data[i].address, 280 | province: res.data[i].ad_info.province, 281 | city: res.data[i].ad_info.city, 282 | district: res.data[i].ad_info.district, 283 | latitude: res.data[i].location.lat, 284 | longitude: res.data[i].location.lng 285 | }); 286 | } 287 | self.setData({ 288 | selectedId: 0, 289 | centerData: sug[0], 290 | nearList: sug, 291 | suggestion: sug 292 | }) 293 | self.addMarker(sug[0]); 294 | }, 295 | fail: function (res) { 296 | //console.log(res); 297 | }, 298 | complete: function (res) { 299 | //console.log(res); 300 | } 301 | }); 302 | }, 303 | //根据关键词搜索匹配位置 304 | getsuggest: function (e) { 305 | var _this = this; 306 | var keyword = e.detail.value; 307 | _this.setData({ 308 | addListShow: true 309 | }) 310 | //调用关键词提示接口 311 | qqmapsdk.getSuggestion({ 312 | //获取输入框值并设置keyword参数 313 | keyword: keyword, //用户输入的关键词,可设置固定值,如keyword:'KFC' 314 | location: _this.data.latitude + ',' + _this.data.longitude, 315 | page_size: 20, 316 | page_index: 1, 317 | //region:'北京', //设置城市名,限制关键词所示的地域范围,非必填参数 318 | success: function (res) {//搜索成功后的回调 319 | //console.log(res); 320 | var sug = []; 321 | for (var i = 0; i < res.data.length; i++) { 322 | sug.push({ // 获取返回结果,放到sug数组中 323 | title: res.data[i].title, 324 | id: res.data[i].id, 325 | addr: res.data[i].address, 326 | province: res.data[i].province, 327 | city: res.data[i].city, 328 | district: res.data[i].district, 329 | latitude: res.data[i].location.lat, 330 | longitude: res.data[i].location.lng 331 | }); 332 | } 333 | _this.setData({ //设置suggestion属性,将关键词搜索结果以列表形式展示 334 | suggestion: sug, 335 | nearList: sug, 336 | keyword: keyword 337 | }); 338 | }, 339 | fail: function (error) { 340 | //console.error(error); 341 | }, 342 | complete: function (res) { 343 | //console.log(res); 344 | } 345 | }); 346 | }, 347 | //打开选择省市区页面 348 | chooseCity: function () { 349 | let self = this; 350 | self.getRegionData(); 351 | self.setData({ 352 | chooseCity: true, 353 | regionShow: { 354 | province: false, 355 | city: false, 356 | district: true 357 | }, 358 | currentProvince: self.data.currentRegion.province, 359 | currentCity: self.data.currentRegion.city, 360 | currentDistrict: self.data.currentRegion.district, 361 | }) 362 | }, 363 | //选择省 364 | showProvince: function () { 365 | this.setData({ 366 | regionShow: { 367 | province: true, 368 | city: false, 369 | district: false 370 | } 371 | }) 372 | }, 373 | //选择城市 374 | showCity: function () { 375 | this.setData({ 376 | regionShow: { 377 | province: false, 378 | city: true, 379 | district: false 380 | } 381 | }) 382 | }, 383 | //选择地区 384 | showDistrict: function () { 385 | this.setData({ 386 | regionShow: { 387 | province: false, 388 | city: false, 389 | district: true 390 | } 391 | }) 392 | }, 393 | //选择省之后操作 394 | selectProvince: function (e) { 395 | //console.log(e) 396 | let self = this; 397 | let id = e.currentTarget.dataset.id; 398 | let name = e.currentTarget.dataset.name; 399 | self.setData({ 400 | currentProvince: name, 401 | currentCity: '请选择城市', 402 | }) 403 | if (name == '北京市' || name == '天津市' || name == '上海市' || name == '重庆市'){ 404 | var provinceArr = self.data.regionData.province; 405 | var cityArr = []; 406 | for (var i = 0; i < provinceArr.length;i++){ 407 | if(provinceArr[i].fullname == name){ 408 | cityArr.push(provinceArr[i]) 409 | self.setData({ 410 | regionData: { 411 | province: self.data.regionData.province, 412 | city: cityArr, 413 | district: self.data.regionData.district 414 | } 415 | }) 416 | self.showCity(); 417 | return; 418 | } 419 | } 420 | }else{ 421 | let bj = self.data.regionShow; 422 | self.getById(id, name, bj) 423 | } 424 | }, 425 | //选择城市之后操作 426 | selectCity: function (e) { 427 | let self = this; 428 | let id = e.currentTarget.dataset.id; 429 | let name = e.currentTarget.dataset.name; 430 | self.setData({ 431 | currentCity: name, 432 | currentDistrict: '请选择城市', 433 | }) 434 | let bj = self.data.regionShow; 435 | self.getById(id, name, bj) 436 | }, 437 | //选择区县之后操作 438 | selectDistrict: function (e) { 439 | let self = this; 440 | let id = e.currentTarget.dataset.id; 441 | let name = e.currentTarget.dataset.name; 442 | let latitude = e.currentTarget.dataset.latitude; 443 | let longitude = e.currentTarget.dataset.longitude; 444 | self.setData({ 445 | currentDistrict: name, 446 | latitude: latitude, 447 | longitude: longitude, 448 | currentRegion: { 449 | province: self.data.currentProvince, 450 | city: self.data.currentCity, 451 | district: name 452 | }, 453 | chooseCity: false, 454 | keyword: self.data.defaultKeyword 455 | }) 456 | self.nearby_search(); 457 | }, 458 | //根据选择省市加载市区列表 459 | getById: function (id,name,bj) { 460 | let self = this; 461 | qqmapsdk.getDistrictByCityId({ 462 | // 传入对应省份ID获得城市数据,传入城市ID获得区县数据,依次类推 463 | id: id, //对应接口getCityList返回数据的Id,如:北京是'110000' 464 | success: function (res) {//成功后的回调 465 | //console.log(res); 466 | if(bj.province){ 467 | self.setData({ 468 | regionData: { 469 | province: self.data.regionData.province, 470 | city: res.result[0], 471 | district: self.data.regionData.district 472 | } 473 | }) 474 | self.showCity(); 475 | } else if (bj.city) { 476 | self.setData({ 477 | regionData: { 478 | province: self.data.regionData.province, 479 | city: self.data.regionData.city, 480 | district: res.result[0] 481 | } 482 | }) 483 | self.showDistrict(); 484 | } else { 485 | self.setData({ 486 | chooseCity: false, 487 | }) 488 | } 489 | }, 490 | fail: function (error) { 491 | //console.error(error); 492 | }, 493 | complete: function (res) { 494 | //console.log(res); 495 | } 496 | }); 497 | }, 498 | //返回上一页或关闭搜索页面 499 | back1: function () { 500 | if (this.data.addListShow) { 501 | this.setData({ 502 | addListShow: false 503 | }) 504 | }else { 505 | wx.navigateBack({ 506 | delta: 1 507 | }) 508 | } 509 | }, 510 | //关闭选择省市区页面 511 | back2: function () { 512 | this.setData({ 513 | chooseCity: false 514 | }) 515 | }, 516 | //确认选择地址 517 | selectedOk: function () { 518 | //let pages = getCurrentPages(); //获取当前页面js里面的pages里的所有信息。 519 | //let prevPage = pages[pages.length - 2]; 520 | console.log(this.data.centerData) 521 | //prevPage.setData({ 522 | //storeAddress: this.data.centerData.title 523 | //}) 524 | //wx.navigateBack({ 525 | //delta: 1 526 | //}) 527 | } 528 | }) -------------------------------------------------------------------------------- /pages/shopMap/shopMap.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "地图", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /pages/shopMap/shopMap.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {{currentRegion.district}} 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | {{item.title}} 22 | 23 | {{item.addr}} 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 37 | 38 | 39 | 40 | 41 | 42 | {{currentRegion.district}} 43 | 44 | 请输入您的店铺地址 45 | 46 | 47 | 您可拖动地图, 标记店铺准确位置 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | {{item.title}} 64 | 65 | {{item.addr}} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 选择城市 78 | 79 | 80 | {{currentProvince}} 81 | {{currentCity}} 82 | {{currentDistrict}} 83 | 84 | 85 | 86 | 87 | 88 | {{item.fullname}} 89 | 90 | 91 | 92 | 93 | 94 | 95 | {{item.fullname}} 96 | 97 | 98 | 99 | 100 | 101 | 102 | {{item.fullname}} 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /pages/shopMap/shopMap.wxss: -------------------------------------------------------------------------------- 1 | /* pages/shopMap/shopMap.wxss */ 2 | @import "../../lib/css/iconfont.wxss"; 3 | 4 | .top { 5 | width: 100%; 6 | height: 80rpx; 7 | line-height: 80rpx; 8 | position: fixed; 9 | top: 0; 10 | left: 0; 11 | padding: 30rpx 20rpx; 12 | z-index: 999; 13 | overflow: hidden; 14 | } 15 | .back { 16 | width: 80rpx; 17 | height: 80rpx; 18 | line-height: 80rpx; 19 | color: #666; 20 | text-align: center; 21 | background: rgb(255,255,255); 22 | font-size: 50rpx; 23 | border-radius: 50%; 24 | float: left; 25 | } 26 | .back cover-image{ 27 | width: 50rpx; 28 | height: 50rpx; 29 | display: inline-block; 30 | margin-top: 15rpx; 31 | } 32 | .search-box { 33 | width: 610rpx; 34 | height: 80rpx; 35 | line-height: 80rpx; 36 | border-radius: 40rpx; 37 | background: rgb(255,255,255); 38 | margin-left: 20rpx; 39 | float: left; 40 | overflow: hidden; 41 | } 42 | .search-box1 { 43 | border: 1px solid #ccc; 44 | border-radius: 10rpx; 45 | background: #eee; 46 | } 47 | .search-box .region { 48 | width: 199rpx; 49 | line-height: 80rpx; 50 | font-size: 30rpx; 51 | color: #282828; 52 | text-align: center; 53 | float: left; 54 | white-space: nowrap; 55 | overflow: hidden; 56 | text-overflow: ellipsis; 57 | } 58 | .search-box .shu { 59 | width: 1rpx; 60 | height: 80rpx; 61 | background:#ccc; 62 | float: left; 63 | } 64 | .search-box input { 65 | width: 380rpx; 66 | height: 80rpx; 67 | line-height: 80rpx; 68 | font-size: 30rpx; 69 | color: #282828; 70 | padding: 10rpx 20rpx; 71 | box-sizing: border-box; 72 | float: left; 73 | } 74 | .search-box .placeholder{ 75 | width: 380rpx; 76 | height: 80rpx; 77 | line-height: 80rpx; 78 | font-size: 30rpx; 79 | color: #ccc; 80 | padding: 0 20rpx; 81 | box-sizing: border-box; 82 | float: left; 83 | } 84 | .add-list-box { 85 | position: absolute; 86 | width: 100%; 87 | height: 100%; 88 | top: 0; 89 | z-index: 998; 90 | padding-top: 150rpx; 91 | background: #fff; 92 | box-sizing: border-box; 93 | overflow: hidden; 94 | } 95 | .add-list { 96 | width: 100%; 97 | height: 1000rpx; 98 | } 99 | .add-item { 100 | line-height: 40rpx; 101 | padding: 30rpx 50rpx; 102 | text-align: left; 103 | border-top: 1px solid #eee; 104 | } 105 | .add-item .title { 106 | color: #282828; 107 | font-size: 32rpx; 108 | white-space: nowrap; 109 | overflow: hidden; 110 | text-overflow: ellipsis; 111 | } 112 | .add-item .add { 113 | color: #707070; 114 | font-size: 24rpx; 115 | white-space: nowrap; 116 | overflow: hidden; 117 | text-overflow: ellipsis; 118 | } 119 | .current-site-icon { 120 | width: 50rpx; 121 | height: 50rpx; 122 | position: absolute; 123 | top: 50%; 124 | left: 50%; 125 | transform: translate(-50%,-50%); 126 | } 127 | .near-list { 128 | height: 650rpx; 129 | padding-bottom: 100rpx; 130 | box-sizing: border-box; 131 | } 132 | .near-item { 133 | line-height: 40rpx; 134 | padding: 30rpx 50rpx 30rpx 90rpx; 135 | text-align: left; 136 | border-bottom: 1px solid #eee; 137 | position: relative; 138 | } 139 | .current-site { 140 | font-size: 40rpx; 141 | color: #3095F9; 142 | position: absolute; 143 | top: 40rpx; 144 | left: 30rpx; 145 | } 146 | .near-item .title { 147 | color: #282828; 148 | font-size: 32rpx; 149 | white-space: nowrap; 150 | overflow: hidden; 151 | text-overflow: ellipsis; 152 | } 153 | .near-item .add { 154 | color: #707070; 155 | font-size: 24rpx; 156 | white-space: nowrap; 157 | overflow: hidden; 158 | text-overflow: ellipsis; 159 | } 160 | .near-item .title1 { 161 | color: #3095F9; 162 | } 163 | .near-item .add1 { 164 | color: #3095F9; 165 | } 166 | .bottom-box { 167 | width: 100%; 168 | padding: 20rpx; 169 | background: #fff; 170 | box-sizing: border-box; 171 | position: fixed; 172 | left: 0; 173 | bottom: 0; 174 | z-index: 88; 175 | overflow: hidden; 176 | } 177 | .bottom-box button{ 178 | width: 100%; 179 | height: 80rpx; 180 | line-height: 80rpx; 181 | border: none; 182 | background: #3095F9; 183 | color: #fff; 184 | font-size: 36rpx; 185 | } 186 | 187 | .region-box { 188 | width: 100%; 189 | height: 100%; 190 | background: #FFF; 191 | position: fixed; 192 | top: 0; 193 | left: 0; 194 | z-index: 1001; 195 | } 196 | .region-box .region-top { 197 | position: relative; 198 | font-size: 40rpx; 199 | color: #282828; 200 | font-weight: bold; 201 | line-height: 100rpx; 202 | text-align: center; 203 | } 204 | .region-box .region-back { 205 | width: 80rpx; 206 | height: 80rpx; 207 | font-size: 50rpx; 208 | text-align: center; 209 | position: absolute; 210 | top: 0; 211 | left: 0; 212 | } 213 | .region-box .region-tabs{ 214 | line-height: 60rpx; 215 | font-size: 20rpx; 216 | } 217 | .region-tabs .tab { 218 | min-width: 100rpx; 219 | max-width: 200rpx; 220 | line-height: 40rpx; 221 | font-size: 20rpx; 222 | color: #3095F9; 223 | text-align: center; 224 | border: 1rpx solid #3095F9; 225 | border-radius: 20rpx; 226 | display: inline-block; 227 | margin: 20rpx 0 20rpx 20rpx; 228 | padding: 3rpx 20rpx; 229 | white-space: nowrap; 230 | overflow: hidden; 231 | text-overflow: ellipsis; 232 | } 233 | .region-list .region-item{ 234 | font-size: 30rpx; 235 | color: #282828; 236 | line-height: 80rpx; 237 | padding: 10rpx 30rpx; 238 | border-top: 1rpx solid #eee; 239 | } 240 | 241 | .map-prompt { 242 | width: 420rpx; 243 | height: 60rpx; 244 | line-height: 60rpx; 245 | font-size: 24rpx; 246 | color: #707070; 247 | text-align: center; 248 | background: #fff; 249 | border-radius: 10rpx; 250 | box-shadow: 0 0 10rpx rgba(0,0,0,0.1); 251 | position: absolute; 252 | bottom: 40rpx; 253 | left: 50%; 254 | transform: translate(-50%,0); 255 | } 256 | .reload { 257 | width: 80rpx; 258 | height: 80rpx; 259 | background: #fff; 260 | border-radius: 50%; 261 | box-shadow: 0 0 10rpx rgba(0,0,0,0.1); 262 | position: absolute; 263 | bottom: 30rpx; 264 | right: 30rpx; 265 | } 266 | .reload .center1 { 267 | width: 30rpx; 268 | height: 30rpx; 269 | border: 1rpx solid #3095F9; 270 | border-radius: 50%; 271 | margin: 24rpx auto; 272 | } 273 | .reload .center2 { 274 | width: 25rpx; 275 | height: 25rpx; 276 | background: #3095F9; 277 | border-radius: 50%; 278 | margin: 3rpx auto; 279 | } -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件", 3 | "packOptions": { 4 | "ignore": [] 5 | }, 6 | "setting": { 7 | "urlCheck": true, 8 | "es6": true, 9 | "postcss": true, 10 | "minified": true, 11 | "newFeature": true, 12 | "autoAudits": false 13 | }, 14 | "compileType": "miniprogram", 15 | "libVersion": "2.6.4", 16 | "appid": "wxbedc59cf0dbf5250", 17 | "projectname": "map", 18 | "debugOptions": { 19 | "hidedInDevtools": [] 20 | }, 21 | "isGameTourist": false, 22 | "condition": { 23 | "search": { 24 | "current": -1, 25 | "list": [] 26 | }, 27 | "conversation": { 28 | "current": -1, 29 | "list": [] 30 | }, 31 | "game": { 32 | "currentL": -1, 33 | "list": [] 34 | }, 35 | "miniprogram": { 36 | "current": -1, 37 | "list": [] 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /utils/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 微信小程序JavaScriptSDK 3 | * 4 | * @version 1.2 5 | * @date 2019-03-06 6 | * @author v_ylyue@tencent.com 7 | */ 8 | 9 | var ERROR_CONF = { 10 | KEY_ERR: 311, 11 | KEY_ERR_MSG: 'key格式错误', 12 | PARAM_ERR: 310, 13 | PARAM_ERR_MSG: '请求参数信息有误', 14 | SYSTEM_ERR: 600, 15 | SYSTEM_ERR_MSG: '系统错误', 16 | WX_ERR_CODE: 1000, 17 | WX_OK_CODE: 200 18 | }; 19 | var BASE_URL = 'https://apis.map.qq.com/ws/'; 20 | var URL_SEARCH = BASE_URL + 'place/v1/search'; 21 | var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion'; 22 | var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/'; 23 | var URL_CITY_LIST = BASE_URL + 'district/v1/list'; 24 | var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren'; 25 | var URL_DISTANCE = BASE_URL + 'distance/v1/'; 26 | var URL_DIRECTION = BASE_URL + 'direction/v1/'; 27 | var MODE = { 28 | driving: 'driving', 29 | transit: 'transit' 30 | }; 31 | var EARTH_RADIUS = 6378136.49; 32 | var Utils = { 33 | /** 34 | * md5加密方法 35 | * 版权所有©2011 Sebastian Tschan,https://blueimp.net 36 | */ 37 | safeAdd(x, y) { 38 | var lsw = (x & 0xffff) + (y & 0xffff); 39 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 40 | return (msw << 16) | (lsw & 0xffff); 41 | }, 42 | bitRotateLeft(num, cnt) { 43 | return (num << cnt) | (num >>> (32 - cnt)); 44 | }, 45 | md5cmn(q, a, b, x, s, t) { 46 | return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b); 47 | }, 48 | md5ff(a, b, c, d, x, s, t) { 49 | return this.md5cmn((b & c) | (~b & d), a, b, x, s, t); 50 | }, 51 | md5gg(a, b, c, d, x, s, t) { 52 | return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t); 53 | }, 54 | md5hh(a, b, c, d, x, s, t) { 55 | return this.md5cmn(b ^ c ^ d, a, b, x, s, t); 56 | }, 57 | md5ii(a, b, c, d, x, s, t) { 58 | return this.md5cmn(c ^ (b | ~d), a, b, x, s, t); 59 | }, 60 | binlMD5(x, len) { 61 | /* append padding */ 62 | x[len >> 5] |= 0x80 << (len % 32); 63 | x[((len + 64) >>> 9 << 4) + 14] = len; 64 | 65 | var i; 66 | var olda; 67 | var oldb; 68 | var oldc; 69 | var oldd; 70 | var a = 1732584193; 71 | var b = -271733879; 72 | var c = -1732584194; 73 | var d = 271733878; 74 | 75 | for (i = 0; i < x.length; i += 16) { 76 | olda = a; 77 | oldb = b; 78 | oldc = c; 79 | oldd = d; 80 | 81 | a = this.md5ff(a, b, c, d, x[i], 7, -680876936); 82 | d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586); 83 | c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819); 84 | b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330); 85 | a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897); 86 | d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426); 87 | c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341); 88 | b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983); 89 | a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416); 90 | d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417); 91 | c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063); 92 | b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162); 93 | a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682); 94 | d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101); 95 | c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290); 96 | b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329); 97 | 98 | a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510); 99 | d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632); 100 | c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713); 101 | b = this.md5gg(b, c, d, a, x[i], 20, -373897302); 102 | a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691); 103 | d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083); 104 | c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335); 105 | b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848); 106 | a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438); 107 | d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690); 108 | c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961); 109 | b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501); 110 | a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467); 111 | d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784); 112 | c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473); 113 | b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734); 114 | 115 | a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558); 116 | d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463); 117 | c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562); 118 | b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556); 119 | a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060); 120 | d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353); 121 | c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632); 122 | b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640); 123 | a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174); 124 | d = this.md5hh(d, a, b, c, x[i], 11, -358537222); 125 | c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979); 126 | b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189); 127 | a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487); 128 | d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835); 129 | c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520); 130 | b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651); 131 | 132 | a = this.md5ii(a, b, c, d, x[i], 6, -198630844); 133 | d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415); 134 | c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905); 135 | b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055); 136 | a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571); 137 | d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606); 138 | c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523); 139 | b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799); 140 | a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359); 141 | d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744); 142 | c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380); 143 | b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649); 144 | a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070); 145 | d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379); 146 | c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259); 147 | b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551); 148 | 149 | a = this.safeAdd(a, olda); 150 | b = this.safeAdd(b, oldb); 151 | c = this.safeAdd(c, oldc); 152 | d = this.safeAdd(d, oldd); 153 | } 154 | return [a, b, c, d]; 155 | }, 156 | binl2rstr(input) { 157 | var i; 158 | var output = ''; 159 | var length32 = input.length * 32; 160 | for (i = 0; i < length32; i += 8) { 161 | output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff); 162 | } 163 | return output; 164 | }, 165 | rstr2binl(input) { 166 | var i; 167 | var output = []; 168 | output[(input.length >> 2) - 1] = undefined; 169 | for (i = 0; i < output.length; i += 1) { 170 | output[i] = 0; 171 | } 172 | var length8 = input.length * 8; 173 | for (i = 0; i < length8; i += 8) { 174 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32); 175 | } 176 | return output; 177 | }, 178 | rstrMD5(s) { 179 | return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8)); 180 | }, 181 | rstrHMACMD5(key, data) { 182 | var i; 183 | var bkey = this.rstr2binl(key); 184 | var ipad = []; 185 | var opad = []; 186 | var hash; 187 | ipad[15] = opad[15] = undefined; 188 | if (bkey.length > 16) { 189 | bkey = this.binlMD5(bkey, key.length * 8); 190 | } 191 | for (i = 0; i < 16; i += 1) { 192 | ipad[i] = bkey[i] ^ 0x36363636; 193 | opad[i] = bkey[i] ^ 0x5c5c5c5c; 194 | } 195 | hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8); 196 | return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128)); 197 | }, 198 | rstr2hex(input) { 199 | var hexTab = '0123456789abcdef'; 200 | var output = ''; 201 | var x; 202 | var i; 203 | for (i = 0; i < input.length; i += 1) { 204 | x = input.charCodeAt(i); 205 | output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f); 206 | } 207 | return output; 208 | }, 209 | str2rstrUTF8(input) { 210 | return unescape(encodeURIComponent(input)); 211 | }, 212 | rawMD5(s) { 213 | return this.rstrMD5(this.str2rstrUTF8(s)); 214 | }, 215 | hexMD5(s) { 216 | return this.rstr2hex(this.rawMD5(s)); 217 | }, 218 | rawHMACMD5(k, d) { 219 | return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d)); 220 | }, 221 | hexHMACMD5(k, d) { 222 | return this.rstr2hex(this.rawHMACMD5(k, d)); 223 | }, 224 | 225 | md5(string, key, raw) { 226 | if (!key) { 227 | if (!raw) { 228 | return this.hexMD5(string); 229 | } 230 | return this.rawMD5(string); 231 | } 232 | if (!raw) { 233 | return this.hexHMACMD5(key, string); 234 | } 235 | return this.rawHMACMD5(key, string); 236 | }, 237 | /** 238 | * 得到md5加密后的sig参数 239 | * @param {Object} requestParam 接口参数 240 | * @param {String} sk签名字符串 241 | * @param {String} featrue 方法名 242 | * @return 返回加密后的sig参数 243 | */ 244 | getSig(requestParam, sk, feature, mode) { 245 | var sig = null; 246 | var requestArr = []; 247 | Object.keys(requestParam).sort().forEach(function(key){ 248 | requestArr.push(key + '=' + requestParam[key]); 249 | }); 250 | if (feature == 'search') { 251 | sig = '/ws/place/v1/search?' + requestArr.join('&') + sk; 252 | } 253 | if (feature == 'suggest') { 254 | sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk; 255 | } 256 | if (feature == 'reverseGeocoder') { 257 | sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk; 258 | } 259 | if (feature == 'geocoder') { 260 | sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk; 261 | } 262 | if (feature == 'getCityList') { 263 | sig = '/ws/district/v1/list?' + requestArr.join('&') + sk; 264 | } 265 | if (feature == 'getDistrictByCityId') { 266 | sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk; 267 | } 268 | if (feature == 'calculateDistance') { 269 | sig = '/ws/distance/v1/?' + requestArr.join('&') + sk; 270 | } 271 | if (feature == 'direction') { 272 | sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk; 273 | } 274 | sig = this.md5(sig); 275 | return sig; 276 | }, 277 | /** 278 | * 得到终点query字符串 279 | * @param {Array|String} 检索数据 280 | */ 281 | location2query(data) { 282 | if (typeof data == 'string') { 283 | return data; 284 | } 285 | var query = ''; 286 | for (var i = 0; i < data.length; i++) { 287 | var d = data[i]; 288 | if (!!query) { 289 | query += ';'; 290 | } 291 | if (d.location) { 292 | query = query + d.location.lat + ',' + d.location.lng; 293 | } 294 | if (d.latitude && d.longitude) { 295 | query = query + d.latitude + ',' + d.longitude; 296 | } 297 | } 298 | return query; 299 | }, 300 | 301 | /** 302 | * 计算角度 303 | */ 304 | rad(d) { 305 | return d * Math.PI / 180.0; 306 | }, 307 | /** 308 | * 处理终点location数组 309 | * @return 返回终点数组 310 | */ 311 | getEndLocation(location){ 312 | var to = location.split(';'); 313 | var endLocation = []; 314 | for (var i = 0; i < to.length; i++) { 315 | endLocation.push({ 316 | lat: parseFloat(to[i].split(',')[0]), 317 | lng: parseFloat(to[i].split(',')[1]) 318 | }) 319 | } 320 | return endLocation; 321 | }, 322 | 323 | /** 324 | * 计算两点间直线距离 325 | * @param a 表示纬度差 326 | * @param b 表示经度差 327 | * @return 返回的是距离,单位m 328 | */ 329 | getDistance(latFrom, lngFrom, latTo, lngTo) { 330 | var radLatFrom = this.rad(latFrom); 331 | var radLatTo = this.rad(latTo); 332 | var a = radLatFrom - radLatTo; 333 | var b = this.rad(lngFrom) - this.rad(lngTo); 334 | 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))); 335 | distance = distance * EARTH_RADIUS; 336 | distance = Math.round(distance * 10000) / 10000; 337 | return parseFloat(distance.toFixed(0)); 338 | }, 339 | /** 340 | * 使用微信接口进行定位 341 | */ 342 | getWXLocation(success, fail, complete) { 343 | wx.getLocation({ 344 | type: 'gcj02', 345 | success: success, 346 | fail: fail, 347 | complete: complete 348 | }); 349 | }, 350 | 351 | /** 352 | * 获取location参数 353 | */ 354 | getLocationParam(location) { 355 | if (typeof location == 'string') { 356 | var locationArr = location.split(','); 357 | if (locationArr.length === 2) { 358 | location = { 359 | latitude: location.split(',')[0], 360 | longitude: location.split(',')[1] 361 | }; 362 | } else { 363 | location = {}; 364 | } 365 | } 366 | return location; 367 | }, 368 | 369 | /** 370 | * 回调函数默认处理 371 | */ 372 | polyfillParam(param) { 373 | param.success = param.success || function () { }; 374 | param.fail = param.fail || function () { }; 375 | param.complete = param.complete || function () { }; 376 | }, 377 | 378 | /** 379 | * 验证param对应的key值是否为空 380 | * 381 | * @param {Object} param 接口参数 382 | * @param {String} key 对应参数的key 383 | */ 384 | checkParamKeyEmpty(param, key) { 385 | if (!param[key]) { 386 | var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误'); 387 | param.fail(errconf); 388 | param.complete(errconf); 389 | return true; 390 | } 391 | return false; 392 | }, 393 | 394 | /** 395 | * 验证参数中是否存在检索词keyword 396 | * 397 | * @param {Object} param 接口参数 398 | */ 399 | checkKeyword(param){ 400 | return !this.checkParamKeyEmpty(param, 'keyword'); 401 | }, 402 | 403 | /** 404 | * 验证location值 405 | * 406 | * @param {Object} param 接口参数 407 | */ 408 | checkLocation(param) { 409 | var location = this.getLocationParam(param.location); 410 | if (!location || !location.latitude || !location.longitude) { 411 | var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误'); 412 | param.fail(errconf); 413 | param.complete(errconf); 414 | return false; 415 | } 416 | return true; 417 | }, 418 | 419 | /** 420 | * 构造错误数据结构 421 | * @param {Number} errCode 错误码 422 | * @param {Number} errMsg 错误描述 423 | */ 424 | buildErrorConfig(errCode, errMsg) { 425 | return { 426 | status: errCode, 427 | message: errMsg 428 | }; 429 | }, 430 | 431 | /** 432 | * 433 | * 数据处理函数 434 | * 根据传入参数不同处理不同数据 435 | * @param {String} feature 功能名称 436 | * search 地点搜索 437 | * suggest关键词提示 438 | * reverseGeocoder逆地址解析 439 | * geocoder地址解析 440 | * getCityList获取城市列表:父集 441 | * getDistrictByCityId获取区县列表:子集 442 | * calculateDistance距离计算 443 | * @param {Object} param 接口参数 444 | * @param {Object} data 数据 445 | */ 446 | handleData(param,data,feature){ 447 | if (feature == 'search') { 448 | var searchResult = data.data; 449 | var searchSimplify = []; 450 | for (var i = 0; i < searchResult.length; i++) { 451 | searchSimplify.push({ 452 | id: searchResult[i].id || null, 453 | title: searchResult[i].title || null, 454 | latitude: searchResult[i].location && searchResult[i].location.lat || null, 455 | longitude: searchResult[i].location && searchResult[i].location.lng || null, 456 | address: searchResult[i].address || null, 457 | category: searchResult[i].category || null, 458 | tel: searchResult[i].tel || null, 459 | adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null, 460 | city: searchResult[i].ad_info && searchResult[i].ad_info.city || null, 461 | district: searchResult[i].ad_info && searchResult[i].ad_info.district || null, 462 | province: searchResult[i].ad_info && searchResult[i].ad_info.province || null 463 | }) 464 | } 465 | param.success(data, { 466 | searchResult: searchResult, 467 | searchSimplify: searchSimplify 468 | }) 469 | } else if (feature == 'suggest') { 470 | var suggestResult = data.data; 471 | var suggestSimplify = []; 472 | for (var i = 0; i < suggestResult.length; i++) { 473 | suggestSimplify.push({ 474 | adcode: suggestResult[i].adcode || null, 475 | address: suggestResult[i].address || null, 476 | category: suggestResult[i].category || null, 477 | city: suggestResult[i].city || null, 478 | district: suggestResult[i].district || null, 479 | id: suggestResult[i].id || null, 480 | latitude: suggestResult[i].location && suggestResult[i].location.lat || null, 481 | longitude: suggestResult[i].location && suggestResult[i].location.lng || null, 482 | province: suggestResult[i].province || null, 483 | title: suggestResult[i].title || null, 484 | type: suggestResult[i].type || null 485 | }) 486 | } 487 | param.success(data, { 488 | suggestResult: suggestResult, 489 | suggestSimplify: suggestSimplify 490 | }) 491 | } else if (feature == 'reverseGeocoder') { 492 | var reverseGeocoderResult = data.result; 493 | var reverseGeocoderSimplify = { 494 | address: reverseGeocoderResult.address || null, 495 | latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null, 496 | longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null, 497 | adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null, 498 | city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null, 499 | district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null, 500 | nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null, 501 | province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null, 502 | street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null, 503 | street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null, 504 | recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null, 505 | rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null 506 | }; 507 | if (reverseGeocoderResult.pois) {//判断是否返回周边poi 508 | var pois = reverseGeocoderResult.pois; 509 | var poisSimplify = []; 510 | for (var i = 0;i < pois.length;i++) { 511 | poisSimplify.push({ 512 | id: pois[i].id || null, 513 | title: pois[i].title || null, 514 | latitude: pois[i].location && pois[i].location.lat || null, 515 | longitude: pois[i].location && pois[i].location.lng || null, 516 | address: pois[i].address || null, 517 | category: pois[i].category || null, 518 | adcode: pois[i].ad_info && pois[i].ad_info.adcode || null, 519 | city: pois[i].ad_info && pois[i].ad_info.city || null, 520 | district: pois[i].ad_info && pois[i].ad_info.district || null, 521 | province: pois[i].ad_info && pois[i].ad_info.province || null 522 | }) 523 | } 524 | param.success(data,{ 525 | reverseGeocoderResult: reverseGeocoderResult, 526 | reverseGeocoderSimplify: reverseGeocoderSimplify, 527 | pois: pois, 528 | poisSimplify: poisSimplify 529 | }) 530 | } else { 531 | param.success(data, { 532 | reverseGeocoderResult: reverseGeocoderResult, 533 | reverseGeocoderSimplify: reverseGeocoderSimplify 534 | }) 535 | } 536 | } else if (feature == 'geocoder') { 537 | var geocoderResult = data.result; 538 | var geocoderSimplify = { 539 | title: geocoderResult.title || null, 540 | latitude: geocoderResult.location && geocoderResult.location.lat || null, 541 | longitude: geocoderResult.location && geocoderResult.location.lng || null, 542 | adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null, 543 | province: geocoderResult.address_components && geocoderResult.address_components.province || null, 544 | city: geocoderResult.address_components && geocoderResult.address_components.city || null, 545 | district: geocoderResult.address_components && geocoderResult.address_components.district || null, 546 | street: geocoderResult.address_components && geocoderResult.address_components.street || null, 547 | street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null, 548 | level: geocoderResult.level || null 549 | }; 550 | param.success(data,{ 551 | geocoderResult: geocoderResult, 552 | geocoderSimplify: geocoderSimplify 553 | }); 554 | } else if (feature == 'getCityList') { 555 | var provinceResult = data.result[0]; 556 | var cityResult = data.result[1]; 557 | var districtResult = data.result[2]; 558 | param.success(data,{ 559 | provinceResult: provinceResult, 560 | cityResult: cityResult, 561 | districtResult: districtResult 562 | }); 563 | } else if (feature == 'getDistrictByCityId') { 564 | var districtByCity = data.result[0]; 565 | param.success(data, districtByCity); 566 | } else if (feature == 'calculateDistance') { 567 | var calculateDistanceResult = data.result.elements; 568 | var distance = []; 569 | for (var i = 0; i < calculateDistanceResult.length; i++){ 570 | distance.push(calculateDistanceResult[i].distance); 571 | } 572 | param.success(data, { 573 | calculateDistanceResult: calculateDistanceResult, 574 | distance: distance 575 | }); 576 | } else if (feature == 'direction') { 577 | var direction = data.result.routes; 578 | param.success(data,direction); 579 | } else { 580 | param.success(data); 581 | } 582 | }, 583 | 584 | /** 585 | * 构造微信请求参数,公共属性处理 586 | * 587 | * @param {Object} param 接口参数 588 | * @param {Object} param 配置项 589 | * @param {String} feature 方法名 590 | */ 591 | buildWxRequestConfig(param, options, feature) { 592 | var that = this; 593 | options.header = { "content-type": "application/json" }; 594 | options.method = 'GET'; 595 | options.success = function (res) { 596 | var data = res.data; 597 | if (data.status === 0) { 598 | that.handleData(param, data, feature); 599 | } else { 600 | param.fail(data); 601 | } 602 | }; 603 | options.fail = function (res) { 604 | res.statusCode = ERROR_CONF.WX_ERR_CODE; 605 | param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); 606 | }; 607 | options.complete = function (res) { 608 | var statusCode = +res.statusCode; 609 | switch(statusCode) { 610 | case ERROR_CONF.WX_ERR_CODE: { 611 | param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); 612 | break; 613 | } 614 | case ERROR_CONF.WX_OK_CODE: { 615 | var data = res.data; 616 | if (data.status === 0) { 617 | param.complete(data); 618 | } else { 619 | param.complete(that.buildErrorConfig(data.status, data.message)); 620 | } 621 | break; 622 | } 623 | default:{ 624 | param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG)); 625 | } 626 | 627 | } 628 | }; 629 | return options; 630 | }, 631 | 632 | /** 633 | * 处理用户参数是否传入坐标进行不同的处理 634 | */ 635 | locationProcess(param, locationsuccess, locationfail, locationcomplete) { 636 | var that = this; 637 | locationfail = locationfail || function (res) { 638 | res.statusCode = ERROR_CONF.WX_ERR_CODE; 639 | param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); 640 | }; 641 | locationcomplete = locationcomplete || function (res) { 642 | if (res.statusCode == ERROR_CONF.WX_ERR_CODE) { 643 | param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); 644 | } 645 | }; 646 | if (!param.location) { 647 | that.getWXLocation(locationsuccess, locationfail, locationcomplete); 648 | } else if (that.checkLocation(param)) { 649 | var location = Utils.getLocationParam(param.location); 650 | locationsuccess(location); 651 | } 652 | } 653 | }; 654 | 655 | 656 | class QQMapWX { 657 | 658 | /** 659 | * 构造函数 660 | * 661 | * @param {Object} options 接口参数,key 为必选参数 662 | */ 663 | constructor(options) { 664 | if (!options.key) { 665 | throw Error('key值不能为空'); 666 | } 667 | this.key = options.key; 668 | }; 669 | 670 | /** 671 | * POI周边检索 672 | * 673 | * @param {Object} options 接口参数对象 674 | * 675 | * 参数对象结构可以参考 676 | * @see http://lbs.qq.com/webservice_v1/guide-search.html 677 | */ 678 | search(options) { 679 | var that = this; 680 | options = options || {}; 681 | 682 | Utils.polyfillParam(options); 683 | 684 | if (!Utils.checkKeyword(options)) { 685 | return; 686 | } 687 | 688 | var requestParam = { 689 | keyword: options.keyword, 690 | orderby: options.orderby || '_distance', 691 | page_size: options.page_size || 10, 692 | page_index: options.page_index || 1, 693 | output: 'json', 694 | key: that.key 695 | }; 696 | 697 | if (options.address_format) { 698 | requestParam.address_format = options.address_format; 699 | } 700 | 701 | if (options.filter) { 702 | requestParam.filter = options.filter; 703 | } 704 | 705 | var distance = options.distance || "1000"; 706 | var auto_extend = options.auto_extend || 1; 707 | var region = null; 708 | var rectangle = null; 709 | 710 | //判断城市限定参数 711 | if (options.region) { 712 | region = options.region; 713 | } 714 | 715 | //矩形限定坐标(暂时只支持字符串格式) 716 | if (options.rectangle) { 717 | rectangle = options.rectangle; 718 | } 719 | 720 | var locationsuccess = function (result) { 721 | if (region && !rectangle) { 722 | //城市限定参数拼接 723 | requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")"; 724 | if (options.sig) { 725 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'search'); 726 | } 727 | } else if (rectangle && !region) { 728 | //矩形搜索 729 | requestParam.boundary = "rectangle(" + rectangle + ")"; 730 | if (options.sig) { 731 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'search'); 732 | } 733 | } else { 734 | requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")"; 735 | if (options.sig) { 736 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'search'); 737 | } 738 | } 739 | wx.request(Utils.buildWxRequestConfig(options, { 740 | url: URL_SEARCH, 741 | data: requestParam 742 | }, 'search')); 743 | }; 744 | Utils.locationProcess(options, locationsuccess); 745 | }; 746 | 747 | /** 748 | * sug模糊检索 749 | * 750 | * @param {Object} options 接口参数对象 751 | * 752 | * 参数对象结构可以参考 753 | * http://lbs.qq.com/webservice_v1/guide-suggestion.html 754 | */ 755 | getSuggestion(options) { 756 | var that = this; 757 | options = options || {}; 758 | Utils.polyfillParam(options); 759 | 760 | if (!Utils.checkKeyword(options)) { 761 | return; 762 | } 763 | 764 | var requestParam = { 765 | keyword: options.keyword, 766 | region: options.region || '全国', 767 | region_fix: options.region_fix || 0, 768 | policy: options.policy || 0, 769 | page_size: options.page_size || 10,//控制显示条数 770 | page_index: options.page_index || 1,//控制页数 771 | get_subpois : options.get_subpois || 0,//返回子地点 772 | output: 'json', 773 | key: that.key 774 | }; 775 | //长地址 776 | if (options.address_format) { 777 | requestParam.address_format = options.address_format; 778 | } 779 | //过滤 780 | if (options.filter) { 781 | requestParam.filter = options.filter; 782 | } 783 | //排序 784 | if (options.location) { 785 | var locationsuccess = function (result) { 786 | requestParam.location = result.latitude + ',' + result.longitude; 787 | if (options.sig) { 788 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest'); 789 | } 790 | wx.request(Utils.buildWxRequestConfig(options, { 791 | url: URL_SUGGESTION, 792 | data: requestParam 793 | }, "suggest")); 794 | }; 795 | Utils.locationProcess(options, locationsuccess); 796 | } else { 797 | if (options.sig) { 798 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest'); 799 | } 800 | wx.request(Utils.buildWxRequestConfig(options, { 801 | url: URL_SUGGESTION, 802 | data: requestParam 803 | }, "suggest")); 804 | } 805 | }; 806 | 807 | /** 808 | * 逆地址解析 809 | * 810 | * @param {Object} options 接口参数对象 811 | * 812 | * 请求参数结构可以参考 813 | * http://lbs.qq.com/webservice_v1/guide-gcoder.html 814 | */ 815 | reverseGeocoder(options) { 816 | var that = this; 817 | options = options || {}; 818 | Utils.polyfillParam(options); 819 | var requestParam = { 820 | coord_type: options.coord_type || 5, 821 | get_poi: options.get_poi || 0, 822 | output: 'json', 823 | key: that.key 824 | }; 825 | if (options.poi_options) { 826 | requestParam.poi_options = options.poi_options 827 | } 828 | 829 | var locationsuccess = function (result) { 830 | requestParam.location = result.latitude + ',' + result.longitude; 831 | if (options.sig) { 832 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder'); 833 | } 834 | wx.request(Utils.buildWxRequestConfig(options, { 835 | url: URL_GET_GEOCODER, 836 | data: requestParam 837 | }, 'reverseGeocoder')); 838 | }; 839 | Utils.locationProcess(options, locationsuccess); 840 | }; 841 | 842 | /** 843 | * 地址解析 844 | * 845 | * @param {Object} options 接口参数对象 846 | * 847 | * 请求参数结构可以参考 848 | * http://lbs.qq.com/webservice_v1/guide-geocoder.html 849 | */ 850 | geocoder(options) { 851 | var that = this; 852 | options = options || {}; 853 | Utils.polyfillParam(options); 854 | 855 | if (Utils.checkParamKeyEmpty(options, 'address')) { 856 | return; 857 | } 858 | 859 | var requestParam = { 860 | address: options.address, 861 | output: 'json', 862 | key: that.key 863 | }; 864 | 865 | //城市限定 866 | if (options.region) { 867 | requestParam.region = options.region; 868 | } 869 | 870 | if (options.sig) { 871 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder'); 872 | } 873 | 874 | wx.request(Utils.buildWxRequestConfig(options, { 875 | url: URL_GET_GEOCODER, 876 | data: requestParam 877 | },'geocoder')); 878 | }; 879 | 880 | 881 | /** 882 | * 获取城市列表 883 | * 884 | * @param {Object} options 接口参数对象 885 | * 886 | * 请求参数结构可以参考 887 | * http://lbs.qq.com/webservice_v1/guide-region.html 888 | */ 889 | getCityList(options) { 890 | var that = this; 891 | options = options || {}; 892 | Utils.polyfillParam(options); 893 | var requestParam = { 894 | output: 'json', 895 | key: that.key 896 | }; 897 | 898 | if (options.sig) { 899 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList'); 900 | } 901 | 902 | wx.request(Utils.buildWxRequestConfig(options, { 903 | url: URL_CITY_LIST, 904 | data: requestParam 905 | },'getCityList')); 906 | }; 907 | 908 | /** 909 | * 获取对应城市ID的区县列表 910 | * 911 | * @param {Object} options 接口参数对象 912 | * 913 | * 请求参数结构可以参考 914 | * http://lbs.qq.com/webservice_v1/guide-region.html 915 | */ 916 | getDistrictByCityId(options) { 917 | var that = this; 918 | options = options || {}; 919 | Utils.polyfillParam(options); 920 | 921 | if (Utils.checkParamKeyEmpty(options, 'id')) { 922 | return; 923 | } 924 | 925 | var requestParam = { 926 | id: options.id || '', 927 | output: 'json', 928 | key: that.key 929 | }; 930 | 931 | if (options.sig) { 932 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId'); 933 | } 934 | 935 | wx.request(Utils.buildWxRequestConfig(options, { 936 | url: URL_AREA_LIST, 937 | data: requestParam 938 | },'getDistrictByCityId')); 939 | }; 940 | 941 | /** 942 | * 用于单起点到多终点的路线距离(非直线距离)计算: 943 | * 支持两种距离计算方式:步行和驾车。 944 | * 起点到终点最大限制直线距离10公里。 945 | * 946 | * 新增直线距离计算。 947 | * 948 | * @param {Object} options 接口参数对象 949 | * 950 | * 请求参数结构可以参考 951 | * http://lbs.qq.com/webservice_v1/guide-distance.html 952 | */ 953 | calculateDistance(options) { 954 | var that = this; 955 | options = options || {}; 956 | Utils.polyfillParam(options); 957 | 958 | if (Utils.checkParamKeyEmpty(options, 'to')) { 959 | return; 960 | } 961 | 962 | var requestParam = { 963 | mode: options.mode || 'walking', 964 | to: Utils.location2query(options.to), 965 | output: 'json', 966 | key: that.key 967 | }; 968 | 969 | if (options.from) { 970 | options.location = options.from; 971 | } 972 | 973 | //计算直线距离 974 | if(requestParam.mode == 'straight'){ 975 | var locationsuccess = function (result) { 976 | var locationTo = Utils.getEndLocation(requestParam.to);//处理终点坐标 977 | var data = { 978 | message:"query ok", 979 | result:{ 980 | elements:[] 981 | }, 982 | status:0 983 | }; 984 | for (var i = 0; i < locationTo.length; i++) { 985 | data.result.elements.push({//将坐标存入 986 | distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng), 987 | duration:0, 988 | from:{ 989 | lat: result.latitude, 990 | lng:result.longitude 991 | }, 992 | to:{ 993 | lat: locationTo[i].lat, 994 | lng: locationTo[i].lng 995 | } 996 | }); 997 | } 998 | var calculateResult = data.result.elements; 999 | var distanceResult = []; 1000 | for (var i = 0; i < calculateResult.length; i++) { 1001 | distanceResult.push(calculateResult[i].distance); 1002 | } 1003 | return options.success(data,{ 1004 | calculateResult: calculateResult, 1005 | distanceResult: distanceResult 1006 | }); 1007 | }; 1008 | 1009 | Utils.locationProcess(options, locationsuccess); 1010 | } else { 1011 | var locationsuccess = function (result) { 1012 | requestParam.from = result.latitude + ',' + result.longitude; 1013 | if (options.sig) { 1014 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance'); 1015 | } 1016 | wx.request(Utils.buildWxRequestConfig(options, { 1017 | url: URL_DISTANCE, 1018 | data: requestParam 1019 | },'calculateDistance')); 1020 | }; 1021 | 1022 | Utils.locationProcess(options, locationsuccess); 1023 | } 1024 | }; 1025 | 1026 | /** 1027 | * 路线规划: 1028 | * 1029 | * @param {Object} options 接口参数对象 1030 | * 1031 | * 请求参数结构可以参考 1032 | * https://lbs.qq.com/webservice_v1/guide-road.html 1033 | */ 1034 | direction(options) { 1035 | var that = this; 1036 | options = options || {}; 1037 | Utils.polyfillParam(options); 1038 | 1039 | if (Utils.checkParamKeyEmpty(options, 'to')) { 1040 | return; 1041 | } 1042 | 1043 | var requestParam = { 1044 | output: 'json', 1045 | key: that.key 1046 | }; 1047 | 1048 | //to格式处理 1049 | if (typeof options.to == 'string') { 1050 | requestParam.to = options.to; 1051 | } else { 1052 | requestParam.to = options.to.latitude + ',' + options.to.longitude; 1053 | } 1054 | //初始化局部请求域名 1055 | var SET_URL_DIRECTION = null; 1056 | //设置默认mode属性 1057 | options.mode = options.mode || MODE.driving; 1058 | 1059 | //设置请求域名 1060 | SET_URL_DIRECTION = URL_DIRECTION + options.mode; 1061 | 1062 | if (options.from) { 1063 | options.location = options.from; 1064 | } 1065 | 1066 | if (options.mode == MODE.driving) { 1067 | if (options.from_poi) { 1068 | requestParam.from_poi = options.from_poi; 1069 | } 1070 | if (options.heading) { 1071 | requestParam.heading = options.heading; 1072 | } 1073 | if (options.speed) { 1074 | requestParam.speed = options.speed; 1075 | } 1076 | if (options.accuracy) { 1077 | requestParam.accuracy = options.accuracy; 1078 | } 1079 | if (options.road_type) { 1080 | requestParam.road_type = options.road_type; 1081 | } 1082 | if (options.to_poi) { 1083 | requestParam.to_poi = options.to_poi; 1084 | } 1085 | if (options.from_track) { 1086 | requestParam.from_track = options.from_track; 1087 | } 1088 | if (options.waypoints) { 1089 | requestParam.waypoints = options.waypoints; 1090 | } 1091 | if (options.policy) { 1092 | requestParam.policy = options.policy; 1093 | } 1094 | if (options.plate_number) { 1095 | requestParam.plate_number = options.plate_number; 1096 | } 1097 | } 1098 | 1099 | if (options.mode == MODE.transit) { 1100 | if (options.departure_time) { 1101 | requestParam.departure_time = options.departure_time; 1102 | } 1103 | if (options.policy) { 1104 | requestParam.policy = options.policy; 1105 | } 1106 | } 1107 | 1108 | var locationsuccess = function (result) { 1109 | requestParam.from = result.latitude + ',' + result.longitude; 1110 | if (options.sig) { 1111 | requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction',options.mode); 1112 | } 1113 | wx.request(Utils.buildWxRequestConfig(options, { 1114 | url: SET_URL_DIRECTION, 1115 | data: requestParam 1116 | }, 'direction')); 1117 | }; 1118 | 1119 | Utils.locationProcess(options, locationsuccess); 1120 | } 1121 | }; 1122 | 1123 | module.exports = QQMapWX; -------------------------------------------------------------------------------- /utils/qqmap-wx-jssdk1.2/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: formatTime 19 | } 20 | --------------------------------------------------------------------------------