如果不是唯一的,则略微偏移纬度

时间:2011-02-05 19:53:47

标签: c# asp.net linq maps

我有一堆事件,他们的位置是从数据库中提取的,我正在执行以下操作:

List<Place> placeList = new List<Place>();
foreach (var item in eventsList)
{
    bool coordinateExist= placeList.Where(x => x.latitude == item.Latitude && x.longitude == item.Longitude).Count()>0;
    Place place;
    if (coordinateExist)
        place = new Place() { title = item.Title, latitude = item.Latitude+0.0001, longitude = item.Longitude};
    else
        place = new Place() { title = item.Title, latitude = item.Latitude, longitude = item.Longitude};

    placeList.Add(place);
}

我有一个小问题。如果两个位置具有完全相同的纬度和经度,我想将纬度偏移最小量(相当于几米?),然后将其添加到placeList。因此,我将有一个充满独特坐标的列表。

我怎样才能很好地实现这一目标?上面的工作,但不是很好的IMO

2 个答案:

答案 0 :(得分:1)

之前我做过类似的事。棘手的部分是你可能有两个以上位置相同的地方。他们最好的解决方案是在列表上进行多次传递(从数据库中获取它们之后)。在每次传递中,您都会维护一个新的纬度/经度对列表,这些对象之前已经“看到”了,并且在您的循环中,如果某个地方占据了您之前看到过的位置,则移动它。当你终于有一个没有移动地方的通行证时,你就完成了。

答案 1 :(得分:1)

您选择执行此操作的方法取决于您希望将多少项放入列表中以及您希望列表填充速度达到多快。

如果列表非常小,您可以检查相同位置的列表,然后更新您的纬度,再次检查等。这是:

foreach (var item in eventsList)
{
    var latitude = item.Latitude;
    var longitude = item.Longitude;
    while (placeList.Any((p) => p.latitude == latitude && p.longitude == longitude))
    {
        // adjust item latitude
    }
    Place place = new Place() { title=item.Title, latitude = latitude, longitude = longitude };
    placeList.Add(place);
}

如您所能想象的那样,如果事件数量很大,则会非常昂贵,因为您必须至少为您添加的每个项目搜索整个列表一次。

如果费用过高,您可以维持HashSet纬度/经度对,并在添加项目时进行检查。想想看,你可以把它构建为HashSet,然后将其转换为列表:

class Place: IEquatable<Place>
{
    public int longitude { get; set; }
    public int latitude { get; set; }
    public string title { get; set; }

    public Place (int long, int lat, string ttl)
    {
        // initialization here
    }

    public bool Equals(Place other)
    {
        return (this.longitude == other.longitude) && (this.latitude == other.latitude);
    }
}

...
HashSet<Place> Places = new HashSet<Place>();

foreach (var item in eventsList)
{
    var place = new Place(item.Title, item.Longitude, item.Latitude);
    while (!Places.Add(place))
    {
        // Adjust place.Latitude
    }
}

// Finally, convert it to a list.
List<Place> Placelist = Places.ToList();

如果您有大量具有相同纬度/经度的事件,那么仍然存在潜在的病态行为。您可以通过在调整纬度时添加一个小的随机量来最小化这些效果。也就是说,例如,不是仅仅添加2米或其他任何东西,而是添加1到10米之间的随机量。或者,您也可能想要随机移动经度。

如果您按照@anon建议的那样做:使用重复项构建列表,然后在以后删除它们,您最终会做一些非常相似的事情。也就是说,您可能会构建HashSet个访问过的位置,并在删除欺骗时对其进行测试。