示例#1
0
def _get_sicd_xml_from_nitf(sicd_details):
    """
    Fetch the xml string for the SICD.

    Parameters
    ----------
    sicd_details : SICDDetails
    """

    for i in range(sicd_details.des_subheader_offsets.size):
        subhead_bytes = sicd_details.get_des_subheader_bytes(i)
        if subhead_bytes.startswith(b'DEXML_DATA_CONTENT'):
            des_bytes = sicd_details.get_des_bytes(i).decode('utf-8').strip()
            # noinspection PyBroadException
            try:
                root_node, xml_ns = parse_xml_from_string(des_bytes)
                if 'SICD' in root_node.tag:  # namespace makes this ugly
                    return des_bytes, root_node, xml_ns
            except Exception:
                continue
        elif subhead_bytes.startswith(b'DESICD_XML'):
            # This is an old format SICD
            des_bytes = sicd_details.get_des_bytes(i).decode('utf-8').strip()
            try:
                root_node, xml_ns = parse_xml_from_string(des_bytes)
                if 'SICD' in root_node.tag:  # namespace makes this ugly
                    return des_bytes, root_node, xml_ns
            except Exception as e:
                logger.error('We found an apparent old-style SICD DES header, '
                              'but failed parsing with error {}'.format(e))
                continue
    return None, None, None
示例#2
0
文件: sicd.py 项目: Bob-Asian/sarpy
    def _find_sicd(self):
        self._is_sicd = False
        self._sicd_meta = None
        if self.des_subheader_offsets is None:
            return

        for i in range(self.des_subheader_offsets.size):
            subhead_bytes = self.get_des_subheader_bytes(i)
            if subhead_bytes.startswith(b'DEXML_DATA_CONTENT'):
                des_header = DataExtensionHeader.from_bytes(subhead_bytes, start=0)
                des_bytes = self.get_des_bytes(i)
                # noinspection PyBroadException
                try:
                    root_node, xml_ns = parse_xml_from_string(des_bytes.decode('utf-8').strip())
                    if 'SIDD' in root_node.tag:  # namespace makes this ugly
                        # NOTE that SIDD files are supposed to have the corresponding
                        # SICD xml as one of the DES AFTER the SIDD xml.
                        # The same basic format is used for both headers.
                        # So, abandon if we find a SIDD xml
                        self._des_index = None
                        self._des_header = None
                        self._is_sicd = False
                        break
                    elif 'SICD' in root_node.tag:  # namespace makes this ugly
                        self._des_index = i
                        self._des_header = des_header
                        self._is_sicd = True
                        self._sicd_meta = SICDType.from_node(root_node, xml_ns, ns_key='default')
                        break
                except Exception:
                    continue
            elif subhead_bytes.startswith(b'DESIDD_XML'):
                # This is an old format SIDD and can't be a SICD
                self._des_index = None
                self._des_header = None
                self._is_sicd = False
                break
            elif subhead_bytes.startswith(b'DESICD_XML'):
                # This is an old format SICD
                des_bytes = self.get_des_bytes(i)
                try:
                    root_node, xml_ns = parse_xml_from_string(des_bytes)
                    if 'SICD' in root_node.tag:  # namespace makes this ugly
                        self._des_index = i
                        self._des_header = None
                        self._is_sicd = True
                        self._sicd_meta = SICDType.from_node(root_node, xml_ns, ns_key='default')
                        break
                except Exception as e:
                    logging.error('We found an apparent old-style SICD DES header, '
                                  'but failed parsing with error {}'.format(e))
                    continue

        if not self._is_sicd:
            return
        self._sicd_meta.derive()
