#!/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";