コード例 #1
0
    def parse_lat_lon_bounding_box(self, layer, layer_obj):
        """ Version specific implementation of the bounding box parsing

        Args:
            layer: The xml element which holds the layer info (parsing from)
            layer_obj: The backend model which holds the layer data (parsing to)
        Returns:
             nothing
        """
        try:
            bbox = xml_helper.try_get_element_from_xml(
                "./" +
                GENERIC_NAMESPACE_TEMPLATE.format("EX_GeographicBoundingBox"),
                layer)[0]
            attrs = {
                "westBoundLongitude": "minx",
                "eastBoundLongitude": "maxx",
                "southBoundLatitude": "miny",
                "northBoundLatitude": "maxy",
            }
            for key, val in attrs.items():
                tmp = xml_helper.try_get_text_from_xml_element(
                    xml_elem=bbox,
                    elem="./" + GENERIC_NAMESPACE_TEMPLATE.format(key))
                if tmp is None:
                    tmp = 0
                layer_obj.capability_bbox_lat_lon[val] = tmp
        except IndexError:
            pass
コード例 #2
0
    def get_service_operations_and_formats(self, xml_obj):
        """ Creates table records from <Capability><Request></Request></Capability contents

        Creates MimeType records

        Args:
            xml_obj: The xml document object
        Returns:

        """
        cap_request = xml_helper.try_get_single_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("Capability") +
            "/" + GENERIC_NAMESPACE_TEMPLATE.format("Request"),
            xml_obj
        )
        operations = cap_request.getchildren()
        for operation in operations:
            RequestOperation.objects.get_or_create(
                operation_name=operation.tag,
            )
            # Parse formats
            formats = xml_helper.try_get_element_from_xml(
                "./" + GENERIC_NAMESPACE_TEMPLATE.format("Format"),
                operation
            )
            formats = [f.text for f in formats]
            self.operation_format_map[operation.tag] = formats
コード例 #3
0
    def _create_formats_from_md_metadata(self, md_metadata: Element) -> list:
        """ Creates a list of MimeType objects from MD_Metadata element

        Args:
            md_metadata (Element): The xml element
        Returns:
             formats (list)
        """
        formats = []
        distribution_elem = xml_helper.try_get_single_element_from_xml(
            ".//" + GENERIC_NAMESPACE_TEMPLATE.format("distributionFormat"),
            md_metadata)
        if distribution_elem is None:
            return formats
        md_format_elems = xml_helper.try_get_element_from_xml(
            ".//" + GENERIC_NAMESPACE_TEMPLATE.format("MD_Format"),
            md_metadata)
        for md_format_elem in md_format_elems:
            name = xml_helper.try_get_text_from_xml_element(
                md_format_elem,
                ".//" + GENERIC_NAMESPACE_TEMPLATE.format("name") + "/" +
                GENERIC_NAMESPACE_TEMPLATE.format("CharacterString"))
            if name is not None:
                formats.append(name)
        return formats
コード例 #4
0
    def _parse_parameter_metadata(self, upper_elem):
        """ Parses the <Parameter> elements inside of <OperationsMetadata>

        Args:
            upper_elem (Element): The upper xml element
        Returns:
            parameter_map (dict): Mapped parameters and values
        """
        parameter_objs = xml_helper.try_get_element_from_xml(
            "./" + GENERIC_NAMESPACE_TEMPLATE.format("Parameter"),
            upper_elem
        )
        parameter_map = {}
        for parameter in parameter_objs:
            param_name = xml_helper.try_get_attribute_from_xml_element(
                parameter,
                "name"
            )
            param_val = xml_helper.try_get_text_from_xml_element(
                parameter,
                ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Value")
            )
            parameter_map[param_name] = param_val

        return parameter_map
