#商户
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* @author kong
*/
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class MerchantDTO {
private Long id;
private Double latitude;
private Double longitude;
/**
* 用户距离商户的距离
*/
private Double distance;
private BigDecimal money;
}
#用户
package com.yun.brand.tools.distance;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* @author kong
*/
@Data
@Accessors
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
private Long id;
private Double latitude;
private Double longitude;
}
#工具,计算用户与多个商户之间的距离 ,以1公里5元 为配送费 排序
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author kong
*/
@Slf4j
public class DistanceTools {
/**
* 赤道半径
*/
private static final double EARTH_RADIUS = 6378137;
private static double rad(double d) {
return d * Math.PI / 180.0;
}
public static double getDistance(UserDTO u, MerchantDTO m) {
return getDistance(u.getLatitude(), u.getLongitude(), m.getLatitude(), m.getLongitude());
}
public static double getDistance(double lon1, double lat1, double lon2, double lat2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lon1) - rad(lon2);
double s = 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)));
s = s * EARTH_RADIUS;
//单位米
return s;
}
public static void main(String[] args) {
//用户经纬度 103.123321 30.123321
UserDTO user = new UserDTO(1L, 103.123321, 30.123321);
//商户经纬度
List<MerchantDTO> merchants = Lists.newArrayList(
new MerchantDTO(1L, 103.123321, 30.123321, 0.0, BigDecimal.ZERO),
new MerchantDTO(2L, 104.063402, 30.568744, 0.0,BigDecimal.ZERO));
merchants.parallelStream().forEach(m ->{
m.setDistance(getDistance(user, m));
m.setMoney(new BigDecimal(String.valueOf(m.getDistance())).multiply(new BigDecimal("5")));
});
merchants = merchants.parallelStream().sorted(Comparator.comparing(MerchantDTO::getDistance)).sorted(Comparator.comparing(MerchantDTO::getMoney)).collect(Collectors.toList());
merchants.forEach(m -> log.debug(JSON.toJSONString(m)));
}
}