生产环境_移动目标轨迹压缩应用和算法处理-Douglas-Peucker轨迹压缩算法

本文主要是介绍生产环境_移动目标轨迹压缩应用和算法处理-Douglas-Peucker轨迹压缩算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

场景:

我目前设计到的场景是:以路面上行驶的汽车为例,即在地图应用中,对GPS轨迹数据进行压缩,减少数据传输和存储开销,因为轨迹点太频繁了,占用空间太大,运行节点太慢了,经过小组讨论需要上这个算法。

涉及到的算法

  1. Douglas-Peucker算法:该算法通过递归地将轨迹分割为线段,并丢弃那些与整体轨迹偏差较小的线段,从而实现轨迹的压缩。
    1. Visvalingam-Whyatt算法:该算法基于三角形面积的概念,通过不断移除面积最小的点来达到轨迹压缩的目的

                                图片来源:郑宇博士《computing with spatial trajectories》

Haversine公式计算距离和Douglas-Peucker压缩算法代码实现-scala版

import org.apache.spark.sql.{DataFrame, SparkSession}
import org.apache.spark.sql.functions._
import scala.math._// 定义表示点的类
case class Point(lon: Double, lat: Double, time: String, id: String)// Haversine距离计算函数
def haversineDistance(point1: Point, point2: Point): Double = {val R = 6371000.0 // 地球半径(米)val dLat = toRadians(point2.lat - point1.lat)val dLon = toRadians(point2.lon - point1.lon)val a = pow(sin(dLat / 2), 2) + cos(toRadians(point1.lat)) * cos(toRadians(point2.lat)) * pow(sin(dLon / 2), 2)val c = 2 * atan2(sqrt(a), sqrt(1 - a))R * c
}// Douglas-Peucker轨迹压缩函数
def douglasPeucker(points: List[Point], epsilon: Double): List[Point] = {if (points.length < 3) {return points}val dmax = points.view.zipWithIndex.map { case (point, index) =>if (index != 0 && index != points.length - 1) {perpendicularDistance(point, points.head, points.last)} else {0.0}}.maxif (dmax > epsilon) {val index = points.view.zipWithIndex.maxBy { case (point, index) =>if (index != 0 && index != points.length - 1) {perpendicularDistance(point, points.head, points.last)} else {0.0}}._2val recResults1 = douglasPeucker(points.take(index+1), epsilon)val recResults2 = douglasPeucker(points.drop(index), epsilon)recResults1.init ::: recResults2} else {List(points.head, points.last)}
}val spark = SparkSession.builder().appName("TrajectoryCompression").getOrCreate()// 接入包含lon、lat、time和id列的DataFrame
//https://blog.csdn.net/qq_52128187?type=blog,by_laoli
val data = Seq((40.7128, -74.0060, "2023-11-18 08:00:00", "1"),(40.7215, -74.0112, "2023-11-18 08:05:00", "1"),(40.7312, -74.0146, "2023-11-18 08:10:00", "1"),(40.7356, -74.0162, "2023-11-18 08:15:00", "1"),(40.7391, -74.0182, "2023-11-18 08:20:00", "1"),(40.7483, -74.0224, "2023-11-18 08:25:00", "1"),(40.7527, -74.0260, "2023-11-18 08:30:00", "1")
).toDF("lon", "lat", "time", "id")// 为DataFrame添加id列
val dfWithId = data.withColumn("id", monotonically_increasing_id())// 将DataFrame转换为Point列表
val points = dfWithId.as[(Double, Double, String, Long)].collect().map(p => Point(p._1, p._2, p._3, p._4.toString)).toList// 执行轨迹压缩
val compressedPoints = douglasPeucker(points, epsilon = 10)  
// <- 设置epsilon值// 将压缩后的数据重新转换为DataFrame
import spark.implicits._
val df2 = compressedPoints.toDF("lon", "lat", "time", "id")

参考文章

  • Douglas, D.H., and Peucker, T.K. "Algorithms for the reduction of the number of points required to represent a digitized line or its caricature." The Canadian Cartographer 10.2 (1973): 112-122.
  • Visvalingam, M., and Whyatt, J.D. "Line generalization by repeated elimination of the smallest-area triangle." Cartographic Journal 30.1 (1993): 46-51.
  • 轨迹数据压缩的Douglas-Peucker算法(附代码及原始数据) - 知乎

这篇关于生产环境_移动目标轨迹压缩应用和算法处理-Douglas-Peucker轨迹压缩算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/402626

相关文章

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过

mysql外键创建不成功/失效如何处理

《mysql外键创建不成功/失效如何处理》文章介绍了在MySQL5.5.40版本中,创建带有外键约束的`stu`和`grade`表时遇到的问题,发现`grade`表的`id`字段没有随着`studen... 当前mysql版本:SELECT VERSION();结果为:5.5.40。在复习mysql外键约

Python调用另一个py文件并传递参数常见的方法及其应用场景

《Python调用另一个py文件并传递参数常见的方法及其应用场景》:本文主要介绍在Python中调用另一个py文件并传递参数的几种常见方法,包括使用import语句、exec函数、subproce... 目录前言1. 使用import语句1.1 基本用法1.2 导入特定函数1.3 处理文件路径2. 使用ex

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

Python结合requests和Cheerio处理网页内容的操作步骤

《Python结合requests和Cheerio处理网页内容的操作步骤》Python因其简洁明了的语法和强大的库支持,成为了编写爬虫程序的首选语言之一,requests库是Python中用于发送HT... 目录一、前言二、环境搭建三、requests库的基本使用四、Cheerio库的基本使用五、结合req

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1