コード例 #5
0
    def _parse_xml_legal_dates(self, xml_obj: Element):
        """ Parses existing CI_Date elements from the MD_DataIdentification element

        Args:
            xml_obj (Element): The document xml element
        Returns:

        """
        md_data_ident_elem = xml_helper.try_get_single_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("MD_DataIdentification"),
            xml_obj)
        legal_date_elems = xml_helper.try_get_element_from_xml(
            ".//" + GENERIC_NAMESPACE_TEMPLATE.format("CI_Date"),
            md_data_ident_elem)
        if legal_date_elems:
            for legal_date_elem in legal_date_elems:
                legal_date = LegalDate()
                legal_date.date = xml_helper.try_get_text_from_xml_element(
                    legal_date_elem,
                    ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Date"))
                legal_date.date_type_code = xml_helper.try_get_attribute_from_xml_element(
                    legal_date_elem, "codeListValue", ".//" +
                    GENERIC_NAMESPACE_TEMPLATE.format("CI_DateTypeCode"))
                legal_date.date_type_code_list_url = xml_helper.try_get_attribute_from_xml_element(
                    legal_date_elem, "codeList", ".//" +
                    GENERIC_NAMESPACE_TEMPLATE.format("CI_DateTypeCode"))
                self.legal_dates.append(legal_date)
コード例 #6
0
    def get_version_specific_metadata(self, xml_obj):
        service_xml = xml_helper.try_get_single_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("Service"),
            xml_obj
        )
        # Keywords
        # Keywords are not separated in single <Keyword> elements.
        # There is a single <Keywords> element, containing a continuous string, where keywords are space separated
        keywords = xml_helper.try_get_text_from_xml_element(
            service_xml,
            "./" + GENERIC_NAMESPACE_TEMPLATE.format("Keywords")
        )
        keywords = keywords.split(" ")
        tmp = []
        for kw in keywords:
            kw = kw.strip()
            if len(kw) != 0:
               tmp.append(kw)
        self.service_identification_keywords = tmp

        # Online Resource
        # The online resource is not found as an attribute of an element.
        # It is the text of the <OnlineResource> element
        online_resource = xml_helper.try_get_text_from_xml_element(
            service_xml,
            "./" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource")
        )
        self.service_provider_onlineresource_linkage = online_resource
コード例 #7
0
 def parse_keywords(self, layer, layer_obj):
     keywords = xml_helper.try_get_element_from_xml(
         elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("KeywordList") +
         "/" + GENERIC_NAMESPACE_TEMPLATE.format("Keyword"),
         xml_elem=layer)
     for keyword in keywords:
         layer_obj.capability_keywords.append(keyword.text)
コード例 #8
0
    def get_version_specific_service_metadata(self, xml_obj):
        """ The version specific implementation of service metadata parsing

        There are elements in the <Service> part fo the GetCapabilities document which are not covered in the regular
        service metadata parsing due to the fact, they are only used in the newest version of WMS which is by far not
        regularly used.

        Args:
            xml_obj: The xml element
        Returns:
             nothing
        """
        # layer limit is new
        layer_limit = xml_helper.try_get_text_from_xml_element(
            elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("LayerLimit"),
            xml_elem=xml_obj)
        self.layer_limit = layer_limit

        # max height and width is new
        max_width = xml_helper.try_get_text_from_xml_element(
            elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("MaxWidth"),
            xml_elem=xml_obj)
        self.max_width = max_width

        max_height = xml_helper.try_get_text_from_xml_element(
            elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("MaxHeight"),
            xml_elem=xml_obj)
        self.max_height = max_height

        self._parse_layers(xml_obj=xml_obj)
コード例 #9
0
    def _parse_layers(self, xml_obj):
        """ Parses all layers of a service and creates OGCWebMapLayer objects from each.

        Uses recursion on the inside to get all children.

        Args:
            xml_obj: The iterable xml tree
        Returns:
             nothing
        """
        # get most upper parent layer, which normally lives directly in <Capability>
        layers = xml_helper.try_get_element_from_xml(
            elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("Capability") + "/" +
            GENERIC_NAMESPACE_TEMPLATE.format("Layer"),
            xml_elem=xml_obj)
        total_layers = xml_helper.try_get_element_from_xml(
            elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("Layer"),
            xml_elem=xml_obj)

        # calculate the step size for an async call
        # 55 is the diff from the last process update (10) to the next static one (65)
        len_layers = len(total_layers)
        if len_layers == 0:
            # No division by zero!
            len_layers = 1
        step_size = float(PROGRESS_STATUS_AFTER_PARSING / len_layers)
        service_logger.debug(
            "Total number of layers: {}. Step size: {}".format(
                len_layers, step_size))

        self._parse_layers_recursive(layers, step_size=step_size)
