Nested while loop to calculate distance for multiple destinations

Oke, I feel bad right now. I wanted to create the correct script using strict rules and warnings (still a challenge for me;). But now I'm completely lost. I am considering so many examples that I am completely confused. I am trying to calculate the distance between two points using lat / lon. I think I have this part covered by gis :: distance. BUT the problem is that I'm trying to find destinations that are within 5000 meters of each other. (and skip if the destinations match). Therefore, when he finds a destination within 5000 m from another destination, I want him to place it after the last element in the first file.

Both input files are the same, this is how they look. Both files have about 45 thousand lines.

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

Let's say that these two recipients are next to each other, I try to output it like this:

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;

The actual result will correspond, of course, to more than 2. An agreed destination, destination ID and estimated distance are added to the output file. It is possible that for each recipient there are several matches. Pff it's really hard to explain haha. As I said, I use strict warnings and narrow down errors to a minimum, but still not completely. These are the errors:

Global symbol "$infile1" requires explicit package name at E:\etc.pl line 17.
Execution of E:\etc.pl aborted due to compilation errors.

This is the code I have. I also do not make heads and tails with my declarations.

Can someone help me? (this may not be the most efficient way, but at the moment it helps me understand perl more, step by step)

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);

--------------- EDIT --------------

, . , -. , , , . ; ! script , . , :

script. , latlons , . , . .

Oh [4] [5], . ne a!= . , , . , , script , . , . script, .

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
1

. .

"$ infile1" E:\etc.pl 17.

. Perl . $INFILE1. .

open my $INFILE1, '<', $inputfile1  or die "In use/Not found :$!\n";

, . , , ( INFILE1). ( 17) $INFILE1.

my @elements = split(";",$infile1);

( my), . .

, . . .  - , .

    while ( my @infile1 ){ 

while . -. @infile1 my , . , .

  • , . , :

    while (my $infile1 = <$INFILE1> ){ 
      my @elements = split(";",$infile1);
    

    . while , . , undef, . . $INFILE1 split.

    chomp , :

    while (my $infile1 = <$INFILE1> ){ 
      chomp $infile1;
      my @elements = split(";",$infile1);
    
  • seek. , . , . . my. . , :

    seek $INFILE2, 0, 0;
    
  • while:

    while (my $infile2 = <$INFILE2>){
      chomp $infile2;
      my @loopelements = split(";",$infile2);
    
  • , , 42:

    my $distance = distance($lat1, $lon1 => $lat2, $lon2);
    

    , . , => - (,). , , , -.

  • 50 .

    if (($afstand < $maxdist) and (!($elements[4] == $loopelements[4]))){     
    

    and . perldoc , . &&. , . !($a == $b), !=. , , , , ne, eq. , :

    if ($afstand < $maxdist && $elements[4] ne $loopelements[4]){
    

    , ?

  • 58 join @elements . . , - . .

  • 59 print, OUTFILE, . , $OUTFILE. join , \n , :

    print $OUTFILE join(";",@elements), "\n";
    
  • : , . :

    close($INFILE1);
    close($INFILE2);
    close($OUTFILE);
    

:

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 = <$INFILE1> ){
  chomp $infile1;
  my @elements = split(";",$infile1);

  my $lat1 = $elements[6];
  my $lon1 = $elements[7];

  $lat1 =~ s/,/./g;
  $lon1 =~ s/,/./g;

  print "1. $lat1\n";
  print "2. $lon1\n";

  seek $INFILE2, 0, 0;

  while ( my $infile2 = <$INFILE2> ){
    chomp $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 && $elements[4] ne $loopelements[4]){ 
      push (@elements, $afstand,$loopelements[4],$loopelements[5]);
      print "7. $afstand\n";
    } else {
      next;
    }
  }

  print $OUTFILE join(";",@elements), "\n";
}

close($INFILE1);
close($INFILE2);
close($OUTFILE);

, : , . , .

use strict;
use warnings;
use GIS::Distance::Lite qw(distance);
use feature qw(say);

my $inputfile1 = shift || die "first file missing";
my $inputfile2 = shift || die "second file missing";
my $outputfile = shift || die "output file missing!";

# Read the second file first
my @file2; # save the lines of INFILE2 as array refs
open my $INFILE2, '<', $inputfile2  or die "In use/Not found :$!";
while ( my $infile2 = <$INFILE2> ){ 
  chomp $infile2;
  my @loopelements = split(/;/, $infile2);

  $loopelements[6] =~ y/,/./;
  $loopelements[7] =~ y/,/./;

  push @file2, \@loopelements;
}
close($INFILE2);

open my $INFILE1, '<', $inputfile1  or die "In use/Not found :$!";
open my $OUTFILE, '>', $outputfile  or die "In use/Not found :$!";

my $maxdist = 5000;
my $mindist = 0.0001;

while (my $infile1 = <$INFILE1> ){
  chomp $infile1;
  my @elements = split(";",$infile1);

  my $lat1 = $elements[6];
  my $lon1 = $elements[7];

  $lat1 =~ y/,/./;
  $lon1 =~ y/,/./;

  say "1. $lat1";
  say "2. $lon1";

  FILE2: foreach my $loopelements ( @file2 ){
    my ($lat2, $lon2) = @$loopelements[6, 7];

    say "3. $lat2";
    say "4. $lon2";

    my $distance = distance($lat1, $lon1 => $lat2, $lon2);      # Afstand berekenen tussen latlon1 and latlon2

    say "5. $distance";

    my $afstand = sprintf("%.4f",$distance);

    say "6. $afstand";

    if ($afstand < $maxdist && $elements[4] ne $$loopelements[4]){ 
      push (@elements, $afstand, $$loopelements[4], $$loopelements[5]);
      say "7. $afstand";
    } else {
      next FILE2;
    }
  }

  say $OUTFILE join(";",@elements);
}

close($INFILE1);
close($OUTFILE);

, .

  • , use feature qw(say) . say print, . . . feature .
  • "\n" die. , . , , . Perldoc :

    LIST , script ( ) , .

  • - , . while while . @file2. ref . .

    s/// y/// ( tr///) . , . . , /g, float , .

    2. , 40k + .

  • , . . .

  • while a foreach, @file2. $lat2 $lon2 vars. (ref). , .

  • $loopelements @loopelements, ref, , $$loopelements[$index].

, , .

, , Perl , - . , , . , , . , .


Update:

, . .

file1.csv:

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

file2.csv:

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
Europe;3;France;23;Parijs;42545;48,856555;2,350976
Europe;3;France;23;Parisot;84459;44,264381;1,857827
+5

All Articles