def parse(self, xml): xml = XMLParser.parse(self, xml) _, self.offering.identifier = self.searchFirst(xml, "identifier") _, self.offering.procedure = self.searchFirst(xml, "procedure") for _, value in self.search(xml, "procedureDescriptionFormat"): self.offering.procedureDescriptionFormats.append(value) for _, value in self.search(xml, "observableProperty"): _, self.offering.observableProperties.append(value) observedAreaNode, observedAreaType = self.searchFirst( xml, "observedArea/*") if observedAreaNode: _, self.offering.srsName = self.searchFirst( observedAreaNode, "@srsName") if observedAreaType == "Envelope": self.offering.observedArea = GMLParser.rectangleFromGMLEnvelope( observedAreaNode) elif observedAreaType == "Box": self.offering.observedArea = GMLParser.rectangleFromGMLBox( observedAreaNode) else: geo = GMLParser.geometryFromGML(observedAreaNode) if geo: self.offering.observedArea = geo.boundingBox() else: self.offering.observedArea = QgsRectangle() timeNode, timePrimitive = self.searchFirst(xml, "phenomenonTime/*") if timePrimitive: try: gmlTimeParser = XMLParserFactory.getInstance("GML" + timePrimitive) self.offering.phenomenonTime = gmlTimeParser().parse(timeNode) except NotImplementedError: self.offering.phenomenonTime = QgsTime() resultTimeNode, resultTimePrimitive = self.searchFirst( xml, "resultTime/*") if resultTimePrimitive: try: gmlTimeParser = XMLParserFactory.getInstance( "GML" + resultTimePrimitive) self.offering.resultTime = gmlTimeParser().parse( resultTimeNode) except NotImplementedError: self.offering.resultTime = QgsTime() _, self.offering.featureOfInterestType = self.searchFirst( xml, "featureOfInterestType") for _, value in self.search(xml, "responseFormat"): self.offering.responseFormats.append(value) for _, value in self.search(xml, "observationType"): _, self.offering.observationTypes.append(value) return self.offering
def parse (self, xml): xml = XMLParser.parse(self, xml) _, self.offering.id = self.searchFirst (xml, "@id") _, self.offering.name = self.searchFirst (xml, "name") _, self.offering.description = self.searchFirst (xml, "description") boundedByNode, boundedByType = self.searchFirst (xml, "boundedBy/*") _, self.offering.srsName = self.searchFirst (boundedByNode, "@srsName") if boundedByType == "Envelope": self.offering.boundedBy = GMLParser.rectangleFromGMLEnvelope(boundedByNode) elif boundedByType == "Box": self.offering.boundedBy = GMLParser.rectangleFromGMLBox(boundedByNode) else: geo = GMLParser.geometryFromGML(boundedByNode) if geo: self.offering.boundedBy = geo.boundingBox() else: self.offering.boundedBy = QgsRectangle() timeNode, timePrimitive = self.searchFirst (xml, "time/*") if timePrimitive: try: gmlTimeParser = XMLParserFactory.getInstance ("GML" + timePrimitive) self.offering.time = gmlTimeParser().parse(timeNode) except NotImplementedError: self.offering.time = QgsTime() self.offering.proceduresList = [] for _, value in self.search (xml, "procedure@href"): self.offering.proceduresList.append(value) self.offering.observedPropertiesList = [] for _, value in self.search (xml, "observedProperty@href"): self.offering.observedPropertiesList.append(value) self.offering.featureOfInterestList = [] for _, value in self.search (xml, "featureOfInterest@href"): self.offering.featureOfInterestList.append(value) for _, value in self.search (xml, "responseFormat"): if value in ['text/xml;subtype="om/1.0.0"']: self.offering.responseFormat = value break for _, value in self.search (xml, "resultModel"): self.offering.resultModel.append(value) for _, value in self.search (xml, "responseMode"): if value in ['inline']: self.offering.responseMode = value break return self.offering
def parse(self, xml): xml = XMLParser.parse(self, xml) node, _ = self.searchFirst(xml, "") if not node or not node.localName() == "ObservationCollection": if node.localName() == "ExceptionReport": node, exceptionCode = self.searchFirst( node, "Exception@exceptionCode") _, exceptionText = self.searchFirst(node, "ExceptionText") raise sos.ExceptionReport(exceptionCode, exceptionText) raise ValueError(node.localName()) boundedByNode, boundedByType = self.searchFirst(xml, "boundedBy/*") _, self.provider.srsName = self.searchFirst(boundedByNode, "@srsName") crs = QgsCoordinateReferenceSystem() if crs.createFromUserInput(self.provider.srsName): yx = crs.axisInverted() else: yx = (self.provider.srsName == 'urn:ogc:def:crs:EPSG:0' ) #Hack para meteogalicia if boundedByType == "Envelope": self.provider.extent = GMLParser.rectangleFromGMLEnvelope( boundedByNode) elif boundedByType == "Box": self.provider.extent = GMLParser.rectangleFromGMLBox(boundedByNode) else: geo = GMLParser.geometryFromGML(boundedByNode) if geo: self.provider.extent = geo.boundingBox() _, tag = self.searchFirst(xml, 'member/*') omParser = XMLParserFactory.getInstance(tag)(self.provider, yx) components = omParser.parse(xml) components = filter(lambda f: f != None, components.values()) hasTime = False for i, f in enumerate(components): if f.name() == "Time" or f.name() == "SamplingTime": components.pop(i) f.setName("Time") self.provider.fields.append(f) hasTime = True break if not hasTime: self.provider.fields.append(QgsField("Time", QVariant.String, '')) self.provider.fields.extend(components) return self.provider
def parse (self, xml): xml = XMLParser.parse(self, xml) _, self.offering.identifier = self.searchFirst (xml, "identifier") _, self.offering.procedure = self.searchFirst (xml, "procedure") for _, value in self.search (xml, "procedureDescriptionFormat"): self.offering.procedureDescriptionFormats.append(value) for _, value in self.search (xml, "observableProperty"): _, self.offering.observableProperties.append(value) observedAreaNode, observedAreaType = self.searchFirst (xml, "observedArea/*") if observedAreaNode: _, self.offering.srsName = self.searchFirst (observedAreaNode, "@srsName") if observedAreaType == "Envelope": self.offering.observedArea = GMLParser.rectangleFromGMLEnvelope(observedAreaNode) elif observedAreaType == "Box": self.offering.observedArea = GMLParser.rectangleFromGMLBox(observedAreaNode) else: geo = GMLParser.geometryFromGML(observedAreaNode) if geo: self.offering.observedArea = geo.boundingBox() else: self.offering.observedArea = QgsRectangle() timeNode, timePrimitive = self.searchFirst (xml, "phenomenonTime/*") if timePrimitive: try: gmlTimeParser = XMLParserFactory.getInstance ("GML" + timePrimitive) self.offering.phenomenonTime = gmlTimeParser().parse(timeNode) except NotImplementedError: self.offering.phenomenonTime = QgsTime() resultTimeNode, resultTimePrimitive = self.searchFirst (xml, "resultTime/*") if resultTimePrimitive: try: gmlTimeParser = XMLParserFactory.getInstance ("GML" + resultTimePrimitive) self.offering.resultTime = gmlTimeParser().parse(resultTimeNode) except NotImplementedError: self.offering.resultTime = QgsTime() _, self.offering.featureOfInterestType = self.searchFirst (xml, "featureOfInterestType") for _, value in self.search (xml, "responseFormat"): self.offering.responseFormats.append(value) for _, value in self.search (xml, "observationType"): _, self.offering.observationTypes.append(value) return self.offering
def parse (self, xml): def _float (value): try: return float(value) except: return None components = {} for member, _ in self.search(xml, "member"): for node, tag in self.search (member, "Measurement/*"): if tag == "samplingTime": samplingTime = self.timeParser.parse(node) elif tag == "observedProperty": _, prop = self.searchFirst(node, "@href") if not prop in components: components[prop] = None elif tag == "featureOfInterest": hasSamplingPoint = False for point, foi_id in chain(self.search (node, "FeatureCollection/featureMember/SamplingPoint@id"),self.search (node, "SamplingPoint@id"),self.search (node, "SamplingPointAtDepth@id")): hasSamplingPoint = True _, name = self.searchFirst (point, "name") pointGeo, _ = self.searchFirst(point, "position") pointGeo = GMLParser.geometryFromGML(pointGeo) if self.yx: pointGeo = pointGeo.asPoint() pointGeo = QgsGeometry.fromPoint(QgsPoint (pointGeo.y(),pointGeo.x())) self.provider.features [foi_id] = (name, pointGeo) if point.localName () == "SamplingPointAtDepth": _, depth = self.searchFirst (point, "depth") foi_id = (foi_id, depth) if not hasSamplingPoint: for _, foi_id in self.search (node, "FeatureCollection/featureMember@href"): self.provider.features [foi_id] = (foi_id, None) elif node.localName () == "result": self.provider.setObservation (unicode(foi_id), QDateTime.fromString(str(samplingTime), Qt.ISODate), unicode(prop), str(tag)) if prop in components and components[prop] == None: components[prop] = QgsField (prop, QVariant.Double if _float(tag) else QVariant.String, node.attribute("uom")) return components
def parse (self, xml): xml = XMLParser.parse(self, xml) node,_ = self.searchFirst (xml, "") if not node or not node.localName() == "ObservationCollection": if node.localName() == "ExceptionReport": node, exceptionCode = self.searchFirst(node, "Exception@exceptionCode") _, exceptionText = self.searchFirst(node, "ExceptionText") raise sos.ExceptionReport (exceptionCode, exceptionText) raise ValueError (node.localName()) boundedByNode, boundedByType = self.searchFirst (xml, "boundedBy/*") _, self.provider.srsName = self.searchFirst (boundedByNode, "@srsName") crs = QgsCoordinateReferenceSystem() if crs.createFromUserInput(self.provider.srsName): yx = crs.axisInverted() else: yx = (self.provider.srsName == 'urn:ogc:def:crs:EPSG:0') #Hack para meteogalicia if boundedByType == "Envelope": self.provider.extent = GMLParser.rectangleFromGMLEnvelope(boundedByNode) elif boundedByType == "Box": self.provider.extent = GMLParser.rectangleFromGMLBox(boundedByNode) else: geo = GMLParser.geometryFromGML(boundedByNode) if geo: self.provider.extent = geo.boundingBox() _, tag = self.searchFirst(xml, 'member/*') omParser = XMLParserFactory.getInstance(tag)(self.provider, yx) components = omParser.parse(xml) components = filter(lambda f: f != None, components.values()) hasTime = False for i, f in enumerate(components): if f.name() == "Time" or f.name() == "SamplingTime": components.pop (i) f.setName("Time") self.provider.fields.append(f) hasTime = True break if not hasTime: self.provider.fields.append(QgsField ("Time", QVariant.String, '')) self.provider.fields.extend(components) return self.provider
def createFunctionElement(document, element, function): expr = QgsExpression(function) if expr.hasParserError(): element.appendChild(document.createComment("Parser Error")) return False filterElem = QgsOgcUtils.expressionToOgcFilter(expr, document) if filterElem: element.appendChild(filterElem) # NOTE: in qgis2 filterElem was tuple return True
def parse(self, xml): def _float(value): try: return float(value) except: return None components = {} for member, _ in self.search(xml, "member"): for node, tag in self.search(member, "Measurement/*"): if tag == "samplingTime": samplingTime = self.timeParser.parse(node) elif tag == "observedProperty": _, prop = self.searchFirst(node, "@href") if not prop in components: components[prop] = None elif tag == "featureOfInterest": hasSamplingPoint = False for point, foi_id in chain( self.search( node, "FeatureCollection/featureMember/SamplingPoint@id" ), self.search(node, "SamplingPoint@id"), self.search(node, "SamplingPointAtDepth@id")): hasSamplingPoint = True _, name = self.searchFirst(point, "name") pointGeo, _ = self.searchFirst(point, "position") pointGeo = GMLParser.geometryFromGML(pointGeo) if self.yx: pointGeo = pointGeo.asPoint() pointGeo = QgsGeometry.fromPoint( QgsPoint(pointGeo.y(), pointGeo.x())) self.provider.features[foi_id] = (name, pointGeo) if point.localName() == "SamplingPointAtDepth": _, depth = self.searchFirst(point, "depth") foi_id = (foi_id, depth) if not hasSamplingPoint: for _, foi_id in self.search( node, "FeatureCollection/featureMember@href"): self.provider.features[foi_id] = (foi_id, None) elif node.localName() == "result": self.provider.setObservation( unicode(foi_id), QDateTime.fromString(str(samplingTime), Qt.ISODate), unicode(prop), str(tag)) if prop in components and components[prop] == None: components[prop] = QgsField( prop, QVariant.Double if _float(tag) else QVariant.String, node.attribute("uom")) return components
def test_expressionFromOgcFilterWithAndOrPropertyIsLike(self): """ Test expressionFromOgcFilter with And, Or and PropertyIsLike with wildCard """ vl = QgsVectorLayer('Point', 'vl', 'memory') vl.dataProvider().addAttributes([ QgsField('id', QVariant.LongLong), QgsField('THEME', QVariant.String), QgsField('PROGRAMME', QVariant.String) ]) vl.updateFields() f = '''<?xml version="1.0" encoding="UTF-8"?> <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"> <ogc:And> <ogc:PropertyIsLike escape="\\" wildCard="%" singleChar="_"> <ogc:PropertyName>THEME</ogc:PropertyName> <ogc:Literal>%Phytoplancton total%</ogc:Literal> </ogc:PropertyIsLike> <ogc:Or> <ogc:PropertyIsLike escapeChar="\\" matchCase="false" singleChar="?" wildCard="*"> <ogc:PropertyName>PROGRAMME</ogc:PropertyName> <ogc:Literal>REPHY;*</ogc:Literal> </ogc:PropertyIsLike> <ogc:PropertyIsLike escapeChar="\\" matchCase="false" singleChar="?" wildCard="*"> <ogc:PropertyName>PROGRAMME</ogc:PropertyName> <ogc:Literal>*;REPHY</ogc:Literal> </ogc:PropertyIsLike> <ogc:PropertyIsLike escapeChar="\\" matchCase="false" singleChar="?" wildCard="*"> <ogc:PropertyName>PROGRAMME</ogc:PropertyName> <ogc:Literal>*;REPHY;*</ogc:Literal> </ogc:PropertyIsLike> <ogc:PropertyIsLike escapeChar="\\" matchCase="false" singleChar="?" wildCard="*"> <ogc:PropertyName>PROGRAMME</ogc:PropertyName> <ogc:Literal>^REPHY$</ogc:Literal> </ogc:PropertyIsLike> </ogc:Or> </ogc:And> </ogc:Filter> ''' d = QDomDocument('filter') d.setContent(f, True) e = QgsOgcUtils.expressionFromOgcFilter(d.documentElement(), vl) self.assertEqual( e.expression(), 'THEME LIKE \'%Phytoplancton total%\' AND (PROGRAMME ILIKE \'REPHY;%\' OR PROGRAMME ILIKE \'%;REPHY\' OR PROGRAMME ILIKE \'%;REPHY;%\' OR PROGRAMME ILIKE \'^REPHY$\')' )
def test_expressionFromOgcFilterWithString(self): """ Test expressionFromOgcFilter with String type field """ vl = QgsVectorLayer('Point', 'vl', 'memory') vl.dataProvider().addAttributes([QgsField('id', QVariant.String)]) vl.updateFields() # Literals are Integer 1 and 3 f = '''<?xml version="1.0" encoding="UTF-8"?> <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"> <ogc:And> <ogc:PropertyIsGreaterThan> <ogc:PropertyName>id</ogc:PropertyName> <ogc:Literal>1</ogc:Literal> </ogc:PropertyIsGreaterThan> <ogc:PropertyIsLessThan> <ogc:PropertyName>id</ogc:PropertyName> <ogc:Literal>3</ogc:Literal> </ogc:PropertyIsLessThan> </ogc:And> </ogc:Filter> ''' d = QDomDocument('filter') d.setContent(f, True) e = QgsOgcUtils.expressionFromOgcFilter(d.documentElement(), vl) self.assertEqual(e.expression(), 'id > \'1\' AND id < \'3\'') # Literals are Double 1.0 and 3.0 f = '''<?xml version="1.0" encoding="UTF-8"?> <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"> <ogc:And> <ogc:PropertyIsGreaterThan> <ogc:PropertyName>id</ogc:PropertyName> <ogc:Literal>1.0</ogc:Literal> </ogc:PropertyIsGreaterThan> <ogc:PropertyIsLessThan> <ogc:PropertyName>id</ogc:PropertyName> <ogc:Literal>3.0</ogc:Literal> </ogc:PropertyIsLessThan> </ogc:And> </ogc:Filter> ''' d = QDomDocument('filter') d.setContent(f, True) e = QgsOgcUtils.expressionFromOgcFilter(d.documentElement(), vl) self.assertEqual(e.expression(), 'id > \'1.0\' AND id < \'3.0\'') # Literals are Double 1.5 and 3.5 f = '''<?xml version="1.0" encoding="UTF-8"?> <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"> <ogc:And> <ogc:PropertyIsGreaterThan> <ogc:PropertyName>id</ogc:PropertyName> <ogc:Literal>1.5</ogc:Literal> </ogc:PropertyIsGreaterThan> <ogc:PropertyIsLessThan> <ogc:PropertyName>id</ogc:PropertyName> <ogc:Literal>3.5</ogc:Literal> </ogc:PropertyIsLessThan> </ogc:And> </ogc:Filter> ''' d = QDomDocument('filter') d.setContent(f, True) e = QgsOgcUtils.expressionFromOgcFilter(d.documentElement(), vl) self.assertEqual(e.expression(), 'id > \'1.5\' AND id < \'3.5\'') # Literals are Scientific notation 15e-01 and 35e-01 f = '''<?xml version="1.0" encoding="UTF-8"?> <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"> <ogc:And> <ogc:PropertyIsGreaterThan> <ogc:PropertyName>id</ogc:PropertyName> <ogc:Literal>15e-01</ogc:Literal> </ogc:PropertyIsGreaterThan> <ogc:PropertyIsLessThan> <ogc:PropertyName>id</ogc:PropertyName> <ogc:Literal>35e-01</ogc:Literal> </ogc:PropertyIsLessThan> </ogc:And> </ogc:Filter> ''' d = QDomDocument('filter') d.setContent(f, True) e = QgsOgcUtils.expressionFromOgcFilter(d.documentElement(), vl) self.assertEqual(e.expression(), 'id > \'15e-01\' AND id < \'35e-01\'')
def getObservations (self, offering="", properties=[], features=[], procedures=[], filters=None, resultModel = ""): """ :param offering: Offering name :type offering: str :param properties: Selected properties names :type properties: str list :param features: Selected features of interest names :type features: str list :param procedures: Selected procedures names :type procedures: str list :param filters: Configured filters :type filters: FilterRequest :param resultModel: Selected result model :type resultModel: str :return: xml data """ doc = QDomDocument() doc.appendChild(doc.createProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"')) root = doc.createElement('GetObservation') root.setAttribute('xmlns',"http://www.opengis.net/sos/1.0") root.setAttribute('xmlns:ows',"http://www.opengis.net/ows/1.1") root.setAttribute('xmlns:gml',"http://www.opengis.net/gml") root.setAttribute('xmlns:ogc',"http://www.opengis.net/ogc") root.setAttribute('xmlns:om',"http://www.opengis.net/om/1.0") root.setAttribute('xmlns:xsi',"http://www.w3.org/2001/XMLSchema-instance") root.setAttribute('xsi:schemaLocation',"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd") root.setAttribute('service',"SOS") root.setAttribute('version',"1.0.0") root.setAttribute('srsName',self[offering].srsName) doc.appendChild(root) offer = doc.createElement("offering") offer.appendChild(doc.createTextNode(offering)) root.appendChild (offer) if filters.temporalFilter: timeEvent = doc.createElement("eventTime") operator = doc.createElement("ogc:%s" % filters.temporalOperator) prop = doc.createElement("ogc:PropertyName") prop.appendChild (doc.createTextNode ("om:samplingTime")) operand = doc.createElement(filters.temporalOperand) if filters.temporalOperand == "gml:TimeInstant": timePos = doc.createElement("gml:timePosition") timePos.appendChild(doc.createTextNode(str(filters.temporalValue))) operand.appendChild (timePos) elif filters.temporalOperand == "gml:TimePeriod": begin = doc.createElement("gml:beginPosition") begin.appendChild(doc.createTextNode(str(filters.temporalValue).split()[0])) end = doc.createElement("gml:endPosition") end.appendChild(doc.createTextNode(str(filters.temporalValue).split()[-1])) operand.appendChild(begin) operand.appendChild(end) root.appendChild(timeEvent) timeEvent.appendChild(operator) operator.appendChild (prop) operator.appendChild (operand) for proc in procedures: procElement = doc.createElement("procedure") procElement.appendChild (doc.createTextNode(proc)) root.appendChild (procElement) for prop in properties: propElement = doc.createElement("observedProperty") propElement.appendChild(doc.createTextNode(prop)) root.appendChild (propElement) foi = doc.createElement("featureOfInterest") if len (features) else None for foiName in features: foiElement = doc.createElement("ObjectID") foiElement.appendChild(doc.createTextNode(foiName)) foi.appendChild (foiElement) if filters.spatialFilter and not foi: foi = doc.createElement("featureOfInterest") operator = doc.createElement("ogc:%s" % filters.spatialOperator) prop = doc.createElement("ogc:PropertyName") prop.appendChild (doc.createTextNode ("urn:ogc:data:location")) operator.appendChild (prop) try: if filters.spatialOperand == "gml:Point": gmlNode = QgsOgcUtils.geometryToGML(QgsGeometry.fromPoint(filters._spatialValue), doc) elif filters.spatialOperand == "gml:Envelope": gmlNode = QgsOgcUtils.rectangleToGMLEnvelope(QgsGeometry.fromRect(filters._spatialValue).boundingBox(), doc) elif filters.spatialOperand == "gml:Polygon": gmlNode = QgsOgcUtils.geometryToGML(QgsGeometry.fromPolygon(filters._spatialValue), doc) elif filters.spatialOperand == "gml:LineString": gmlNode = QgsOgcUtils.geometryToGML(QgsGeometry.fromPolyline(filters._spatialValue), doc) gmlNode.setAttribute('srsName',self[offering].srsName) operator.appendChild (gmlNode) except: pass foi.appendChild(operator) #Lista de features o filtro espacial if foi: root.appendChild(foi) if filters.scalarFilter: result = doc.createElement("result") operator = doc.createElement("ogc:PropertyIs%s" % filters.scalarOperator) prop = doc.createElement("ogc:PropertyName") prop.appendChild (doc.createTextNode (filters.scalarOperand)) operator.appendChild (prop) if filters.scalarOperator in ["Between"]: try: lower = doc.createElement ("ogc:LowerBoundary") lowValue = doc.createElement ("ogc:Literal") lowValue.appendChild(doc.createTextNode(str(filters.scalarValue).split()[0])) lower.appendChild (lowValue) upper = doc.createElement ("ogc:UpperBoundary") upValue = doc.createElement ("ogc:Literal") upValue.appendChild(doc.createTextNode(str(filters.scalarValue).split()[-1])) upper.appendChild (upValue) operator.appendChild (lower) operator.appendChild (upper) except: pass else: value = doc.createElement ("ogc:Literal") value.appendChild(doc.createTextNode(str(filters.scalarValue))) operator.appendChild (value) root.appendChild(result) result.appendChild(operator) responseFormat = doc.createElement ("responseFormat") responseFormat.appendChild (doc.createTextNode('text/xml;subtype="om/1.0.0"')) root.appendChild (responseFormat) resultModelElement = doc.createElement ("resultModel") resultModelElement.appendChild (doc.createTextNode(resultModel)) root.appendChild (resultModelElement) responseMode = doc.createElement ("responseMode") responseMode.appendChild (doc.createTextNode("inline")) root.appendChild (responseMode) return doc.toString(4)
def parse(self, xml): def _float(value): try: return float(value) except: return None components = {} for member, _ in self.search(xml, "member"): for node, tag in self.search(member, "Observation/*"): if tag == "samplingTime": samplingTime = self.timeParser.parse(node) elif tag == "observedProperty": _, prop = self.searchFirst(node, "@href") if prop: if not prop in components: components[prop] = None else: for _, prop in self.search( node, "CompositePhenomenon/component@href"): if not prop in components: components[prop] = None elif tag == "featureOfInterest": hasSamplingPoint = False for point, foi_id in chain( self.search( node, "FeatureCollection/featureMember/SamplingPoint@id" ), self.search(node, "SamplingPoint@id"), self.search(node, "SamplingPointAtDepth@id")): hasSamplingPoint = True _, name = self.searchFirst(point, "name") pointGeo, _ = self.searchFirst(point, "position") pointGeo = GMLParser.geometryFromGML(pointGeo) if self.yx: pointGeo = pointGeo.asPoint() pointGeo = QgsGeometry.fromPoint( QgsPoint(pointGeo.y(), pointGeo.x())) self.provider.features[foi_id] = (name, pointGeo) if point.localName() == "SamplingPointAtDepth": _, depth = self.searchFirst(point, "depth") foi_id = (foi_id, depth) if not hasSamplingPoint: for _, foi_id in self.search( node, "FeatureCollection/featureMember@href"): self.provider.features[foi_id] = (foi_id, None) elif tag == "result": node, tag = self.searchFirst(node, "*") if tag == "DataArray": simpleDataRecord = [] for fieldNode, field in chain( self.search( node, "elementType/SimpleDataRecord/field@name"), self.search( node, "elementType/DataRecord/field@name")): simpleDataRecord.append(field) fieldNode, definition = self.searchFirst( fieldNode, "*/@definition") if definition in components and components[ definition] == None: if fieldNode.localName() == "Quantity": fieldType = QVariant.Double _, definition = self.searchFirst( fieldNode, "uom@code") elif fieldNode.localName() == "Time": fieldType = QVariant.String else: fieldType = QVariant.String components[definition] = QgsField( field, fieldType, definition) encoding, _ = self.searchFirst(node, "encoding") _, blockSeparator = self.searchFirst( encoding, "TextBlock@blockSeparator") _, tokenSeparator = self.searchFirst( encoding, "TextBlock@tokenSeparator") _, values = self.searchFirst(node, "values") try: indexes = map(simpleDataRecord.index, ["feature", "Time"]) except: indexes = None if not indexes: try: indexes = map( simpleDataRecord.index, ["FeatureOfInterest", "SamplingTime"]) except: indexes = None if not indexes: raise ValueError('SimpleDataRecord = ' + str(simpleDataRecord)) map(simpleDataRecord.pop, indexes) for block in filter(lambda x: len(x), values.split(blockSeparator)): observation = block.split(tokenSeparator) observationKeys = map(observation.pop, indexes) map( lambda prop, value: self.provider. setObservation( unicode(observationKeys[0]), QDateTime.fromString( observationKeys[1], Qt.ISODate), unicode(prop), str(value)), simpleDataRecord, observation) return components
def parse (self, xml): def _float (value): try: return float(value) except: return None components = {} for member, _ in self.search(xml, "member"): for node, tag in self.search (member, "Observation/*"): if tag == "samplingTime": samplingTime = self.timeParser.parse(node) elif tag == "observedProperty": _, prop = self.searchFirst(node, "@href") if prop: if not prop in components: components[prop] = None else: for _, prop in self.search (node, "CompositePhenomenon/component@href"): if not prop in components: components[prop] = None elif tag == "featureOfInterest": hasSamplingPoint = False for point, foi_id in chain(self.search (node, "FeatureCollection/featureMember/SamplingPoint@id"),self.search (node, "SamplingPoint@id"),self.search (node, "SamplingPointAtDepth@id")): hasSamplingPoint = True _, name = self.searchFirst (point, "name") pointGeo, _ = self.searchFirst(point, "position") pointGeo = GMLParser.geometryFromGML(pointGeo) if self.yx: pointGeo = pointGeo.asPoint() pointGeo = QgsGeometry.fromPoint(QgsPoint (pointGeo.y(),pointGeo.x())) self.provider.features [foi_id] = (name, pointGeo) if point.localName () == "SamplingPointAtDepth": _, depth = self.searchFirst (point, "depth") foi_id = (foi_id, depth) if not hasSamplingPoint: for _, foi_id in self.search (node, "FeatureCollection/featureMember@href"): self.provider.features [foi_id] = (foi_id, None) elif tag == "result": node, tag = self.searchFirst(node, "*") if tag == "DataArray": simpleDataRecord = [] for fieldNode, field in chain(self.search(node, "elementType/SimpleDataRecord/field@name"),self.search(node, "elementType/DataRecord/field@name")): simpleDataRecord.append(field) fieldNode, definition = self.searchFirst(fieldNode, "*/@definition") if definition in components and components[definition] == None: if fieldNode.localName () == "Quantity": fieldType = QVariant.Double _, definition = self.searchFirst (fieldNode, "uom@code") elif fieldNode.localName () == "Time": fieldType = QVariant.String else: fieldType = QVariant.String components[definition] = QgsField (field, fieldType, definition) encoding, _ = self.searchFirst (node, "encoding") _, blockSeparator = self.searchFirst (encoding, "TextBlock@blockSeparator") _, tokenSeparator = self.searchFirst (encoding, "TextBlock@tokenSeparator") _, values = self.searchFirst (node, "values") try: indexes = map(simpleDataRecord.index, ["feature", "Time"]) except: indexes = None if not indexes: try: indexes = map(simpleDataRecord.index, ["FeatureOfInterest","SamplingTime"]) except: indexes = None if not indexes: raise ValueError('SimpleDataRecord = ' + str(simpleDataRecord)) map(simpleDataRecord.pop, indexes) for block in filter (lambda x: len(x), values.split (blockSeparator)): observation = block.split(tokenSeparator) observationKeys = map(observation.pop, indexes) map (lambda prop, value: self.provider.setObservation (unicode(observationKeys[0]), QDateTime.fromString(observationKeys[1], Qt.ISODate), unicode(prop), str(value)), simpleDataRecord, observation) return components
def getObservations(self, offering="", properties=[], features=[], procedures=[], filters=None, resultModel=""): """ :param offering: Offering name :type offering: str :param properties: Selected properties names :type properties: str list :param features: Selected features of interest names :type features: str list :param procedures: Selected procedures names :type procedures: str list :param filters: Configured filters :type filters: FilterRequest :param resultModel: Selected result model :type resultModel: str :return: xml data """ doc = QDomDocument() doc.appendChild( doc.createProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"')) root = doc.createElement('GetObservation') root.setAttribute('xmlns', "http://www.opengis.net/sos/1.0") root.setAttribute('xmlns:ows', "http://www.opengis.net/ows/1.1") root.setAttribute('xmlns:gml', "http://www.opengis.net/gml") root.setAttribute('xmlns:ogc', "http://www.opengis.net/ogc") root.setAttribute('xmlns:om', "http://www.opengis.net/om/1.0") root.setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance") root.setAttribute( 'xsi:schemaLocation', "http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd" ) root.setAttribute('service', "SOS") root.setAttribute('version', "2.0.0") root.setAttribute('srsName', self[offering].srsName) doc.appendChild(root) offer = doc.createElement("offering") offer.appendChild(doc.createTextNode(offering)) root.appendChild(offer) if filters.temporalFilter: timeEvent = doc.createElement("eventTime") operator = doc.createElement("ogc:%s" % filters.temporalOperator) prop = doc.createElement("ogc:PropertyName") prop.appendChild(doc.createTextNode("om:samplingTime")) operand = doc.createElement(filters.temporalOperand) if filters.temporalOperand == "gml:TimeInstant": timePos = doc.createElement("gml:timePosition") timePos.appendChild( doc.createTextNode(str(filters.temporalValue))) operand.appendChild(timePos) elif filters.temporalOperand == "gml:TimePeriod": begin = doc.createElement("gml:beginPosition") begin.appendChild( doc.createTextNode(str(filters.temporalValue).split()[0])) end = doc.createElement("gml:endPosition") end.appendChild( doc.createTextNode(str(filters.temporalValue).split()[-1])) operand.appendChild(begin) operand.appendChild(end) root.appendChild(timeEvent) timeEvent.appendChild(operator) operator.appendChild(prop) operator.appendChild(operand) for proc in procedures: procElement = doc.createElement("procedure") procElement.appendChild(doc.createTextNode(proc)) root.appendChild(procElement) for prop in properties: propElement = doc.createElement("observedProperty") propElement.appendChild(doc.createTextNode(prop)) root.appendChild(propElement) foi = doc.createElement("featureOfInterest") if len(features) else None for foiName in features: foiElement = doc.createElement("ObjectID") foiElement.appendChild(doc.createTextNode(foiName)) foi.appendChild(foiElement) if filters.spatialFilter and not foi: foi = doc.createElement("featureOfInterest") operator = doc.createElement("ogc:%s" % filters.spatialOperator) prop = doc.createElement("ogc:PropertyName") prop.appendChild(doc.createTextNode("urn:ogc:data:location")) operator.appendChild(prop) try: if filters.spatialOperand == "gml:Point": gmlNode = QgsOgcUtils.geometryToGML( QgsGeometry.fromPoint(filters._spatialValue), doc) elif filters.spatialOperand == "gml:Envelope": gmlNode = QgsOgcUtils.rectangleToGMLEnvelope( QgsGeometry.fromRect( filters._spatialValue).boundingBox(), doc) elif filters.spatialOperand == "gml:Polygon": gmlNode = QgsOgcUtils.geometryToGML( QgsGeometry.fromPolygon(filters._spatialValue), doc) elif filters.spatialOperand == "gml:LineString": gmlNode = QgsOgcUtils.geometryToGML( QgsGeometry.fromPolyline(filters._spatialValue), doc) gmlNode.setAttribute('srsName', self[offering].srsName) operator.appendChild(gmlNode) except: pass foi.appendChild(operator) #Lista de features o filtro espacial if foi: root.appendChild(foi) if filters.scalarFilter: result = doc.createElement("result") operator = doc.createElement("ogc:PropertyIs%s" % filters.scalarOperator) prop = doc.createElement("ogc:PropertyName") prop.appendChild(doc.createTextNode(filters.scalarOperand)) operator.appendChild(prop) if filters.scalarOperator in ["Between"]: try: lower = doc.createElement("ogc:LowerBoundary") lowValue = doc.createElement("ogc:Literal") lowValue.appendChild( doc.createTextNode( str(filters.scalarValue).split()[0])) lower.appendChild(lowValue) upper = doc.createElement("ogc:UpperBoundary") upValue = doc.createElement("ogc:Literal") upValue.appendChild( doc.createTextNode( str(filters.scalarValue).split()[-1])) upper.appendChild(upValue) operator.appendChild(lower) operator.appendChild(upper) except: pass else: value = doc.createElement("ogc:Literal") value.appendChild(doc.createTextNode(str(filters.scalarValue))) operator.appendChild(value) root.appendChild(result) result.appendChild(operator) responseFormat = doc.createElement("responseFormat") responseFormat.appendChild( doc.createTextNode('text/xml;subtype="om/2.0.0"')) root.appendChild(responseFormat) resultModelElement = doc.createElement("resultModel") resultModelElement.appendChild(doc.createTextNode(resultModel)) root.appendChild(resultModelElement) responseMode = doc.createElement("responseMode") responseMode.appendChild(doc.createTextNode("inline")) root.appendChild(responseMode) return doc.toString(4)