Пример #1
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):
        f.sosFilter.__init__(self, sosRequest, method, requestObject,
                             sosConfig)
        #**************************
        if method == "GET":
            raise sosException.SOSException(
                "NoApplicableCode", None,
                "registerSensor request support only POST method!")

        if method == "POST":

            #---assignedSensorId
            asid = requestObject.getElementsByTagName('AssignedSensorId')
            if len(asid) == 1:
                self.assignedSensorId = getElemTxt(asid[0])
            else:
                raise sosException.SOSException(
                    "MissingParameterValue", "AssignedSensorId",
                    "AssignedSensorId parameter is mandatory with multiplicity 1"
                )

            #---SensorDescription
            sd = requestObject.getElementsByTagName('SensorDescription')
            if len(sd) == 1:
                self.xmlSensorDescription = sd[0]
            else:
                raise sosException.SOSException(
                    "MissingParameterValue", "SensorDescription",
                    "SensorDescription parameter is mandatory with multiplicity 1"
                )
Пример #2
0
def CQLvalueFilter2PostgisSql(fildName, CQLfilter):
    """parse a CQL filter and returen an SQL filter"""
    CQLsupportedOperators = ("<", "<=", ">", ">=", "=")

    if CQLfilter.__class__.__name__ in ["str", "StringField"]:
        if CQLfilter[0] in ["<", ">", "="]:
            if CQLfilter[1] in ["="]:
                if not CQLfilter[2:].isdigit():
                    raise sosException.SOSException(
                        "NoApplicableCode", None,
                        "CQLvalueFilter2PostgisSql: only numeric comparison supported"
                    )
            else:
                if not CQLfilter[1:].isdigit():
                    raise sosException.SOSException(
                        "NoApplicableCode", None,
                        "CQLvalueFilter2PostgisSql: only numeric comparison supported"
                    )
        else:
            raise sosException.SOSException(
                "NoApplicableCode", None,
                "CQLvalueFilter2PostgisSql: only filter by comparing values is supported"
            )
    else:
        raise sosException.SOSException(
            "NoApplicableCode", None,
            "CQLvalueFilter2PostgisSql: input must be a string")
    return "%s %s" % (fildName, CQLfilter)
Пример #3
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):
        f.sosFilter.__init__(self, sosRequest, method, requestObject,
                             sosConfig)

        if method == "GET":

            self.sections = None

            if "section" in requestObject:
                self.sections = requestObject["section"].lower().split(",")

            if "sections" in requestObject:
                self.sections = requestObject["sections"].lower().split(",")

            if self.sections:
                for s in self.sections:
                    if self.version == '2.0.0':
                        if s not in sosConfig.parameters["GC_Section_2_0_0"]:
                            err_txt = "Allowed parameter \"section\" values are: " + ",".join(
                                sosConfig.parameters["GC_Section"])
                            raise sosException.SOSException(
                                "InvalidParameterValue", "section", err_txt)

                    else:
                        if s not in sosConfig.parameters["GC_Section"]:
                            err_txt = "Allowed parameter \"section\" values are: " + ",".join(
                                sosConfig.parameters["GC_Section"])
                            raise sosException.SOSException(
                                "InvalidParameterValue", "section", err_txt)

            else:
                self.sections = ["all"]

        if method == "POST":

            if requestObject.nodeType == requestObject.ELEMENT_NODE:
                #-------SECTIONS-------------
                self.sections = []
                sects = requestObject.getElementsByTagName('section')

                if len(sects) > 0:
                    for sect in sects:
                        for val in sect.childNodes:
                            if val.nodeType == val.TEXT_NODE and str(
                                    val.data).lower(
                                    ) in sosConfig.parameters["GC_Section"]:
                                self.sections.append(str(val.data).lower())
                            else:
                                err_txt = "Allowed parameter \"section\" values are: " + ",".join(
                                    sosConfig.parameters["GC_Section"])
                                raise sosException.SOSException(
                                    "InvalidParameterValue", "sections",
                                    err_txt)

                else:
                    self.sections = ["all"]
Пример #4
0
 def checkAuthorization(self):
     if self.service and self.user and not self.user.isAdmin():
         if self.service == 'default':
             raise sosException.SOSException(
                 "ResourceNotFound", "Authorization",
                 "Access to admin request are not allowed.")
         elif not self.user.allowedService(self.service):
             raise sosException.SOSException(
                 "ResourceNotFound", "Authorization",
                 "You don't have the permissions to access the '%s' instance."
                 % self.service)
Пример #5
0
    def __init__(self,filter,pgdb):
        
        #check assigned sensor id
        sql  = "SELECT id_prc, name_prc FROM %s.procedures WHERE assignedid_prc='%s'" %(filter.sosConfig.schema,get_name_from_urn(filter.assignedSensorId,"sensor",filter.sosConfig))
        try:
            prc = pgdb.select(sql)[0]
        except:
            raise sosException.SOSException("InvalidParameterValue","assignedSensorId","assignedSensorId: '%s' is not valid!" %(filter.assignedSensorId))
    
        #----------------------------------------
        # create SensorML for inserted procedure
        #----------------------------------------
        
        f = open(filter.sosConfig.sensorMLpath + filter.procedure + ".xml", 'w')
        
        xml_pre = """<SensorML xmlns:sml="http://www.opengis.net/sensorML/1.0.1"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:swe="http://www.opengis.net/swe/1.0.1"
          xmlns:gml="http://www.opengis.net/gml"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          xsi:schemaLocation="http://www.opengis.net/sensorML/1.0.1 http://schemas.opengis.net/sensorML/1.0.1/sensorML.xsd"
          version="1.0.1">
  <member xlink:arcrole="urn:ogc:def:process:OGC:detector">"""
 
        xml_ascii = filter.xmlSensorDescription.toxml().encode('ascii','ignore')
        
        xml_post = "  </member>\n</SensorML>"
        
        f.write(xml_pre + xml_ascii + xml_post)
        f.close()
        
        self.procedure = prc["name_prc"]
Пример #6
0
def get_name_from_urn(stringa, urnName, sosConfig):
    a = stringa.split(":")
    name = a[-1]
    urn = sosConfig.urn[urnName].split(":")
    if len(a) > 1:
        for index in range(len(urn) - 1):
            if urn[index] == a[index]:
                pass
            else:
                raise sosException.SOSException(
                    1, "Urn \"%s\" is not valid: %s." % (a, urn))
    return name
Пример #7
0
def sosFactoryRender(response, sosConfig):

    res_type = str(response.__class__.__name__)

    if res_type == "GetCapabilitiesResponse":
        from istsoslib.renderers import GCresponseRender
        if response.version == '2.0.0':
            return GCresponseRender.render_2_0_0(response, sosConfig)

        else:
            return GCresponseRender.render(response, sosConfig)

    elif res_type == "DescribeSensorResponse":
        from istsoslib.renderers import DSresponseRender
        if response.version == '2.0.0':
            return DSresponseRender.render_2_0_0(response, sosConfig)

        else:
            return DSresponseRender.render(response, sosConfig)

    elif res_type in [
            "GetObservationResponse", "GetObservationResponse_2_0_0"
    ]:
        from istsoslib.renderers import GOresponseRender
        return GOresponseRender.render(response, sosConfig)

    elif res_type == "foi":
        from istsoslib.renderers import GFresponseRender
        return GFresponseRender.render(response, sosConfig)

    elif res_type == "InsertObservationResponse":
        from istsoslib.renderers import IOresponseRender
        return IOresponseRender.render(response, sosConfig)

    elif res_type == "RegisterSensorResponse":
        from istsoslib.renderers import RSresponseRender
        return RSresponseRender.render(response, sosConfig)

    elif res_type == "UpdateSensorDescriptionResponse":
        from istsoslib.renderers import USDresponseRender
        return USDresponseRender.render(response, sosConfig)

    else:
        raise sosException.SOSException(
            "InvalidRequest", "request", "\"request\": %s not supported" %
            (str(response.__class__.__name__)))
Пример #8
0
    def __init__(self,sosRequest,method,requestObject,sosConfig):
        f.sosFilter.__init__(self,sosRequest,method,requestObject,sosConfig)
        #**************************
        if method == "GET":
            #---FeatureOfInterest
            if not requestObject.has_key("featureofinterestid"):
                raise sosException.SOSException("MissingParameterValue","FeatureOfInterestId","Parameter \"FeatureOfInterestId\" is required with multiplicity 1")
            else:
                self.featureOfInterest = get_name_from_urn(requestObject["featureofinterestid"],"feature",sosConfig) #one-many ID
            #---srsName
            if requestObject.has_key("srsname"):
                self.srsName = get_name_from_urn(requestObject["srsname"],"refsystem",sosConfig)
                if not self.srsName in sosConfig.parameters["GO_srs"]:
                    raise sosException.SOSException("OptionNotSupported","srsName","Supported \"srsName\" valueas are: " + ",".join(sosConfig.parameters["GO_srs"]))
            else:
                self.srsName = sosConfig.parameters["GO_srs"][0]
        if method == "POST":
            #---FeatureOfInterest
            fets = requestObject.getElementsByTagName('FeatureOfInterestId')
            if len(fets)==1:
                try:
                    self.featureOfInterest = get_name_from_urn(getElemAtt(fets[0],"xlink:href"),"feature",sosConfig)
                except:
                    try:
                        self.featureOfInterest = get_name_from_urn(getElemTxt(fets[0]),"feature",sosConfig)
                    except:
                        err_txt = "XML parsing error (get value: FeatureOfInterestId)"
                        raise sosException.SOSException("NoApplicableCode",None,err_txt)
            else:
                err_txt = "parameter \"FeatureOfInterestId\" is mandatory with multiplicity 1"
                if len(fets)==0:
                    raise sosException.SOSException("MissingParameterValue","FeatureOfInterestId",err_txt)
                else:
                    raise sosException.SOSException("NoApplicableCode",None,err_txt)

            #---srsName
            srss = requestObject.getElementsByTagName('srsName')
            if len(srss) ==1:
                self.srsName = get_name_from_urn(getElemTxt(srss[0]),"refsystem",sosConfig)
                if not self.srsName in sosConfig.parameters["GO_srs"]:
                    raise sosException.SOSException("OptionNotSupported","srsName","Supported \"srsName\" valueas are: " + ",".join(sosConfig.parameters["GO_srs"]))
            elif len(srss) == 0:
                self.srsName = sosConfig.parameters["GO_srs"][0]
            else:
                err_txt = "parameter \"srsName\" is optional with multiplicity 1"
                raise sosException.SOSException("NoApplicableCode",None,err_txt)
Пример #9
0
def sosFactoryResponse(sosFilter, pgdb):

    if sosFilter.request == "getcapabilities":
        from istsoslib.responders import GCresponse
        return GCresponse.GetCapabilitiesResponse(sosFilter, pgdb)

    elif sosFilter.request == "describesensor":
        from istsoslib.responders import DSresponse
        return DSresponse.DescribeSensorResponse(sosFilter, pgdb)

    elif sosFilter.request == "getobservation":
        from istsoslib.responders import GOresponse
        if sosFilter.version == '2.0.0':
            return GOresponse.GetObservationResponse_2_0_0(sosFilter, pgdb)

        else:
            return GOresponse.GetObservationResponse(sosFilter, pgdb)

    elif sosFilter.request == "getfeatureofinterest":
        from istsoslib.responders import GFresponse
        return GFresponse.foi(sosFilter, pgdb)

    elif sosFilter.request == "insertobservation":
        from istsoslib.responders import IOresponse
        return IOresponse.InsertObservationResponse(sosFilter, pgdb)

    elif sosFilter.request == "registersensor":
        from istsoslib.responders import RSresponse
        return RSresponse.RegisterSensorResponse(sosFilter, pgdb)

    elif sosFilter.request == "updatesensordescription":
        from istsoslib.responders import USDresponse
        return USDresponse.UpdateSensorDescription(sosFilter, pgdb)

    else:
        raise sosException.SOSException(
            "InvalidRequest", "request",
            "\"request\": %s not supported" % (sosFilter.request))
Пример #10
0
def ogcCompCons2PostgisSql(ogcComparisonOperator):
    """parse an ogc property operator element and convert it to a PostGIS SQL WHERE clause"""
    ogcSupportedCompOperators = {
        'ogc:PropertyIsEqualTo': '=',
        'ogc:PropertyIsNotEqualTo': '!=',
        'ogc:PropertyIsLessThan': '<',
        'ogc:PropertyIsGreaterThan': '>',
        'ogc:PropertyIsLessThanOrEqualTo': '<=',
        'ogc:PropertyIsGreaterThanOrEqualTo': '>=',
    }
    """
    'ogc:PropertyIsBetween':'BETWEEN'
    'ogc:PropertyIsLike':'LIKE',
    'ogc:PropertyIsNull':'= NULL'
    """

    if ogcComparisonOperator.__class__.__name__ in ["str", "StringField"]:
        xmlString = """<?xml version="1.0" encoding="UTF-8"?><sos:result 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://schemas.opengis.net/sos/1.0.0/sosAll.xsd"
        xmlns:sos="http://www.opengis.net/sos/1.0"
        xmlns:gml="http://www.opengis.net/gml/3.2"
        xmlns:ogc="http://www.opengis.net/ogc"
        xmlns:om="http://www.opengis.net/om/1.0" 
        service="SOS" version='1.0.0'>
        """
        xmlString += ogcComparisonOperator + "</sos:result>"
        xmlObject = minidom.parseString(xmlString)
        res = xmlObject.getElementsByTagName("sos:result")[0]
        ogcComparisonOperator = childElementNodes(res)[0]

    try:
        ogcOperator = ogcComparisonOperator.nodeName.encode()
    except:
        raise sosException.SOSException(
            "NoApplicableCode", None,
            "ogcCompCons2PostgisSql: argunment must be an ''XML object'' or a valid ''XML string''"
        )

    prop = ''
    sql = ''

    #---------------------------
    # PARSE OPTIONS
    #---------------------------
    if ogcOperator in ogcSupportedCompOperators.keys():
        childs = childElementNodes(ogcComparisonOperator)
        propertyNameObj = ogcComparisonOperator.getElementsByTagName(
            "ogc:PropertyName")
        literalObj = ogcComparisonOperator.getElementsByTagName("ogc:Literal")
        matchCase = True
        if len(propertyNameObj) == 1 and len(literalObj) == 1:
            #raise sosException.SOSException(1,"XML %s" %(propertyNameObj[0].data))
            propertyName = propertyNameObj[0].firstChild.data.encode().strip()
            """ -- unsupported because only digits are valid --
            if propertyNameObj[0].value.upper()=="FALSE": 
                matchCase = False
            """
            literal = literalObj[0].firstChild.data.encode().strip()
            if not literal.isdigit() and not literal == None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "Sorry istsos support only numeric constraints, provided: \'%s\'"
                    % (literal))
        else:
            raise sosException.SOSException(
                "NoApplicableCode", None,
                "ogcCompCons2PostgisSql: ogc:comparisonOps allow only two expression"
            )

        return ("%s" % (propertyName),
                "%s %s" % (ogcSupportedCompOperators[ogcOperator], literal))
    else:
        raise sosException.SOSException(
            "NoApplicableCode", None,
            "ogcCompCons2PostgisSql: ogc:comparisonOps not jet supported")
Пример #11
0
def sosFactoryFilter(environ, sosConfig):
    """Instantiate the correct filter type depending on requests

    Args:
        environ (obj): the mod_wsgi environment object
        sosCOnfig (obj): the service configuration

    Returns:
        filter (obj): the filter subclass which meet the request

    Raises:
        Exception if missing or invalid parameters are used in the request

    """
    content_type = environ.get('CONTENT_TYPE', '')
    # set method, requestObject and sosRequest
    method = str(environ['REQUEST_METHOD']).upper()
    if method == "GET":
        # Returns a dictionary containing lists as values.
        #  > keep_blank_values used in version 2.0.0 to check
        #  > null parameter exceptions
        rect = parse_qs(environ['QUERY_STRING'], keep_blank_values=True)
        requestObject = {}
        for key in rect.keys():
            requestObject[key.lower()] = rect[key][0]
        if "request" in requestObject:
            sosRequest = requestObject["request"].lower()
        else:
            raise sosException.SOSException(
                "MissingParameterValue", "request",
                "Parameter \"request\" is mandatory")

    elif method == "POST":
        # the environment variable CONTENT_LENGTH may be empty or missing
        try:
            request_body_size = int(environ.get('CONTENT_LENGTH', 0))
        except (ValueError):
            request_body_size = 0

        # get the request
        from xml.dom import minidom

        content = environ['wsgi.input'].read(request_body_size)

        if content_type.startswith("application/x-www-form-urlencoded"):
            form = cgi.parse_qs(content)
            if "request" in form:
                xmldoc = minidom.parseString(form["request"][0])
            else:
                raise sosException.SOSException(
                    "MissingParameterValue", "request",
                    "Parameter \"request\" is mandatory")

        else:
            try:
                xmldoc = minidom.parseString(content)
            except:
                raise sosException.SOSException(
                    "MissingParameterValue", None,
                    "Unable to parse the request body: validation issue")

        requestObject = xmldoc.firstChild
        sosRequest = requestObject.localName.lower()

    else:
        raise sosException.SOSException(
            "InvalidRequest", None, "Allowed \"http request\" are GET and "
            "POST: %s" % (method == "GET"))

    # if request is allowed instantiate the rigth filter
    if sosRequest in sosConfig.parameters["requests"]:
        if sosRequest == "getcapabilities":
            from istsoslib.filters import GC_filter
            return GC_filter.sosGCfilter(sosRequest, method, requestObject,
                                         sosConfig)

        elif sosRequest == "describesensor":
            from istsoslib.filters import DS_filter
            return DS_filter.sosDSfilter(sosRequest, method, requestObject,
                                         sosConfig)

        elif sosRequest == "getobservation":
            from istsoslib.filters import GO_filter
            return GO_filter.sosGOfilter(sosRequest, method, requestObject,
                                         sosConfig)

        elif sosRequest == "getfeatureofinterest":
            from istsoslib.filters import GF_filter
            return GF_filter.sosGFfilter(sosRequest, method, requestObject,
                                         sosConfig)

        elif sosRequest == "insertobservation":
            from istsoslib.filters import IO_filter
            return IO_filter.sosIOfilter(sosRequest, method, content,
                                         sosConfig)

        elif sosRequest == "registersensor":
            from istsoslib.filters import RS_filter
            return RS_filter.sosRSfilter(sosRequest, method, content,
                                         sosConfig)

        elif sosRequest == "updateSensorDescription":
            from istsoslib.filters import USD_filter
            return USD_filter.sosUSDfilter(sosRequest, method, requestObject,
                                           sosConfig)

    else:
        raise sosException.SOSException(
            "InvalidParameterValue", "request",
            "\"request\": %s not supported" % (sosRequest))