コード例 #10
0
    def parse_style(self, layer, layer_obj):
        style_xml = xml_helper.try_get_single_element_from_xml(
            "./" + GENERIC_NAMESPACE_TEMPLATE.format("Style"), layer)

        if style_xml is None:
            # no <Style> element found
            return

        style_obj = Style()

        style_obj.name = xml_helper.try_get_text_from_xml_element(
            style_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("Name"))
        style_obj.title = xml_helper.try_get_text_from_xml_element(
            style_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("Title"))
        legend_elem = xml_helper.try_get_single_element_from_xml(
            elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("LegendURL") + "/" +
            GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource"),
            xml_elem=style_xml)
        style_obj.legend_uri = xml_helper.get_href_attribute(legend_elem)
        style_obj.width = int(
            xml_helper.try_get_attribute_from_xml_element(
                style_xml, "width",
                "./" + GENERIC_NAMESPACE_TEMPLATE.format("LegendURL")) or 0)
        style_obj.height = int(
            xml_helper.try_get_attribute_from_xml_element(
                style_xml, "height",
                "./" + GENERIC_NAMESPACE_TEMPLATE.format("LegendURL")) or 0)
        style_obj.mime_type = MimeType.objects.filter(
            mime_type=xml_helper.try_get_text_from_xml_element(
                style_xml, "./" +
                GENERIC_NAMESPACE_TEMPLATE.format("LegendURL") + "/ " +
                GENERIC_NAMESPACE_TEMPLATE.format("Format"))).first()

        layer_obj.style = style_obj
コード例 #11
0
ファイル: test_csw.py プロジェクト: terrestris/mrmap
    def test_get_records_by_id(self):
        """ Test for checking if the GetRecordsById is working fine or not.

        Returns:

        """
        get_records_param = {
            "service": "CSW",
            "version": "2.0.2",
            "request": "GetRecordById",
            "id": self.test_id,
            "elementsetname": "full",
        }

        response = self.client.get(reverse(CSW_PATH), data=get_records_param)
        status_code = response.status_code
        content = response.content
        content_xml = xml_helper.parse_xml(content)

        self.assertEqual(response.status_code, 200,
                         WRONG_STATUS_CODE_TEMPLATE.format(status_code))
        self.assertIsNotNone(content_xml, INVALID_XML_MSG)

        # Check that the results are correct in amount and quality
        num_returned_elems = int(
            xml_helper.try_get_attribute_from_xml_element(
                xml_elem=content_xml,
                attribute="numberOfRecordsMatched",
                elem="//" +
                GENERIC_NAMESPACE_TEMPLATE.format("SearchResults")))
        self.assertEqual(
            num_returned_elems, 1,
            "More than one element returned on GetRecordsById with only one used identifier!"
        )
        real_returned_elems = xml_helper.try_get_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("Record"), content_xml)
        num_real_returned_elems = len(real_returned_elems)
        self.assertEqual(
            num_real_returned_elems, num_returned_elems,
            "csw:SearchResults contains wrong numberOfRecordsMatched! {} stated but {} returned!"
            .format(num_returned_elems, num_real_returned_elems))

        identifiers = [
            xml_helper.try_get_text_from_xml_element(
                real_returned_elem,
                "//" + GENERIC_NAMESPACE_TEMPLATE.format("identifier"))
            for real_returned_elem in real_returned_elems
        ]
        identifiers_identical = [
            identifier == self.test_id for identifier in identifiers
        ]
        self.assertTrue(
            False not in identifiers_identical,
            "Elements with not matching identifier has been returned: {}".
            format(", ".join(identifiers)))
