rplantiko

Find UN/LOCODES via Fuzzy Search

Jan 10th, 2020 (edited)
1,301
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 2.39 KB | None | 0 0
  1. # UN/LOCODES zu gegebener Liste mit Ortsnamen zuordnen
  2. # Für die Ermittlung der Bezugsorte wird Fuzzy-Suche verwendet (Text::Fuzzy)
  3. # Das generierte CSV-File wird nachher in ABAP für eine DB-Aktualisierung verwendet
  4.  
  5. use open qw(:std :utf8);
  6.  
  7. use Text::CSV;
  8. use Text::Fuzzy;
  9.  
  10. my $full_list = "C:\\Temp\\code-list_csv.csv";
  11. # Volle Liste von UN/LOCODEs
  12. # Z.B. die code-list.csv via https://datahub.io/core/un-locode
  13. #CA;YAF;Asbestos Hill
  14. #CA;ABH;Ashburn
  15. #CA;YZA;Ashcroft
  16. #...
  17.  
  18. my $gegebene_orte = "C:\\Temp\\zek_incot_orte.csv";
  19. # Orte, die identifiziert werden müssen:
  20. # IT;Treviso
  21. # IN;Tuticorin
  22. # DE;Tuttlingen
  23. # ...
  24.  
  25. my $ergebnis = "C:\\Temp\\out.csv";
  26. # Ergebnis dieses Perl-Programms:
  27. # Format wie $full_list,
  28. # aber mit den Ortsnamen aus $gegebene_orte
  29. # ...
  30. # CH;ABG;Aarberg  BE
  31. # CH;ACL;Aclens  VD
  32. # DE;ALE;Albershausen
  33. # ...
  34.  
  35.  
  36. # CSV-Parser
  37. my $csv = Text::CSV->new({ sep_char => ';' });
  38.  
  39. my %code = ();
  40. my %orte = ();
  41.  
  42. open LIST, "<$full_list" or die "Can't open $full_list for reading: $!";
  43.  
  44. <LIST>; # Kopfzeile überlesen
  45.  
  46. foreach my $line (<LIST>) {
  47.   chomp $line;
  48.   if ($csv->parse($line)) {
  49.     my ($land,$code,$ort) = $csv->fields();
  50.     $ort = uc $ort;
  51.     if (not exists $orte{$land}) {
  52.       $orte{$land} = [ $ort ];
  53.     } else {
  54.       push @{$orte{$land}}, $ort;
  55.     }
  56.     $code{$land.$ort} = $code;
  57.    }
  58. }
  59. close LIST;
  60.  
  61. open ORTE, "<$gegebene_orte" or die "Can't open $gegebene_orte for reading: $!";
  62.  
  63. # Ausgabedatei mit BOM explizit als UTF-8 markieren
  64. open OUT, ">$ergebnis" or die "Can't open $ergebnis for writing: $!";
  65. print OUT "\x{feff}";  # UTF8-BOM, sonst hat ABAP zuweilen ein Problem, UTF-8 zu erkennen
  66. # Kopfzeile = Spaltenüberschriften
  67. print OUT "Land;Ortscode;Ort;Wort-Distanz\n";
  68.  
  69. foreach my $line(<ORTE>) {
  70.   chomp $line;
  71.   if ($csv->parse($line)) {
  72.     my ($land,$ort) = $csv->fields();
  73.     my $ORT = uc $ort;
  74.     my $tf = new Text::Fuzzy( $ORT );
  75.     my $nearestv = $tf->nearestv( $orte{$land} );
  76.     if ($nearestv) {
  77.       # Beispiel:
  78.       # CH;ACL;Aclens VD;4
  79.       my $dist = $tf->distance($nearestv);
  80.       $csv->say( *OUT, [ $land,$code{$land.$nearestv},$ort,$dist ] );
  81.       if ($nearestv ne $ORT) {
  82.         printf "%.3d: %s (%s) --> %s\n", $dist, $ort,$land,$nearestv;
  83.       }
  84.     } else {
  85.       printf "Ort $ort in Land $land konnte nicht zugeordnet werden\n";
  86.     }      
  87.   }
  88. }
  89. close OUT;
  90. close ORTE;
Add Comment
Please, Sign In to add comment