def __init__(self, iface, template, layer): """Constructor for the Composition Report class. :param iface: Reference to the QGIS iface object. :type iface: QgsAppInterface :param template: The QGIS template path. :type template: str """ LOGGER.debug('InaSAFE Impact Report class initialised') self._iface = iface self._template = template self._layer = layer self._extent = self._iface.mapCanvas().extent() self._page_dpi = 300.0 self._safe_logo = resources_path( 'img', 'logos', 'inasafe-logo-url.svg') self._organisation_logo = default_organisation_logo_path() self._north_arrow = default_north_arrow_path() self._disclaimer = disclaimer() # For QGIS < 2.4 compatibility # QgsMapSettings is added in 2.4 if qgis_version() < 20400: map_settings = self._iface.mapCanvas().mapRenderer() else: map_settings = self._iface.mapCanvas().mapSettings() self._template_composition = TemplateComposition( template_path=self.template, map_settings=map_settings) self._keyword_io = KeywordIO()
def test_missing_elements(self): """Test if we can get missing elements correctly.""" # Copy the inasafe template to temp dir template_path = os.path.join(temp_dir('test'), 'a4-portrait-blue.qpt') shutil.copy2(INASAFE_TEMPLATE_PATH, template_path) template_composition = TemplateComposition(template_path=template_path) # No missing elements here component_ids = [ 'white-inasafe-logo', 'north-arrow', 'organisation-logo', 'impact-map', 'impact-legend' ] template_composition.component_ids = component_ids message = 'There should be no missing elements, but it gets: %s' % ( template_composition.missing_elements) expected_result = [] self.assertEqual(template_composition.missing_elements, expected_result, message) # There are missing elements component_ids = [ 'white-inasafe-logo', 'north-arrow', 'organisation-logo', 'impact-map', 'impact-legend', 'i-added-element-id-here-nooo' ] template_composition.component_ids = component_ids message = 'There should be no missing elements, but it gets: %s' % ( template_composition.missing_elements) expected_result = ['i-added-element-id-here-nooo'] self.assertEqual(template_composition.missing_elements, expected_result, message) # Remove test dir shutil.rmtree(temp_dir('test'))
def test_constructor(self): """Test constructor.""" # If we give param map_settings, composition instance must not be none map_settings = CANVAS.mapSettings() template_composition = TemplateComposition(map_settings=map_settings) message = 'The composition instance variable must not be none.' self.assertIsNotNone(template_composition.composition, message)
def template(self, template): """Set template that will be used for report generation. :param template: Path to composer template :type template: str """ if isinstance(template, basestring) and os.path.exists(template): self._template = template else: self._template = resources_path( 'qgis-composer-templates', 'a4-portrait-blue.qpt') # Also recreate template composition self._template_composition = TemplateComposition( template_path=self.template, map_settings=self._iface.mapCanvas().mapSettings())
def test_load_template(self): """Test we can load template correctly.""" # Copy the inasafe template to temp dir template_path = os.path.join(temp_dir('test'), 'a4-portrait-blue.qpt') shutil.copy2(INASAFE_TEMPLATE_PATH, template_path) template_composition = TemplateComposition( template_path=template_path, map_settings=CANVAS.mapSettings()) template_composition.load_template() # Check the element of the composition # In that template, there should be these components: component_ids = [ 'white-inasafe-logo', 'north-arrow', 'organisation-logo', 'impact-map', 'impact-legend' ] for component_id in component_ids: component = template_composition.composition.getComposerItemById( component_id) message = ('In this template: %s, there should be this component ' '%s') % (INASAFE_TEMPLATE_PATH, component_id) self.assertIsNotNone(component, message)
def __init__(self, iface, template, layer, extra_layers=[]): """Constructor for the Composition Report class. :param iface: Reference to the QGIS iface object. :type iface: QgsAppInterface :param template: The QGIS template path. :type template: str """ LOGGER.debug('InaSAFE Impact Report class initialised') self._iface = iface self._template = None self.template = template self._layer = layer self._extra_layers = extra_layers self._extent = self._iface.mapCanvas().extent() self._page_dpi = 300.0 self._black_inasafe_logo = black_inasafe_logo_path() self._white_inasafe_logo = white_inasafe_logo_path() # User can change this path in preferences self._organisation_logo = supporters_logo_path() self._supporters_logo = supporters_logo_path() self._north_arrow = default_north_arrow_path() self._disclaimer = disclaimer() # For QGIS < 2.4 compatibility # QgsMapSettings is added in 2.4 if qgis_version() < 20400: map_settings = self._iface.mapCanvas().mapRenderer() else: map_settings = self._iface.mapCanvas().mapSettings() self._template_composition = TemplateComposition( template_path=self.template, map_settings=map_settings) self._keyword_io = KeywordIO()
def load_template(self, map_settings): """Load composer template for merged report. Validate it as well. The template needs to have: 1. QgsComposerMap with id 'impact-map' for merged impact map. 2. QgsComposerPicture with id 'safe-logo' for InaSAFE logo. 3. QgsComposerLabel with id 'summary-report' for a summary of two impacts. 4. QgsComposerLabel with id 'aggregation-area' to indicate the area of aggregation. 5. QgsComposerScaleBar with id 'map-scale' for impact map scale. 6. QgsComposerLegend with id 'map-legend' for impact map legend. 7. QgsComposerPicture with id 'organisation-logo' for organisation logo. 8. QgsComposerLegend with id 'impact-legend' for map legend. 9. QgsComposerHTML with id 'merged-report-table' for the merged report. :param map_settings: Map settings. :type map_settings: QgsMapSettings, QgsMapRenderer """ # Create Composition template_composition = TemplateComposition(self.template_path, map_settings) # Validate the component in the template component_ids = [ 'impact-map', 'safe-logo', 'summary-report', 'aggregation-area', 'map-scale', 'map-legend', 'organisation-logo', 'merged-report-table' ] template_composition.component_ids = component_ids if len(template_composition.missing_elements) > 0: raise ReportCreationError( self.tr('Components: %s could not be found' % ', '.join(template_composition.missing_elements))) # Prepare map substitution and set to composition impact_title = '%s and %s' % (self.first_impact['map_title'], self.second_impact['map_title']) substitution_map = { 'impact-title': impact_title, 'hazard-title': self.first_impact['hazard_title'], 'disclaimer': self.disclaimer } template_composition.substitution = substitution_map # Load Template try: template_composition.load_template() except TemplateLoadingError: raise # Draw Composition # Set InaSAFE logo composition = template_composition.composition safe_logo = composition.getComposerItemById('safe-logo') safe_logo.setPictureFile(self.safe_logo_path) # set organisation logo org_logo = composition.getComposerItemById('organisation-logo') org_logo.setPictureFile(self.organisation_logo_path) # Set Map Legend legend = composition.getComposerItemById('map-legend') if qgis_version() < 20400: layers = map_settings.layerSet() else: layers = map_settings.layers() if qgis_version() < 20600: legend.model().setLayerSet(layers) legend.synchronizeWithModel() else: root_group = legend.modelV2().rootGroup() layer_ids = map_settings.layers() for layer_id in layer_ids: # noinspection PyUnresolvedReferences layer = QgsMapLayerRegistry.instance().mapLayer(layer_id) root_group.addLayer(layer) legend.synchronizeWithModel() return composition