def from_counts_to_ratios(layer, callback=None): """Transform counts to ratios. Formula: ratio = subset count / total count :param layer: The vector layer. :type layer: QgsVectorLayer :param callback: A function to all to indicate progress. The function should accept params 'current' (int), 'maximum' (int) and 'step' (str). Defaults to None. :type callback: function :return: The layer with new ratios. :rtype: QgsVectorLayer .. versionadded:: 4.0 """ output_layer_name = recompute_counts_steps['output_layer_name'] processing_step = recompute_counts_steps['step_name'] exposure = definition(layer.keywords['exposure']) inasafe_fields = layer.keywords['inasafe_fields'] layer.keywords['title'] = output_layer_name if not population_count_field['key'] in inasafe_fields: # There is not a population count field. Let's skip this layer. LOGGER.info( 'Population count field {population_count_field} is not detected ' 'in the exposure. We will not compute a ratio from this field ' 'because the formula needs Population count field. Formula: ' 'ratio = subset count / total count.'.format( population_count_field=population_count_field['key'])) return layer layer.startEditing() mapping = {} non_compulsory_fields = get_non_compulsory_fields( layer_purpose_exposure['key'], exposure['key']) for count_field in non_compulsory_fields: exists = count_field['key'] in inasafe_fields if count_field['key'] in count_ratio_mapping.keys() and exists: ratio_field = definition(count_ratio_mapping[count_field['key']]) field = create_field_from_definition(ratio_field) layer.addAttribute(field) name = ratio_field['field_name'] layer.keywords['inasafe_fields'][ratio_field['key']] = name mapping[count_field['field_name']] = layer.fieldNameIndex(name) LOGGER.info( 'Count field {count_field} detected in the exposure, we are ' 'going to create a equivalent field {ratio_field} in the ' 'exposure layer.'.format(count_field=count_field['key'], ratio_field=ratio_field['key'])) else: LOGGER.info( 'Count field {count_field} not detected in the exposure. We ' 'will not compute a ratio from this field.'.format( count_field=count_field['key'])) if len(mapping) == 0: # There is not a subset count field. Let's skip this layer. layer.commitChanges() return layer for feature in layer.getFeatures(): total_count = feature[inasafe_fields[population_count_field['key']]] for count_field, index in mapping.iteritems(): count = feature[count_field] try: new_value = count / total_count except TypeError: new_value = '' layer.changeAttributeValue(feature.id(), index, new_value) layer.commitChanges() check_layer(layer) return layer
def from_counts_to_ratios(layer): """Transform counts to ratios. Formula: ratio = subset count / total count :param layer: The vector layer. :type layer: QgsVectorLayer :return: The layer with new ratios. :rtype: QgsVectorLayer .. versionadded:: 4.0 """ output_layer_name = recompute_counts_steps['output_layer_name'] exposure = definition(layer.keywords['exposure']) inasafe_fields = layer.keywords['inasafe_fields'] layer.keywords['title'] = output_layer_name if not population_count_field['key'] in inasafe_fields: # There is not a population count field. Let's skip this layer. LOGGER.info( 'Population count field {population_count_field} is not detected ' 'in the exposure. We will not compute a ratio from this field ' 'because the formula needs Population count field. Formula: ' 'ratio = subset count / total count.'.format( population_count_field=population_count_field['key'])) return layer layer.startEditing() mapping = {} non_compulsory_fields = get_non_compulsory_fields( layer_purpose_exposure['key'], exposure['key']) for count_field in non_compulsory_fields: exists = count_field['key'] in inasafe_fields if count_field['key'] in list(count_ratio_mapping.keys()) and exists: ratio_field = definition(count_ratio_mapping[count_field['key']]) field = create_field_from_definition(ratio_field) layer.addAttribute(field) name = ratio_field['field_name'] layer.keywords['inasafe_fields'][ratio_field['key']] = name mapping[count_field['field_name']] = layer.fields().lookupField( name) LOGGER.info( 'Count field {count_field} detected in the exposure, we are ' 'going to create a equivalent field {ratio_field} in the ' 'exposure layer.'.format(count_field=count_field['key'], ratio_field=ratio_field['key'])) else: LOGGER.info( 'Count field {count_field} not detected in the exposure. We ' 'will not compute a ratio from this field.'.format( count_field=count_field['key'])) if len(mapping) == 0: # There is not a subset count field. Let's skip this layer. layer.commitChanges() return layer for feature in layer.getFeatures(): total_count = feature[inasafe_fields[population_count_field['key']]] for count_field, index in list(mapping.items()): count = feature[count_field] try: # For #4669, fix always get 0 new_value = count / float(total_count) except TypeError: new_value = '' except ZeroDivisionError: new_value = 0 layer.changeAttributeValue(feature.id(), index, new_value) layer.commitChanges() check_layer(layer) return layer
def from_counts_to_ratios(layer): """Transform counts to ratios. Formula: ratio = subset count / total count :param layer: The vector layer. :type layer: QgsVectorLayer :return: The layer with new ratios. :rtype: QgsVectorLayer .. versionadded:: 4.0 """ output_layer_name = recompute_counts_steps['output_layer_name'] exposure = definition(layer.keywords['exposure']) inasafe_fields = layer.keywords['inasafe_fields'] layer.keywords['title'] = output_layer_name if not population_count_field['key'] in inasafe_fields: # There is not a population count field. Let's skip this layer. LOGGER.info( 'Population count field {population_count_field} is not detected ' 'in the exposure. We will not compute a ratio from this field ' 'because the formula needs Population count field. Formula: ' 'ratio = subset count / total count.'.format( population_count_field=population_count_field['key'])) return layer layer.startEditing() mapping = {} non_compulsory_fields = get_non_compulsory_fields( layer_purpose_exposure['key'], exposure['key']) for count_field in non_compulsory_fields: exists = count_field['key'] in inasafe_fields if count_field['key'] in list(count_ratio_mapping.keys()) and exists: ratio_field = definition(count_ratio_mapping[count_field['key']]) field = create_field_from_definition(ratio_field) layer.addAttribute(field) name = ratio_field['field_name'] layer.keywords['inasafe_fields'][ratio_field['key']] = name mapping[count_field['field_name'] ] = layer.fields().lookupField(name) LOGGER.info( 'Count field {count_field} detected in the exposure, we are ' 'going to create a equivalent field {ratio_field} in the ' 'exposure layer.'.format( count_field=count_field['key'], ratio_field=ratio_field['key'])) else: LOGGER.info( 'Count field {count_field} not detected in the exposure. We ' 'will not compute a ratio from this field.'.format( count_field=count_field['key'])) if len(mapping) == 0: # There is not a subset count field. Let's skip this layer. layer.commitChanges() return layer for feature in layer.getFeatures(): total_count = feature[inasafe_fields[population_count_field['key']]] for count_field, index in list(mapping.items()): count = feature[count_field] try: # For #4669, fix always get 0 new_value = count / float(total_count) except TypeError: new_value = '' except ZeroDivisionError: new_value = 0 layer.changeAttributeValue(feature.id(), index, new_value) layer.commitChanges() check_layer(layer) return layer
def from_counts_to_ratios(layer, callback=None): """Transform counts to ratios. Formula: ratio = subset count / total count :param layer: The vector layer. :type layer: QgsVectorLayer :param callback: A function to all to indicate progress. The function should accept params 'current' (int), 'maximum' (int) and 'step' (str). Defaults to None. :type callback: function :return: The layer with new ratios. :rtype: QgsVectorLayer .. versionadded:: 4.0 """ output_layer_name = recompute_counts_steps['output_layer_name'] processing_step = recompute_counts_steps['step_name'] exposure = definition(layer.keywords['exposure']) inasafe_fields = layer.keywords['inasafe_fields'] layer.keywords['title'] = output_layer_name if not population_count_field['key'] in inasafe_fields: # There is not a population count field. Let's skip this layer. LOGGER.info( 'Population count field {population_count_field} is not detected ' 'in the exposure. We will not compute a ratio from this field ' 'because the formula needs Population count field. Formula: ' 'ratio = subset count / total count.'.format( population_count_field=population_count_field['key'])) return layer layer.startEditing() mapping = {} non_compulsory_fields = get_non_compulsory_fields( layer_purpose_exposure['key'], exposure['key']) for count_field in non_compulsory_fields: exists = count_field['key'] in inasafe_fields if count_field['key'] in count_ratio_mapping.keys() and exists: ratio_field = definition(count_ratio_mapping[count_field['key']]) field = create_field_from_definition(ratio_field) layer.addAttribute(field) name = ratio_field['field_name'] layer.keywords['inasafe_fields'][ratio_field['key']] = name mapping[count_field['field_name']] = layer.fieldNameIndex(name) LOGGER.info( 'Count field {count_field} detected in the exposure, we are ' 'going to create a equivalent field {ratio_field} in the ' 'exposure layer.'.format( count_field=count_field['key'], ratio_field=ratio_field['key'])) else: LOGGER.info( 'Count field {count_field} not detected in the exposure. We ' 'will not compute a ratio from this field.'.format( count_field=count_field['key'])) if len(mapping) == 0: # There is not a subset count field. Let's skip this layer. layer.commitChanges() return layer for feature in layer.getFeatures(): total_count = feature[inasafe_fields[population_count_field['key']]] for count_field, index in mapping.iteritems(): count = feature[count_field] try: new_value = count / total_count except TypeError: new_value = '' layer.changeAttributeValue(feature.id(), index, new_value) layer.commitChanges() check_layer(layer) return layer