def _setconstraint(self, parent, qtype=None, propertyname='csw:AnyText', keywords=[], bbox=None, cql=None, identifier=None): if keywords or bbox is not None or qtype is not None or cql is not None or identifier is not None: node0 = etree.SubElement(parent, util.nspath_eval('csw:Constraint', namespaces)) node0.set('version', '1.1.0') if identifier is not None: # set identifier filter, overrides all other parameters flt = fes.FilterRequest() node0.append(flt.set(identifier=identifier)) elif cql is not None: # send raw CQL query # CQL passed, overrides all other parameters node1 = etree.SubElement(node0, util.nspath_eval('csw:CqlText', namespaces)) node1.text = cql else: # construct a Filter request flt = fes.FilterRequest() node0.append(flt.set(qtype=qtype, keywords=keywords, propertyname=propertyname,bbox=bbox))
def toXML(self): node0 = etree.Element( util.nspath_eval('ogc:PropertyIsLike', namespaces)) node0.set('wildCard', self.wildCard) node0.set('singleChar', self.singleChar) node0.set('escapeChar', self.escapeChar) if not self.matchCase: node0.set('matchCase', 'false') etree.SubElement(node0, util.nspath_eval('ogc:PropertyName', namespaces)).text = self.propertyname etree.SubElement(node0, util.nspath_eval('ogc:Literal', namespaces)).text = self.literal return node0
def toXML(self): node0 = etree.Element( util.nspath_eval('ogc:PropertyIsNull', namespaces)) etree.SubElement(node0, util.nspath_eval('ogc:PropertyName', namespaces)).text = self.propertyname return node0
def toXML(self): tmp = etree.Element(util.nspath_eval('ogc:BBOX', namespaces)) etree.SubElement(tmp, util.nspath_eval('ogc:PropertyName', namespaces)).text = 'ows:BoundingBox' tmp2 = etree.SubElement(tmp, util.nspath_eval('gml:Envelope', namespaces)) if self.crs is not None: tmp2.set('srsName', self.crs) etree.SubElement(tmp2, util.nspath_eval( 'gml:lowerCorner', namespaces)).text = '%s %s' % (self.bbox[0], self.bbox[1]) etree.SubElement(tmp2, util.nspath_eval( 'gml:upperCorner', namespaces)).text = '%s %s' % (self.bbox[2], self.bbox[3]) return tmp
def describerecord(self, typename='csw:Record', format=outputformat): """ Construct and process DescribeRecord request Parameters ---------- - typename: the typename to describe (default is 'csw:Record') - format: the outputFormat (default is 'application/xml') """ # construct request node0 = self._setrootelement('csw:DescribeRecord') node0.set('service', self.service) node0.set('version', self.version) node0.set('outputFormat', format) node0.set('schemaLanguage', namespaces['xs2']) node0.set(util.nspath_eval('xsi:schemaLocation', namespaces), schema_location) etree.SubElement(node0, util.nspath_eval('csw:TypeName', namespaces)).text = typename self.request = node0 self._invoke()
def toXML(self): node0 = etree.Element( util.nspath_eval('ogc:PropertyIsBetween', namespaces)) etree.SubElement(node0, util.nspath_eval('ogc:PropertyName', namespaces)).text = self.propertyname node1 = etree.SubElement( node0, util.nspath_eval('ogc:LowerBoundary', namespaces)) etree.SubElement(node1, util.nspath_eval('ogc:Literal', namespaces)).text = '%s' % self.lower node2 = etree.SubElement( node0, util.nspath_eval('ogc:UpperBoundary', namespaces)) etree.SubElement(node2, util.nspath_eval('ogc:Literal', namespaces)).text = '%s' % self.upper return node0
def harvest(self, source, resourcetype, resourceformat=None, harvestinterval=None, responsehandler=None): """ Construct and process a Harvest request Parameters ---------- - source: a URI to harvest - resourcetype: namespace identifying the type of resource - resourceformat: MIME type of the resource - harvestinterval: frequency of harvesting, in ISO8601 - responsehandler: endpoint that CSW should responsd to with response """ # construct request node0 = self._setrootelement('csw:Harvest') node0.set('version', self.version) node0.set('service', self.service) node0.set(util.nspath_eval('xsi:schemaLocation', namespaces), schema_location) etree.SubElement(node0, util.nspath_eval('csw:Source', namespaces)).text = source etree.SubElement(node0, util.nspath_eval('csw:ResourceType', namespaces)).text = resourcetype if resourceformat is not None: etree.SubElement(node0, util.nspath_eval('csw:ResourceFormat', namespaces)).text = resourceformat if harvestinterval is not None: etree.SubElement(node0, util.nspath_eval('csw:HarvestInterval', namespaces)).text = harvestinterval if responsehandler is not None: etree.SubElement(node0, util.nspath_eval('csw:ResponseHandler', namespaces)).text = responsehandler self.request = node0 self._invoke() self.results = {} if self.exceptionreport is None: val = self._exml.find(util.nspath_eval('csw:Acknowledgement', namespaces)) if util.testXMLValue(val) is not None: ts = val.attrib.get('timeStamp') self.timestamp = util.testXMLValue(ts, True) id = val.find(util.nspath_eval('csw:RequestId', namespaces)) self.id = util.testXMLValue(id) else: self._parsetransactionsummary() self._parseinsertresult()
def _setbbox(self, parent, bbox): """ construct a BBOX search predicate Parameters ---------- - parent: parent etree.Element object - bbox: the bounding box in the form [minx,miny,maxx,maxy] """ tmp = etree.SubElement(parent, util.nspath('BBOX', namespaces['ogc'])) etree.SubElement(tmp, util.nspath('PropertyName', namespaces['ogc'])).text = 'ows:BoundingBox' tmp2 = etree.SubElement(tmp, util.nspath('Envelope', namespaces['gml'])) etree.SubElement(tmp2, util.nspath('lowerCorner', namespaces['gml'])).text = '%s %s' % (bbox[0], bbox[1]) etree.SubElement(tmp2, util.nspath('upperCorner', namespaces['gml'])).text = '%s %s' % (bbox[2], bbox[3])
def setsortby(parent, propertyname, order='ASC'): """ constructs a SortBy element Parameters ---------- - parent: parent etree.Element object - propertyname: the PropertyName - order: the SortOrder (default is 'ASC') """ tmp = etree.SubElement(parent, util.nspath_eval('ogc:SortBy', namespaces)) tmp2 = etree.SubElement(tmp, util.nspath_eval('ogc:SortProperty', namespaces)) etree.SubElement(tmp2, util.nspath_eval('ogc:PropertyName', namespaces)).text = propertyname etree.SubElement(tmp2, util.nspath_eval('ogc:SortOrder', namespaces)).text = order
def axml_styleset(d): # <owc:styleSet> # <owc:name>raster</owc:name> # <owc:title>Default Raster</owc:title> # <owc:abstract>A sample style that draws a </owc:abstract> # <owc:legendURL href="h...." type="image/png"/> # </owc:styleSet> if is_empty(d): return None else: try: styleset = etree.Element(ns_elem("owc", "styleSet"), nsmap=ns) name = extract_p('name', d, None) if name is not None: etree.SubElement(styleset, ns_elem("owc", "name")).text = name title = extract_p('title', d, None) if title is not None: etree.SubElement(styleset, ns_elem("owc", "title")).text = title subtitle = extract_p('abstract', d, None) if subtitle is not None: etree.SubElement(styleset, ns_elem("owc", "abstract")).text = subtitle is_default = extract_p('default', d, None) # TODO no example for default setting on style set if is_default is not None: etree.SubElement(styleset, ns_elem("owc", "default")).text = is_default legend_url = extract_p('legendURL', d, None) if legend_url is not None: etree.SubElement(styleset, ns_elem("owc", "legendURL")).text = legend_url # TODO no example for content on style set content = extract_p('content', d, None) content_enc = None if content is None else axml_content(content) if content_enc is not None: styleset.append(content_enc) return styleset except Exception as ex: log.warning('could encode styleset', ex) return None
def getrecordbyid(self, id=[], esn='full', outputschema=namespaces['csw'], format=outputformat): """ Construct and process a GetRecordById request Parameters ---------- - id: the list of Ids - esn: the ElementSetName 'full', 'brief' or 'summary' (default is 'full') - outputschema: the outputSchema (default is 'http://www.opengis.net/cat/csw/2.0.2') - format: the outputFormat (default is 'application/xml') """ # construct request node0 = etree.Element(util.nspath_eval('csw:GetRecordById', namespaces)) node0.set('outputSchema', outputschema) node0.set('outputFormat', format) node0.set('version', self.version) node0.set('service', self.service) node0.set(util.nspath_eval('xsi:schemaLocation', namespaces), schema_location) for i in id: etree.SubElement(node0, util.nspath_eval('csw:Id', namespaces)).text = i etree.SubElement(node0, util.nspath_eval('csw:ElementSetName', namespaces)).text = esn self.request = util.xml2string(etree.tostring(node0)) self._invoke() if self.exceptionreport is None: self.results = {} self.records = {} self._parserecords(outputschema, esn)
def getdomain(self, dname, dtype='parameter'): """ Construct and process a GetDomain request Parameters ---------- - dname: the value of the Parameter or Property to query - dtype: whether to query a parameter (parameter) or property (property) """ # construct request dtypename = 'ParameterName' node0 = self._setrootelement('csw30:GetDomain') node0.set('service', self.service) node0.set('version', self.version) node0.set(util.nspath_eval('xsi:schemaLocation', namespaces), schema_location) if dtype == 'property': dtypename = 'ValueReference' else: dtypename = 'ParameterName' etree.SubElement(node0, util.nspath_eval('csw30:%s' % dtypename, namespaces)).text = dname self.request = node0 self._invoke() if self.exceptionreport is None: self.results = {} val = self._exml.find( util.nspath_eval('csw30:DomainValues', namespaces)).attrib.get('type') self.results['type'] = util.testXMLValue(val, True) val = self._exml.find( util.nspath_eval('csw30:DomainValues/csw30:%s' % dtypename, namespaces)) self.results[dtype] = util.testXMLValue(val) # get the list of values associated with the Domain self.results['values'] = [] for f in self._exml.findall( util.nspath_eval( 'csw30:DomainValues/csw30:ListOfValues/csw30:Value', namespaces)): # noqa self.results['values'].append(util.testXMLValue(f))
def _setpropertyisequalto(self, parent, propertyname, literal, matchcase=True): """ construct a PropertyIsEqualTo Parameters ---------- - parent: parent etree.Element object - propertyname: the PropertyName - literal: the Literal value - matchcase: whether to perform a case insensitve query (default is True) """ tmp = etree.SubElement(parent, util.nspath('PropertyIsEqualTo', namespaces['ogc'])) if matchcase is False: tmp.set('matchCase', 'false') etree.SubElement(tmp, util.nspath('PropertyName', namespaces['ogc'])).text = propertyname etree.SubElement(tmp, util.nspath('Literal', namespaces['ogc'])).text = literal
def axml_author(d): # <author> .. # <name> # <email> if is_empty(d): return None else: try: author = etree.Element("author", nsmap=ns) name = extract_p('name', d, None) if name is not None: etree.SubElement(author, "name").text = name email = extract_p('email', d, None) if email is not None: etree.SubElement(author, "email").text = email uri = extract_p('uri', d, None) if uri is not None: etree.SubElement(author, "uri").text = uri return author except Exception as ex: log.warn('could encode author', ex) return None
def set_bbox(self, bbox): """Set a bbox filter. Cannot be used with set_featureid() or set_filter(). """ filter_tree = etree.SubElement(self._query, util.nspath('Filter', OGC_NAMESPACE)) bbox_tree = etree.SubElement(filter_tree, util.nspath('BBOX', OGC_NAMESPACE)) coords = etree.SubElement(bbox_tree, util.nspath('Envelope', GML_NAMESPACE)) if len(bbox) > 4: coords.set('srsName', bbox[4]) lower = etree.SubElement(coords, util.nspath('lowerCorner', GML_NAMESPACE)) lower.text = '{} {}'.format(bbox[0], bbox[1]) upper = etree.SubElement(coords, util.nspath('upperCorner', GML_NAMESPACE)) upper.text = '{} {}'.format(bbox[2], bbox[3])
def set_featureid(self, featureid): """Set filter by feature id. Cannot be used with set_bbox() or set_filter(). """ feature_tree = etree.SubElement(self._query, util.nspath('Filter', FES_NAMESPACE)) for ft in featureid: prop_id = etree.Element(util.nspath('ResourceId', FES_NAMESPACE)) prop_id.set('rid', ft) feature_tree.append(prop_id)
def set_featureid(self, featureid): """Set filter by feature id. Cannot be used with set_bbox() or set_filter(). """ feature_tree = etree.SubElement(self._query, util.nspath('Filter', OGC_NAMESPACE)) for ft in featureid: prop_id = etree.Element(util.nspath('GmlObjectId', OGC_NAMESPACE)) prop_id.set(util.nspath('id', GML_NAMESPACE), ft) feature_tree.append(prop_id)
def toXML(self): """Return `lxml.etree.Element` object.""" node = etree.Element(prefix("gml32:Point")) for key in ["id", "srsName"]: if getattr(self, key, None) is not None: node.set(prefix(f"gml32:{key}"), getattr(self, key)) for key in [ "description", "descriptionReference", "identifier", "name" ]: content = getattr(self, key) if content is not None: etree.SubElement(node, prefix(f"gml32:{key}")).text = content coords = etree.SubElement(node, prefix("gml32:pos")) coords.text = " ".join([str(c) for c in self.pos]) for key in ["srsDimension"]: if getattr(self, key, None) is not None: node.set(prefix(f"gml32:{key}"), getattr(self, key)) return node
def _create_elements(self, start_element, list_of_element_names): tree = self.record_etree base_element = start_element for elem_name in list_of_element_names: elem_name_split = elem_name.split(":") ns = "{" + self.namespaces[elem_name_split[0]] + "}" base_element = etree.SubElement(base_element, "{ns}".format(ns=ns) + elem_name_split[1], nsmap=self.namespaces) log.debug("Created {n}".format(n=elem_name)) self.tree_changed = True
def _setpropertyislike(self, parent, propertyname, literal, wildcard='%', singlechar='_', escapechar='\\'): """ construct a PropertyIsLike Parameters ---------- - parent: parent etree.Element object - propertyname: the PropertyName - literal: the Literal value - wildcard: the wildCard character (default is '%') - singlechar: the singleChar character (default is '_') - escapechar: the escapeChar character (default is '\') """ tmp = etree.SubElement(parent, util.nspath('PropertyIsLike', namespaces['ogc'])) tmp.set('wildCard', wildcard) tmp.set('singleChar', singlechar) tmp.set('escapeChar', escapechar) etree.SubElement(tmp, util.nspath('PropertyName', namespaces['ogc'])).text = propertyname etree.SubElement(tmp, util.nspath('Literal', namespaces['ogc'])).text = literal
def axml_display(d): # <owc:display> # <owc:pixelWidth> if is_empty(d): return None else: try: creator_display = etree.Element(ns_elem("owc", "display"), nsmap=ns) pixel_width = try_int(extract_p('pixelWidth', d, None)) if pixel_width is not None: etree.SubElement(creator_display, ns_elem( "owc", "pixelWidth")).text = str(pixel_width) pixel_height = try_int(extract_p('pixelHeight', d, None)) if pixel_height is not None: etree.SubElement(creator_display, ns_elem( "owc", "pixelHeight")).text = str(pixel_height) mm_per_pixel = try_float(extract_p('mmPerPixel', d, None)) if mm_per_pixel is not None: etree.SubElement(creator_display, ns_elem( "owc", "mmPerPixel")).text = str(mm_per_pixel) return creator_display except Exception as ex: log.warn('could encode creator_display', ex) return None
def getdomain(self, dname, dtype='parameter'): """ Construct and process a GetDomain request Parameters ---------- - dname: the value of the Parameter or Property to query - dtype: whether to query a parameter (parameter) or property (property) """ # construct request dtypename = 'ParameterName' node0 = etree.Element(util.nspath('GetDomain', namespaces['csw'])) node0.set('service', self.service) node0.set('version', self.version) node0.set(util.nspath('schemaLocation', namespaces['xsi']), schema_location) if dtype == 'property': dtypename = 'PropertyName' etree.SubElement(node0, util.nspath(dtypename, namespaces['csw'])).text = dname self.request = util.xml2string(etree.tostring(node0)) self._invoke() if self.exceptionreport is None: self.results = {} val = self._exml.find( util.nspath('DomainValues', namespaces['csw'])).attrib.get('type') self.results['type'] = util.testXMLValue(val, True) val = self._exml.find( util.nspath('DomainValues/' + dtypename, namespaces['csw'])) self.results[dtype] = util.testXMLValue(val) # get the list of values associated with the Domain self.results['values'] = [] for f in self._exml.findall( util.nspath('DomainValues/ListOfValues/Value', namespaces['csw'])): self.results['values'].append(util.testXMLValue(f))
def getrecords(self, qtype=None, keywords=[], typenames='csw:Record', propertyname='csw:AnyText', bbox=None, esn='summary', sortby=None, outputschema=namespaces['csw'], format=outputformat, startposition=0, maxrecords=10, cql=None, xml=None, resulttype='results'): """ Construct and process a GetRecords request Parameters ---------- - qtype: type of resource to query (i.e. service, dataset) - keywords: list of keywords - typenames: the typeNames to query against (default is csw:Record) - propertyname: the PropertyName to Filter against - bbox: the bounding box of the spatial query in the form [minx,miny,maxx,maxy] - esn: the ElementSetName 'full', 'brief' or 'summary' (default is 'summary') - sortby: property to sort results on - outputschema: the outputSchema (default is 'http://www.opengis.net/cat/csw/2.0.2') - format: the outputFormat (default is 'application/xml') - startposition: requests a slice of the result set, starting at this position (default is 0) - maxrecords: the maximum number of records to return. No records are returned if 0 (default is 10) - cql: common query language text. Note this overrides bbox, qtype, keywords - xml: raw XML request. Note this overrides all other options - resulttype: the resultType 'hits', 'results', 'validate' (default is 'results') """ warnings.warn( """Please use the updated 'getrecords2' method instead of 'getrecords'. The 'getrecords' method will be upgraded to use the 'getrecords2' parameters in a future version of OWSLib.""") if xml is not None: self.request = etree.fromstring(xml) val = self.request.find( util.nspath_eval('csw:Query/csw:ElementSetName', namespaces)) if val is not None: esn = util.testXMLValue(val) else: # construct request node0 = self._setrootelement('csw:GetRecords') if etree.__name__ != 'lxml.etree': # apply nsmap manually node0.set('xmlns:ows', namespaces['ows']) node0.set('xmlns:gmd', namespaces['gmd']) node0.set('xmlns:dif', namespaces['dif']) node0.set('xmlns:fgdc', namespaces['fgdc']) node0.set('outputSchema', outputschema) node0.set('outputFormat', format) node0.set('version', self.version) node0.set('resultType', resulttype) node0.set('service', self.service) if startposition > 0: node0.set('startPosition', str(startposition)) node0.set('maxRecords', str(maxrecords)) node0.set(util.nspath_eval('xsi:schemaLocation', namespaces), schema_location) node1 = etree.SubElement(node0, util.nspath_eval('csw:Query', namespaces)) node1.set('typeNames', typenames) etree.SubElement( node1, util.nspath_eval('csw:ElementSetName', namespaces)).text = esn self._setconstraint(node1, qtype, propertyname, keywords, bbox, cql, None) if sortby is not None: fes.setsortby(node1, sortby) self.request = node0 self._invoke() if self.exceptionreport is None: self.results = {} # process search results attributes val = self._exml.find( util.nspath_eval( 'csw:SearchResults', namespaces)).attrib.get('numberOfRecordsMatched') self.results['matches'] = int(util.testXMLValue(val, True)) val = self._exml.find( util.nspath_eval( 'csw:SearchResults', namespaces)).attrib.get('numberOfRecordsReturned') self.results['returned'] = int(util.testXMLValue(val, True)) val = self._exml.find( util.nspath_eval('csw:SearchResults', namespaces)).attrib.get('nextRecord') self.results['nextrecord'] = int(util.testXMLValue(val, True)) # process list of matching records self.records = OrderedDict() self._parserecords(outputschema, esn)
def axml_context(d): """ encodes base OwcContext as dict to atom xml tree :param d: :return: """ xml = etree.Element("feed", nsmap=ns) etree.SubElement(xml, "id").text = d['id'] spec_reference = [ axml_link(do) for do in extract_p('properties.links.profiles', d, []) ] [xml.append(el) for el in spec_reference if el is not None] area_of_interest = extract_p('bbox', d, None) if area_of_interest is not None: try: gml = etree.fromstring(area_of_interest) georss = etree.SubElement(xml, ns_elem("georss", "where")) georss.append(gml) except Exception as ex: log.warning('could encode bbox into georss:where', ex) pass context_metadata = [ axml_link(do) for do in extract_p('properties.links.via', d, []) ] [xml.append(el) for el in context_metadata if el is not None] language = extract_p('properties.lang', d, None) if language is not None: xml.set(ns_elem("xml", "lang"), language) title = extract_p('properties.title', d, None) if title is not None: etree.SubElement(xml, "title").text = title # <subtitle type = "html" subtitle = extract_p('properties.abstract', d, None) if subtitle is not None: etree.SubElement(xml, "subtitle").text = subtitle update_date = extract_p('properties.updated', d, None) if update_date is not None: etree.SubElement(xml, "updated").text = update_date authors = [ axml_author(do) for do in extract_p('properties.authors', d, []) ] [xml.append(el) for el in authors if el is not None] publisher = extract_p('properties.publisher', d, None) if publisher is not None: etree.SubElement(xml, ns_elem("dc", "publisher")).text = publisher creator_application = axml_creator_app( extract_p('properties.generator', d, None)) if creator_application is not None and not is_empty(creator_application): xml.append(creator_application) creator_display = axml_display(extract_p('properties.display', d, None)) if creator_display is not None: xml.append(creator_display) rights = extract_p('properties.rights', d, None) if rights is not None: etree.SubElement(xml, "rights").text = rights time_interval_of_interest = extract_p('properties.date', d, None) if time_interval_of_interest is not None: etree.SubElement(xml, ns_elem("dc", "date")).text = time_interval_of_interest keywords = [ axml_category(do) for do in extract_p('properties.categories', d, []) ] [xml.append(el) for el in keywords if el is not None] # here we generate single elements and attach them resources = [axml_resource(do) for do in extract_p('features', d, [])] [xml.append(el) for el in resources if el is not None] return xml
def toXML(self): node0 = etree.Element(util.nspath_eval("ogc:SortProperty", namespaces)) etree.SubElement(node0, util.nspath_eval('ogc:PropertyName', namespaces)).text = self.propertyname etree.SubElement(node0, util.nspath_eval('ogc:SortOrder', namespaces)).text = self.order return node0
def axml_resource(d): """ encodes an OwcResource as dict into atom xml tree :param d: :return: """ entry = etree.Element("entry", nsmap=ns) etree.SubElement(entry, "id").text = d['id'] geospatial_extent = extract_p('geometry', d, None) if geospatial_extent is not None: try: gml = etree.fromstring(geospatial_extent) georss = etree.SubElement(entry, ns_elem("georss", "where")) georss.append(gml) except Exception as ex: log.warning('could encode geometry into georss:where', ex) pass title = d['properties']['title'] if title is not None: etree.SubElement(entry, "title").text = title subtitle = extract_p('properties.abstract', d, None) # <content type = "text" > if subtitle is not None: etree.SubElement(entry, "content").text = subtitle update_date = extract_p('properties.updated', d, None) if update_date is not None: etree.SubElement(entry, "updated").text = update_date authors = [ axml_author(do) for do in extract_p('properties.authors', d, []) ] [entry.append(el) for el in authors if el is not None] publisher = extract_p('properties.publisher', d, None) if update_date is not None: etree.SubElement(entry, ns_elem("dc", "publisher")).text = publisher rights = extract_p('properties.rights', d, None) if update_date is not None: etree.SubElement(entry, ns_elem("dc", "rights")).text = rights temporal_extent = extract_p('properties.date', d, None) if temporal_extent is not None: etree.SubElement(entry, "date").text = temporal_extent keywords = [ axml_category(do) for do in extract_p('properties.categories', d, []) ] [entry.append(el) for el in keywords if el is not None] resource_metadata = [ axml_link(do) for do in extract_p('properties.links.via', d, []) ] [entry.append(el) for el in resource_metadata if el is not None] content_description = [ axml_content(do) for do in extract_p('properties.links.alternates', d, []) ] [entry.append(el) for el in content_description if el is not None] preview = [ axml_link(do) for do in extract_p('properties.links.preview', d, []) ] [entry.append(el) for el in preview if el is not None] content_by_ref = [ axml_link(do) for do in extract_p('properties.links.data', d, []) ] [entry.append(el) for el in content_by_ref if el is not None] offerings = [ axml_offering(do) for do in extract_p('properties.offerings', d, []) ] [entry.append(el) for el in offerings if el is not None] # TODO no examples for active attribute active = extract_p('properties.active', d, None) if active is not None: etree.SubElement(entry, "active").text = active min_scale_denominator = try_float( extract_p('properties.minscaledenominator', d, None)) # <owc:minScaleDenominator>2500</owc:minScaleDenominator> if min_scale_denominator is not None: etree.SubElement(entry, ns_elem( "owc", "minScaleDenominator")).text = str(min_scale_denominator) max_scale_denominator = try_float( extract_p('properties.maxscaledenominator', d, None)) # <owc:maxScaleDenominator>25000</owc:maxScaleDenominator> if max_scale_denominator is not None: etree.SubElement(entry, ns_elem( "owc", "maxScaleDenominator")).text = str(max_scale_denominator) # TODO no examples for folder attribute folder = extract_p('properties.folder', d, None) if folder is not None: etree.SubElement(entry, "folder").text = folder # xml.append(entry) return entry
def getrecords2(self, constraints=[], sortby=None, typenames='csw:Record', esn='summary', outputschema=namespaces['csw'], format=outputformat, startposition=0, maxrecords=10, cql=None, xml=None, resulttype='results'): """ Construct and process a GetRecords request Parameters ---------- - constraints: the list of constraints (OgcExpression from owslib.fes module) - sortby: an OGC SortBy object (SortBy from owslib.fes module) - typenames: the typeNames to query against (default is csw:Record) - esn: the ElementSetName 'full', 'brief' or 'summary' (default is 'summary') - outputschema: the outputSchema (default is 'http://www.opengis.net/cat/csw/2.0.2') - format: the outputFormat (default is 'application/xml') - startposition: requests a slice of the result set, starting at this position (default is 0) - maxrecords: the maximum number of records to return. No records are returned if 0 (default is 10) - cql: common query language text. Note this overrides bbox, qtype, keywords - xml: raw XML request. Note this overrides all other options - resulttype: the resultType 'hits', 'results', 'validate' (default is 'results') """ if xml is not None: self.request = etree.fromstring(xml) val = self.request.find( util.nspath_eval('csw:Query/csw:ElementSetName', namespaces)) if val is not None: esn = util.testXMLValue(val) val = self.request.attrib.get('outputSchema') if val is not None: outputschema = util.testXMLValue(val, True) else: # construct request node0 = self._setrootelement('csw:GetRecords') if etree.__name__ != 'lxml.etree': # apply nsmap manually node0.set('xmlns:ows', namespaces['ows']) node0.set('xmlns:gmd', namespaces['gmd']) node0.set('xmlns:dif', namespaces['dif']) node0.set('xmlns:fgdc', namespaces['fgdc']) node0.set('outputSchema', outputschema) node0.set('outputFormat', format) node0.set('version', self.version) node0.set('service', self.service) node0.set('resultType', resulttype) if startposition > 0: node0.set('startPosition', str(startposition)) node0.set('maxRecords', str(maxrecords)) node0.set(util.nspath_eval('xsi:schemaLocation', namespaces), schema_location) node1 = etree.SubElement(node0, util.nspath_eval('csw:Query', namespaces)) node1.set('typeNames', typenames) etree.SubElement( node1, util.nspath_eval('csw:ElementSetName', namespaces)).text = esn if any([len(constraints) > 0, cql is not None]): node2 = etree.SubElement( node1, util.nspath_eval('csw:Constraint', namespaces)) node2.set('version', '1.1.0') flt = fes.FilterRequest() if len(constraints) > 0: node2.append(flt.setConstraintList(constraints)) # Now add a CQL filter if passed in elif cql is not None: etree.SubElement( node2, util.nspath_eval('csw:CqlText', namespaces)).text = cql if sortby is not None and isinstance(sortby, fes.SortBy): node1.append(sortby.toXML()) self.request = node0 self._invoke() if self.exceptionreport is None: self.results = {} # process search results attributes val = self._exml.find( util.nspath_eval( 'csw:SearchResults', namespaces)).attrib.get('numberOfRecordsMatched') self.results['matches'] = int(util.testXMLValue(val, True)) val = self._exml.find( util.nspath_eval( 'csw:SearchResults', namespaces)).attrib.get('numberOfRecordsReturned') self.results['returned'] = int(util.testXMLValue(val, True)) val = self._exml.find( util.nspath_eval('csw:SearchResults', namespaces)).attrib.get('nextRecord') if val is not None: self.results['nextrecord'] = int(util.testXMLValue(val, True)) else: warnings.warn( """CSW Server did not supply a nextRecord value (it is optional), so the client should page through the results in another way.""") # For more info, see: # https://github.com/geopython/OWSLib/issues/100 self.results['nextrecord'] = None # process list of matching records self.records = OrderedDict() self._parserecords(outputschema, esn)
def set_propertyname(self, propertyname): """Set which feature properties will be returned. If not set, will return all properties.""" for pn in propertyname: etree.SubElement(self._query, "PropertyName").text = pn
def transaction(self, ttype=None, typename='csw:Record', record=None, propertyname=None, propertyvalue=None, bbox=None, keywords=[], cql=None, identifier=None): """ Construct and process a Transaction request Parameters ---------- - ttype: the type of transaction 'insert, 'update', 'delete' - typename: the typename to describe (default is 'csw:Record') - record: the XML record to insert - propertyname: the RecordProperty/PropertyName to Filter against - propertyvalue: the RecordProperty Value to Filter against (for updates) - bbox: the bounding box of the spatial query in the form [minx,miny,maxx,maxy] - keywords: list of keywords - cql: common query language text. Note this overrides bbox, qtype, keywords - identifier: record identifier. Note this overrides bbox, qtype, keywords, cql """ # construct request node0 = self._setrootelement('csw:Transaction') node0.set('version', self.version) node0.set('service', self.service) node0.set(util.nspath_eval('xsi:schemaLocation', namespaces), schema_location) validtransactions = ['insert', 'update', 'delete'] if ttype not in validtransactions: # invalid transaction raise RuntimeError('Invalid transaction \'%s\'.' % ttype) node1 = etree.SubElement( node0, util.nspath_eval('csw:%s' % ttype.capitalize(), namespaces)) if ttype != 'update': node1.set('typeName', typename) if ttype == 'insert': if record is None: raise RuntimeError('Nothing to insert.') node1.append(etree.fromstring(record)) if ttype == 'update': if record is not None: node1.append(etree.fromstring(record)) else: if propertyname is not None and propertyvalue is not None: node2 = etree.SubElement( node1, util.nspath_eval('csw:RecordProperty', namespaces)) etree.SubElement(node2, util.nspath_eval( 'csw:Name', namespaces)).text = propertyname etree.SubElement(node2, util.nspath_eval( 'csw:Value', namespaces)).text = propertyvalue self._setconstraint(node1, qtype, propertyname, keywords, bbox, cql, identifier) if ttype == 'delete': self._setconstraint(node1, None, propertyname, keywords, bbox, cql, identifier) self.request = node0 self._invoke() self.results = {} if self.exceptionreport is None: self._parsetransactionsummary() self._parseinsertresult()
def _create_query(self, typename): self._query = etree.SubElement( self._root, util.nspath('Query', self._wfsnamespace))