/**
* @author sysg
* 经纬度实体类
*/
@Data
@ApiModel(value = "Point", description = "经纬度实体类")
public class Point implements Serializable {
private static final long serialVersionUID = 940239742704329929L;
/**
* 经度
*/
@JsonProperty("j")
@ApiModelProperty("经度")
@NotNull("经度不能为空")
private Double longitude;
/**
* 纬度
*/
@JsonProperty("w")
@ApiModelProperty("纬度")
@NotNull("纬度不能为空")
private Double latitude;
public Point(double longitude,double latitude) {
setLongitude(longitude);
setLatitude(latitude);
}
@NotNull
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
}
十进制的经纬度,基本单位是度°。
东半球(东经)、北半球(北纬)为正数,西半球(西经)、南半球(南纬)为负数。
例如:
经度165.2446934°,纬度44.1794393°,对应了东、北半球上的一个点;
经度-65.2446934°,纬度-4.1794393°,对应了西、南半球上的一个点。
六十进制的经纬度,基本单位是度°、分’、秒’‘,1度°=60分’;1分’=60秒’'。
例如:
东经165°14’40.896",北纬44°10’45.981",对应了东、北半球上的一个点;
西经65°14’40.896",南纬4°10’45.981",对应了西、南半球上的一个点。
以上秒中的小数是十进制,小数位越长精度越高。
注:后台统一接收十进制的经纬度。
/**
* 最大误差,单位米
*/
@Value("${distance.max}")
private double MAX_DISTANCE;
application.yml配置文件
#经纬度校验最大距离,单位米
distance:
max: 1500.0
public static final double EARTH_RADIUS = 6371004.0;
static double convertDegreesToRadians(double degrees){
return degrees * Math.PI / 180;
}
/**
* 比较系数 (两点距离转为比较系数)
* 2h^2 = 1-cos(dlat) + cos(lat_a)*cos(lat_b)*(1-cos(dlon))
* @param a
* @param b
* @return
*/
public static double toCoefficient(Point a, Point b){
double lona = convertDegreesToRadians(a.getLongitude());
double lata = convertDegreesToRadians(a.getLatitude());
double lonb = convertDegreesToRadians(b.getLongitude());
double latb = convertDegreesToRadians(b.getLatitude());
double dlon = Math.abs(lona-lonb);
double dlat = Math.abs(lata-latb);
return 1 - Math.cos(dlat) + Math.cos(lata)*Math.cos(latb)*(1-Math.cos(dlon));
}
/**
* 公式推导
* A D
* -----
* /| \
* / | \
* / | \
* / | \
* -----+---------
* C H B
*
* s