坐标点/GPS点/经纬度/UTM的抽稀算法-道格拉斯算法

道格拉斯-普克算法(经纬度或坐标点抽稀) 起因 最近在做一个车联网项目,有一个场景是车辆定时上报当前所在经纬度等位置信息上报给平台,平台通过web页面在高德地图上展示车辆行驶路径。 由于车辆上报规则是每隔4s上报一次,一个小时也就是900个点,一天也就是21600个点,如果是10辆车就是216000个点,那如果是100辆车,甚至是10000辆车对于数据库存储来说会是一个灾难,对于渲染地图,过多的点,也减少页面的流畅度。 考虑到车辆直线行驶... 阅读详情

输入点集合进行抽稀,根据不同的抽稀力度获取不同的点集结果,力度越大,点集越稀疏。

package com.hxkj.common.utils;

import java.util.*;


/**
 * 坐标处理类 GPS点的抽稀-道格拉斯算法
 *
 * @author Elinx
 * @since 2021-05-31 10:28
 */
public class GisDouglasUtil {

    /**
     * 计算两点距离
     *
     * @param point1 点1
     * @param point2 点2
     * @return double
     */
    private static double calculationDistance(double[] point1, double[] point2) {
        double lat1 = point1[0];
        double lat2 = point2[0];
        double lng1 = point1[1];
        double lng2 = point2[1];
        double radLat1 = lat1 * Math.PI / 180.0;
        double radLat2 = lat2 * Math.PI / 180.0;
        double a = radLat1 - radLat2;
        double b = (lng1 * Math.PI / 180.0) - (lng2 * Math.PI / 180.0);
        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)));
        return s * 6370996.81;

    }

    /**
     * 计算点pX到点pA和pB所确定的直线的距离
     *
     * @param start  开始
     * @param end    结束
     * @param center 中心
     * @return double
     */
    private static double distToSegment(double[] start, double[] end, double[] center) {
        double a = Math.abs(calculationDistance(start, end));
        double b = Math.abs(calculationDistance(start, center));
        double c = Math.abs(calculationDistance(end, center));
        double p = (a + b + c) / 2.0;
        double s = Math.sqrt(Math.abs(p * (p - a) * (p - b) * (p - c)));
        return s * 2.0 / a;
    }

    /**
     * 递归方式压缩轨迹
     *
     * @param coordinate 坐标集
     * @param result     结果集
     * @param start      开始
     * @param end        结束
     * @param dMax       抽稀力度
     * @return List<double [ ]>
     */
    private static List<double[]> compressLine(List<double[]> coordinate, List<double[]> result, int start, int end, int dMax) {
        if (start < end) {
            double maxDist = 0;
            int currentIndex = 0;
            double[] startPoint = coordinate.get(start);
            double[] endPoint = coordinate.get(end);
            for (int i = start + 1; i < end; i++) {
                double currentDist = distToSegment(startPoint, endPoint, coordinate.get(i));
                if (currentDist > maxDist) {
                    maxDist = currentDist;
                    currentIndex = i;
                }
            }
            if (maxDist >= dMax) {
                //将当前点加入到过滤数组中
                result.add(coordinate.get(currentIndex));
                //将原来的线段以当前点为中心拆成两段,分别进行递归处理
                compressLine(coordinate, result, start, currentIndex, dMax);
                compressLine(coordinate, result, currentIndex, end, dMax);
            }
        }
        return result;
    }

    /**
     * @param coordinate 原始轨迹Array<{longitude, latitude}>
     * @param dMax       允许最大距离误差
     * @return douglasResult 抽稀后的轨迹
     */
    public static List<double[]> douglasPeucker(List<double[]> coordinate, int dMax) {
        //抽稀点数量需要大于2
        if (coordinate == null || coordinate.size() <= 2) {
            return null;
        }

        List<double[]> coordinate2 = new ArrayList<>();
        for (int i = 0; i < coordinate.size(); i++) {
            double[] point = Arrays.copyOf(coordinate.get(i), 3);
            point[2] = i;
            coordinate2.add(point);
        }
        List<double[]> result = new ArrayList<>();
        result = compressLine(coordinate2, result, 0, coordinate2.size() - 1, dMax);

        result.add(coordinate2.get(0));
        result.add(coordinate2.get(coordinate.size() - 1));

        Collections.sort(result, new Comparator<double[]>() {
            @Override
            public int compare(double[] u1, double[] u2) {
                if (u1[2] > u2[2]) {
                    return 1;
                } else if (u1[2] < u2[2]) {
                    return -1;
                }
                return 0; //相等为0
            }
        });

        return result;
    }

}