コード例 #12
0
    def _parse_xml_legal_reports(self, xml_obj: Element):
        """ Parses existing CI_Date elements from the MD_DataIdentification element

        Args:
            xml_obj (Element): The document xml element
        Returns:

        """
        data_quality_elem = xml_helper.try_get_single_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("DQ_DataQuality"),
            xml_obj)
        report_elems = xml_helper.try_get_single_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("report"), xml_obj)
        for report_elem in report_elems:
            report = LegalReport()
            report.title = xml_helper.try_get_text_from_xml_element(
                report_elem,
                ".//" + GENERIC_NAMESPACE_TEMPLATE.format("title") + "/" +
                GENERIC_NAMESPACE_TEMPLATE.format("CharacterString"))
            report.explanation = xml_helper.try_get_text_from_xml_element(
                report_elem,
                ".//" + GENERIC_NAMESPACE_TEMPLATE.format("explanation") +
                "/" + GENERIC_NAMESPACE_TEMPLATE.format("CharacterString"))
            legal_date = LegalDate()
            legal_date.date = xml_helper.try_get_text_from_xml_element(
                report_elem, ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Date"))
            legal_date.date_type_code = xml_helper.try_get_attribute_from_xml_element(
                report_elem, "codeListValue",
                ".//" + GENERIC_NAMESPACE_TEMPLATE.format("CI_DateTypeCode"))
            legal_date.date_type_code_list_url = xml_helper.try_get_attribute_from_xml_element(
                report_elem, "codeList",
                ".//" + GENERIC_NAMESPACE_TEMPLATE.format("CI_DateTypeCode"))
            report.date = legal_date
            self.legal_reports.append(report)
コード例 #13
0
    def _parse_operations_metadata(self, upper_elem):
        """ Parses the <Operation> elements inside of <OperationsMetadata>

        Args:
            upper_elem (Element): The upper xml element
        Returns:

        """
        operations_objs = xml_helper.try_get_element_from_xml(
            ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Operation"),
            upper_elem
        )

        attribute_map = {
            OGCOperationEnum.GET_CAPABILITIES.value: 'get_capabilities_uri',
            OGCOperationEnum.DESCRIBE_RECORD.value: 'describe_record_uri',
            OGCOperationEnum.GET_RECORDS.value: 'get_records_uri',
            OGCOperationEnum.GET_RECORD_BY_ID.value: 'get_record_by_id_uri',
        }

        for operation in operations_objs:
            operation_name = xml_helper.try_get_attribute_from_xml_element(
                operation,
                "name",
            )
            get_uri = xml_helper.try_get_single_element_from_xml(
                ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Get"),
                operation
            )
            get_uri = xml_helper.get_href_attribute(get_uri) if get_uri is not None else None

            post_uri = xml_helper.try_get_single_element_from_xml(
                ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Post"),
                operation
            )
            post_uri = xml_helper.get_href_attribute(post_uri) if post_uri is not None else None

            if attribute_map.get(operation_name):
                setattr(self, attribute_map.get(operation_name)+'_GET', get_uri)
                setattr(self, attribute_map.get(operation_name)+'_POST', post_uri)
            else:
                # the given operation is not supported for now
                pass

            parameters = self._parse_parameter_metadata(operation)
            output_format = parameters.get("outputFormat", None)
            if output_format is not None:
                self.formats_list.append(
                    MimeType.objects.get_or_create(
                        operation=operation_name,
                        mime_type=output_format,
                    )[0]
                )
コード例 #14
0
def _overwrite_capabilities_data(xml_obj: _Element, metadata: Metadata):
    """ Overwrites capabilities document data with changed data from editor based changes.

    Only capable of changing <Title>, <Abstract> and <AccessConstraints>

    Args:
        xml_obj (_Element): The document xml object
        metadata (Metadata): The metadata holding the data
    Returns:

    """
    # Create licence appendix for AccessConstraints and Fees
    licence = metadata.licence
    licence_appendix = ""
    if licence is not None:
        licence_appendix = "\n {} ({}), \n {}, \n {}".format(
            licence.name, licence.identifier, licence.description,
            licence.description_url)
    elements = {
        "Title":
        metadata.title,
        "Abstract":
        metadata.abstract,
        "AccessConstraints":
        "{}{}".format(metadata.access_constraints, licence_appendix),
        "Fees":
        "{}{}".format(metadata.fees, licence_appendix),
    }

    for key, val in elements.items():
        try:
            # Check if element exists to change it
            key_xml_obj = xml_helper.try_get_single_element_from_xml(
                "./" + GENERIC_NAMESPACE_TEMPLATE.format(key), xml_obj)
            if key_xml_obj is not None:
                # Element exists, we can change it easily
                xml_helper.write_text_to_element(
                    xml_obj, "./" + GENERIC_NAMESPACE_TEMPLATE.format(key),
                    val)
            else:
                # The element does not exist (happens in case of abstract sometimes)
                # First create, than change it
                xml_helper.create_subelement(
                    xml_obj,
                    key,
                )
                xml_helper.write_text_to_element(
                    xml_obj, "./" + GENERIC_NAMESPACE_TEMPLATE.format(key),
                    val)
        except AttributeError as e:
            # for not is_root this will fail in AccessConstraints querying
            pass
コード例 #15
0
 def parse_formats(self, layer, layer_obj):
     actions = ["Map", "Capabilities", "FeatureInfo"]
     results = {}
     for action in actions:
         try:
             results[action] = []
             format_list = layer.xpath(
                 "//" + GENERIC_NAMESPACE_TEMPLATE.format("Request") + "/" +
                 GENERIC_NAMESPACE_TEMPLATE.format(action) + "/" +
                 GENERIC_NAMESPACE_TEMPLATE.format("Format")).getchildren()
             for format in format_list:
                 results[action].append(format.text)
         except AttributeError:
             pass
     layer_obj.format_list = results
コード例 #16
0
ファイル: test_csw.py プロジェクト: terrestris/mrmap
    def test_exception_report(self):
        """ Test for checking if the ows:ExceptionReport is working fine or not.

        Test by requesting a wrong operation

        Returns:

        """
        get_records_param = {
            "service": "CSW",
            "version": "2.0.2",
            "request": "WRONG_OPERATION",
            "id": self.test_id,
            "elementsetname": "brief",
            "typenames": "gmd:MD_Metadata",
            "outputschema": "http://www.isotc211.org/2005/gmd",
        }

        response = self.client.get(reverse(CSW_PATH), data=get_records_param)
        status_code = response.status_code
        content = response.content
        content_xml = xml_helper.parse_xml(content)

        self.assertEqual(response.status_code, 200,
                         WRONG_STATUS_CODE_TEMPLATE.format(status_code))
        self.assertIsNotNone(content_xml, INVALID_XML_MSG)
        exception_report_elem = xml_helper.try_get_single_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("ExceptionReport"),
            content_xml)
        self.assertIsNotNone(exception_report_elem,
                             "No ows:ExceptionReport was generated!")
