道格拉斯-普克抽稀算法过滤经纬度-java

道格拉斯-普克抽稀算法过滤经纬度-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;

}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是Java实现的道格拉斯-普克抽稀算法的示例代码: ```java import java.util.ArrayList; import java.util.List; public class DouglasPeucker { public static List<Point> douglasPeucker(List<Point> points, double epsilon) { if (points == null || points.size() < 3) { return points; } int maxIndex = 0; double maxDistance = 0; int endIndex = points.size() - 1; for (int i = 1; i < endIndex; i++) { double distance = perpendicularDistance(points.get(i), points.get(0), points.get(endIndex)); if (distance > maxDistance) { maxIndex = i; maxDistance = distance; } } List<Point> resultList = new ArrayList<>(); if (maxDistance > epsilon) { List<Point> leftList = points.subList(0, maxIndex + 1); List<Point> rightList = points.subList(maxIndex, endIndex + 1); List<Point> leftResultList = douglasPeucker(leftList, epsilon); List<Point> rightResultList = douglasPeucker(rightList, epsilon); resultList.addAll(leftResultList.subList(0, leftResultList.size() - 1)); resultList.addAll(rightResultList); } else { resultList.add(points.get(0)); resultList.add(points.get(endIndex)); } return resultList; } private static double perpendicularDistance(Point point, Point start, Point end) { double area = Math.abs(0.5 * (start.getX() * end.getY() + end.getX() * point.getY() + point.getX() * start.getY() - end.getX() * start.getY() - point.getX() * end.getY() - start.getX() * point.getY())); double bottom = Math.sqrt(Math.pow(start.getX() - end.getX(),2) + Math.pow(start.getY() - end.getY(), 2)); double height = area / bottom * 2; return height; } public static class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } } } ``` 上述代码中,`douglasPeucker`方法接收一个点集和一个误差值`epsilon`,返回一个抽稀后的点集。`perpendicularDistance`方法用于计算一个点到一条线段的垂直距离。`Point`类表示一个二维坐标点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值