用法:

List list = new ArrayList<>(); // 点集对象列表
List<double[]> runtimeTrackList = new ArrayList<>();
for (Object trackObj : list) {
     // new track 仅包含x,y,自行设定解析类
     Double longitude = track.getX();
     Double latitude = track.getY();
     if (latitude != null && longitude != null) {
         double[] temp = new double[2];
         Arrays.fill(temp, longitude);
         Arrays.fill(temp, latitude);
         runtimeTrackList.add(temp);
     }
 }
 // 抽稀算法,力度3
 runtimeTrackList = GisDouglasUtil.douglasPeucker(runtimeTrackList, 3);
GPS定位轨迹抽稀之道格拉斯-普克(Douglas-Peuker)算法详解 目录 1. 抽稀 2. 原理 3. 具体思路 4. 代码示例 道格拉斯-普克算法是我们常用的一种轨迹点的抽稀算法,抽稀出来的点可以尽可能的维持原先轨迹点的大体轮廓,剔除一些非必要的点 2. 原理 假设在平面坐标系上有一条由N个坐标点组成的曲线,已设定一个阈值epsilon。 (1)首先,将起始点与结束点用直线连接, 再找出到该直线的距离最大,同时又大于阈值epsilon的点并记... 阅读详情

相关推荐

从游戏外挂检测到智慧交通:聊聊‘三点定角’算法在轨迹分析里的那些骚操作

本文探讨了‘三点定角’算法在轨迹分析中的多样化应用,从游戏外挂检测到智慧交通和生态研究。通过计算三个坐标点的夹角,该算法能精准识别异常轨迹、危险驾驶行为和动物迁徙关键点。文章详细介绍了算法原理、优化策略及在不同领域的实战案例,展示了基础算法在经纬度轨迹数据处理中的强大跨界潜力。

weixin_33719619的博客 489

C语言程序实现道格拉斯—普克算法(Douglas--Peucker)

算法简介 道格拉斯—普克算法(Douglas—Peucker)也称,线简化算法。作用在于,删除冗余数据,减少数据的存贮量,节省存贮空间,加快后继处理的速度。 格拉斯—普克算法(Douglas—Peucker)的核心思想: 对每一条曲线的首末端点连一条线,求所有点到该直线的距离,并找出最大距离值Dmax,用与阈值限差D相比: 若Dmax<D,这条曲线上的中间点全部舍去; 若Dmax ≥ D...

Xiaoqing的博客 4160

【点云抽稀】一种基于均匀分布随机数的点云抽稀算法

一种基于均匀分布的随机数的点云抽稀算法,时间复杂度是O(n)。经验证,效果可行,效率也行。

GeomasterYi的博客 2559

曲线点抽稀算法-Python实现

何为抽稀 在处理矢量化数据时,记录中往往会有很多重复数据,对进一步数据处理带来诸多不便。多余的数据一方面浪费了较多的存储空间,另一方面造成所要表达的图形不光滑或不符合标准。因此要通过某种规则,在保证矢量曲线形状不变的情况下, 最大限度地减少数据点个数,这个过程称为抽稀。 通俗的讲就是对曲线...

chenxuan5849的博客 1440

GPS点的抽稀-道格拉斯算法 java实现

格拉斯普克算法原理 对曲线的首末点虚连一条直线,求曲线上所有点与直线的距离,并找出最大距离值dmax,用dmax与事先给定的阈值D相比 若dmax<D,则将这条曲线上的中间点全部舍去;则该直线段作为曲线的近似,该段曲线处理完毕。 若dmax≥D,保留dmax对应的坐标点,并以该点为界,把曲线分为两部分,对这两部分重复使用该方法,即重复1,2步,直到所有dmax均<D,即完成对...

n009ww的博客 4885

【运动规划算法项目实战】路径规划中常用的抽稀算法(附ROS C++代码)

抽稀(Simplification)算法是指在保持数据尽可能不失真的前提下,对数据进行精简处理,减少数据的数量,便于数据的存储和处理。路径规划中,抽稀算法的作用是将原始路径中的冗余点去除,从而减小路径点的数量,降低计算量和存储量,同时保留路径的形状特征和轨迹信息,确保路径规划的精度和实时性。常见的抽稀算法有 Douglas-Peucker算法和垂距限值法。

xiewf的博客 3859

Douglas-Peucker算法详解:折线抽稀原理、实现与最佳实践