示例#3
0
文件: sidd.py 项目: nyulacska/sarpy
    def _find_sidd(self):
        self._is_sidd = False
        if self.des_subheader_offsets is None:
            return

        self._sidd_meta = []
        self._sicd_meta = []

        for i in range(self.des_subheader_offsets.size):
            subhead_bytes = self.get_des_subheader_bytes(i)
            if subhead_bytes.startswith(b'DEXML_DATA_CONTENT'):
                des_bytes = self.get_des_bytes(i)
                try:
                    root_node, xml_ns = parse_xml_from_string(des_bytes)
                    if 'SIDD' in root_node.tag:
                        self._is_sidd = True
                        self._sidd_meta.append(SIDDType.from_node(root_node, xml_ns, ns_key='default'))
                    elif 'SICD' in root_node.tag:
                        self._sicd_meta.append(SICDType.from_node(root_node, xml_ns, ns_key='default'))
                except Exception as e:
                    logging.error('Failed checking des xml header at index {} with error {}'.format(i, e))
                    continue
            elif subhead_bytes.startswith(b'DESIDD_XML'):
                # This is an old format SIDD header
                des_bytes = self.get_des_bytes(i)
                try:
                    root_node, xml_ns = parse_xml_from_string(des_bytes)
                    if 'SIDD' in root_node.tag:
                        self._is_sidd = True
                        self._sidd_meta.append(SIDDType.from_node(root_node, xml_ns, ns_key='default'))
                except Exception as e:
                    logging.error('We found an apparent old-style SIDD DES header at index {}, '
                                  'but failed parsing with error {}'.format(i, e))
                    continue
            elif subhead_bytes.startswith(b'DESICD_XML'):
                # This is an old format SICD header
                des_bytes = self.get_des_bytes(i)
                try:
                    root_node, xml_ns = parse_xml_from_string(des_bytes)
                    if 'SICD' in root_node.tag:
                        self._sicd_meta.append(SICDType.from_node(root_node, xml_ns, ns_key='default'))
                except Exception as e:
                    logging.error('We found an apparent old-style SICD DES header at index {}, '
                                  'but failed parsing with error {}'.format(i, e))
                    continue

        if not self._is_sidd:
            return

        for sicd in self._sicd_meta:
            sicd.derive()
示例#4
0
def generic_construction_test(instance,
                              the_type,
                              the_dict,
                              tag='The_Type',
                              print_xml=False,
                              print_json=False):
    if not issubclass(the_type, Serializable):
        raise TypeError(
            'Class {} must be a subclass of Serializable'.format(the_type))
    the_item = the_type.from_dict(the_dict)

    with instance.subTest(msg='Comparing json deserialization with original'):
        new_dict = the_item.to_dict()
        if print_json:
            print(json.dumps(the_dict, indent=1))
            print(json.dumps(new_dict, indent=1))
        instance.assertEqual(the_dict, new_dict)

    with instance.subTest(msg='Test xml serialization issues'):
        # let's serialize to xml
        xml = the_item.to_xml_string(tag=tag)
        if print_xml:
            print(xml)
        # let's deserialize from xml
        node, xml_ns = parse_xml_from_string(xml)
        item2 = the_type.from_node(node, xml_ns)
        instance.assertEqual(the_item.to_dict(), item2.to_dict())

    with instance.subTest(msg='Test validity'):
        instance.assertTrue(the_item.is_valid())
    return the_item
示例#5
0
    def _extract_cphd(self, fi):
        """
        Extract and interpret the CPHD structure from the file.

        Parameters
        ----------
        fi
            The open file object, required to be opened in binary mode.

        Returns
        -------
        None
        """

        xml = self._get_cphd_bytes(fi)
        if self.cphd_version.startswith('0.3'):
            the_type = CPHDType0_3
        elif self.cphd_version.startswith('1.0'):
            the_type = CPHDType
        else:
            raise ValueError('Got unhandled version number {}'.format(
                self.cphd_version))

        root_node, xml_ns = parse_xml_from_string(xml)
        if 'default' in xml_ns:
            self._cphd_meta = the_type.from_node(root_node,
                                                 xml_ns,
                                                 ns_key='default')
        else:
            self._cphd_meta = the_type.from_node(root_node, xml_ns)
