SpringBoot入门教程(五)Java基于MySQL实现附近的人
“附近的人”这个功能估计都不陌生,与之类似的功能最开始是在各大地图应用上接触过,比如搜附近的电影院,附近的超市等等。然而真正让附近的人火遍大江南北的应该是微信"附近的人"这个功能,记得微信刚出的时候,坊间还有一句"寂寞女聊玩微信,寂寞男人搜附近"的说法。
v准备工作
创建测试数据库
CREATE TABLE `userposition` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`city` varchar(20) NOT NULL,
`position` varchar(128) NOT NULL,
`longitude` decimal(18,15) NOT NULL,
`latitude` decimal(18,15) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into `userposition` values(1,'北京市','回龙观新村中区', 116.310771,40.06263);
insert into `userposition` values(2,'北京市','金域华府', 116.310127,40.064379);
insert into `userposition` values(3,'北京市','融泽嘉园中区', 116.311962,40.064822);
insert into `userposition` values(4,'北京市','回龙观新村东区', 116.312541,40.063246);
insert into `userposition` values(5,'北京市','上地东里', 116.314168,40.033075);
v附近的人
原理
先算出某个坐标位置周围的矩形的四个点,然后使用经纬度去直接匹配数据库中的记录。
思路
首先算出“给定坐标附近1000米”这个范围的坐标范围。 虽然它是个圆,但我们可以先求出该圆的外接正方形,然后拿正方形的经纬度范围去搜索数据库。圆形内为要求的搜索范围,方形内为我们能间接得到的结果范围。

先来求东西两侧的的范围边界。在haversin公式中令φ1 = φ2,可得

Java实现
/**
* 查找附近的人
* @param radii 半径距离(单位km)
* @param lon 经度
* @param lat 纬度
* @return
*/
@GetMapping("/nearby")
public List<UserPosition> getVicinity(double radii, double lon, double lat){
double r = 6371;//地球半径千米
double dis = radii;
double dlng = 2*Math.asin(Math.sin(dis/(2*r))/Math.cos(lat*Math.PI/180));
dlng = dlng*180/Math.PI;//角度转为弧度
double dlat = dis/r;
dlat = dlat*180/Math.PI;
double minlat =lat-dlat;
double maxlat = lat+dlat;
double minlng = lon -dlng;
double maxlng = lon + dlng; return userService.getVicinity(BigDecimal.valueOf(minlng), BigDecimal.valueOf(maxlng), BigDecimal.valueOf(minlat), BigDecimal.valueOf(maxlat));
}
mybatis
<select id="getvicinity" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from userposition
where longitude >= #{minlng} and longitude <= #{maxlng} and latitude >= #{minlat} and latitude <= #{maxlat}
</select>
List<UserPosition> getvicinity(@Param("minlng") BigDecimal minlng,
@Param("maxlng") BigDecimal maxlng,
@Param("minlat") BigDecimal minlat,
@Param("maxlat") BigDecimal maxlat);
测试效果
在地图中找到回龙新村的经纬度,然后测试。


