本文参考了一篇学长的博客,链接一下找不着了。
数据处理
数据预览
fd=open(r".\2007-10-14-GPS.log",'r')
limit=3
i=0
for line in fd:
if i<limit:
print(line.strip())
i+=1
else:
break
fd.close()
可见文件包含了原始的GPS数据,为了后续计算方便,需要对原始数据进行处理与提取。
课题任务为路径压缩,只需要用到GPS数据中的经纬度,所以将经纬度字段进行提取。
GPS原始数据格式及其意义见百度。
数据预处理
将GPS数据提取出来并进行单位统一化,单位为度。
fd_s=open(r".\2007-10-14-GPS.log",'r')
fd_d=open(r".\2007-10-14-GPS_transformed.txt",'w')
id=0 #坐标点序号,以0开始,以文件行数结束
for line in fd_s:
#转换为标准经纬度,ddd.mm
longitude=float(line.split(" ")[3])/100
latitude=float(line.split(" ")[5])/100
#转换成以度为单位的经纬度,ddd+mm/60
longitude_transform=longitude//1+(longitude-longitude//1)*100/60
latitude_transform=latitude//1+(latitude-latitude//1)*100/60
#此处注意精度,若精度不够后面会出现两个点极其相近而发生除0错误
fd_d.write("%s,%.6f,%.6f\n"%(id,longitude_transform,latitude_transform))
id+=1
fd_s.close()
fd_d.close()
print("data size:{}".format(id))
输出为:3150
Douglas-Peucker算法
简介
Douglas-Peucker算法常用于轨迹压缩,典型步骤如下:
- 在曲线首尾两点A,B之间连接一条直线AB,该直线为曲线的弦
- 计算离弦AB距离最远的点与最大距离
- 比较最大距离与阈值,若小于阈值则舍弃该点,以AB弦作为曲线的近似
- 若大于阈值,则以此点将曲线划分成两段,并对两段曲线分别进行1-3步操作
此处实现了四个函数,分别为:
- Geodist(point1,point2):返回两个点之间的距离
- get_vertical_dist(pointA,pointB,pointX):返回点X与弦AB的垂直距离
- DP_compress(point_list,output_point_list,Dmax):按照阈值Dmax将压缩后的point_list输出到output_point_list中
- get_MeanErr(point_list,output_point_list):返回输出相对于输入的平均误差
点间距离
import math
def Rad(d):
return d * math.pi / 180
def Geodist(point1,point2):
radLat1 = Rad(point1[1])
radLat2 = Rad(point2[1])
delta_lon = Rad(point1[0] - point2[0])
top_1 = math.cos(radLat2) * math.sin(delta_lon)
top_2 = math.cos(radLat1) * math.sin(radLat2) - math.sin(radLat1) * math.cos(radLat2) * math.cos(delta_lon)
top = math.sqrt(