def test_add_above_layer(self): """Test we can add one layer above another - see #2322 .. versionadded:: 3.2 """ setup_scenario(self.dock, hazard='Continuous Flood', exposure='Population', function='Need evacuation', function_id='FloodEvacuationRasterHazardFunction') layer_path = join(TESTDATA, 'polygon_0.shp') new_layer = QgsVectorLayer(layer_path, 'foo', 'ogr') exposure_layer = self.dock.get_exposure_layer() add_above_layer(new_layer, exposure_layer) root = QgsProject.instance().layerTreeRoot() id_list = root.findLayerIds() self.assertIn(new_layer.id(), id_list) new_layer_position = id_list.index(new_layer.id()) existing_layer_position = id_list.index(exposure_layer.id()) self.assertEqual(new_layer_position, existing_layer_position - 1)
def test_add_above_layer(self): """Test we can add one layer above another - see #2322 .. versionadded:: 3.2 """ setup_scenario( self.dock, hazard='Continuous Flood', exposure='Population', function='Need evacuation', function_id='FloodEvacuationRasterHazardFunction') layer_path = join(TESTDATA, 'polygon_0.shp') new_layer = QgsVectorLayer(layer_path, 'foo', 'ogr') exposure_layer = self.dock.get_exposure_layer() add_above_layer(new_layer, exposure_layer) root = QgsProject.instance().layerTreeRoot() id_list = root.findLayerIds() self.assertIn(new_layer.id(), id_list) new_layer_position = id_list.index(new_layer.id()) existing_layer_position = id_list.index(exposure_layer.id()) self.assertEqual(new_layer_position, existing_layer_position - 1)
def show_results(self): """Helper function for slot activated when the process is done. .. versionchanged:: 3.4 - removed parameters. .. note:: If you update this function, please report your change to safe.gui.widgets.dock.show_results too. :returns: Provides a report for writing to the dock. :rtype: str """ qgis_exposure = self.impact_function.exposure.qgis_layer() qgis_hazard = self.impact_function.hazard.qgis_layer() qgis_aggregation = self.impact_function.aggregation.qgis_layer() safe_impact_layer = self.impact_function.impact qgis_impact_layer = read_impact_layer(safe_impact_layer) keywords = self.keyword_io.read_keywords(qgis_impact_layer) json_path = os.path.splitext(qgis_impact_layer.source())[0] + '.json' # write postprocessing report to keyword postprocessor_data = self.impact_function.postprocessor_manager.\ get_json_data(self.impact_function.aggregator.aoi_mode) post_processing_report = m.Message() if os.path.exists(json_path): with open(json_path) as json_file: impact_data = json.load( json_file, object_pairs_hook=OrderedDict) impact_data['post processing'] = postprocessor_data with open(json_path, 'w') as json_file_2: json.dump(impact_data, json_file_2, indent=2) else: post_processing_report = self.impact_function.\ postprocessor_manager.get_output( self.impact_function.aggregator.aoi_mode) keywords['postprocessing_report'] = post_processing_report.to_html( suppress_newlines=True) self.keyword_io.write_keywords(qgis_impact_layer, keywords) # Get tabular information from impact layer report = m.Message() report.add(LOGO_ELEMENT) report.add(m.Heading(self.tr('Analysis Results'), **INFO_STYLE)) # If JSON Impact Data Exist, use JSON json_path = qgis_impact_layer.source()[:-3] + 'json' LOGGER.debug('JSON Path %s' % json_path) if os.path.exists(json_path): impact_template = get_report_template(json_file=json_path) impact_report = impact_template.generate_message_report() report.add(impact_report) else: report.add(self.keyword_io.read_keywords( qgis_impact_layer, 'impact_summary')) # append postprocessing report report.add(post_processing_report.to_html()) # Layer attribution comes last report.add(impact_attribution(keywords).to_html(True)) # Get requested style for impact layer of either kind style = safe_impact_layer.get_style_info() style_type = safe_impact_layer.get_style_type() # Determine styling for QGIS layer if safe_impact_layer.is_vector: if not style: # Set default style if possible pass elif style_type == 'categorizedSymbol': LOGGER.debug('use categorized') set_vector_categorized_style(qgis_impact_layer, style) elif style_type == 'graduatedSymbol': LOGGER.debug('use graduated') set_vector_graduated_style(qgis_impact_layer, style) elif safe_impact_layer.is_raster: if not style: qgis_impact_layer.setDrawingStyle("SingleBandPseudoColor") else: setRasterStyle(qgis_impact_layer, style) else: message = self.tr( 'Impact layer %s was neither a raster or a vector layer') % ( qgis_impact_layer.source()) # noinspection PyExceptionInherit raise ReadLayerError(message) legend = self.iface.legendInterface() # Insert the aggregation output above the input aggregation layer if self.show_intermediate_layers: add_above_layer( self.impact_function.aggregator.layer, qgis_aggregation) legend.setLayerVisible(self.impact_function.aggregator.layer, True) if self.hide_exposure_flag: # Insert the impact always above the hazard add_above_layer( qgis_impact_layer, qgis_hazard) else: # Insert the impact above the hazard and the exposure if # we don't hide the exposure. See #2899 add_above_layer( qgis_impact_layer, qgis_exposure, qgis_hazard) # In QGIS 2.14.2 and GDAL 1.11.3, if the exposure is in 3857, # the impact layer is in 54004, we need to change it. See issue #2790. if qgis_exposure.crs().authid() == 'EPSG:3857': if qgis_impact_layer.crs().authid() != 'EPSG:3857': epsg_3857 = QgsCoordinateReferenceSystem(3857) qgis_impact_layer.setCrs(epsg_3857) # make sure it is active in the legend - needed since QGIS 2.4 self.iface.setActiveLayer(qgis_impact_layer) # then zoom to it if self.zoom_to_impact_flag: self.iface.zoomToActiveLayer() if self.hide_exposure_flag: exposure_layer = self.get_exposure_layer() legend.setLayerVisible(exposure_layer, False) # Make the layer visible. Might be hidden by default. See #2925 legend.setLayerVisible(qgis_impact_layer, True) # Return text to display in report panel return report
def show_results(self): """Helper function for slot activated when the process is done. .. versionchanged:: 3.4 - removed parameters. .. note:: If you update this function, please report your change to safe.gui.widgets.dock.show_results too. :returns: Provides a report for writing to the dock. :rtype: str """ qgis_exposure = self.impact_function.exposure.qgis_layer() qgis_hazard = self.impact_function.hazard.qgis_layer() qgis_aggregation = self.impact_function.aggregation.qgis_layer() safe_impact_layer = self.impact_function.impact qgis_impact_layer = read_impact_layer(safe_impact_layer) keywords = self.keyword_io.read_keywords(qgis_impact_layer) json_path = os.path.splitext(qgis_impact_layer.source())[0] + '.json' # write postprocessing report to keyword postprocessor_data = self.impact_function.postprocessor_manager.\ get_json_data(self.impact_function.aggregator.aoi_mode) post_processing_report = m.Message() if os.path.exists(json_path): with open(json_path) as json_file: impact_data = json.load(json_file, object_pairs_hook=OrderedDict) impact_data['post processing'] = postprocessor_data write_json(impact_data, json_path) else: post_processing_report = self.impact_function.\ postprocessor_manager.get_output( self.impact_function.aggregator.aoi_mode) keywords['postprocessing_report'] = post_processing_report.to_html( suppress_newlines=True) self.keyword_io.write_keywords(qgis_impact_layer, keywords) # Get tabular information from impact layer report = m.Message() report.add(LOGO_ELEMENT) report.add(m.Heading(self.tr('Analysis Results'), **INFO_STYLE)) # If JSON Impact Data Exist, use JSON json_path = qgis_impact_layer.source()[:-3] + 'json' LOGGER.debug('JSON Path %s' % json_path) if os.path.exists(json_path): impact_template = get_report_template(json_file=json_path) impact_report = impact_template.generate_message_report() report.add(impact_report) else: report.add( self.keyword_io.read_keywords(qgis_impact_layer, 'impact_summary')) # append postprocessing report report.add(post_processing_report.to_html()) # Layer attribution comes last report.add(impact_attribution(keywords).to_html(True)) # Get requested style for impact layer of either kind style = safe_impact_layer.get_style_info() style_type = safe_impact_layer.get_style_type() # Determine styling for QGIS layer if safe_impact_layer.is_vector: if not style: # Set default style if possible pass elif style_type == 'categorizedSymbol': LOGGER.debug('use categorized') set_vector_categorized_style(qgis_impact_layer, style) elif style_type == 'graduatedSymbol': LOGGER.debug('use graduated') set_vector_graduated_style(qgis_impact_layer, style) elif safe_impact_layer.is_raster: if not style: qgis_impact_layer.setDrawingStyle("SingleBandPseudoColor") else: setRasterStyle(qgis_impact_layer, style) else: message = self.tr( 'Impact layer %s was neither a raster or a vector layer') % ( qgis_impact_layer.source()) # noinspection PyExceptionInherit raise ReadLayerError(message) legend = self.iface.legendInterface() # Insert the aggregation output above the input aggregation layer if self.show_intermediate_layers: add_above_layer(self.impact_function.aggregator.layer, qgis_aggregation) legend.setLayerVisible(self.impact_function.aggregator.layer, True) if self.hide_exposure_flag: # Insert the impact always above the hazard add_above_layer(qgis_impact_layer, qgis_hazard) else: # Insert the impact above the hazard and the exposure if # we don't hide the exposure. See #2899 add_above_layer(qgis_impact_layer, qgis_exposure, qgis_hazard) # In QGIS 2.14.2 and GDAL 1.11.3, if the exposure is in 3857, # the impact layer is in 54004, we need to change it. See issue #2790. if qgis_exposure.crs().authid() == 'EPSG:3857': if qgis_impact_layer.crs().authid() != 'EPSG:3857': epsg_3857 = QgsCoordinateReferenceSystem(3857) qgis_impact_layer.setCrs(epsg_3857) # make sure it is active in the legend - needed since QGIS 2.4 self.iface.setActiveLayer(qgis_impact_layer) # then zoom to it if self.zoom_to_impact_flag: self.iface.zoomToActiveLayer() if self.hide_exposure_flag: exposure_layer = self.get_exposure_layer() legend.setLayerVisible(exposure_layer, False) # Make the layer visible. Might be hidden by default. See #2925 legend.setLayerVisible(qgis_impact_layer, True) # Return text to display in report panel return report