Source code for safe_qgis.minimum_needs

"""**Minimum Needs Implementation.**

.. tip:: Provides minimum needs assessment for a polygon layer containing
    counts of people affected per polygon.

"""

__author__ = 'tim@linfiniti.com, ole.moller.nielsen@gmail.com'
__revision__ = '$Format:%H$'
__date__ = '20/1/2013'
__license__ = "GPL"
__copyright__ = 'Copyright 2013, Australia Indonesia Facility for '
__copyright__ += 'Disaster Reduction'

from safe.storage.core import read_layer
from safe.storage.vector import Vector
import logging

from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSignature

from qgis.core import QgsMapLayerRegistry, QgsVectorLayer

from safe_qgis.safe_interface import get_version
from safe_qgis.minimum_needs_base import Ui_MinimumNeedsBase
from safe_qgis.utilities import (addComboItemInOrder,
                                 isLayerPolygonal,
                                 isLayerPoint)

LOGGER = logging.getLogger('InaSAFE')


[docs]class MinimumNeeds(QtGui.QDialog, Ui_MinimumNeedsBase): """Dialog implementation class for the InaSAFE keywords editor.""" def __init__(self, parent): """Constructor for the dialog. Args: * parent - parent widget of this dialog. * iface - a Quantum GIS QGisAppInterface instance. Returns: not applicable. Raises: no exceptions explicitly raised. """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr( 'InaSAFE %1 Minimum Needs Tool').arg(get_version())) self.polygonLayersToCombo()
[docs] def minimum_needs(self, input_layer, population_name): """ Args input_layer: InaSAFE layer object assumed to contain population counts population_name: Attribute name that holds population count Returns InaSAFE layer with attributes for minimum needs as per Perka 7 """ needs_attributes = [] for attributes in input_layer.get_data(): attribute_dict = attributes # Get population count population = attributes[population_name] # Clean up and turn into integer if population in ['-', None]: displaced = 0 else: population = str(population).replace(',', '') try: displaced = int(population) except ValueError: QtGui.QMessageBox.information(None, self.tr('Format error'), self.tr('Please change the value of %s in ' 'attribute %s to integer format') % (population, population_name)) raise ValueError # Calculate estimated needs based on BNPB Perka 7/2008 # minimum bantuan # 400g per person per day rice = int(displaced * 2.8) # 2.5L per person per day drinking_water = int(displaced * 17.5) # 15L per person per day water = int(displaced * 105) # assume 5 people per family (not in perka) family_kits = int(displaced / 5) # 20 people per toilet toilets = int(displaced / 20) # Add to attributes attribute_dict['Beras'] = rice attribute_dict['Air minum'] = drinking_water attribute_dict['Air bersih'] = water attribute_dict['Kit keluarga'] = family_kits attribute_dict['Jamba'] = toilets # Record attributes for this feature needs_attributes.append(attribute_dict) output_layer = Vector(geometry=input_layer.get_geometry(), data=needs_attributes, projection=input_layer.get_projection()) return output_layer
[docs] def polygonLayersToCombo(self): """Populate the combo with all polygon layers loaded in QGIS.""" myRegistry = QgsMapLayerRegistry.instance() myLayers = myRegistry.mapLayers().values() myFoundFlag = False for myLayer in myLayers: myName = myLayer.name() mySource = str(myLayer.id()) #check if layer is a vector polygon layer if isLayerPolygonal(myLayer) or isLayerPoint(myLayer): myFoundFlag = True addComboItemInOrder(self.cboPolygonLayers, myName, mySource) if myFoundFlag: self.cboPolygonLayers.setCurrentIndex(0)
@pyqtSignature('int')
[docs] def on_cboPolygonLayers_currentIndexChanged(self, theIndex=None): """Automatic slot executed when the layer is changed to update fields. Args: theIndex: int - passed by the signal that triggers this slot. Returns: None. Raises: no exceptions explicitly raised.""" myLayerId = self.cboPolygonLayers.itemData(theIndex, QtCore.Qt.UserRole).toString() myLayer = QgsMapLayerRegistry.instance().mapLayer(myLayerId) myFields = myLayer.dataProvider().fieldNameMap().keys() self.cboFields.clear() for myField in myFields: addComboItemInOrder(self.cboFields, myField, myField)
[docs] def accept(self): """PRocess the layer and field and generate a new layer. .. note:: This is called on ok click. """ myIndex = self.cboFields.currentIndex() myFieldName = self.cboFields.itemData(myIndex, QtCore.Qt.UserRole).toString() myIndex = self.cboPolygonLayers.currentIndex() myLayerId = self.cboPolygonLayers.itemData(myIndex, QtCore.Qt.UserRole).toString() myLayer = QgsMapLayerRegistry.instance().mapLayer(myLayerId) myFileName = str(myLayer.source()) myInputLayer = read_layer(myFileName) try: myOutputLayer = self.minimum_needs(myInputLayer, str(myFieldName)) except ValueError: return myNewFile = myFileName[:-4] + '_perka7' + '.shp' myOutputLayer.write_to_file(myNewFile) myNewLayer = QgsVectorLayer(myNewFile, 'Minimum Needs', 'ogr') QgsMapLayerRegistry.instance().addMapLayers([myNewLayer]) self.done(QtGui.QDialog.Accepted)