コード例 #17
0
    def _parse_single_layer(self, layer, parent, step_size: float = None, async_task: Task = None):
        """ Parses data from an xml <Layer> element into the OGCWebMapLayer object.

        Runs recursive through own children for further parsing

        Args:
            layer: The layer xml element
            parent: The parent OGCWebMapLayer object
        Returns:
            nothing
        """
        # iterate over all top level layer and find their children
        layer_obj = self._start_single_layer_parsing(layer)

        if step_size is not None and async_task is not None:
            task_helper.update_progress_by_step(async_task, step_size)
            task_helper.update_service_description(async_task, None, "Parsing {}".format(layer_obj.title))

        layer_obj.parent = parent
        if self.layers is None:
            self.layers = []
        self.layers.append(layer_obj)
        sublayers = xml_helper.try_get_element_from_xml(
            elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("Layer"),
            xml_elem=layer
        )
        if parent is not None:
            parent.child_layers.append(layer_obj)

        self._parse_layers_recursive(layers=sublayers, parent=layer_obj, step_size=step_size, async_task=async_task)
コード例 #18
0
ファイル: test_csw.py プロジェクト: terrestris/mrmap
    def test_get_records_sort(self):
        """ Test whether the sorting parameter is working properly

        Returns:

        """
        get_records_param = {
            "service": "CSW",
            "version": "2.0.2",
            "request": "GetRecords",
            "elementsetname": "brief",
            "resulttype": "results",
            "sortby": "dc:title:D",
        }

        response = self.client.get(reverse(CSW_PATH), data=get_records_param)
        status_code = response.status_code
        content = response.content
        content_xml = xml_helper.parse_xml(content)

        self.assertEqual(response.status_code, 200,
                         WRONG_STATUS_CODE_TEMPLATE.format(status_code))
        self.assertIsNotNone(content_xml, INVALID_XML_MSG)

        # Iterate over dc:title objects and check whether they are sorted correctly!
        title_elems = xml_helper.try_get_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("title"), content_xml)
        titles = [
            xml_helper.try_get_text_from_xml_element(title_elem)
            for title_elem in title_elems
        ]
        titles_sorted = copy(titles)
        titles.sort(reverse=True)  # Check the descending sorted way
        self.assertEqual(titles, titles_sorted)
