def _update_keywords(self, **update_props):
        """ Update operation for ISO type-specific Keywords metadata: Theme or Place """

        tree_to_update = update_props['tree_to_update']
        prop = update_props['prop']
        values = update_props['values']

        keywords = []

        if prop in [KEYWORDS_PLACE, KEYWORDS_THEME]:
            xpath_root = self._data_map['_keywords_root']
            xpath_map = self._data_structures[update_props['prop']]

            xtype = xpath_map['keyword_type']
            xroot = xpath_map['keyword_root']
            xpath = xpath_map['keyword']

            if prop == KEYWORDS_PLACE:
                ktype = KEYWORD_TYPE_PLACE
            elif prop == KEYWORDS_THEME:
                ktype = KEYWORD_TYPE_THEME

            # Remove descriptiveKeyword nodes according to type
            for element in get_elements(tree_to_update, xpath_root):
                if get_element_text(element, xtype).lower() == ktype.lower():
                    remove_element(tree_to_update, xpath_root)

            element = insert_element(tree_to_update, 0, xpath_root)
            insert_element(element, 0, xtype, ktype)  # Add the type node

            keywords.extend(update_property(element, xroot, xpath, prop, values))

        return keywords
    def _update_keywords(self, **update_props):
        """ Update operation for ISO type-specific Keywords metadata: Theme or Place """

        tree_to_update = update_props['tree_to_update']
        prop = update_props['prop']
        values = update_props['values']

        keywords = []

        if prop in KEYWORD_PROPS:
            xpath_root = self._data_map['_keywords_root']
            xpath_map = self._data_structures[prop]

            xtype = xpath_map['keyword_type']
            xroot = xpath_map['keyword_root']
            xpath = xpath_map['keyword']
            ktype = KEYWORD_TYPES[prop]

            # Remove descriptiveKeyword nodes according to type
            for element in get_elements(tree_to_update, xpath_root):
                if get_element_text(element, xtype).lower() == ktype.lower():
                    remove_element(tree_to_update, xpath_root)

            element = insert_element(tree_to_update, 0, xpath_root)
            insert_element(element, 0, xtype, ktype)  # Add the type node

            keywords.extend(update_property(element, xroot, xpath, prop, values))

        return keywords
Esempio n. 3
0
    def _update_dates(self, xpath_root=None, **update_props):
        """
        Default update operation for Dates metadata
        :see: gis_metadata.utils._complex_definitions[DATES]
        """

        tree_to_update = update_props['tree_to_update']
        prop = update_props['prop']
        values = (update_props['values'] or {}).get(DATE_VALUES) or u''
        xpaths = self._data_structures[prop]

        if not self.dates:
            date_xpaths = xpath_root
        elif self.dates[DATE_TYPE] != DATE_TYPE_RANGE:
            date_xpaths = xpaths.get(self.dates[DATE_TYPE], u'')
        else:
            date_xpaths = [
                xpaths[DATE_TYPE_RANGE_BEGIN], xpaths[DATE_TYPE_RANGE_END]
            ]

        if xpath_root:
            remove_element(tree_to_update, xpath_root)

        return update_property(tree_to_update, xpath_root, date_xpaths, prop,
                               values)
Esempio n. 4
0
    def _get_template(self, root=None, **metadata_defaults):
        """ Iterate over items metadata_defaults {prop: val, ...} to populate template """

        if root is None:
            if self._data_map is None:
                self._init_data_map()

            root = self._xml_root = self._data_map['_root']

        template_tree = self._xml_tree = create_element_tree(root)

        for prop, val in iteritems(metadata_defaults):
            path = self._data_map.get(prop)
            if path and val:
                setattr(self, prop, val)
                update_property(template_tree, None, path, prop, val)

        return template_tree
Esempio n. 5
0
    def update(self, use_template=False, **metadata_defaults):
        """
        Validates instance properties and updates either a template or the original XML tree with them.
        :param use_template: if True, updates a new template XML tree; otherwise the original XML tree
        """

        self.validate()

        tree_to_update = self._xml_tree if not use_template else self._get_template(
            **metadata_defaults)
        supported_props = self._metadata_props

        for prop, xpath in iteritems(self._data_map):
            if not prop.startswith('_') or prop.strip('_') in supported_props:
                # Send only public or alternate properties
                update_property(tree_to_update,
                                self._get_xroot_for(prop), xpath, prop,
                                getattr(self, prop, u''), supported_props)

        return tree_to_update
    def update(self, use_template=False, **metadata_defaults):
        """ OVERRIDDEN: Prevents writing multiple CharacterStrings per XPATH property """

        self.validate()

        tree_to_update = self._xml_tree if not use_template else self._get_template(**metadata_defaults)
        supported_props = self._metadata_props

        # Iterate over keys, and extract non-primitive root for all XPATHs
        #    xroot = identificationInfo/MD_DataIdentification/abstract/
        #    xpath = identificationInfo/MD_DataIdentification/abstract/CharacterString
        #
        # This prevents multiple primitive tags from being inserted under an element

        for prop, xpath in iteritems(self._data_map):
            if not prop.startswith('_') or prop.strip('_') in supported_props:
                # Send only public or alternate properties
                xroot = self._trim_xpath(xpath, prop)
                values = getattr(self, prop, u'')
                update_property(tree_to_update, xroot, xpath, prop, values, supported_props)

        return tree_to_update
    def update(self, use_template=False, **metadata_defaults):
        """ OVERRIDDEN: Prevents writing multiple CharacterStrings per XPATH property """

        self.validate()

        tree_to_update = self._xml_tree if not use_template else self._get_template(**metadata_defaults)
        supported_props = self._metadata_props

        # Iterate over keys, and extract non-primitive root for all XPATHs
        #    xroot = identificationInfo/MD_DataIdentification/abstract/
        #    xpath = identificationInfo/MD_DataIdentification/abstract/CharacterString
        #
        # This prevents multiple primitive tags from being inserted under an element

        for prop, xpath in iteritems(self._data_map):
            if not prop.startswith('_') or prop.strip('_') in supported_props:
                # Send only public or alternate properties
                xroot = self._trim_xpath(xpath, prop)
                values = getattr(self, prop, u'')
                update_property(tree_to_update, xroot, xpath, prop, values, supported_props)

        return tree_to_update
Esempio n. 8
0
    def _update_raster_info(self, **update_props):
        """ Derives multiple dimensions from a single raster_info complex struct """

        tree_to_update = update_props['tree_to_update']
        prop = update_props['prop']
        values = update_props.pop('values')

        # Update number of dimensions at raster_info root (applies to all dimensions below)

        xroot, xpath = None, self._data_map['_ri_num_dims']
        raster_info = [
            update_property(tree_to_update, xroot, xpath, prop,
                            values.get('dimensions', u''))
        ]

        # Derive vertical, longitude, and latitude dimensions from raster_info

        xpath_root = self._get_xroot_for(prop)
        xpath_map = self._data_structures[prop]

        v_dimension = {}
        if values.get('vertical_count'):
            v_dimension = v_dimension.fromkeys(xpath_map, u'')
            v_dimension['type'] = 'vertical'
            v_dimension['size'] = values.get('vertical_count', u'')

        x_dimension = {}
        if values.get('column_count') or values.get('x_resolution'):
            x_dimension = x_dimension.fromkeys(xpath_map, u'')
            x_dimension['type'] = 'column'
            x_dimension['size'] = values.get('column_count', u'')
            x_dimension['value'] = values.get('x_resolution', u'')

        y_dimension = {}
        if values.get('row_count') or values.get('y_resolution'):
            y_dimension = y_dimension.fromkeys(xpath_map, u'')
            y_dimension['type'] = 'row'
            y_dimension['size'] = values.get('row_count', u'')
            y_dimension['value'] = values.get('y_resolution', u'')

        # Update derived dimensions as complex list, and append affected elements for return

        update_props['prop'] = RASTER_DIMS
        update_props['values'] = [v_dimension, x_dimension, y_dimension]

        raster_info += update_complex_list(xpath_root=xpath_root,
                                           xpath_map=xpath_map,
                                           **update_props)

        return raster_info