#!/usr/bin/perl use 5.34.0; # creates composite file from Geonames cities1000.txt, countryInfo.txt, # admin1CodesASCII.txt & admin2Codes.txt, containing only fields of interest: # lat, lon, city_name, admin1_name, admin2_name, country_code, country_name, population # ----------------------------- # 1. Load admin1 (state / county) # ----------------------------- my %admin1_map; open my $fh1, '<', 'admin1CodesASCII.txt' or die $!; while (<$fh1>) { chomp; my ($code, $name) = split /\t/; $admin1_map{$code} = $name; } close $fh1; # ----------------------------- # 2. Load admin2 (district / county) # ----------------------------- my %admin2_map; open my $fh2, '<', 'admin2Codes.txt' or die $!; while (<$fh2>) { chomp; my ($code, $name) = split /\t/; $admin2_map{$code} = $name; } close $fh2; # ----------------------------- # 3. Load country names (optional, for readable output) # ----------------------------- my %country_map; open my $fhc, '<', 'countryInfo.txt' or die "Download countryInfo.txt from GeoNames\n"; while (<$fhc>) { next if /^#/; my @f = split /\t/; my ($cc, $cname) = @f[0,4]; $country_map{$cc} = $cname; } close $fhc; # ----------------------------- # 4. Merge cities with admin1/admin2 # ----------------------------- open my $fh3, '<', 'cities1000.txt' or die $!; open my $out, '>', 'cities_full.txt' or die $!; print $out join("\t", qw(lat lon city_name admin1_name admin2_name country_code country_name population)), "\n"; while (<$fh3>) { chomp; my @f = split /\t/; my ($geoid,$name,$asciiname,$altname,$lat,$lon,$feat_class,$feat_code, $country,$cc2,$admin1,$admin2,$population) = @f[0..11,14]; my $admin1_name = $admin1_map{"$country.$admin1"} // ''; my $admin2_name = $admin2_map{"$country.$admin1.$admin2"} // ''; my $country_name = $country_map{$country} // ''; print $out join "\t", $lat, $lon, $name, $admin2_map{"$country.$admin1.$admin2"} // '', $admin1_map{"$country.$admin1"} // '', $country_map{$country} // '', $country, $population, "\n"; } close $fh3; close $out; print "Merged file written to $out\n";