Окей, я сейчас сильно облажаюсь. Я хотел создать правильный сценарий с использованием ограничений и предупреждений (, но для меня это было проблемой; ). Но сейчас я совсем потерялся. Я просмотрел так много примеров, что совершенно запутался. Я пытаюсь рассчитать расстояние между двумя точками, используя широту/долготу. Я думаю, что эта часть покрыта расстоянием gis ::. НО проблема в том, что я пытаюсь найти пункты назначения, которые находятся в пределах 5000 м друг от друга. (и пропустите, если адресаты совпадают ). Поэтому, когда он находит пункт назначения, который находится в пределах 5000 м от другого пункта назначения, я хочу, чтобы он поместил его после последнего элемента в первом файле.
Оба входных файла одинаковы, вот как они выглядят. Оба файла имеют около 45 тыс. строк.
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, конечно. В выходной файл добавляются совпадающий пункт назначения, идентификатор пункта назначения и рассчитанное расстояние. Возможно, что для каждого адресата есть несколько совпадений. Пфф, это действительно трудно объяснить, ха-ха. Как я уже сказал, я использую 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);
---------------РЕДАКТИРОВАТЬ--------------
Ну вот и я снова. Я смотрел на ваш обновленный код, и это довольно интенсивная версия моего, ха-ха. Я честно должен сказать, что понимаю только половину. Это все еще довольно полезно;все это! Я решил придерживаться своего оригинального дизайна сценария с вашими улучшениями, но он все еще не работает. У меня есть несколько вопросов по этому поводу, если вы не возражаете:
Я сделал несколько корректировок в сценарии. Во-первых, теперь он пропускает латлоны с нулем, потому что это дало бы бесполезный результат. В той же строке он также пропускает пустые ячейки, что также бесполезно. Я сделал это для обоих файлов.
О, и там, где я сказал elements[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);