67,512
社区成员
发帖
与我相关
我的任务
分享
满足条件的客户数量:10
距离4.7077公里 CustomerInfo [id=42, name=第42个客户, point=Point [lat=25.38652801513672, lon=102.53978729248047]]
距离7.6318公里 CustomerInfo [id=66, name=第66个客户, point=Point [lat=25.292055130004883, lon=102.52806854248047]]
距离9.1959公里 CustomerInfo [id=3, name=第3个客户, point=Point [lat=25.295881271362305, lon=102.6337890625]]
距离14.1178公里 CustomerInfo [id=53, name=第53个客户, point=Point [lat=25.386337280273438, lon=102.70116424560547]]
距离15.1921公里 CustomerInfo [id=24, name=第24个客户, point=Point [lat=25.487585067749023, lon=102.57908630371094]]
距离16.2238公里 CustomerInfo [id=61, name=第61个客户, point=Point [lat=25.281827926635742, lon=102.70787811279297]]
距离16.9743公里 CustomerInfo [id=84, name=第84个客户, point=Point [lat=25.479028701782227, lon=102.47322845458984]]
距离17.6577公里 CustomerInfo [id=5, name=第5个客户, point=Point [lat=25.499061584472656, lon=102.63092803955078]]
距离19.0416公里 CustomerInfo [id=79, name=第79个客户, point=Point [lat=25.364389419555664, lon=102.75501251220703]]
距离19.4402公里 CustomerInfo [id=4, name=第4个客户, point=Point [lat=25.524290084838867, lon=102.53683471679688]]
package cn.miw.test.model;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
/**
* 根据客户位置计算与商家距离,筛选出在派送范围内的客户
* @ClassName: CustomerInfo
* @author mrzhou@miw.cn<br>
* www.miw.cn<br>
* 2018年9月13日 下午6:29:08<br>
*/
public class CustomerInfo {
private int id;
private String name;
private Point point;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "CustomerInfo [id=" + id + ", name=" + name + ", point=" + point + "]";
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public CustomerInfo(int id, String name, Point point) {
super();
this.id = id;
this.name = name;
this.point = point;
}
/**
* 进行测试
* @author mrzhou@miw.cn<br>
* www.miw.cn<br>
* 2018年9月13日 下午6:28:56<br>
* @param args
*/
public static void main(String[] args) {
List<CustomerInfo> customers = prepare();//准备客户数据
Point point = new Point(25.351475,102.56606);//店家所在位置
double radius = 20 * 1000; //派送范围10km
List<CustomerInfo> list = customers.stream().filter(customer -> customer.getDistance(point) < radius)
.collect(Collectors.toList());//过滤不在范围内的客户
System.out.println("满足条件的客户数量:" + list.size());
list.stream().sorted((a, b) -> a.getDistance(point) > b.getDistance(point) ? 1 : -1) //按距离排序显示
.forEach(c -> {
System.out.print("距离" + c.getDistance(point) / 1000 + "公里\t");
System.out.println(c);
});
}
/**
* 准备客户数据
* @author mrzhou@miw.cn<br>
* www.miw.cn<br>
* 2018年9月13日 下午6:28:39<br>
* @return
*/
private static List<CustomerInfo> prepare() {
List<CustomerInfo> shops = new ArrayList<CustomerInfo>();
Random random = new Random(System.nanoTime());
for (int i = 0; i < 100; i++) {
float lat = 25f + random.nextFloat(), lon = 102f + random.nextFloat();
System.out.println(i+":"+lat+","+lon);
shops.add(new CustomerInfo(i, "第" + i + "个客户", new Point(lat, lon)));
}
return shops;
}
/**
* 计算与某点的距离
* @author mrzhou@miw.cn<br>
* www.miw.cn<br>
* 2018年9月13日 下午6:30:27<br>
* @param p
* @return
*/
private double getDistance(Point p) {
double radLat1 = rad(p.lat);
double radLat2 = rad(point.lat);
double a = radLat1 - radLat2;
double b = rad(p.lon) - rad(point.lon);
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;
s = Math.round(s * 10000d) / 10000d;
s = s * 1000;
return s;
}
private static double EARTH_RADIUS = 6371.393;//地球半径
private static double rad(double d) {
return d * Math.PI / 180.0;
}
static class Point {
double lat, lon;
public Point(double lat, double lon) {
super();
this.lat = lat;
this.lon = lon;
}
@Override
public String toString() {
return "Point [lat=" + lat + ", lon=" + lon + "]";
}
}
}
SELECT number,address,lng,lat,serve_time,distance FROM (
SELECT is_open,number,address,lng,lat,serve_time,ROUND(ACOS(COS(#{lat}*PI()/180 )*COS(lat*PI()/180)*COS(#{lng}*PI()/180 -lng*PI()/180)+SIN(#{lat}*PI()/180 )*SIN(lat*PI()/180))*6370996.81) AS distance FROM recycling_machine
) AS tb WHERE is_open=1
<IF test="distance != null">
AND <![CDATA[ distance <= #{distance} ]]>
</IF>
ORDER BY distance
LIMIT #{startIndex},#{pageSize}