在GIS、地图渲染与轨迹处理中,海量坐标点常导致存储、传输与渲染压力激增。折线抽稀(Line Simplification)是解决该问题的关键手段,而Douglas-Peucker(DP)算法作为最经典的全局抽稀算法,通过递归分治与阈值控制,在保留形状特征的同时大幅压缩点数。它提供明确的最大偏差上界,能有效平衡压缩率与几何精度。无论是GPS轨迹抽稀、地图边界简化,还是手写笔迹降采样,DP算法都是工程实践中的首选方案。本文深入拆解DP算法的核心原理、距离阈值选择、经纬度坐标处理技巧、迭代实现方式,并结合真实案

weixin_33888907的博客 285

point-clustering.rar Java后端前端进行经纬度点抽稀聚合渲染

Java后端进行经纬度点抽稀聚合,HTML呈现及前端聚合渲染 index.html 谷歌map后端点聚合 geos.html 后端点聚合并渲染 geo_cluster.html mapbox前端点聚合 jpg/heatJpgTile.html 栅格瓦片jpg渲染底图及数据 multilines.html 多点,线面渲染

道格拉斯普克算法

道格拉斯-普克算法(Douglas–Peucker algorithm),亦称为拉默-道格拉斯-普克算法(Ramer–Douglas–Peucker algorithm),这个算法最初由拉默(Urs Ramer)于1972年提出,1973年道格拉斯(David Douglas)和普克(Thomas Peucker)二人又独立于拉默提出了该算法。

qq_25368751的博客 7173

cutlass2.x源码解读之PitchLinearStripminedThreadMap

TensorCoord:使用layout::PitchLinearCoord作为张量坐标。Shape:使用模板参数Shape_作为tile的形状,kThreads:线程总数,定义为模板参数Threads。kElementsPerAccess:每次访问的元素数,定义为模板参数ElementsPerAccess。ThreadAccessShape:线程访问的形状,使用layout::PitchLinearShape定义。内部实现细节:ShapeVec。

jiangjkd的专栏 790

RK3588实战:如何将8路1080P视频流实时拼接成一张超清全景图?聊聊AVS模块的那些事

本文深入解析了RK3588芯片的AVS模块如何实现8路1080P视频流的实时全景拼接技术。通过硬件加速、时间同步、几何校正和色彩均衡等关键技术,RK3588能够高效处理高密度视频流,输出超清全景图。文章还提供了优化策略和实战经验,帮助开发者充分发挥RK3588的潜力。

weixin_27014595的博客 744

道格拉斯佩克算法c语言,曲线近似——道格拉斯-普克算法

