Beispiel #1
0
    def executePost(self):
        """
        Method for executing a POST requests that insert new observations into
        a SOS procedure

        .. note::  The POST data shall be in JSON format as following:

        >>> {
            "ForceInsert" : "true",
            "Observation" : {
                "procedure": "urn:ogc:object:procedure:x-istsos:1.01.0:P_TRE",
                "AssignedSensorId" : "247df84cf4a0c2ebc632d08318d00cb3",
                "samplingTime": {
                    "beginPosition": "2012-01-01T13:00:00+01:00",
                    "endPosition": "2012-01-01T17:00:00+01:00"
                },
                "observedProperty": {
                    "CompositePhenomenon": {
                        "id": "comp_126",
                        "dimension": "2"
                    },
                    "component": [
                        "urn:ogc:def:parameter:x-istsos:1.01.0:time:iso8601",
                        "urn:ogc:def:parameter:x-istsos:1.0:meteo:air:rainfall"
                    ]
                },
                "featureOfInterest": {
                    "geom": (
                        "<gml:Point srsName='EPSG:21781'>"
                        "<gml:coordinates>717900,98520,342</gml:coordinates>"
                        "</gml:Point>"),
                    "name": "urn:ogc:object:feature:x-istsos:1.01.0:"
                            "station:Trevano"
                },
                "result": {
                    "DataArray": {
                        "elementCount": "2",
                        "values": [
                            [
                                "22012-01-01T14:00:00+01:00",
                                "10.000000"
                            ],
                            [
                                "2012-01-01T15:00:00+01:00",
                                "20.000000"
                            ]
                        ],
                        "field": [
                            {
                                "definition": "urn:ogc:def:parameter:x-istsos:"
                                              "1.01.0:time:iso8601",
                                "name": "Time"
                            },
                            {
                                "definition": "urn:ogc:def:parameter:x-istsos:"
                                              "1.0:meteo:air:rainfall",
                                "name": "air-rainfall",
                                "uom": "mm"
                            }
                        ]
                    }
                }
            }
        }
        """
        ns = {
            'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
            'sml': 'http://www.opengis.net/sensorML',
            'swe': 'http://www.opengis.net/swe',
            'xlink': 'http://www.w3.org/1999/xlink',
            'gml': 'http://www.opengis.net/gml',
            'sos': 'http://www.opengis.net/sos/1.0',
            'sa': 'http://www.opengis.net/sampling/1.0',
            'ogc': 'http://www.opengis.net/ogc',
            'om': 'http://www.opengis.net/om/1.0'
        }

        # map namespaces
        try:
            register_namespace = et.register_namespace
            for key in ns:
                register_namespace(key, ns[key])

        except AttributeError:
            try:
                et._namespace_map.update(ns)
                for key in ns:
                    et._namespace_map[ns[key]] = key

            except AttributeError:
                try:
                    from xml.etree.ElementTree import _namespace_map

                except ImportError:
                    try:
                        from elementtree.ElementTree import _namespace_map

                    except ImportError:
                        traceback.print_exc(file=sys.stderr)

                for key in ns:
                    _namespace_map[ns[key]] = key

        #create xml request
        root = et.Element("{%s}InsertObservation" % ns['sos'])
        root.attrib["{%s}schemaLocation" % ns['xsi']] = (
            "http://schemas.opengis.net/sos/1.0.0/sosAll.xsd")
        root.attrib["version"] = "1.0.0"
        root.attrib["service"] = "SOS"

        AssignedSensorId = et.SubElement(root,
                                         "{%s}AssignedSensorId" % ns['sos'])
        AssignedSensorId.text = self.json["AssignedSensorId"]

        if "ForceInsert" in self.json:
            ForceInsert = et.SubElement(root, "{%s}ForceInsert" % ns['sos'])
            ForceInsert.text = self.json["ForceInsert"]

        Observation = et.SubElement(root, "{%s}Observation" % ns['om'])

        procedure = et.SubElement(Observation, "{%s}procedure" % ns['om'])
        procedure.attrib["{%s}href" %
                         ns['xlink']] = (self.json["Observation"]["procedure"])

        samplingTime = et.SubElement(Observation,
                                     "{%s}samplingTime" % ns['om'])
        TimePeriod = et.SubElement(samplingTime, "{%s}TimePeriod" % ns['gml'])
        beginPosition = et.SubElement(TimePeriod,
                                      "{%s}beginPosition" % ns['gml'])
        beginPosition.text = (
            self.json["Observation"]["samplingTime"]["beginPosition"])
        endPosition = et.SubElement(TimePeriod, "{%s}endPosition" % ns['gml'])
        endPosition.text = (
            self.json["Observation"]["samplingTime"]["endPosition"])

        observedProperty = et.SubElement(Observation,
                                         "{%s}observedProperty" % ns['om'])
        CompositePhenomenon = et.SubElement(
            observedProperty, "{%s}CompositePhenomenon" % ns['swe'])
        CompositePhenomenon.attrib["dimension"] = (
            self.json["Observation"]["observedProperty"]
        )["CompositePhenomenon"]["dimension"]

        for comp in self.json["Observation"]["observedProperty"]["component"]:
            component = et.SubElement(CompositePhenomenon,
                                      "{%s}component" % ns['swe'])
            component.attrib["{%s}href" % ns['xlink']] = comp

        featureOfInterest = et.SubElement(Observation,
                                          "{%s}featureOfInterest" % ns['om'])
        featureOfInterest.attrib["{%s}href" % ns['xlink']] = (
            self.json["Observation"]["featureOfInterest"]["name"])

        result = et.SubElement(Observation, "{%s}result" % ns['om'])
        DataArray = et.SubElement(result, "{%s}DataArray" % ns['swe'])
        elementCount = et.SubElement(DataArray, "{%s}elementCount" % ns['swe'])
        value = et.SubElement(elementCount, "{%s}value" % ns['swe'])
        value.text = (
            self.json["Observation"]["result"]["DataArray"]["elementCount"])
        elementType = et.SubElement(DataArray, "{%s}elementType" % ns['swe'])
        elementType.attrib["name"] = "SimpleDataArray"
        DataRecord = et.SubElement(elementType, "{%s}DataRecord" % ns['swe'])
        DataRecord.attrib["definition"] = (
            "urn:ogc:def:dataType:x-istsos:1.0:timeSeries")
        for index, item in enumerate(
                self.json["Observation"]["result"]["DataArray"]["field"]):
            field = et.SubElement(DataRecord, "{%s}field" % ns['swe'])
            field.attrib["name"] = item["name"]
            if index == 0:
                Time = et.SubElement(field, "{%s}Time" % ns['swe'])
                Time.attrib["definition"] = item["definition"]
                if not item["definition"].find("time") > 0:
                    raise Exception("first element of DataRecord is not of "
                                    "type time")
            else:
                Quantity = et.SubElement(field, "{%s}Quantity" % ns['swe'])
                Quantity.attrib["definition"] = item["definition"]
                if "uom" in item:
                    uom = et.SubElement(Quantity, "{%s}uom" % ns['swe'])
                    uom.attrib["code"] = item["uom"]

        encoding = et.SubElement(DataArray, "{%s}encoding" % ns['swe'])
        TextBlock = et.SubElement(encoding, "{%s}TextBlock" % ns['swe'])
        TextBlock.attrib["tokenSeparator"] = ","
        TextBlock.attrib["blockSeparator"] = "@"
        TextBlock.attrib["decimalSeparator"] = "."

        values = et.SubElement(DataArray, "{%s}values" % ns['swe'])
        values.text = "@".join([
            ",".join(row) for row in (
                self.json["Observation"]["result"]["DataArray"]["values"])
        ])

        # PrettyPrint XML
        iostring = et.tostring(root, encoding="UTF-8")

        headers = {"Content-type": "text/xml"}
        if 'HTTP_AUTHORIZATION' in self.waEnviron:
            headers['Authorization'] = self.waEnviron['HTTP_AUTHORIZATION']

        response = requests.post(self.serviceconf.serviceurl["url"],
                                 data=iostring,
                                 headers=headers)
        data = response.text

        try:
            response.raise_for_status()
            if data.find("AssignedObservationId") > 0:
                self.setMessage("%s" % data)

            else:
                self.setException(
                    "Insert observations failed - Communication: %s %s - "
                    "Response: %s" % (response.status_code, e, response.text))

        except Exception as e:
            self.setException(
                "Insert observations failed - Communication: %s %s - Response:"
                " %s" % (response.status_code, e, response.text))
