原文为JS版本,见JS版本
这里将其转成python版本,如下:
from geog import distance import pandas as pd from matplotlib import pyplot as plt import numpy as np class Douglas_Peuker: "Douglas–Peucker algorithm压缩轨迹" def __init__(self, traj, dMax=5): print('原始轨迹长度:', len(traj)) plt.figure() # 画图 plt.subplot(1, 2, 1) # 画图 plt.plot(np.array(traj)[:,0], np.array(traj)[:,1], 'r-') plt.title('init_traj') traj = [[i, x[0], x[1]] for i, x in enumerate(traj)] douglasPecker_traj = self.douglasPecker(traj, dMax) print('压缩后轨迹长度:', len(douglasPecker_traj)) plt.subplot(1, 2, 2) # 画图 plt.plot(np.array(douglasPecker_traj)[:, 0], np.array(douglasPecker_traj)[:, 1], 'b-') plt.title('douglasPecker_traj') plt.show() plt.close() def douglasPecker(self, coordinate, dMax): """ :param coordinate: 原始轨迹 :param dMax: 允许最大距离误差 :return: douglasResult 抽稀后的轨迹 """ result = self.compressLine(coordinate, [], 0, len(coordinate)-1, dMax) result.append(coordinate[0]) result.append(coordinate[-1]) result = pd.DataFrame(result, columns=['myIndex', 'lat', 'lng']) result.sort_values(by=['myIndex'], inplace=True) result.reset_index(drop=True, inplace=True) return result.loc[:, ['lat', 'lng']].values.tolist() def compressLine(self, coordinate, result, start, end, dMax): "递归方式压缩轨迹" if start<end: maxDist = 0 currentIndex = 0 startPoint = coordinate[start][1:] endPoint = coordinate[end][1:] for i in range(start+1, end): currentDist = self.disToSegment(startPoint, endPoint, coordinate[i][1:]) if currentDist>maxDist: maxDist = currentDist currentIndex = i if maxDist>=dMax: # 将当前点加入到过滤数组中 result.append(coordinate[currentIndex]) # 将原来的线段以当前点为中心拆成两段,分别进行递归处理 self.compressLine(coordinate, result, start, currentIndex, dMax) self.compressLine(coordinate, result, currentIndex, end, dMax) return result def disToSegment(self, start, end, center): "计算垂距,用海伦公式计算面积" a = distance(start, end) b = distance(start, center) c = distance(end, center) p = (a+b+c) / 2 s = np.sqrt(abs(p*(p-a)*(p-b)*(p-c))) return s*2/a if __name__=='__main__': "traj是一个二维数组格式的经纬度列表,lng在前,lat在后" Douglas_Peuker(traj, dMax=5)
结果:
原始轨迹长度: 167
压缩后轨迹长度: 129