Beispiel #1
0
    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)
Beispiel #2
0
    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))
Beispiel #3
0
    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)
Beispiel #4
0
    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)