Beispiel #2
0
def XMLformat_2_0_0(GO, sosConfig):

    res = et.XML("""<sos:GetObservationResponse 
            xmlns:sos="http://www.opengis.net/sos/2.0" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns:om="http://www.opengis.net/om/2.0" 
            xmlns:gml="http://www.opengis.net/gml/3.2" 
            xmlns:xlink="http://www.w3.org/1999/xlink" 
            xsi:schemaLocation="http://www.opengis.net/sos/2.0 http://schemas.opengis.net/sos/2.0/sosGetObservation.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd http://www.opengis.net/om/2.0 http://schemas.opengis.net/om/2.0/observation.xsd">
        </sos:GetObservationResponse>""")

    ns = {
        'xsi': "http://www.w3.org/2001/XMLSchema-instance",
        'sos': "http://www.opengis.net/sos/2.0",
        'om': "http://www.opengis.net/om/2.0",
        'gml': 'http://www.opengis.net/gml/3.2',
        'xlink': "http://www.w3.org/1999/xlink"
    }

    # map namespaces
    try:
        register_namespace = et.register_namespace
        for key in ns:
            register_namespace(key, ns[key])
    except AttributeError:
        try:
            et._namespace_map.update(ns)
            for key in ns:
                et._namespace_map[ns[key]] = key
        except AttributeError:
            try:
                from xml.etree.ElementTree import _namespace_map
            except ImportError:
                try:
                    from elementtree.ElementTree import _namespace_map
                except ImportError:
                    print >> sys.stderr, (
                        "Failed to import ElementTree from any known place")
            for key in ns:
                _namespace_map[ns[key]] = key

    if len(GO.obs) > 0:
        data = et.SubElement(res, '{%s}observationData' % ns['sos'])
        for observation in GO.obs:
            cnt = 1
            idx = 0
            while idx < len(observation.observedProperty):

                observedProperty = observation.observedProperty[idx]
                observedPropertyId = observation.observedPropertyId[idx]
                uom = observation.uom[idx]

                for result in observation.data:

                    uid = "%s_%s_%s" % (observation.id_prc,
                                        result[0].strftime("%s"),
                                        observedPropertyId)

                    # Creating om:OM_Observation
                    omobservation = et.SubElement(
                        data, '{%s}OM_Observation' % ns['om'])

                    omobservation.set("{%s}id" % ns['gml'],
                                      "o_%s" % hashlib.md5(uid).hexdigest())

                    # Adding om:type with attribute
                    et.SubElement(omobservation, '{%s}type' % ns['om']).set(
                        "{%s}href" % ns['xlink'],
                        'http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement'
                    )

                    # Adding om:phenomenonTime
                    phenomenonTime = et.SubElement(
                        omobservation, '{%s}phenomenonTime' % ns['om'])

                    # Generating TimeInstant id shared that will be linked from the phenomenonTime
                    timeInstantId = "p_%s" % hashlib.md5(uid).hexdigest()

                    # Adding gml:TimeInstant
                    timeInstant = et.SubElement(phenomenonTime,
                                                '{%s}TimeInstant' % ns['gml'])
                    timeInstant.set("{%s}id" % ns['gml'], timeInstantId)

                    # Adding gml:timePosition ad date value as string (iso format)
                    et.SubElement(timeInstant, '{%s}timePosition' %
                                  ns['gml']).text = result[0].isoformat()

                    # Adding om:phenomenonTime
                    et.SubElement(omobservation,
                                  '{%s}resultTime' % ns['om']).set(
                                      "{%s}href" % ns['xlink'],
                                      '#%s' % timeInstantId)

                    # Adding om:procedure
                    et.SubElement(
                        omobservation, '{%s}procedure' % ns['om']).set(
                            "{%s}href" % ns['xlink'], "%s%s" %
                            (sosConfig.urn["procedure"], observation.name))

                    # Add quality index as parameter
                    if observation.qualityIndex:

                        parameter = et.SubElement(omobservation,
                                                  '{%s}parameter' % ns['om'])
                        namedValue = et.SubElement(parameter,
                                                   '{%s}NamedValue' % ns['om'])
                        name = et.SubElement(namedValue, '{%s}name' % ns['om'])
                        name.set("{%s}href" % ns['xlink'],
                                 observation.observedProperty[idx + 1])
                        value = et.SubElement(namedValue,
                                              '{%s}value' % ns['om'])
                        value.text = str(result[cnt + 1])

                    # Adding om:observedProperty
                    et.SubElement(omobservation,
                                  '{%s}observedProperty' % ns['om']).set(
                                      "{%s}href" % ns['xlink'],
                                      observedProperty)

                    # Adding om:featureOfInterest
                    et.SubElement(omobservation,
                                  '{%s}featureOfInterest' % ns['om']).set(
                                      "{%s}href" % ns['xlink'],
                                      observation.foi_urn)

                    # Adding om:result
                    omresult = et.SubElement(omobservation,
                                             '{%s}result' % ns['om'])
                    omresult.set("uom", uom)
                    omresult.set("{%s}type" % ns['xsi'], "gml:MeasureType")
                    omresult.text = str(result[cnt])

                if observation.qualityIndex:
                    idx += 2
                    cnt += 2
                else:
                    idx += 1
                    cnt += 1
    """
    http://sensorweb.demo.52north.org/sensorwebtestbed/client
    
    Examples: 
    http://sensorweb.demo.52north.org/sensorwebtestbed/service?service=SOS&request=GetCapabilities&crs=4258
    http://sensorweb.demo.52north.org/sensorwebtestbed/service?service=SOS&version=2.0.0&request=GetObservation&procedure=ws2500&temporalFilter=om:phenomenonTime,2016-02-24T00:00:00.000Z/2016-02-24T13:00:00.000Z
    http://sensorweb.demo.52north.org/sensorwebtestbed/service?service=SOS&version=2.0.0&request=GetObservation&procedure=ws2500&temporalFilter=om:phenomenonTime,2016-02-24T00:00:00.000Z/2016-02-24T13:00:00.000Z&MergeObservationsIntoDataArray=true
    
    """

    return '<?xml version="1.0" encoding="UTF-8"?>\n%s' % et.tostring(res)
