Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 112 lines (82 sloc) 3.99 KB
#!/usr/bin/python
import csv
import multiprocessing
import os
import sys
import invar
DEFAULT_FRAME_ZOOM = 16
class IVFrame(invar.InvarUtility):
description = 'Render centered frames from a Mapnik2 XML configuration file. Accepts either a single latitude/longitude pair or the name of a CSV file containing appropriate columns.'
def add_arguments(self):
self.argparser.add_argument('latitude', help='Latitude to center rendering on.', type=float, nargs='?')
self.argparser.add_argument('longitude', help='Longitude to center rendering on.', type=float, nargs='?')
self.argparser.add_argument('-z', '--zoom', help="Zoom level to render.", type=int, default=DEFAULT_FRAME_ZOOM)
self.argparser.add_argument('--csv', help='A CSV file containing at latitude and longitude columns.')
self.argparser.add_argument('-n', '--name', help='The name of the output image or the name of a column in the CSV file to use as a filename (not including extension).')
def main(self):
# Get a list of tile parameter tuples to be added to the tile queue
if self.args.csv:
tile_parameters = get_tile_parameters_from_csv(self.args.csv, self.args.zoom, self.args.name)
else:
if not self.args.latitude or not self.args.longitude:
sys.exit('You must specify a latitude and longitude unless providing the name of a CSV.')
tile_parameters = [('%s.png' % (self.args.name or 'frame'), self.args.latitude, self.args.longitude, self.args.zoom)]
if not os.path.isdir(self.args.output_dir):
os.mkdir(self.args.output_dir)
tile_queue = multiprocessing.JoinableQueue()
tile_count = 0
for i, t in enumerate(tile_parameters):
tile_queue.put(t)
tile_count += 1
print 'Using %i processes to render %i tiles' % (self.args.process_count, tile_count)
processes = []
for i in range(self.args.process_count):
renderer = invar.FrameRenderer(tile_queue, self.args.config, self.args.width, self.args.height, buffer_size=self.args.buffer, skip_existing=self.args.skip_existing)
renderer.start()
processes.append(renderer)
try:
tile_queue.join()
except KeyboardInterrupt:
for p in processes:
p.terminate()
def get_tile_parameters_from_csv(filename, zoom, name_column=None):
"""
Finds latitude and longitude columns in a CSV and extracts coordinate pairs from them.
Note: this is a generator function.
"""
with open(filename, 'rU') as f:
rows = csv.reader(f)
headers = rows.next()
headers = [s.lower().strip() for s in headers]
latitude_index = None
longitude_index = None
name_index = None
for n in ['latitude', 'lat', 'y']:
if n in headers:
latitude_index = headers.index(n)
if latitude_index < 0:
sys.exit('Unable to find latitude column in CSV.')
for n in ['longitude', 'lon', 'x']:
if n in headers:
longitude_index = headers.index(n)
if longitude_index < 0:
sys.exit('Unable to find longitude column in CSV.')
if name_column:
name_index = headers.index(name_column)
if name_index < 0:
sys.exit('Column "%s" does not exist in the input CSV.' % name_column)
for i, row in enumerate(rows):
try:
latitude = float(row[latitude_index].strip())
longitude = float(row[longitude_index].strip())
except ValueError:
print 'Skipping non-numeric latitude/longitude: %s, %s' % (row[latitude_index], row[longitude_index])
continue
if name_index:
name = row[name_index]
else:
name = str(i)
yield ('%s.png' % name, latitude, longitude, zoom)
if __name__ == "__main__":
ivframe = IVFrame()
ivframe.main()