好吧,我现在搞砸了。我想使用严格和警告创建一个合适的脚本(对我来说仍然是一个挑战;)。但现在我完全迷路了。我一直在看这么多的例子,我完全糊涂了。我正在尝试使用纬度/经度计算两点之间的距离。我想我已经用 gis::distance 覆盖了那部分。但问题是我试图找到彼此相距 5000 米以内的目的地。(如果目的地相同,则跳过)。因此,当它找到一个距离另一个目的地 5000m 以内的目的地时,我希望它把它放在第一个文件中的最后一个元素之后。
两个输入文件是相同的,这是它们的外观。这两个文件都有大约 45k 行。
Europe;3;France;23;Parijs;42545;48,856555;2,350976
Europe;3;France;23;Parisot;84459;44,264381;1,857827
Europe;3;France;23;Parlan;11337;44,828976;2,172435
Europe;3;France;23;Parnac;35670;46,4533;1,4425
Europe;3;France;23;Parnans;22065;45,1097;5,1456
假设这些目的地中的 2 个彼此靠近,我试图像这样输出它:
Europe;3;France;23;Parijs;42545;48,856555;2,350976;Parlan;11337;200
Europe;3;France;23;Parisot;84459;44,264381;1,857827;
Europe;3;France;23;Parlan;11337;44,828976;2,172435;
Europe;3;France;23;Parnac;35670;46,4533;1,4425;Parisot;84459;2000;Parnans;22065;350
Europe;3;France;23;Parnans;22065;45,1097;5,1456;
实际结果当然会匹配超过 2 个。在输出文件中添加匹配的目的地、目的地 id 和计算的距离。每个目的地可能有多个匹配项。Pff 这真的很难解释哈哈。正如我所说,我正在使用 strict&warnings 并将错误缩小到最低限度,但仍不完全。这些是错误:
Global symbol "$infile1" requires explicit package name at E:\etc.pl line 17.
Execution of E:\etc.pl aborted due to compilation errors.
这是我到目前为止的代码。我的声明也没有正面或反面。
有人能帮我吗?(也许这不是最有效的方法,但现在它可以帮助我更多地理解 perl,一步一步)
use strict;
use warnings;
use GIS::Distance::Lite qw(distance);
my $inputfile1 = shift || die "Give input!\n";
my $inputfile2 = shift || die "Give more input!\n";
my $outputfile = shift || die "Give output!\n";
open my $INFILE1, '<', $inputfile1 or die "In use/Not found :$!\n";
open my $INFILE2, '<', $inputfile2 or die "In use/Not found :$!\n";
open my $OUTFILE, '>', $outputfile or die "In use/Not found :$!\n";
my $maxdist = 5000;
my $mindist = 0.0001;
while ( my @infile1 ){
my @elements = split(";",$infile1);
my $lat1 = $elements[6];
my $lon1 = $elements[7];
$lat1 =~ s/,/./g;
$lon1 =~ s/,/./g;
seek my $infile2, 0, 0;
print "1. $lat1\n";
print "2. $lon1\n";
while ( my @infile2 ){
my @loopelements = split(";",$infile2);
my $lat2 = $loopelements[6];
my $lon2 = $loopelements[7];
$lat2 =~ s/,/./g;
$lon2 =~ s/,/./g;
print "3. $lat1\n";
print "4. $lon1\n";
my $distance = distance($lat1, $lon1 => $lat2, $lon2); # Afstand berekenen tussen latlon1 and latlon2
print "5. $distance\n";
my $afstand = sprintf("%.4f",$distance);
print "6. $afstand\n";
if (($afstand < $maxdist) and (!($elements[4] == $loopelements[4]))){
push (@elements, $afstand,$loopelements[4],$loopelements[5]);
print "7. $afstand\n";
} else {
next;
}
}
@elements = join(";",@elements); # add ';' to all elements
print OUTFILE "@elements";
#if ($i == 10) {last;}
}
close(INFILE1);
close(INFILE2);
close(OUTFILE);
- - - - - - - - 编辑 - - - - - - -
嗯,我又来了。我一直在查看您更新的代码,这是我的一个非常激烈的版本哈哈。老实说,我只懂了一半。它仍然很有帮助;全部!我决定通过您的改进坚持我的原始脚本设计,但它仍然无法正常工作。如果您不介意,我有几个问题:
我在剧本中做了一些调整。第一个是它现在跳过带有零的纬度,因为这会产生无用的结果。在同一行中,它还会跳过空单元格,这也是无用的。我已经为两个 infiles 做了这个。
哦,在我说元素[4]的地方我提到了元素[5],所以它是数字。所以我把 ne 换成了 != 如果我没记错的话。但我认为我再次创建了一个无限循环,因为它没有循环通过第二个文件。我知道我可能看起来很固执,但我想先了解我的原始脚本,并在我运行我的脚本后立即开始处理你的版本。我认为搜索功能无法正常工作。这是现在的脚本。
use strict;
use warnings;
use GIS::Distance::Lite qw(distance);
my $inputfile1 = shift || die "Give input!\n";
my $inputfile2 = shift || die "Give more input!\n";
my $outputfile = shift || die "Give output!\n";
open my $INFILE1, '<', $inputfile1 or die "In use/Not found :$!\n";
open my $INFILE2, '<', $inputfile2 or die "In use/Not found :$!\n";
open my $OUTFILE, '>', $outputfile or die "In use/Not found :$!\n";
my $maxdist = 3000;
my $mindist = 0.0001;
while (my $infile1 = <$INFILE1> ){
chomp $infile1;
my @elements = split(";",$infile1);
print "1. $elements[6]\n";
print "2. $elements[7]\n";
my $lat1 = $elements[6];
my $lon1 = $elements[7];
if ((($lat1 and $lon1) ne '0') and (!($lat1 and $lon1) eq "")){
$lat1 =~ s/,/./;
$lon1 =~ s/,/./;
print "lat1: $lat1\n";
print "lon1: $lon1\n";
} else {
next;
}
print "3. $lat1\n";
print "4. $lon1\n";
seek $INFILE2, 0, 0;
while ( my $infile2 = <$INFILE2> ){
chomp $infile2;
my @loopelements = split(";",$infile2);
print "5. $elements[6]\n";
print "6. $elements[7]\n";
my $lat2 = $loopelements[6];
my $lon2 = $loopelements[7];
if ((($lat2 and $lon2) ne '0') and (!($lat2 and $lon2) eq "")){
$lat2 =~ s/,/./;
$lon2 =~ s/,/./;
print "lat2: $lat1\n";
print "lon2: $lon1\n";
} else {
next;
}
my $distance = distance($lat1, $lon1 => $lat2, $lon2); # Afstand berekenen tussen latlon1 and latlon2
print "7. $distance\n";
my $afstand = sprintf("%.4f",$distance);
print "8. $afstand\n";
if ($afstand < $maxdist && $elements[4] != $loopelements[4]){
push (@elements, $afstand, $loopelements[4],$loopelements[5]);
print "9. $afstand\n";
} else {
next;
}
}
print $OUTFILE join(";",@elements), "\n";
}
close($INFILE1);
close($INFILE2);
close($OUTFILE);