根据经纬度获取附近的数据、和与当前经纬度的距离

根据经纬度获取附近的数据、和与当前经纬度的距离

环境:java+mysql

一:添加TestUsers表

CREATE TABLE `TestUsers` (
  `userId` INT(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
  `lat` DOUBLE DEFAULT NULL COMMENT '纬度',
  `lon` DOUBLE DEFAULT NULL COMMENT '经度',
  PRIMARY KEY (`userId`)
) ENGINE=INNODB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8 COMMENT='用户测试表'
二:创建存储过程(mysql)

#根据经纬度查询附近的数据(:存储过程)
#传入参数:
#double mylon, 当前所在经度
#double mylat, 当前所在纬度
#int beginId, 取值开始 
#int counts  获取条数 
#dist 查询范围 1km 5km 10km....... 
DROP PROCEDURE IF EXISTS pro_test_GetNearData;
DELIMITER //
CREATE PROCEDURE pro_test_GetNearData(IN mylon DOUBLE,IN mylat DOUBLE,IN beginId INT,IN counts INT,IN dist DOUBLE)  
BEGIN  
DECLARE lon1 FLOAT;  
DECLARE lon2 FLOAT; 
DECLARE lat1 FLOAT; 
DECLARE lat2 FLOAT; 
-- calculate lon and lat for the rectangle:
SET lon1 = mylon-dist/ABS(COS(RADIANS(mylat))*69);  
SET lon2 = mylon+dist/ABS(COS(RADIANS(mylat))*69); 
SET lat1 = mylat-(dist/69);   
SET lat2 = mylat+(dist/69); 
-- run the query:
SELECT  dest.userId,ROUND(  
3956 * 2 * ASIN(SQRT(POWER(SIN((mylat - dest.lat) * PI()/180 / 2), 2) +  
COS(mylat * PI()/180) *  COS(dest.lat * PI()/180) * POWER(SIN((mylon -dest.lon) * PI()/180 / 2), 2))),3) 
AS distance -- 两点间距离km 四舍五入,小数点后保留三位
FROM  TestUsers dest
WHERE  dest.lon BETWEEN lon1 AND lon2  
AND  dest.lat BETWEEN lat1 AND lat2 
HAVING distance < dist ORDER BY dest.userId LIMIT beginId,counts;  
END; 
//
DELIMITER ;
SHOW WARNINGS;   
#--------------------------------------------------------------------------------
SHOW CREATE PROCEDURE pro_test_GetNearData;      
CALL pro_test_GetNearData(22.591047,113.895543,0,5,1);   


三:Dao调用执行存储过程方法

// 执行存储过程
	@Override
	public List<Map<String, Object>> execProcQuery(final String procName,
			final Object[] params, final String[] resultParams) {
		return (List<Map<String, Object>>) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						CallableStatement cstmt = session.connection()
								.prepareCall(procName);
						List<Map<String, Object>> resultMapList = null;
						Map<String, Object> resultMap = null;
						if (params != null) {
							for (int i = 0; i < params.length; i++) {
								cstmt.setObject(i + 1, params[i]);
							}
						}
						ResultSet rs = cstmt.executeQuery();
						while (rs.next()) {
							if (resultMapList == null) {
								resultMapList = new ArrayList<Map<String, Object>>();
							}
							resultMap = new HashMap<String, Object>();
							for (int i = 0; i < resultParams.length; i++) {
								resultMap.put(resultParams[i],
										rs.getString(resultParams[i]));
							}
							resultMapList.add(resultMap);
						}
						return resultMapList;
					}
				});
	}


四:service调用存储过程


	@Override
	public List<Map<String, Object>> getNearData(Double longitude,
			Double latitude, Integer beginId, Integer count,Double dist) {
		List<Map<String, Object>> resultMapList=null; 
		try {
			//调用查询附近数据存储过程 
			resultMapList= testDao.execProcQuery("{CALL pro_test_GetNearData(?,?,?,?,?)}",//要调用的存储过程
					new Object[] { longitude, latitude, beginId, count, dist }, //参数列表
					new String[] {"userId","distance"});// 要获取的值 key
		} catch (Exception e) {
			e.printStackTrace(); 
		}
		return resultMapList;
	}
	


五:resultMapList结果

[{distance=0.026,  userId=101}, {distance=0.052,  userId=102}, {distance=0.112,  userId=103}, {distance=0.016,  userId=104}]



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值