Вложенный цикл while для расчета расстояния для нескольких пунктов назначения

Окей, я сейчас сильно облажаюсь. Я хотел создать правильный сценарий с использованием ограничений и предупреждений (, но для меня это было проблемой; ). Но сейчас я совсем потерялся. Я просмотрел так много примеров, что совершенно запутался. Я пытаюсь рассчитать расстояние между двумя точками, используя широту/долготу. Я думаю, что эта часть покрыта расстоянием 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);
5
задан Jan 26 July 2012 в 12:28
поделиться