コード例 #19
0
    def parse_dimension(self, layer, layer_obj):
        """ The version specific implementation of the dimension parsing

        Args:
            layer: The xml element which holds the layer info (parsing from)
            layer_obj: The backend model which holds the layer data (parsing to)
        Returns:
             nothing
        """
        dim_list = []
        try:
            dims = xml_helper.try_get_element_from_xml(
                elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("Dimension"),
                xml_elem=layer)
            for dim in dims:
                dim_dict = {
                    "type": dim.get("name"),
                    "units": dim.get("units"),
                    "extent": dim.text,
                }
                dim_list.append(dim_dict)

        except (IndexError, AttributeError) as error:
            pass
        layer_obj.dimension_list = dim_list
コード例 #20
0
 def parse_formats(self, layer, layer_obj):
     actions = ["GetMap", "GetCapabilities", "GetFeatureInfo", "DescribeLayer", "GetLegendGraphic", "GetStyles"]
     results = {}
     for action in actions:
         try:
             results[action] = []
             format_list = xml_helper.try_get_element_from_xml(
                 elem="//" + GENERIC_NAMESPACE_TEMPLATE.format(action) +
                      "/" + GENERIC_NAMESPACE_TEMPLATE.format("Format"),
                 xml_elem=layer
             )
             for format in format_list:
                 results[action].append(format.text)
         except AttributeError:
             pass
     layer_obj.format_list = results
コード例 #21
0
 def parse_dataset_md(self, layer, layer_obj):
     # check for possible dataset metadata
     if self.has_dataset_metadata(layer):
         iso_metadata_xml_elements = xml_helper.try_get_element_from_xml(
             xml_elem=layer,
             elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("MetadataURL") +
                   "/" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource")
         )
         for iso_xml in iso_metadata_xml_elements:
             iso_uri = xml_helper.get_href_attribute(xml_elem=iso_xml)
             try:
                 iso_metadata = ISOMetadata(uri=iso_uri, origin=ResourceOriginEnum.CAPABILITIES.value)
             except Exception as e:
                 # there are iso metadatas that have been filled wrongly -> if so we will drop them
                 continue
             layer_obj.iso_metadata.append(iso_metadata)
コード例 #22
0
ファイル: converter.py プロジェクト: terrestris/mrmap
    def create_metadata_elem(self, returned_md: Metadata):
        """ Returns existing service/dataset metadata as xml elements

        Args:
            returned_md (Metadata): The processing metadata
        Returns:
             xml (Element): The xml element
        """
        if returned_md.is_dataset_metadata:
            doc = Document.objects.get(
                metadata=returned_md,
                document_type=DocumentEnum.METADATA.value,
            )
            xml = doc.content
        else:
            xml = returned_md.get_service_metadata_xml()

        xml = xml_helper.parse_xml(xml)
        xml = xml_helper.try_get_single_element_from_xml(
            xml_elem=xml,
            elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("MD_Metadata"))

        # Reduce the amount of information returned based on the requested elementSetName parameter
        xml = self.reduce_information(xml)

        return xml
コード例 #23
0
 def parse_projection_system(self, layer, layer_obj):
     srs = xml_helper.try_get_element_from_xml(
         elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("SRS"),
         xml_elem=layer
     )
     for elem in srs:
         layer_obj.capability_projection_system.append(elem.text)
コード例 #24
0
def transform_constraint_to_cql(constraint: str, constraint_language: str):
    """ Transforms a xml filter style constraint into CQL style

    Args:
        constraint (str): The constraint parameter
        constraint_language (str): The constraintlanguage parameter
    Returns:
         constraint (str): The transfored constrained
    """
    if constraint_language.upper() != "FILTER":
        raise ValueError(
            "{} is no valid CSW conform value. Choices are `CQL_TEXT, FILTER`".
            format(constraint_language), "constraintlanguage")

    constraint_xml = xml_helper.parse_xml(constraint)
    if constraint_xml is None:
        raise ValueError(
            "Constraint value is no valid xml! Did you set the correct value for 'constraintlanguage'?",
            CONSTRAINT_LOCATOR)
    filter_elem = xml_helper.try_get_single_element_from_xml(
        "//" + GENERIC_NAMESPACE_TEMPLATE.format("Filter"),
        constraint_xml.getroot())
    new_constraint = _transform_constraint_to_cql_recursive(filter_elem)

    return new_constraint