Beispiel #3
0
    def toXML(self, indent=False):
        """
        Return the SensorML that represent the self.data object as L{string}
        """
        import sys
        ns = {
            'xsi': "http://www.w3.org/2001/XMLSchema-instance",
            'sml': "http://www.opengis.net/sensorML/1.0.1",
            'swe': "http://www.opengis.net/swe/1.0.1",
            'xlink': "http://www.w3.org/1999/xlink",
            'gml': 'http://www.opengis.net/gml'
        }

        #---map namespaces---
        try:
            register_namespace = et.register_namespace
            for key in ns:
                register_namespace(key, ns[key])
        except AttributeError:
            try:
                et._namespace_map.update(ns)
                for key in ns:
                    et._namespace_map[ns[key]] = key
            except AttributeError:
                try:
                    from xml.etree.ElementTree import _namespace_map
                except ImportError:
                    try:
                        from elementtree.ElementTree import _namespace_map
                    except ImportError:
                        print >> sys.stderr, (
                            "Failed to import ElementTree from any known place"
                        )
                for key in ns:
                    _namespace_map[ns[key]] = key

        root = et.Element("{%s}SensorML" % ns['sml'])
        root.attrib["{%s}schemaLocation" % ns[
            'xsi']] = "http://www.opengis.net/sensorML/1.0.1 http://schemas.opengis.net/sensorML/1.0.1/sensorML.xsd"
        root.attrib["version"] = "1.0"

        member = et.SubElement(root, "{%s}member" % ns['sml'])

        system = et.SubElement(member, "{%s}System" % ns['sml'])
        system.attrib["{%s}id" % ns['gml']] = self.data["system_id"]

        #--- System Description
        system.append(et.Comment("System Description"))

        if ("keywords" in self.data) and (not self.data["description"] == ""):
            desc = et.SubElement(system, "{%s}description" % ns['gml'])
            desc.text = self.data["description"]

        name = et.SubElement(system, "{%s}name" % ns['gml'])
        name.text = self.data["system"]

        #--- System Search Keywords
        if ("keywords" in self.data) and (not self.data["keywords"] == ""):
            system.append(et.Comment("System Search Keywords"))
            keys = et.SubElement(system, "{%s}keywords" % ns['sml'])
            keylist = et.SubElement(keys, "{%s}KeywordList" % ns['sml'])
            for k in self.data["keywords"].split(","):
                key = et.SubElement(keylist, "{%s}keyword" % ns['sml'])
                key.text = k

        #--- System Identifiers
        if ("identification"
                in self.data) and (not self.data["identification"] == []):
            system.append(et.Comment("System Identifiers"))
            identification = et.SubElement(system,
                                           "{%s}identification" % ns['sml'])
            IdentifierList = et.SubElement(identification,
                                           "{%s}IdentifierList" % ns['sml'])
            uniqueidPresent = False
            for i in self.data["identification"]:
                if i["definition"] == 'urn:ogc:def:identifier:OGC:uniqueID':
                    uniqueidPresent = True
                identifier = et.SubElement(IdentifierList,
                                           "{%s}identifier" % ns['sml'])
                identifier.attrib["name"] = i["name"]
                term = et.SubElement(identifier, "{%s}Term" % ns['sml'])
                term.attrib["definition"] = i["definition"]
                value = et.SubElement(term, "{%s}value" % ns['sml'])
                value.text = i["value"]
            if not uniqueidPresent:
                raise Exception(
                    "self.data['identification']: 'uniqueID' is mandatory")

        #--- System Classifiers
        system.append(et.Comment("System Classifiers"))
        classification = et.SubElement(system,
                                       "{%s}classification" % ns['sml'])
        ClassifierList = et.SubElement(classification,
                                       "{%s}ClassifierList" % ns['sml'])
        for c in self.data["classification"]:
            classifier = et.SubElement(ClassifierList,
                                       "{%s}classifier" % ns['sml'])
            classifier.attrib["name"] = c["name"]
            term = et.SubElement(classifier, "{%s}Term" % ns['sml'])
            term.attrib["definition"] = c["definition"]
            value = et.SubElement(term, "{%s}value" % ns['sml'])
            value.text = c["value"]
            if c["name"] == "System Type":
                systype = True
            elif c["name"] == "Sensor Type":
                senstype = True
        if not systype == True and senstype == True:
            raise Exception(
                "self.data['classification']: 'System Type' and 'Sensor Type' are mandatory"
            )

        #--- System Characteristics
        if ("characteristics"
                in self.data) and (not self.data["characteristics"] == ""):
            system.append(et.Comment("System Characteristics"))
            characteristics = et.SubElement(system,
                                            "{%s}characteristics" % ns['sml'])
            characteristics.attrib["{%s}href" %
                                   ns['xlink']] = self.data["characteristics"]

        #--- System Capabilities
        system.append(et.Comment("System Capabilities"))
        capabilities = et.SubElement(system, "{%s}capabilities" % ns['sml'])
        DataRecord = et.SubElement(capabilities, "{%s}DataRecord" % ns['swe'])
        stres = False
        atres = False
        for f in self.data["capabilities"]:
            field = et.SubElement(DataRecord, "{%s}field" % ns['swe'])
            field.attrib["name"] = f["name"]
            Quantity = et.SubElement(field, "{%s}Quantity" % ns['swe'])
            Quantity.attrib["definition"] = f["definition"]
            if "uom" in f and "value" in f:
                uom = et.SubElement(Quantity, "{%s}uom" % ns['swe'])
                uom.attrib["code"] = f["uom"]
                value = et.SubElement(Quantity, "{%s}value" % ns['swe'])
                value.text = f["value"]
            if c["name"] == "Sampling time resolution":
                stres = True
            elif c["name"] == "Acquisition time resolution":
                atres = True
        if not stres == True and atres == True:
            raise Exception(
                "self.data['capabilities']: 'Sampling time resolution' and 'Acquisition time resolution' are mandatory"
            )

        #--- Relevant Contacts
        if ("contacts" in self.data) and (not self.data["contacts"] == []):
            system.append(et.Comment("Relevant Contacts"))
            for c in self.data["contacts"]:
                contact = et.SubElement(system, "{%s}contact" % ns['sml'])
                contact.attrib["{%s}role" % ns['xlink']] = c["role"]
                ResponsibleParty = et.SubElement(
                    contact, "{%s}ResponsibleParty" % ns['sml'])
                if not c["individualName"] == "":
                    individualName = et.SubElement(
                        ResponsibleParty, "{%s}individualName" % ns['sml'])
                    individualName.text = c["individualName"]
                organizationName = et.SubElement(
                    ResponsibleParty, "{%s}organizationName" % ns['sml'])
                organizationName.text = c["organizationName"]
                phonetag = not c["voice"] == c["fax"] == ""
                addresstag = not c["deliveryPoint"] == c["city"] == c[
                    "administrativeArea"] == c["postalcode"] == c[
                        "country"] == c["email"] == ""
                onlineResourcetag = not c["web"] == ""
                if not phonetag == addresstag == onlineResourcetag == False:
                    contactInfo = et.SubElement(ResponsibleParty,
                                                "{%s}contactInfo" % ns['sml'])
                    if not phonetag == False:
                        phone = et.SubElement(contactInfo,
                                              "{%s}phone" % ns['sml'])
                        if not c["voice"] == "":
                            voice = et.SubElement(phone,
                                                  "{%s}voice" % ns['sml'])
                            voice.text = c["voice"]
                        if not c["fax"] == "":
                            facsimile = et.SubElement(
                                phone, "{%s}facsimile" % ns['sml'])
                            facsimile.text = c["fax"]
                    if not addresstag == False:
                        address = et.SubElement(contactInfo,
                                                "{%s}address" % ns['sml'])
                        if not c["deliveryPoint"] == "":
                            deliveryPoint = et.SubElement(
                                address, "{%s}deliveryPoint" % ns['sml'])
                            deliveryPoint.text = c["deliveryPoint"]
                        if not c["city"] == "":
                            city = et.SubElement(address,
                                                 "{%s}city" % ns['sml'])
                            city.text = c["city"]
                        if not c["administrativeArea"] == "":
                            administrativeArea = et.SubElement(
                                address, "{%s}administrativeArea" % ns['sml'])
                            administrativeArea.text = c["administrativeArea"]
                        if not c["postalcode"] == "":
                            postalCode = et.SubElement(
                                address, "{%s}postalCode" % ns['sml'])
                            postalCode.text = c["postalcode"]
                        if not c["country"] == "":
                            country = et.SubElement(address,
                                                    "{%s}country" % ns['sml'])
                            country.text = c["country"]
                        if not c["email"] == "":
                            electronicMailAddress = et.SubElement(
                                address,
                                "{%s}electronicMailAddress" % ns['sml'])
                            electronicMailAddress.text = c["email"]
                    if not onlineResourcetag == False:
                        onlineResource = et.SubElement(
                            contactInfo, "{%s}onlineResource" % ns['sml'])
                        onlineResource.attrib["{%s}href" %
                                              ns['xlink']] = c["web"]

        #--- System Documentation
        if ("documentation"
                in self.data) and (not self.data["documentation"] == []):
            system.append(et.Comment("System Documentation"))
            for d in self.data["documentation"]:
                documentation = et.SubElement(system,
                                              "{%s}documentation" % ns['sml'])
                Document = et.SubElement(documentation,
                                         "{%s}Document" % ns['sml'])
                description = et.SubElement(Document,
                                            "{%s}description" % ns['gml'])
                description.text = d["description"]
                if not d["date"] == "":
                    date = et.SubElement(Document, "{%s}date" % ns['sml'])
                    date.text = d["date"]
                if not d["format"] == "":
                    format = et.SubElement(Document, "{%s}format" % ns['sml'])
                    format.text = d["format"]
                onlineResource = et.SubElement(
                    Document, "{%s}onlineResource" % ns['sml'])
                onlineResource.attrib["{%s}href" % ns['xlink']] = d["link"]

        #--- System Location
        system.append(et.Comment("System Location"))
        location = et.SubElement(system, "{%s}location" % ns['sml'])
        for item in self.data["classification"]:
            if item["name"] == "System Type":
                if item["value"].find("mobile") > 0:
                    location.attrib["{%s}role" % ns[
                        'xlink']] = "urn:ogc:def:dataType:x-istsos:1.0:lastPosition"
        Point = et.SubElement(location, "{%s}Point" % ns['gml'])

        if ut.valid_NCName(self.data["location"]["properties"]["name"]):
            Point.attrib[
                "{%s}id" %
                ns['gml']] = self.data["location"]["properties"]["name"]
        else:
            raise Exception(
                "Invalid location name '%s' (gml:id only allows alphanumeric characters)"
                % self.data["location"]["properties"]["name"])
        Point.attrib["srsName"] = "EPSG:" + str(
            self.data["location"]["crs"]["properties"]["name"])
        coordinates = et.SubElement(Point, "{%s}coordinates" % ns['gml'])
        coordinates.text = ",".join(
            [str(a) for a in self.data["location"]["geometry"]["coordinates"]])

        #--- System Interfaces
        if ("interfaces" in self.data) and (not self.data["interfaces"] == ""):
            system.append(et.Comment("System Interfaces"))
            interfaces = et.SubElement(system, "{%s}interfaces" % ns['sml'])
            InterfaceList = et.SubElement(interfaces,
                                          "{%s}InterfaceList" % ns['sml'])
            for i in self.data["interfaces"].split(","):
                interface = et.SubElement(InterfaceList,
                                          "{%s}interface" % ns['sml'])
                interface.attrib["name"] = i

        #--- System Inputs # Not yet supported in waAdmin !!
        if ("inputs" in self.data) and (not self.data["inputs"] == []):
            system.append(et.Comment("System Inputs"))
            inputs = et.SubElement(system, "{%s}inputs" % ns['sml'])
            InputList = et.SubElement(inputs, "{%s}InputList" % ns['sml'])
            for inp in self.data["inputs"]:
                inputml = et.SubElement(InputList, "{%s}input" % ns['sml'])
                inputml.attrib["name"] = inp["name"]
                Quantity = et.SubElement(inputml, "{%s}Quantity" % ns['swe'])
                Quantity.attrib["definition"] = inp["definition"]
                if not inp["description"] == "":
                    description = et.SubElement(Quantity,
                                                "{%s}description" % ns['gml'])
                    description.text = inp["description"]

        #--- System Outputs
        timetag = False
        system.append(et.Comment("System Outputs"))
        outputs = et.SubElement(system, "{%s}outputs" % ns['sml'])
        OutputList = et.SubElement(outputs, "{%s}OutputList" % ns['sml'])
        output = et.SubElement(OutputList, "{%s}output" % ns['sml'])
        output.attrib["name"] = "output data"
        DataRecord = et.SubElement(output, "{%s}DataRecord" % ns['swe'])
        DataRecord.attrib[
            "definition"] = "urn:ogc:def:dataType:x-istsos:1.0:timeSeries"
        oid = 0
        for o in self.data["outputs"]:
            oid += 1
            field = et.SubElement(DataRecord, "{%s}field" % ns['swe'])
            field.attrib["name"] = o["name"]

            if o["name"] == "Time":
                timetag = True
                item = et.SubElement(field, "{%s}Time" % ns['swe'])
                item.attrib["{%s}id" % ns['gml']] = "IDT_" + str(oid)
                item.attrib["definition"] = o["definition"]

                if not o["description"] == "":
                    description = et.SubElement(item,
                                                "{%s}description" % ns['gml'])
                    description.text = o["description"]

                uom = et.SubElement(item, "{%s}uom" % ns['swe'])
                uom.attrib["code"] = o["uom"]

                # The constraint object is not mandatory
                if "constraint" in o and o[
                        "constraint"] != {}:  # and o["constraint"]["role"]!="" and o["constraint"]["role"]!=None:

                    constraint = et.SubElement(item,
                                               "{%s}constraint" % ns['swe'])

                    # Role attribute is not mandatory
                    if "role" in o["constraint"] and o["constraint"][
                            "role"] != "" and o["constraint"]["role"] != None:
                        constraint.attrib[
                            "{%s}role" % ns['xlink']] = o["constraint"]["role"]

                    AllowedTimes = et.SubElement(
                        constraint, "{%s}AllowedTimes" % ns['swe'])
                    interval = et.SubElement(AllowedTimes,
                                             "{%s}interval" % ns['swe'])
                    interval.text = " ".join(
                        [str(a) for a in o["constraint"]["interval"]])

            else:
                item = et.SubElement(field, "{%s}Quantity" % ns['swe'])
                item.attrib["{%s}id" % ns['gml']] = "IDQ_" + str(oid)
                item.attrib["definition"] = o["definition"]

                if not o["description"] == "":
                    description = et.SubElement(item,
                                                "{%s}description" % ns['gml'])
                    description.text = o["description"]

                uom = et.SubElement(item, "{%s}uom" % ns['swe'])
                uom.attrib["code"] = o["uom"]

                # The constraint object is not mandatory
                if "constraint" in o and o[
                        "constraint"] != {}:  # and o["constraint"]["role"]!="" and o["constraint"]["role"]!=None:
                    #print >> sys.stderr, o['constraint']
                    try:
                        ut.validateJsonConstraint(o['constraint'])
                    except Exception as ex:
                        raise Exception(
                            "Constraint for observed property '%s' is not valid: %s"
                            % (o["definition"], ex))

                    constraint = et.SubElement(item,
                                               "{%s}constraint" % ns['swe'])

                    # Role attribute is not mandatory
                    if "role" in o["constraint"] and o["constraint"][
                            "role"] != "" and o["constraint"]["role"] != None:
                        constraint.attrib[
                            "{%s}role" % ns['xlink']] = o["constraint"]["role"]

                    AllowedValues = et.SubElement(
                        constraint, "{%s}AllowedValues" % ns['swe'])

                    # Factory on constraint min/max/interval/valuelist
                    if "interval" in o["constraint"]:
                        interval = et.SubElement(AllowedValues,
                                                 "{%s}interval" % ns['swe'])
                        interval.text = " ".join(
                            [str(a) for a in o["constraint"]["interval"]])

                    elif "valueList" in o[
                            "constraint"]:  #.has_key("valueList"):
                        valueList = et.SubElement(AllowedValues,
                                                  "{%s}valueList" % ns['swe'])
                        valueList.text = " ".join(
                            [str(a) for a in o["constraint"]["valueList"]])

                    elif "min" in o["constraint"]:  #.has_key("min"):
                        amin = et.SubElement(AllowedValues,
                                             "{%s}min" % ns['swe'])
                        amin.text = str(o["constraint"]["min"])

                    elif "max" in o["constraint"]:  #.has_key("max"):
                        amax = et.SubElement(AllowedValues,
                                             "{%s}max" % ns['swe'])
                        amax.text = str(o["constraint"]["max"])

        if timetag == False:
            raise Exception("self.data['outputs']: Time is mandatory")

        #--- System History
        if ("history" in self.data) and (not self.data["history"] == []):
            system.append(et.Comment("System History"))
            history = et.SubElement(system, "{%s}history" % ns['sml'])
            EventList = et.SubElement(history, "{%s}EventList" % ns['sml'])
            for h in self.data["history"]:
                member = et.SubElement(EventList, "{%s}member" % ns['sml'])
                member.attrib["name"] = h["type"]
                Event = et.SubElement(member, "{%s}Event" % ns['sml'])
                date = et.SubElement(Event, "{%s}date" % ns['sml'])
                date.text = h["date"]
                if not h["description"] == "":
                    description = et.SubElement(Event,
                                                "{%s}description" % ns['gml'])
                    description.text = h["description"]
                contact = et.SubElement(Event, "{%s}contact" % ns['sml'])
                contact.attrib["{%s}href" %
                               ns['xlink']] = h["reference"]["username"]
                contact.attrib["{%s}arcrole" %
                               ns['xlink']] = h["reference"]["role"]

        return et.tostring(root, encoding="UTF-8")
Beispiel #4
0
    def toRegisterSensorDom(self, indent=False):
        """
        Create a SOS register sensor request DOM element from self.procedure object
        """
        import sys
        ns = {
            'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
            'sml': 'http://www.opengis.net/sensorML/1.0.1',
            'swe': "http://www.opengis.net/swe/1.0.1",
            'xlink': "http://www.w3.org/1999/xlink",
            'gml': 'http://www.opengis.net/gml',
            'sos': "http://www.opengis.net/sos/1.0",
            'ogc': "http://www.opengis.net/ogc",
            'om': "http://www.opengis.net/om/1.0",
        }

        #---map namespaces---
        try:
            register_namespace = et.register_namespace
            for key in ns:
                register_namespace(key, ns[key])
        except AttributeError:
            try:
                et._namespace_map.update(ns)
                for key in ns:
                    et._namespace_map[ns[key]] = key
            except AttributeError:
                try:
                    from xml.etree.ElementTree import _namespace_map
                except ImportError:
                    try:
                        from elementtree.ElementTree import _namespace_map
                    except ImportError:
                        print >> sys.stderr, (
                            "Failed to import ElementTree from any known place"
                        )
                for key in ns:
                    _namespace_map[ns[key]] = key

        #---start creating XML ----
        root = et.Element("{%s}RegisterSensor" % ns['sos'])
        root.attrib["{%s}schemaLocation" % ns[
            'xsi']] = "http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd"
        root.attrib["version"] = "1.0.0"
        root.attrib["service"] = "SOS"

        SensorDescription = et.SubElement(root,
                                          "{%s}SensorDescription" % ns['sos'])

        sml = self.toXML()
        #print >> sys.stderr, "SML:%s" % sml
        from StringIO import StringIO
        smltree, smlns = parse_and_get_ns(StringIO(sml))
        member = smltree.find("{%s}member" % ns['sml'])
        SensorDescription.append(member)

        #---
        ObservationTemplate = et.SubElement(
            root, "{%s}ObservationTemplate" % ns['sos'])
        Observation = et.SubElement(ObservationTemplate,
                                    "{%s}Observation" % ns['om'])
        procedure = et.SubElement(Observation, "{%s}procedure" % ns['om'])
        procedure.attrib["{%s}href" % ns[
            'xlink']] = "urn:ogc:object:procedure:x-istsos:1.0:" + self.data[
                "system"]

        samplingTime = et.SubElement(Observation,
                                     "{%s}samplingTime" % ns['om'])
        TimePeriod = et.SubElement(samplingTime, "{%s}TimePeriod" % ns['gml'])
        beginPosition = et.SubElement(TimePeriod,
                                      "{%s}beginPosition" % ns['gml'])
        endPosition = et.SubElement(TimePeriod, "{%s}endPosition" % ns['gml'])

        observedProperty = et.SubElement(Observation,
                                         "{%s}observedProperty" % ns['om'])
        CompositePhenomenon = et.SubElement(
            observedProperty, "{%s}CompositePhenomenon" % ns['swe'])
        CompositePhenomenon.attrib["{%s}id" % ns['gml']] = str("comp_XXX")
        CompositePhenomenon.attrib["dimension"] = str(len(
            self.data["outputs"]))
        name = et.SubElement(CompositePhenomenon, "{%s}name" % ns['gml'])
        name.text = "timeSeriesOfObservations"
        for o in self.data["outputs"]:
            component = et.SubElement(CompositePhenomenon,
                                      "{%s}component" % ns['swe'])
            component.attrib["{%s}href" % ns['xlink']] = o["definition"]

        featureOfInterest = et.SubElement(Observation,
                                          "{%s}featureOfInterest" % ns['om'])
        featureOfInterest.attrib[
            "{%s}href" %
            ns['xlink']] = self.data["location"]["properties"]["name"]
        FeatureCollection = et.SubElement(featureOfInterest,
                                          "{%s}FeatureCollection" % ns['gml'])
        #FeatureCollection = et.SubElement(featureOfInterest, "{%s}FeatureCollection" % ns['gml'])
        location = et.SubElement(FeatureCollection, "{%s}location" % ns['gml'])
        Point = et.SubElement(location, "{%s}Point" % ns['gml'])
        Point.attrib["{%s}id" % ns['gml']] = "gmlfoi_" + self.data["location"][
            "properties"]["name"]
        Point.attrib["srsName"] = self.data["location"]["crs"]["properties"][
            "name"] if "EPSG:" in self.data["location"]["crs"]["properties"][
                "name"] else "EPSG:%s" % self.data["location"]["crs"][
                    "properties"]["name"]
        coordinates = et.SubElement(Point, "{%s}coordinates" % ns['gml'])
        coordinates.text = ",".join(
            [str(a) for a in self.data["location"]["geometry"]["coordinates"]])

        result = et.SubElement(Observation, "{%s}result" % ns['om'])
        DataArray = et.SubElement(result, "{%s}DataArray" % ns['swe'])

        elementCount = et.SubElement(DataArray, "{%s}elementCount" % ns['swe'])
        count = et.SubElement(elementCount, "{%s}count" % ns['swe'])
        value = et.SubElement(count, "{%s}value" % ns['swe'])
        value.text = str(len(self.data["outputs"]))

        elementType = et.SubElement(DataArray, "{%s}elementType" % ns['swe'])
        elementType.attrib["name"] = "SimpleDataArray"
        elementType.attrib["{%s}href" % ns[
            'xlink']] = "urn:ogc:def:dataType:x-istsos:1.0:timeSeriesDataRecord"

        DataRecord = smltree.find(
            "{%s}member/{%s}System/{%s}outputs/{%s}OutputList/{%s}output/{%s}DataRecord"
            %
            (ns['sml'], ns['sml'], ns['sml'], ns['sml'], ns['sml'], ns['swe']))

        elementType.append(DataRecord)

        encoding = et.SubElement(DataArray, "{%s}encoding" % ns['swe'])
        TextBlock = et.SubElement(encoding, "{%s}TextBlock" % ns['swe'])
        TextBlock.attrib["tokenSeparator"] = ","
        TextBlock.attrib["blockSeparator"] = "@"
        TextBlock.attrib["decimalSeparator"] = "."

        #values = et.SubElement(DataArray, "{%s}values" % ns['swe'])

        return root
