java mysql 周

阅读: 评论:0

java mysql 周

java mysql 周

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

v准备工作

创建测试数据库

CREATE TABLE`userposition` (

`id`int(10) unsigned NOT NULLAUTO_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实现

/*** 查找附近的人

*@paramradii 半径距离(单位km)

*@paramlon 经度

*@paramlat 纬度

*@return

*/@GetMapping("/nearby")public List getVicinity(double radii, double lon, doublelat){double r = 6371;//地球半径千米

double dis =radii;double dlng = 2*Math.asin(Math.sin(dis/(2*r))/s(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 +Vicinity(BigDecimal.valueOf(minlng), BigDecimal.valueOf(maxlng), BigDecimal.valueOf(minlat), BigDecimal.valueOf(maxlat));

}

mybatis

selectfrom userposition

where longitude>= #{minlng} and longitude <= #{maxlng} and latitude >= #{minlat} and latitude <= #{maxlat}

List getvicinity(@Param("minlng") BigDecimal minlng,

@Param("maxlng") BigDecimal maxlng,

@Param("minlat") BigDecimal minlat,

@Param("maxlat") BigDecimal maxlat);

测试效果

在地图中找到回龙新村的经纬度,然后测试。

v按距离远近排序

Java代码

/*** 附近的人排序

*@paramlon 经度

*@paramlat 纬度

*@return

*/@GetMapping("/nearbysort")public List getVicinitySort(double lon, doublelat){vicinitysort(BigDecimal.valueOf(lon), BigDecimal.valueOf(lat));

}

mybatis代码

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

List 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)ASdistanceFROMuserpositionORDER BYdistanceASC

v博客总结

如果数据量大的话,还可以考虑基于Redis实现附近的人。

其他参考资料:

本文发布于:2024-01-31 06:26:52,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170665361526214.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:java   mysql
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23