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
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
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
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
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)
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
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)
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)
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)
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
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)))
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)
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] )
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
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
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!")
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)
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)
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
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
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)
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
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)
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
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
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
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
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)
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
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)