わかりました私は今かなりひどくめちゃくちゃです。strict と warnings を使用して適切なスクリプトを作成したかった (私にとってはまだ挑戦です;)。しかし今、私は完全に迷っています。私は非常に多くの例を見てきましたが、完全に混乱しています。私がしようとしているのは、緯度/経度を使用して 2 点間の距離を計算することです。その部分は gis::distance でカバーしていると思います。しかし、問題は、互いに 5000 m 以内にある目的地を見つけようとしていることです。(宛先が同じ場合はスキップ)。したがって、別の目的地から 5000 m 以内にある目的地が見つかった場合は、最初のファイルの最後の要素の後に配置する必要があります。
どちらの入力ファイルも同じです。次のように表示されます。どちらのファイルにも約 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、および計算された距離が追加されます。各目的地に複数の一致が存在する可能性があります。うーん、これを説明するのは本当に難しいです(笑)。私が言ったように、私は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);
- - - - - - - - 編集 - - - - - - -
さて、また来ました。私はあなたの更新されたコードを見てきましたが、これは私のかなり強烈なバージョンです。私は正直言って、半分しか理解していないと言わざるを得ません。それでもかなり役に立ちます。それのすべて!私はあなたの改善で元のスクリプト設計に固執することにしましたが、まだ機能していません. 差し支えなければ、いくつか質問があります。
スクリプトにいくつかの調整を加えました。1 つ目は、latlon をゼロでスキップするようになったことです。これは、役に立たない結果になるためです。同じ行で、空のセルもスキップしますが、これも役に立ちません。私は両方のinfilesに対してこれを行いました。
ああ、要素[4]は要素[5]だと言ったので、数字になります。だから、私が間違っていなければ、!= の ne を切り替えました。しかし、2 番目のファイルをループしていないため、再び無限ループを作成したと思います。私は頑固に見えるかもしれませんが、最初に元のスクリプトを理解し、私のバージョンを実行したらすぐにあなたのバージョンに取り組みたいと思っていました. シーク機能が正常に動作していないと思います。これが今のスクリプトです。
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);