示例#6
0
def check_file(file_name):
    """
    Check the SICD validity for the given file SICD (i.e. appropriately styled NITF)
    or xml file containing the SICD structure alone.

    Parameters
    ----------
    file_name : str|SICDDetails

    Returns
    -------
    bool
    """

    sicd_xml, root_node, xml_ns, urn_string = None, None, None, None
    if isinstance(file_name, SICDDetails):
        sicd_xml, root_node, xml_ns = _get_sicd_xml_from_nitf(file_name)
    else:
        # check if this is just an xml file
        with open(file_name, 'rb') as fi:
            initial_bits = fi.read(100)
            if initial_bits.startswith(b'<?xml') or initial_bits.startswith(b'<SICD'):
                sicd_xml = fi.read().decode('utf-8')
                root_node, xml_ns = parse_xml_from_string(sicd_xml)

        if sicd_xml is None:
            # try to first test whether this is SICD file
            try:
                sicd_details = SICDDetails(file_name)
                if not sicd_details.is_sicd:
                    logger.error('File {} is a NITF file, but is apparently not a SICD file.')
                    return False
                sicd_xml, root_node, xml_ns = _get_sicd_xml_from_nitf(sicd_details)
            except SarpyIOError:
                pass

    if sicd_xml is None:
        logger.error('Could not interpret input {}'.format(file_name))
        return False

    urn_string = xml_ns['default']
    valid_xml = evaluate_xml_versus_schema(sicd_xml, urn_string)
    if valid_xml is None:
        valid_xml = True

    the_sicd = SICDType.from_node(root_node, xml_ns=xml_ns)
    valid_sicd_contents = the_sicd.is_valid(recursive=True, stack=False)
    return valid_xml & valid_sicd_contents
示例#7
0
    def _extract_cphd(self, fi):
        """
        Extract and interpret the CPHD structure from the file.

        Parameters
        ----------
        fi
            The open file object, required to be opened in binary mode.

        Returns
        -------
        None
        """

        header = self.cphd_header
        if header is None:
            raise ValueError('No cphd_header populated.')

        if self.cphd_version.startswith('0.3'):
            assert isinstance(header, CPHDHeader0_3)
            # extract the xml data
            fi.seek(header.XML_BYTE_OFFSET)
            xml = fi.read(header.XML_DATA_SIZE)
            the_type = CPHDType0_3
        elif self.cphd_version.startswith('1.0'):
            assert isinstance(header, CPHDHeader)
            # extract the xml data
            fi.seek(header.XML_BLOCK_BYTE_OFFSET)
            xml = fi.read(header.XML_BLOCK_SIZE)
            the_type = CPHDType
        else:
            raise ValueError('Got unhandled version number {}'.format(
                self.cphd_version))

        root_node, xml_ns = parse_xml_from_string(xml)
        if 'default' in xml_ns:
            self._cphd_meta = the_type.from_node(root_node,
                                                 xml_ns,
                                                 ns_key='default')
        else:
            self._cphd_meta = the_type.from_node(root_node, xml_ns)
        return xml
示例#8
0
    def get_sicd(self):
        """
        Extract the SICD details.

        Returns
        -------
        SICDType
        """

        if self._sicd is not None:
            return self._sicd
        if self._user_data is None:
            self._read_user_data()
        if self._caspr_data is None:
            self._find_caspr_data()
        # Check if the user data contains a sicd structure.
        sicd_string = None
        for nam in ['SICDMETA', 'SICD_META', 'SICD']:
            if sicd_string is None:
                sicd_string = self._user_data.get(nam, None)
        # If so, assume that this SICD is valid and simply present it
        if sicd_string is not None:
            root_node, xml_ns = parse_xml_from_string(sicd_string)
            self._sicd = SICDType.from_node(root_node, xml_ns)
            self._sicd.derive()
        else:
            # otherwise, we populate a really minimal sicd structure
            num_rows, num_cols = self.data_size
            self._sicd = SICDType(ImageData=ImageDataType(
                NumRows=num_rows,
                NumCols=num_cols,
                FirstRow=0,
                FirstCol=0,
                PixelType=self.pixel_type,
                FullImage=FullImageType(NumRows=num_rows, NumCols=num_cols),
                SCPPixel=RowColType(Row=num_rows / 2, Col=num_cols / 2)))
        return self._sicd