def render(self, config, renderer_name, output_formats, file_prefix): """Renders a job with the given rendering configuration, using the provided renderer, to the given output formats. Args: config (RenderingConfiguration): the rendering configuration object. renderer_name (string): the layout renderer to use for this rendering. output_formats (list): a list of output formats to render to, from the list of supported output formats (pdf, svgz, etc.). file_prefix (string): filename prefix for all output files. """ assert config.osmid or config.bounding_box, \ 'At least an OSM ID or a bounding box must be provided!' output_formats = map(lambda x: x.lower(), output_formats) config.i18n = i18n.install_translation(config.language, self._locale_path) LOG.info('Rendering with renderer %s in language: %s (rtl: %s).' % (renderer_name, config.i18n.language_code(), config.i18n.isrtl())) # Determine bounding box and WKT of interest if config.osmid: osmid_bbox, osmid_area \ = self.get_geographic_info(config.osmid) # Define the bbox if not already defined if not config.bounding_box: config.bounding_box \ = coords.BoundingBox.parse_wkt(osmid_bbox) # Update the polygon WKT of interest config.polygon_wkt = osmid_area else: # No OSM ID provided => use specified bbox config.polygon_wkt = config.bounding_box.as_wkt() # Make sure we have a bounding box assert config.bounding_box is not None assert config.polygon_wkt is not None osm_date = self.get_osm_database_last_update() # Create a temporary directory for all our shape files tmpdir = tempfile.mkdtemp(prefix='ocitysmap') try: LOG.debug('Rendering in temporary directory %s' % tmpdir) # Prepare the generic renderer renderer_cls = renderers.get_renderer_class_by_name(renderer_name) # Perform the actual rendering to the Cairo devices for output_format in output_formats: output_filename = '%s.%s' % (file_prefix, output_format) try: self._render_one(config, tmpdir, renderer_cls, output_format, output_filename, osm_date, file_prefix) except IndexDoesNotFitError: LOG.exception("The actual font metrics probably don't " "match those pre-computed by the renderer's" "constructor. Backtrace follows...") finally: self._cleanup_tempdir(tmpdir)
def __init__(self, config_file=None, map_areas_prefix=None, city_name=None, boundingbox=None, osmid=None, language=None): """Creates a new OCitySMap renderer instance for the given city. Args: config_file (string): location of the config file map_areas_prefix (string): map_areas table name prefix city_name (string): The name of the city we're created the map of. boundingbox (BoundingBox): An optional BoundingBox object defining the city's bounding box. If not given, OCitySMap will try to guess the bounding box from the OSM data. An UnsufficientDataError exception will be raised in the bounding box can't be guessed. osmid (integer): The OSM id of the polygon of the city to render """ optcnt = 0 for var in city_name, boundingbox, osmid: if var: optcnt += 1 assert optcnt == 1 (self.city_name, self.boundingbox, self.osmid) = (city_name, boundingbox, osmid) if self.city_name: LOG.info('OCitySMap renderer for %s.' % self.city_name) elif self.boundingbox: LOG.info('OCitySMap renderer for bounding box %s.' % self.boundingbox) else: LOG.info('OCitySMap renderer for OSMID %s.' % self.osmid) if config_file: config_files = [config_file] else: config_files = ['/etc/ocitysmap.conf', os.getenv('HOME') + '/.ocitysmap.conf'] LOG.info('Reading configuration from %s...' % ', '.join(config_files)) self.parser = ConfigParser.RawConfigParser() if not self.parser.read(config_files): raise IOError, 'Failed to load the config file' locale_path = self.parser.get('ocitysmap', 'locale_path') self.i18n = i18n.install_translation(language, locale_path) LOG.info('Rendering language: ' + self.i18n.language_code()) # Create the map_areas table name string using the provided prefix map_areas_prefix = map_areas_prefix or '' self._map_areas_table_name = '%smap_areas' % map_areas_prefix self.SELECTED_AMENITIES = [ (_(u"Places of worship"), "place_of_worship", _(u"Place of worship")), (_(u"Education"), "kindergarten", _(u"Kindergarten")), (_(u"Education"), "school", _(u"School")), (_(u"Education"), "college", _(u"College")), (_(u"Education"), "university", _(u"University")), (_(u"Education"), "library", _(u"Library")), (_(u"Public buildings"), "townhall", _(u"Town hall")), (_(u"Public buildings"), "post_office", _(u"Post office")), (_(u"Public buildings"), "public_building", _(u"Public building")), (_(u"Public buildings"), "police", _(u"Police"))] datasource = dict(self.parser.items('datasource')) LOG.info('Connecting to database %s at %s (user: %s)...' % (datasource['dbname'], datasource['host'], datasource['user'])) db = psycopg2.connect(user=datasource['user'], password=datasource['password'], host=datasource['host'], database=datasource['dbname']) # Force everything to be unicode-encoded, in case we run along # django (which loads the unicode extensions for psycopg2) db.set_client_encoding('utf8') # Set session timeout parameter (18mn) cursor = db.cursor() cursor.execute("show statement_timeout;") LOG.debug("Initial statement timeout: %s" % cursor.fetchall()[0][0]) cursor.execute("set session statement_timeout=%d;" % (STATEMENT_TIMEOUT_MINUTES*60*1000)) cursor.execute("show statement_timeout;") LOG.debug("Configured statement timeout: %s" % cursor.fetchall()[0][0]) del cursor if self.city_name: self.boundingbox = self.find_bounding_box_by_name(db, self.city_name) elif self.osmid: self.boundingbox = self.find_bounding_box_by_osmid(db, self.osmid) self.griddesc = grid.GridDescriptor(self.boundingbox, db) try: self._gen_map_areas(db) self.contour = None self.polygon = None if self.city_name: self.contour, self.polygon = \ self.get_city_contour_by_name(db, self.city_name) elif self.osmid: self.contour, self.polygon = \ self.get_city_contour_by_osmid(db, self.osmid) self.streets = self.get_streets(db, self.polygon) self.amenities = self.get_amenities(db, self.polygon) finally: LOG.debug('Restoring database state...') db.rollback() self._del_map_areas(db) LOG.info('City bounding box is %s.' % str(self.boundingbox))
def render(self, config, renderer_name, output_formats, file_prefix): """Renders a job with the given rendering configuration, using the provided renderer, to the given output formats. Args: config (RenderingConfiguration): the rendering configuration object. renderer_name (string): the layout renderer to use for this rendering. output_formats (list): a list of output formats to render to, from the list of supported output formats (pdf, svgz, etc.). file_prefix (string): filename prefix for all output files. """ assert config.osmid or config.bounding_box, \ 'At least an OSM ID or a bounding box must be provided!' output_formats = map(lambda x: x.lower(), output_formats) config.i18n = i18n.install_translation(config.language, self._locale_path) LOG.info('Rendering with renderer %s in language: %s (rtl: %s).' % (renderer_name, config.i18n.language_code(), config.i18n.isrtl())) # Determine bounding box and WKT of interest if config.osmid: osmid_bbox, osmid_area \ = self.get_geographic_info(config.osmid) # Define the bbox if not already defined if not config.bounding_box: config.bounding_box \ = coords.BoundingBox.parse_wkt(osmid_bbox) # Update the polygon WKT of interest config.polygon_wkt = osmid_area else: # No OSM ID provided => use specified bbox config.polygon_wkt = config.bounding_box.as_wkt() # Make sure we have a bounding box assert config.bounding_box is not None assert config.polygon_wkt is not None # Prepare the index try: street_index = EQNZIndex(self._db, config.polygon_wkt, config.i18n, ush_url='http://eq.org.nz', ush_category_ids=config.ush_category_ids) except IndexEmptyError: LOG.warning("Designated area leads to an empty index") street_index = None # Create a temporary directory for all our shape files tmpdir = tempfile.mkdtemp(prefix='ocitysmap') try: LOG.debug('Rendering in temporary directory %s' % tmpdir) # Prepare the generic renderer renderer_cls = renderers.get_renderer_class_by_name(renderer_name) renderer = renderer_cls(config, tmpdir, street_index) # Update the street_index to reflect the grid's actual position if renderer.grid and street_index: street_index.apply_grid(renderer.grid) # Perform the actual rendering to the Cairo devices for output_format in output_formats: output_filename = '%s.%s' % (file_prefix, output_format) try: self._render_one(renderer, output_format, output_filename) except IndexDoesNotFitError: LOG.exception("The actual font metrics probably don't " "match those pre-computed by the renderer's" "constructor. Backtrace follows...") # Also dump the CSV street index if street_index: street_index.write_to_csv(config.title, '%s.csv' % file_prefix) finally: self._cleanup_tempdir(tmpdir)
def render(self, config, renderer_name, output_formats, file_prefix): """Renders a job with the given rendering configuration, using the provided renderer, to the given output formats. Args: config (RenderingConfiguration): the rendering configuration object. renderer_name (string): the layout renderer to use for this rendering. output_formats (list): a list of output formats to render to, from the list of supported output formats (pdf, svgz, etc.). file_prefix (string): filename prefix for all output files. """ assert config.osmid or config.bounding_box, \ 'At least an OSM ID or a bounding box must be provided!' output_formats = map(lambda x: x.lower(), output_formats) config.i18n = i18n.install_translation(config.language, self._locale_path) LOG.info( 'Rendering with renderer %s in language: %s (rtl: %s).' % (renderer_name, config.i18n.language_code(), config.i18n.isrtl())) # Determine bounding box and WKT of interest if config.osmid: osmid_bbox, osmid_area \ = self.get_geographic_info(config.osmid) # Define the bbox if not already defined if not config.bounding_box: config.bounding_box \ = coords.BoundingBox.parse_wkt(osmid_bbox) # Update the polygon WKT of interest config.polygon_wkt = osmid_area else: # No OSM ID provided => use specified bbox config.polygon_wkt = config.bounding_box.as_wkt() # Make sure we have a bounding box assert config.bounding_box is not None assert config.polygon_wkt is not None osm_date = self.get_osm_database_last_update() # Create a temporary directory for all our shape files tmpdir = tempfile.mkdtemp(prefix='ocitysmap') try: LOG.debug('Rendering in temporary directory %s' % tmpdir) # Prepare the generic renderer renderer_cls = renderers.get_renderer_class_by_name(renderer_name) # Perform the actual rendering to the Cairo devices for output_format in output_formats: output_filename = '%s.%s' % (file_prefix, output_format) try: self._render_one(config, tmpdir, renderer_cls, output_format, output_filename, osm_date, file_prefix) except IndexDoesNotFitError: LOG.exception("The actual font metrics probably don't " "match those pre-computed by the renderer's" "constructor. Backtrace follows...") finally: self._cleanup_tempdir(tmpdir)