Beispiel #5
0
def render(DS,sosConfig):
    # Returning content of the SensorML

    try:
        #---parse xml
        tree, ns = parse_and_get_ns(DS.smlFile)
    except Exception as ex:
        raise Exception("sensorML description for procedure '%s' not found or corrupted! [%s]"%(DS.smlFile,ex))

    #---map namespaces---
    try:
        register_namespace = et.register_namespace
        for key in ns:
            register_namespace(key,ns[key])
    except AttributeError:
        try:
            et._namespace_map.update(ns)
            for key in ns:
                et._namespace_map[ns[key]] = key
        except AttributeError:
            try:
                from xml.etree.ElementTree import _namespace_map
            except ImportError:
                try:
                    from elementtree.ElementTree import _namespace_map
                except ImportError:
                    print >> sys.stderr, ("Failed to import ElementTree from any known place")
            for key in ns:
                _namespace_map[ns[key]] = key

    mns = {
            'xsi': "http://www.w3.org/2001/XMLSchema-instance" ,
            'sml': "http://www.opengis.net/sensorML/1.0.1",
            'swe': "http://www.opengis.net/swe/1.0.1",
            'xlink': "http://www.w3.org/1999/xlink",
            'gml': 'http://www.opengis.net/gml'
        }

    for n in mns.keys():
        try:
            ns[n]
        except:
            ns[n] = mns[n]


    #--- CREEATE FIELDS ACCORDING TO DATABASE OBSERVED_PROPERTIES
    datarecord = tree.find("{%s}member/{%s}System/{%s}outputs/{%s}OutputList/{%s}output/{%s}DataRecord"
                        %(ns['sml'],ns['sml'],ns['sml'],ns['sml'],ns['sml'],ns['swe']) )


    datarecord.clear()
    datarecord.attrib["definition"] = "%stimeSeries" % (sosConfig.urn['dataType'])
    fieldT = et.SubElement(datarecord,"{%s}field" % ns["swe"])
    fieldT.attrib["name"] = "Time"
    time = et.SubElement(fieldT,"{%s}Time" % ns["swe"])
    time.attrib["definition"] = sosConfig.urn["time"]

    # Adding constraint for current allowed times
    if (not DS.stime == None) and (not DS.etime == None):
        constraint =  et.SubElement(time, "{%s}constraint" % ns['swe'])
        allowedTimes =  et.SubElement(constraint, "{%s}AllowedTimes" % ns['swe'])
        interval = et.SubElement(allowedTimes, "{%s}interval" % ns['swe'])
        interval.text = "%s %s" %(DS.stime.strftime("%Y-%m-%dT%H:%M:%S.%fZ"), DS.etime.strftime("%Y-%m-%dT%H:%M:%S.%fZ"))

    if DS.procedureType=="insitu-mobile-point": # Adding 3d coordinates observation

        cord = et.SubElement(datarecord,"{%s}field" % ns["swe"])
        cord.attrib["name"] = "x"
        quantity = et.SubElement(cord,"{%s}Quantity" % ns["swe"])
        quantity.attrib["definition"] = sosConfig.urn["refsystem"] + sosConfig.istsosepsg + ":x-position"

        cord = et.SubElement(datarecord,"{%s}field" % ns["swe"])
        cord.attrib["name"] = "y"
        quantity = et.SubElement(cord,"{%s}Quantity" % ns["swe"])
        quantity.attrib["definition"] = sosConfig.urn["refsystem"] + sosConfig.istsosepsg + ":y-position"

        cord = et.SubElement(datarecord,"{%s}field" % ns["swe"])
        cord.attrib["name"] = "z"
        quantity = et.SubElement(cord,"{%s}Quantity" % ns["swe"])
        quantity.attrib["definition"] = sosConfig.urn["refsystem"] + sosConfig.istsosepsg + ":z-position"


    for index, field in enumerate(DS.observedProperties):

        fieldQ = et.SubElement(datarecord,"{%s}field" % ns["swe"])
        fieldQ.attrib["name"] = field["name_opr"]
        quantity = et.SubElement(fieldQ,"{%s}Quantity" % ns["swe"])
        quantity.attrib["definition"] = field["def_opr"]

        if not (field["name_uom"]=="" or field["name_uom"]==None or field["name_uom"]=="NULL"):
            uom = et.SubElement(quantity,"{%s}uom" % ns["swe"])
            uom.attrib["code"] = field["name_uom"]
        """
        if not (field["desc_opr"]=="" or field["desc_opr"]==None or field["desc_opr"]=="NULL"):
            description = et.SubElement(quantity,"{%s}description" % ns["swe"])
            description.text = field["desc_opr"]
        """

        """
        # Handling constraint
        Permitted conigurations:
            {"role":"urn:ogc:def:classifiers:x-istsos:1.0:qualityIndex:check:reasonable","min":"10"}
            {"role":"urn:ogc:def:classifiers:x-istsos:1.0:qualityIndex:check:reasonable","max":"10"}
            {"role":"urn:ogc:def:classifiers:x-istsos:1.0:qualityIndex:check:reasonable","interval":["-10","10"]}
            {"role":"urn:ogc:def:classifiers:x-istsos:1.0:qualityIndex:check:reasonable","valueList":["1","2","3","4","5","6"]}
        """
        if not (field["constr_pro"]=="" or field["constr_pro"]==None):
            try:
                constraintObj = json.loads(field["constr_pro"])

                constraint = et.SubElement(quantity,"{%s}constraint" % ns["swe"])

                # Role attribute is not mandatory
                if "role" in constraintObj and constraintObj["role"]!="" and constraintObj["role"]!=None:
                    constraint.attrib[ "{%s}role" % ns['xlink'] ]= constraintObj["role"]

                AllowedValues = et.SubElement(constraint, "{%s}AllowedValues" % ns['swe'])

                # Factory on constraint min/max/interval/valuelist
                if "interval" in constraintObj:
                    interval = et.SubElement(AllowedValues, "{%s}interval" % ns['swe'])
                    interval.text = " ".join([ str(a) for a in constraintObj["interval"] ])
                    #interval.text = " ".join(constraintObj["interval"])

                elif "valueList" in constraintObj:#.has_key("valueList"):
                    valueList = et.SubElement(AllowedValues, "{%s}valueList" % ns['swe'])
                    valueList.text = ", ".join([ str(a) for a in constraintObj["valueList"] ])
                    #valueList.text = " ".join(constraintObj["valueList"])

                elif "min" in constraintObj:#.has_key("min"):
                    amin = et.SubElement(AllowedValues, "{%s}min" % ns['swe'])
                    amin.text = str(constraintObj["min"])

                elif "max" in constraintObj:#.has_key("max"):
                    amax = et.SubElement(AllowedValues, "{%s}max" % ns['swe'])
                    amax.text = str(constraintObj["max"])

            except Exception:
                raise Exception("Constraint definition invalid in the database for %s" % field["def_opr"])

    #verify that gml_id does not contain blanks
    #(workaround to be corrected in future name sensor registration)
