道格拉斯-普克抽稀算法过滤经纬度-java
package com.wm.weather.backend.utils;
import javax.swing.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
public class Douglas extends JFrame {
/**
* 存储采样点数据链表
*/
public static List<ModelDTO > points = new ArrayList<ModelDTO >();
/**
* 控制数据经度压缩的极差
*/
private static final double D = 0.0001;
/**
* 对矢量曲线进行压缩
*
* @param from 曲线的起始点
* @param to 曲线的终止点
*/
public static void compress(ModelDTO from, ModelDTO to) {
/**
* 压缩算法的开关
*/
boolean switchvalue = false;
/**
* 由起始点和终止点构成直线方程一般式的系数
*/
double fromLat = Double.valueOf(from.getBlat());
double fromLng = Double.valueOf(from.getBlng());
double toLat = Double.valueOf(to.getBlat());
double toLng = Double.valueOf(to.getBlng());
double A = (fromLat - toLat)
/ Math.sqrt(Math.pow((fromLat - toLat), 2)
+ Math.pow((fromLng - toLng), 2));
/**
* 由起始点和终止点构成直线方程一般式的系数
*/
double B = (toLng - fromLng)
/ Math.sqrt(Math.pow((fromLat - toLat), 2)
+ Math.pow((fromLng - toLng), 2));
/**
* 由起始点和终止点构成直线方程一般式的系数
*/
double C = (fromLng * toLat - toLng * fromLat)
/ Math.sqrt(Math.pow((fromLat - toLat), 2)
+ Math.pow((fromLng - toLng), 2));
double d = 0;
double dmax = 0;
int m = points.indexOf(from);
int n = points.indexOf(to);
if (n == m + 1)
return;
SurveyMonitorDTO middle = null;
List<Double> distance = new ArrayList<>();
for (int i = m + 1; i < n; i++) {
double blng = Double.valueOf(points.get(i).getBlng());
double blat = Double.valueOf(points.get(i).getBlat());
d = Math.abs(A * (blng) + B * (blat) + C) / Math.sqrt(Math.pow(A, 2) + Math.pow(B, 2));
distance.add(d);
}
dmax = distance.get(0);
for (int j = 1; j < distance.size(); j++) {
if (distance.get(j) > dmax)
dmax = distance.get(j);
}
if (dmax > D)
switchvalue = true;
else
switchvalue = false;
if (!switchvalue) {
//删除Points(m,n)内的坐标
for (int i = m + 1; i < n; i++) {
points.get(i).setIndex(-1);
}
} else {
for (int i = m + 1; i < n; i++) {
double blng = Double.valueOf(points.get(i).getBlng());
double blat = Double.valueOf(points.get(i).getBlat());
if ((Math.abs(A * (blng) + B
* (blat) + C)
/ Math.sqrt(Math.pow(A, 2) + Math.pow(B, 2)) == dmax))
middle = points.get(i);
}
compress(from, middle);
compress(middle, to);
}
}
public static List<ModelDTO > douglasData(List<ModelDTO > source) {
points = source;
System.out.println("压缩前:");
for (int i = 0; i < points.size(); i++) {
ModelDTO p = points.get(i);
System.out.print("[" + p.getBlng() + "," + p.getBlat() + "],");
}
compress(points.get(0), points.get(points.size() - 1));
System.out.println("\n压缩后:");
List<ModelDTO > list = new ArrayList<>();
for (int i = 0; i < points.size(); i++) {
ModelDTO p = points.get(i);
if (p.getIndex() > -1) {
list.add(p);
System.out.print("[" + p.getBlng() + "," + p.getBlat() + "],");
}
}
return list;
}
}
@Data
class ModelDTO implements Serializable {
@ApiModelProperty(value = "纬度", example = "23")
private String blat;
@ApiModelProperty(value = "经度", example = "106")
private String blng;
}