前言 现在很多App都需要附带着附近人列表功能,所以我在这里实现2个点之间的距离计算
经纬度的获取需要第三方来支持,高德地图、百度地图…. 附近人功能具体的实现逻辑:
获取每个人的经纬度坐标,存库记录
通过SQL获取指定距离范围内的用户列表(文章中的MySQL中通过经纬度,获取范围内的用户
)
通过获取到的用户列表,计算自己与用户之间度距离(文章中的JAVA代码实现计算AB两点的直线距离
)
方法一:JAVA代码实现计算AB两点的直线距离
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 import java.math.BigDecimal;import java.util.HashMap;import java.util.Map; public class DistanceUtil { private static double EARTH_RADIUS = 6378.137 ; private static double rad (double d) { return d * Math.PI / 180.0 ; } public static Map<String, Object> getDistance (double longitude1, double latitude1, double longitude2, double latitude2) { double radLat1 = rad(latitude1); double radLat2 = rad(latitude2); double a = radLat1 - radLat2; double b = rad(longitude1) - rad(longitude2); double distance = 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 ))); distance = distance * EARTH_RADIUS; Map<String, Object> map = new HashMap <String, Object>(); BigDecimal decimal = new BigDecimal (distance); distance = decimal.setScale(2 , BigDecimal.ROUND_HALF_UP).doubleValue(); map.put("units" , "km" ); map.put("distance" , distance); return map; } public static void main (String[] args) { Map<String, Object> m = DistanceUtil.getDistance(36.665777 , 117.034727 , 36.665871 , 117.041006 ); System.out.println(m); } }
方法二:MySQL中通过经纬度,获取范围内的用户
创建数据表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0 ;DROP TABLE IF EXISTS `user_coordinates`;CREATE TABLE `user_coordinates` ( `id` varchar (255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL , `user_id` varchar (32 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户ID' , `x_longitude` double (11 , 8 ) DEFAULT NULL COMMENT '经度' , `y_latitude` double (11 , 8 ) DEFAULT NULL COMMENT '纬度' , PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户经纬度坐标表' ROW_FORMAT = Dynamic ; INSERT INTO `user_coordinates` VALUES ('1' , '1001' , 117.12345678 , 36.12345678 );SET FOREIGN_KEY_CHECKS = 1 ;
传入中心点的,经纬度,distance的单位为km 1 2 3 4 5 6 7 8 9 SELECT id, user_id, ROUND(6378.138 * 2 * ASIN (SQRT (POW(SIN (('纬度' * PI()/ 180 - y_latitude* PI()/ 180 )/ 2 ),2 )+ COS ('纬度' * PI()/ 180 )* COS (y_latitude* PI()/ 180 )* POW(SIN (('经度' * PI()/ 180 - x_longitude* PI()/ 180 )/ 2 ),2 ))),2 ) AS distance FROM user_coordinates HAVING distance <= '范围大小(单位:千米)' ORDER BY distance ASC
案例 例如:当前坐标经纬为【117.041006, 36.665871
】,结合用户经纬度坐标表
,查询10公里
范围内的所有用户
1 2 3 4 5 6 7 8 9 10 SELECT id, user_id, ROUND(6378.138 * 2 * ASIN (SQRT (POW(SIN (('36.665871' * PI()/ 180 - y_latitude* PI()/ 180 )/ 2 ),2 )+ COS ('36.665871' * PI()/ 180 )* COS (y_latitude* PI()/ 180 )* POW(SIN (('117.041006' * PI()/ 180 - x_longitude* PI()/ 180 )/ 2 ),2 )))) AS distance FROM user_coordinates HAVING distance <= '10' ORDER BY distance ASC