Commit a9ad8a12 by 宋珺琪

轨迹相似度(湖南)

parent 19a48ab8
package com.founder.commonutils.model.vo.param;
import com.founder.commonutils.util.map.Coordinate;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 轨迹相似度传参类
* @author yangyang
* @date 2022/12/13/
*/
@Data
@ApiModel(value="轨迹相似度传参类", description="")
public class SkTrailXsdParam {
@ApiModelProperty(value = "轨迹点1")
private List<Coordinate> listOne;
@ApiModelProperty(value = "轨迹点2")
private List<Coordinate> listTwo;
@ApiModelProperty(value = "距离")
private Integer radius;
@ApiModelProperty(value = "时间间隔(分钟)")
private int minutes;
}
package com.founder.commonutils.util.map;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value="轨迹点位坐标", description="")
public class Coordinate {
@ApiModelProperty(value = "x轴")
private double x;
@ApiModelProperty(value = "y轴")
private double y;
@ApiModelProperty(value = "时间")
private String time;
}
package com.founder.commonutils.util.map;
import java.util.*;
public class LCSS {
private List<Coordinate> l1;
private List<Coordinate> l2;
private List<Coordinate> lcs = new ArrayList<>();
public static double getDistance(Coordinate p, Coordinate q) {
double dx = p.getX() - q.getX();
double dy = p.getY() - q.getY();
double distance = Math.sqrt(dx * dx + dy * dy);
return distance;
}
public boolean isNearby(Coordinate a, Coordinate b,int radius) {
if (getDistance(a.getX(), a.getY(), b.getX(), b.getY()) < radius) return true;
return false;
}
public void printLcs(int[][] flag, List<Coordinate> a, int i, int j) {
if (i == 0 || j == 0) return;
System.out.println("flag[i][j]="+flag[i][j] +" "+"i="+i +"j="+j);
if (flag[i][j] == 1) {
printLcs(flag, a, i - 1, j - 1);
lcs.add(a.get(i - 1));
} else if (flag[i][j] == 2) {
printLcs(flag, a, i, j - 1);
} else {
printLcs(flag, a, i - 1, j);
}
}
//轨迹相似度
public Map lcs(List<Coordinate> l1, List<Coordinate> l2, int radius,int minutes) {
long timeItervalMinutes = minutes * 60 * 1000;
Map map = new HashMap();
Set<Coordinate> loneMz = new HashSet<>();
Set<Coordinate> ltwoMz = new HashSet<>();
Double xsd ;
int len1 = l1.size();
int len2 = l2.size();
int[][] c = new int[len1 + 1][len2 + 1];
int[][] flag = new int[len1 + 1][len2 + 1];
// 外层遍历第一条轨迹
for (int i = 0; i < len1; i++) {
//内层遍历第二条轨迹
for (int j = 0; j < len2; j++) {
// 时间范围比较 俩个点之间的时差
long timeIterval = Long.parseLong(l1.get(i).getTime()) - Long.parseLong(l2.get(j).getTime());
//第一条轨迹的第i个点和第二条轨迹的第j个点是否在radius范围内 && 俩个点之间的时差小于等于minutes && 俩个点之间的时差大于等于-minutes
if ( isNearby(l1.get(i), l2.get(j),radius) && timeIterval<=timeItervalMinutes && timeIterval>=-timeItervalMinutes) {
loneMz.add(l1.get(i));
ltwoMz.add(l2.get(j));
c[i + 1][j + 1] = c[i][j] + 1;
flag[i + 1][j + 1] = 1;//1='ok' //1表示箭头为 左上
//for循环知道行数列数的情况
System.out.print("1++++"+flag[i + 1][j + 1] + " ");
} else if (c[i + 1][j] > c[i][j + 1]) {
c[i + 1][j + 1] = c[i + 1][j];
flag[i + 1][j + 1] = 2;//2='left' //2表示箭头向 上
//for循环知道行数列数的情况
System.out.print("2++++"+flag[i + 1][j + 1] + " ");
} else {
c[i + 1][j + 1] = c[i][j + 1];
flag[i + 1][j + 1] = 3;//3='up' //3表示箭头向 左
//for循环知道行数列数的情况
System.out.print("3++++"+flag[i + 1][j + 1] + " ");
}
}
}
System.out.println("打印flag:");
for (int[] ints : flag) {
for (int anInt : ints) {
System.out.print(anInt + "\t" );
}
System.out.println();
}
System.out.println("打印c:");
for (int[] ints : c) {
for (int anInt : ints) {
System.out.print(anInt + "\t" );
}
System.out.println();
}
printLcs(flag, l1, len1, len2);
System.out.println(lcs);
xsd=(lcs.size() * 1.0 / Math.min(len1, len2));
map.put("listOneMz",loneMz);
map.put("listTwoMz",ltwoMz);
map.put("xsd",xsd);
//归一化处理
return map;
}
private static double EARTH_RADIUS = 6371.393;
private static double rad(double d) {
return d * Math.PI / 180.0;
}
public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * Math.asin(Math.sqrt(Math.abs(
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 * 1000);
return s;
}
}
\ No newline at end of file
......@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.extension.api.ApiController;
import com.founder.commonutils.model.newPublicEntity.MapRestResult;
import com.founder.commonutils.model.newPublicEntity.SkTrail;
import com.founder.commonutils.model.vo.param.SkTrailParam;
import com.founder.commonutils.model.vo.param.SkTrailXsdParam;
import com.founder.commonutils.util.map.LCSS;
import com.founder.publicapi.service.SkTrailService;
import com.founder.servicebase.logs.OperLog;
import com.founder.servicebase.logs.OperationType;
......@@ -69,7 +71,13 @@ public class SkTrailController extends ApiController {
public MapRestResult getTrackGroupByTime(@RequestBody List<SkTrailParam> points){
return skTrailService.getTrackGroupByTime(points);
}
@PostMapping("getGjxsd")
@ApiOperation(value = "公共_轨迹相似度")
@OperLog(message = "公共_轨迹相似度", operation = OperationType.QUERY)
public MapRestResult getGjxsd(@RequestBody SkTrailXsdParam skTrailXsdParam){
LCSS lcss = new LCSS();
return MapRestResult.build(200, "轨迹相似度",1 ,lcss.lcs(skTrailXsdParam.getListOne(), skTrailXsdParam.getListTwo(),skTrailXsdParam.getRadius(),skTrailXsdParam.getMinutes()));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment