Пример #1
0
class ImpactLayerMetadata(BaseMetadata):
    """
    Metadata class for impact layers

    if you need to add a standard XML property that only applies to this
    subclass, do it this way. @property and @propname.setter will be
    generated automatically

    _standard_properties = {
        'TESTprop': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'gco:CharacterString')
    }
    from safe.metadata35.utils import merge_dictionaries
    _standard_properties = merge_dictionaries(
        BaseMetadata._standard_properties, _standard_properties)

    .. versionadded:: 3.2
    """

    # remember to add an attribute or a setter property with the same name
    # these are properties that need special getters and setters thus are
    # not put in the standard_properties
    _standard_properties = {
        'elapsed_time': ('gmd:identificationInfo/'
                         'gmd:MD_DataIdentification/'
                         'gmd:supplementalInformation/'
                         'inasafe/'
                         'elapsed_time/'
                         'gco:Integer'),
        'hazard_title': ('gmd:identificationInfo/'
                         'gmd:MD_DataIdentification/'
                         'gmd:supplementalInformation/'
                         'inasafe/'
                         'hazard_title/'
                         'gco:CharacterString'),
        'postprocessing_report': ('gmd:identificationInfo/'
                                  'gmd:MD_DataIdentification/'
                                  'gmd:supplementalInformation/'
                                  'inasafe/'
                                  'postprocessing_report/'
                                  'gco:CharacterString'),
        'exposure_title': ('gmd:identificationInfo/'
                           'gmd:MD_DataIdentification/'
                           'gmd:supplementalInformation/'
                           'inasafe/'
                           'exposure_title/'
                           'gco:CharacterString'),
        'legend_title': ('gmd:identificationInfo/'
                         'gmd:MD_DataIdentification/'
                         'gmd:supplementalInformation/'
                         'inasafe/'
                         'legend_title/'
                         'gco:CharacterString'),
        'legend_notes': ('gmd:identificationInfo/'
                         'gmd:MD_DataIdentification/'
                         'gmd:supplementalInformation/'
                         'inasafe/'
                         'legend_notes/'
                         'gco:CharacterString'),
        'exposure_source': ('gmd:identificationInfo/'
                            'gmd:MD_DataIdentification/'
                            'gmd:supplementalInformation/'
                            'inasafe/'
                            'exposure_source/'
                            'gco:CharacterString'),
        'map_title': ('gmd:identificationInfo/'
                      'gmd:MD_DataIdentification/'
                      'gmd:supplementalInformation/'
                      'inasafe/'
                      'map_title/'
                      'gco:CharacterString'),
        'legend_units': ('gmd:identificationInfo/'
                         'gmd:MD_DataIdentification/'
                         'gmd:supplementalInformation/'
                         'inasafe/'
                         'legend_units/'
                         'gco:CharacterString'),
        'impact_summary': ('gmd:identificationInfo/'
                           'gmd:MD_DataIdentification/'
                           'gmd:supplementalInformation/'
                           'inasafe/'
                           'impact_summary/'
                           'gco:CharacterString'),
        'user': ('gmd:identificationInfo/'
                 'gmd:MD_DataIdentification/'
                 'gmd:supplementalInformation/'
                 'inasafe/'
                 'user/'
                 'gco:CharacterString'),
        'host_name': ('gmd:identificationInfo/'
                      'gmd:MD_DataIdentification/'
                      'gmd:supplementalInformation/'
                      'inasafe/'
                      'host_name/'
                      'gco:CharacterString'),
        'time_stamp': ('gmd:identificationInfo/'
                       'gmd:MD_DataIdentification/'
                       'gmd:supplementalInformation/'
                       'inasafe/'
                       'time_stamp/'
                       'gco:CharacterString'),
        'hazard_source': ('gmd:identificationInfo/'
                          'gmd:MD_DataIdentification/'
                          'gmd:supplementalInformation/'
                          'inasafe/'
                          'hazard_source/'
                          'gco:CharacterString'),
        'target_field': ('gmd:identificationInfo/'
                         'gmd:MD_DataIdentification/'
                         'gmd:supplementalInformation/'
                         'inasafe/'
                         'target_field/'
                         'gco:CharacterString'),
        'impact_table': ('gmd:identificationInfo/'
                         'gmd:MD_DataIdentification/'
                         'gmd:supplementalInformation/'
                         'inasafe/'
                         'impact_table/'
                         'gco:CharacterString'),
    }
    _standard_properties = merge_dictionaries(
        BaseMetadata._standard_properties, _standard_properties)

    _special_properties = {
        'provenance': ('gmd:identificationInfo/'
                       'gmd:MD_DataIdentification/'
                       'gmd:supplementalInformation/'
                       'inasafe_provenance')
    }

    def __init__(self, layer_uri, xml_uri=None, json_uri=None):
        """
        Constructor

        :param layer_uri: uri of the layer for which the metadata ae
        :type layer_uri: str
        :param xml_uri: uri of an xml file to use
        :type xml_uri: str
        :param json_uri: uri of a json file to use
        :type json_uri: str
        """

        # Initialise members
        # private members
        self._provenance = Provenance()

        # public members
        self.summary_data = None

        # initialize base class
        super(ImpactLayerMetadata, self).__init__(layer_uri, xml_uri, json_uri)

    @property
    def dict(self):
        """
        calls the overridden method and adds provenance and summary data

        :return: dictionary representation of the metadata
        :rtype: dict
        """
        metadata = super(ImpactLayerMetadata, self).dict

        metadata['provenance'] = self.provenance
        metadata['summary_data'] = self.summary_data

        return metadata

    @property
    def json(self):
        """
        json representation of the metadata

        :return: json representation of the metadata
        :rtype: str
        """
        metadata = self.dict

        metadata['provenance'] = self.provenance.dict
        json_dumps = json.dumps(metadata,
                                indent=2,
                                sort_keys=True,
                                separators=(',', ': '),
                                cls=MetadataEncoder)
        if not json_dumps.endswith('\n'):
            json_dumps += '\n'
        return json_dumps

    def read_json(self):
        """
        read metadata from json and set all the found properties.

        :return: the read metadata
        :rtype: dict
        """
        with reading_ancillary_files(self):
            metadata = super(ImpactLayerMetadata, self).read_json()
            if 'provenance' in metadata:
                for provenance_step in metadata['provenance']:
                    try:
                        title = provenance_step['title']
                        if 'IF Provenance' in title:
                            self.append_if_provenance_step(
                                provenance_step['title'],
                                provenance_step['description'],
                                provenance_step['time'],
                                provenance_step['data'])
                        else:
                            self.append_provenance_step(
                                provenance_step['title'],
                                provenance_step['description'],
                                provenance_step['time'],
                            )
                    except KeyError:
                        # we want to get as much as we can without raising
                        # errors
                        pass
            if 'summary_data' in metadata:
                self.summary_data = metadata['summary_data']

        return metadata

    @property
    def xml(self):
        """
        xml representation of the metadata.

        :return: xml representation of the metadata
        :rtype: ElementTree.Element
        """

        root = super(ImpactLayerMetadata, self).xml
        provenance_path = self._special_properties['provenance']
        provenance_element = root.find(provenance_path, XML_NS)

        # find the provenance parent tag
        if provenance_element is not None:
            # there is already a provenance tag so we remove it
            provenance_parent = provenance_element.getparent()
            provenance_parent.remove(provenance_element)
        else:
            # find the parent using the provenance path minus one level
            provenance_parent = '/'.join(provenance_path.split('/')[:-1])
            provenance_parent = root.find(provenance_parent, XML_NS)

        # generate the provenance xml element
        provenance_element = ElementTree.fromstring(self.provenance.xml)
        provenance_parent.append(provenance_element)
        return prettify_xml(ElementTree.tostring(root))

    def read_xml(self):
        """
        read metadata from xml and set all the found properties.

        :return: the root element of the xml
        :rtype: ElementTree.Element
        """

        with reading_ancillary_files(self):
            root = super(ImpactLayerMetadata, self).read_xml()
            if root is not None:
                self._read_provenance_from_xml(root)
        return root

    def _read_provenance_from_xml(self, root):
        """
        read metadata provenance from xml.

        :param root: container in which we search
        :type root: ElementTree.Element
        """
        path = self._special_properties['provenance']
        provenance = root.find(path, XML_NS)
        for step in provenance.iter('provenance_step'):
            title = step.find('title').text
            description = step.find('description').text
            timestamp = step.get('timestamp')

            if 'IF Provenance' in title:
                data = {}
                from safe.metadata35.provenance import IFProvenanceStep
                keys = IFProvenanceStep.impact_functions_fields
                for key in keys:
                    value = step.find(key)
                    if value is not None:
                        data[key] = value.text
                    else:
                        data[key] = ''
                self.append_if_provenance_step(title, description, timestamp,
                                               data)
            else:
                self.append_provenance_step(title, description, timestamp)

    @property
    def provenance(self):
        """
        Get the provenance elements of the metadata

        there is no setter as provenance can only grow. use
        append_provenance_step to add steps

        :return: The provenance element
        :rtype: Provenance
        """
        return self._provenance

    def append_provenance_step(self, title, description, timestamp=None):
        """
        Add a step to the provenance of the metadata

        :param title: The title of the step.
        :type title: str

        :param description: The content of the step
        :type description: str

        :param timestamp: the time of the step
        :type timestamp: datetime, str
        """
        step_time = self._provenance.append_step(title, description, timestamp)
        if step_time > self.last_update:
            self.last_update = step_time

    def append_if_provenance_step(self,
                                  title,
                                  description,
                                  timestamp=None,
                                  data=None):
        """Add a if provenance step to the provenance of the metadata

        :param title: The title of the step.
        :type title: str

        :param description: The content of the step
        :type description: str

        :param timestamp: the time of the step
        :type timestamp: datetime, str

        :param data: The data of the step.
        :type data: dict
        """
        step_time = self._provenance.append_if_provenance_step(
            title, description, timestamp, data)
        if step_time > self.last_update:
            self.last_update = step_time

    def update_from_dict(self, keywords):
        """Update metadata value from a keywords dictionary.

        :param keywords:
        :return:
        """
        super(ImpactLayerMetadata, self).update_from_dict(keywords)

        if 'if_provenance' in keywords.keys():
            if_provenance = keywords['if_provenance']
            for provenance_step in if_provenance:
                self.provenance.append_provenance_step(provenance_step)
Пример #2
0
class HazardLayerMetadata(GenericLayerMetadata):
    """
    Metadata class for hazard layers

    .. versionadded:: 3.2
    """

    _standard_properties = {
        'hazard': ('gmd:identificationInfo/'
                   'gmd:MD_DataIdentification/'
                   'gmd:supplementalInformation/'
                   'inasafe/'
                   'hazard/'
                   'gco:CharacterString'),
        'hazard_category': ('gmd:identificationInfo/'
                            'gmd:MD_DataIdentification/'
                            'gmd:supplementalInformation/'
                            'inasafe/'
                            'hazard_category/'
                            'gco:CharacterString'),
        'continuous_hazard_unit': ('gmd:identificationInfo/'
                                   'gmd:MD_DataIdentification/'
                                   'gmd:supplementalInformation/'
                                   'inasafe/'
                                   'continuous_hazard_unit/'
                                   'gco:CharacterString'),
        'vector_hazard_classification': ('gmd:identificationInfo/'
                                         'gmd:MD_DataIdentification/'
                                         'gmd:supplementalInformation/'
                                         'inasafe/'
                                         'vector_hazard_classification/'
                                         'gco:CharacterString'),
        'raster_hazard_classification': ('gmd:identificationInfo/'
                                         'gmd:MD_DataIdentification/'
                                         'gmd:supplementalInformation/'
                                         'inasafe/'
                                         'raster_hazard_classification/'
                                         'gco:CharacterString'),
        'field': ('gmd:identificationInfo/'
                  'gmd:MD_DataIdentification/'
                  'gmd:supplementalInformation/'
                  'inasafe/'
                  'field/'
                  'gco:CharacterString'),
        'value_map': ('gmd:identificationInfo/'
                      'gmd:MD_DataIdentification/'
                      'gmd:supplementalInformation/'
                      'inasafe/'
                      'value_map/'
                      'gco:Dictionary'),
        'volcano_name_field': ('gmd:identificationInfo/'
                               'gmd:MD_DataIdentification/'
                               'gmd:supplementalInformation/'
                               'inasafe/'
                               'volcano_name_field/'
                               'gco:CharacterString'),
        'prob_fatality_mag': ('gmd:identificationInfo/'
                              'gmd:MD_DataIdentification/'
                              'gmd:supplementalInformation/'
                              'inasafe/'
                              'prob_fatality_mag/'
                              'gco:Tuple'),
    }
    _standard_properties = merge_dictionaries(
        GenericLayerMetadata._standard_properties, _standard_properties)
class AggregationLayerMetadata(GenericLayerMetadata):
    """
    Metadata class for aggregation layers

    .. versionadded:: 3.2
    """

    _standard_properties = {
        'aggregation attribute': ('gmd:identificationInfo/'
                                  'gmd:MD_DataIdentification/'
                                  'gmd:supplementalInformation/'
                                  'inasafe/'
                                  'aggregation_attribute/'
                                  'gco:CharacterString'),
        'adult ratio attribute': ('gmd:identificationInfo/'
                                  'gmd:MD_DataIdentification/'
                                  'gmd:supplementalInformation/'
                                  'inasafe/'
                                  'adult_ratio_attribute/'
                                  'gco:CharacterString'),
        'adult ratio default': ('gmd:identificationInfo/'
                                'gmd:MD_DataIdentification/'
                                'gmd:supplementalInformation/'
                                'inasafe/'
                                'adult_ratio_default/'
                                'gco:Float'),
        'elderly ratio attribute': ('gmd:identificationInfo/'
                                    'gmd:MD_DataIdentification/'
                                    'gmd:supplementalInformation/'
                                    'inasafe/'
                                    'elderly_ratio_attribute/'
                                    'gco:CharacterString'),
        'elderly ratio default': ('gmd:identificationInfo/'
                                  'gmd:MD_DataIdentification/'
                                  'gmd:supplementalInformation/'
                                  'inasafe/'
                                  'elderly_ratio_default/'
                                  'gco:Float'),
        'female ratio attribute': ('gmd:identificationInfo/'
                                   'gmd:MD_DataIdentification/'
                                   'gmd:supplementalInformation/'
                                   'inasafe/'
                                   'female_ratio_attribute/'
                                   'gco:CharacterString'),
        'female ratio default': ('gmd:identificationInfo/'
                                 'gmd:MD_DataIdentification/'
                                 'gmd:supplementalInformation/'
                                 'inasafe/'
                                 'female_ratio_default/'
                                 'gco:Float'),
        'youth ratio attribute': ('gmd:identificationInfo/'
                                  'gmd:MD_DataIdentification/'
                                  'gmd:supplementalInformation/'
                                  'inasafe/'
                                  'youth_ratio_attribute/'
                                  'gco:CharacterString'),
        'youth ratio default': ('gmd:identificationInfo/'
                                'gmd:MD_DataIdentification/'
                                'gmd:supplementalInformation/'
                                'inasafe/'
                                'youth_ratio_default/'
                                'gco:Float')
    }
    _standard_properties = merge_dictionaries(
        GenericLayerMetadata._standard_properties, _standard_properties)
