需求:根据一个经纬度查询附近5公里的地点
因为附近5公里是个圆形要去数据库匹配的点位太多了,所以我们可以用这个圆的外切正方形取到四个点位去数据库里面进行匹配。如果追求精准度可以将取到的数据进一步进行对比。工具类代码如下:
package com.risen.app.util;
import java.util.HashMap;
import java.util.Map;
/**
*@describe 经纬度工具类
*@author denghz
*@date 2023/06/30 10:28:20
*@version 1.0.0
*/
public class DistanceUtil {
//地球半径千米
final static double EARTH_RADIUS_KILOMETER = 6378.137;
//地球半径,单位米
final static double EARTH_RADIUS_METER = 6378137;
/**
* @describe 根据一个给定经纬度的点和距离,进行附近地点查询
*
* @param longitude 经度
* @param latitude 纬度
* @param distance 距离(单位:公里或千米)
* @return 返回一个范围的4个点,最小纬度和纬度,最大经度和纬度
*/
public static Map<String, Double> findNeighPosition(double longitude, double latitude, double distance) {
//先计算查询点的经纬度范围
double dlng = 2 * Math.asin(Math.sin(distance / (2 * EARTH_RADIUS_KILOMETER)) / Math.cos(latitude * Math.PI / 180));
dlng = dlng * 180 / Math.PI;//角度转为弧度
double dlat = distance / EARTH_RADIUS_KILOMETER;
dlat = dlat * 180 / Math.PI;
Double minlat = latitude - dlat;
Double maxlat = latitude + dlat;
Double minlng = longitude - dlng;
Double maxlng = longitude + dlng;
Map<String, Double> map = new HashMap<>();
map.put("minlat", minlat);
map.put("maxlat", maxlat);
map.put("minlng", minlng);
map.put("maxlng", maxlng);
return map;
}
/**
* @describe 计算两点位置的距离,返回两点的距离,单位:公里或千米 (误差小于0.2米)
*
* @param lat1 第一点纬度
* @param lng1 第一点经度
* @param lat2 第二点纬度
* @param lng2 第二点经度
* @return 返回两点的距离,单位:公里或千米
*/
public static double GetDistance(double lat1, double lng1, double lat2, double lng2) {
double radLat1 = Rad(lat1);
double radLng1 = Rad(lng1);
double radLat2 = Rad(lat2);
double radLng2 = Rad(lng2);
double a = radLat1 - radLat2;
double b = radLng1 - radLng2;
double result = 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))) * EARTH_RADIUS_METER;
return result / 1000;
}
/**
* @describe 经纬度转化成弧度
*
* @param d 经纬度
* @return 弧度
*/
private static double Rad(double d) {
return d * Math.PI / 180d;
}
}