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

news2024/12/27 12:32:03

场景:

我目前设计到的场景是:即在地图应用中,对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
    }
  }.max

  if (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
      }
    }._2

    val recResults1 = douglasPeucker(points.take(index+1), epsilon)
    val recResults2 = douglasPeucker(points.drop(index), epsilon)

    recResults1.init ::: recResults2
  } else {
    List(points.head, points.last)
  }
}

// 创建Spark会话
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算法(附代码及原始数据) - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1232982.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nosql的redis概述及基本操作

关系数据库与非关系型数据库概述 关系型数据库 关系型数据库是一个结构化的数据库&#xff0c;创建在关系模型&#xff08;二维表格模型&#xff09;基础上&#xff0c;一般面向于记录。SQL语句(标准数据查询语言)就是一种基于关系型数据库的语言&#xff0c;用于执行对关系型…

【Linux专题】退出bash后再运行jobs命令为什么不会显示后台任务

【Linux专题】firewalld 过滤出接口流量-CSDN博客文章浏览阅读214次。风和日丽&#xff0c;小微给你送福利~如果你是小微的老粉&#xff0c;这里有一份粉丝福利待领取...如果你是新粉关注到了小微&#xff0c;那恭喜你&#xff0c;你赚到了&#xff01;[欢迎关注微信公众号&…

技巧大揭秘!如何优雅地应对Redis读写超时问题

大家好&#xff0c;我是小米&#xff01;今天我们要聊的话题是在Java中如何优雅地处理Redis读写超时问题。这可是个让人头疼的问题&#xff0c;但别担心&#xff0c;我会在这里和大家一起揭开它的神秘面纱&#xff0c;分享一些超实用的技巧和优雅的处理方法。 问题背景 在我们…

陶瓷行业废污水处理使用MES系统的作用

陶瓷行业属于高能耗、高污染行业&#xff0c;生产过程中消耗大量矿产资源和能源&#xff0c;产生的废气、废水、废渣、粉尘等对环境造成严重污染。在近年来&#xff0c;全社会环保意识增强&#xff0c;政府出台了一系列政策、措施加大节能、减排力度&#xff0c;整治行业污染。…

NX二次开发UF_CAM_ask_lower_limit_plane_usage 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;里海NX二次开发3000例专栏 UF_CAM_ask_lower_limit_plane_usage Defined in: uf_cam_planes.h int UF_CAM_ask_lower_limit_plane_usage(tag_t object_tag, UF_PARAM_lwplane_usage_t * usage ) overview 概述 Query the usa…

Nginx解决跨域问题的一些想法

参考博客https://blog.csdn.net/agonie201218/article/details/112562252&#xff0c;https://blog.csdn.net/Zisson_no_error/article/details/119357629。都是写得非常很好的文章 重中之重&#xff1a;一定要长眼睛&#xff0c;带脑子 通过跨域访问的报错&#xff0c;看清楚…

H5生成二维码(HTML、CSS、QrCodeJs内含源码)

H5生成二维码 前言二维码实现过程页面实现关键点全部源码 前言 本文主要讲解如何通过原生HTML、CSS、Js中的qrcodejs二维码生成库&#xff0c;实现一个输入URL按下回车后输出URL。文章底部有全部源码&#xff0c;需要可以自取。 实现效果图&#xff1a; 上述实现效果为&#…

2023年11月中旬大模型新动向集锦

2023年11月中旬大模型新动向集锦 2023.11.21版权声明&#xff1a;本文为博主chszs的原创文章&#xff0c;未经博主允许不得转载。 1、谷歌生成式 AI 搜索生成体验&#xff08;SGE&#xff09;扩展到 120 多个新国家/地区 近日&#xff0c;Google 扩展了其由生成式人工智能驱…

无法打开 “XXXX“ ,因为Apple 无法检测其是否包含恶意软件

解决方案 设置 - > 隐私和安全性 这里会显示这个,点击仍要打开

高压放大器使用方法介绍

高压放大器是一种用于放大高压信号的电子设备&#xff0c;常用于科学研究、工业应用和医疗设备等领域。它可以将低电压信号放大到较高的电压水平&#xff0c;以满足特定应用的需求。 使用高压放大器需要注意以下几个方面&#xff1a; 1.了解设备规格&#xff1a;在使用高压放大…

Linux操作系统使用及C高级编程-D9D10Linux 服务搭建与使用

TFTP服务器 TFTP&#xff08;Trivial File Transfer Protocol&#xff09;即简单文件传输协议&#xff0c;是TCP/IP协议中一个用来在客户机与服务器之间进行简单文件传输的协议&#xff0c;提供不复杂、开销不大的文件传输服务。端口号为69 1、使用客户服务器方式和使用UDP数据…

Vue项目Jenkins自动化部署

1. 需求描述 我们希望提交uat分支时,UAT项目能够自动发布,提交master分支时,无需自动发布,管理员手工发布 2. 效果展示 3. 采用技术 Jenkins + K8S + Docker + Nginx 4. 具体实现 4.1 编写default.conf 在Vue项目根目录新建default.conf文件,主要进行代理配置、首页…

yum 搭建仓库 http/ftp

目录 http ftp http 服务端 1. 下载 httpd 服务&#xff0c;记得将防火墙和安全终端全部关掉 2. 开启 httpd 服务 3. 临时挂载 客户端 1. 下载 httpd 服务&#xff0c;记得将防火墙和安全终端全部关掉 2. 开启 httpd 服务 3. 进入 /etc/yum.repos.d 4. 新建一个目录 mhy&…

代码随想录 11.21 || 单调栈 LeetCode 84.柱状图中最大的矩形

84.柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1。求在柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。和 42.接雨水 类似&#xff0c;在由数组组成的柱状图中&#xff0c;根据条件求解。 图…

本地/笔记本/纯 cpu 部署、使用类 gpt 大模型

文章目录 1. 安装 web UI1.1. 下载代码库1.2. 创建 conda 环境1.3. 安装 pytorch1.4. 安装 pip 库 2. 下载大模型3. 使用 web UI3.1. 运行 UI 界面3.2. 加载模型3.3. 进行对话 使用 web UI 大模型文件&#xff0c;即可在笔记本上部署、使用类 gpt 大模型。 1. 安装 web UI 1…

nvm 离线安装,并离线安装指定版本 node

1. 离线安装 nvm 通常通过网络安装nvm的时候会被墙&#xff0c;所以nvm安装就只能进行离线安装了。 我们可以在github上下载nvm的安装包&#xff0c;然后在本地安装&#xff0c;下载地址&#xff1a;点击直达 点进去的详情长这样&#xff1a; 将下载下来的文件放到服务器&…

jdk9.0.1下载、安装、配置

下载路径xIndex of java-local/jdk/9.0.111 安装 环境变量配置 新增变量&#xff1a;JAVA_HOME 值&#xff1a;安装路径 path中新增&#xff1a;%JAVA_HOME%\bin

LeetCode【76】最小覆盖子串

题目&#xff1a; 思路&#xff1a; https://segmentfault.com/a/1190000021815411 代码&#xff1a; public String minWindow(String s, String t) { Map<Character, Integer> map new HashMap<>();//遍历字符串 t&#xff0c;初始化每个字母的次数for (int…

华为防火墙 DMZ 设置

DMZ 是英文"Demilitarized Zone"的缩写&#xff0c;中文名称为"隔离区" 它是为了解决安装防火墙后外部网络不能访问内部网络服务器的问题&#xff0c;而设立的一个位于内部网络与外部网络之间的缓冲区&#xff0c;在这个网络区域内可以放置一些公开的服务…