def accept(self): """Process the layer and field and generate a new layer. .. note:: This is called on OK click. """ # run minimum needs calculator try: success, self.result_layer = ( self.minimum_needs(self.layer.currentLayer())) if not success: return except Exception as e: error_name, traceback = humanise_exception(e) message = ( 'Problem(s) occured. \n%s \nDiagnosis: \n%s' % ( error_name, traceback)) display_critical_message_box( title=self.tr('Error while calculating minimum needs'), message=message) return # remove monkey patching keywords del self.result_layer.keywords # write memory layer to file system settings = QSettings() default_user_directory = settings.value( 'inasafe/defaultUserDirectory', defaultValue='') if default_user_directory: output_directory = os.path.join( default_user_directory, 'minimum_needs_calculator') if not os.path.exists(output_directory): os.makedirs(output_directory) else: output_directory = temp_dir(sub_dir='minimum_needs_calculator') output_layer_name = os.path.split(self.result_layer.name())[1] # If normal filename doesn't exist, then use normal filename random_string_length = len(output_layer_name.split('_')[-1]) normal_filename = output_layer_name[:-(random_string_length + 1)] if not os.path.exists(os.path.join(output_directory, normal_filename)): output_layer_name = normal_filename data_store = Folder(output_directory) data_store.default_vector_format = 'geojson' data_store.add_layer(self.result_layer, output_layer_name) self.result_layer = data_store.layer(output_layer_name) # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers( [data_store.layer(self.result_layer.name())]) self.done(QtGui.QDialog.Accepted)
def accept(self): """Process the layer and field and generate a new layer. .. note:: This is called on OK click. """ # run minimum needs calculator try: success, self.result_layer = ( self.minimum_needs(self.layer.currentLayer())) if not success: return except Exception as e: error_name, traceback = humanise_exception(e) message = ( 'Problem(s) occured. \n%s \nDiagnosis: \n%s' % ( error_name, traceback)) display_critical_message_box( title=self.tr('Error while calculating minimum needs'), message=message) return # remove monkey patching keywords del self.result_layer.keywords # write memory layer to file system settings = QSettings() default_user_directory = settings.value( 'inasafe/defaultUserDirectory', defaultValue='') if default_user_directory: output_directory = os.path.join( default_user_directory, 'minimum_needs_calculator') if not os.path.exists(output_directory): os.makedirs(output_directory) else: output_directory = temp_dir(sub_dir='minimum_needs_calculator') output_layer_name = os.path.split(self.result_layer.name())[1] # If normal filename doesn't exist, then use normal filename random_string_length = len(output_layer_name.split('_')[-1]) normal_filename = output_layer_name[:-(random_string_length + 1)] if not os.path.exists(os.path.join(output_directory, normal_filename)): output_layer_name = normal_filename data_store = Folder(output_directory) data_store.default_vector_format = 'geojson' data_store.add_layer(self.result_layer, output_layer_name) self.result_layer = data_store.layer(output_layer_name) # noinspection PyArgumentList QgsProject.instance().addMapLayers( [data_store.layer(self.result_layer.name())]) self.done(QtWidgets.QDialog.Accepted)
def accept(self): """Process the layer and field and generate a new layer. .. note:: This is called on OK click. """ # run minimum needs calculator try: success, self.result_layer = ( self.minimum_needs(self.layer.currentLayer())) if not success: return except Exception as e: error_name, traceback = humanise_exception(e) message = ( 'Problem(s) occured. \n%s \nDiagnosis: \n%s' % ( error_name, traceback)) display_critical_message_box( title=self.tr('Error while calculating minimum needs'), message=message) return # remove monkey patching keywords del self.result_layer.keywords # write memory layer to file system settings = QSettings() default_user_directory = settings.value( 'inasafe/defaultUserDirectory', defaultValue='') if default_user_directory: path = os.path.join( default_user_directory, self.result_layer.name()) if not os.path.exists(path): os.makedirs(path) data_store = Folder(path) else: data_store = Folder(temp_dir(sub_dir=self.result_layer.name())) data_store.default_vector_format = 'geojson' data_store.add_layer(self.result_layer, self.result_layer.name()) self.result_layer = data_store.layer(self.result_layer.name()) # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers( [data_store.layer(self.result_layer.name())]) self.done(QtGui.QDialog.Accepted)
def test_empty_layer(self): """Test if we import an empty layer.""" layer = create_memory_layer( 'test', QgsWkbTypes.PolygonGeometry, QgsCoordinateReferenceSystem(3857), [ QgsField('my_field_1', QVariant.Int), QgsField('my_field_2', QVariant.Double), QgsField('my_field_3', QVariant.String) ]) self.assertTrue(layer.isValid()) self.assertEqual(len(layer.fields()), 3) # These following tests doesn't work if we add 'geosjon' in the formats # list. https://issues.qgis.org/issues/18370 formats = ['shp'] for extension in formats: path = QDir(mkdtemp()) data_store = Folder(path) data_store.default_vector_format = extension name = 'test' result, message = data_store.add_layer(layer, name) self.assertTrue(result, message) # Fetch the layer imported_layer = data_store.layer(name) self.assertTrue(imported_layer.isValid()) self.assertListEqual([f.name() for f in imported_layer.fields()], ['my_field_1', 'my_field_2', 'my_field_3'])
def rasterize_vector_layer(layer, width, height, extent): """Rasterize a vector layer to the grid given by extent and width/height. :param layer: The vector layer. :type layer: QgsVectorLayer :param width: The width of the output. :type width: int :param height: The height of the output. :type height: int :param extent: The extent to use. :type extent: QgsRectangle :return: The new raster layer. :rtype: QgsRasterLayer """ name = rasterize_steps['gdal_layer_name'] output_filename = unique_filename(prefix=name, suffix='.tif') extent_str = '%f,%f,%f,%f' % (extent.xMinimum(), extent.xMaximum(), extent.yMinimum(), extent.yMaximum()) keywords = dict(layer.keywords) # The layer is in memory, we need to save it to a file for Processing. data_store = Folder(mkdtemp()) data_store.default_vector_format = 'geojson' result = data_store.add_layer(layer, 'vector_layer') layer = data_store.layer(result[1]) assert layer.isValid() field = layer.keywords['inasafe_fields'][aggregation_id_field['key']] # ET 21/02/17. I got some issues using rasterize algorithm from Processing. # I keep it in case of we need it later. Let's use gdal command line. use_gdal_command_line = True if use_gdal_command_line: startupinfo = None if sys.platform == 'win32': # On windows, we don't want to display the bash shell. # https://github.com/inasafe/inasafe/issues/3980 startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW commands = [which('gdal_rasterize')[0]] commands += ['-a', field] commands += ['-ts', str(width), str(height)] commands += ['-ot', 'Int16'] commands += ['-a_nodata', "'-1'"] commands += [layer.source(), output_filename] LOGGER.info(' '.join(commands)) result = subprocess.check_call(commands, startupinfo=startupinfo) LOGGER.info('Result : %s' % result) else: parameters = dict() parameters['INPUT'] = layer parameters['FIELD'] = field parameters['DIMENSIONS'] = 0 # output size is given in pixels parameters['WIDTH'] = width parameters['HEIGHT'] = height parameters['RASTER_EXT'] = extent_str parameters['TFW'] = False # force generation of ESRI TFW parameters['RTYPE'] = 1 # raster type: Int16 parameters['NO_DATA'] = '-1' # nodata value parameters['COMPRESS'] = 4 # GeoTIFF compression: DEFLATE parameters['JPEGCOMPRESSION'] = 75 # JPEG compression level: 75 parameters['ZLEVEL'] = 6 # DEFLATE compression level parameters['PREDICTOR'] = 1 # predictor for JPEG/DEFLATE parameters['TILED'] = False # Tiled GeoTIFF? parameters['BIGTIFF'] = 0 # whether to make big TIFF parameters['EXTRA'] = '' # additional creation parameters parameters['OUTPUT'] = output_filename result = runalg('gdalogr:rasterize', parameters) if result is None: # Let's try be removing a new parameter added between 2.14 and 2.16 del parameters['RASTER_EXT'] result = runalg('gdalogr:rasterize', parameters) assert result is not None layer_aligned = QgsRasterLayer(output_filename, name, 'gdal') assert layer_aligned.isValid() layer_aligned.keywords = keywords layer_aligned.keywords['title'] = (rasterize_steps['output_layer_name'] % 'aggregation') layer_aligned.keywords['layer_purpose'] = ( layer_purpose_aggregation_summary['key']) del layer_aligned.keywords['inasafe_fields'] check_layer(layer_aligned) return layer_aligned
class MultiBufferDialog(QtWidgets.QDialog, FORM_CLASS): """Dialog implementation class for the InaSAFE multi buffer tool.""" def __init__(self, parent=None, iface=None, dock_widget=None): """Constructor for the multi buffer dialog. :param parent: Parent widget of this dialog. :type parent: QWidget """ QtWidgets.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr('InaSAFE Multi Buffer Tool')) icon = resources_path('img', 'icons', 'show-multi-buffer.svg') self.setWindowIcon(QtGui.QIcon(icon)) self.parent = parent self.iface = iface self.dock_widget = dock_widget self.keyword_wizard = None # output file properties initialisation self.data_store = None self.output_directory = None self.output_filename = None self.output_extension = None self.output_layer = None self.classification = [] # set icon self.add_class_button.setIcon( QIcon(resources_path('img', 'icons', 'add.svg'))) self.remove_class_button.setIcon( QIcon(resources_path('img', 'icons', 'remove.svg'))) # prepare dialog initialisation self.layer.setFilters(QgsMapLayerProxyModel.VectorLayer) self.directory_button_status() self.add_class_button_status() self.ok_button_status() self.output_form.setPlaceholderText( self.tr('[Create a temporary layer]')) self.keyword_wizard_checkbox.setChecked(True) # set signal self.layer.layerChanged.connect(self.directory_button_status) self.layer.layerChanged.connect(self.ok_button_status) self.output_form.textChanged.connect(self.ok_button_status) self.directory_button.clicked.connect( self.on_directory_button_tool_clicked) self.radius_form.valueChanged.connect(self.add_class_button_status) self.class_form.textChanged.connect(self.add_class_button_status) self.add_class_button.clicked.connect( self.populate_hazard_classification) self.add_class_button.clicked.connect(self.ok_button_status) self.remove_class_button.clicked.connect( self.remove_selected_classification) self.remove_class_button.clicked.connect(self.ok_button_status) # Set up things for context help self.help_button = self.button_box.button( QtWidgets.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Fix for issue 1699 - cancel button does nothing cancel_button = self.button_box.button( QtWidgets.QDialogButtonBox.Cancel) cancel_button.clicked.connect(self.reject) # Fix ends ok_button = self.button_box.button(QtWidgets.QDialogButtonBox.Ok) ok_button.clicked.connect(self.accept) def accept(self): """Process the layer for multi buffering and generate a new layer. .. note:: This is called on OK click. """ # set parameter from dialog input_layer = self.layer.currentLayer() output_path = self.output_form.text() radius = self.get_classification() # monkey patch keywords so layer works on multi buffering function input_layer.keywords = {'inasafe_fields': {}} # run multi buffering self.output_layer = multi_buffering(input_layer, radius) # save output layer to data store and check whether user # provide the output path. if output_path: self.output_directory, self.output_filename = ( os.path.split(output_path)) self.output_filename, self.output_extension = (os.path.splitext( self.output_filename)) # if user do not provide the output path, create a temporary file. else: self.output_directory = temp_dir(sub_dir='work') self.output_filename = (unique_filename(prefix='hazard_layer', suffix='.geojson', dir=self.output_directory)) self.output_filename = os.path.split(self.output_filename)[1] self.output_filename, self.output_extension = (os.path.splitext( self.output_filename)) self.data_store = Folder(self.output_directory) if self.output_extension == '.shp': self.data_store.default_vector_format = 'shp' elif self.output_extension == '.geojson': self.data_store.default_vector_format = 'geojson' self.data_store.add_layer(self.output_layer, self.output_filename) # add output layer to map canvas self.output_layer = self.data_store.layer(self.output_filename) QgsProject.instance().addMapLayers([self.output_layer]) self.iface.setActiveLayer(self.output_layer) self.iface.zoomToActiveLayer() self.done(QtWidgets.QDialog.Accepted) if self.keyword_wizard_checkbox.isChecked(): self.launch_keyword_wizard() @pyqtSlot() # prevents actions being handled twice def on_directory_button_tool_clicked(self): """Autoconnect slot activated when directory button is clicked.""" # noinspection PyCallByClass,PyTypeChecker # set up parameter from dialog input_path = self.layer.currentLayer().source() input_directory, self.output_filename = os.path.split(input_path) file_extension = os.path.splitext(self.output_filename)[1] self.output_filename = os.path.splitext(self.output_filename)[0] # show Qt file directory dialog output_path, __ = QtWidgets.QFileDialog.getSaveFileName( self, self.tr('Output file'), '%s_multi_buffer%s' % (os.path.join( input_directory, self.output_filename), file_extension), 'GeoJSON (*.geojson);;Shapefile (*.shp)') # set selected path to the dialog self.output_form.setText(output_path) def get_output_from_input(self): """Populate output form with default output path based on input layer. """ input_path = self.layer.currentLayer().source() output_path = (os.path.splitext(input_path)[0] + '_multi_buffer' + os.path.splitext(input_path)[1]) self.output_form.setText(output_path) def populate_hazard_classification(self): """Populate hazard classification on hazard class form.""" new_class = { 'value': self.radius_form.value(), 'name': self.class_form.text() } self.classification.append(new_class) self.classification = sorted(self.classification, key=itemgetter('value')) self.hazard_class_form.clear() for item in self.classification: new_item = '{value} - {name}'.format(value=item['value'], name=item['name']) self.hazard_class_form.addItem(new_item) self.radius_form.setValue(0) self.class_form.clear() self.ok_button_status() def remove_selected_classification(self): """Remove selected item on hazard class form.""" removed_classes = self.hazard_class_form.selectedItems() current_item = self.hazard_class_form.currentItem() removed_index = self.hazard_class_form.indexFromItem(current_item) del self.classification[removed_index.row()] for item in removed_classes: self.hazard_class_form.takeItem(self.hazard_class_form.row(item)) def get_classification(self): """Get all hazard class created by user. :return: Hazard class definition created by user. :rtype: OrderedDict """ classification_dictionary = {} for item in self.classification: classification_dictionary[item['value']] = item['name'] classification_dictionary = OrderedDict( sorted(classification_dictionary.items())) return classification_dictionary def directory_button_status(self): """Function to enable or disable directory button.""" if self.layer.currentLayer(): self.directory_button.setEnabled(True) else: self.directory_button.setEnabled(False) def add_class_button_status(self): """Function to enable or disable add class button.""" if self.class_form.text() and self.radius_form.value() >= 0: self.add_class_button.setEnabled(True) else: self.add_class_button.setEnabled(False) def ok_button_status(self): """Function to enable or disable OK button.""" if not self.layer.currentLayer(): self.button_box.button( QtWidgets.QDialogButtonBox.Ok).setEnabled(False) elif (self.hazard_class_form.count() > 0 and self.layer.currentLayer().name() and len(self.output_form.text()) >= 0): self.button_box.button( QtWidgets.QDialogButtonBox.Ok).setEnabled(True) else: self.button_box.button( QtWidgets.QDialogButtonBox.Ok).setEnabled(False) @pyqtSlot(bool) # prevents actions being handled twice def help_toggled(self, flag): """Show or hide the help tab in the stacked widget. :param flag: Flag indicating whether help should be shown or hidden. :type flag: bool """ if flag: self.help_button.setText(self.tr('Hide Help')) self.show_help() else: self.help_button.setText(self.tr('Show Help')) self.hide_help() def hide_help(self): """Hide the usage info from the user.""" self.main_stacked_widget.setCurrentIndex(1) def show_help(self): """Show usage info to the user.""" # Read the header and footer html snippets self.main_stacked_widget.setCurrentIndex(0) header = html_header() footer = html_footer() string = header message = multi_buffer_help() string += message.to_html() string += footer self.help_web_view.setHtml(string) def launch_keyword_wizard(self): """Launch keyword creation wizard.""" # make sure selected layer is the output layer if self.iface.activeLayer() != self.output_layer: return # launch wizard dialog self.keyword_wizard = WizardDialog(self.iface.mainWindow(), self.iface, self.dock_widget) self.keyword_wizard.set_keywords_creation_mode(self.output_layer) self.keyword_wizard.exec_() # modal
class MultiBufferDialog(QtGui.QDialog, FORM_CLASS): """Dialog implementation class for the InaSAFE multi buffer tool.""" def __init__(self, parent=None, iface=None, dock_widget=None): """Constructor for the multi buffer dialog. :param parent: Parent widget of this dialog. :type parent: QWidget """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr('InaSAFE Multi Buffer Tool')) self.parent = parent self.iface = iface self.dock_widget = dock_widget self.keyword_wizard = None # output file properties initialisation self.data_store = None self.output_directory = None self.output_filename = None self.output_extension = None self.output_layer = None self.classification = [] # set icon self.add_class_button.setIcon( QIcon(resources_path('img', 'icons', 'add.svg'))) self.remove_class_button.setIcon( QIcon(resources_path('img', 'icons', 'remove.svg'))) # prepare dialog initialisation self.layer.setFilters(QgsMapLayerProxyModel.VectorLayer) self.directory_button_status() self.add_class_button_status() self.ok_button_status() self.output_form.setPlaceholderText( self.tr('[Create a temporary layer]')) self.keyword_wizard_checkbox.setChecked(True) # set signal self.layer.layerChanged.connect(self.directory_button_status) self.layer.layerChanged.connect(self.ok_button_status) self.output_form.textChanged.connect(self.ok_button_status) self.directory_button.clicked.connect( self.on_directory_button_tool_clicked) self.radius_form.valueChanged.connect(self.add_class_button_status) self.class_form.textChanged.connect(self.add_class_button_status) self.add_class_button.clicked.connect( self.populate_hazard_classification) self.add_class_button.clicked.connect(self.ok_button_status) self.remove_class_button.clicked.connect( self.remove_selected_classification) self.remove_class_button.clicked.connect(self.ok_button_status) # Set up things for context help self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Fix for issue 1699 - cancel button does nothing cancel_button = self.button_box.button(QtGui.QDialogButtonBox.Cancel) cancel_button.clicked.connect(self.reject) # Fix ends ok_button = self.button_box.button(QtGui.QDialogButtonBox.Ok) ok_button.clicked.connect(self.accept) def accept(self): """Process the layer for multi buffering and generate a new layer. .. note:: This is called on OK click. """ # set parameter from dialog input_layer = self.layer.currentLayer() output_path = self.output_form.text() radius = self.get_classification() # monkey patch keywords so layer works on multi buffering function input_layer.keywords = {'inasafe_fields': {}} # run multi buffering self.output_layer = multi_buffering(input_layer, radius) # save output layer to data store and check whether user # provide the output path. if output_path: self.output_directory, self.output_filename = ( os.path.split(output_path)) self.output_filename, self.output_extension = ( os.path.splitext(self.output_filename)) # if user do not provide the output path, create a temporary file. else: self.output_directory = temp_dir(sub_dir='work') self.output_filename = ( unique_filename( prefix='hazard_layer', suffix='.geojson', dir=self.output_directory)) self.output_filename = os.path.split(self.output_filename)[1] self.output_filename, self.output_extension = ( os.path.splitext(self.output_filename)) self.data_store = Folder(self.output_directory) if self.output_extension == '.shp': self.data_store.default_vector_format = 'shp' elif self.output_extension == '.geojson': self.data_store.default_vector_format = 'geojson' self.data_store.add_layer(self.output_layer, self.output_filename) # add output layer to map canvas self.output_layer = self.data_store.layer(self.output_filename) QgsMapLayerRegistry.instance().addMapLayers( [self.output_layer]) self.iface.setActiveLayer(self.output_layer) self.iface.zoomToActiveLayer() self.done(QtGui.QDialog.Accepted) if self.keyword_wizard_checkbox.isChecked(): self.launch_keyword_wizard() @pyqtSignature('') # prevents actions being handled twice def on_directory_button_tool_clicked(self): """Autoconnect slot activated when directory button is clicked.""" # noinspection PyCallByClass,PyTypeChecker # set up parameter from dialog input_path = self.layer.currentLayer().source() input_directory, self.output_filename = os.path.split(input_path) file_extension = os.path.splitext(self.output_filename)[1] self.output_filename = os.path.splitext(self.output_filename)[0] # show Qt file directory dialog output_path = QFileDialog.getSaveFileName( self, self.tr('Output file'), '%s_multi_buffer%s' % ( os.path.join(input_directory, self.output_filename), file_extension), 'GeoJSON (*.geojson);;Shapefile (*.shp)') # set selected path to the dialog self.output_form.setText(output_path) def get_output_from_input(self): """Populate output form with default output path based on input layer. """ input_path = self.layer.currentLayer().source() output_path = ( os.path.splitext(input_path)[0] + '_multi_buffer' + os.path.splitext(input_path)[1]) self.output_form.setText(output_path) def populate_hazard_classification(self): """Populate hazard classification on hazard class form.""" new_class = { 'value': self.radius_form.value(), 'name': self.class_form.text()} self.classification.append(new_class) self.classification = sorted( self.classification, key=itemgetter('value')) self.hazard_class_form.clear() for item in self.classification: new_item = '{value} - {name}'.format( value=item['value'], name=item['name']) self.hazard_class_form.addItem(new_item) self.radius_form.setValue(0) self.class_form.clear() self.ok_button_status() def remove_selected_classification(self): """Remove selected item on hazard class form.""" removed_classes = self.hazard_class_form.selectedItems() current_item = self.hazard_class_form.currentItem() removed_index = self.hazard_class_form.indexFromItem(current_item) del self.classification[removed_index.row()] for item in removed_classes: self.hazard_class_form.takeItem( self.hazard_class_form.row(item)) def get_classification(self): """Get all hazard class created by user. :return: Hazard class definition created by user. :rtype: OrderedDict """ classification_dictionary = {} for item in self.classification: classification_dictionary[item['value']] = item['name'] classification_dictionary = OrderedDict( sorted(classification_dictionary.items())) return classification_dictionary def directory_button_status(self): """Function to enable or disable directory button.""" if self.layer.currentLayer(): self.directory_button.setEnabled(True) else: self.directory_button.setEnabled(False) def add_class_button_status(self): """Function to enable or disable add class button.""" if self.class_form.text() and self.radius_form >= 0: self.add_class_button.setEnabled(True) else: self.add_class_button.setEnabled(False) def ok_button_status(self): """Function to enable or disable OK button.""" if not self.layer.currentLayer(): self.button_box.button(QtGui.QDialogButtonBox.Ok).setEnabled(False) elif (self.hazard_class_form.count() > 0 and self.layer.currentLayer().name() and len(self.output_form.text()) >= 0): self.button_box.button(QtGui.QDialogButtonBox.Ok).setEnabled(True) else: self.button_box.button(QtGui.QDialogButtonBox.Ok).setEnabled(False) @pyqtSlot() @pyqtSignature('bool') # prevents actions being handled twice def help_toggled(self, flag): """Show or hide the help tab in the stacked widget. :param flag: Flag indicating whether help should be shown or hidden. :type flag: bool """ if flag: self.help_button.setText(self.tr('Hide Help')) self.show_help() else: self.help_button.setText(self.tr('Show Help')) self.hide_help() def hide_help(self): """Hide the usage info from the user.""" self.main_stacked_widget.setCurrentIndex(1) def show_help(self): """Show usage info to the user.""" # Read the header and footer html snippets self.main_stacked_widget.setCurrentIndex(0) header = html_header() footer = html_footer() string = header message = multi_buffer_help() string += message.to_html() string += footer self.help_web_view.setHtml(string) def launch_keyword_wizard(self): """Launch keyword creation wizard.""" # make sure selected layer is the output layer if self.iface.activeLayer() != self.output_layer: return # launch wizard dialog self.keyword_wizard = WizardDialog( self.iface.mainWindow(), self.iface, self.dock_widget) self.keyword_wizard.set_keywords_creation_mode(self.output_layer) self.keyword_wizard.exec_() # modal
def rasterize_vector_layer(layer, width, height, extent): """Rasterize a vector layer to the grid given by extent and width/height. :param layer: The vector layer. :type layer: QgsVectorLayer :param width: The width of the output. :type width: int :param height: The height of the output. :type height: int :param extent: The extent to use. :type extent: QgsRectangle :return: The new raster layer. :rtype: QgsRasterLayer """ name = rasterize_steps['gdal_layer_name'] output_filename = unique_filename(prefix=name, suffix='.tif') extent_str = '%f,%f,%f,%f' % ( extent.xMinimum(), extent.xMaximum(), extent.yMinimum(), extent.yMaximum()) keywords = dict(layer.keywords) # The layer is in memory, we need to save it to a file for Processing. data_store = Folder(mkdtemp()) data_store.default_vector_format = 'geojson' result = data_store.add_layer(layer, 'vector_layer') layer = data_store.layer(result[1]) assert layer.isValid() field = layer.keywords['inasafe_fields'][aggregation_id_field['key']] # ET 21/02/17. I got some issues using rasterize algorithm from Processing. # I keep it in case of we need it later. Let's use gdal command line. use_gdal_command_line = True if use_gdal_command_line: startupinfo = None if sys.platform == 'win32': # On windows, we don't want to display the bash shell. # https://github.com/inasafe/inasafe/issues/3980 startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW commands = [which('gdal_rasterize')[0]] commands += ['-a', field] commands += ['-ts', str(width), str(height)] commands += ['-ot', 'Int16'] commands += ['-a_nodata', "'-1'"] commands += [layer.source(), output_filename] LOGGER.info(' '.join(commands)) result = subprocess.check_call(commands, startupinfo=startupinfo) LOGGER.info('Result : %s' % result) else: parameters = dict() parameters['INPUT'] = layer parameters['FIELD'] = field parameters['DIMENSIONS'] = 0 # output size is given in pixels parameters['WIDTH'] = width parameters['HEIGHT'] = height parameters['RASTER_EXT'] = extent_str parameters['TFW'] = False # force generation of ESRI TFW parameters['RTYPE'] = 1 # raster type: Int16 parameters['NO_DATA'] = '-1' # nodata value parameters['COMPRESS'] = 4 # GeoTIFF compression: DEFLATE parameters['JPEGCOMPRESSION'] = 75 # JPEG compression level: 75 parameters['ZLEVEL'] = 6 # DEFLATE compression level parameters['PREDICTOR'] = 1 # predictor for JPEG/DEFLATE parameters['TILED'] = False # Tiled GeoTIFF? parameters['BIGTIFF'] = 0 # whether to make big TIFF parameters['EXTRA'] = '' # additional creation parameters parameters['OUTPUT'] = output_filename result = runalg('gdalogr:rasterize', parameters) if result is None: # Let's try be removing a new parameter added between 2.14 and 2.16 del parameters['RASTER_EXT'] result = runalg('gdalogr:rasterize', parameters) assert result is not None layer_aligned = QgsRasterLayer(output_filename, name, 'gdal') assert layer_aligned.isValid() layer_aligned.keywords = keywords layer_aligned.keywords['title'] = ( rasterize_steps['output_layer_name'] % 'aggregation') layer_aligned.keywords['layer_purpose'] = ( layer_purpose_aggregation_summary['key']) del layer_aligned.keywords['inasafe_fields'] check_layer(layer_aligned) return layer_aligned