在perl中,确保我的哈希只包含相距超过30英尺的纬度/经度

时间:2015-04-08 18:31:31

标签: perl hash gps latitude-longitude

编辑是为了确保问题来判断距离......我的gcdist()例程将会这样做并且常规工作(为简洁起见, )...为了测试每个foreach对另一个ll对,我需要做的更多 - ll。有没有更好的方法来比较哈希中的键彼此:

我有一个包含以下内容的哈希:

my %HASH
$HASH{"38.4486x122.7047"} = 1;
$HASH{"38.4487x122.7049"} = 10;
$HASH{"38.4489x122.7050"} = 14;
$HASH{"38.4491x122.7051"} = 20;

这个哈希主要用于确保 - 低至4分,我没有重复。我想要做的是现在确保HASH中的所有点都不在彼此30英尺范围内......(以上是测试数据,所以这些都可能不在30英尺范围内......但是你知道我的意思。)

我有一个例程,可以获得纬度/经度点之间的距离。但这是(笨拙地)我会想到的方式:

my %HASH_NEW;
foreach my $_ll_1 (sort {$a cmp $b} keys %HASH)
{
    my ($_la1,$_lo1) = split ("x",$_ll_1);
    my $keep_this_one = 1;
    foreach my $_ll_2 (sort {$a cmp $b} keys %HASH)
    {
        # so we don't compare to the current one in the loop
        next if $_ll_2 eq $_ll_1;

        my ($_la2,$_lo2) = split ("x",$_ll_2);
        if (gcdist([$_la1,$_lo1],[$_la1,$_lo1] < ~30ft)
        {
            $keep_this_one = 0;
            last;
        }

    }
    if ($keep_this_one)
    {
        $HASH_NEW{$_ll_1} = $HASH{$_ll_1};
    }
}

sub gcdist
{
    my $_ll1_arrayref = shift();
    my $_ll2_arrayref = shift();

    # get distance between $_ll1_arrayref and $_ll2_arrayref
    # return it to caller
}

现在%HASH_NEW的内容为%HASH,没有ll对在30英尺内......或者我认为这是错误的?

TIA

1 个答案:

答案 0 :(得分:3)

在列表上迭代两次是置换,但这不是你想要的。你不在乎订单。 X和Y之间的距离与Y和X之间的距离相同,没有理由计算它两次。看看使用像Algorithm::Combinatorics之类的东西来生成要测试的对。

过去,在给定距离内倾倒第一个坐标可能会产生不良结果。让我们假设4点,一个b c d,距离是:

a <-> b = 40
a <-> c = 45
a <-> d = 25
b <-> c = 40
b <-> d = 20
c <-> d = 15

按顺序迭代对并在低于所需距离30时立即转储坐标将导致:

a thrown out; it's 25 from d
b thrown out; it's 20 from d
c thrown out, it's 15 from d

虽然您可能更愿意丢弃d,因为剩下的3个点是有效的。

我会研究迭代对的组合,计算&amp;所有组合的缓存距离,然后开始一次一个地删除具有最大数量的关闭点的数据点,直到没有超过期望的数量。