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 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 field_keyword_for_the_layer(self): """Return the proper keyword for field for the current layer. :returns: the field keyword :rtype: str """ layer_purpose_key = self.step_kw_purpose.selected_purpose()['key'] if layer_purpose_key == layer_purpose_aggregation['key']: return get_compulsory_fields(layer_purpose_key)['key'] elif layer_purpose_key in [ layer_purpose_exposure['key'], layer_purpose_hazard['key']]: layer_subcategory_key = \ self.step_kw_subcategory.selected_subcategory()['key'] return get_compulsory_fields( layer_purpose_key, layer_subcategory_key)['key'] else: raise InvalidParameterError
def field_keyword_for_the_layer(self): """Return the proper keyword for field for the current layer. :returns: the field keyword :rtype: str """ layer_purpose_key = self.step_kw_purpose.selected_purpose()['key'] if layer_purpose_key == layer_purpose_aggregation['key']: return get_compulsory_fields(layer_purpose_key)['key'] elif layer_purpose_key in [ layer_purpose_exposure['key'], layer_purpose_hazard['key']]: layer_subcategory_key = \ self.step_kw_subcategory.selected_subcategory()['key'] return get_compulsory_fields( layer_purpose_key, layer_subcategory_key)['key'] else: raise InvalidParameterError
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']) compulsory_field = get_compulsory_fields( layer_purpose['key'], subcategory['key']) # It's aggregation and has field_groups. if field_groups and layer_purpose == layer_purpose_aggregation: return self.parent.step_kw_fields_mapping # It has field_groups and the compulsory field is population count. if field_groups and compulsory_field == population_count_field: 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 """ 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_compulsory_field(self): """Test get_compulsory_field method.""" compulsory_field = get_compulsory_fields('exposure', 'structure') expected_fields = exposure_structure['compulsory_fields'] self.assertListEqual([compulsory_field], expected_fields)
def _remove_features(layer): """Remove features which do not have information for InaSAFE or an invalid geometry. :param layer: The vector layer. :type layer: QgsVectorLayer """ # Get the layer purpose of the layer. layer_purpose = layer.keywords['layer_purpose'] layer_subcategory = layer.keywords.get(layer_purpose) compulsory_field = get_compulsory_fields(layer_purpose, layer_subcategory) inasafe_fields = layer.keywords['inasafe_fields'] field_name = inasafe_fields.get(compulsory_field['key']) if not field_name: msg = 'Keyword %s is missing from %s' % ( compulsory_field['key'], layer_purpose) raise InvalidKeywordsForProcessingAlgorithm(msg) index = layer.fieldNameIndex(field_name) request = QgsFeatureRequest() request.setSubsetOfAttributes([field_name], layer.pendingFields()) layer.startEditing() i = 0 for feature in layer.getFeatures(request): if isinstance(feature.attributes()[index], QPyNullVariant): if layer_purpose == 'hazard': # Remove the feature if the hazard is null. layer.deleteFeature(feature.id()) i += 1 elif layer_purpose == 'aggregation': # Put the ID if the value is null. layer.changeAttributeValue( feature.id(), index, str(feature.id())) elif layer_purpose == 'exposure': # Put an empty value, the value mapping will take care of it # in the 'other' group. layer.changeAttributeValue( feature.id(), index, '') # Check if there is en empty geometry. geometry = feature.geometry() if not geometry: layer.deleteFeature(feature.id()) i += 1 continue # Check if the geometry is empty. if geometry.isGeosEmpty(): layer.deleteFeature(feature.id()) i += 1 continue # Check if the geometry is valid. if not geometry.isGeosValid(): # polygonize can produce some invalid geometries # For instance a polygon like this, sharing a same point : # _______ # | ___|__ # | |__| | # |________| # layer.deleteFeature(feature.id()) # i += 1 pass # TODO We need to add more tests # like checking if the value is in the value_mapping. layer.commitChanges() LOGGER.debug(tr( 'Features which have been removed from %s : %s' % (layer.keywords['layer_purpose'], i)))
def _remove_features(layer): """Remove features which do not have information for InaSAFE or an invalid geometry. :param layer: The vector layer. :type layer: QgsVectorLayer """ # Get the layer purpose of the layer. layer_purpose = layer.keywords['layer_purpose'] layer_subcategory = layer.keywords.get(layer_purpose) compulsory_field = get_compulsory_fields(layer_purpose, layer_subcategory) inasafe_fields = layer.keywords['inasafe_fields'] # Compulsory fields can be list of field name or single field name. # We need to iterate through all of them field_names = inasafe_fields.get(compulsory_field['key']) if not isinstance(field_names, list): field_names = [field_names] for field_name in field_names: if not field_name: message = 'Keyword %s is missing from %s' % ( compulsory_field['key'], layer_purpose) raise InvalidKeywordsForProcessingAlgorithm(message) index = layer.fields().lookupField(field_name) request = QgsFeatureRequest() request.setSubsetOfAttributes([field_name], layer.fields()) layer.startEditing() i = 0 for feature in layer.getFeatures(request): feat_attr = feature.attributes()[index] if (feat_attr is None or (hasattr(feat_attr, 'isNull') and feat_attr.isNull())): if layer_purpose == 'hazard': # Remove the feature if the hazard is null. layer.deleteFeature(feature.id()) i += 1 elif layer_purpose == 'aggregation': # Put the ID if the value is null. layer.changeAttributeValue(feature.id(), index, str(feature.id())) elif layer_purpose == 'exposure': # Put an empty value, the value mapping will take care of # it in the 'other' group. layer.changeAttributeValue(feature.id(), index, '') # Check if there is en empty geometry. geometry = feature.geometry() if not geometry: layer.deleteFeature(feature.id()) i += 1 continue # Check if the geometry is empty. if geometry.isEmpty(): layer.deleteFeature(feature.id()) i += 1 continue # Check if the geometry is valid. if not geometry.isGeosValid(): # polygonize can produce some invalid geometries # For instance a polygon like this, sharing a same point : # _______ # | ___|__ # | |__| | # |________| # layer.deleteFeature(feature.id()) # i += 1 pass # TODO We need to add more tests # like checking if the value is in the value_mapping. layer.commitChanges() if i: LOGGER.critical('Features which have been removed from %s : %s' % (layer.keywords['layer_purpose'], i)) else: LOGGER.info( 'No feature has been removed from %s during the vector layer ' 'preparation' % layer.keywords['layer_purpose'])
def _remove_features(layer): """Remove features which do not have information for InaSAFE or an invalid geometry. :param layer: The vector layer. :type layer: QgsVectorLayer """ # Get the layer purpose of the layer. layer_purpose = layer.keywords['layer_purpose'] layer_subcategory = layer.keywords.get(layer_purpose) compulsory_field = get_compulsory_fields(layer_purpose, layer_subcategory) inasafe_fields = layer.keywords['inasafe_fields'] # Compulsory fields can be list of field name or single field name. # We need to iterate through all of them field_names = inasafe_fields.get(compulsory_field['key']) if not isinstance(field_names, list): field_names = [field_names] for field_name in field_names: if not field_name: message = 'Keyword %s is missing from %s' % ( compulsory_field['key'], layer_purpose) raise InvalidKeywordsForProcessingAlgorithm(message) index = layer.fieldNameIndex(field_name) request = QgsFeatureRequest() request.setSubsetOfAttributes([field_name], layer.pendingFields()) layer.startEditing() i = 0 for feature in layer.getFeatures(request): if isinstance(feature.attributes()[index], QPyNullVariant): if layer_purpose == 'hazard': # Remove the feature if the hazard is null. layer.deleteFeature(feature.id()) i += 1 elif layer_purpose == 'aggregation': # Put the ID if the value is null. layer.changeAttributeValue( feature.id(), index, str(feature.id())) elif layer_purpose == 'exposure': # Put an empty value, the value mapping will take care of # it in the 'other' group. layer.changeAttributeValue( feature.id(), index, '') # Check if there is en empty geometry. geometry = feature.geometry() if not geometry: layer.deleteFeature(feature.id()) i += 1 continue # Check if the geometry is empty. if geometry.isGeosEmpty(): layer.deleteFeature(feature.id()) i += 1 continue # Check if the geometry is valid. if not geometry.isGeosValid(): # polygonize can produce some invalid geometries # For instance a polygon like this, sharing a same point : # _______ # | ___|__ # | |__| | # |________| # layer.deleteFeature(feature.id()) # i += 1 pass # TODO We need to add more tests # like checking if the value is in the value_mapping. layer.commitChanges() LOGGER.debug(tr( 'Features which have been removed from %s : %s' % (layer.keywords['layer_purpose'], i)))
def test_get_compulsory_field(self): """Test get_compulsory_field method.""" compulsory_field = get_compulsory_fields('exposure', 'structure') expected_fields = exposure_structure['compulsory_fields'] self.assertListEqual([compulsory_field], expected_fields)