Javaweb获取用户附近商家

开始

项目上需要在用户端展示周围的商家,比如用户周围5km内的商家,思路是先获取用户的经纬度,然后与商家的经纬度计算出距离是否符合。

环境框架

后端使用关系型数据库,前端使用js、jq。

步骤

1. 获取用户经纬度。

因为是手机端网页,且小程序初始代码中就写好了方法,因此这里给出微信公众号网页和支付宝内网页获取用户地理位置的方式:

// 微信公众号获取用户地理位置
wx.getLocation({
  type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
  success: function (res) {
    var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
    var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
    var speed = res.speed; // 速度,以米/每秒计
    var accuracy = res.accuracy; // 位置精度
  }
});
//通过支付宝提供的接口获取用户地理位置
alipay.mobile.public.gis.get
2. 换算最大/最小经纬度。

将用户距离范围圈子转化成最大/最小经纬度。如下图。事实上,这里用户的范围其实是正方形,范围要比预想中的大一些。
在这里插入图片描述

 * 但是这种方式,需要将距离转化成经纬度数,因为地面其实是个弧度,所以这里要通过求反正弦得到距离相应度数。
 可以参考以下代码。

//userlat 用户所在纬度
//userlng 用户所在经度
//distince 用户范围半径
function getLatAndLngScope(userlat,userlng,distince){
        var r = 6371.393;    // 地球半径(km)
        var lng = userlng;
        var lat = userlat;
        var dlng = 2 * Math.asin(Math.sin(distince / (2 * r)) / Math.cos(lat * Math.PI / 180));
        dlng = dlng * 180 / Math.PI;
        var dlat = distince / r;
        dlat = dlat * 180 / Math.PI;
        return {
        	minlat:lat - dlat,
        	maxlat:lat + dlat,
        	minlng:lng - dlng,
        	maxlng:lng + dlng
        };
  }
3.检索符合条件商家。

商家注册时会要求填写经纬度并且保存,这时通过条件对比,即可筛选出合适的商家们。

sql语句:
 
*** where lat >= minlat
and lat <= maxlat
and lng >= minlng
and lng <= maxlng

 * 如果想要更好的准确度,在拉取这些商家后,通过循环迭代,使用商家和用户的经纬度,算出他们之间的距离,将距离大于预设的这部分商家剔除。可以参考以下代码。

// 根据经纬度计算距离,参数分别为第一点的纬度,经度;第二点的纬度,经度
        function getDistanceByLatAndLng(lat1, lng1, lat2, lng2) {
            var radLat1 = rad(lat1);
            var radLat2 = rad(lat2);
            var a = radLat1 - radLat2;
            var b = rad(lng1) - rad(lng2);
            var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
            s = s * 6378.137;
            s = Math.round(s * 10000) / 10000;
            var distance = s;
            var distance_str = "";
            if (parseInt(distance) >= 1) {
                distance_str = distance.toFixed(1) + "km";
            } else {
                distance_str = distance * 1000 + "m";
            }
            return s;
        }
        //此代码参考于 https://www.cnblogs.com/feiquan/p/11338691.html

示例

以微信公众号页面做个demo

var wantDistance = 5;//用户范围5km内
wx.ready(function(){
		wx.getLocation({
	  	type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
  		success: function (res) {
    		var userlat= res.latitude; // 纬度,浮点数,范围为90 ~ -90
    		var userlng= res.longitude; // 经度,浮点数,范围为180 ~ -180。
    		var scope = getLatAndLngScope(userlat,userlng,wantDistance);
    		$.ajax({ //以下简写
				url: '**/getStoresByScope', //访问后台换取方形范围内商家
				data: scope,
				success:function(e){
					var storelist = e.storelist;
					for(var n in storelist ){
					//若是精度要求较高(其实没必要),可以进一步筛选出圆形范围内的商家。如下:
						var store = storelist[n];
						var realDistance = getDistanceByLatAndLng(store.lat,store.lng,userlat,userlng);
						if(realDistance>wantDistance ){
							continue;
						}
						showstore(store);//展示商家,此处跳出结束。
					}
				}				
			});
  		}
	});
});
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值