道格拉斯-普克 Douglas-Peuker(DP算法) python php实现

2024-08-28 17:28

本文主要是介绍道格拉斯-普克 Douglas-Peuker(DP算法) python php实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

废话不多说,直接开干!

最近在做一个车联网项目,有一个场景是车辆定时上报当前所在经纬度等位置信息上报给平台,平台通过web页面在高德地图上展示车辆行驶路径。

说明

道格拉斯-普克算法 (Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法、迭代适应点算法、分裂与合并算法)是将曲线近似表示为一系列点,并减少点的数量的一种算法。它的优点是具有平移和旋转不变性,给定曲线与阈值后,抽样结果一定。—摘自百度百科

python 代码
安装模块Shapely

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple Shapely

# -*- coding:utf-8 -*-
"""
道格拉斯算法的实现
程序需要安装shapely模块
"""
import math
from shapely import wkt, geometry
import matplotlib.pyplot as pltclass Point:"""点类"""x = 0.0y = 0.0index = 0  # 点在线上的索引def __init__(self, x, y, index):self.x = xself.y = yself.index = indexclass Douglas:"""道格拉斯算法类"""points = []D = 1  # 容差def readPoint(self):"""生成点要素"""g = wkt.loads("LINESTRING(1 4,2 3,4 2,6 6,7 7,8 6,9 5,10 10)")coords = g.coordsfor i in range(len(coords)):self.points.append(Point(coords[i][0], coords[i][1], i))def compress(self, p1, p2):"""具体的抽稀算法"""swichvalue = False# 一般式直线方程系数 A*x+B*y+C=0,利用点斜式,分母可以省略约区# A=(p1.y-p2.y)/math.sqrt(math.pow(p1.y-p2.y,2)+math.pow(p1.x-p2.x,2))A = (p1.y - p2.y)# B=(p2.x-p1.x)/math.sqrt(math.pow(p1.y-p2.y,2)+math.pow(p1.x-p2.x,2))B = (p2.x - p1.x)# C=(p1.x*p2.y-p2.x*p1.y)/math.sqrt(math.pow(p1.y-p2.y,2)+math.pow(p1.x-p2.x,2))C = (p1.x * p2.y - p2.x * p1.y)m = self.points.index(p1)n = self.points.index(p2)distance = []middle = Noneif (n == m + 1):return# 计算中间点到直线的距离for i in range(m + 1, n):d = abs(A * self.points[i].x + B * self.points[i].y + C) / math.sqrt(math.pow(A, 2) + math.pow(B, 2))distance.append(d)dmax = max(distance)if dmax > self.D:swichvalue = Trueelse:swichvalue = Falseif (not swichvalue):for i in range(m + 1, n):del self.points[i]else:for i in range(m + 1, n):if (abs(A * self.points[i].x + B * self.points[i].y + C) / math.sqrt(math.pow(A, 2) + math.pow(B, 2)) == dmax):middle = self.points[i]self.compress(p1, middle)self.compress(middle, p2)def printPoint(self):"""打印数据点"""for p in self.points:print( "%d,%f,%f" % (p.index, p.x, p.y))def main():"""测试"""d = Douglas()d.readPoint()# d.printPoint()# 结果图形的绘制,抽稀之前绘制fig = plt.figure()a1 = fig.add_subplot(121)dx = []dy = []for i in range(len(d.points)):dx.append(d.points[i].x)dy.append(d.points[i].y)a1.plot(dx, dy, color='g', linestyle='-', marker='+')d.compress(d.points[0], d.points[len(d.points) - 1]) #稀释后轨迹# 抽稀之后绘制dx1 = []dy1 = []a2 = fig.add_subplot(122)for p in d.points:print(p.x,p.y)dx1.append(p.x)dy1.append(p.y)a2.plot(dx1, dy1, color='r', linestyle='-', marker='+')plt.show()if __name__ == '__main__':main()

运行结果
在这里插入图片描述
php代码

/*** 根据两个点求直线方程 ax+by+c=0* @param $xy1 string 点1,例如"1,1"* @param $xy2 string 点2,例如"2,2"* @return array*/function getLineByPoint($xy1, $xy2){$x1 = explode(",", $xy1)[0];//第一个点的横坐标$y1 = explode(",", $xy1)[1];//第一个点的纵坐标$x2 = explode(",", $xy2)[0];//第二个点的横坐标$y2 = explode(",", $xy2)[1];//第二个点的横坐标$a = $y2 - $y1;$b = $x1 - $x2;$c = ($y1 - $y2) * $x1 - $y1 * ($x1 - $x2);return [$a, $b, $c];}/*** 稀疏点* @param $points array 参数为["1,2","2,3"]点集* @param $max float 阈值,越大稀疏效果越好但是细节越差* @return array*/function sparePoints($points, $max){if (count($points) < 3) {return $points;}//        var_dump($points);die;$xy1 = $points[0];//取第一个点$xy1 = $xy1['glng'].','.$xy1['glat'];$xy2 = end($points);//取最后一个点$xy2 = $xy2['glng'].','.$xy2['glat'];
//        var_dump(end($points)['glat']);die;list($a, $b, $c) = getLineByPoint($xy1, $xy2);//获取直线方程的a,b,c值$ret   = [];//最后稀疏以后的点集$dmax  = 0;//记录点到直线的最大距离$split = 0;//分割位置for ($i = 1; $i < count($points) - 1; $i++) {$d = getDistanceFromPointToLine($a, $b, $c, $points[$i]);if ($d > $dmax) {$split = $i;$dmax  = $d;}}if ($dmax>$max) {//如果存在点到首位点连成直线的距离大于max,即需要再次划分$child1 = sparePoints(array_slice($points, 0, $split + 1), $max);//按split分成左边一份,递归$child2 = sparePoints(array_slice($points, $split), $max);//按split分成右边一份,递归//因为child1的最后一个点和child2的第一个点,肯定是同一个(即为分割点),合并的时候,需要注意一下$ret = array_merge($ret, $child1, array_slice($child2, 1));return $ret;} else {//如果不存在点到直线的距离大于阈值的,那么就直接是首尾点了return [$points[0], end($points)];}}$gps_list=  ["118.7727996753945,34.1246971539229","118.77485177448638,34.124702346094594","118.7831576932094,34.13298337245958","118.78533669945193,34.133335134266446",    ];$data = sparePoints($gps_list, "0.0001");//稀释万分之一

运行结果
在这里插入图片描述

这篇关于道格拉斯-普克 Douglas-Peuker(DP算法) python php实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Python安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre