我有一台记录GPS数据的设备。每2-10秒读取一次。对于需要2个小时的活动,有很多GPS点。
有没有人知道通过删除冗余数据点来压缩数据集的算法。即如果一系列数据点都在一条直线上,那么只需要起点和终点。
答案 0 :(得分:6)
查看用于简化多边形的Douglas Peucker Algorithm。我已成功使用此功能来减少传输给客户端以显示目的时的gps航路点数量。
答案 1 :(得分:1)
关于Compressing GPS Data on Mobile Devices的研究论文。
此外,您可以在Writing GPS Applications上查看此CodeProject文章。我认为你将遇到的问题不是直线点,而是弯道。这一切都取决于你想要的道路精确程度。
答案 2 :(得分:1)
您可能希望使用多项式近似来近似路径x(t),y(t)。你在找这样的东西:http://www.youtube.com/watch?v=YtcZXlKbDJY ???
答案 3 :(得分:1)
您可以通过基于后续点之间的斜率计算执行非常基本的简化来删除冗余点。
这里有一些但不完整的C ++代码提供了可能的算法:
struct Point
{
double x;
double y;
};
double calculate_slope(Point const& p1, Point const& p2)
{
// dy y2 - y1
// m = ---- = ---------
// dx x2 - x1
return ((p2.y - p1.y) / (p2.x - p1.x));
}
// 1. Read first two points from GPS stream source
Point p0 = ... ;
Point p1 = ... ;
// 2. Accept p0 as it's first point
// 3. Calculate slope
double m0 = calculate_slope(p0, p1);
// 4. next point is now previous
p0 = p1;
// 5. Read another point
p1 = ... ;
double m1 = calculate_slope(p0, p1);
// 6. Eliminate Compare slopes
double const tolerance = 0.1; // choose your tolerance
double const diff = m0 - m1;
bool if (!((diff <= tolerance) && (diff >= -tolerance)))
{
// 7. Accept p0 and eliminate p1
m0 = m1;
}
// Repeat steps from 4 to 7 for the rest of points.
我希望它有所帮助。
答案 4 :(得分:0)
上面给出的代码有几个问题可能会使它不合适:
“相同坡度”公差测量的是梯度而不是角度的差异,因此NNE到NNW被认为是NE与SE之间的差异(假设y轴向南北方向运行)。
解决这个问题的一种方法是测量两段的点积如何与它们的长度乘积相比较的容差。 (记住两个向量的点积是它们的长度和它们之间角度的余弦的乘积可能有助于理解。)但是,请参阅下一点。
仅考虑斜率误差而不是位置误差,因此长的ENE段跟随长ESE段就像在ENE和ESE之间交替的一串短段压缩到单个段一样。
我想到的方法是查看矢量图形应用程序将光标坐标列表转换为一系列曲线的功能。例如。请参阅lib2geom的bezier-utils.cpp。请注意,(i)它几乎完全基于位置而不是基于方向; (ii)它给出了立方贝塞尔曲线作为输出而不是折线,尽管你可以使用相同的方法来给出折线输出(如果这是首选的)(在这种情况下,Newton-Raphson步骤基本上只是一个简单的点积)。 p>