UNPKG

wb-positioning-jssdk

Version:

Produce universal library with webpack and es6

278 lines (264 loc) 10.7 kB
/** * Created by j_bleach on 2018/10/16 0016. */ import wx from "weixin-js-sdk"; const INTERVAL = 500; // 服务器时间间隔 const POINTLENTH = 3; // 质心点计算数组长度 const CHANGE_GPS = 5000; // 搜索不到蓝牙5000ms后,切换gps const blueToothFn = (target) => { const signUrl = `https://map.parkbobo.com/location/weixin/v1/jsSdkSign`; const getIbeconUrl = `https://map.parkbobo.com/location/weka/v1/classify`; const signBody = `url=${encodeURIComponent(window.location.href.split("#")[0])}`; let phoneType = "ios"; let ibeaconArr = []; // 蓝牙地位点集合 let gpsTimeId = null; // gps定时器标记 const ua = navigator.userAgent.toLowerCase(); if (/iphone|ipad|ipod/.test(ua)) { phoneType = `ios`; } else if (/android/.test(ua)) { phoneType = `android`; } return class bluetooth extends target { constructor() { super(); } getSignature() { console.log("请求签名"); // 注销页面,停止微信 window.onunload = () => { wx.stopSearchBeacons(); }; // 请求签名 fetch(signUrl, { method: "PUT", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body: signBody }).then((response) => response.json()).then((data) => { this.configWx(data.data); this.initIbeacon = true; this.initSuccess(); }).catch((err) => { this.initError(err); }); } // 配置微信 configWx(sign) { wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: sign.appid, // 必填,公众号的唯一标识 timestamp: sign.timestamp, // 必填,生成签名的时间戳 nonceStr: sign.nonceStr, // 必填,生成签名的随机串 signature: sign.signature,// 必填,签名 beta: true, //用于在页面加载之初调用JSAPI jsApiList: ["openWXDeviceLib", "closeWXDeviceLib", "onWXDeviceBluetoothStateChange", "startSearchBeacons", "stopSearchBeacons", "onSearchBeacons", "startRecord", "stopRecord", "translateVoice", "onMenuShareAppMessage", "getLocation"] // 必填,需要使用的JS接口列表 }); wx.error((res) => { this.initError(res); }); } stopIbeaconSearch() { wx.stopSearchBeacons({ complete: () => { console.log("停止蓝牙"); this.stopLocationComplete({code: 0, msg: "蓝牙停止"}); }, }); } /** * @author j_bleach * @date 2018-10-16 * @Description: 开始搜索 * @param name:String * @return name:String */ startIbeaconSearch() { console.log("进入蓝牙"); wx.ready(() => { let time = Date.now(); let flag = false; let timeId = void 0; window.addEventListener("devicemotion", () => { if (Date.now() - time >= 80) { time = Date.now(); if (false === flag) { wx.stopSearchBeacons({ complete: () => { console.log("启动蓝牙搜索"); ibeaconArr = []; this.searchIbeacon(); }, fail: (err) => { console.log("stop fail", err); } }); } flag = true; timeId && clearTimeout(timeId); timeId = setTimeout(() => { flag = false; wx.stopSearchBeacons(); }, 500); } }); if (!this.initGps) { this.onSearchBeacons(); } else { this.onSearchBeaconsWithGps(); } }); } /** * @author j_bleach * @date 2018-10-16 * @Description: 搜索蓝牙点 */ searchIbeacon() { wx.startSearchBeacons({ ticket: "", complete: (t) => { console.log("开启成功", t); this.startSuccess({code: 0, msg: `室内定位启动,${t.errMsg}`}); let n = t.errMsg; if ("startSearchBeacons:already started" === n) { return wx.stopSearchBeacons(() => { this.searchIbeacon(); }); } if ("startSearchBeacons:system unsupported" === n) { this.searchIbeacon(); } "startSearchBeacons:bluetooth power off" === n ? this.startLocationError("蓝牙未打开,请打开蓝牙后,重新打开页面") : "startSearchBeacons:location service disable" === n && this.startLocationError("地理位置服务未打开"); }, fail: (t) => { console.log("开启失败", t); } }); } /** * @author j_bleach * @date 2018-10-17 * @Description: 监听蓝牙点 */ onSearchBeacons() { wx.onSearchBeacons({ //监听iBeacon设备更新事件 complete: (data) => { this.getIbeaconPoints(data); } }); } /** * @author j_bleach * @date 2018-10-18 * @Description: 监听蓝牙点(超时切换gps) * @param name:String * @return name:String */ onSearchBeaconsWithGps() { console.log("进入蓝牙定时搜索"); wx.onSearchBeacons({ //监听iBeacon设备更新事件 complete: (data) => { this.getIbeaconPoints(data); this.currentLocation = "ibeacon"; gpsTimeId && clearTimeout(gpsTimeId); gpsTimeId = setTimeout(() => { console.log("定时器执行", this); this.currentLocation = "gps"; }, CHANGE_GPS); } }); } /** * @author j_bleach * @date 2018-10-17 * @Description: 获取蓝牙点 */ getIbeaconPoints(data) { let filterData = data.beacons && data.beacons .filter(v => v.rssi != 0) .map(v => { return {rssi: v.rssi, device: `${v.major}_${v.minor}`}; }); if (filterData.length === 0) { // this.onSuccess(); } else { filterData = JSON.stringify([filterData]); const getIbeaconBody = `mapId=${this.mapId}&datajson=${filterData} &interval=${INTERVAL}&type=wx_${phoneType}`; fetch(getIbeconUrl, { method: "PUT", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body: getIbeaconBody }).then((response) => response.json()).then((data) => { if (data.code == 0) { const res = data.data; const Polygon = this.setPolygonLocation(res); const ibeaconObj = { isOutdoor: 0, longitude: res.lon, latitude: res.lat, buildingId: res.building, level: res.level, fiducialLat: res.fiducialLat, fiducialLon: res.fiducialLon, locType: "ibeacon", ...Polygon }; this.onSuccessIbeacon(ibeaconObj); } }).catch((err) => { // this.initError(err); console.log(err); }); } } /** * @author j_bleach * @date 2018-10-17 * @Description: 计算质心点 * @param data:array * @return Polygon:obj */ setPolygonLocation(data) { if (ibeaconArr.length < POINTLENTH) { ibeaconArr.push(data); return { polygonLon: 0, polygonLat: 0 }; } else { ibeaconArr.push(data); const inputArr = ibeaconArr && ibeaconArr.map((v, i) => { return {...v, timestamp: new Date().getTime() + i * 2000}; }); const polygonLocation = this.polygonV2(inputArr); ibeaconArr.shift(); return polygonLocation; } } /** * @author j_bleach * @date 2018-08-23 * @Description: 更新质心点算法 polygonV2 * @param points:Array */ polygonV2(points) { let m = 0, x = 0, y = 0; for (let i = 0; i < points.length; i++) { m += points[i].timestamp; x += (points[i].lon * points[i].timestamp); y += (points[i].lat * points[i].timestamp); } return {polygonLon: x / m, polygonLat: y / m}; } }; }; export default blueToothFn;