Example #1
0
    def single_field(field, field_definition):
        """Returning single field as string.

        :param field: The field property. Can be string or list of string.
        :type field: basestring, list

        :param field_definition: The definition of field.
        :type field_definition: dict

        :returns: The first element of list if only one, or the string if
            it's string.
        :rtype: basestring
        """
        if isinstance(field, list):
            if len(field) == 1:
                return field[0]
            elif len(field) == 0:
                return None
            else:
                raise MetadataConversionError(
                    'Can not convert keyword with multiple field mapping. The '
                    'field concept is %s\nThe fields are %s' %
                    (field_definition['key'], ', '.join(field)))
        else:
            return field
Example #2
0
def convert_metadata(keywords, **converter_parameters):
    """Convert metadata from version 4.3 to 3.5

    :param keywords: Metadata to be converted, in version 4.3.
    :type keywords: dict

    :param converter_parameters: Collection of parameters to convert the
        metadata properly.
    :type converter_parameters: str

    :returns: A metadata version 3.5.
    :rtype: dict
    """
    def single_field(field, field_definition):
        """Returning single field as string.

        :param field: The field property. Can be string or list of string.
        :type field: basestring, list

        :param field_definition: The definition of field.
        :type field_definition: dict

        :returns: The first element of list if only one, or the string if
            it's string.
        :rtype: basestring
        """
        if isinstance(field, list):
            if len(field) == 1:
                return field[0]
            elif len(field) == 0:
                return None
            else:
                raise MetadataConversionError(
                    'Can not convert keyword with multiple field mapping. The '
                    'field concept is %s\nThe fields are %s' %
                    (field_definition['key'], ', '.join(field)))
        else:
            return field

    if not keywords.get('keyword_version'):
        raise MetadataConversionError('No keyword version found.')
    if not keywords['keyword_version'].startswith('4'):
        raise MetadataConversionError(
            'Only able to convert metadata version 4.x. Your version is %s' %
            keywords['keyword_version'])
    new_keywords = {
        'keyword_version': '3.5',
    }
    # Properties that have the same concepts / values in both 3.5 and 4.3
    same_properties = [
        'organisation',
        'email',
        'date',
        'abstract',
        'title',
        'license',
        'url',
        'layer_purpose',
        'layer_mode',
        'layer_geometry',
        'scale',
        'source',
        'exposure',
        'exposure_unit',
        'hazard',
        'hazard_category',
        'continuous_hazard_unit',
    ]
    for same_property in same_properties:
        if keywords.get(same_property):
            new_keywords[same_property] = keywords.get(same_property)

    # Mandatory keywords
    try:
        layer_purpose = keywords['layer_purpose']
        layer_geometry = keywords['layer_geometry']
    except KeyError as e:
        raise MetadataConversionError(e)

    # No need to set value for multipart polygon and resolution
    inasafe_fields = keywords.get('inasafe_fields', {})
    inasafe_default_values = keywords.get('inasafe_default_values', {})
    if layer_purpose == layer_purpose_exposure['key']:
        exposure = keywords.get('exposure')
        if not exposure:
            raise MetadataConversionError(
                'Layer purpose is exposure but exposure is not set.')
        if inasafe_fields.get('exposure_type_field'):
            exposure_class_field = inasafe_fields.get('exposure_type_field')
            if exposure == exposure_structure['key']:
                new_keywords['structure_class_field'] = exposure_class_field
            elif exposure == exposure_road['key']:
                new_keywords['road_class_field'] = exposure_class_field
            else:
                new_keywords['field'] = exposure_class_field
        # Data type is only used in population exposure and in v4.x it is
        # always count
        if (exposure == exposure_population['key']
                and layer_geometry == layer_geometry_raster['key']):
            new_keywords['datatype'] = 'count'
        if (exposure == exposure_population['key']
                and layer_geometry == layer_geometry_polygon['key']):
            if inasafe_fields.get(exposure_name_field['key']):
                new_keywords['area_name_field'] = inasafe_fields[
                    exposure_name_field['key']]
            if inasafe_fields.get(exposure_id_field['key']):
                new_keywords['area_id_field'] = inasafe_fields[
                    exposure_id_field['key']]
        if inasafe_fields.get(population_count_field['key']):
            population_field = inasafe_fields[population_count_field['key']]
            new_keywords['population_field'] = single_field(
                population_field, population_count_field)
        if inasafe_fields.get(exposure_name_field['key']):
            new_keywords['name_field'] = inasafe_fields[
                exposure_name_field['key']]

        if keywords.get('value_map'):
            new_keywords['value_mapping'] = keywords['value_map']

    elif layer_purpose == layer_purpose_hazard['key']:
        layer_mode = keywords['layer_mode']
        hazard = keywords.get('hazard')
        if not hazard:
            raise MetadataConversionError(
                'Layer purpose is hazard but hazard is not set.')
        if hazard == hazard_volcano['key']:
            if inasafe_fields.get(hazard_name_field['key']):
                new_keywords['volcano_name_field'] = inasafe_fields[
                    hazard_name_field['key']]
        if inasafe_fields.get(hazard_value_field['key']):
            new_keywords['field'] = inasafe_fields[hazard_value_field['key']]

        # Classification and value map (depends on the exposure)
        try:
            target_exposure = converter_parameters['exposure']
        except KeyError:
            raise MetadataConversionError(
                'You should supply target exposure for this hazard.')
        if layer_mode == layer_mode_continuous['key']:
            pass
        # Classified
        else:
            classification = active_classification(keywords, target_exposure)
            value_map = active_thresholds_value_maps(keywords, target_exposure)
            if layer_geometry == layer_geometry_raster['key']:
                raster_classification = raster_classification_conversion.get(
                    classification)
                if raster_classification:
                    new_keywords[
                        'raster_hazard_classification'] = raster_classification
                    new_keywords['value_map'] = value_map
                else:
                    raise MetadataConversionError(
                        'Could not convert %s to version 3.5 '
                        'raster hazard classification' % classification)
            else:
                vector_classification = vector_classification_conversion.get(
                    classification)
                if vector_classification:
                    new_keywords[
                        'vector_hazard_classification'] = vector_classification
                    new_keywords['value_map'] = value_map
                else:
                    raise MetadataConversionError(
                        'Could not convert %s to version 3.5 '
                        'vector hazard  classification' % classification)

    elif layer_purpose == layer_purpose_aggregation['key']:
        # Fields
        if inasafe_fields.get(adult_ratio_field['key']):
            new_keywords['adult ratio attribute'] = single_field(
                inasafe_fields[adult_ratio_field['key']], adult_ratio_field)
        if inasafe_fields.get(elderly_ratio_field['key']):
            new_keywords['elderly ratio attribute'] = single_field(
                inasafe_fields[elderly_ratio_field['key']],
                elderly_ratio_field)
        if inasafe_fields.get(youth_ratio_field['key']):
            new_keywords['youth ratio attribute'] = single_field(
                inasafe_fields[youth_ratio_field['key']], youth_ratio_field)
        if inasafe_fields.get(female_ratio_field['key']):
            new_keywords['female ratio attribute'] = single_field(
                inasafe_fields[female_ratio_field['key']], female_ratio_field)
        # Notes(IS) I think people use name for the aggregation attribute
        if inasafe_fields.get(aggregation_name_field['key']):
            new_keywords['aggregation attribute'] = inasafe_fields[
                aggregation_name_field['key']]
        # Default values
        if inasafe_default_values.get(adult_ratio_field['key']):
            new_keywords['adult ratio default'] = inasafe_default_values[
                adult_ratio_field['key']]
        if inasafe_default_values.get(elderly_ratio_field['key']):
            new_keywords['elderly ratio default'] = inasafe_default_values[
                elderly_ratio_field['key']]
        if inasafe_default_values.get(youth_ratio_field['key']):
            new_keywords['youth ratio default'] = inasafe_default_values[
                youth_ratio_field['key']]
        if inasafe_default_values.get(female_ratio_field['key']):
            new_keywords['female ratio default'] = inasafe_default_values[
                female_ratio_field['key']]

    return new_keywords