// pages/advoad-city-search/advoad-message/electronic-fence/electronic-fence.js const app = getApp() const { queryLocation, areaMonitoringexport, queryFirstLineDestinations } = require('../../../../utils/ajax') const amapFile = require('../../../../utils/amap-wx') // 保留百度地图相关代码作为备用 const QQMapWX = require('../../../../utils/qqmap-wx-jssdk') let qqmapsdk; const ADVOAD_START_LOCATION_STORAGE_KEY = 'advoadStartSelectedLocation' const ADVOAD_END_LOCATION_STORAGE_KEY = 'advoadEndSelectedLocation' Page({ /** * 页面的初始数据 */ data: { options: {}, //数据展示, mapLocation: [], //地图电子围栏 longitude: "", latitude: "", abovadStartId: "", where: "", isCitys: false, addressList: [], userId: "", startSiteId: "", endSiteId: "", startLocation: "加载中", district: "", type:0, source: "", stationWhere: "", locatingCurrent: false, hasTriedAutoLocate: false, fenceList: [] }, /** * 生命周期函数--监听页面加载 */ onLoad: async function (options) { console.log('qweqweqwe',options); if (options) { let where = options.where this.setData({ where, type:options.type, source: options.source || "", stationWhere: options.stationWhere || "" }) if (where == 'startLocation') { wx.setNavigationBarTitle({ title: "设置上车点" }) this.setData({ options, abovadStartId: options.abovadStartId, startLocation1: options.abvoadStartLocation, userId: options.abovadStartId, startSiteId: options.abovadStartId || "", endSiteId: options.abovadEndId || "" }) let response = await this.handleDistrict() console.log('/**/*/**/*',response); const fenceList = this.getFenceListFromResponse(response) console.log('+-89587877',fenceList); if(fenceList.length > 0){ this.setData({ district: fenceList[0].district, startLocation: fenceList[0].city },()=>{ console.log('+++++',this.data); }) } let location = wx.getStorageSync('longitude') + ',' + wx.getStorageSync('latitude') //获取起点电子围栏 this.getNearLocation(options.abvoadStartLocation,location,true) if(this.data.district){ this.getNearLocation(this.data.district, location, true) } } else { wx.setNavigationBarTitle({ title: "设置下车点" }) this.setData({ options, startLocation1: options.abvoadEndLocation, abovadStartId: options.abovadEndId, userId: options.abovadEndId, startSiteId: options.abovadStartId || "", endSiteId: options.abovadEndId || "" }) let response = await this.handleDistrict() console.log('/**/*/**/*',response); const fenceList = this.getFenceListFromResponse(response) console.log('+-89587877',fenceList); if(fenceList.length > 0){ this.setData({ district: fenceList[0].district, startLocation: fenceList[0].city },()=>{ console.log('+++++',this.data); }) } const userLongitude = wx.getStorageSync('longitude') const userLatitude = wx.getStorageSync('latitude') let location = userLongitude + ',' + userLatitude const normalizedFenceList = fenceList.map((item) => this.normalizeFenceItem(item)) const currentInFence = userLongitude && userLatitude ? normalizedFenceList.some((item) => { const parsedFence = this.parseFenceCoordinate(item) if(!parsedFence){ return false } if(parsedFence.mode == 'circle'){ const distance = this.getDistanceMeters( Number(userLatitude), Number(userLongitude), parsedFence.centerLatitude, parsedFence.centerLongitude ) return distance <= Number(parsedFence.radius || 0) } return parsedFence.points && parsedFence.points.length >= 3 ? this.isPointInPolygon(Number(userLatitude), Number(userLongitude), parsedFence.points) : false }) : false if(!currentInFence){ location = this.getMainFenceLocation(normalizedFenceList) || location } //获取起点电子围栏 this.getNearLocation(options.abvoadEndLocation,location,true) if(this.data.district){ this.getNearLocation(this.data.district, location, true) } } } //设置当前位置经纬度 }, createMarker(latitude, longitude){ return [{ id: 1, latitude, longitude, iconPath: "/img/icon_location.png", width: 26, height: 35 }] }, getAmapInstance(){ return new amapFile.AMapWX({ key: 'cea7923a93987b959ab1d2f8ab44d497' }) }, reverseGeocode(latitude, longitude) { const myAmapFun = this.getAmapInstance() return new Promise((resolve, reject) => { myAmapFun.getRegeo({ location: `${longitude},${latitude}`, success: (res) => { const regeocodeData = res[0].regeocodeData resolve({ addressComponent: regeocodeData.addressComponent, formattedAddress: regeocodeData.formatted_address }) }, fail: reject }) }) }, toRadians(deg){ return deg * Math.PI / 180 }, getDistanceMeters(lat1, lon1, lat2, lon2){ const earthRadius = 6378137 const dLat = this.toRadians(lat2 - lat1) const dLon = this.toRadians(lon2 - lon1) const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.toRadians(lat1)) * Math.cos(this.toRadians(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2) const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) return earthRadius * c }, isPointInPolygon(latitude, longitude, points){ let inside = false for (let i = 0, j = points.length - 1; i < points.length; j = i++) { const xi = Number(points[i].longitude) const yi = Number(points[i].latitude) const xj = Number(points[j].longitude) const yj = Number(points[j].latitude) const intersect = ((yi > latitude) !== (yj > latitude)) && (longitude < (xj - xi) * (latitude - yi) / ((yj - yi) || 0.0000001) + xi) if (intersect) { inside = !inside } } return inside }, isCurrentLocationInFence(latitude, longitude){ const circles = this.data.circles || [] const polygons = this.data.polygons || [] const inCircle = circles.some((circle) => { const distance = this.getDistanceMeters( latitude, longitude, Number(circle.latitude), Number(circle.longitude) ) return distance <= Number(circle.radius || 0) }) if(inCircle){ return true } return polygons.some((polygon) => { return polygon.points && polygon.points.length >= 3 ? this.isPointInPolygon(latitude, longitude, polygon.points) : false }) }, getLocationStorageKey(where){ return where == 'startLocation' ? ADVOAD_START_LOCATION_STORAGE_KEY : ADVOAD_END_LOCATION_STORAGE_KEY }, saveSelectedLocation(where, siteId, siteName, locationName, locationInfo, extraData = {}){ wx.setStorageSync(this.getLocationStorageKey(where), { siteId, siteName, locationName, locationInfo, ...extraData }) }, getDefaultText(currentText, defaultText){ if(currentText && currentText.indexOf('选择') !== -1 && currentText.indexOf('请') === -1){ return defaultText.replace('请', '') } return defaultText }, getNearLocationKeyword(defaultKeyword){ const options = this.data.options || {} if(this.data.where == 'endLocation'){ return options.abvoadEndLocation || this.data.startLocation1 || defaultKeyword } if(this.data.where == 'startLocation'){ return options.abvoadStartLocation || this.data.startLocation1 || defaultKeyword } return defaultKeyword }, getFenceListFromResponse(response){ const data = response && response.data && response.data.data if(Array.isArray(data)){ return data } if(data && typeof data === 'object'){ if(Array.isArray(data.records)){ return data.records } if(Array.isArray(data.list)){ return data.list } return [data] } if(data && Array.isArray(data.records)){ return data.records } if(data && Array.isArray(data.list)){ return data.list } return [] }, normalizeFenceItem(item){ const fenceInfo = item.fenceInfo || {} const coordinate = item.coordinate || fenceInfo.coordinate || '' const coordinateList = coordinate.split(';').filter(i => i) const firstPoint = coordinateList[0] ? coordinateList[0].split(',') : [] const isCircleByCoordinate = coordinateList.length == 2 && firstPoint.length == 2 && !Number.isNaN(Number(firstPoint[0])) && !Number.isNaN(Number(firstPoint[1])) && !Number.isNaN(Number(coordinateList[1])) const derivedFenceType = isCircleByCoordinate ? 1 : (coordinateList.length >= 3 ? 2 : Number(item.fenceType || fenceInfo.fenceType || item.type || 0)) const derivedDefaultPointLon = Number(item.defaultPointLon || fenceInfo.defaultPointLon || (firstPoint[0] || 0)) const derivedDefaultPointLat = Number(item.defaultPointLat || fenceInfo.defaultPointLat || (firstPoint[1] || 0)) return { ...item, coordinate, fenceType: derivedFenceType, defaultPointLat: derivedDefaultPointLat, defaultPointLon: derivedDefaultPointLon, district: item.district || fenceInfo.district || '', city: item.city || fenceInfo.city || '', name: item.name || fenceInfo.name || '' } }, parseFenceCoordinate(fenceItem){ const coordinate = fenceItem.coordinate || '' const coordinateList = coordinate.split(';').filter(i => i) const firstPoint = coordinateList[0] ? coordinateList[0].split(',') : [] const isCircleByCoordinate = coordinateList.length == 2 && firstPoint.length == 2 && !Number.isNaN(Number(firstPoint[0])) && !Number.isNaN(Number(firstPoint[1])) && !Number.isNaN(Number(coordinateList[1])) if((fenceItem.fenceType == 1 || isCircleByCoordinate) && coordinateList.length >= 2){ return { mode: 'circle', centerLongitude: Number(firstPoint[0]), centerLatitude: Number(firstPoint[1]), radius: Number(Number(coordinateList[1]).toFixed(5)) } } if(coordinateList.length >= 3){ return { mode: 'polygon', points: coordinateList.map((item) => { return { longitude: Number(item.split(',')[0]), latitude: Number(item.split(',')[1]) } }) } } return null }, getMatchedFenceItemByLocation(latitude, longitude){ const fenceList = this.data.fenceList || [] for(let i = 0; i < fenceList.length; i++){ const fenceItem = fenceList[i] const parsedFence = this.parseFenceCoordinate(fenceItem) if(!parsedFence){ continue } if(parsedFence.mode == 'circle'){ const distance = this.getDistanceMeters( latitude, longitude, parsedFence.centerLatitude, parsedFence.centerLongitude ) if(distance <= Number(parsedFence.radius || 0)){ return fenceItem } }else if(parsedFence.mode == 'polygon'){ if(this.isPointInPolygon(latitude, longitude, parsedFence.points)){ return fenceItem } } } return null }, getMainFenceLocation(fenceList = []){ const mainFence = fenceList.find((item) => Number(item.isMain) == 1) || fenceList[0] if(!mainFence){ return '' } const parsedMainFence = this.parseFenceCoordinate(mainFence) const longitude = mainFence.defaultPointLon || (parsedMainFence && parsedMainFence.centerLongitude) || (parsedMainFence && parsedMainFence.points && parsedMainFence.points[0] && parsedMainFence.points[0].longitude) const latitude = mainFence.defaultPointLat || (parsedMainFence && parsedMainFence.centerLatitude) || (parsedMainFence && parsedMainFence.points && parsedMainFence.points[0] && parsedMainFence.points[0].latitude) if(!longitude || !latitude){ return '' } return `${longitude},${latitude}` }, async fetchFenceData(){ if(this.data.where == 'endLocation'){ const startId = this.data.startSiteId const endId = this.data.endSiteId || this.data.userId if(!startId || !endId){ return { data: { code: 200, data: [] } } } // 原来根据终点站点ID获取围栏的方法先保留注释,改为按起终站点查询新的围栏 // return queryLocation(endId) return queryFirstLineDestinations(startId, endId) } return queryLocation(this.data.userId) }, handleStationSelectResult(self, startInfo, extraUpdates = {}){ let pages = getCurrentPages(); let targetPage = pages[pages.length - 3]; if(!targetPage){ app.showToastSuccess('页面信息获取失败',null,'none',1500) return } const isStartStation = this.data.stationWhere == 'statrLocation' const siteId = this.data.userId const siteName = this.data.startLocation1 || self.name this.saveSelectedLocation(this.data.where, siteId, siteName, self.name, startInfo, extraUpdates) if(targetPage.route == 'pages/home/home'){ const homeUpdates = isStartStation ? { abovadStartId: siteId, abvoadStartLocation: self.name, abovadEndId: null, abvoadEndLocation: '请选择终点' } : { abovadEndId: siteId, abvoadEndLocation: self.name } targetPage.setData(homeUpdates,()=>{ wx.navigateBack({ delta:2 }) }) return } const updates = isStartStation ? { abovadStartId: siteId, abvoadStartLocation: siteName, abvoadEndLocation: this.getDefaultText(targetPage.data.abvoadEndLocation, '请选择终点'), abovadEndId: null, startLocation: self.name, startInfo, endLocation: this.getDefaultText(targetPage.data.endLocation, '请选择下车点'), endInfo: {}, lineDestinationId: '' } : { abovadEndId: siteId, abvoadEndLocation: siteName, endLocation: self.name, endInfo: startInfo, lineDestinationId: extraUpdates.lineDestinationId || '' } targetPage.setData(updates,()=>{ wx.navigateBack({ delta:2 }) }) }, async confirmSelectedLocation(self, silentInvalid){ let { abovadStartId, where } = this.data let pages = getCurrentPages(); let prevPage = pages[pages.length - 2]; const locationArr = (self.location || '').split(',') const currentLongitude = Number(locationArr[0]) const currentLatitude = Number(locationArr[1]) const hasFence = (this.data.circles && this.data.circles.length > 0) || (this.data.polygons && this.data.polygons.length > 0) if( hasFence && Number.isFinite(currentLatitude) && Number.isFinite(currentLongitude) && !this.isCurrentLocationInFence(currentLatitude, currentLongitude) ){ if(!silentInvalid){ app.showToastSuccess('该位置不在围栏范围内,请重新选择',null,'none',1500) } return false } if(where == 'endLocation'){ const firstLineValid = await this.queryEndLocationLineDestinations(silentInvalid) if(!firstLineValid){ return false } } let res = await areaMonitoringexport(self.adcode, self.location,abovadStartId) let data = res.data let startInfo = { startLat : self.location.split(',')[1], startLon : self.location.split(',')[0] } const matchedFenceItem = where == 'endLocation' ? this.getMatchedFenceItemByLocation(currentLatitude, currentLongitude) : null const lineDestinationId = matchedFenceItem ? (matchedFenceItem.id || matchedFenceItem.lineDestinationId || '') : '' const extraUpdates = where == 'endLocation' ? { lineDestinationId } : {} if(data.code==200){ if(data.data==1){ if(this.data.source == 'stationSelect'){ this.handleStationSelectResult(self, startInfo, extraUpdates) return true } this.saveSelectedLocation( where, abovadStartId, this.data.startLocation1 || self.name, self.name, startInfo, extraUpdates ) if(where == "startLocation"){ prevPage.setData({ startLocation:self.name, startInfo:startInfo, lineDestinationId: '' },()=>{ if(this.data.type!=1){ prevPage.queryOrderMoney() } wx.navigateBack({ delta:1 }) }) }else{ prevPage.setData({ endLocation:self.name, endInfo:startInfo, lineDestinationId },()=>{ if(this.data.type!=1){ prevPage.queryOrderMoney() } wx.navigateBack({ delta:1 }) }) } return true } if(!silentInvalid){ app.showToastSuccess('该位置不在有效范围内,请重新选择',null,'none',1500) } return false } app.showToastSuccess(data.msg,null,'none',1500) return false }, async queryEndLocationLineDestinations(silentInvalid){ const startId = this.data.startSiteId const endId = this.data.endSiteId || this.data.userId if(!startId || !endId){ return true } try{ const res = await queryFirstLineDestinations(startId, endId) const data = res.data || {} if(data.code == 200){ return true } if(!silentInvalid){ app.showToastSuccess(data.msg || '终点线路信息获取失败',null,'none',1500) } return false }catch(error){ if(!silentInvalid){ app.showToastSuccess('终点线路信息获取失败',null,'none',1500) } return false } }, async getCurrentLocationInfo(updateMap){ if(this.data.locatingCurrent){ return null } this.setData({ locatingCurrent: true }) try{ const locationRes = await new Promise((resolve, reject) => { wx.getLocation({ type: 'gcj02', success: resolve, fail: reject }) }) const latitude = locationRes.latitude const longitude = locationRes.longitude const regeoRes = await this.reverseGeocode(latitude, longitude) const adcode = regeoRes.addressComponent.adcode || wx.getStorageSync('adcode') const formattedAddress = regeoRes.formattedAddress || '当前位置' const location = `${longitude},${latitude}` if(updateMap){ const nearLocationKeyword = formattedAddress || regeoRes.addressComponent.district || regeoRes.addressComponent.city || this.getNearLocationKeyword(formattedAddress) this.setData({ longitude, latitude, startLocation: regeoRes.addressComponent.city || regeoRes.addressComponent.district || this.data.startLocation, markers: this.createMarker(latitude, longitude) }) this.getNearLocation(nearLocationKeyword, location, false) } return { name: formattedAddress, location, adcode, latitude, longitude } }catch(error){ return null }finally{ this.setData({ locatingCurrent: false }) } }, async tryAutoLocateCurrentPosition(){ if(this.data.where != 'startLocation'){ return } if(this.data.hasTriedAutoLocate){ return } this.setData({ hasTriedAutoLocate: true }) const currentLocation = await this.getCurrentLocationInfo(true) if(!currentLocation){ app.showToastSuccess('定位失败,请手动选择上车位置',null,'none',1500) return } }, handleLocationButtonTap(){ this.getCurrentLocationInfo(true).then((currentLocation) => { if(!currentLocation){ app.showToastSuccess('定位失败,请手动选择上车位置',null,'none',1500) } }) }, //cancelAddress cancelAddress() { wx.navigateBack({ delta: 1 }) }, //获取 poi getNearLocation(inputValue, location, bloone) { console.log('///////////',location); // let myAmapFun = new amapFile.AMapWX({ key: '22f054fcf175ade2af008875bdd68242' }); var myAmapFun = new amapFile.AMapWX({ key: 'cea7923a93987b959ab1d2f8ab44d497' }); myAmapFun.getInputtips({ keywords: inputValue, location: location, success: (res) => { let arr = res.tips.filter(item=>{ return item.location.length>0 }) this.setData({ addressList: arr, }, () => { if (bloone || '') { this.init() } }) } }) }, // 用户滑动地图获取中心位置 regionchange(e){ // 地图发生变化的时候,获取中间点 if (e.type == 'end' && (e.causedBy == 'scale' || e.causedBy == 'drag')) { this.mapCtx = wx.createMapContext("mapSelsect"); //获取中心坐标 api this.mapCtx.getCenterLocation({ type: 'gcj02', success: (res) => { this.setData({ isCitys:false, latitude:res.latitude, longitude:res.longitude, markers: this.createMarker(res.latitude, res.longitude), }) this.getLocal (res.latitude,res.longitude) } }) } }, //获取Value getLocal(latitude, longitude) { this.reverseGeocode(latitude, longitude).then((res) => { const addressComponent = res.addressComponent; const formattedAddress = res.formattedAddress; this.setData({ startLocation: addressComponent.city || addressComponent.district }) let location = longitude + ',' + latitude const nearLocationKeyword = formattedAddress || addressComponent.district || addressComponent.city || this.getNearLocationKeyword(formattedAddress) this.getNearLocation(nearLocationKeyword, location, false) }).catch(() => { app.showToastSuccess('数据获取失败222222222222', null, 'none', 1500) }) }, //点击从哪里上车 handelClickFrom() { wx.navigateTo({ url: '/pages/getLocation/getLocation?where=' + 'advoad' + '&cityName=' + this.data.startLocation + '&advoadLocation=' + this.data.where + '&abovadStartId=' + this.data.abovadStartId + "&circles=" + JSON.stringify(this.data.circles) + '&polygons=' + JSON.stringify(this.data.polygons), }) }, //点击poi 跳转到 确定页面 async handelClickLocationItem(e) { let self = e.currentTarget.dataset.self await this.confirmSelectedLocation(self) }, handleDistrict() { return this.fetchFenceData(); }, //异步操作 async init() { try { let res1 = await this.fetchFenceData() let data = res1.data let _circles = [] let _polygons = [] const fenceList = this.getFenceListFromResponse(res1).map((item) => this.normalizeFenceItem(item)) if(fenceList.length > 0){ this.setData({ fenceList, district: fenceList[0].district || this.data.district, startLocation: fenceList[0].city || this.data.startLocation }) }else{ this.setData({ fenceList: [] }) } if (data.code == 200) { const mainFence = fenceList.find((item) => Number(item.isMain) == 1) || fenceList[0] if (mainFence) { const parsedMainFence = this.parseFenceCoordinate(mainFence) const longitude = mainFence.defaultPointLon || (parsedMainFence && parsedMainFence.centerLongitude) || (parsedMainFence && parsedMainFence.points && parsedMainFence.points[0] && parsedMainFence.points[0].longitude) const latitude = mainFence.defaultPointLat || (parsedMainFence && parsedMainFence.centerLatitude) || (parsedMainFence && parsedMainFence.points && parsedMainFence.points[0] && parsedMainFence.points[0].latitude) if(longitude && latitude){ this.setData({ markers: this.createMarker(latitude, longitude), longitude, latitude }, () => { this.getLocal(latitude, longitude) }) } } else { if(this.data.addressList[0] && this.data.addressList[0].location.length){ this.setData({ longitude: this.data.addressList[0].location.split(',')[0], latitude: this.data.addressList[0].location.split(',')[1], startLocation: this.data.startLocation1 }) }else if(this.data.addressList[1] && this.data.addressList[1].location.length){ this.setData({ longitude: this.data.addressList[1].location.split(',')[0], latitude: this.data.addressList[1].location.split(',')[1], startLocation: this.data.startLocation1 }) } } fenceList.forEach((x) => { const parsedFence = this.parseFenceCoordinate(x) if (!parsedFence) { return } if (parsedFence.mode == 'circle') { _circles.push({ latitude: parsedFence.centerLatitude, longitude: parsedFence.centerLongitude, color: '#7cb5ec88', fillColor: '#7cb5ec88', radius: parsedFence.radius, strokeWidth: 1 }) } else if (parsedFence.mode == 'polygon') { _polygons.push({ points: parsedFence.points, fillColor: "#7cb5ec88", strokeColor: "#7cb5ec88", strokeWidth: 1, zIndex: 1 }) } }) this.setData({ circles: _circles, polygons: _polygons },()=>{ if(this.data.where == 'startLocation'){ this.tryAutoLocateCurrentPosition() } }) } else { app.showToastSuccess(data.msg, null, 'none', 1500) } } catch (error) { } }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } })