“附近的人”这个功能估计都不陌生,与之类似的功能最开始是在各大地图应用上接触过,比如搜附近的电影院,附近的超市等等。然而真正让附近的人火遍大江南北的应该是微信"附近的人"这个功能,记得微信刚出的时候,坊间还有一句"寂寞女聊玩微信,寂寞男人搜附近"的说法。

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 &gt;= #{minlng} and longitude &lt;= #{maxlng} and latitude &gt;= #{minlat} and latitude &lt;= #{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

其他参考资料:

作  者:请叫我头头哥

出  处:http://www.cnblogs.com/toutou/

关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!

版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信

声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

SpringBoot入门教程(五)Java基于MySQL实现附近的人的更多相关文章

  1. SpringBoot入门(五)——自定义配置

    本文来自网易云社区 大部分比萨店也提供某种形式的自动配置.你可以点荤比萨.素比萨.香辣意大利比萨,或者是自动配置比萨中的极品--至尊比萨.在下单时,你并没有指定具体的辅料,你所点的比萨种类决定了所用的 ...

  2. SpringBoot入门教程(二)CentOS部署SpringBoot项目从0到1

    在之前的博文<详解intellij idea搭建SpringBoot>介绍了idea搭建SpringBoot的详细过程, 并在<CentOS安装Tomcat>中介绍了Tomca ...

  3. PySide——Python图形化界面入门教程(五)

    PySide——Python图形化界面入门教程(五) ——QListWidget 翻译自:http://pythoncentral.io/pyside-pyqt-tutorial-the-qlistw ...

  4. Elasticsearch入门教程(五):Elasticsearch查询(一)

    原文:Elasticsearch入门教程(五):Elasticsearch查询(一) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...

  5. 无废话ExtJs 入门教程五[文本框:TextField]

    无废话ExtJs 入门教程五[文本框:TextField] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个文本框.如下所示代码区的第42行位置,items: ...

  6. 【Zigbee技术入门教程-号外】基于Z-Stack协议栈的抢答系统

    [Zigbee技术入门教程-号外]基于Z-Stack协议栈的抢答系统 广东职业技术学院  欧浩源 一.引言    2017年全国职业院校技能大赛"物联网技术应用"赛项中任务三题2的 ...

  7. Java进阶(二十五)Java连接mysql数据库(底层实现)

    Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜 ...

  8. SpringBoot进阶教程(五十九)整合Codis

    上一篇博文<详解Codis安装与部署>中,详细介绍了codis的安装与部署,这篇文章主要介绍介绍springboot整合codis.如果之前看过<SpringBoot进阶教程(五十二 ...

  9. RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)

    原文:RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...

随机推荐

  1. sublime2 nodejs 执行编译无反应

    这个问题困扰了我得一周了,好不容易解决了, 一.问题描述: 安装网上的一些教程在sublime text 2 里面安装Nodejs 的编译环境,但是安装完之后执行编译没有任何输出信息,编译没有反应,只 ...

  2. hive动态分区和混合分区

    各位看官,今天我们来讨论下再Hive中的动态分区和混合分区方面的一些知识点以及相关的一些问题. 前面我们已经讲过管理表和外部表的一般分区的一些知识点,对于需要对表创建很多的分区,那么用户就需要些很多的 ...

  3. centos7 ping不通 name or service not known

    最近打算为centos安装一个界面时,发现不能上网.ping www.baidu.com 报name or service not known. 原来网络配置没设好. 一.选择VMWare的NAT模式 ...

  4. maven 禁止连接外网仓库

    有些内网机器不能连外网的情况下,因为依赖的项目pom配置问题,mvn package时仍会尝试请求外网的repo(比如默认中央repo或oss). 此时配置 settings.xml 为自己内网rep ...

  5. 微信小程序中的AJAX——POST,GET区别

    注意:发送服务器时的DATA 最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String .转换规则如下: 对于 GET 方法的数据,会将数 ...

  6. shuffle的工作原理

    Shuffle的正常意思是洗牌或弄乱,可能大家更熟悉的是Java API里的Collections.shuffle(List)方法,它会随机地打乱参数list里的元素顺序.如果你不知道MapReduc ...

  7. mybatis的基本语句的应用

    大家好今晚整理有关mybatis的添加删除修改更新的操作 一.select <!-- 查询学生,根据id --> <select id="getStudent" ...

  8. NodeJS NPM 镜像使用方法

    每次npm的时候,走国外的镜像,非常的慢,可以配置一下 通过改变默认npm镜像代理服务,以下三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候不用重新配置. 通过config命令 ...

  9. 学用HBuilder开发App的看过来

    自己的呕心沥血之作吧,花了一年时间,系统介绍HTML5 App开发的相关技术. 越来越多的公司采用HTML5来快速开发移动跨平台App,它支持当前市场流行的移动设备. 本书主要介绍了HTML5在移动A ...

  10. LAMP构架搭建论坛

    安装MYSQL数据库服务程序       LAMP动态网站部署架构是一套由Linux+Nginx+MYSQL+PHP组成的动态网站系统解决方案,具有免费.高效.扩展性强且资源消耗低等优良特性.使用手工 ...