NAME

geo-latlon2place-makedb - generate database for use with Geo::LatLon2Place

SYNOPSIS

geo-latlon2place-makedb [OPTION]... inputfile.txt outputfile.cdb

DESCRIPTION

abc

OPTIONS AND ARGUMENTS

geo-latlon2place-makedb requires two arguments: a text file with geo data and the name of the database file to be written.

By default, the input file is considered to be in geonames gazetteer format, but this can be customized using --extract.

--cellsize km (default 20)

The (minimum) size of a single grid cell in km - the data is binned into cells of at least this size. It should not be larger than the search radius.

--extract geonames|geonames-postalcodes|perl...

The extraction method: the default is geonames, which expects a geonames database (https://download.geonames.org/export/dump/, for example DE.txt, cities500.txt or allCountries.txt) and extracts placename, countrycode strings from it.

The method geonames-postalcodes (not yet implemented) does the same, but for a geonames postal code database https://download.geonames.org/export/zip.

Lastly, you can specify a perl fragment that implements your own filtering and extraction.

FILTERING AND EXTRACTION

Record selection and the returned data are not fixed - you can filter your records yourself and associate any (reasonably short, the maximum is a bit above 200 octets) binary blob with a coordinate pair.

To do this, you have to provide a perl fragment that extracts latitude, longitude, a weight and the associated data blob from an input line stored in $_. The file is opened using the :perlio layer, so if your input file is in UTF-8, so will be $_.

For example, the following would expect an input file with space separated latitude, longitude, weight and name, where name can contain spaces, which is useful when you wat to provide your own input data:

geo-latlon2place-makedb --extract 'chomp; split / /, 4' input output

A slighly more verbose example expecting only latitude, longitude and a name would be:

geo-latlon2place-makedb --extract '
   chomp;
   my ($lat, $lon, $name) = split / /, 4;
   ($lat, $lon, 1, $name)
' input output

If you want to skip certain lines without adding anything to the database, you can return nothing:

geo-latlon2place-makedb --extract '
   chomp;
   my ($lat, $lon, $name) = split / /;
   return unless $lat < 0; # only add southern hemisphere points
   ($lat, $lon, 1, $name)
' input output

In general, the fragment should return either an empty list, or a four-tuple with decimal latitude, longitude, a weight (integer 0..255) and the binary data to be associated with the coordinate. Other than the weight, these should be self-explaining. The weight is used during search and will be multiplied to the square of the distance, and is used to make larger cities win over small ones when the coordinate is somewhere between them.

The geonames filter looks similar to this fragment, which shows off more possibilities:

my ($id, $name, undef, undef, $lat, $lon, $t1, $t2, $cc, undef, $a1, $s2, $a3, $a4, $pop, undef) = split /\t/;

return if $t1 ne "P"; # only places

# minimum population 200, or it is a populated place with no known population
$pop => 200
   or ($pop eq "" and $t2 eq "PPL")
   or return;

# skip certain places we are not interested in
return if $t2 eq "PPLX"; # section of populated place
return if $t2 eq "PPLW"; # destroyed populated place
return if $t2 eq "PPLH"; # historical populated place
return if $t2 eq "PPLQ"; # abandoned populated place

# geonames has a lot of very long place names which aren't
# actually place names, so ignore very long names
60 > length $name
   or return;

# we estimate a weight by dividing 25 by the radius of the place,
# which we get by assuming a fixed population density of 5000 people/km²,
# which is almost always a considerable over-estimate.
# 25 and 5000 are pretty much made-up, feel free to improve and
# send me the results.
my $w = 25 / (1 + sqrt $pop / 5000);

# administrative centers get a fixed low weight
if ($t2 =~ /^PPLA(\d*)/) {
   $w = $1 || 1;
}

($lat, $lon, $w, "$name, $cc")

AUTHOR

Marc Lehmann <schmorp@schmorp.de>

1 POD Error

The following errors were encountered while parsing the POD:

Around line 119:

Non-ASCII character seen before =encoding in 'people/km²,'. Assuming UTF-8