Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: grid
Fetching contributors…

Cannot retrieve contributors at this time

executable file 110 lines (82 sloc) 4.082 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
#!/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()
Something went wrong with that request. Please try again.