用于 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.001Math.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。

用于 GPS 数据缩减数据的 LINQ 命令

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。它也适用于结构和类。