#!/usr/bin/python """ Find the average population density of a set of GPS coordinates. """ import sys import os import site import pgdb from optparse import OptionParser # Basically, add '../src' to our path. # Needed for the imports that follow. site.addsitedir(os.path.dirname(os.path.abspath(sys.argv[0])) + '/../src') import Configuration.Defaults import ExitCodes import GPS import StringUtils import SummaryFile1 """ Parse the command line options. There's some magic involved here; otherwise, optparse woule like nothing more than to interpret GPS coordinates such as '-78.000000' as options. """ for idx, value in enumerate(sys.argv): # Please oh please don't rename this script to something which # validates as a negative float. if (StringUtils.is_negative_float(value)): sys.argv.insert(idx, '--') # We have to break here, otherwise the negative argument # will get shifted down the list, and we'll hit it again # in the next iteration of enumerate(). And then it'll # get shifted down the list... break usage = '%prog [options] ' # -h (help) Conflicts with -h HOSTNAME parser = OptionParser(usage=usage, add_help_option = False) # Use this module's docstring as the description. parser.description = __doc__.strip() parser.add_option('-h', '--host', help='The hostname/address where the database is located.', default=Configuration.Defaults.DATABASE_HOST) parser.add_option('-d', '--database', help='The database in which the population data are stored.', default=Configuration.Defaults.DATABASE_NAME) parser.add_option('-U', '--username', help='The username who has access to the database.', default=Configuration.Defaults.DATABASE_USERNAME) (options, args) = parser.parse_args() if len(args) < 2: print "\nERROR: You must supply a longitude and latitude.\n" parser.print_help() print '' # Print a newline raise SystemExit(ExitCodes.NOT_ENOUGH_ARGS) coords = GPS.Coordinates() coords.longitude = float(args[0]) coords.latitude = float(args[1]) conn = pgdb.connect(host=options.host, database=options.database, user=options.username) cursor = conn.cursor() ########### # WARNING # ########### # # Most GIS software, including PostGIS and the associated libraries, # store and manipulate GPS coordinates in (longitude, latitude) format # rather than (latitude, longitude) format. # query = """ SELECT population_density FROM (sf1_blocks INNER JOIN tiger ON sf1_blocks.tiger_blkidfp00=tiger.blkidfp00) WHERE ST_Contains(tiger.the_geom, ST_SetSRID(ST_Point(%.6f, %.6f), 4269)); """ % (coords.longitude, coords.latitude) cursor.execute(query) rows = cursor.fetchall() if len(rows) > 0: avg_density = rows[0][0] print str(avg_density) else: print 'Error: No rows returned.' print 'Did you pass (longitude, latitude) in the correct order?' raise SystemExit(ExitCodes.NO_RESULTS) conn.close()