#    ------------------------------------------
#    NCName stands for "non-colonized name".
#    NCName can be defined as an XML Schema regular expression [\i-[:]][\c-[:]]*
#
#    So in plain English it would mean "any initial character, but not :".
#    The whole regular expression reads as "One initial XML name character,
#    but not a colon, followed by zero or more XML name characters, but not a colon."
#
#    The practical restrictions of NCName are that it cannot contain several symbol characters
#    ------------------------------------------

    not_allowed_NCName = [' ', '!','"', '#', '$', '%', '&', '\'',
                          '(', ')', '*', '+', ',', '/', ':', ';',
                          '<', '=', '>', '?', '@', '[', '\\', ']',
                          '^', '`', '{', '|', '}', '~']

    location = tree.find("{%s}member/{%s}System/{%s}location" % (
        ns['sml'],
        ns['sml'],
        ns['sml']))

    for feature in location:
        for ch in not_allowed_NCName:
            if ch in feature.attrib['{%s}id' % ns['gml']]:
                feature.attrib['{%s}id' % ns['gml']] = feature.attrib['{%s}id' %ns['gml']].replace(ch,"_")

        # An underscore is added to be OGC compliant
        #   -> WALIB remove this underscore !!
        #   @TODO: think something better
        if not sosConfig.urn["feature"] in feature.attrib['{%s}id' % ns['gml']]:
            feature.attrib['{%s}id' % ns['gml']] = "loc_%s" % (
                feature.attrib['{%s}id' % ns['gml']])

    # The unique identifier in the response document matches the procedure specified in the request
    system = tree.find("{%s}member/{%s}System" %(ns['sml'],ns['sml']))
    identification = tree.find("{%s}member/{%s}System/{%s}identification" %(ns['sml'],ns['sml'],ns['sml']))

    if not identification:
        identification = et.Element("{%s}identification" % ns["sml"])
        identifierList = et.SubElement(identification, "{%s}IdentifierList" % ns["sml"])
        identifier = et.SubElement(identifierList, "{%s}identifier" % ns["sml"])
        term = et.SubElement(identifier, "{%s}Term" % ns["sml"])
        term.attrib['definition'] = "urn:ogc:def:identifier:OGC:uniqueID"
        value = et.SubElement(term, "{%s}value" % ns["sml"])
        value.text = system.attrib['{%s}id' % ns['gml']]
        system.insert(1, identification)

    else:
        identifierList = identification.find("{%s}IdentifierList" % ns["sml"])
        if not identifierList:
            identifierList = et.SubElement(identification, "{%s}IdentifierList" % ns["sml"])
            identifier = et.SubElement(identifierList, "{%s}identifier" % ns["sml"])
            term = et.SubElement(identifier, "{%s}Term" % ns["sml"])
            term.attrib['definition'] = "urn:ogc:def:identifier:OGC:uniqueID"
            value = et.SubElement(term, "{%s}value" % ns["sml"])
            value.text = system.attrib['{%s}id' % ns['gml']]

        else:
            identifiers = identifierList.findall("{%s}identifier" % ns["sml"])
            unique = False
            for identifier in identifiers:
                if identifier.find("{%s}Term" % ns["sml"]).attrib['definition'] == "urn:ogc:def:identifier:OGC:uniqueID":
                    unique = True
                    break

            if not unique:
                identifier = et.SubElement(identifierList,"{%s}identifier" % ns["sml"])
                term = et.SubElement(identifier,"{%s}Term" % ns["sml"])
                term.attrib['definition'] = "urn:ogc:def:identifier:OGC:uniqueID"
                value = et.SubElement(term,"{%s}value" % ns["sml"])
                value.text = system.attrib['{%s}id' %ns['gml']]

    root = tree.getroot()
    root.attrib["xmlns"]="http://www.opengis.net/sensorML/1.0.1"
    root.attrib["version"]="1.0.1"
    return """<?xml version="1.0" encoding="UTF-8"?>\n%s""" % et.tostring(root)