景运管家智慧导览系统的地图定位采用多重方式,首选微信JS SDK的经纬度接口,另有浏览器原生接口、高德地图定位api等。
在某些特殊情况下(如一些偏远地区、建筑复杂地区、其他一些特殊地区)定位的精准度各有不同。
经测试发现,原生微信小程序的地理位置接口返回的经纬度最为精准。
如采用微信小程序或者原生APP的原生接口获取经纬度,用webview的方式加载景运管家导览系统,因为webview无法直接和H5通信,则可把获取的经纬度上传至服务器。
然后地图H5页面去服务器获取对应用户的经纬度。
下面具体介绍此方案。
开发方:自己开发小程序,用webview加载景运管家手绘地图的合作伙伴。
手绘地图:景运管家开发的智慧景区导览系统,H5页面。
1.
开发方在小程序webview页面获取用户经纬度,上传至开发方自己的服务器(每个用户生成唯一的用户标识,建议命名为getLocationUserIndex)。
接口示例:
https://开发方域名/map/index/saveUserLocation?lat=xxx&lng=xxx&getLocationUserIndex=ZV3wqhfewv83263
此接口后端参考逻辑:
//获取用户标识
getLocationUserIndex = request->getLocationUserIndex;
//获取用户的经纬度
location = [request->lnt, request->lat];
//保存用户的经纬度
memcache->set(getLocationUserIndex, location, 30);
2.
开发方在小程序webview页面内加载手绘地图(地图的URL由景运管家运营或者技术提供)时,增加如下2个参数:
getLocationFromServer,值为1
getLocationUserIndex,值为用户的唯一标识
如:
https://nwx.weijingtong.net/map?id=37&getLocationFromServer=1&getLocationUserIndex=ZV3wqhfewv83263
3.
手绘地图H5页面将调用开发方获取用户经纬度的接口(手绘地图通过轮询方式,大概每秒请求1次或2次),此由开发方提供,如:/map/index/getUserLocation。
手绘地图H5调用开发方接口的方式为jsonp,会传入2个参数:
callback //jsonp的返回执行方法
getLocationUserIndex //用户的标识ID
如:https://开发方域名/map/index/getUserLocation?callback=jQuery5262_1718&getLocationUserIndex=ZV3wqhfewv83263
开发方根据手绘地图传入的用户标识,查询到用户的经纬度返回,参数如下:
err_code:0正常
data:{
"longitude":经度,
"latitude": 维度
}
jsonp调用,返回信息注意要callback包裹返回值
示例:
jQuery5262_1718({"err_code":0,"err_msg":1,"data":{"longitude":10.635232,"latitude":130.285334,"accuracy":null}});
此接口参考逻辑:
//获取前端传入的回调方法名
callback = request->callback;
//获取用户标识
getLocationUserIndex = request->getLocationUserIndex;
//根据用户标识获取最新的经纬度
userLocation = memcache->get(getLocationUserIndex);
返回jsonp格式数据
return callback + "(" + {"err_code": 0, "data": {"longitude": userLocation[0], "latitude": userLocation[1]}}.toString() + ")";
开发方开发完成此接口后,提供给景运管家技术或者运营,配置到手绘地图后台。手绘地图即调用此接口获取用户经纬度。
另:
如果使用微信小程序,开发方需要在微信小程序后台开通相关的地理位置接口权限。http://mp.weijingtong.net/include/images/liteapp/tech-apply-api-getlocation.jpg
更多地图开放参数见接口文档。
下面是微信小程序获取经纬度及加载wevbiew手绘地图的示例代码:
//获取应用实例
var app = getApp();
Page({
data: {
page: {
title: '正在加载……',
desc: '正在加载……',
path: 'pages/webviewMap/webviewMap', //建议
},
clientId: '', //景运管家系统的clientId
signKey: '', //签名私钥,联系景运管家运营获取
wxappid: '', //小程序的appid
getLocationUserIndex: '',},
onLoad: function(option) {
var _this = this;
//此处生成每个用户唯一的ID,且缓存,以便每次进入页面都一样
_this.data.getLocationUserIndex = wx.getStorageSync('getLocationUserIndex');
if (!_this.data.getLocationUserIndex) {
//此处生成每个用户唯一的ID
_this.data.getLocationUserIndex = (wx.getStorageSync('userId') || '').substr(-5) + (Math.random() + '').substr(3);
wx.setStorageSync('getLocationUserIndex', _this.data.getLocationUserIndex);
}
console.log('option:', option);
wx.startLocationUpdate({
type: 'gcj02',
success: function () {
app.showMsg('开启监听位置变化的接口调用成功');
wx.onLocationChange(function (res) {
var data = res;
data['getLocationUserIndex'] = _this.data.getLocationUserIndex;
var date = new Date();
data['time'] = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
app.request({
url : 'https://开发方域名/map/index/saveUserLocation?lat=xxx&lng=xxx&getLocationUserIndex=ZV3wqhfewv83263', //这是服务器api接口,保存用户经纬度,由开发方提供。提示:另外还需要开发获取经纬度的接口,配置到手绘地图。
data : data,
method : 'POST',
});
});
},
fail: function (res) {
app.showMsg('开启监听位置变化的接口调用失败');
app.saveErrorLog(res);
},
complete: function (res) {
console.log('开启监听位置变化的接口调用complete');
}
});
var mapUrl = ''; //地图的URL
_this._setUrl(mapUrl);
},
onReady: function(option) {
var _this = this;
},
_setUrl: function (webviewUrl) {
webviewUrl = webviewUrl.split('#')[0];
console.log('webviewUrl4:', webviewUrl);
webviewUrl += webviewUrl.indexOf('?') > -1 ? '' : '?';
//可传入用户的openid(userId),则手绘地图系统不去授权获取用户openid
var time = parseInt(new Date().getTime() / 1000);var userId = wx.getStorageSync('userId');
webviewUrl += '&clientId=' + this.data.clientId + '&userId=' + userId;
webviewUrl += '&time=' + time + '&sign=' + (this.data.signKey + userId + time).md5();
webviewUrl += '&';
//传入小程序获取经纬度的用户标识
webviewUrl += 'wxappid=' + this.data.wxappid + '&';
webviewUrl += 'getLocationUserIndex=' + this.data.getLocationUserIndex + '&';
console.log('webviewUrl1:', webviewUrl);
this.setData({
webviewUrl: webviewUrl + '#wechat_redirect',
});
}
})