算法的JAVA源程序:packagecom.mapbar.jts;publicclassPoint{privatedoublex=0;privatedoubley=0;privateintindex=0;publicdoublegetX() {returnx;}publicvoidsetX(doublex) {this.x=x;}publicdoublegetY() {returny;}publi...

weixin_32161697的博客 404

DataWorks数据安全治理最佳实践

DataWorks基于数据安全治理的常见思路,针对资产梳理、技术体系建设和运营体系建设,提供了一系列数据安全产品能力,您可通过“基础防护建设、数据安全防护措施及策略增强建设、数据安全持续运营”三个阶段在DataWorks上落地数据安全治理项目。参考本文启动数据安全治理项目前,建议您先了解DataWorks数据安全产品相关能力了解DataWorks数据安全产品能力后,您可参考如下三个阶段在DataWorks上落地数据安全治理项目。

soso1968的博客 1438

Java【算法 02】道格拉斯-普克 Douglas-Peucker 抽稀算法分析及15w个坐标点抽稀到3.7w耗时从360s+优化到365ms接近1000倍的速度提升(并行流+多线程+泛型)

Java【算法 02】道格拉斯-普克 Douglas-Peucker 抽稀算法分析及15w个坐标点抽稀到3.7w耗时从360s+优化到365ms接近1000倍的速度提升(并行流+多线程+泛型)

Java与大数据相关实践内容分享! 2743

iOS中.obj、.usdz、.dae和.scn格式之间的转化(思路清晰版)

作者最近在写项目的过程中遇到了一些3d模型格式问题,故写下这篇文章记录一下解决问题的过程。

yueliangmua的博客 5586

使用pdfBox实现pdf转图片出现中文方块乱码 简单修改源码解决

参考文章 问题排查:使用pdfbox将pdf转image时STSong-Light字体中文乱码 pdfbox版本是2.0 日志中打印出类似这样的日志(例:Using fallback XXX for CID-keyed font STSong-Light),就说明系统没有安装STSong-Light字体,pdfbox使用XXX字体来替代了。如果出现方块,就说明没有这种字体,并且替代字体也没有,日志也有相应的其他提示。 正常操作就是安装缺失的 STSong-Light 字体,但是在网上搜到的都是 STSong

aji_csdn的博客 5266

道格拉斯-普克 抽稀算法

道格拉斯-普克抽稀算法,是用来对大量冗余的图形数据点进行压缩以提取必要的数据点。该算法实现抽稀的过程是:先将一条曲线首尾点虚连一条直线,求其余各点到该直线的距离,取其最大者与规定的临界值相比较,若小于临界值,则将直线两端间各点全部舍去,否则将离该直线距离最大的点保留,并将原线条分成两部分,对每部分线条再实施该抽稀过程,直到结束。抽稀结果点数随选取限差临界值的增大而减少,应用时应根据精度来选取限差临...

3016

图解链表 —— JAVA中的单链表基本操作

文章目录1. 什么是链表2. 链表的种类3. 创建单链表3.1 创建 Node 类(车厢类)3.2 创建 MySingleList (火车类)4. 单链表的基本操作4.1 增加链表元素4.1.1 在链表头部添加元素4.1.2 在链表任意位置添加元素4.1.3 在链表尾部添加元素4.2 删除链表元素4.2.1 删除第一个节点元素4.2.2 删除任意位置 index 元素4.2.3 删除链表中指定元素的第一个节点4.2.4 删除链表的所有指定元素4.3 查找链表元素4.3.1 判断链表中是否包含元素 data4

AlinaQ05的博客 2502

路径规划中常用的抽稀(simplification)算法

在路径规划中,过度密集的路径点不仅会增加计算和存储的负担,还可能导致路径冗余和效率下降,因此需要进行抽稀处理,同时保留路径的形状特征和轨迹信息,确保路径规划的精度和实时性。常见的抽稀算法有Ramer-Douglas-Peucker(RDP)算法和垂距限值法。

每天进步一点点。 3228

【WRF-Chem工具】pyVPRM 计算大气与陆地植被之间的 CO₂ 交换通量

pyVPRM 计算大气与陆地植被之间的 CO₂ 交换通量

WW、forever的博客 210

手把手教你学Simulink--基于电能质量与无功补偿的场景实例:统一电能质量调节器(UPQC)的联合控制仿真

在现代电力系统中,电能质量问题有源电力滤波器(APF)→ 治理谐波与无功动态电压恢复器(DVR)→ 补偿电压暂降/暂升静止无功发生器(SVG)→ 无功补偿与电压支撑而统一电能质量调节器(Unified Power Quality Conditioner, UPQC)是一种集串联补偿与并联补偿于一体的全能型电能质量治理装置✅ 电压类问题:暂降、暂升、不平衡、闪变✅ 电流类问题:谐波、无功、三相不平衡✅ 实现双向有功交换(储能型)串联单元(DVR功能):串联于线路,控制电源侧电压质量并联单元。

MHD0815的博客 239

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

baidu_39547612的博客 2352

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

抽稀算法-抽稀函数-数据压缩

抽稀(Data Decimation)是一种数据压缩技术,用于减少数据点的数量同时保持数据的主要特征。

远方雪的专栏 1147

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

对 gps 经纬度点进行抽稀算法处理,不影响整体路线的精度

注意points 格式 [{lng:120,lat:34}.....]注意 threshold 一般 0.005 自己调。

weixin_39170410的博客 830

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

抽稀-Douglas-Peucker算法

Douglas-Peucker算法   在数字化过程中,需要对曲线进行采样简化,即在曲线上取有限个点,将其变为折线,并且能够在一定程度 上保持原有的形状。   经典的Douglas-Peucker算法描述如下: (1)在曲线首尾两点A,B之间连接一条直线AB,该直线为曲线的弦; (2)得到曲线上离该直线段距离最大的点C,计算其与AB的距离d; (3)比较该距离与预先给定的阈值thr

GeoTechMAN's Zone 5744

Java【算法 01】道格拉斯-普克 Douglas-Peucker 抽稀算法(算法流程图解+使用JDK8方法实现+详细注解源码)

Java【算法 01】道格拉斯-普克 Douglas-Peucker 抽稀算法(算法流程图解+使用JDK8方法实现+详细注解源码)

Java与大数据相关实践内容分享! 5494
上一篇: XY坐标两点插值(加密)计算(Java)
下一篇: 计算JTS缓冲区面积(Java)
苟先
博客等级 码龄15年 15粉丝 19原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值