java完成复杂的巡检轨迹抽稀功能


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class TrajectorySimplification {

    // 轨迹点类
    static class Point {
        double x, y;

        Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public String toString() {
            return "Point{" +
                    "x=" + x +
                    ", y=" + y +
                    '}';
        }
    }

    // 计算点到线段的垂直距离
    private static double perpendicularDistance(Point p, Point start, Point end) {
        double dx = end.x - start.x;
        double dy = end.y - start.y;

        double mag = Math.hypot(dx, dy);
        if (mag > 0.0) {
            dx /= mag;
            dy /= mag;
        }

        double pvx = p.x - start.x;
        double pvy = p.y - start.y;

        double pvdot = dx * pvx + dy * pvy;
        double ax = pvx - pvdot * dx;
        double ay = pvy - pvdot * dy;

        return Math.hypot(ax, ay);
    }

    // 道格拉斯-普克算法
    public static List<Point> douglasPeucker(List<Point> points, double epsilon) {
        if (points == null || points.size() < 3) {
            return points;
        }

        int startIndex = 0;
        int endIndex = points.size() - 1;

        List<Point> result = new ArrayList<>();
        result.add(points.get(startIndex));
        result.add(points.get(endIndex));

        douglasPeuckerRecursive(points, startIndex, endIndex, epsilon, result);

        // 按照原始顺序排序
        Collections.sort(result, Comparator.comparingDouble(p -> p.x));
        return result;
    }

    private static void douglasPeuckerRecursive(List<Point> points, int startIndex, int endIndex, double epsilon, List<Point> result) {
        double maxDistance = 0.0;
        int index = 0;

        for (int i = startIndex + 1; i < endIndex; i++) {
            double distance = perpendicularDistance(points.get(i), points.get(startIndex), points.get(endIndex));
            if (distance > maxDistance) {
                maxDistance = distance;
                index = i;
            }
        }

        if (maxDistance > epsilon) {
            result.add(points.get(index));
            douglasPeuckerRecursive(points, startIndex, index, epsilon, result);
            douglasPeuckerRecursive(points, index, endIndex, epsilon, result);
        }
    }

    public static void main(String[] args) {
        List<Point> points = new ArrayList<>();
        points.add(new Point(0, 0));
        points.add(new Point(1, 0.1));
        points.add(new Point(2, -0.1));
        points.add(new Point(3, 5));
        points.add(new Point(4, 6));
        points.add(new Point(5, 7));
        points.add(new Point(6, 8.1));
        points.add(new Point(7, 9));
        points.add(new Point(8, 9));
        points.add(new Point(9, 9));
        
        // 经纬度数据点数比较多的情况下,epsilon 设置0.006,根据自己的业务去动态调整
        double epsilon = 1.0;

        List<Point> simplifiedPoints = douglasPeucker(points, epsilon);

        System.out.println("Original Points:");
        for (Point point : points) {
            System.out.println(point);
        }

        System.out.println("\nSimplified Points:");
        for (Point point : simplifiedPoints) {
            System.out.println(point);
        }
    }
}

代码解释

  1. Point类: 定义一个简单的点类,包含x和y坐标。
  2. perpendicularDistance方法: 计算一个点到一条线段的垂直距离。
  3. douglasPeucker方法: 实现道格拉斯-普克算法,接受一个点列表和一个阈值epsilon,返回简化后的点列表。
  4. douglasPeuckerRecursive方法: 递归实现轨迹简化的核心算法。
  5. main方法: 示例代码,展示如何使用上述方法进行复杂巡检轨迹的抽稀。

使用说明

  1. 输入: 轨迹点列表和阈值epsilon。
  2. 输出: 简化后的轨迹点列表。

你可以调整epsilon的值来控制简化的程度。较大的epsilon值会删除更多的点,而较小的epsilon值会保留更多的点。

示例输出

运行上述代码后,你将看到原始点列表和简化后的点列表。简化后的点列表将包含较少的点,但仍然保留了轨迹的大致形状。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值