コード例 #25
0
def _transform_constraint_to_cql_recursive(upper_elem: Element):
    constraints = []

    connector_tags = ["and", "or", "not"]
    # Prevent <ogc:Filter> from being used as upper_tag joiner in the end
    upper_tag = QName(upper_elem).localname.lower()
    upper_tag = upper_tag if upper_tag in connector_tags else ""
    elements = upper_elem.getchildren()

    for child in elements:
        child_tag = QName(child).localname
        if child_tag.lower() in connector_tags:
            constraints.append(_transform_constraint_to_cql_recursive(child))
        else:
            property_name = xml_helper.try_get_text_from_xml_element(
                elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("PropertyName"),
                xml_elem=child)
            literal = xml_helper.try_get_text_from_xml_element(
                elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("Literal"),
                xml_elem=child)
            expr = ""
            if child_tag == "PropertyIsLike":
                expr = "like"
                wild_card = xml_helper.try_get_attribute_from_xml_element(
                    child, "wildCard")
                literal = literal.replace(wild_card, "%")
            elif child_tag == "PropertyIsEqualTo":
                expr = "="
            elif child_tag == "PropertyIsNotEqualTo":
                expr = "!="
            elif child_tag == "PropertyIsGreaterThanOrEqualTo":
                expr = ">="
            elif child_tag == "PropertyIsGreaterThan":
                expr = ">"
            elif child_tag == "PropertyIsLessThanOrEqualTo":
                expr = "<="
            elif child_tag == "PropertyIsLessThan":
                expr = "<"
            else:
                raise ValueError("Unsupported {} found!".format(child_tag),
                                 "Filter")
            constraints.append("{} {} {}".format(property_name, expr, literal))
    constraint = " {} ".format(upper_tag).join(constraints)
    return constraint
コード例 #26
0
 def parse_scale_hint(self, layer, layer_obj):
     try:
         scales = xml_helper.try_get_element_from_xml(
             elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("ScaleHint"),
             xml_elem=layer)[0]
         attrs = ["min", "max"]
         for attr in attrs:
             layer_obj.capability_scale_hint[attr] = scales.get(attr)
     except IndexError:
         pass
コード例 #27
0
 def parse_dimension(self, layer, layer_obj):
     dim_list = []
     try:
         dims = xml_helper.try_get_element_from_xml(
             elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("Dimension"),
             xml_elem=layer)
         for dim in dims:
             ext = xml_helper.try_get_single_element_from_xml(
                 elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("Extent") +
                 '[@name="' + dim.get('name') + '"]',
                 xml_elem=layer)
             dim_dict = {
                 "type": dim.get("name"),
                 "units": dim.get("units"),
                 "extent": ext.text,
             }
             dim_list.append(dim_dict)
     except (IndexError, AttributeError) as error:
         pass
     layer_obj.dimension_list = dim_list
コード例 #28
0
ファイル: test_views.py プロジェクト: terrestris/mrmap
    def _get_num_of_layers(self, xml_obj):
        return
        """ Helping function to get the number of the layers in the service

        Args:
            xml_obj: The capabilities xml object
        Returns:
            The number of layer objects inside the xml object
        """
        layer_elems = xml_helper.try_get_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("Layer"), xml_obj) or []
        return len(layer_elems)
コード例 #29
0
    def has_dataset_metadata(self, xml):
        """ Checks whether the xml element has an iso 19115 dataset metadata record or not

        Args:
            xml: The xml etree object
        Returns:
             True if element has dataset metadata, false otherwise
        """
        iso_metadata = xml_helper.try_get_element_from_xml(
            xml_elem=xml,
            elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("MetadataURL"))
        return len(iso_metadata) != 0
コード例 #30
0
    def parse_projection_system(self, layer, layer_obj):
        """ Version specific implementation of the projection system parsing

        Args:
            layer: The xml element which holds the layer info (parsing from)
            layer_obj: The backend model which holds the layer data (parsing to)
        Returns:
             nothing
        """
        crs = xml_helper.try_get_element_from_xml(
            "./" + GENERIC_NAMESPACE_TEMPLATE.format("CRS"), layer)
        for elem in crs:
            layer_obj.capability_projection_system.append(elem.text)