Пример #12
0
    def __init__(self, filter, pgdb):
        #sys.stderr.write("*****************************************************************")
        self.name = filter.featureOfInterest
        self.type = ""
        self.desc = ""
        self.procedures = []
        self.idPrc = []
        self.obsType = []
        self.samplingTime = []
        self.properties = []
        self.geom = ""

        #select foi
        sql = "SELECT id_foi, name_foi, desc_foi, ST_AsGml(ST_Transform(geom_foi,%s)) as geom, name_fty"  #%(filter.srsName)
        sql += " FROM %s.foi, %s.feature_type" % (filter.sosConfig.schema,
                                                  filter.sosConfig.schema)
        sql += " WHERE id_fty_fk=id_fty AND name_foi=%s"  #%(filter.featureOfInterest)
        params = (filter.srsName, str(filter.featureOfInterest))
        try:
            foi = pgdb.select(sql, params)[0]
        except:
            raise sosException.SOSException(
                "InvalidParameterValue", "FeatureOfInterestId",
                "FeatureOfInterestId: Feature of Interest '%s' not found." %
                (filter.featureOfInterest))

        self.name = foi["name_foi"]
        self.desc = foi["desc_foi"]
        self.type = foi["name_fty"]
        self.geom = foi["geom"]

        #select procedures
        sql = "SELECT id_prc, name_prc, name_oty "
        sql += "FROM %s.procedures, %s.foi, %s.obs_type " % (
            filter.sosConfig.schema, filter.sosConfig.schema,
            filter.sosConfig.schema)
        sql += "WHERE id_foi_fk=id_foi AND id_oty=id_oty_fk AND name_foi=%s "  #%(filter.featureOfInterest)
        sql += "ORDER BY name_prc "
        params = (str(filter.featureOfInterest), )
        try:
            prc = pgdb.select(sql, params)
        except:
            raise Exception("GFresponse, SQL: %s" %
                            (pgdb.mogrify(sql, params)))

        for p in prc:
            self.procedures.append(p["name_prc"])
            self.obsType.append(p["name_oty"])
            self.idPrc.append(p["id_prc"])
            # select obesrved properties of aa given procedure
            sql = "SELECT name_opr "
            sql += " FROM %s.procedures, %s.proc_obs, %s.observed_properties" % (
                filter.sosConfig.schema, filter.sosConfig.schema,
                filter.sosConfig.schema)
            sql += " WHERE id_prc=id_prc_fk AND id_opr=id_opr_fk AND name_prc=%s"  #%(p["name_prc"])
            sql += " ORDER BY name_opr"
            params = (p["name_prc"], )
            try:
                obs = pgdb.select(sql, params)
            except:
                raise Exception("GFresponse, SQL: %s" %
                                (pgdb.mogrify(sql, params)))
            obsArr = []
            for o in obs:
                obsArr.append(o['name_opr'])
            self.properties.append(obsArr)

            sql = "SELECT MIN(time_eti) as firstet, MAX(time_eti) as lastet FROM %s.event_time " % (
                filter.sosConfig.schema)
            sql += "WHERE id_prc_fk = %s GROUP BY id_prc_fk"  #% (p["id_prc"])
            params = (p["id_prc"], )
            try:
                samplTime = pgdb.select(sql, params)
            except:
                raise Exception("GFresponse, SQL: %s" %
                                (pgdb.mogrify(sql, params)))
            samplTimeArr = []
            for st in samplTime:
                samplTimeArr.append([st['firstet'], st['lastet']])
            self.samplingTime.append(samplTimeArr)
Пример #13
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):

        f.sosFilter.__init__(self, sosRequest, method, requestObject,
                             sosConfig)
        if method == "GET":
            raise sosException.SOSException(
                "NoApplicableCode", None,
                "registerSensor request support only POST method!")

        if method == "POST":
            from StringIO import StringIO

            tree, ns = parse_and_get_ns(StringIO(requestObject))

            SensorDescription = tree.find("{%s}SensorDescription" % ns['sos'])
            if SensorDescription is None:
                raise sosException.SOSException(
                    "MissingParameterValue", "SensorDescription",
                    ("sos:SensorDescription parameter is "
                     "mandatory with multiplicity 1"))

            name = tree.find(
                "{%s}SensorDescription/{%s}member/{%s}System/{%s}name" %
                (ns['sos'], ns['sml'], ns['sml'], ns['gml']))
            self.procedure = name.text

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

            if not description is None:
                self.proc_desc = description.text
            else:
                self.proc_desc = 'NULL'

            #---Capabilities
            capabilities = tree.findall(
                "{%s}SensorDescription/{%s}member/{%s}System/"
                "{%s}capabilities/{%s}DataRecord/{%s}field" %
                (ns['sos'], ns['sml'], ns['sml'], ns['sml'], ns['swe'],
                 ns['swe']))

            self.time_sam_val = "0"
            self.time_acq_val = "0"

            for cap in capabilities:

                if ('name' in cap.attrib
                        and cap.attrib['name'] == 'Sampling time resolution'):

                    tmpSam = int(
                        cap.find("{%s}Quantity/{%s}value" %
                                 (ns['swe'], ns['swe'])).text)

                    uom = cap.find("{%s}Quantity/{%s}uom" %
                                   (ns['swe'], ns['swe']))

                    if 'code' in uom.attrib:
                        uomSam = uom.attrib['code']
                        self.time_sam_val = convertToSec[uomSam](tmpSam)
                    else:
                        raise sosException.SOSException(
                            "MissingParameterValue", "SensorDescription",
                            ("sml:capabilities, missing uom for "
                             "Sampling time resolution"))
                elif ('name' in cap.attrib
                      and cap.attrib['name'] == 'Acquisition time resolution'):

                    tmpAcq = int(
                        cap.find("{%s}Quantity/{%s}value" %
                                 (ns['swe'], ns['swe'])).text)
                    uom = cap.find("{%s}Quantity/{%s}uom" %
                                   (ns['swe'], ns['swe']))
                    if 'code' in uom.attrib:
                        uomAcq = uom.attrib['code']
                        self.time_acq_val = convertToSec[uomAcq](tmpAcq)
                    else:
                        raise sosException.SOSException(
                            "MissingParameterValue", "SensorDescription",
                            ("sml:capabilities, missing uom "
                             "for Sampling time resolution"))

            self.systemType = None
            classifiers = tree.findall(
                "{%s}SensorDescription/{%s}member/{%s}System/"
                "{%s}classification/{%s}ClassifierList/{%s}classifier" %
                (ns['sos'], ns['sml'], ns['sml'], ns['sml'], ns['sml'],
                 ns['sml']))
            for classifier in classifiers:
                if ('name' in classifier.attrib
                        and classifier.attrib['name'] == 'System Type'):
                    val = classifier.find("{%s}Term/{%s}value" %
                                          (ns['sml'], ns['sml']))
                    if val is not None:
                        self.systemType = val.text

            member = tree.find("{%s}SensorDescription/{%s}member" %
                               (ns['sos'], ns['sml']))
            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.1"
            root.append(member)
            self.xmlSensorDescription = root
            """
            from xml.dom.minidom import parseString
            txt = et.tostring(root, encoding="UTF-8")
            self.xmlSensorDescription = parseString(txt).toprettyxml()
            """

            ObservationTemplate = tree.find("{%s}ObservationTemplate" %
                                            ns['sos'])
            if ObservationTemplate is None:
                raise sosException.SOSException(
                    "MissingParameterValue", "ObservationTemplate",
                    ("ObservationTemplate parameter is "
                     "mandatory with multiplicity 1"))

            Observation = ObservationTemplate.find("{%s}Observation" %
                                                   ns['om'])
            if Observation is None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:Observation tag is mandatory with multiplicity 1")

            procedure = Observation.find("{%s}procedure" % ns['om'])
            self.procedure = procedure.attrib["{%s}href" %
                                              ns['xlink']].split(":")[-1]
            if procedure is None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:procedure tag is mandatory with multiplicity 1")

            self.oprDef = []
            self.oprDesc = []
            self.oprName = []
            self.beginPosition = 'NULL'

            try:
                name = Observation.find(
                    "{%s}observedProperty/{%s}CompositePhenomenon/{%s}name" %
                    (ns['om'], ns['swe'], ns['gml']))
            except:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "swe:CompositePhenomenon mandatory name element is missing"
                )

            components = Observation.findall(
                "{%s}observedProperty/{%s}CompositePhenomenon/{%s}component" %
                (ns['om'], ns['swe'], ns['swe']))

            if not components == []:
                for comp in components:
                    try:
                        self.oprDef.append(comp.attrib["{%s}href" %
                                                       ns['xlink']])
                    except:
                        raise sosException.SOSException(
                            "NoApplicableCode", None,
                            ("om:observedProperty/component attribute "
                             "missing: 'xlink:href' required"))

            featureOfInterest = Observation.find("{%s}featureOfInterest" %
                                                 ns['om'])
            if featureOfInterest is None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:featureOfInterest tag is mandatory with multiplicity 1"
                )
            try:
                self.foiName = featureOfInterest.attrib["{%s}href" %
                                                        ns['xlink']]
            except:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:featureOfInterest: attribute 'xlink:href' is required")

            description = Observation.find(
                "{%s}featureOfInterest/{%s}FeatureCollection/{%s}description" %
                (ns['om'], ns['gml'], ns['gml']))

            if not description is None:
                self.foiDesc = description.text
            else:
                self.foiDesc = "NULL"

            self.foiType = None
            for geomtype in sosConfig.foiGeometryType:
                geomtype = geomtype.split(":")[1]
                GMLfeature = Observation.find(
                    "{%s}featureOfInterest/{%s}FeatureCollection/"
                    "{%s}location/{%s}%s" %
                    (ns['om'], ns['gml'], ns['gml'], ns['gml'], geomtype))

                if not GMLfeature is None:
                    self.foiType = geomtype
                    self.foiSRS = GMLfeature.attrib["srsName"].split(":")[-1]
                    self.foiGML = et.tostring(
                        GMLfeature, encoding="UTF-8").replace(
                            "<?xml version='1.0' encoding='UTF-8'?>", "")

            if self.foiType is None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "not found valid GML feature, supported: %s " %
                    (";".join(sosConfig.foiGeometryType)))

            result = Observation.find("{%s}result" % ns['om'])
            self.parameters = []
            self.uoms = []
            self.names = []
            self.descs = []
            self.constr = []
            self.partime = []

            if not result is None:
                sdr = Observation.find("{%s}result/{%s}SimpleDataRecord" %
                                       (ns['om'], ns['swe']))
                da = Observation.find("{%s}result/{%s}DataArray" %
                                      (ns['om'], ns['swe']))

                if sdr is not None and da is None:
                    fields = sdr.findall("{%s}field" % ns['swe'])
                elif da is not None and sdr is None:
                    fields = da.findall(
                        "{%s}elementType/{%s}DataRecord/{%s}field" %
                        (ns['swe'], ns['swe'], ns['swe']))
                else:
                    err_txt = (
                        "in <swe:result>: <swe:DataRecord> or "
                        "<swe:DataArray> are mandatory in multiplicity 1")
                    raise sosException.SOSException("NoApplicableCode", None,
                                                    err_txt)

                timetag = False
                for field in fields:
                    defin = None
                    uom = None
                    self.names.append(field.attrib['name'])
                    tf = field.find("{%s}Time" % ns['swe'])
                    qf = field.find("{%s}Quantity" % ns['swe'])

                    if not tf is None and qf is None:
                        self.partime.append(1)
                        timetag = True
                        self.parameters.append(tf.attrib["definition"])
                        uom = tf.find("{%s}uom" % ns['swe'])
                        self.uoms.append(uom.attrib["code"])
                        desc = tf.find("{%s}description" % ns['swe'])
                        if not desc is None:
                            self.descs.append(desc.text)
                        else:
                            self.descs.append("NULL")

                    elif not qf is None and tf is None:
                        self.partime.append(0)
                        self.parameters.append(qf.attrib["definition"])
                        uom = qf.find("{%s}uom" % ns['swe'])
                        self.uoms.append(uom.attrib["code"])
                        desc = qf.find("{%s}description" % ns['swe'])
                        if not desc is None:
                            self.descs.append(desc.text)
                        else:
                            self.descs.append("NULL")

                        cc = {}
                        constraints = qf.findall("{%s}constraint" %
                                                 (ns['swe']))
                        if len(constraints) == 0:
                            self.constr.append(None)
                        else:
                            for constraint in constraints:
                                if (constraint and "{%s}role" % ns["xlink"]
                                        in constraint.attrib):
                                    if constraint.attrib["{%s}role" % ns[
                                            "xlink"]] == "urn:ogc:def:classifiers:x-istsos:1.0:qualityIndex:check:reasonable":
                                        crole = constraint.attrib["{%s}role" %
                                                                  ns["xlink"]]

                                        allow = constraint.find(
                                            "{%s}AllowedValues" % (ns['swe']))
                                        if allow is None:
                                            err_txt = "in <swe:constraint>: <swe:AllowedValues> is mandatory in multiplicity 1"
                                            raise sosException.SOSException(
                                                "NoApplicableCode", None,
                                                err_txt)
                                        else:

                                            cvals = None
                                            if len(allow) == 1:
                                                ct = allow[0].tag
                                                if not ct in [
                                                        "{%s}min" % ns["swe"],
                                                        "{%s}max" % ns["swe"],
                                                        "{%s}interval" %
                                                        ns["swe"],
                                                        "{%s}valueList" %
                                                        ns["swe"]
                                                ]:
                                                    err_txt = "in <swe:constraint>: support only min, max, interval, valueList tag"
                                                    raise sosException.SOSException(
                                                        "NoApplicableCode",
                                                        None, err_txt)

                                                xvals = allow[0].text.strip(
                                                ).split(" ")

                                                if ct == "{%s}min" % ns["swe"]:
                                                    ct = "min"
                                                    if not len(xvals) == 1:
                                                        err_txt = "'%s' constraint support/need one values" % ct
                                                        raise sosException.SOSException(
                                                            "NoApplicableCode",
                                                            None, err_txt)
                                                    try:
                                                        cvals = float(xvals[0])
                                                    except:
                                                        err_txt = "'%s' constraint requires float value" % ct
                                                        raise sosException.SOSException(
                                                            "NoApplicableCode",
                                                            None, err_txt)

                                                elif ct == "{%s}max" % ns[
                                                        "swe"]:
                                                    ct = "max"
                                                    if not len(xvals) == 1:
                                                        err_txt = "'%s' constraint support/need one values" % ct
                                                        raise sosException.SOSException(
                                                            "NoApplicableCode",
                                                            None, err_txt)
                                                    try:
                                                        cvals = float(xvals[0])
                                                    except:
                                                        err_txt = "'%s' constraint requires float value" % ct
                                                        raise sosException.SOSException(
                                                            "NoApplicableCode",
                                                            None, err_txt)

                                                elif ct == "{%s}interval" % ns[
                                                        "swe"]:
                                                    ct = "interval"
                                                    if not len(xvals) == 2:
                                                        err_txt = "'%s' constraint support/need two values" % ct
                                                        raise sosException.SOSException(
                                                            "NoApplicableCode",
                                                            None, err_txt)
                                                    try:
                                                        cvals = [
                                                            float(xvals[0]),
                                                            float(xvals[1])
                                                        ]
                                                    except:
                                                        err_txt = "'%s' constraint requires float value" % ct
                                                        raise sosException.SOSException(
                                                            "NoApplicableCode",
                                                            None, err_txt)

                                                elif ct == "{%s}valueList" % ns[
                                                        "swe"]:
                                                    ct = "valueList"
                                                    if not len(xvals) > 0:
                                                        err_txt = "'%s' constraint support/need at least one values" % ct
                                                        raise sosException.SOSException(
                                                            "NoApplicableCode",
                                                            None, err_txt)
                                                    try:
                                                        cvals = [
                                                            float(a)
                                                            for a in xvals
                                                        ]
                                                    except:
                                                        err_txt = "'%s' constraint requires float value" % ct
                                                        raise sosException.SOSException(
                                                            "NoApplicableCode",
                                                            None, err_txt)

                                                cc["role"] = crole
                                                cc["%s" % ct] = cvals

                                if not cc == {}:
                                    self.constr.append(json.dumps(cc))
                                else:
                                    self.constr.append(None)

                    else:
                        err_txt = ("swe:Time or swe:Quantity is mandatory "
                                   "in multiplicity 1:N")
                        raise sosException.SOSException(
                            "NoApplicableCode", None, err_txt)

            else:
                err_txt = "om:result is mandatory in multiplicity 1:N"
                raise sosException.SOSException("NoApplicableCode", None,
                                                err_txt)
Пример #14
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):
        """Init sosFilter class"""
        self.request = sosRequest
        if self.request == '':
            raise sosException.SOSException("MissingParameterValue", "request",
                                            "Missing 'request' parameter")

        self.sosConfig = sosConfig
        if method == "GET":
            # OGC 12-006/REQ 5:
            # http://www.opengis.net/spec/SOS/2.0/req/core/gc-version
            if self.request == "getcapabilities":
                if "acceptversions" in requestObject:
                    AcceptVersions = requestObject["acceptversions"].split(",")
                    AcceptVersions.sort()
                    self.version = None

                    for version in AcceptVersions:
                        if version in sosConfig.parameters["version"]:
                            self.version = version
                            break

                    if not self.version:
                        raise sosException.SOSException(
                            "VersionNegotiationFailed", None,
                            "Any of the accepted versions are supported"
                            " by this server")

                else:
                    self.version = sosConfig.parameters["default_version"]

            else:
                # OGC 12-006/REQ 2:
                # http://www.opengis.net/spec/SOS/2.0/req/core/request-version
                if "version" in requestObject:
                    self.version = requestObject["version"]
                    if self.version == '':
                        raise sosException.SOSException(
                            "MissingParameterValue", "version",
                            "Missing 'version' parameter")

                    if self.version not in sosConfig.parameters["version"]:
                        raise sosException.SOSException(
                            "InvalidParameterValue", "version",
                            "\"version\": %s not supported" % (self.version))

                else:
                    raise sosException.SOSException(
                        "MissingParameterValue", "version",
                        "\"version\" parameter is mandatory")

            # OGC 12-006/REQ 1:
            # http://www.opengis.net/spec/SOS/2.0/req/core/request-service
            if "service" in requestObject:
                self.service = requestObject["service"]
                if self.service == '':
                    raise sosException.SOSException(
                        "MissingParameterValue", "service",
                        "Missing 'service' parameter")

                if self.service not in sosConfig.parameters["service"]:
                    raise sosException.SOSException(
                        "InvalidParameterValue", "service",
                        "\"service\": %s not supported" % (self.service))

            else:
                raise sosException.SOSException(
                    "MissingParameterValue", "service",
                    "\"service\" parameter is mandatory")

        if method == "POST":
            if not isinstance(requestObject, basestring):
                # OGC 12-006/REQ 1:
                # http://www.opengis.net/spec/SOS/2.0/req/core/request-service
                if "service" in requestObject.attributes.keys():
                    self.service = str(requestObject.getAttribute("service"))
                    if self.service not in sosConfig.parameters["service"]:
                        raise sosException.SOSException(
                            "InvalidParameterValue", "service",
                            "\"service\": %s not supported" % (self.service))

                else:
                    raise sosException.SOSException(
                        "MissingParameterValue", "service",
                        "\"service\" parameter is mandatory")

                # OGC 12-006/REQ 5:
                # http://www.opengis.net/spec/SOS/2.0/req/core/gc-version
                if self.request == "getcapabilities":
                    AcceptVersions = requestObject.getElementsByTagName(
                        'AcceptVersions')

                    if len(AcceptVersions) > 1:
                        raise sosException.SOSException(
                            "InvalidParameterValue", "AcceptVersions",
                            "AcceptVersions multiplicity is 1" %
                            (self.version))

                    elif len(AcceptVersions) == 1:
                        VersionsObj = requestObject.getElementsByTagName(
                            'Version')
                        versions = [
                            str(val.firstChild.data) for val in VersionsObj
                        ]
                        versions.sort()
                        self.version = None
                        for version in versions:
                            if version in sosConfig.parameters["version"]:
                                self.version = version
                                break

                        if not self.version:
                            raise sosException.SOSException(
                                "VersionNegotiationFailed", None,
                                "Any of the accepted versions are "
                                "supported by this server")
                    else:
                        self.version = sosConfig.parameters["version"][0]

                else:
                    # OGC 12-006/REQ 2:
                    # http://www.opengis.net/spec/SOS/2.0/req/
                    # core/request-version
                    if "version" in requestObject.attributes.keys():
                        self.version = str(
                            requestObject.getAttribute("version"))
                        if self.version not in sosConfig.parameters["version"]:
                            raise sosException.SOSException(
                                "InvalidParameterValue", "version",
                                "\"version\": %s not supported" %
                                (self.version))

                    else:
                        self.version = sosConfig.parameters["default_version"]