v按距离远近排序
Java代码
/**
* 附近的人排序
* @param lon 经度
* @param lat 纬度
* @return
*/
@GetMapping("/nearbysort")
public List<UserPosition> getVicinitySort(double lon, double lat){ return userService.getvicinitysort(BigDecimal.valueOf(lon), BigDecimal.valueOf(lat));
}
mybatis代码
<select id="getvicinitysort" resultMap="BaseResultMap">
SELECT id, city, position, longitude,latitude,
(POWER(MOD(ABS(longitude - #{longitude}),360),2) + POWER(ABS(latitude - #{latitude}),2)) AS distance
FROM `userposition`
ORDER BY distance LIMIT 20
</select>
List<UserPosition> getvicinitysort(@Param("longitude") BigDecimal longitude,
@Param("latitude") BigDecimal latitude);
测试效果

补充,如果需要按距离排序,并返回距离的字段。可以按如下方式实现。
SELECT
*,
ROUND(
6378.138 * 2 * ASIN(
SQRT(
POW(
SIN(
(
$latitude * PI() / 180 - latitude * PI() / 180
) / 2
),
2
) + COS($latitude * PI() / 180) * COS(latitude * PI() / 180) * POW(
SIN(
(
$longitude * PI() / 180 - longitude * PI() / 180
) / 2
),
2
)
)
) * 1000
) AS distance
FROM
userposition
ORDER BY
distance ASC
v博客总结
如果数据量大的话,还可以考虑基于Redis实现附近的人。Redis GEO地理位置信息,查看附近的人
v源码地址
https://github.com/toutouge/javademosecond/tree/master/hellospringboot
其他参考资料:
- 根据一个给定经纬度的点,进行附近500米地点查询–合理利用算法__算法 https://yq.aliyun.com/ziliao/230566
- mysql 下 计算 两点 经纬度 之间的距离 https://www.cnblogs.com/sandea/p/4673297.html
- MYSQL创建一个function用来计算经纬度距离 http://xigua366.iteye.com/blog/2242818
作 者:请叫我头头哥
出 处:http://www.cnblogs.com/toutou/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
SpringBoot入门教程(五)Java基于MySQL实现附近的人的更多相关文章
- SpringBoot入门(五)——自定义配置
本文来自网易云社区 大部分比萨店也提供某种形式的自动配置.你可以点荤比萨.素比萨.香辣意大利比萨,或者是自动配置比萨中的极品--至尊比萨.在下单时,你并没有指定具体的辅料,你所点的比萨种类决定了所用的 ...
- SpringBoot入门教程(二)CentOS部署SpringBoot项目从0到1
在之前的博文<详解intellij idea搭建SpringBoot>介绍了idea搭建SpringBoot的详细过程, 并在<CentOS安装Tomcat>中介绍了Tomca ...
- PySide——Python图形化界面入门教程(五)
PySide——Python图形化界面入门教程(五) ——QListWidget 翻译自:http://pythoncentral.io/pyside-pyqt-tutorial-the-qlistw ...
- Elasticsearch入门教程(五):Elasticsearch查询(一)
原文:Elasticsearch入门教程(五):Elasticsearch查询(一) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...
- 无废话ExtJs 入门教程五[文本框:TextField]
无废话ExtJs 入门教程五[文本框:TextField] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个文本框.如下所示代码区的第42行位置,items: ...
- 【Zigbee技术入门教程-号外】基于Z-Stack协议栈的抢答系统
[Zigbee技术入门教程-号外]基于Z-Stack协议栈的抢答系统 广东职业技术学院 欧浩源 一.引言 2017年全国职业院校技能大赛"物联网技术应用"赛项中任务三题2的 ...
- Java进阶(二十五)Java连接mysql数据库(底层实现)
Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜 ...
- SpringBoot进阶教程(五十九)整合Codis
上一篇博文<详解Codis安装与部署>中,详细介绍了codis的安装与部署,这篇文章主要介绍介绍springboot整合codis.如果之前看过<SpringBoot进阶教程(五十二 ...
- RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)
原文:RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...
随机推荐
- python之socketserver实现并发
python之socketserver实现并发 服务端 import socketserver #socketserver模块是用来实现并发 # 我们自己的类里一定要继承socketserver.Ba ...
- vue解决加载闪烁问题
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>& ...
- opencv imwrite保存图片花屏的问题
问题:在项目中用opencv的imwrite保存图片出现花屏的问题,如下图: 思路:1. 因为项目中的图像数据(float类型,0-255)是在GPU中,保存的话:可以用CPU保存图片,也可以用GP ...
- vue-These relative modules were not found
今天在做vue2.0+webpack的项目的时候,本来一切正常,整理了一下文件夹分类,就是把一些基础的组件新建了一个文件夹移进去,然后就报了以下的错误,其他东西都没改 最后网上找了很多资料,有说配置文 ...
- CDN(Content Delivery Network)技术原理概要
简介 CDN(Content Delivery Network)即内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡.内容分发.调度等功能,使用户就近获取所需内容,提高用户访问响应速度和 ...
- 搭积木(java)-蓝桥杯
搭积木小明最近喜欢搭数字积木,一共有10块积木,每个积木上有一个数字,0~9.搭积木规则:每个积木放到其它两个积木的上面,并且一定比下面的两个积木数字小.最后搭成4层的金字塔形,必须用完所有的积木.下 ...
- 11、js 数组详细操作方法及解析合集
js 数组详细操作方法及解析合集 前言 在开发中,数组的使用场景非常多,平日中也涉及到很多数组的api/相关操作,一直也没有对这块内容进行一块整理总结,很多时候就算用过几次这个api,在开发中也很容易 ...
- HelloPython
HELLOWORD!你好!Python! 学习Python已有一段时间,一个人自学颇不容易,在此分享一些自己学习经验和感受,温故而知新,也希望自己能有些新收获. 学习Python,大多数人创建的第一个 ...
- 使用AOP实现方法执行时间和自定义注解
环境:IDEA2018+JDK1.8+SpringBoot 第一步:在pom文件中引入依赖(度娘有很多(*^▽^*)): <!--引入AOP的依赖--><dependency> ...
- 手机touch事件及参数【转】(自己懒得写了,找了一篇摘过来)
[html5构建触屏网站]之touch事件 前言 一个触屏网站到底和传统的pc端网站有什么区别呢,交互方式的改变首当其冲.例如我们常用的click事件,在触屏设备下是如此无力. 手机上的大部分交互都是 ...