项目中,两个不同的业务完全重合的gps点位(lon和lat数值完全相等)的情况并不多,更多的是需要比对大概重合的点位,给定一个偏差值。下面给出工具类,计算两份数据的大概重合点位个数。改造一下,也可以将点位信息输出。
package com.compass.patrol.utils;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import lombok.extern.slf4j.Slf4j;
import org.postgis.PGgeometry;
/**
* @author 张闯
*/
@Slf4j
public class GPSHelper {
// 圆周率
public static final double PI = 3.14159265358979324;
// 赤道半径(单位m)
private static final double EARTH_RADIUS = 6378137;
/**
* 两个gps点之间的距离
*/
public static final int DISTANCE=50;
/**
* 转化为弧度(rad)
* */
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* 基于googleMap中的算法得到两经纬度之间的距离,
* 计算精度与谷歌地图的距离精度差不多,相差范围在0.2米以下
* @param lon1 第一点的经度
* @param lat2 第一点的纬度
* @param lon2 第二点的经度
* @param lat1 第二点的纬度
* @return 返回的距离,单位m
* */
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;
//s = Math.round(s * 10000) / 10000;
return s;
}
public static void main(String[] args) {
//0.9897437
System.out.println(GetDistance(120.590001854527,31.3519078188015,120.6279,31.329));
}
/**
* 计算zdyjList中与cgbsList重合的点
*
* @param zdyjList Agps信息 list中的数值是gemotry ,关于gemotry需要自行百度
* @param cgbsList Bgps信息 list中的数值是gemotry,关于gemotry需要自行百度
* @return
*/
public static Map<String, String> distanceCalculation(List<String> zdyjList,List<String> cgbsList){
Map<String,String> matchMap=new HashMap<>();
Set<String> set=new HashSet<>();
PGgeometry pGgeometry=new PGgeometry();
AtomicInteger minValue= new AtomicInteger(Integer.MAX_VALUE);
AtomicReference<String> geometry= new AtomicReference<>("");
zdyjList.stream().forEach(s -> {
try {
if(set.contains(s))
return;
pGgeometry.setValue(s);
String[] point = pGgeometry.getValue().substring(16, pGgeometry.getValue().length() - 1)
.split(" ");
double originX=Double.parseDouble(point[0]);
double originxY=Double.parseDouble(point[1]);
cgbsList.stream().forEach(s1 -> {
try {
pGgeometry.setValue(s1);
String[] point2 = pGgeometry.getValue()
.substring(16, pGgeometry.getValue().length() - 1)
.split(" ");
Double realDistance = GPSHelper.GetDistance(originX,originxY, Double.parseDouble(point2[0]),Double.parseDouble(point2[1]));
if(realDistance.intValue() < DISTANCE && realDistance.intValue() < minValue.get()){
minValue.set(realDistance.intValue());
geometry.set(s1);
}
}catch (Exception e){
log.error("匹配重合点位 处理gps点失败 ",e);
}
});
if(minValue.get()==Integer.MAX_VALUE)
return;
matchMap.put(s,geometry.get());
set.add(s);
minValue.set(Integer.MAX_VALUE);
geometry.set("");
} catch (Exception e) {
log.error("匹配重合点位 处理gps点失败 ",e);
}
}
);
return matchMap;
}
}