Пример #15
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):
        f.sosFilter.__init__(self, sosRequest, method, requestObject,
                             sosConfig)

        if method == "GET":
            self.outputFormat = None
            self.procedure = None

            if self.version == '2.0.0':
                # OUTPUTFORMAT
                if requestObject.has_key("procedure"):
                    if requestObject["procedure"] == '':
                        raise sosException.SOSException(
                            "MissingParameterValue", "procedure",
                            "Missing 'procedure' parameter")

                if requestObject.has_key("proceduredescriptionformat"):
                    if requestObject["proceduredescriptionformat"] == '':
                        raise sosException.SOSException(
                            "MissingParameterValue",
                            "proceduredescriptionformat",
                            "Missing 'proceduredescriptionformat' parameter")

                    if requestObject[
                            "proceduredescriptionformat"] in sosConfig.parameters[
                                "DS_outputFormats_2_0_0"]:
                        self.outputFormat = requestObject[
                            "proceduredescriptionformat"]

                    else:
                        raise sosException.SOSException(
                            "InvalidParameterValue",
                            "procedureDescriptionFormat",
                            "Supported \"procedureDescriptionFormat\" values are: "
                            + ",".join(sosConfig.
                                       parameters["DS_outputFormats_2_0_0"]))

                else:
                    raise sosException.SOSException(
                        "MissingParameterValue", "procedureDescriptionFormat",
                        "Parameter \"procedureDescriptionFormat\" is mandatory"
                    )

            else:
                # OUTPUTFORMAT
                if requestObject.has_key("outputformat"):
                    if requestObject["outputformat"] in sosConfig.parameters[
                            "DS_outputFormats"]:
                        self.outputFormat = requestObject["outputformat"]

                    else:
                        err_txt = "Supported \"outputFormat\" values are: " + ",".join(
                            sosConfig.parameters["DS_outputFormats"])
                        raise sosException.SOSException(
                            "InvalidParameterValue", "outputFormat", err_txt)

                else:
                    raise sosException.SOSException(
                        "MissingParameterValue", "outputFormat",
                        "Parameter \"outputFormat\" is mandatory")

            # PROCEDURES
            if requestObject.has_key("procedure"):
                if requestObject["procedure"] == '':
                    raise sosException.SOSException(
                        "MissingParameterValue", "procedure",
                        "Missing 'procedure' parameter")

                prc = requestObject["procedure"].split(":")
                self.procedure = prc[-1]
                if len(prc) > 1:
                    prc[-1] = ""

                    if ":".join(prc) == sosConfig.urn["procedure"]:
                        pass

                    else:
                        err_txt = "Supported \"procedure\" urn is: " + sosConfig.urn[
                            "procedure"]
                        err_txt += "\n passed: " + ":".join(prc)
                        raise sosException.SOSException(
                            "InvalidParameterValue", "procedure", err_txt)

            else:
                raise sosException.SOSException(
                    "MissingParameterValue", "procedure",
                    "Parameter \"procedure\" is mandatory with multiplicity 1")

        if method == "POST":
            self.outputFormat = None
            self.procedure = None

            # OUTPUTFORMAT
            if "outputFormat" in requestObject.attributes.keys():
                self.outputFormat = str(
                    requestObject.getAttribute("outputFormat"))
                if self.outputFormat not in sosConfig.parameters[
                        "DS_outputFormats"]:
                    err_txt = "Allowed \"outputFormat\" values are: " + ",".join(
                        sosConfig.parameters["DS_outputFormats"])
                    raise sosException.SOSException("InvalidParameterValue",
                                                    "outputFormat", err_txt)

            else:
                err_txt = "Parameter \"outputFormat\" is mandatory"
                raise sosException.SOSException(
                    "MissingParameterValue", "outputFormat",
                    "Parameter \"outputFormat\" is mandatory")

            # PROCEDURES
            procs = requestObject.getElementsByTagName('procedure')
            if len(procs) > 0:
                if len(procs) < 2:

                    val = procs[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        """
                        self.procedure = str(val.data)
                        """
                        prc = str(val.data).split(":")
                        if len(prc) > 1:
                            if prc[0:-1] == filter(
                                    None,
                                    sosConfig.urn["procedure"].split(":")):
                                pass
                            else:
                                err_txt = "Supported \"procedure\" urn is: " + sosConfig.urn[
                                    "procedure"]
                                raise sosException.SOSException(
                                    "InvalidParameterValue", "procedure",
                                    err_txt)
                        self.procedure = prc[-1]

                    else:
                        err_txt = "XML parsing error (get value: procedure)"
                        raise sosException.SOSException(
                            "MissingParameterValue", "procedure",
                            "Parameter \"procedure\" is mandatory with multiplicity 1",
                            err_txt)

                else:
                    err_txt = "Allowed only ONE parameter \"procedure\""
                    raise sosException.SOSException("IvalidParameterValue",
                                                    "procedure", err_txt)

            else:
                err_txt = "Parameter \"procedure\" is mandatory"
                raise sosException.SOSException(
                    "MissingParameterValue", "procedure",
                    "Parameter \"procedure\" is mandatory with multiplicity 1")
Пример #16
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):
        f.sosFilter.__init__(self, sosRequest, method, requestObject,
                             sosConfig)
        if method == "GET":
            raise sosException.SOSException(
                "NoApplicableCode", None, "insertObservation request support "
                "only POST method!")

        if method == "POST":
            from StringIO import StringIO
            tree, ns = parse_and_get_ns(StringIO(requestObject))

            # Workaround for rare xml parsing bug in etree
            ns = {
                'gml': 'http://www.opengis.net/gml',
                'swe': 'http://www.opengis.net/swe',
                'om': 'http://www.opengis.net/om/1.0',
                'sos': 'http://www.opengis.net/sos/1.0',
                'xlink': 'http://www.w3.org/1999/xlink',
                'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
            }

            if not 'swe' in ns:
                ns['swe'] = 'http://www.opengis.net/swe/1.0.1'

            # assignedSensorId
            AssignedSensorId = tree.find("{%s}AssignedSensorId" % ns['sos'])
            if AssignedSensorId is None:
                raise sosException.SOSException(
                    "MissingParameterValue", "AssignedSensorId",
                    "sos:AssignedSensorId parameter is mandatory "
                    "with multiplicity 1")

            else:
                self.assignedSensorId = AssignedSensorId.text.split(":")[-1]

            # forceInsert
            ForceInsert = tree.find("{%s}ForceInsert" % ns['sos'])
            if not ForceInsert is None:
                if ForceInsert.text == 'true' or ForceInsert.text == "":
                    self.forceInsert = True

                elif ForceInsert.text == 'false':
                    self.forceInsert = False

                else:
                    err_txt = ("parameter \"ForceInsert\" can only be: "
                               "'true' or 'false'")
                    raise sosException.SOSException("InvalidParameterValue",
                                                    "ForceInsert", err_txt)

            else:
                self.forceInsert = False

            # om:observation
            Observation = tree.find("{%s}Observation" % ns['om'])
            if Observation is None:
                raise sosException.SOSException(
                    "MissingParameterValue", "Observation",
                    "om:Observation tag is mandatory with multiplicity 1")

            # procedure
            procedure = Observation.find("{%s}procedure" % ns['om'])
            if procedure is None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:procedure tag is mandatory with multiplicity 1")

            self.procedure = procedure.attrib["{%s}href" %
                                              ns['xlink']].split(":")[-1]

            # ObservedProperties
            self.oprName = []
            observedProperty = Observation.find("{%s}observedProperty" %
                                                ns['om'])
            if observedProperty is None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:observedProperty tag is mandatory with multiplicity 1")

            CompositPhenomenon = observedProperty.find(
                "{%s}CompositePhenomenon" % ns['swe'])

            if not CompositPhenomenon is None:
                components = CompositPhenomenon.findall("{%s}component" %
                                                        ns['swe'])
                for co in components:
                    try:
                        self.oprName.append(co.attrib["{%s}href" %
                                                      ns['xlink']])

                    except:
                        try:
                            name = co.find("{%s}name" % ns['gml'])
                            self.oprName.append(name.text)

                        except:
                            raise sosException.SOSException(
                                "NoApplicableCode", None,
                                "om:observedProperty Name is missing: "
                                "'xlink:href' or 'gml:name' required")

            else:
                try:
                    self.oprName.append(observedProperty.attrib["{%s}href" %
                                                                ns['xlink']])

                except:
                    try:
                        name = co.find("{%s}name" % ns['gml'])
                        self.oprName.append(name.text)

                    except:
                        print >> sys.stderr, "XML: %s" % requestObject
                        raise sosException.SOSException(
                            "NoApplicableCode", None,
                            "om:observedProperty Name is missing: "
                            "'xlink:href' or 'gml:name' required")

            # samplingTime
            samplingTime = Observation.find("{%s}samplingTime" % ns['om'])
            if samplingTime is None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:samplingTime is mandatory in multiplicity 1")

            TimePeriod = samplingTime.find("{%s}TimePeriod" % ns['gml'])
            if not TimePeriod is None:
                bp = TimePeriod.find("{%s}beginPosition" % ns['gml'])
                ep = TimePeriod.find("{%s}endPosition" % ns['gml'])
                if bp is None or ep is None:
                    raise sosException.SOSException(
                        "NoApplicableCode", None,
                        "gml:TimePeriod is mandatory in multiplicity 1")
                self.samplingTime = bp.text + "/" + ep.text

            else:
                TimeInstant = samplingTime.find("{%s}TimeInstant" % ns['gml'])
                if not TimeInstant is None:
                    tpos = TimeInstant.find("{%s}timePosition" % ns['gml'])
                    self.samplingTime = tpos.text

                else:
                    raise sosException.SOSException(
                        "NoApplicableCode", None,
                        "one of gml:TimePeriod or gml:TimeInstant "
                        "is mandatory in multiplicity 1")

            # featureOfInterest
            featureOfInterest = Observation.find("{%s}featureOfInterest" %
                                                 ns['om'])
            if featureOfInterest is None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:featureOfInterest tag is mandatory with "
                    "multiplicity 1")
            try:
                self.foiName = featureOfInterest.attrib[
                    "{%s}href" % ns['xlink']].split(":")[-1]

            except:
                try:
                    gml_name = featureOfInterest.find("{%s}name" %
                                                      ns['gml']).split(":")[-1]
                    self.foiName = gml_name.text

                except:
                    raise sosException.SOSException(
                        "NoApplicableCode", None,
                        "om:featureOfInterest name is missing: 'xlink:href' "
                        "or 'gml:name' is required")

            # result
            if Observation.find("{%s}result" % ns['om']) is None:
                raise sosException.SOSException("NoApplicableCode", None,
                                                "om:result tag is required")

            SimpleDataRecord = Observation.find(
                "{%s}result/{%s}SimpleDataRecord" % (ns['om'], ns['swe']))
            DataArray = Observation.find("{%s}result/{%s}DataArray" %
                                         (ns['om'], ns['swe']))

            ###################################################################
            # RESULT
            # return self.data where self.data is a dictionary of "definition"
            # containing dictionary of "uom" and "vals"
            #""" e.g.:
            #self.data = {
            #            "urn:ist:parameter:time:iso8601":
            #                {
            #                "uom":"sec",
            #                "vals":[
            #                   "2009-07-31T12:00:00+02:00",
            #                   "2009-07-31T12:10:00+02:00",
            #                   "2009-07-31T12:20:00+02:00"]
            #                },
            #            "urn:ist:def:phenomenon:rainfall":
            #                {
            #                "uom":"mm",
            #                "vals":[0.1,0.2,0.3,0.4]
            #                }
            #            }
            #
            ###################################################################

            self.parameters = []
            self.uoms = []
            self.data = {}

            #case SimpleDataRecord
            if not SimpleDataRecord is None and DataArray is None:
                fields = SimpleDataRecord.findall("{%s}field" % ns['swe'])
                for field in fields:
                    defin = None
                    uom = None
                    vals = []
                    fieldName = field.attrib["name"]
                    if not field.find("{%s}Time" % ns['swe']) is None:
                        tf = field.find("{%s}Time" % ns['swe'])
                        defin = tf.attrib["definition"]
                        vals.append(tf.find("{%s}value" % ns['swe']).text)

                    elif not field.find("{%s}Quantity" % ns['swe']) is None:
                        qf = field.find("{%s}Quantity" % ns['swe'])
                        defin = qf.attrib["definition"]
                        uom = qf.find("{%s}uom" % ns['swe']).attrib["code"]
                        vals.append(qf.find("{%s}value" % ns['swe']).text)

                    else:
                        raise sosException.SOSException(
                            "NoApplicableCode", None,
                            "swe:Time or swe:Quantity is mandatory in "
                            "multiplicity 1")

                    self.data[defin] = {"uom": uom, "vals": vals}

            # Case DataArray
            elif SimpleDataRecord is None and not DataArray is None:
                DataRecord = DataArray.find("{%s}elementType/{%s}DataRecord" %
                                            (ns['swe'], ns['swe']))
                fields = DataRecord.findall("{%s}field" % ns['swe'])
                urnlist = []
                for id, field in enumerate(fields):
                    defin = None
                    uom = None
                    vals = []
                    #fieldName = field.attrib["name"]
                    if not field.find("{%s}Time" % ns['swe']) is None:
                        swet = field.find("{%s}Time" % ns['swe'])
                        defin = swet.attrib["definition"]
                        urnlist.append(swet.attrib["definition"])

                    elif not field.find("{%s}Quantity" % ns['swe']) is None:
                        sweq = field.find("{%s}Quantity" % ns['swe'])
                        defin = sweq.attrib["definition"]
                        urnlist.append(sweq.attrib["definition"])
                        if not sweq.find("{%s}uom" % ns['swe']) is None:
                            uom = sweq.find("{%s}uom" %
                                            ns['swe']).attrib["code"]

                    else:
                        raise sosException.SOSException(
                            "NoApplicableCode", None,
                            "swe:Time or swe:Quantity is mandatory in "
                            "multiplicity 1")

                    self.data[defin] = {"uom": uom, "vals": vals}

                # encoding
                encodingTxtBlock = Observation.find(
                    "{%s}result/{%s}DataArray/{%s}encoding/{%s}TextBlock" %
                    (ns['om'], ns['swe'], ns['swe'], ns['swe']))
                if encodingTxtBlock is None:
                    raise sosException.SOSException(
                        "NoApplicableCode", None,
                        "swe:encoding is mandatory in multiplicity 1")

                tokenSeparator = encodingTxtBlock.attrib["tokenSeparator"]
                blockSeparator = encodingTxtBlock.attrib["blockSeparator"]

                values = Observation.find(
                    "{%s}result/{%s}DataArray/{%s}values" %
                    (ns['om'], ns['swe'], ns['swe']))

                if values is None:
                    raise sosException.SOSException(
                        "NoApplicableCode", None,
                        "swe:values is mandatory in multiplicity 1")

                self.dataArray = []
                if values.text:
                    valsplit = [
                        i.split(tokenSeparator)
                        for i in values.text.split(blockSeparator)
                    ]
                    self.dataArray = valsplit
                    for index, c in enumerate(urnlist):
                        col = []
                        for l in valsplit:
                            col.append(l[index])
                        self.data[c]["vals"] = col

            # case simple om:result
            elif SimpleDataRecord is None and DataArray is None:
                self.data[sosConfig.urn["time"]] = {
                    "uom": None,
                    "vals": [self.samplingTime]
                }
                result = Observation.find("{%s}result" % (ns['om']))
                uom = result.attrib["uom"]
                vals = result.text
                self.data[sosConfig.urn["phenomena"] + self.oprName] = {
                    "uom": uom,
                    "vals": vals
                }
                self.dataArray = [[self.samplingTime, vals]]

            # error
            else:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:SimpleDataRecord in multiplicity N or om:DataArray "
                    "in multiplicity 1 is mandatory")
