JNRowe

Cities and cities.py

Adapting point.py for GNU Miscfiles' city database

Cities and cities.py

Warning

The code discussed in this page is now part of the upoints project. The packages available for download include usage documentation that is kept current with the package’s interface, the text on this page isn’t updated to reflect changes in the upoints interface.

A colleague pointed me to the GNU miscfiles cities database after I posted geolocation and path cross, suggesting that it would be a useful database to support. Being that it includes five hundred places around the globe, and I already have the database installed, I have to agree.

GNU miscfiles is a package of, well miscellaneous files. It contains, amongst other things a list of world currencies, languages and the file we’re looking at today cities.dat.

In v1.4.2, the version I have installed, cities.dat contains 496 entries. The file is a simple flat Unicode database, with records separated by //, a format that would be as well suited to processing with awk as it would with Python.

ID          : 12
Type        : City
Population  :
Size        :
Name        : Alblasserwaard
 Country    : NL
 Region     :
Location    : Earth
 Longitude  :    4.833
 Latitude   :   51.867
 Elevation  :
Date        : 19961206
Entered-By  : Rob.Hooft@EMBL-Heidelberg.DE
//
ID          : 13
Type        : Pass
Population  :
Size        :
Name        : Albula Pass
 Country    :
 Region     :
Location    : Earth
 Longitude  :    9.833
 Latitude   :   46.583
 Elevation  :
Date        : 19961206
Entered-By  : Rob.Hooft@EMBL-Heidelberg.DE

You don’t need to hand process the data though, I’ve added cities.py to the upoints tarball that takes care of importing the data. When you import the entries with cities.Cities() it returns a dictionary of City objects that are children of the Trigpoint objects defined for Trigpointing and point.py

On my Gentoo desktop the cities database is installed as /usr/share/misc/cities.dat, and can be imported as simply as:

>>> from upoints import cities
>>> Cities = cities.Cities("/usr/share/misc/cities.dat")

And the imported database can be used in a variety of ways:

>>> print len(Cities), "cities"
496 cities
>>> print "Cities larger with more than 8 million people"
Cities larger with more than 8 million people
>>> for city in Cities.values():
...     if city.population > 8000000:
...         print "  ", city.name, "-", city.population
   Bombay - 8243405
   Jakarta - 9200000
   Moskwa - 8769000
   Sao Paolo - 10063110
   Tokyo - 8354615
   Mexico - 8831079
>>> print "Mountains"
Mountains
>>> for city in Cities.values():
...     if city.ptype == "Mountain":
...         print "  ", city.name
   Aconcagua
   Popocatepetl

You can recreate the database as a smoke test using the following:

>>> f = open("cities.dat", "w")
>>> f.write("\n//\n".join([str(city) for city in Cities.values()]))
>>> f.close()

unfortunately the files aren’t simply comparable using diff because of some unusual formatting in the original file, but visually scanning over the diff -w output shows that we have a correct export.

The City class inherits Trigpoint which in turn inherits Point, and therefore has all the same methods they do. This allows you to calculate distances and bearings between the City objects or any other derivative object of the parent classes. For example, you could use the dump_xearth_markers function from utils.py:

>>> from upoints.utils import dump_xearth_markers
>>> scottish_markers = dict(filter(lambda x: x[1].region == "Scotland",
...                                Cities.items()))
>>> print "\n".join(dump_xearth_markers(scottish_markers, "name"))
57.150000 -2.083000 "Aberdeen" # 1
55.950000 -3.183000 "Edinburgh" # 83
55.867000 -4.267000 "Glasgow" # 92

Take a look at the epydoc generated documentation that is included in the tarball to see what can be done.

Return to Top