用于 GPS 数据缩减数据的 LINQ 命令
本文关键字:数据 LINQ 命令 GPS 用于 | 更新日期: 2023-09-27 18:30:34
>我有这个:
public class LatLon
{
public double lat {get;set;}
public double lon {get;set;}
}
在List<LatLon>
.它包含
p1 { lat = 49.9429989, lon = 3.9542134 }
p2 { lat = 49.9429989, lon = 3.9542133 }
p3 { lat = 49.9429989, lon = 3.9542136 }
等。。
我的目标是从此列表中删除与其他坐标的差异小于lat_bound和lon_bound边界的坐标,因此即使记录者长时间站在某个地方,也意味着只剩下一个坐标。什么是 LINQ 命令?
例:
p1 { lat = 4.555, lon = 6.555 }
p2 { lat = 4.556, lon = 6.556 }
.
然后Math.Abs(p1.lat - p2.lat) = 0.001
和Math.Abs(p1.lon - p2.lon) = 0.001
. p1.lon - p2.lon
是另一个坐标的lon值的lon差值。假设lon_bound
等于 0.0005,那么如果lat_bound
也是 0.0005,则删除该坐标,如 0.001> 0.0005。
编辑:我决定用管道代替 http://www.gpsbabel.org。
LINQ 不会创造奇迹。你所指的问题不仅仅是一个"Distict"类型的问题。
首先,您必须创建一个函数来测量 2 点之间的距离。
第二,您需要检测点的聚类。(将近距离点组织成组)
最后,最简单的方法是按所属集群分组,并且每个组仅保留 1 个点.....
但话又说回来.....还有其他几个问题可能无法产生准确的结果。
例如,最能代表其组的一点是什么?
Math.Round
将值舍入到所需的精度。然后使用 Linq Distinct
删除重复项。
void Main()
{
var list = new List<Coordinate>()
{
new Coordinate(25.25251, 100.21254),
new Coordinate(25.25252, 100.21255),
new Coordinate(25.25253, 100.21256),
new Coordinate(25.80000, 100.90000)
};
int precision = 4;
var res = list.Select(x => new Coordinate(
Math.Round(x.Lon, precision),
Math.Round(x.Lat, precision))).Distinct().ToList();
}
public struct Coordinate
{
private double lon;
private double lat;
public Coordinate(double lon, double lat)
{
this.lon = lon;
this.lat = lat;
}
public double Lat { get { return lat; } }
public double Lon { get { return lon; } }
}
(请注意,我使用的是结构体而不是坐标的类)
如果你有一个函数Func<LatLon, LatLon, bool> bounded
,如果两个点在你的范围内,则返回true
,如果不是,则返回false
,则此查询有效:
var keeps =
latlons
.Aggregate(new List<LatLon>(), (xs, y) =>
{
if (!xs.Any(x => bounded(x, y)))
{
xs.Add(y);
}
return xs;
});
您可以按邻近性进行筛选,如下所示:
public class LatLon
{
public double lat {get;set;}
public double lon {get;set;}
}
class ProximityFilter
{
private LatLon m_ref = null;
internal bool DifferentFromPrevious(LatLon arg)
{
if (m_ref == null)
{
m_ref = arg;
return true;
}
var are_different = Math.Abs(arg.lat - m_ref.lat) > 0.001 || Math.Abs(arg.lon - m_ref.lon) > 0.001;
if (are_different)
m_ref = arg;
return are_different;
}
}
class Program
{
static int Main(string[] args)
{
var p1 = new LatLon { lat = 49.9429989, lon = 3.9542134 };
var p2 = new LatLon { lat = 49.9529989, lon = 3.9642134 };
var p3 = new LatLon { lat = 49.9429989, lon = 3.9542133 };
var p4 = new LatLon { lat = 49.9429989, lon = 3.9542136 };
var list = new List<LatLon> {p1, p2, p3, p4};
var filter = new ProximityFilter();
var cleaned = list.Where(filter.DifferentFromPrevious);
// ...
}
}
您不能使用Distinct
因为它会删除具有之前看到的值的点,即使它们之间存在不同的值。
此外,这种方法具有O(N)复杂性,因此至少在理论上它的性能优于Distinct
。它也适用于结构和类。