Пример #17
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):
        f.sosFilter.__init__(
            self, sosRequest,
            method, requestObject, sosConfig
        )
        if method == "GET":

            self.eventTime = None
            self.featureOfInterest = None
            self.featureOfInterestSpatial = None
            self.result = None  # zero-one optional
            self.observedProperty = [':']

            # OBSERVED PROPERTY
            #   get_name_from_urn limit the ability to ask for an observedProperty with LIKE:
            #   eg: ask "water" to get all the water related data, "water:discharge", "water:temperature" ...
            if "observedproperty" in requestObject:
                self.observedProperty = []
                oprs = requestObject["observedproperty"].split(",")

                for opr in oprs:
                    if opr == '':
                        raise sosException.SOSException(
                            "MissingParameterValue", "observedProperty",
                            "Missing 'observedProperty' parameter"
                        )

                    oprName = opr
                    self.observedProperty.append(oprName)  # one-many ID

            # PROCEDURES FILTER
            if "procedure" in requestObject:
                self.procedure = []
                prcs = requestObject["procedure"].split(",")

                for prc in prcs:
                    if prc == '':
                        raise sosException.SOSException(
                            "MissingParameterValue", "procedure",
                            "Missing 'procedure' parameter"
                        )

                    try:
                        prcName = get_name_from_urn(
                            prc, "procedure", sosConfig
                        )

                    except Exception as e:
                        raise sosException.SOSException(
                            "InvalidParameterValue",
                            "procedure", str(e)
                        )

                    self.procedure.append(prcName)

            else:
                self.procedure = None

            if self.version == '2.0.0':

                # THE OFFERING
                #  > in istSOS offerings are equals to procedures
                #  > so offerings are inserted into the procedure array filter

                if "offering" in requestObject:
                    prcs = requestObject["offering"].split(",")
                    if self.procedure is None:
                        self.procedure = []

                    for prc in prcs:
                        if prc == '':
                            raise sosException.SOSException(
                                "MissingParameterValue", "offering",
                                "Missing 'offering' parameter"
                            )
                        try:
                            prcName = get_name_from_urn(
                                prc, "offering",
                                sosConfig
                            )

                        except Exception as e:
                            raise sosException.SOSException(
                                "InvalidParameterValue",
                                "offering", str(e)
                            )

                        # Check for name redundancy
                        if prcName not in self.procedure:
                            self.procedure.append(prcName)

                # RESPONSE FORMAT
                self.responseFormat = 'text/xml;subtype="om/2.0"'
                if "responseformat" in requestObject:
                    if requestObject["responseformat"] == '':
                        raise sosException.SOSException(
                            "MissingParameterValue", "responseformat",
                            "Missing 'responseformat' parameter"
                        )
                    if not requestObject["responseformat"] in sosConfig.parameters["GO_responseFormat_2_0_0"]:
                        raise sosException.SOSException(
                            "InvalidParameterValue", "responseFormat",
                            "Parameter \"responseFormat\" sent with invalid value : use one of %s" % "; ".join(sosConfig.parameters["GO_responseFormat_2_0_0"])
                        )
                    elif requestObject["responseformat"] == sosConfig.parameters["GO_responseFormat_2_0_0"][0]:
                        self.responseFormat = 'text/xml;subtype="om/2.0"'
                    else:
                        self.responseFormat = requestObject["responseformat"]

                # OPTIONAL SRS FILTER
                if "crs" in requestObject:
                    try:
                        self.srsName = requestObject["crs"].split(':')[-1]

                    except Exception as e:
                        raise sosException.SOSException("InvalidParameterValue", "crs", "%s" % e)

                    if self.srsName not in sosConfig.parameters["GO_srs"]:
                        raise sosException.SOSException(
                            "InvalidParameterValue", "crs",
                            "crs \"%s\" not supported, use one of: %s" %(self.srsName, ",".join(sosConfig.parameters["GO_srs"]))
                        )

                else:
                    self.srsName = sosConfig.parameters["GO_srs"][0]

                # TIME FILTER
                # istSOS supports
                #     kvp examples:
                #     - during:       temporalFilter=om:phenomenonTime,2012-11-19T14:00:00+01:00/2012-11-19T14:15:00+01:00
                #     - equals:       temporalFilter=om:phenomenonTime,2012-11-19T14:00:00.000+01:00
                #     - combination:  temporalFilter=om:phenomenonTime,2012-11-19T14:00:00+01:00/2012-11-19T14:15:00+01:00,2012-11-19T14:00:00.000+01:00
                if 'temporalfilter' in requestObject:
                    self.eventTime = []
                    temporalfilter = requestObject["temporalfilter"].replace(
                        " ", "+").split(",")

                    #  > in istSOS om:phenomenonTime is equals to om:resultTime
                    if temporalfilter.pop(0) not in ['om:phenomenonTime','phenomenonTime','om:resultTime','resultTime']:
                        raise sosException.SOSException("InvalidParameterValue", "temporalfilter",
                            "Parameter \"temporalFilter\" bad formatted")

                    for i in temporalfilter:
                        if '/' in i:
                            interval = i.split("/")
                            if len(interval) != 2:
                                raise sosException.SOSException(
                                    "InvalidParameterValue", "temporalfilter",
                                    "Parameter \"temporalfilter\" bad formatted"
                                )
                            try:
                                iso.parse_date(interval[0])
                                iso.parse_date(interval[1])

                            except iso.ISO8601Error as isoerr:
                                raise sosException.SOSException(
                                    "InvalidParameterValue", "temporalfilter",
                                    "Parameter \"temporalfilter\" bad formatted, %s" % isoerr
                                )

                            self.eventTime.append(interval)

                        else:
                            try:
                                iso.parse_date(i)

                            except iso.ISO8601Error as isoerr:
                                raise sosException.SOSException(
                                    "InvalidParameterValue", "temporalfilter",
                                    "Parameter \"temporalfilter\" bad formatted, %s" % isoerr
                                )

                            self.eventTime.append([i])

                # FEATURES OF INTEREST FILTER
                if "featureofinterest" in requestObject:
                    if requestObject["featureofinterest"] == '':
                        raise sosException.SOSException("MissingParameterValue", "featureOfInterest", "Missing 'featureOfInterest' parameter")
                    if sosConfig.urn["feature"] in requestObject["featureofinterest"]:
                        self.featureOfInterest = get_name_from_urn(requestObject["featureofinterest"], "feature", sosConfig)
                    else:
                        self.featureOfInterest = requestObject["featureofinterest"]

                # SPATIAL FILTER
                # example1: spatialFilter=om:featureOfInterest/*/sams:shape,0.0,0.0,60.0,60.0,http://www.opengis.net/def/crs/EPSG/0/4326
                # example2: spatialFilter=om:featureOfInterest/*/sams:shape,0.0,0.0,60.0,60.0,urn:ogc:def:crs:EPSG::4326
                if "spatialfilter" in requestObject:

                    sfs = requestObject["spatialfilter"].split(",")

                    if len(sfs) != 6:
                        raise sosException.SOSException(
                            "InvalidParameterValue", "spatialfilter",
                            "Invalid spatial filter '%s'" % requestObject["spatialfilter"]
                        )

                    if sfs[0] != 'om:featureOfInterest/*/sams:shape':
                        raise sosException.SOSException("InvalidParameterValue", "spatialfilter",
                            "Invalid spatial filter '%s'" % requestObject["spatialfilter"])

                    srsName = None

                    if sfs[5].index(':')>-1:
                        srsName = sfs[5].split(':')[-1]

                    if sfs[5].index('/')>-1:
                        srsName = sfs[5].split('/')[-1]

                    ogcfilter = (
                        "<ogc:BBOX>" +
                          "<ogc:PropertyName>the_geom</ogc:PropertyName>"+
                          ("<gml:Box srsName='EPSG:%s'>" % (srsName) )+
                             ("<gml:coordinates>%s,%s %s,%s</gml:coordinates>" % (sfs[1], sfs[2], sfs[3], sfs[4])) +
                          "</gml:Box>"+
                        "</ogc:BBOX>")

                    self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(
                        ogcfilter, 'geom_foi', sosConfig.istsosepsg
                    )


            else:

                # THE OFFERING
                if "offering" in requestObject:
                    try:
                        self.offering = get_name_from_urn(requestObject["offering"], "offering", sosConfig)

                    except Exception as e:
                        raise sosException.SOSException("InvalidParameterValue","offering",str(e))

                # RESPONSE FORMAT
                if "responseformat" in requestObject:
                    if requestObject["responseformat"] == '':
                        raise sosException.SOSException("MissingParameterValue", "responseFormat", "Missing 'responseFormat' parameter")

                    if not requestObject["responseformat"] in sosConfig.parameters["GO_responseFormat"]:
                        raise sosException.SOSException("InvalidParameterValue", "responseFormat",
                            "Parameter \"responseFormat\" sent with invalid value : use one of %s" % "; ".join(sosConfig.parameters["GO_responseFormat"]))

                    else:
                        self.responseFormat = requestObject["responseformat"]

                if "offering" not in requestObject:
                    raise sosException.SOSException("MissingParameterValue", "offering",
                        "Parameter \"offering\" is mandatory with multiplicity 1")

                if "observedproperty" not in requestObject:
                    raise sosException.SOSException("MissingParameterValue", "observedProperty",
                        "Parameter \"observedProperty\" is mandatory with multiplicity N")

                if "responseformat" not in requestObject:
                    raise sosException.SOSException("MissingParameterValue", "responseFormat",
                        "Parameter \"responseFormat\" is mandatory with multiplicity 1") #one

                # OPTIONAL SRS FILTER
                if "srsname" in requestObject:
                    try:
                        self.srsName = get_name_from_urn(requestObject["srsname"], "refsystem", sosConfig)
                    except Exception as e:
                        raise sosException.SOSException("InvalidParameterValue", "srsname", "%s" % e)

                    if not self.srsName in sosConfig.parameters["GO_srs"]:
                        raise sosException.SOSException("InvalidParameterValue", "srsName",
                            "srsName \"%s\" not supported, use one of: %s" %(self.srsName, ",".join(sosConfig.parameters["GO_srs"])))
                else:
                    self.srsName = sosConfig.parameters["GO_srs"][0]

                # TIME FILTER
                if 'eventtime' in requestObject:
                    self.eventTime = []
                    for i in requestObject["eventtime"].replace(" ","+").split(","):
                        if len(i.split("/")) < 3:
                            self.eventTime.append(i.split("/"))

                        else:
                            raise sosException.SOSException("InvalidParameterValue", "eventTime",
                                "Parameter \"eventTime\" bad formatted")

                # FEATURES OF INTEREST FILTER
                if "featureofinterest" in requestObject:
                    foi = requestObject["featureofinterest"]
                    if foi.find("<ogc:") >= 0 and foi.find("<gml:")>=0:
                        self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(foi, 'geom_foi', sosConfig.istsosepsg)

                    else:
                        try:
                            self.featureOfInterest = get_name_from_urn(foi, "feature", sosConfig)

                        except Exception as e:
                            raise sosException.SOSException("InvalidParameterValue", "featureofinterest", str(e))

                # FILTERS FOR QUERY NOT SUPPORTED YET
                if "result" in requestObject:
                    self.result = sosUtils.ogcCompCons2PostgisSql(requestObject["result"])

                # RESULT MODEL
                if "resultmodel" in requestObject:
                    if requestObject["resultmodel"] in sosConfig.parameters["GO_resultModel"]:
                        self.resultModel = requestObject["resultmodel"]

                    else:
                        raise sosException.SOSException("InvalidParameterValue", "resultModel",
                            "Parameter \"resultModel\" sent with invalid value: supported values are: %s" %",".join(sosConfig.parameters["GO_resultModel"]))

                else:
                    self.resultModel = sosConfig.parameters["GO_resultModel"][0]

                # RESPONSE MODE
                if "responsemode" in requestObject:
                    if requestObject["responsemode"] in sosConfig.parameters["GO_responseMode"]:
                        self.responseMode = requestObject["responsemode"]

                    else:
                        raise sosException.SOSException("InvalidParameterValue", "responseMode",
                            "Parameter \"responseMode\" sent with invalid value, supported values are: %s" %(",".join(sosConfig.parameters["GO_responseMode"])))

                else:
                    self.responseMode = sosConfig.parameters["GO_responseMode"][0]

            # Checking if some event limitation is reached
            if self.eventTime != None:
                tp=[]
                for t in self.eventTime:
                    if len(t) == 2:
                        tp.append(iso.parse_datetime(t[0]))
                        tp.append(iso.parse_datetime(t[1]))

                    if len(t)==1:
                        tp.append(iso.parse_datetime(t[0]))

                if int(sosConfig.maxGoPeriod) > 0:
                    maxhours = timedelta(hours=int(sosConfig.maxGoPeriod))
                    userPeriod = max(tp)-min(tp)

                    if maxhours < userPeriod:
                        if self.version == '2.0.0':
                            # REQ39 - http://www.opengis.net/spec/SOS/2.0/req/core/go-too-many-obs-exception
                            #     The service determined that the requested result set exceeds the response
                            #     size limit of the service and thus cannot be delivered.
                            raise sosException.SOSException("ResponseExceedsSizeLimit", "",
                                "You are requesting data for a period of [%s hours], but you are not permitted to ask for a period longer than: %s hours" % (userPeriod, maxhours))

                        else:
                            raise sosException.SOSException("InvalidParameterValue", "eventTime",
                                "You are requesting data for a period of [%s hours], but you are not permitted to ask for a period longer than: %s hours" % (userPeriod, maxhours))

            elif (
                    sosConfig.strictogc in ['True','true',1]
                    and self.version == '2.0.0'
                    and self.eventTime == None
                    and self.featureOfInterest == None
                    and self.featureOfInterestSpatial == None
                    and self.procedure == None
                ):
                # ResponseExceedsSizeLimit fake exception
                raise sosException.SOSException("ResponseExceedsSizeLimit", "",
                    "Sorry but, You are requesting too many data")


            #####################################
            # NON STANDARD PARAMETERS by istSOS #
            #####################################

            # AGGREGATE INTERVAL
            #  In ISO 8601 duration format
            if "aggregateinterval" in requestObject:
                # Check on the eventTime parameter: it must be only one interval: 2010-01-01T00:00:00+00/2011-01-01T00:00:01+00
                exeMsg = "Using aggregate functions, the event time must exist with an interval composed by a begin and an end date (ISO8601)"
                if self.eventTime == None or len(self.eventTime)!=1 or len(self.eventTime[0])!=2:
                    raise sosException.SOSException("InvalidParameterValue", "aggregateInterval", exeMsg)

                self.aggregate_interval = requestObject["aggregateinterval"]
                try:
                    iso.parse_duration(self.aggregate_interval)

                except Exception as ex:
                    raise sosException.SOSException("InvalidParameterValue", "aggregateInterval",
                        "Parameter \"aggregate_interval\" sent with invalid format (check ISO8601 duration spec): %s" % ex)
            else:
                self.aggregate_interval = None

            # AGGREGATE FUNCTION
            #  sum,avg,max,min
            if "aggregatefunction" in requestObject:
                if self.aggregate_interval==None:
                    raise sosException.SOSException("InvalidParameterValue", "aggregateFunction",
                        "Using aggregate functions parameters \"aggregateInterval\" and \"aggregateFunction\" are both mandatory")

                self.aggregate_function = requestObject["aggregatefunction"]
                if not (self.aggregate_function.upper() in ["AVG", "COUNT", "MAX", "MIN", "SUM"]):
                    raise sosException.SOSException("InvalidParameterValue", "aggregateFunction",
                        "Available aggregation functions: avg, count, max, min, sum.")

            else:
                self.aggregate_function = None

            # AGGREGATE NODATA
            if "aggregatenodata" in requestObject:
                if self.aggregate_interval==None or self.aggregate_function==None:
                    raise sosException.SOSException("InvalidParameterValue", "aggregateNodata",
                        "Using aggregateNodata parameter requires both \"aggregateInterval\" and \"aggregateFunction\"")

                self.aggregate_nodata = requestObject["aggregatenodata"]

            else:
                self.aggregate_nodata = sosConfig.aggregate_nodata

            # AGGREGATE NODATA QUALITY INDEX
            if "aggregatenodataqi" in requestObject:
                if self.aggregate_interval==None or self.aggregate_function==None:
                    raise sosException.SOSException("InvalidParameterValue", "aggregateNodataQi",
                        "Using aggregateNodataQi parameter requires both \"aggregateInterval\" and \"aggregateFunction\"")
                self.aggregate_nodata_qi = requestObject["aggregatenodataqi"]

            else:
                self.aggregate_nodata_qi = sosConfig.aggregate_nodata_qi

            # QUALITY INDEX
            self.qualityIndex=False
            if "qualityindex" in requestObject:
                if requestObject["qualityindex"].upper() == "TRUE":
                    self.qualityIndex = True

                elif requestObject["qualityindex"].upper() == "FALSE":
                    self.qualityIndex = False

                else:
                    raise sosException.SOSException("InvalidParameterValue", "qualityIndex",
                        "qualityIndex can only be True or False!")

            # QUALITY INDEX FILTERING
            self.qualityFilter=False
            if "qualityfilter" in requestObject:
                if len(requestObject["qualityfilter"])>=2:
                    try:
                        if requestObject["qualityfilter"][0:2]=='<=' or requestObject["qualityfilter"][0:2]=='>=':
                            self.qualityFilter = (requestObject["qualityfilter"][0:2], float(requestObject["qualityfilter"][2:]))

                        elif (requestObject["qualityfilter"][0]=='>' or
                                requestObject["qualityfilter"][0]=='=' or
                                requestObject["qualityfilter"][0]=='<'):
                            self.qualityFilter = (requestObject["qualityfilter"][0], float(requestObject["qualityfilter"][1:]))

                        # If qualityFilter is defined qualityIndex are automatically returned
                        self.qualityIndex=True

                    except ValueError as ve:
                        raise sosException.SOSException("InvalidParameterValue", "qualityFilter",
                            "invalid quality index value in qualityFilter")

                else:
                    raise sosException.SOSException("InvalidParameterValue", "qualityFilter",
                        "qualityFilter operator can only be in ['<','>','<=','>=','=']")

        if method == "POST":
            from xml.dom import minidom
            # THE OFFERING
            offs = requestObject.getElementsByTagName('offering')
            if len(offs) == 1:
                val = offs[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    try:
                        self.offering = get_name_from_urn(str(val.data), "offering", sosConfig)

                    except Exception as e:
                        raise sosException.SOSException("InvalidParameterValue", "offering", str(e))

                else:
                    err_txt = "XML parsing error (get value: offering)"
                    raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                err_txt = "Parameter \"offering\" is mandatory with multiplicity 1"
                raise sosException.SOSException("MissingParameterValue", "offering", err_txt)

            # THE OBSERVED PROPERTY
            obsProps = requestObject.getElementsByTagName('observedProperty')
            self.observedProperty = []
            if len(obsProps) > 0:
                for obsProp in obsProps:
                    val = obsProp.firstChild
                    if val.nodeType == val.TEXT_NODE:
                        # get_name_from_urn limit the ability to ask for an observedProperty with LIKE:
                        # eg: ask "water" to get all the water related data, "water:discharge", "water:temperature" ...
                        #self.observedProperty.append(get_name_from_urn(str(val.data),"property"))
                        self.observedProperty.append(str(val.data))

                    else:
                        err_txt = "XML parsing error (get value: observedProperty)"
                        raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                err_txt = "Parameter \"observedProperty\" is mandatory with multiplicity N"
                raise sosException.SOSException("MissingParameterValue", "observedProperty", err_txt)

            # RESPONSE FORMAT
            respF = requestObject.getElementsByTagName('responseFormat')
            if len(respF) == 1:
                val = respF[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.responseFormat = str(val.data)
                    if self.responseFormat not in sosConfig.parameters["GO_responseFormat"]:
                        raise sosException.SOSException("InvalidParameterValue", "responseFormat",
                            "Parameter \"responseFormat\" sent with invalid value: use one of %s" % "; ".join(sosConfig.parameters["GO_responseFormat"]))

                else:
                    err_txt = "XML parsing error (get value: responseFormat)"
                    raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                err_txt = "Parameter \"responseFormat\" is mandatory with multiplicity 1"
                raise sosException.SOSException("MissingParameterValue", "responseFormat", err_txt)

            # OPTIONAL request parameters
            #  SRS OF RETURNED GML FEATURES
            srs = requestObject.getAttributeNode('srsName')
            if srs:
                self.srsName = srs.nodeValue
                if not self.srsName in sosConfig.parameters["GO_srs"]:
                    raise sosException.SOSException("InvalidParameterValue", "srsName",
                        "srsName \"%s\" not supported, use one of: %s" %(self.srsName, ",".join(sosConfig.parameters["GO_srs"])))

            else:
                self.srsName = sosConfig.parameters["GO_srs"][0]

            # TIME FILTER
            evtms = requestObject.getElementsByTagName('eventTime')
            self.eventTime = []
            if len(evtms) > 0:
                for evtm in evtms:
                    tps = evtm.getElementsByTagName('gml:TimePeriod')
                    for tp in tps:
                        begin = tp.getElementsByTagName('gml:beginPosition')
                        end = tp.getElementsByTagName('gml:endPosition')
                        if len(begin)==1 and len(end)==1:
                            Bval = begin[0].firstChild
                            Eval = end[0].firstChild
                            if Bval.nodeType == Bval.TEXT_NODE and Eval.nodeType == Eval.TEXT_NODE:
                                self.eventTime.append([str(Bval.data).replace(" ","+"), str(Eval.data).replace(" ","+")])

                            else:
                                err_txt = "XML parsing error (get value: TimePeriod)"
                                raise sosException.SOSException("NoApplicableCode",None,err_txt)

                    tis = evtm.getElementsByTagName('gml:TimeInstant')
                    for ti in tis:
                        instant = ti.getElementsByTagName('gml:timePosition')
                        if len(instant)>0 and len(instant)<2:
                            Ival = instant[0].firstChild
                            if Ival.nodeType == Ival.TEXT_NODE:
                                self.eventTime.append([str(Ival.data).replace(" ","+")])
                            else:
                                err_txt = "XML parsing error (get value: Timeinstant)"
                                raise sosException.SOSException("NoApplicableCode", None, err_txt)
            else:
                self.eventTime = None

            # PROCEDURES FILTER
            procs = requestObject.getElementsByTagName('procedure')
            if len(procs) > 0:
                self.procedure=[]
                for proc in procs:
                    if "xlink:href" in list(proc.attributes.keys()):
                        self.procedure.append(str(proc.getAttribute("xlink:href")))

                    elif proc.hasChildNodes():
                        val = proc.firstChild
                        if val.nodeType == val.TEXT_NODE:
                            try:
                                self.procedure.append(get_name_from_urn(str(val.data), "procedure", sosConfig))

                            except Exception as e:
                                raise sosException.SOSException("InvalidParameterValue", "procedure", str(e))
                    else:
                        err_txt = "XML parsing error (get value: procedure)"
                        raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                self.procedure = None

            # FEATURES OF INTEREST FILTER
            fets = requestObject.getElementsByTagName('featureOfInterest')
            self.featureOfInterest = None
            self.featureOfInterestSpatial = None

            # get sub-elements of FOI
            if fets:
                elements = [e for e in fets[0].childNodes if e.nodeType == e.ELEMENT_NODE]
                if len(elements)==0:
                    err_txt = "ObjectID or ogc:spatialOps elements in parameter \"featureOfInterest\" are mandatory"
                    raise sosException.SOSException("NoApplicableCode",None,err_txt)

                # only one sub element
                elif len(elements)==1 and elements[0].tagName!="ObjectID" :
                    self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(elements[0], 'geom_foi', sosConfig.istsosepsg)

                else:
                    tempfois=[]
                    for e in elements:
                        if not e.tagName=="ObjectID":
                            err_txt = "Allowed only ObjectID or ogc:spatialOps elements in parameter \"featureOfInterest\""
                            raise sosException.SOSException("NoApplicableCode", None, err_txt)

                        try:
                            val = e.firstChild
                            if val.nodeType == val.TEXT_NODE:
                                try:
                                    tempfois.append( get_name_from_urn(str(val.data), "feature", sosConfig))

                                except Exception as e:
                                     raise sosException.SOSException("InvalidParameterValue", "featureOfInterest", str(e))

                        except Exception as e:
                            raise e

                    self.featureOfInterest = ",".join(tempfois)

            # FILTERS FOR QUERY NOT SUPPORTED YET
            ress = requestObject.getElementsByTagName('result')
            if len(ress)>0:
                raise sosException.SOSException("NoApplicableCode", None, "Parameter \"result\" not yet supported")
            else:
                self.result = None #zero-one optional

            # RESULT MODEL
            mods = requestObject.getElementsByTagName('resultModel')
            if len(mods)>0:
                if len(mods)<2:
                    val = mods[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.resultModel = str(val.data)
                        if self.resultModel not in sosConfig.parameters["GO_resultModel"]:
                            raise sosException.SOSException("InvalidParameterValue", "resultModel",
                                "Parameter \"resultModel\" sent with invalid value")

                    else:
                        err_txt = "XML parsing error (get value: resultModel)"
                        raise sosException.SOSException("NoApplicableCode", None, err_txt)

                else:
                    err_txt = "Allowed only ONE parameter \"resultModel\""
                    raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                self.resultModel = None

            # RESPONSE MODE
            rsmods = requestObject.getElementsByTagName('responseMode')
            if len(rsmods)>0:
                if len(rsmods)<2:
                    val = rsmods[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.responseMode = str(val.data)
                        if self.responseMode not in sosConfig.parameters["GO_responseMode"]:
                            raise sosException.SOSException("InvalidParameterValue", "responseMode",
                                "Parameter \"responseMode\" sent with invalid value")

                    else:
                        err_txt = "XML parsing error (get value: responseMode)"
                        raise sosException.SOSException("NoApplicableCode", None, err_txt)

                else:
                    err_txt = "Allowed only ONE parameter \"responseMode\""
                    raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                self.responseMode = sosConfig.parameters["GO_responseMode"][0]

            # AGGREGATE INTERVAL & FUNCTION
            self.aggregate_interval = None
            self.aggregate_function = None
            self.aggregate_nodata = None
            self.aggregate_nodata_qi = None

            aggint = requestObject.getElementsByTagName('aggregateInterval')
            aggfun = requestObject.getElementsByTagName('aggregateFunction')
            aggnodata = requestObject.getElementsByTagName('aggregateNodata')

            if len(aggint)==1 and len(aggfun)==1:
                # aggregate_interval
                #  Check on the eventTime parameter: it must be only one interval: 2010-01-01T00:00:00+00/2011-01-01T00:00:01+00
                exeMsg = "Using aggregate functions, the event time must exist with an interval composed by a begin and an end date (ISO8601)"
                if self.eventTime == None or len(self.eventTime)!=1 or len(self.eventTime[0])!=2:
                    raise sosException.SOSException("NoApplicableCode", None, exeMsg)

                val = aggint[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.aggregate_interval = str(val.data)
                    try:
                        iso.parse_duration(self.aggregate_interval)

                    except Exception as ex:
                        raise sosException.SOSException("InvalidParameterValue", "aggregateInterval",
                            "Parameter \"aggregate_interval\" sent with invalid format (check ISO8601 duration spec): %s" % ex)

                else:
                    err_txt = "cannot get ISO8601 duration value in \"aggregateInterval\""
                    raise sosException.SOSException("InvalidParameterValue", "aggregateInterval", err_txt)

                # aggregate_function
                val = aggfun[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.aggregate_function = str(val.data)
                    if not (self.aggregate_function.upper() in ["AVG", "COUNT", "MAX", "MIN", "SUM"]):
                        raise sosException.SOSException("InvalidParameterValue", "aggregateFunction",
                            "Available aggregation functions: avg, count, max, min, sum.")

                # aggregate_no_data default value
                if len(aggnodata)==1:
                    val = aggnodata[0].firstChild
                    self.aggregate_nodata = str(val.data)

                else:
                    self.aggregate_nodata = sosConfig.aggregate_nodata

           #================================
           # MISSING AGGREGATE QUALITY INDEX
           #================================

            elif len(aggint)==0 and len(aggfun)==0:
                pass
            else:
                err_txt = "\"aggregateInterval\" and \"aggregate_function\" are both required with multiplicity 1"
                raise sosException.SOSException("NoApplicableCode", None, err_txt)

            # QUALITY INDEX
            self.qualityIndex=False
            qidx = requestObject.getElementsByTagName('qualityIndex')

            if len(qidx)>0:
                if len(qidx)<2:
                    val = qidx[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.qualityIndex = str(val.data)
                        if self.qualityIndex.upper() == "TRUE":
                            self.qualityIndex=True

                        elif self.qualityIndex.upper() == "FALSE":
                            pass

                        else:
                            raise sosException.SOSException("InvalidParameterValue", "qualityIndex",
                                "qualityIndex can only be \'True\' or \'False\'")

            elif len(qidx)==0:
                pass

            else:
                err_txt = "\"qualityIndex\" is allowed with multiplicity 1 only"
                raise sosException.SOSException("NoApplicableCode", None, err_txt)

            self.qualityFilter=False
Пример #18
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):
        f.sosFilter.__init__(self, sosRequest, method, requestObject,
                             sosConfig)
        # @TODO Declare attribute first!
        # self.offering = None
        # etc..

        #**************************
        if method == "GET":
            #---------- THE OFFERING
            if requestObject.has_key("offering"):
                self.offering = get_name_from_urn(requestObject["offering"],
                                                  "offering", sosConfig)
            else:
                raise sosException.SOSException(
                    1,
                    "Parameter \"offering\" is mandatory with multiplicity 1")

            #---------- THE OBSERVED PROPERTY
            if requestObject.has_key("observedProperty"):
                self.observedProperty = []
                oprs = requestObject["observedProperty"].split(",")
                for opr in oprs:
                    # get_name_from_urn limit the ability to ask for an observedProperty with LIKE:
                    # eg: ask "water" to get all the water related data, "water:discharge", "water:temperature" ...
                    #oprName = get_name_from_urn(opr,"property")
                    oprName = opr
                    self.observedProperty.append(oprName)  # one-many ID
            else:
                raise sosException.SOSException(
                    1,
                    "Parameter \"observedProperty\" is mandatory with multiplicity N"
                )

            #---------- RESPONSE FORMAT
            if requestObject.has_key("responseFormat"):
                if not requestObject["responseFormat"] in sosConfig.parameters[
                        "GO_responseFormat"]:
                    raise sosException.SOSException(
                        2,
                        "Parameter \"responseFormat\" sent with invalid value : use one of %s"
                        % "; ".join(sosConfig.parameters["GO_responseFormat"]))
                else:
                    self.responseFormat = requestObject["responseFormat"]
            else:
                raise sosException.SOSException(
                    1,
                    "Parameter \"responseFormat\" is mandatory with multiplicity 1"
                )  #one

            #OPTIONAL request parameters
            #---------- SRS FILTER
            if requestObject.has_key("srsName"):
                self.srsName = get_name_from_urn(requestObject["srsName"],
                                                 "refsystem", sosConfig)
                if not self.srsName in sosConfig.parameters["GO_srs"]:
                    raise sosException.SOSException(
                        2, "srsName \"%s\" not supported, use one of: %s" %
                        (self.srsName, ",".join(
                            sosConfig.parameters["GO_srs"])))
            else:
                self.srsName = sosConfig.parameters["GO_srs"][0]

            #---------- TIME FILTER
            if requestObject.has_key('eventTime'):
                self.eventTime = []
                for i in requestObject["eventTime"].replace(" ",
                                                            "+").split(","):
                    if len(i.split("/")) < 3:
                        self.eventTime.append(i.split("/"))
                    else:
                        raise sosException.SOSException(
                            2, "Parameter \"eventTime\" bad formatted")

                tp = []
                for t in self.eventTime:
                    if len(t) == 2:
                        tp.append(iso.parse_datetime(t[0]))
                        tp.append(iso.parse_datetime(t[1]))
                    if len(t) == 1:
                        tp.append(iso.parse_datetime(t[0]))

                # Checking if some event limitation is reached
                #if sosConfig["maxGoPeriod"]:
                if int(sosConfig.maxGoPeriod) > 0:
                    from datetime import timedelta
                    d = timedelta(hours=int(sosConfig.maxGoPeriod))
                    userPeriod = max(tp) - min(tp)
                    if d < userPeriod:
                        raise sosException.SOSException(
                            2,
                            "You are requesting data for a period of [%s hours], but you are not permitted to ask for a period longer than: %s hours"
                            % (userPeriod, d))

            else:
                self.eventTime = None

            #---------- PROCEDURES FILTER
            if requestObject.has_key("procedure"):
                self.procedure = []
                prcs = requestObject["procedure"].split(",")
                for prc in prcs:
                    prcName = get_name_from_urn(prc, "procedure", sosConfig)
                    self.procedure.append(prcName)
            else:
                self.procedure = None

            #---------- FEATURES OF INTEREST FILTER
            self.featureOfInterest = None
            self.featureOfInterestSpatial = None
            if requestObject.has_key("featureOfInterest"):
                foi = requestObject["featureOfInterest"]
                if foi.find("<ogc:") >= 0 and foi.find("<gml:") >= 0:
                    #raise sosException.SOSException(3,"FOI SPATIAL: %s" %(foi))
                    self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(
                        foi, 'geom_foi', sosConfig.istsosepsg)
                else:
                    self.featureOfInterest = get_name_from_urn(
                        foi, "feature", sosConfig)

                #fois = requestObject["featureOfInterest"].split(",")
                #for foi in fois:
                #    foiName = get_name_from_urn(foi,"feature")
                #    self.featureOfInterest.append(foiName)

            #---------- FILTERS FOR QUERY NOT SUPPORTED YET
            if requestObject.has_key("result"):
                #raise sosException.SOSException(3,"Parameter \"result\" not yet supported")
                self.result = sosUtils.ogcCompCons2PostgisSql(
                    requestObject["result"])
            else:
                self.result = None  #zero-one optional

            #---------- RESULT MODEL
            if requestObject.has_key("resultModel"):
                if requestObject["resultModel"] in sosConfig.parameters[
                        "GO_resultModel"]:
                    self.resultModel = requestObject["resultModel"]
                else:
                    raise sosException.SOSException(
                        2,
                        "Parameter \"resultModel\" sent with invalid value: supported values are: %s"
                        % ",".join(sosConfig.parameters["GO_resultModel"]))
            else:
                self.resultModel = sosConfig.parameters["GO_resultModel"][0]

            #---------- RESPONSE MODE
            if requestObject.has_key("responseMode"):
                if requestObject["responseMode"] in sosConfig.parameters[
                        "GO_responseMode"]:
                    self.responseMode = requestObject["responseMode"]
                else:
                    raise sosException.SOSException(
                        2,
                        "Parameter \"responseMode\" sent with invalid value, supported values are: %s"
                        % (",".join(sosConfig.parameters["GO_responseMode"])))

            else:
                self.responseMode = sosConfig.parameters["GO_responseMode"][0]

            ###########################
            # NON STANDARD PARAMETERS #
            ###########################
            #---------- AGGREGATE INTERVAL
            # In ISO 8601 duration format
            if requestObject.has_key("aggregateInterval"):
                # Check on the eventTime parameter: it must be only one interval: 2010-01-01T00:00:00+00/2011-01-01T00:00:01+00
                exeMsg = "Using aggregate functions, the event time must exist with an interval composed by a begin and an end date (ISO8601)"
                if self.eventTime == None or len(self.eventTime) != 1 or len(
                        self.eventTime[0]) != 2:
                    raise sosException.SOSException(2, exeMsg)
                self.aggregate_interval = requestObject["aggregateInterval"]
                try:
                    iso.parse_duration(self.aggregate_interval)
                except Exception as ex:
                    raise sosException.SOSException(
                        2,
                        "Parameter \"aggregate_interval\" sent with invalid format (check ISO8601 duration spec): %s"
                        % ex)
            else:
                self.aggregate_interval = None

            #---------- AGGREGATE FUNCTION
            # sum,avg,max,min
            if requestObject.has_key("aggregateFunction"):
                if self.aggregate_interval == None:
                    raise sosException.SOSException(
                        2,
                        "Using aggregate functions parameters \"aggregateInterval\" and \"aggregateFunction\" are both mandatory"
                    )
                self.aggregate_function = requestObject["aggregateFunction"]
                if not (self.aggregate_function.upper()
                        in ["AVG", "COUNT", "MAX", "MIN", "SUM"]):
                    raise sosException.SOSException(
                        2,
                        "Available aggregation functions: avg, count, max, min, sum."
                    )
            else:
                self.aggregate_function = None

            #---------- AGGREGATE NODATA
            if requestObject.has_key("aggregateNodata"):
                if self.aggregate_interval == None or self.aggregate_function == None:
                    raise sosException.SOSException(
                        2,
                        "Using aggregateNodata parameter requires both \"aggregateInterval\" and \"aggregateFunction\""
                    )
                self.aggregate_nodata = requestObject["aggregateNodata"]
            else:
                self.aggregate_nodata = sosConfig.aggregate_nodata

            #---------- AGGREGATE NODATA QUALITY INDEX
            if requestObject.has_key("aggregateNodataQi"):
                if self.aggregate_interval == None or self.aggregate_function == None:
                    raise sosException.SOSException(
                        2,
                        "Using aggregateNodataQi parameter requires both \"aggregateInterval\" and \"aggregateFunction\""
                    )
                self.aggregate_nodata_qi = requestObject["aggregateNodataQi"]
            else:
                self.aggregate_nodata_qi = sosConfig.aggregate_nodata_qi

            #------------ QUALITY INDEX
            self.qualityIndex = False
            if requestObject.has_key("qualityIndex"):
                if requestObject["qualityIndex"].upper() == "TRUE":
                    self.qualityIndex = True
                elif requestObject["qualityIndex"].upper() == "FALSE":
                    self.qualityIndex = False
                else:
                    raise sosException.SOSException(
                        2, "qualityIndex can only be True or False!")
                #    self.qualityIndex = sosUtils.CQLvalueFilter2PostgisSql("id_qi_fk",requestObject["qualityIndex"])

        #**********************
        if method == "POST":
            from xml.dom import minidom
            #---------- THE OFFERING
            offs = requestObject.getElementsByTagName('offering')
            if len(offs) == 1:
                val = offs[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.offering = get_name_from_urn(str(val.data),
                                                      "offering", sosConfig)
                else:
                    err_txt = "XML parsing error (get value: offering)"
                    raise sosException.SOSException(1, err_txt)
            else:
                err_txt = "Parameter \"offering\" is mandatory with multiplicity 1"
                raise sosException.SOSException(1, err_txt)

            #---------- THE OBSERVED PROPERTY
            obsProps = requestObject.getElementsByTagName('observedProperty')
            self.observedProperty = []
            if len(obsProps) > 0:
                for obsProp in obsProps:
                    val = obsProp.firstChild
                    if val.nodeType == val.TEXT_NODE:
                        # get_name_from_urn limit the ability to ask for an observedProperty with LIKE:
                        # eg: ask "water" to get all the water related data, "water:discharge", "water:temperature" ...
                        #self.observedProperty.append(get_name_from_urn(str(val.data),"property"))
                        self.observedProperty.append(str(val.data))
                    else:
                        err_txt = "XML parsing error (get value: observedProperty)"
                        raise sosException.SOSException(1, err_txt)
            else:
                err_txt = "Parameter \"observedProperty\" is mandatory with multiplicity N"
                raise sosException.SOSException(1, err_txt)

            #---------- RESPONSE FORMAT
            respF = requestObject.getElementsByTagName('responseFormat')
            if len(respF) == 1:
                val = respF[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.responseFormat = str(val.data)
                    if self.responseFormat not in sosConfig.parameters[
                            "GO_responseFormat"]:
                        raise sosException.SOSException(
                            2,
                            "Parameter \"responseFormat\" sent with invalid value: use one of %s"
                            % "; ".join(
                                sosConfig.parameters["GO_responseFormat"]))
                else:
                    err_txt = "XML parsing error (get value: responseFormat)"
                    raise sosException.SOSException(1, err_txt)
            else:
                err_txt = "Parameter \"responseFormat\" is mandatory with multiplicity 1"
                raise sosException.SOSException(1, err_txt)

            #OPTIONAL request parameters
            #---------- SRS OF RETURNED GML FEATURES
            srss = requestObject.getElementsByTagName('srsName')
            if len(srss) > 0:
                if len(srss) < 2:
                    val = srss[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.srsName = get_name_from_urn(
                            str(val.data), "refsystem", sosConfig)
                    else:
                        err_txt = "XML parsing error (get value: srsName)"
                        raise sosException.SOSException(1, err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"srsName\""
                    raise sosException.SOSException(1, err_txt)
            else:
                self.srsName = sosConfig.parameters["GO_srs"][0]

            #---------- TIME FILTER
            evtms = requestObject.getElementsByTagName('eventTime')
            self.eventTime = []
            if len(evtms) > 0:
                for evtm in evtms:
                    tps = evtm.getElementsByTagName('gml:TimePeriod')
                    for tp in tps:
                        begin = tp.getElementsByTagName('gml:beginPosition')
                        end = tp.getElementsByTagName('gml:endPosition')
                        if len(begin) == 1 and len(end) == 1:
                            Bval = begin[0].firstChild
                            Eval = end[0].firstChild
                            #raise sosException.SOSException(1,end[0].toprettyxml())
                            if Bval.nodeType == Bval.TEXT_NODE and Eval.nodeType == Eval.TEXT_NODE:
                                self.eventTime.append([
                                    str(Bval.data).replace(" ", "+"),
                                    str(Eval.data).replace(" ", "+")
                                ])
                                #raise sosException.SOSException(1,str(self.eventTime))
                            else:
                                err_txt = "XML parsing error (get value: TimePeriod)"
                                raise sosException.SOSException(1, err_txt)

                    tis = evtm.getElementsByTagName('gml:TimeInstant')
                    for ti in tis:
                        instant = ti.getElementsByTagName('gml:timePosition')
                        if len(instant) > 0 and len(instant) < 2:
                            Ival = instant[0].firstChild
                            if Ival.nodeType == Ival.TEXT_NODE:
                                self.eventTime.append(
                                    [str(Ival.data).replace(" ", "+")])
                            else:
                                err_txt = "XML parsing error (get value: Timeinstant)"
                                raise sosException.SOSException(1, err_txt)
            else:
                self.eventTime = None

            #---------- PROCEDURES FILTER
            procs = requestObject.getElementsByTagName('procedure')
            if len(procs) > 0:
                self.procedure = []
                for proc in procs:
                    if "xlink:href" in proc.attributes.keys():
                        self.procedure.append(
                            str(proc.getAttribute("xlink:href")))
                    elif proc.hasChildNodes():
                        val = proc.firstChild
                        if val.nodeType == val.TEXT_NODE:
                            self.procedure.append(
                                get_name_from_urn(str(val.data), "procedure",
                                                  sosConfig))
                    else:
                        err_txt = "XML parsing error (get value: procedure)"
                        raise sosException.SOSException(1, err_txt)
            else:
                self.procedure = None

            #---------- FEATURES OF INTEREST FILTER
            fets = requestObject.getElementsByTagName('featureOfInterest')
            self.featureOfInterest = None
            self.featureOfInterestSpatial = None
            if len(fets) > 0:
                if len(fets) < 2:
                    elements = [
                        e for e in fets[0].childNodes
                        if e.nodeType == e.ELEMENT_NODE
                    ]
                    if len(elements) == 1:
                        self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(
                            elements[0], 'geom_foi', sosConfig.istsosepsg)
                    else:
                        if "xlink:href" in fets[0].attributes.keys():
                            self.featureOfInterest = str(
                                fets[0].getAttribute("xlink:href"))
                        elif fets[0].hasChildNodes():
                            val = fets[0].firstChild
                            if val.nodeType == val.TEXT_NODE:
                                self.featureOfInterest = get_name_from_urn(
                                    str(val.data), "feature", sosConfig)
                        else:
                            err_txt = "XML parsing error (get value: featureOfInterest)"
                            raise sosException.SOSException(1, err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"featureOfInterest\""
                    raise sosException.SOSException(1, err_txt)

            #---------- FILTERS FOR QUERY NOT SUPPORTED YET
            ress = requestObject.getElementsByTagName('result')
            if len(ress) > 0:
                raise sosException.SOSException(
                    3, "Parameter \"result\" not yet supported")
            else:
                self.result = None  #zero-one optional

            #---------- RESULT MODEL
            mods = requestObject.getElementsByTagName('resultModel')
            if len(mods) > 0:
                if len(mods) < 2:
                    val = mods[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.resultModel = str(val.data)
                        if self.resultModel not in sosConfig.parameters[
                                "GO_resultModel"]:
                            raise sosException.SOSException(
                                2,
                                "Parameter \"resultModel\" sent with invalid value"
                            )
                    else:
                        err_txt = "XML parsing error (get value: resultModel)"
                        raise sosException.SOSException(1, err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"resultModel\""
                    raise sosException.SOSException(1, err_txt)
            else:
                self.resultModel = None

            #---------- RESPONSE MODE
            rsmods = requestObject.getElementsByTagName('responseMode')
            if len(rsmods) > 0:
                if len(rsmods) < 2:
                    val = rsmods[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.responseMode = str(val.data)
                        if self.responseMode not in sosConfig.parameters[
                                "GO_responseMode"]:
                            raise sosException.SOSException(
                                2,
                                "Parameter \"responseMode\" sent with invalid value"
                            )
                    else:
                        err_txt = "XML parsing error (get value: responseMode)"
                        raise sosException.SOSException(1, err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"responseMode\""
                    raise sosException.SOSException(1, err_txt)
            else:
                self.responseMode = sosConfig.parameters["GO_responseMode"][0]

            #-------------- AGGREGATE INTERVAL & FUNCTION
            self.aggregate_interval = None
            self.aggregate_function = None
            aggint = requestObject.getElementsByTagName('aggregateInterval')
            aggfun = requestObject.getElementsByTagName('aggregateFunction')
            aggnodata = requestObject.getElementsByTagName('aggregateNodata')

            if len(aggint) == 1 and len(aggfun) == 1:
                #-----------------------
                # -- aggregate_interval
                #-----------------------
                # Check on the eventTime parameter: it must be only one interval: 2010-01-01T00:00:00+00/2011-01-01T00:00:01+00
                exeMsg = "Using aggregate functions, the event time must exist with an interval composed by a begin and an end date (ISO8601)"
                if self.eventTime == None or len(self.eventTime) != 1 or len(
                        self.eventTime[0]) != 2:
                    raise sosException.SOSException(2, exeMsg)
                val = aggint[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.aggregate_interval = str(val.data)
                    try:
                        iso.parse_duration(self.aggregate_interval)
                    except Exception as ex:
                        raise sosException.SOSException(
                            2,
                            "Parameter \"aggregate_interval\" sent with invalid format (check ISO8601 duration spec): %s"
                            % ex)
                else:
                    err_txt = "cannot get ISO8601 duration value in \"aggregateInterval\""
                    raise sosException.SOSException(1, err_txt)
                #-----------------------
                # -- aggregate_function
                #-----------------------
                val = aggfun[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.aggregate_function = str(val.data)
                    if not (self.aggregate_function.upper()
                            in ["AVG", "COUNT", "MAX", "MIN", "SUM"]):
                        raise sosException.SOSException(
                            2,
                            "Available aggregation functions: avg, count, max, min, sum."
                        )

                #-----------------------------------
                # -- aggregate_no_data default value
                #-----------------------------------
                if len(aggnodata) == 1:
                    val = aggnodata[0].firstChild
                    self.aggregate_nodata = str(val.data)
                else:
                    self.aggregate_nodata = sosConfig.aggregate_nodata

        #================================
        #MISSING AGGREGATE QUALITY INDEX
        #================================

            elif len(aggint) == 0 and len(aggfun) == 0:
                pass
            else:
                err_txt = "\"aggregateInterval\" and \"aggregate_function\" are both required with multiplicity 1"
                raise sosException.SOSException(1, err_txt)

            #------------ QUALITY INDEX
            self.qualityIndex = False
            qidx = requestObject.getElementsByTagName('qualityIndex')
            if len(qidx) > 0:
                if len(qidx) < 2:
                    val = qidx[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.qualityIndex = str(val.data)
                        if self.qualityIndex.upper() == "TRUE":
                            self.qualityIndex = True
                        elif self.qualityIndex.upper() == "FALSE":
                            pass
                        else:
                            raise sosException.SOSException(
                                2,
                                "qualityIndex can only be \'True\' or \'False\'"
                            )
            elif len(qidx) == 0:
                pass
            else:
                err_txt = "\"qualityIndex\" is allowed with multiplicity 1 only"
                raise sosException.SOSException(1, err_txt)
Пример #19
0
def executeSos(environ, start_response):

    try:
        from istsoslib import sosDatabase
        from istsoslib import sosException

        try:
            sosConfig = waconf2sos.istsosConfig(environ)

        except sosException.SOSException as ise:
            raise ise

        except Exception as ex:
            raise sosException.SOSException("NoApplicableCode", "", str(ex))

        if not sosConfig.istsos_librarypath == "" or (
                sosConfig.istsos_librarypath is None):
            sys.path.insert(0, sosConfig.istsos_librarypath)

        pgdb = sosDatabase.PgDB(sosConfig.connection["user"],
                                sosConfig.connection["password"],
                                sosConfig.connection["dbname"],
                                sosConfig.connection["host"],
                                sosConfig.connection["port"])

        req_filter = FF.sosFactoryFilter(environ, sosConfig)

        # Checking authorizations
        if not sosConfig.user.allowedService(sosConfig.schema):
            raise sosException.SOSException(
                "NoApplicableCode", "", "You are not authorized to access the "
                "'%s' instance" % sosConfig.schema)

        elif req_filter.request in ['insertobservation', 'registersensor']:
            # If hybrid mode enable check authorizations
            if config.hybrid and (not 'HTTP_AUTHORIZATION' in environ):
                raise sosException.SOSException(
                    "NoApplicableCode", "",
                    "In hybrid mode, you are not authorized to "
                    "execute %s requests on this server" % req_filter.request)

            # Only Admin, Network Managers and Data Manager con execute
            # insertobservation or registersensor
            elif not sosConfig.user.isAdmin() and (
                    not sosConfig.user.isNetworkManager()) and (
                        not sosConfig.user.isDataManager()):
                raise sosException.SOSException(
                    "NoApplicableCode", "",
                    "You are not authorized to execute %s "
                    "requests on this server" % req_filter.request)

        response = FR.sosFactoryResponse(req_filter, pgdb)
        render = FRe.sosFactoryRender(response, sosConfig)

        try:
            content_type = req_filter.responseFormat

        except:
            content_type = 'application/xml; charset=utf-8'

        status = '200 OK'
        response_headers = [('Content-Type', content_type),
                            ('Content-Length',
                             str(len(render.encode('utf-8'))))]

        if str(environ['REQUEST_METHOD']).upper() == 'GET':
            rect = parse_qs(environ['QUERY_STRING'])
            requestObject = {}
            for key in rect.keys():
                requestObject[key.lower()] = rect[key][0]
            if "attachment" in requestObject:
                response_headers.append(
                    ("Content-Disposition",
                     "attachment; filename=%s" % requestObject["attachment"]))

        start_response(status, response_headers)
        return [render.encode('utf-8')]

    except sosException.SOSException, e:
        #print >> sys.stderr, traceback.print_exc()
        response_body = e.ToXML()
        status = '200 OK'
        response_headers = [('Content-Type', 'application/xml; charset=utf-8'),
                            ('Content-Length',
                             str(len(response_body.encode('utf-8'))))]
        start_response(status, response_headers)
        return [response_body.encode('utf-8')]
Пример #20
0
    except sosException.SOSException, e:
        #print >> sys.stderr, traceback.print_exc()
        response_body = e.ToXML()
        status = '200 OK'
        response_headers = [('Content-Type', 'application/xml; charset=utf-8'),
                            ('Content-Length',
                             str(len(response_body.encode('utf-8'))))]
        start_response(status, response_headers)
        return [response_body.encode('utf-8')]

    except Exception, e:
        print >> sys.stderr, traceback.print_exc()
        othertext = traceback.format_exception(*sys.exc_info())
        if sosConfig.debug:
            response_body = "%s" % (sosException.SOSException(
                "NoApplicableCode", None, e.__class__.__name__,
                [e, othertext]), )
        else:
            response_body = "%s" % (sosException.SOSException(
                "NoApplicableCode", None, "istSOS internal error",
                ["Please activate debug level for more details"]))
        status = '200 OK'
        response_headers = [('Content-Type', 'application/xml; charset=utf-8'),
                            ('Content-Length',
                             str(len(response_body.encode('utf-8'))))]
        start_response(status, response_headers)
        return [response_body.encode('utf-8')]

    return []
Пример #21
0
    def __init__(self, filter, pgdb):

        # get procedure information
        sql = """
            SELECT
                id_prc,
                name_prc,
                name_oty,
                name_foi,
                stime_prc,
                etime_prc
            FROM
                %s.procedures,
                %s.obs_type,
                %s.foi""" % (filter.sosConfig.schema, filter.sosConfig.schema,
                             filter.sosConfig.schema)
        sql += """
            WHERE
                id_oty=id_oty_fk
            AND
                id_foi=id_foi_fk
            AND
                assignedid_prc=%s"""

        params = (filter.assignedSensorId, )
        try:
            prc = pgdb.select(sql, params)[0]
        except:
            raise sosException.SOSException(
                "InvalidParameterValue", "assignedSensorId",
                "assignedSensorId '%s' is not valid!" %
                (filter.assignedSensorId))

        # check requested procedure name exists
        if not prc["name_prc"] == filter.procedure:
            raise sosException.SOSException(
                "NoApplicableCode", None,
                "procedure '%s' not associated with provided "
                "assignedSensorId!" % (filter.procedure))

        # check requested  foi name exists
        if not filter.foiName == prc["name_foi"]:
            raise sosException.SOSException(
                "NoApplicableCode", None,
                "featureOfInterest '%s' not associated with "
                "provided assignedSensorId" % (filter.foiName))

        # check provided samplingTime and upadate
        #  begin/end time procedure if necessary
        #  (samplingTime=period or istant of provided
        #  observations defined by samplingTime filter)
        #=============================================
        if filter.samplingTime:
            stime = filter.samplingTime.split("/")
            #
            if len(stime) == 2:  # is a TimePeriod
                start = iso.parse_datetime(stime[0])
                end = iso.parse_datetime(stime[1])

            elif len(stime) == 1:  # is a TimeInstant
                start = end = iso.parse_datetime(stime[0])

            else:
                raise Exception("filter samplingTime error! given '%s'" %
                                (filter.samplingTime))

            if start > end:
                raise Exception(
                    "endPosition (%s) must be after beginPosition (%s)" %
                    (end, start))

            # check samplingTime
            #  > verify procedure begin/end exist
            if not (prc["stime_prc"].__class__.__name__ == "NoneType" and
                    (prc["etime_prc"].__class__.__name__ == "NoneType")):

                # check eventTime interval and update begin/end position when
                #  force flas is active
                if filter.forceInsert:
                    # update begin time of procedure
                    if start < prc["stime_prc"]:
                        sql = """
                            UPDATE
                                %s.procedures""" % (filter.sosConfig.schema)
                        sql += """
                            SET
                                stime_prc=%s::TIMESTAMPTZ
                            WHERE
                                id_prc=%s"""
                        params = (stime[0], prc["id_prc"])
                        try:
                            a = pgdb.executeInTransaction(sql, params)
                            com = True

                        except:
                            raise Exception("SQL: %s" %
                                            (pgdb.mogrify(sql, params)))

                    # update end time of procedure
                    if end > prc["etime_prc"]:
                        sql = """
                            UPDATE
                                %s.procedures""" % (filter.sosConfig.schema)
                        sql += """
                            SET
                                etime_prc=%s::TIMESTAMPTZ
                            WHERE
                                id_prc=%s"""
                        params = (stime[1], prc["id_prc"])
                        try:
                            b = pgdb.executeInTransaction(sql, params)
                            com = True

                        except Exception as err:
                            raise Exception(
                                "SQL: %s - %s" %
                                (pgdb.mogrify(sql, params), err.pgerror))

                # check eventTime interval and update begin/end position when
                #  force flag is off
                else:
                    if filter.sosConfig.sequential:
                        sql = """
                            SELECT
                                max(time_eti) as max_time_eti
                            FROM
                                %s.event_time""" % (filter.sosConfig.schema)
                        sql += """
                            WHERE
                                id_prc_fk = %s
                            GROUP BY
                                id_prc_fk"""
                        params = (prc["id_prc"], )
                        try:
                            lastMsr = pgdb.select(sql,
                                                  params)[0]["max_time_eti"]
                        except:
                            lastMsr = None

                        if lastMsr is not None:
                            # verify begin observation is minor/equal then end
                            #  time procedure and later then last observation
                            if not (end >= prc["etime_prc"] and
                                    (start <= prc["etime_prc"]) and
                                    (start >= lastMsr)):
                                raise Exception(
                                    "begin observation (%s) must be between last "
                                    "observation (%s) and end procedure (%s); end"
                                    " observation (%s) must be after end "
                                    "procedure (%s)" %
                                    (start, lastMsr, prc["etime_prc"], end,
                                     prc["etime_prc"]))
                        else:
                            # verify begin observation is minor/equal then end
                            #  time procedure and later then first observation
                            if not (end >= prc["etime_prc"] and
                                    (start <= prc["etime_prc"]) and
                                    (start >= prc["stime_prc"])):
                                raise Exception(
                                    "begin observation (%s) must be between start "
                                    "procedure (%s) and end procedure (%s); end "
                                    "observation (%s) must be after end procedure "
                                    "(%s)" %
                                    (start, prc["stime_prc"], prc["etime_prc"],
                                     end, prc["etime_prc"]))

                    #-- update end time of procedure
                    sql = """
                        UPDATE
                            %s.procedures""" % (filter.sosConfig.schema)
                    sql += """
                        SET
                            etime_prc=%s::TIMESTAMPTZ
                        WHERE
                            id_prc=%s"""
                    params = (str(stime[1]), int(prc["id_prc"]))
                    try:
                        b = pgdb.executeInTransaction(sql, params)
                        com = True
                    except Exception as err:
                        raise Exception(
                            "SQL: %s - %s" %
                            (pgdb.mogrify(sql, params), err.pgerror))

            else:
                sql = """
                    UPDATE
                        %s.procedures""" % (filter.sosConfig.schema)
                sql += """
                    SET
                        stime_prc=%s::TIMESTAMPTZ,
                        etime_prc=%s::TIMESTAMPTZ
                    WHERE
                        id_prc=%s"""
                params = (str(stime[0]), str(stime[1]), int(prc["id_prc"]))
                try:
                    b = pgdb.executeInTransaction(sql, params)
                    com = True
                except:
                    raise Exception("SQL: %s" % (pgdb.mogrify(sql, params)))

        # check data definition and uom (compare registered
        #  observed properties with provided observations)
        #==================================================
        # get values for provided data: UOM, NAME, URN, ID
        #--------------------------------------------------
        sql = """
            SELECT
                id_pro,
                id_opr,
                def_opr,
                name_uom,
                constr_opr,
                constr_pro
            FROM
                %s.observed_properties,
                %s.proc_obs,
                %s.uoms""" % (filter.sosConfig.schema, filter.sosConfig.schema,
                              filter.sosConfig.schema)
        sql += """
            WHERE
                id_uom_fk = id_uom
            AND
                id_opr_fk = id_opr
            AND
                id_prc_fk = %s"""
        params = (prc["id_prc"], )
        try:
            opr = pgdb.select(sql, params)
        except Exception as err:
            raise Exception("SQL2: %s -%s" %
                            (pgdb.mogrify(sql, params), err.pgerror))

        # get list of available ObservedProperty, unit of measure, property
        #  id for this procedure
        oprNames = []
        oprUoms = []
        oprIds = []  # to be removed ????
        proIds = []
        obsPropConstr = []
        procConstr = []
        '''
        Building a matrix:

        oprNames = ["urn:ogc:def:parameter:x-istsos:1.0:" +
                    "meteo:air:temperature" , ...]
        oprUoms = ["mm" , ...]
        oprIds = [id_opr , ...]
        proIds = [id_pro , ...]
        obsPropConstr = [{
            "interval": ["-40", "50"],
            "role": "urn:ogc:def:classifiers:x-istsos:1.0:" +
                    "qualityIndex:check:acceptable"} , ...]
        procConstr = [{
            "max": "100",
            "role": "urn:ogc:def:classifiers:x-istsos:1.0:" +
                    "qualityIndex:check:reasonable"} , ...]
        '''

        for row in opr:

            oprNames.append(row["def_opr"])
            oprUoms.append(row["name_uom"])
            oprIds.append(row["id_opr"])
            proIds.append(row["id_pro"])

            if not row["constr_opr"] in [None, '']:
                obsPropConstr.append(json.loads(row["constr_opr"]))
            else:
                obsPropConstr.append(None)

            if not row["constr_pro"] in [None, '']:
                procConstr.append(json.loads(row["constr_pro"]))
            else:
                procConstr.append(None)

        # get ordered list of observed properties in data----
        dataKeys = [key for key in filter.data.keys()]

        # get ordered list of unit of measures provided with data-------
        dataUoms = []
        for key in filter.data.keys():
            if "uom" in filter.data[key].keys():
                dataUoms.append(filter.data[key]["uom"])
            else:
                dataUoms.append('None')

        # verify that all the properties observed by this procedure
        #  are provided with the correct data definition and uom
        for i, opr in enumerate(oprNames):
            try:
                k = dataKeys.index(opr)
            except:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "parameter '%s' not observed by RegisteredSensor "
                    "%s - %s" % (opr, oprNames, dataKeys))

            if not dataUoms[k] == oprUoms[i]:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "parameter '%s' not observed with provided unit of "
                    "measure" % (opr))

        # verify if time and coordinates are passed as data parameters
        #  and create the parameters list and parameters ID
        xobs = yobs = zobs = tpar = None
        pars = []  # Observed parameters
        parsId = []
        parsConsObs = []
        parsConsPro = []

        # urn of different parameters
        for i, dn in enumerate(dataKeys):
            if dn.split(":")[-1] in filter.sosConfig.parGeom["x"]:
                xobs = dataKeys[i]
            elif dn.split(":")[-1] in filter.sosConfig.parGeom["y"]:
                yobs = dataKeys[i]
            elif dn.split(":")[-1] in filter.sosConfig.parGeom["z"]:
                zobs = dataKeys[i]
            elif dn.find("iso8601") >= 0:
                tpar = dataKeys[i]
            else:
                if dn.split(":")[-1] != "qualityIndex":
                    pars.append(dn)
                    try:
                        parsId.append(proIds[oprNames.index(dn)])
                        parsConsObs.append(obsPropConstr[oprNames.index(dn)])
                        parsConsPro.append(procConstr[oprNames.index(dn)])
                    except:
                        raise Exception(
                            "parameter %s not observed by this sensor "
                            "%s - %s" % (dn, pars, oprNames))

        # set default quality index if not provided
        for par in pars:
            try:
                dataKeys.index(par + ":qualityIndex")
            except:
                filter.data[par + ":qualityIndex"] = {
                    "vals": [filter.sosConfig.default_qi] *
                    len(filter.data[par]["vals"])
                }

        # verify that mobile sensors provide coordinates as X,Y,Z
        if (xobs is False and yobs is False and
                zobs is False) and (prc["name_oty"] == "insitu-mobile-point"):
            raise Exception("Mobile sensors require x, y, z parameters")

        # verify that time parameter is provided
        if not tpar:
            raise Exception(
                "parameter 'time:iso8601' is required for InsertObservation")

        # verify that eventime are in provided samplingTime
        if len(filter.data[tpar]["vals"]) > 0:
            maxDate = iso.parse_datetime(max(filter.data[tpar]["vals"]))
            minDate = iso.parse_datetime(min(filter.data[tpar]["vals"]))
            if not maxDate <= end and minDate >= start:
                raise Exception(
                    "provided data (min: %s, max:%s) are not included in "
                    "provided <samplingTime> period (%s / %s) for "
                    "procedure %s" %
                    (minDate.isoformat(), maxDate.isoformat(),
                     start.isoformat(), end.isoformat(), prc["name_prc"]))

        # insert observation
        #  delete existing observations if force flag is active
        if filter.forceInsert:
            sql = """
                DELETE FROM
                    %s.event_time""" % (filter.sosConfig.schema)
            sql += """
                WHERE
                    id_prc_fk = %s
                AND
                    time_eti >= %s::TIMESTAMPTZ
                AND
                    time_eti <= %s::TIMESTAMPTZ"""
            params = (prc["id_prc"], stime[0], stime[1])
            try:
                b = pgdb.executeInTransaction(sql, params)
                com = True
            except:
                raise Exception("SQL: %s" % (pgdb.mogrify(sql, params)))

        # CASE I: observations list is void
        if len(filter.data[tpar]["vals"]) == 0:
            self.assignedId = ""
            ids_eti = []

        # CASE I: observations list contains data
        elif len(filter.data[tpar]["vals"]) > 0:
            # insert event times
            ids_eti = []
            params = []
            sql = """
                INSERT INTO
                    %s.event_time (id_prc_fk,time_eti)""" % (
                filter.sosConfig.schema)
            sql += """
                VALUES (
                    %s, %s::TIMESTAMPTZ)
                RETURNING
                    id_eti"""
            for val in filter.data[tpar]["vals"]:
                try:
                    ids_eti.append(
                        pgdb.executeInTransaction(
                            sql, (prc["id_prc"], val))[0]['id_eti'])
                    com = True
                except Exception as e:
                    raise Exception("Error inserting event times for %s: %s" %
                                    (prc["name_prc"], e))

            for i, par in enumerate(pars):
                params = []
                ids_msr = []
                sql = """
                    INSERT INTO %s.measures (
                        id_pro_fk,
                        id_eti_fk,
                        id_qi_fk,
                        val_msr)""" % (filter.sosConfig.schema)
                sql += """
                    VALUES
                        (%s, %s, %s, %s)
                    RETURNING
                        id_msr"""

                pco = parsConsObs[i]
                pcp = parsConsPro[i]
                for ii, id_et in enumerate(ids_eti):
                    if not filter.data[par]["vals"][ii] in [
                            'NULL', u'NULL', None, 'None', u'None',
                            filter.sosConfig.aggregate_nodata
                    ]:
                        # TODO: add an else statement to add the
                        #  aggregate_nodata value OR delete the event time if
                        #  not filter.data[par]["vals"][ii] in ['NULL',u'NULL',
                        #  None]:
                        pqi = int(
                            float(filter.data[par +
                                              ":qualityIndex"]["vals"][ii]))
                        # Constraint quality is done only if the quality index
                        #  is equal to the default qi (RAW DATA)
                        if int(filter.sosConfig.default_qi) == pqi:
                            # quality check level I (gross error)
                            val = float(filter.data[par]["vals"][ii])
                            if filter.sosConfig.correct_qi is not None and (
                                    pco is not None):
                                if 'max' in pco:
                                    if val <= (float(pco['max'])):
                                        pqi = int(filter.sosConfig.correct_qi)

                                elif 'min' in pco:
                                    if val >= (float(pco['min'])):
                                        pqi = int(filter.sosConfig.correct_qi)

                                elif 'interval' in pco:
                                    if (float(pco['interval'][0]) <= val <=
                                            float(pco['interval'][1])):
                                        pqi = int(filter.sosConfig.correct_qi)

                                elif 'valueList' in pco:
                                    if val in [
                                            float(p)
                                            for p in (pco['valueList'])
                                    ]:
                                        pqi = int(filter.sosConfig.correct_qi)

                            # quality check level II (statistical range)
                            if filter.sosConfig.stat_qi is not None and (
                                    pcp is not None):
                                if 'max' in pcp:
                                    if val <= float(pcp['max']):
                                        pqi = int(filter.sosConfig.stat_qi)

                                elif 'min' in pcp:
                                    if val >= float(pcp['min']):
                                        pqi = int(filter.sosConfig.stat_qi)

                                elif 'interval' in pcp:
                                    if (float(pcp['interval'][0]) <= val <=
                                            float(pcp['interval'][1])):
                                        pqi = int(filter.sosConfig.stat_qi)

                                elif 'valueList' in pcp:
                                    if val in [
                                            float(p) for p in pcp['valueList']
                                    ]:
                                        pqi = int(filter.sosConfig.stat_qi)

                        params = (int(parsId[i]), int(id_et), pqi,
                                  float(filter.data[par]["vals"][ii]))
                        try:
                            nid_msr = pgdb.executeInTransaction(sql, params)
                            ids_msr.append(str(nid_msr[0]['id_msr']))
                        except Exception as e:
                            com = False
                            raise e

            #--insert position values if required
            if prc["name_oty"] == "insitu-mobile-point":
                xparspl = xobs.split(":")
                epsg = xparspl[xparspl.index("EPSG") + 1]
                params = []
                sql = """
                    INSERT INTO %s.positions (
                        id_qi_fk,
                        id_eti_fk,
                        geom_pos)""" % (filter.sosConfig.schema)
                sql += """
                    VALUES (
                        %s, %s,
                        ST_Transform(
                            ST_SetSRID(ST_MakePoint(%s, %s, %s), %s), %s))"""

                for i, id_et in enumerate(ids_eti):
                    params = (filter.sosConfig.default_qi, id_et,
                              filter.data[xobs]["vals"][i],
                              filter.data[yobs]["vals"][i],
                              filter.data[zobs]["vals"][i], epsg,
                              filter.sosConfig.istsosepsg)
                    try:
                        ids_pos = pgdb.executeInTransaction(sql, params)
                        com = True
                    except Exception as a:
                        com = False
                        raise Exception("%s\nSQL: %s" %
                                        (a, pgdb.mogrify(sql, params)))

            # register assigned IDs of measures
            self.assignedId = "@".join([str(p) for p in ids_eti])
            # commit executed operations

        #Register the transactional operation in Log table
        if filter.sosConfig.transactional_log in ['True', 'true', 1]:
            sqlLog = """
                INSERT INTO %s.tran_log (
                    operation_trl,
                    procedure_trl,
                    begin_trl,
                    end_trl,
                    count,
                    stime_prc,
                    etime_prc)""" % (filter.sosConfig.schema)
            sqlLog += """
                VALUES (
                    'InsertObservation',
                    %s,
                    %s::TIMESTAMPTZ,
                    %s::TIMESTAMPTZ,
                    %s,
                    %s::TIMESTAMPTZ,
                    %s::TIMESTAMPTZ)"""
            params = (str(filter.procedure), start, end, len(ids_eti),
                      prc["stime_prc"], prc["etime_prc"])
            try:
                pgdb.executeInTransaction(sqlLog, params)
                com = True
            except:
                raise Exception("SQL: %s" % (pgdb.mogrify(sqlLog, params)))

        if com is True:
            pgdb.commitTransaction()
            # broadcasting to mqtt broker if configured
            if filter.sosConfig.mqtt["broker_url"] != '' and (
                    filter.sosConfig.mqtt["broker_port"] != ''):
                from istmqttlib import PahoPublisher
                PahoPublisher({
                    "broker_url":
                    filter.sosConfig.mqtt["broker_url"],
                    "broker_port":
                    filter.sosConfig.mqtt["broker_port"],
                    "broker_topic":
                    "%s%s" %
                    (filter.sosConfig.mqtt["broker_topic"], filter.procedure),
                    "data":
                    filter.dataArray
                }).start()
Пример #22
0
def ogcSpatCons2PostgisSql(ogcSpatialOperator, geomField, epsgField):
    """parse an ogc spatial operator element and convert it to a PostGIS SQL spatial WHERE clause"""
    ogcSupportedSpatialOperators = {
        'ogc:Disjoint': 'ST_Disjoint',
        'ogc:Equals': 'ST_Equals',
        'ogc:Intersect': 'ST_Intersects',
        'ogc:Touches': 'ST_Touches',
        'ogc:Crosses': 'ST_Crosses',
        'ogc:Within': 'ST_Within',
        'ogc:Contains': 'ST_Contains',
        'ogc:Overlaps': 'ST_Overlaps',
    }

    ogcSupportedDistanceBufferType = ['ogc:DWithin']
    ogcBBOXType = ['ogc:BBOX']
    ogcUnsupportedSpatialOperators = ['ogc:Beyond']

    if ogcSpatialOperator.__class__.__name__ in ["str", "StringField"]:
        xmlString = """<?xml version="1.0" encoding="UTF-8"?><sos:featureOfInterest 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://schemas.opengis.net/sos/1.0.0/sosAll.xsd"
        xmlns:sos="http://www.opengis.net/sos/1.0"
        xmlns:gml="http://www.opengis.net/gml/3.2"
        xmlns:ogc="http://www.opengis.net/ogc"
        xmlns:om="http://www.opengis.net/om/1.0" 
        service="SOS" version='1.0.0'>
        """
        xmlString += ogcSpatialOperator + "</sos:featureOfInterest>"
        xmlObject = minidom.parseString(xmlString)
        foi = xmlObject.getElementsByTagName("sos:featureOfInterest")[0]
        ogcSpatialOperator = childElementNodes(foi)[0]

    try:
        ogcOperator = ogcSpatialOperator.nodeName.encode()
    except:
        raise sosException.SOSException(
            "NoApplicableCode", None,
            "ogcSpatCons2PostgisSql: argunment must be an ''XML object'' or a valid ''XML string''"
        )

    sql = ''

    #---------------------------
    # PARSE OPTIONS
    #---------------------------
    if ogcOperator in ogcSupportedSpatialOperators.keys():
        childs = childElementNodes(ogcSpatialOperator)
        propertyName = childs[0].firstChild.data.encode()
        geometry = childs[1]
        try:
            epsg = geometry.attributes['srsName'].value.split(":")[-1]
        except:
            epsg = None
        if not epsg.isdigit() and not epsg == None:
            raise sosException.SOSException(
                "NoApplicableCode", None,
                "Error: srsName '%s' must be numeric!" % (epsg))
        GMLgeom = str(geometry.toxml()).replace("epsg:", "EPSG:")
        if epsgField == epsg or epsg == None:
            sql = "%s(%s,ST_GeomFromGML('%s'),%s))" % (
                ogcSupportedSpatialOperators[ogcOperator], geomField, GMLgeom,
                epsgField)
        else:
            sql = "%s(%s,ST_Transform(ST_Transform(ST_GeomFromGML('%s'),%s),%s))" % (
                ogcSupportedSpatialOperators[ogcOperator], geomField, GMLgeom,
                epsg, epsgField)
        return sql

    elif ogcOperator == 'ogc:BBOX':
        childs = childElementNodes(ogcSpatialOperator)
        propertyName = childs[0].firstChild.data.encode()
        geometry = childs[1]
        try:
            epsg = geometry.attributes['srsName'].value.split(":")[-1]
        except:
            epsg = None
        if not epsg.isdigit() and not epsg == None:
            raise sosException.SOSException(
                "NoApplicableCode", None,
                "Error: srsName '%s' must be numeric!" % (epsg))

        coords_llur = ",".join(
            geometry.getElementsByTagName('gml:coordinates')
            [0].firstChild.data.split(" "))
        ce = [float(a) for a in coords_llur.split(",")]

        if epsgField == epsg or epsg == None:
            sql = "%s && ST_MakeEnvelope(%s,%s,%s,%s,%s)" % (
                geomField, ce[0], ce[1], ce[2], ce[3], epsgField)
        else:
            sql = "%s && ST_Transform(ST_MakeEnvelope(%s,%s,%s,%s,%s),%s)" % (
                geomField, ce[0], ce[1], ce[2], ce[3], epsg, epsgField)
        return sql

    elif ogcOperator == 'ogc:DWithin':
        childs = childElementNodes(ogcSpatialOperator)
        propertyName = childs[0].firstChild.data.encode()
        geometry = childs[1]
        distance = childs[2].firstChild.data.encode()
        try:
            epsg = geometry.attributes['srsName'].value.split(":")[-1]
        except:
            epsg = None
        if not epsg.isdigit() and not epsg == None:
            raise sosException.SOSException(
                "NoApplicableCode", None,
                "Error: srsName '%s' must be numeric!" % (epsg))
        GMLgeom = str(geometry.toxml()).replace("epsg:", "EPSG:")
        if epsgField == epsg or epsg == None:
            sql = "ST_DWithin(%s,ST_GeomFromGML('%s'),%s)" % (
                geomField, GMLgeom, distance)
        else:
            sql = "ST_DWithin(%s,ST_Transform(ST_GeomFromGML('%s'),%s),%s)" % (
                geomField, GMLgeom, epsgField, distance)
        return sql

    elif ogcOperator in ogcUnsupportedSpatialOperators:
        raise sosException.SOSException(
            "NoApplicableCode", None,
            "Spatial Operator nor supported. Available methods are: %s" %
            (",".join(ogcSupportedSpatialOperators.keys())))

    else:
        raise sosException.SOSException("NoApplicableCode", None,
                                        "ogcSpatialOperator format ERROR")
Пример #23
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):
        f.sosFilter.__init__(self, sosRequest, method, requestObject,
                             sosConfig)
        #**************************
        if method == "GET":
            raise sosException.SOSException(
                "NoApplicableCode", None,
                "registerSensor request support only POST method!")

        if method == "POST":
            from StringIO import StringIO

            tree, ns = parse_and_get_ns(StringIO(requestObject))

            #---SensorDescription
            #----------------------
            SensorDescription = tree.find("{%s}SensorDescription" % ns['sos'])
            if SensorDescription == None:
                raise sosException.SOSException(
                    "MissingParameterValue", "SensorDescription",
                    "sos:SensorDescription parameter is mandatory with multiplicity 1"
                )

            #---Procedure Name
            name = tree.find(
                "{%s}SensorDescription/{%s}member/{%s}System/{%s}name" %
                (ns['sos'], ns['sml'], ns['sml'], ns['gml']))
            self.procedure = name.text

            #---ProcedureDescription
            description = tree.find(
                "{%s}SensorDescription/{%s}member/{%s}System/{%s}description" %
                (ns['sos'], ns['sml'], ns['sml'], ns['gml']))
            if not description == None:
                self.proc_desc = description.text
            else:
                self.proc_desc = 'NULL'

            # Add capabilities time to db
            # Convert all to seconds

            #---Capabilities
            capabilities = tree.findall(
                "{%s}SensorDescription/{%s}member/{%s}System/{%s}capabilities/{%s}DataRecord/{%s}field"
                % (ns['sos'], ns['sml'], ns['sml'], ns['sml'], ns['swe'],
                   ns['swe']))
            #print >> sys.stderr, "capabilities: ",capabilities

            self.time_sam_val = "0"
            self.time_acq_val = "0"

            for cap in capabilities:

                if cap.attrib.has_key('name') and cap.attrib[
                        'name'] == 'Sampling time resolution':
                    # parse Sampling time resolution
                    tmpSam = int(
                        cap.find("{%s}Quantity/{%s}value" %
                                 (ns['swe'], ns['swe'])).text)
                    uom = cap.find("{%s}Quantity/{%s}uom" %
                                   (ns['swe'], ns['swe']))
                    if uom.attrib.has_key('code'):
                        uomSam = uom.attrib['code']
                        self.time_sam_val = convertToSec[uomSam](
                            tmpSam)  #convertToSec(uomSam,tmpSam)
                    else:
                        raise sosException.SOSException(
                            "MissingParameterValue", "SensorDescription",
                            "sml:capabilities, missing uom for Sampling time resolution"
                        )
                elif cap.attrib.has_key('name') and cap.attrib[
                        'name'] == 'Acquisition time resolution':
                    # parse Acquisition time resolution
                    tmpAcq = int(
                        cap.find("{%s}Quantity/{%s}value" %
                                 (ns['swe'], ns['swe'])).text)
                    uom = cap.find("{%s}Quantity/{%s}uom" %
                                   (ns['swe'], ns['swe']))
                    if uom.attrib.has_key('code'):
                        uomAcq = uom.attrib['code']
                        self.time_acq_val = convertToSec[uomAcq](
                            tmpAcq)  #convertToSec(uomAcq,tmpAcq)
                    else:
                        raise sosException.SOSException(
                            "MissingParameterValue", "SensorDescription",
                            "sml:capabilities, missing uom for Sampling time resolution"
                        )

            #print >> sys.stderr, self.time_sam_val

        #---System type
        # From istSOS 2.0 the system type became mandatory (insitu-fixed-point, insitu-mobile-point, ...)
            self.systemType = None
            classifiers = tree.findall(
                "{%s}SensorDescription/{%s}member/{%s}System/{%s}classification/{%s}ClassifierList/{%s}classifier"
                % (ns['sos'], ns['sml'], ns['sml'], ns['sml'], ns['sml'],
                   ns['sml']))
            for classifier in classifiers:
                if classifier.attrib.has_key(
                        'name') and classifier.attrib['name'] == 'System Type':
                    val = classifier.find("{%s}Term/{%s}value" %
                                          (ns['sml'], ns['sml']))
                    if val != None:
                        self.systemType = val.text

            member = tree.find("{%s}SensorDescription/{%s}member" %
                               (ns['sos'], ns['sml']))
            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.1"
            root.append(member)
            self.xmlSensorDescription = root
            """
            from xml.dom.minidom import parseString
            txt = et.tostring(root, encoding="UTF-8")
            self.xmlSensorDescription = parseString(txt).toprettyxml()
            """

            #---ObservationTemplate
            #----------------------
            ObservationTemplate = tree.find("{%s}ObservationTemplate" %
                                            ns['sos'])
            if ObservationTemplate == None:
                raise sosException.SOSException(
                    "MissingParameterValue", "ObservationTemplate",
                    "ObservationTemplate parameter is mandatory with multiplicity 1"
                )

            Observation = ObservationTemplate.find("{%s}Observation" %
                                                   ns['om'])
            if Observation == None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:Observation tag is mandatory with multiplicity 1")

            #-------procedure
            procedure = Observation.find("{%s}procedure" % ns['om'])
            self.procedure = procedure.attrib["{%s}href" %
                                              ns['xlink']].split(":")[-1]
            if procedure == None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:procedure tag is mandatory with multiplicity 1")

            #-------ObservedProperties
            self.oprDef = []
            self.oprDesc = []
            self.oprName = []
            self.beginPosition = 'NULL'

            try:
                name = Observation.find(
                    "{%s}observedProperty/{%s}CompositePhenomenon/{%s}name" %
                    (ns['om'], ns['swe'], ns['gml']))
            except:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "swe:CompositePhenomenon mandatory name element is missing"
                )

            components = Observation.findall(
                "{%s}observedProperty/{%s}CompositePhenomenon/{%s}component" %
                (ns['om'], ns['swe'], ns['swe']))
            if not components == []:
                for comp in components:
                    try:
                        self.oprDef.append(comp.attrib["{%s}href" %
                                                       ns['xlink']])
                    except:
                        raise sosException.SOSException(
                            "NoApplicableCode", None,
                            "om:observedProperty/component attribute missing: 'xlink:href' required"
                        )
                        """ NON STANDARD
                        try:
                            desc = comp.find("{%s}description" % ns['gml'])
                            self.oprDesc.append(desc.text)
                        except:
                            self.oprDesc.append("NULL")

                        try:
                            desc = comp.find("{%s}name" % ns['gml'])
                            self.oprName.append(desc.text)
                        except:
                            self.oprName.append("NULL")
                        """
            """ PER COSA È? CASO NON COMPOSITEPHENOMENON?
            else:
                observedProperty = Observation.find("{%s}observedProperty" % ns['om'])
                try:
                    self.oprName.append(observedProperty.attrib["{%s}href" % ns['xlink']])
                except:
                    name = Observation.find("{%s}observedProperty/{%s}name" %(ns['om'],ns['gml']) )
                    try:
                        self.oprName.append(name.txt)
                    except:
                        raise sosException.SOSException(1,
                                "om:observedProperty Name is missing: 'xlink:href' or 'gml:name' required")

                    desc = Observation.find("{%s}observedProperty/{%s}description" %(ns['om'],ns['gml']) )
                    try:
                        self.oprDesc.append(desc.txt)
                    except:
                        self.oprDesc.append("NULL")
            """

            #-------samplingTime
            #==============================================================================
            #             samplingTime = Observation.find("{%s}samplingTime" % ns['om'] )
            #             if samplingTime == None:
            #                 raise sosException.SOSException("NoApplicableCode",None,"om:samplingTime tag is mandatory with multiplicity 1")
            #             else:
            #                 duration = samplingTime.find("{%s}TimePeriod/{%s}TimeLength/{%s}duration"
            #                                             %(ns['gml'],ns['gml'],ns['gml'], ) )
            #
            #                 if not duration==None:
            #
            #                     strdur = str( parse_duration( duration.text.strip() ) ).split(",")
            #                     if len(strdur)>1:
            #                         self.time_res_val = strdur[0].split(" ")[0]
            #                         self.time_res_unit = strdur[0].split(" ")[1]
            #                     elif len(strdur)==1:
            #                         time = strdur[0].split(":")
            #                         self.time_res_val = parse_duration( duration.text.strip() ).seconds
            #                         self.time_res_unit = "sec"
            #                 else:
            #                     self.time_res_unit = "unknown"
            #                     self.time_res_val = "NULL"
            #==============================================================================

            #------featureOfInterest
            featureOfInterest = Observation.find("{%s}featureOfInterest" %
                                                 ns['om'])
            if featureOfInterest == None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:featureOfInterest tag is mandatory with multiplicity 1"
                )
            try:
                self.foiName = featureOfInterest.attrib["{%s}href" %
                                                        ns['xlink']]
            except:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "om:featureOfInterest: attribute 'xlink:href' is required")
                """ NON COMPLIANT
                name = Observation.find("{%s}featureOfInterest/{%s}name" %(ns['om'],ns['gml']) )
                try:
                    self.foiName = name.text
                except:
                    raise sosException.SOSException(1,"om:featureOfInterest name is missing: 'xlink:href' or 'gml:name' is required")
                """

            description = Observation.find(
                "{%s}featureOfInterest/{%s}FeatureCollection/{%s}description" %
                (ns['om'], ns['gml'], ns['gml']))
            if not description == None:
                self.foiDesc = description.text
            else:
                self.foiDesc = "NULL"

            #--foiWKZ
            # gml_type = ["gml:Polygon", "gml:LineString", "gml:Point", "gml:Box", "gml:GeometryCollection",
            #            "gml:MultiPoint", "gml:MultiLineString", "gml:MultiPolygon"]
            self.foiType = None
            for geomtype in sosConfig.foiGeometryType:
                geomtype = geomtype.split(":")[1]
                GMLfeature = Observation.find(
                    "{%s}featureOfInterest/{%s}FeatureCollection/{%s}location/{%s}%s"
                    % (ns['om'], ns['gml'], ns['gml'], ns['gml'], geomtype))

                if not GMLfeature == None:
                    self.foiType = geomtype
                    self.foiSRS = GMLfeature.attrib["srsName"].split(":")[-1]
                    self.foiGML = et.tostring(
                        GMLfeature, encoding="UTF-8").replace(
                            "<?xml version='1.0' encoding='UTF-8'?>", "")
            if self.foiType == None:
                raise sosException.SOSException(
                    "NoApplicableCode", None,
                    "not found valid GML feature, supported: %s " %
                    (";".join(sosConfig.foiGeometryType)))

            #--result
            result = Observation.find("{%s}result" % ns['om'])
            self.parameters = []
            self.uoms = []
            self.names = []
            self.descs = []
            self.constr = []
            self.partime = []

            if not result == None:
                sdr = Observation.find("{%s}result/{%s}SimpleDataRecord" %
                                       (ns['om'], ns['swe']))
                da = Observation.find("{%s}result/{%s}DataArray" %
                                      (ns['om'], ns['swe']))

                if sdr != None and da == None:
                    fields = sdr.findall("{%s}field" % ns['swe'])
                elif da != None and sdr == None:
                    fields = da.findall(
                        "{%s}elementType/{%s}DataRecord/{%s}field" %
                        (ns['swe'], ns['swe'], ns['swe']))
                else:
                    err_txt = "in <swe:result>: <swe:DataRecord> or <swe:DataArray> are mandatory in multiplicity 1"
                    raise sosException.SOSException("NoApplicableCode", None,
                                                    err_txt)

                timetag = False
                for field in fields:
                    defin = None
                    uom = None
                    self.names.append(field.attrib['name'])
                    tf = field.find("{%s}Time" % ns['swe'])
                    qf = field.find("{%s}Quantity" % ns['swe'])

                    if not tf == None and qf == None:
                        self.partime.append(1)
                        timetag = True
                        self.parameters.append(tf.attrib["definition"])
                        uom = tf.find("{%s}uom" % ns['swe'])
                        self.uoms.append(uom.attrib["code"])
                        desc = tf.find("{%s}description" % ns['swe'])
                        if not desc == None:
                            self.descs.append(desc.text)
                        else:
                            self.descs.append("NULL")
                        #self.constr.append(None)
                        #self.constr.append("NULL")

                    elif not qf == None and tf == None:
                        self.partime.append(0)
                        self.parameters.append(qf.attrib["definition"])
                        uom = qf.find("{%s}uom" % ns['swe'])
                        self.uoms.append(uom.attrib["code"])
                        desc = qf.find("{%s}description" % ns['swe'])
                        if not desc == None:
                            self.descs.append(desc.text)
                        else:
                            self.descs.append("NULL")

                        # look for constraints [min,max,interval,valueList]
                        #===================================================
                        #import sys
                        cc = {}
                        constraints = qf.findall("{%s}constraint" %
                                                 (ns['swe']))
                        if len(constraints) == 0:
                            self.constr.append(None)
                        else:
                            for constraint in constraints:
                                if constraint:
                                    if "{%s}role" % ns[
                                            "xlink"] in constraint.attrib:
                                        if constraint.attrib["{%s}role" % ns[
                                                "xlink"]] == "urn:ogc:def:classifiers:x-istsos:1.0:qualityIndex:check:reasonable":
                                            crole = constraint.attrib[
                                                "{%s}role" % ns["xlink"]]

                                            allow = constraint.find(
                                                "{%s}AllowedValues" %
                                                (ns['swe']))
                                            if allow is None:
                                                err_txt = "in <swe:constraint>: <swe:AllowedValues> is mandatory in multiplicity 1"
                                                raise sosException.SOSException(
                                                    "NoApplicableCode", None,
                                                    err_txt)
                                            else:

                                                cvals = None
                                                if len(allow) == 1:
                                                    ct = allow[0].tag
                                                    if not ct in [
                                                            "{%s}min" %
                                                            ns["swe"],
                                                            "{%s}max" %
                                                            ns["swe"],
                                                            "{%s}interval" %
                                                            ns["swe"],
                                                            "{%s}valueList" %
                                                            ns["swe"]
                                                    ]:
                                                        err_txt = "in <swe:constraint>: support only min, max, interval, valueList tag"
                                                        raise sosException.SOSException(
                                                            "NoApplicableCode",
                                                            None, err_txt)

                                                    xvals = allow[
                                                        0].text.strip().split(
                                                            " ")

                                                    if ct == "{%s}min" % ns[
                                                            "swe"]:
                                                        ct = "min"
                                                        if not len(xvals) == 1:
                                                            err_txt = "'%s' constraint support/need one values" % ct
                                                            raise sosException.SOSException(
                                                                "NoApplicableCode",
                                                                None, err_txt)
                                                        try:
                                                            cvals = float(
                                                                xvals[0])
                                                        except:
                                                            err_txt = "'%s' constraint requires float value" % ct
                                                            raise sosException.SOSException(
                                                                "NoApplicableCode",
                                                                None, err_txt)

                                                    elif ct == "{%s}max" % ns[
                                                            "swe"]:
                                                        ct = "max"
                                                        if not len(xvals) == 1:
                                                            err_txt = "'%s' constraint support/need one values" % ct
                                                            raise sosException.SOSException(
                                                                "NoApplicableCode",
                                                                None, err_txt)
                                                        try:
                                                            cvals = float(
                                                                xvals[0])
                                                        except:
                                                            err_txt = "'%s' constraint requires float value" % ct
                                                            raise sosException.SOSException(
                                                                "NoApplicableCode",
                                                                None, err_txt)

                                                    elif ct == "{%s}interval" % ns[
                                                            "swe"]:
                                                        ct = "interval"
                                                        if not len(xvals) == 2:
                                                            err_txt = "'%s' constraint support/need two values" % ct
                                                            raise sosException.SOSException(
                                                                "NoApplicableCode",
                                                                None, err_txt)
                                                        try:
                                                            cvals = [
                                                                float(
                                                                    xvals[0]),
                                                                float(xvals[1])
                                                            ]
                                                        except:
                                                            err_txt = "'%s' constraint requires float value" % ct
                                                            raise sosException.SOSException(
                                                                "NoApplicableCode",
                                                                None, err_txt)

                                                    elif ct == "{%s}valueList" % ns[
                                                            "swe"]:
                                                        ct = "valueList"
                                                        if not len(xvals) > 0:
                                                            err_txt = "'%s' constraint support/need at least one values" % ct
                                                            raise sosException.SOSException(
                                                                "NoApplicableCode",
                                                                None, err_txt)
                                                        try:
                                                            cvals = [
                                                                float(a)
                                                                for a in xvals
                                                            ]
                                                        except:
                                                            err_txt = "'%s' constraint requires float value" % ct
                                                            raise sosException.SOSException(
                                                                "NoApplicableCode",
                                                                None, err_txt)

                                                    cc["role"] = crole
                                                    cc["%s" % ct] = cvals

                                if not cc == {}:
                                    self.constr.append(json.dumps(cc))
                                else:
                                    self.constr.append(None)

                    else:
                        err_txt = "swe:Time or swe:Quantity is mandatory in multiplicity 1:N"
                        raise sosException.SOSException(
                            "NoApplicableCode", None, err_txt)

            else:
                err_txt = "om:result is mandatory in multiplicity 1:N"
                raise sosException.SOSException("NoApplicableCode", None,
                                                err_txt)

            #case simple om:result
            """ WAS
            elif len(sdr)==0 and len(da)==0:
                if len(observedProperties)==1:
                    self.parameters.append(observedProperties[0])
                    self.uoms.append(getElemAtt(res[0],"uom"))
                else:
                    raise sosException.SOSException(1,"om:observedProperty is mandatory with multiplicity 1")



            else:
                err_txt = "om:observation ERROR"
                raise sosException.SOSException(1,err_txt)
            """
            """
Пример #24
0
 def __init__(self, filter, pgdb):
     
     pgdb.setTimeTZ("UTC")
     self.version = filter.version
 
     self.smlFile = ""
     sql = "SELECT id_prc, stime_prc, etime_prc, name_oty from %s.procedures, %s.obs_type" %(filter.sosConfig.schema,filter.sosConfig.schema)
     sql += " WHERE id_oty=id_oty_fk AND name_prc = %s" 
     params = (str(filter.procedure),)
     try:
         res=pgdb.select(sql,params)
     except:
         raise Exception("Error! sql: %s." %(pgdb.mogrify(sql,params)) )
     
     # raise error if the procedure is not found in db
     if res==None:
         raise sosException.SOSException("InvalidParameterValue","procedure","Procedure '%s' not exist or can't be found.")
     
     
     # look for observation end time
     try:
         self.procedureType = res[0]['name_oty']
     except:
         self.procedureType = None
         
     
     if self.procedureType == 'virtual':
         vpFolder = os.path.join(filter.sosConfig.virtual_processes_folder,filter.procedure)
         try:
             sys.path.append(vpFolder)
         except:
             raise Exception("Error in loading virtual procedure path")
             
         # check if python file exist
         if os.path.isfile("%s/%s.py" % (vpFolder,filter.procedure)):
             
             #import procedure process
             exec "import %s as vproc" %(filter.procedure)
             
             # Initialization of virtual procedure will load the source data
             vp = vproc.istvp()
             vp._configure(filter,pgdb)
             
             self.stime, self.etime = vp.getSampligTime()
             
         else:
             self.stime = None
             self.etime = None
     
     else:
         # look for observation start time
         try:
             self.stime = res[0]['stime_prc']
         except:
             self.stime = None
             #raise sosException.SOSException(1,"Procedure '%s' has no valid stime."%(filter.procedure))
         
         # look for observation end time
         try:
             self.etime = res[0]['etime_prc']
         except:
             self.etime = None
         
     
     # check if folder containing SensorML exists
     if not os.path.isdir(filter.sosConfig.sensorMLpath):
         raise Exception("istsos configuration error, cannot find sensorMLpath!")
     
     # clean up the procedure name to produce a valid file name
     filename = filter.procedure
     valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
     for c in filename:
         if not c in valid_chars:
             raise Exception("procedure name '%s' is not a valid: use only letters or digits!"%(filter.procedure))
     filename += '.xml'
     
     self.smlFile = os.path.join(filter.sosConfig.sensorMLpath, filename)
     # check if file exist                
     if not os.path.isfile(self.smlFile):
         raise Exception("SensorML file for procedure '%s' not found!" % (filter.procedure))
     
     sqlProc  = "SELECT def_opr, name_opr, desc_opr, constr_pro, name_uom, id_pro"
     sqlProc += " FROM %s.observed_properties opr, %s.proc_obs po," %(filter.sosConfig.schema,filter.sosConfig.schema)
     sqlProc += " %s.procedures pr, %s.uoms um" %(filter.sosConfig.schema,filter.sosConfig.schema)
     sqlProc += " WHERE opr.id_opr=po.id_opr_fk AND pr.id_prc=po.id_prc_fk AND um.id_uom = po.id_uom_fk"
     sqlProc += " AND name_prc = %s ORDER BY id_pro" 
     params = (str(filter.procedure),)
     try:
         self.observedProperties = pgdb.select(sqlProc, params)
     except Exception as exe:
         raise Exception("Error! %s\n > sql: %s." % (str(exe), pgdb.mogrify(sqlProc, params)))