Пример #4
0
class ExposureLayerMetadata(GenericLayerMetadata):
    """
    Metadata class for exposure layers

    .. versionadded:: 3.2
    """

    _standard_properties = {
        'exposure': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'exposure/'
            'gco:CharacterString'),
        'exposure_unit': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'exposure_unit/'
            'gco:CharacterString'),
        'structure_class_field': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'structure_class_field/'
            'gco:CharacterString'),
        'road_class_field': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'road_class_field/'
            'gco:CharacterString'),
        'field': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'field/'
            'gco:CharacterString'),
        'area_population_field': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'area_population_field/'
            'gco:CharacterString'),
        'area_name_field': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'area_name_field/'
            'gco:CharacterString'),
        'area_id_field': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'area_id_field/'
            'gco:CharacterString'),
        'area_type_field': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'area_type_field/'
            'gco:CharacterString'),
        'allow_resampling': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'allow_resampling/'
            'gco:CharacterString'),
        'population_field': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'population_field/'
            'gco:CharacterString'),
        'name_field': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'name_field/'
            'gco:CharacterString'),
        'value_mapping': (
            'gmd:identificationInfo/'
            'gmd:MD_DataIdentification/'
            'gmd:supplementalInformation/'
            'inasafe/'
            'value_map/'
            'gco:Dictionary'),
    }
    _standard_properties = merge_dictionaries(
            GenericLayerMetadata._standard_properties, _standard_properties)