def clean_inasafe_fields(layer): """Clean inasafe_fields based on keywords. 1. Must use standard field names. 2. Sum up list of fields' value and put in the standard field name. 3. Remove un-used fields. :param layer: The layer :type layer: QgsVectorLayer """ fields = [] # Exposure if layer.keywords['layer_purpose'] == layer_purpose_exposure['key']: fields = get_fields( layer.keywords['layer_purpose'], layer.keywords['exposure']) # Hazard elif layer.keywords['layer_purpose'] == layer_purpose_hazard['key']: fields = get_fields( layer.keywords['layer_purpose'], layer.keywords['hazard']) # Aggregation elif layer.keywords['layer_purpose'] == layer_purpose_aggregation['key']: fields = get_fields( layer.keywords['layer_purpose']) # Add displaced_field definition to expected_fields # for minimum needs calculator. # If there is no displaced_field keyword, then pass try: if layer.keywords['inasafe_fields'][displaced_field['key']]: fields.append(displaced_field) except KeyError: pass expected_fields = {field['key']: field['field_name'] for field in fields} # Convert the field name and sum up if needed new_keywords = {} for key, val in layer.keywords.get('inasafe_fields').iteritems(): if key in expected_fields: if isinstance(val, basestring): val = [val] sum_fields(layer, key, val) new_keywords[key] = expected_fields[key] # Houra, InaSAFE keywords match our concepts ! layer.keywords['inasafe_fields'].update(new_keywords) to_remove = [] # Remove unnecessary fields (the one that is not in the inasafe_fields) for field in layer.fields().toList(): if field.name() not in layer.keywords['inasafe_fields'].values(): to_remove.append(field.name()) remove_fields(layer, to_remove) LOGGER.debug( 'Fields which have been removed from %s : %s' % (layer.keywords['layer_purpose'], ' '.join(to_remove)))
def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep """ if self.parent.get_layer_geometry_key() == \ layer_geometry_raster['key']: return self.parent.step_kw_source layer_purpose = self.parent.step_kw_purpose.selected_purpose() if layer_purpose['key'] != layer_purpose_aggregation['key']: subcategory = self.parent.step_kw_subcategory. \ selected_subcategory() else: subcategory = {'key': None} # Get all fields with replace_null = False inasafe_fields = get_fields( layer_purpose['key'], subcategory['key'], replace_null=False, in_group=False ) # remove compulsory field since it has been set in previous step try: inasafe_fields.remove(get_compulsory_fields( layer_purpose['key'], subcategory['key'])) except ValueError: pass # Check if possible to skip inasafe field step if skip_inasafe_field(self.parent.layer, inasafe_fields): default_inasafe_fields = get_fields( layer_purpose['key'], subcategory['key'], replace_null=True, in_group=False ) # Check if it can go to inasafe default step if default_inasafe_fields: return self.parent.step_kw_default_inasafe_fields # Else, go to source step else: return self.parent.step_kw_source # If not possible to skip inasafe field step, then go there else: return self.parent.step_kw_inasafe_fields
def test_get_fields(self): """Test get_fields method.""" fields = get_fields('exposure', 'structure') expected_fields = deepcopy(exposure_structure['compulsory_fields']) expected_fields += exposure_structure['fields'] expected_fields += exposure_structure['extra_fields'] expected_fields += fields_in_field_groups( layer_purpose_exposure['field_groups']) self.assertListEqual(fields, expected_fields) fields = get_fields('hazard', 'flood') expected_fields = deepcopy(hazard_flood['compulsory_fields']) expected_fields += hazard_flood['fields'] expected_fields += hazard_flood['extra_fields'] self.assertListEqual(fields, expected_fields) fields = get_fields('hazard') expected_fields = deepcopy(hazard_fields) self.assertListEqual(fields, expected_fields) fields = get_fields('exposure') expected_fields = deepcopy(exposure_fields) expected_fields += fields_in_field_groups( layer_purpose_exposure['field_groups']) self.assertListEqual(fields, expected_fields) fields = get_fields('aggregation') expected_fields = deepcopy(aggregation_fields) expected_fields += fields_in_field_groups( layer_purpose_aggregation['field_groups']) self.assertListEqual(fields, expected_fields) fields = get_fields('aggregation', replace_null=True) expected_fields = deepcopy(aggregation_fields) expected_fields += fields_in_field_groups( layer_purpose_aggregation['field_groups']) expected_fields = [f for f in expected_fields if f['replace_null']] self.assertListEqual(fields, expected_fields) fields = get_fields( layer_purpose_exposure['key'], exposure_land_cover['key'], replace_null=False) expected_fields = deepcopy(exposure_land_cover['compulsory_fields']) expected_fields += deepcopy(exposure_fields) expected_fields += [ productivity_rate_field, production_cost_rate_field, production_value_rate_field ] self.assertListEqual(fields, expected_fields) fields = get_fields('aggregation', replace_null=False) expected_fields = deepcopy(aggregation_fields) expected_fields += fields_in_field_groups( layer_purpose_aggregation['field_groups']) expected_fields = [f for f in expected_fields if not f['replace_null']] self.assertListEqual(fields, expected_fields)
def test_get_fields(self): """Test get_fields method.""" fields = get_fields('exposure', 'structure') expected_fields = deepcopy(exposure_structure['compulsory_fields']) expected_fields += exposure_structure['fields'] expected_fields += exposure_structure['extra_fields'] expected_fields += fields_in_field_groups( layer_purpose_exposure['field_groups']) self.assertListEqual(fields, expected_fields) fields = get_fields('hazard', 'flood') expected_fields = deepcopy(hazard_flood['compulsory_fields']) expected_fields += hazard_flood['fields'] expected_fields += hazard_flood['extra_fields'] self.assertListEqual(fields, expected_fields) fields = get_fields('hazard') expected_fields = deepcopy(hazard_fields) self.assertListEqual(fields, expected_fields) fields = get_fields('exposure') expected_fields = deepcopy(exposure_fields) expected_fields += fields_in_field_groups( layer_purpose_exposure['field_groups']) self.assertListEqual(fields, expected_fields) fields = get_fields('aggregation') expected_fields = deepcopy(aggregation_fields) expected_fields += fields_in_field_groups( layer_purpose_aggregation['field_groups']) self.assertListEqual(fields, expected_fields) fields = get_fields('aggregation', replace_null=True) expected_fields = deepcopy(aggregation_fields) expected_fields += fields_in_field_groups( layer_purpose_aggregation['field_groups']) expected_fields = [f for f in expected_fields if f['replace_null']] self.assertListEqual(fields, expected_fields) fields = get_fields( layer_purpose_exposure['key'], exposure_land_cover['key'], replace_null=False) expected_fields = deepcopy(exposure_land_cover['compulsory_fields']) expected_fields += deepcopy(exposure_fields) expected_fields += [ productivity_rate_field, production_cost_rate_field, production_value_rate_field ] self.assertListEqual(fields, expected_fields) fields = get_fields('aggregation', replace_null=False) expected_fields = deepcopy(aggregation_fields) expected_fields += fields_in_field_groups( layer_purpose_aggregation['field_groups']) expected_fields = [f for f in expected_fields if not f['replace_null']] self.assertListEqual(fields, expected_fields)
def inasafe_fields_for_the_layer(self): """Return a list of inasafe fields the current layer. :returns: A list where each value represents inasafe field. :rtype: list """ if (self.parent.get_layer_geometry_key() == layer_geometry_raster['key']): return [] # Get hazard or exposure value layer_purpose_key = self.parent.step_kw_purpose.selected_purpose( )['key'] if layer_purpose_key != layer_purpose_aggregation['key']: subcategory_key = self.parent.step_kw_subcategory.\ selected_subcategory()['key'] else: subcategory_key = None # Get all fields with replace_null = True inasafe_fields = get_fields(layer_purpose_key, subcategory_key, replace_null=True, in_group=False) # remove compulsory field since it has been set in previous step try: inasafe_fields.remove( get_compulsory_fields(layer_purpose_key, subcategory_key)) except ValueError: pass return inasafe_fields
def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to. :rtype: WizardStep instance or None """ if self.parent.get_layer_geometry_key() == \ layer_geometry_raster['key']: return self.parent.step_kw_source layer_purpose = self.parent.step_kw_purpose.selected_purpose() if layer_purpose['key'] != layer_purpose_aggregation['key']: subcategory = self.parent.step_kw_subcategory. \ selected_subcategory() else: subcategory = {'key': None} # Check if it can go to inasafe field step non_compulsory_fields = get_non_compulsory_fields( layer_purpose['key'], subcategory['key']) if not skip_inasafe_field(self.parent.layer, non_compulsory_fields): return self.parent.step_kw_inasafe_fields # Check if it can go to inasafe default field step default_inasafe_fields = get_fields( layer_purpose['key'], subcategory['key'], replace_null=True, in_group=False ) if default_inasafe_fields: return self.parent.step_kw_default_inasafe_fields # Any other case return self.parent.step_kw_source
def inasafe_fields_for_the_layer(self): """Return a list of inasafe fields the current layer. :returns: A list where each value represents inasafe field. :rtype: list """ if (self.parent.get_layer_geometry_key() == layer_geometry_raster['key']): return [] # Get hazard or exposure value layer_purpose_key = self.parent.step_kw_purpose.selected_purpose()[ 'key'] if layer_purpose_key != layer_purpose_aggregation['key']: subcategory_key = self.parent.step_kw_subcategory.\ selected_subcategory()['key'] else: subcategory_key = None # Get all fields with replace_null = False inasafe_fields = get_fields( layer_purpose_key, subcategory_key, replace_null=False, in_group=False) # remove compulsory field since it has been set in previous step try: inasafe_fields.remove(get_compulsory_fields( layer_purpose_key, subcategory_key)) except ValueError: pass return inasafe_fields
def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to. :rtype: WizardStep instance or None """ if self.parent.get_layer_geometry_key() == \ layer_geometry_raster['key']: return self.parent.step_kw_source layer_purpose = self.parent.step_kw_purpose.selected_purpose() if layer_purpose['key'] != layer_purpose_aggregation['key']: subcategory = self.parent.step_kw_subcategory. \ selected_subcategory() else: subcategory = {'key': None} # Check if it can go to inasafe field step non_compulsory_fields = get_non_compulsory_fields( layer_purpose['key'], subcategory['key']) if not skip_inasafe_field(self.parent.layer, non_compulsory_fields): return self.parent.step_kw_inasafe_fields # Check if it can go to inasafe default field step default_inasafe_fields = get_fields( layer_purpose['key'], subcategory['key'], replace_null=True, in_group=False ) if default_inasafe_fields: return self.parent.step_kw_default_inasafe_fields # Any other case return self.parent.step_kw_source
def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep instance or None """ layer_purpose = self.parent.step_kw_purpose.selected_purpose() if layer_purpose['key'] != layer_purpose_aggregation['key']: subcategory = self.parent.step_kw_subcategory. \ selected_subcategory() else: subcategory = {'key': None} # We don't use field mapping for populated place exposure. Use the # population point instead. # inasafe_fields = self.get_inasafe_fields() # If population field is set, must go to field mapping step first. # if population_count_field['key'] in inasafe_fields.keys(): # return self.parent.step_kw_fields_mapping # Check if it can go to inasafe default field step default_inasafe_fields = get_fields(layer_purpose['key'], subcategory['key'], replace_null=True, in_group=False) if default_inasafe_fields: return self.parent.step_kw_default_inasafe_fields # Any other case return self.parent.step_kw_source
def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep """ layer_purpose = self.parent.step_kw_purpose.selected_purpose() if layer_purpose != layer_purpose_aggregation: subcategory = self.parent.step_kw_subcategory.\ selected_subcategory() else: subcategory = {'key': None} # Has classifications, go to multi classifications if subcategory.get('classifications'): if layer_purpose == layer_purpose_hazard: return self.parent.step_kw_multi_classifications elif layer_purpose == layer_purpose_exposure: return self.parent.step_kw_classification # Check if it can go to inasafe field step non_compulsory_fields = get_non_compulsory_fields( layer_purpose['key'], subcategory['key']) if not skip_inasafe_field(self.parent.layer, non_compulsory_fields): return self.parent.step_kw_inasafe_fields # Check if it can go to inasafe default field step default_inasafe_fields = get_fields( layer_purpose['key'], subcategory['key'], replace_null=True) if default_inasafe_fields: return self.parent.step_kw_default_inasafe_fields # Any other case return self.parent.step_kw_source
def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep """ layer_purpose = self.parent.step_kw_purpose.selected_purpose() if layer_purpose != layer_purpose_aggregation: subcategory = self.parent.step_kw_subcategory.\ selected_subcategory() else: subcategory = {'key': None} # Has layer groups, go to field mapping field_groups = get_field_groups( layer_purpose['key'], subcategory['key']) if field_groups: return self.parent.step_kw_fields_mapping # Has classifications, go to multi classifications if subcategory.get('classifications'): if layer_purpose == layer_purpose_hazard: return self.parent.step_kw_multi_classifications elif layer_purpose == layer_purpose_exposure: return self.parent.step_kw_classification # Check if it can go to inasafe field step non_compulsory_fields = get_non_compulsory_fields( layer_purpose['key'], subcategory['key']) if not skip_inasafe_field(self.parent.layer, non_compulsory_fields): return self.parent.step_kw_inasafe_fields # Check if it can go to inasafe default field step default_inasafe_fields = get_fields( layer_purpose['key'], subcategory['key'], replace_null=True, in_group=False) if default_inasafe_fields: return self.parent.step_kw_default_inasafe_fields # Any other case return self.parent.step_kw_source
def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep """ layer_purpose = self.parent.step_kw_purpose.selected_purpose() if layer_purpose != layer_purpose_aggregation: subcategory = self.parent.step_kw_subcategory.\ selected_subcategory() else: subcategory = {'key': None} # Has classifications, go to multi classifications if subcategory.get('classifications'): if layer_purpose == layer_purpose_hazard: return self.parent.step_kw_multi_classifications # Check if it can go to inasafe field step non_compulsory_fields = get_non_compulsory_fields( layer_purpose['key'], subcategory['key']) if not skip_inasafe_field(self.parent.layer, non_compulsory_fields): # Do not go to InaSAFE Field step if we already visited it. # For example in place exposure. if (self.parent.step_kw_inasafe_fields not in self.parent.keyword_steps): return self.parent.step_kw_inasafe_fields # Check if it can go to inasafe default field step default_inasafe_fields = get_fields( layer_purpose['key'], subcategory['key'], replace_null=True, in_group=False) if default_inasafe_fields: return self.parent.step_kw_default_inasafe_fields # Any other case return self.parent.step_kw_source
def rename_remove_inasafe_fields(layer): """Loop over fields and rename fields which are used in InaSAFE. :param layer: The layer :type layer: QgsVectorLayer """ # Exposure if layer.keywords['layer_purpose'] == layer_purpose_exposure['key']: fields = get_fields( layer.keywords['layer_purpose'], layer.keywords['exposure']) # Hazard elif layer.keywords['layer_purpose'] == layer_purpose_hazard['key']: fields = get_fields( layer.keywords['layer_purpose'], layer.keywords['hazard']) # Aggregation elif layer.keywords['layer_purpose'] == layer_purpose_aggregation['key']: fields = get_fields( layer.keywords['layer_purpose']) # Add displaced_field definition to expected_fields # for minimum needs calculator. # If there is no displaced_field keyword, then pass try: if layer.keywords['inasafe_fields'][displaced_field['key']]: fields.append(displaced_field) except KeyError: pass expected_fields = {field['key']: field['field_name'] for field in fields} # Rename fields to_rename = {} new_keywords = {} for key, val in layer.keywords.get('inasafe_fields').iteritems(): if key in expected_fields: if expected_fields[key] != val: to_rename[val] = expected_fields[key] new_keywords[key] = expected_fields[key] copy_fields(layer, to_rename) to_remove = to_rename.keys() LOGGER.debug( 'Fields which have been renamed from %s :' % ( layer.keywords['layer_purpose'])) for old_name, new_name in to_rename.iteritems(): LOGGER.debug('%s -> %s' % (old_name, new_name)) # Houra, InaSAFE keywords match our concepts ! layer.keywords['inasafe_fields'].update(new_keywords) # Remove unnecessary fields for field in layer.fields().toList(): if field.name() not in expected_fields.values(): if field.name() not in to_remove: to_remove.append(field.name()) remove_fields(layer, to_remove) LOGGER.debug( 'Fields which have been removed from %s : %s' % (layer.keywords['layer_purpose'], ' '.join(to_remove)))