Exemplo n.º 1
0
 def setResolution(self, resolution):
     duration = iso.parse_duration(resolution)
     self.resolution = int(duration.total_seconds())
     if 'days' in dir(duration):
         self.resolution += int(duration.days) * 86400
     if 'months' in dir(duration):
         self.resolution += int(duration.months) * 2592000
Exemplo n.º 2
0
 def setAcquisitionInterval(self, acquisition_interval):
     duration = iso.parse_duration(acquisition_interval)
     self.acquisition_interval = int(duration.total_seconds())
     if 'days' in dir(duration):
         self.acquisition_interval += int(duration.days) * 86400
     if 'months' in dir(duration):
         self.acquisition_interval += int(duration.months) * 2592000
Exemplo n.º 3
0
def execute(args):

    dtconfig = False
    debug = False
    config = False
    header = 0

    user = None
    if 'user' in args and args['user'] is not None:
        user = args['user']
    password = None
    if 'password' in args and args['password'] is not None:
        password = args['password']

    auth = None
    if user and password:
        auth = HTTPBasicAuth(user, password)

    if 'c' in args and args['c'] is not None:
        with open(args['c'], 'r') as f:
            config = json.loads(f.read())

        url = config['url']
        service = config['service']
        procedure = config['procedure']

        if "datetime" in config:
            dtconfig = config["datetime"]

        if "header" in config:
            header = config["header"]

        duration = None
        aggregationFunction = None
        if "aggregationInterval" in config:
            duration = iso.parse_duration(config['aggregationInterval'])
            aggregationFunction = []

        s = serial.Serial(config['port'], config['baud'])

    else:
        url = args['u']
        service = args['s']
        procedure = args['p']

        s = serial.Serial(args['x'], args['b'])

    s.timeout = 5

    if 'v' in args:
        debug = args['v']

    # Requesting service configuration info
    res = requests.get('%s/wa/istsos/services/%s/configsections' %
                       (url, service),
                       auth=auth)
    istConfig = res.json()['data']
    defaultNaN = istConfig["getobservation"]["aggregatenodata"]

    # Requesting a describe sensor mainly to store the assignedSensorId
    res = requests.get('%s/wa/istsos/services/%s/procedures/%s' %
                       (url, service, procedure),
                       auth=auth)

    ds = res.json()['data']
    if debug:
        print "Loading info: %s" % procedure

    # Preparing "io" object to send
    res = requests.get(
        '%s/wa/istsos/services/%s/operations/getobservation/offerings/'
        'temporary/procedures/%s/observedproperties/:/eventtime/last' %
        (url, service, procedure),
        params={"qualityIndex": "False"},
        auth=auth)

    io = {
        "AssignedSensorId": ds['assignedSensorId'],
        "ForceInsert": "true",
        "Observation": res.json()['data'][0]
    }
    ec = int(io['Observation']['result']['DataArray']['elementCount']) - 1

    # If config file given, check observedproperties exactness
    observations = []
    columns = []
    nodata = []
    aggregation = None
    for idx in range(1,
                     len(io["Observation"]['result']['DataArray']['field'])):
        observation = io["Observation"]['result']['DataArray']['field'][idx]
        observations.append(observation['definition'])
        columns.append((idx - 1))
        nodata.append(defaultNaN)
        if aggregationFunction is not None:
            aggregationFunction.append("")

    print aggregationFunction
    if config:
        for observation in config["observations"]:
            if observation['name'] not in observations:
                print "Warning: procedure \"%s\" does not observe %s" % (
                    procedure, observation['name'])
                s.close()
                exit()
            else:
                idx = observations.index(observation['name'])
                columns[idx] = int(observation['column'])
                if "nodata" in observation:
                    nodata[idx] = str(observation['nodata'])
                if "aggregation" in observation:
                    aggregationFunction[idx] = observation["aggregation"]

    skip = True
    sample = True
    line = 0

    startDate = None

    while True:
        if skip:
            # clear buffer (avoid bad read)
            print "Wait for serial"
            s.flushInput()
            s.readline()
            time.sleep(1)
            skip = False
            continue

        elif line < header:
            print "Skipping line: %s " % line
            s.flushInput()
            time.sleep(1)
            line = line + 1
            continue

        try:
            message = s.readline().strip()
            data = message.split(',')

            print data

            if dtconfig:
                if 'column' in dtconfig:
                    eventtime = datetime.strptime(
                        data[int(dtconfig['column'])], dtconfig['format'])

                elif 'date' in dtconfig and 'time' in dtconfig:
                    d = datetime.strptime(
                        data[int(dtconfig['date']['column'])],
                        dtconfig['date']['format'])
                    t = datetime.strptime(
                        data[int(dtconfig['time']['column'])],
                        dtconfig['time']['format'])
                    eventtime = datetime.combine(d, t.time())

                else:
                    print "Warning: date time configuration wrong"
                    s.close()
                    exit()

                if "tz" in dtconfig:
                    eventtime = getDateTimeWithTimeZone(
                        eventtime, dtconfig["tz"])

            else:
                eventtime = datetime.now(tzlocal())
                if startDate is None:
                    startDate = eventtime

            if aggregation is None:
                aggregation = []
                for idx in range(
                        1,
                        len(io["Observation"]['result']['DataArray']
                            ['field'])):
                    aggregation.append([])

            if aggregation and (startDate + duration) > eventtime:
                for idx in range(len(data)):
                    aggregation[idx].append(float(data[idx]))

            else:
                if aggregation is not None:
                    print "Preparing.."
                    startDate = startDate + duration
                    eventtime = startDate
                    data = []
                    for idx in range(len(aggregation)):
                        if aggregationFunction:
                            if aggregationFunction[idx] == 'sum':
                                data.append(str(sum(aggregation[idx])))
                            elif aggregationFunction[idx] == 'avg':
                                data.append(
                                    str(
                                        sum(aggregation[idx]) /
                                        len(aggregation[idx])))
                            elif aggregationFunction[idx] == 'min':
                                data.append(str(min(aggregation[idx])))
                            elif aggregationFunction[idx] == 'max':
                                data.append(str(max(aggregation[idx])))
                    aggregation = None

                io["Observation"]['samplingTime'] = {
                    "beginPosition": eventtime.isoformat(),
                    "endPosition": eventtime.isoformat()
                }
                ob = [eventtime.isoformat()]
                for idx in range(len(columns)):
                    column = columns[idx]
                    if nodata[idx] == data[column]:
                        ob.append(defaultNaN)
                    else:
                        ob.append(data[column])

                io["Observation"]['result']['DataArray']['values'] = [ob]

                if sample:
                    sample = False
                    print "\nData sample:"
                    for idx in range(len(observations)):
                        print "%s = %s" % (observations[idx],
                                           data[columns[idx]])
                    print "\n"

                if debug:
                    print "Sending data: %s" % (", ".join(ob))

                res = requests.post(
                    '%s/wa/istsos/services/%s/operations/insertobservation' %
                    (url, service),
                    data=json.dumps(io),
                    auth=auth)

                line = line + 1

                try:
                    res.raise_for_status()
                    if debug:
                        print "  > Insert Ok!"
                except requests.exceptions.HTTPError as ex:
                    print "Error: inserting data.."
                    s.close()
                    exit()

        except Exception as rex:
            print traceback.print_exc()
            print "Error: inserting data:\n%s" % rex

    s.close()
Exemplo n.º 4
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)
Exemplo n.º 5
0
    def executePost(self, db=True):
        if self.procedurename is None:
            raise Exception("POST action without procedure name not allowed")

        now = datetime.now(iso.UTC)
        non_blocking_exceptions = []

        # Create data array
        data = self.waEnviron['wsgi_input'].split(";")

        # Assigned id always in the first position
        assignedid = data[0]

        if len(data) == 4:  # regular time series
            mode = self.MODE_REGULAR

        elif len(data) == 2:  # irregular time series
            mode = self.MODE_IRREGULAR

        else:
            raise Exception(
                "Body content wrongly formatted. Please read the docs.")

        try:
            conn = databaseManager.PgDB(
                self.serviceconf.connection['user'],
                self.serviceconf.connection['password'],
                self.serviceconf.connection['dbname'],
                self.serviceconf.connection['host'],
                self.serviceconf.connection['port'])

            rows = conn.select(("""
                    SELECT
                        procedures.id_prc,
                        proc_obs.id_pro,
                        proc_obs.constr_pro,
                        procedures.stime_prc,
                        procedures.etime_prc,
                        procedures.name_prc
                    FROM
                        %s.procedures,
                        %s.proc_obs
                    WHERE
                        proc_obs.id_prc_fk = procedures.id_prc
                """ % (self.servicename, self.servicename)) + """
                  AND
                    assignedid_prc = %s
                  ORDER BY
                    proc_obs.id_pro ASC;
                """, (assignedid, ))

            if len(rows) == 0:
                raise Exception("Procedure with aid %s not found." %
                                assignedid)

            id_prc = rows[0][0]
            name_prc = rows[0][5]
            bp = rows[0][3]
            bpu = False
            ep = rows[0][4]
            epu = False

            def check_sampling(sampling):

                # If the end position exists the new measures must be after
                if ep is not None and sampling_time < ep:
                    non_blocking_exceptions.append(
                        "Procedure %s, Sampling time (%s) "
                        "is before the end position (%s)" %
                        (name_prc, sampling_time.isoformat(), ep.isoformat()))
                    return False

                # Check that the sampling time is before now
                if sampling_time > now:
                    non_blocking_exceptions.append(
                        "Procedure %s, Sampling time (%s) "
                        "is in the future (%s)" %
                        (name_prc, sampling_time.isoformat(), now.isoformat()))
                    return False

                return True

            tmp_data = []
            if mode == self.MODE_REGULAR:

                try:
                    start = iso.parse_datetime(data[1])
                except Exception:
                    raise Exception(
                        "Procedure %s, Sampling time (%s) "
                        "wrong format" % name_prc, data[1])

                try:
                    step = iso.parse_duration(data[2])
                except Exception:
                    raise Exception("Procedure %s, duration (%s) "
                                    "wrong format" % (name_prc, data[2]))

                data = data[3].split("@")
                for idx in range(0, len(data)):

                    sampling_time = start + (step * idx)

                    if not check_sampling(sampling_time):
                        continue

                    tmp_data.append([sampling_time.isoformat()] +
                                    data[idx].split(","))

            elif mode == self.MODE_IRREGULAR:
                data = data[1].split("@")
                for i in range(0, len(data)):
                    data[i] = data[i].split(",")

                    try:
                        try:
                            sampling_time = iso.parse_datetime(data[i][0])
                            if not check_sampling(sampling_time):
                                continue
                        except Exception:
                            raise Exception("Procedure %s, Sampling time (%s) "
                                            "wrong format" %
                                            (name_prc, data[i][0]))

                        tmp_data.append(data[i])

                    except Exception:
                        non_blocking_exceptions.append(
                            "Procedure %s, Sampling time (%s) "
                            "wrong format" % (name_prc, data[1]))
                        continue

            data = tmp_data

            op_cnt = len(rows)

            for observation in data:

                id_eti = conn.executeInTransaction(("""
                        INSERT INTO %s.event_time (id_prc_fk, time_eti)
                    """ % self.servicename) + """
                        VALUES (%s, %s::TIMESTAMPTZ) RETURNING id_eti;
                    """, (id_prc, observation[0]))

                if (bp is None) or (bp == '') or (iso.parse_datetime(
                        observation[0]) < bp):
                    bp = iso.parse_datetime(observation[0])
                    bpu = True

                if (ep is None) or (ep == '') or (iso.parse_datetime(
                        observation[0]) > ep):
                    ep = iso.parse_datetime(observation[0])
                    epu = True

                # check if procedure observations length is ok
                #   (-1 remove datetime from lenght of observations array)
                if op_cnt != (len(observation) - 1):
                    non_blocking_exceptions.append(
                        "Procedure %s, Array length missmatch with procedures "
                        "observation number: %s" % (name_prc, observation))
                    continue

                for idx in range(0, op_cnt):
                    try:
                        conn.executeInTransaction(
                            ("""
                                INSERT INTO %s.measures(
                                    id_eti_fk,
                                    id_qi_fk,
                                    id_pro_fk,
                                    val_msr
                                )
                            """ % self.servicename) + """
                                VALUES (%s, 100, %s, %s);
                            """,
                            (
                                int(id_eti[0][0]),  # id_eti
                                int(rows[idx][1]),  # id_pro
                                float(observation[(idx + 1)])))
                    except Exception as ie:
                        non_blocking_exceptions.append("Procedure %s, %s" %
                                                       (name_prc, ie))

            if bpu:
                conn.executeInTransaction(("""
                        UPDATE %s.procedures
                    """ % self.servicename) + """
                        SET stime_prc=%s::TIMESTAMPTZ WHERE id_prc=%s
                    """, (bp.isoformat(), id_prc))

            if epu:
                conn.executeInTransaction(("""
                        UPDATE %s.procedures
                    """ % self.servicename) + """
                        SET etime_prc=%s::TIMESTAMPTZ WHERE id_prc=%s
                    """, (ep.isoformat(), id_prc))

            conn.commitTransaction()

            # self.setData(ret)
            self.setMessage("Thanks for data")

            if len(non_blocking_exceptions) > 0:
                print >> sys.stderr, str(non_blocking_exceptions)

        except Exception as e:
            print >> sys.stderr, traceback.print_exc()
            #traceback.print_exc(file=sys.stderr)
            conn.rollbackTransaction()
            raise Exception("Error in fast insert (%s): %s" % (type(e), e))
Exemplo n.º 6
0
    def setData(self,pgdb,o,filter):
        """get data according to request filters"""
        # @todo mettere da qualche altra parte
            
        #SET FOI OF PROCEDURE
        #=========================================
        sqlFoi  = "SELECT name_fty, name_foi, ST_AsGml(ST_Transform(geom_foi,%s)) as gml, st_x(geom_foi) as x, st_y(geom_foi) as y " %(filter.srsName)
        sqlFoi += " FROM %s.procedures, %s.foi, %s.feature_type" %(filter.sosConfig.schema,filter.sosConfig.schema,filter.sosConfig.schema)
        sqlFoi += " WHERE id_foi_fk=id_foi AND id_fty_fk=id_fty AND id_prc=%s" %(o["id_prc"])
        try:
            resFoi = pgdb.select(sqlFoi)
        except:
            raise Exception("SQL: %s"%(sqlFoi))
        
        self.featureOfInterest = resFoi[0]["name_foi"]
        self.foi_urn = filter.sosConfig.urn["feature"] + resFoi[0]["name_fty"] + ":" + resFoi[0]["name_foi"]
        srs = filter.srsName or filter.sosConfig.istsosepsg
        if resFoi[0]["gml"].find("srsName")<0:
            self.foiGml = resFoi[0]["gml"][:resFoi[0]["gml"].find(">")] + " srsName=\"EPSG:%s\"" % srs + resFoi[0]["gml"][resFoi[0]["gml"].find(">"):]
        else:
            self.foiGml = resFoi[0]["gml"]
        
        self.srs = srs
        self.x = resFoi[0]["x"]
        self.y = resFoi[0]["y"]
        
        #SET INFORMATION ABOUT OBSERVED_PROPERTIES
        #=========================================       
        sqlObsPro = "SELECT id_pro, id_opr, name_opr, def_opr, name_uom FROM %s.observed_properties, %s.proc_obs, %s.uoms" %(filter.sosConfig.schema,filter.sosConfig.schema,filter.sosConfig.schema)
        sqlObsPro += " WHERE id_opr_fk=id_opr AND id_uom_fk=id_uom AND id_prc_fk=%s" %(o["id_prc"])
        sqlObsPro += " AND ("
        #sqlObsPro += " OR ".join(["def_opr='" + str(i) + "'" for i in filter.observedProperty])
        sqlObsPro += " OR ".join(["def_opr SIMILAR TO '%(:|)" + str(i) + "(:|)%'" for i in filter.observedProperty])
        sqlObsPro += " ) ORDER BY def_opr ASC"
        try:
            obspr_res = pgdb.select(sqlObsPro)
        except:
            raise Exception("SQL: %s"%(sqlObsPro))
            
        self.observedProperty = []
        self.observedPropertyName = []
        self.opr_urn = []
        self.uom = []
        self.qualityIndex = filter.qualityIndex
        
        for row in obspr_res:
            self.observedProperty += [str(row["def_opr"])]
            self.observedPropertyName +=[str(row["name_opr"])]
            self.opr_urn += [str(row["def_opr"])]
            try:
                #self.uom += [str(row["name_uom"]).encode('utf-8')]
                self.uom += [row["name_uom"]]
            except:
                self.uom += ["n/a"]
            if self.qualityIndex==True:
                self.observedProperty += [str(row["def_opr"])+":qualityIndex"]
                self.observedPropertyName += [str(row["name_opr"])+":qualityIndex"]
                self.opr_urn += [str(row["def_opr"] +":qualityIndex")]
                self.uom += ["-"]
        
        #SET DATA
        #=========================================getSampligTime
        #CASE "insitu-fixed-point" or "insitu-mobile-point"
        #-----------------------------------------
        if self.procedureType in ["insitu-fixed-point","insitu-mobile-point"]:
            sqlSel = "SELECT et.time_eti as t," 
            joinar=[]
            cols=[]

            aggrCols=[]
            aggrNotNull=[]

            valeFieldName = []
            for idx, obspr_row in enumerate(obspr_res):
                if self.qualityIndex==True:
                    #cols.append("C%s.val_msr as c%s_v, C%s.id_qi_fk as c%s_qi" %(idx,idx,idx,idx))
                    cols.append("C%s.val_msr as c%s_v, COALESCE(C%s.id_qi_fk,%s) as c%s_qi" %(idx,idx,idx,filter.aggregate_nodata_qi,idx))
                    valeFieldName.append("c%s_v" %(idx))
                    valeFieldName.append("c%s_qi" %(idx))
                else:
                    cols.append("C%s.val_msr as c%s_v" %(idx,idx))
                    valeFieldName.append("c%s_v" %(idx))

                # If Aggregatation funtion is set
                #---------------------------------
                if filter.aggregate_interval != None:
                    # This can be usefull with string values
                    '''aggrCols.append("CASE WHEN %s(dt.c%s_v) is NULL THEN '%s' ELSE '' || %s(dt.c%s_v) END as c%s_v\n" % ( 
                        filter.aggregate_function, idx, filter.aggregate_nodata, filter.aggregate_function, idx, idx)
                    )'''
                    # This accept only numeric results
                    aggrCols.append("COALESCE(%s(dt.c%s_v),'%s') as c%s_v\n" %(filter.aggregate_function,idx,filter.aggregate_nodata,idx))
                    if self.qualityIndex==True:
                        #raise sosException.SOSException(3,"QI: %s"%(self.qualityIndex))
                        aggrCols.append("COALESCE(MIN(dt.c%s_qi),%s) as c%s_qi\n" %( idx, filter.aggregate_nodata_qi, idx ))
                    aggrNotNull.append(" c%s_v > -900 " %(idx))
                
                # Set SQL JOINS
                #---------------
                join_txt  = " left join (\n"
                join_txt += " SELECT distinct A%s.id_msr, A%s.val_msr, A%s.id_eti_fk\n" %(idx,idx,idx)

                if self.qualityIndex==True:
                    join_txt += ",A%s.id_qi_fk\n" %(idx)
                join_txt += "   FROM %s.measures A%s, %s.event_time B%s\n" %(filter.sosConfig.schema,idx,filter.sosConfig.schema,idx)
                join_txt += " WHERE A%s.id_eti_fk = B%s.id_eti\n" %(idx,idx)
                join_txt += " AND A%s.id_pro_fk=%s\n" %(idx,obspr_row["id_pro"])
                join_txt += " AND B%s.id_prc_fk=%s\n" %(idx,o["id_prc"])
                
                # if qualityIndex has filter
                #------------------------------
                #if filter.qualityIndex and filter.qualityIndex.__class__.__name__=='str':
                #    join_txt += " AND %s\n" %(filter.qualityIndex)

                # ATTENTION: HERE -999 VALUES ARE EXCLUDED WHEN ASKING AN AGGREAGATE FUNCTION
                if filter.aggregate_interval != None: # >> Should be removed because measures data is not inserted if there is a nodata value
                    join_txt += " AND A%s.val_msr > -900 " % idx
                
                # If eventTime is set add to JOIN part
                #--------------------------------------
                if filter.eventTime:
                    join_txt += " AND ("
                    etf=[]
                    for ft in filter.eventTime:
                        if len(ft)==2:
                            etf.append("B%s.time_eti > timestamptz '%s' AND B%s.time_eti <= timestamptz '%s' \n" %(idx,ft[0],idx,ft[1]))
                        elif len(ft)==1:
                            etf.append("B%s.time_eti = timestamptz '%s' \n" %(idx,ft[0]))
                        else:
                            raise Exception("error in time filter")
                    join_txt += " OR ".join(etf)
                    join_txt +=  ")\n"
                else:
                    join_txt += " AND B%s.time_eti = (SELECT max(time_eti) FROM %s.event_time WHERE id_prc_fk=%s) \n" %(idx,filter.sosConfig.schema,o["id_prc"])
                
                # close SQL JOINS
                #-----------------
                join_txt += " ) as C%s\n" %(idx)
                join_txt += " on C%s.id_eti_fk = et.id_eti" %(idx)
                joinar.append(join_txt)
            
            
            #If MOBILE PROCEDURE
            #--------------------
            if self.procedureType=="insitu-mobile-point":
                join_txt  = " left join (\n"
                join_txt += " SELECT distinct Ax.id_pos, X(ST_Transform(Ax.geom_pos,%s)) as x,Y(ST_Transform(Ax.geom_pos,%s)) as y,Z(ST_Transform(Ax.geom_pos,%s)) as z, Ax.id_eti_fk\n" %(filter.srsName,filter.srsName,filter.srsName)
                if self.qualityIndex==True:
                    join_txt += ", Ax.id_qi_fk as posqi\n"
                join_txt += "   FROM %s.positions Ax, %s.event_time Bx\n" %(filter.sosConfig.schema,filter.sosConfig.schema)
                join_txt += " WHERE Ax.id_eti_fk = Bx.id_eti"
                join_txt += " AND Bx.id_prc_fk=%s" %(o["id_prc"])
                
                if filter.eventTime:
                    join_txt += " AND ("
                    etf=[]
                    for ft in filter.eventTime:
                        if len(ft)==2:
                            etf.append("Bx.time_eti > timestamptz '%s' AND Bx.time_eti <= timestamptz '%s' " %(ft[0],ft[1]))
                        elif len(ft)==1:
                            etf.append("Bx.time_eti = timestamptz '%s' " %(ft[0]))                       
                        else:
                            raise Exception("error in time filter")
                    join_txt += " OR ".join(etf)
                    join_txt +=  ")\n"
                else:
                    join_txt += " AND Bx.time_eti = (SELECT max(time_eti) FROM %s.event_time WHERE id_prc_fk=%s) " %(filter.sosConfig.schema,o["id_prc"])
                
                join_txt += " ) as Cx on Cx.id_eti_fk = et.id_eti\n"
                sqlSel += " Cx.x as x, Cx.y as y, Cx.z as z, "
                if self.qualityIndex==True:
                    #sqlSel += "COALESCE(Cx.posqi,%s) as posqi, " % filter.aggregate_nodata_qi
                    sqlSel += "Cx.posqi, "
                joinar.append(join_txt)
            
            
            # Set FROM CLAUSE
            #-----------------    
            sqlSel += ", ".join(cols)
            sqlSel += " FROM %s.event_time et\n" %(filter.sosConfig.schema)

            #====================            
            # Set WHERE CLAUSES
            #====================
            sqlData = " ".join(joinar)
            sqlData += " WHERE et.id_prc_fk=%s\n" %(o["id_prc"]) 

            # Set FILTER ON RESULT (OGC:COMPARISON) -
            #----------------------------------------
            if filter.result:
                for ind, ov in enumerate(self.observedProperty):
                    if ov.find(filter.result[0])>0:
                        sqlData += " AND C%s.val_msr %s" %(ind,filter.result[1])
                #sqlData += " AND C%s.val_msr %s" %(self.observedProperty.index(filter.result[0]),filter.result[1])
                
            # Set FILTER ON EVENT-TIME -
            #---------------------------
            if filter.eventTime:
                sqlData += " AND ("
                etf=[]
                for ft in filter.eventTime:
                    if len(ft)==2:
                        etf.append("et.time_eti > timestamptz '%s' AND et.time_eti <= timestamptz '%s' " %(ft[0],ft[1]))
                    elif len(ft)==1:
                        etf.append("et.time_eti = timestamptz '%s' " %(ft[0]))                        
                    else:
                        raise Exception("error in time filter")
                sqlData += " OR ".join(etf)
                sqlData +=  ")"
            else:
                sqlData += " AND et.time_eti = (SELECT max(time_eti) FROM %s.event_time WHERE id_prc_fk=%s) " %(filter.sosConfig.schema,o["id_prc"])

            sqlData += " ORDER by et.time_eti"

            sql = sqlSel+sqlData
            
            #
            if filter.aggregate_interval != None:
                self.aggregate_function = filter.aggregate_function.upper()
                '''
                for i in range(0,len(self.observedProperty)):
                    self.observedProperty[i] = "%s:%s" % (self.observedProperty[i], filter.aggregate_function)

                for ob in self.observedProperty:
                    ob = "%s:%s" % (ob, filter.aggregate_function)'''
                
                # Interval preparation
                # Converting ISO 8601 duration
                isoInt = iso.parse_duration(filter.aggregate_interval)
                sqlInt = ""

                if isinstance(isoInt, timedelta):
                
                    if isoInt.days>0:
                        sqlInt += "%s days " % isoInt.days
                    if isoInt.seconds>0:
                        sqlInt += "%s seconds " % isoInt.seconds
                        
                elif isinstance(isoInt, iso.Duration): 
                    if isoInt.years>0:
                        sqlInt += "%s years " % isoInt.years
                    if isoInt.months>0:
                        isoInt.months = int(isoInt.months)
                        sqlInt += "%s months " % isoInt.months
                    if isoInt.days>0:
                        sqlInt += "%s days " % isoInt.days
                    if isoInt.seconds>0:
                        sqlInt += "%s seconds " % isoInt.seconds

                
                # @todo improve this part
                # calculate how many step are included in the asked interval.
                hopBefore = 1
                hop = 0
                tmpStart = iso.parse_datetime(filter.eventTime[0][0])
                tmpEnd = self.samplingTime[1]
                
                while (tmpStart+isoInt)<=tmpEnd and (tmpStart+isoInt)<=iso.parse_datetime(filter.eventTime[0][1]):
                    
                    if   tmpStart <  self.samplingTime[0]:
                        hopBefore+=1
                        hop+=1

                    elif (tmpStart >= self.samplingTime[0]) and ((tmpStart+isoInt)<=self.samplingTime[1]):
                        hop+=1
                        
                    tmpStart=tmpStart+isoInt

                aggregationSQL = "SELECT ts.sint  as t, %s\n"
                aggregationSQL += "FROM\n"
                aggregationSQL += "    (\n" # Generating time series here
                aggregationSQL += "        select\n"
                aggregationSQL += "        (('%s'::TIMESTAMP WITH TIME ZONE)  \n"
                aggregationSQL += "            + s.a * '%s'::interval)::TIMESTAMP WITH TIME ZONE as sint\n"
                aggregationSQL += "        from generate_series(%s, %s) as s(a)\n"
                aggregationSQL += "    ) as ts LEFT JOIN ( \n\n"
                aggregationSQL += "    %s \n\n"
                aggregationSQL += "    ) as dt\n"
                aggregationSQL += "    ON (\n"
                aggregationSQL += "        dt.t > (ts.sint-'%s'::interval)\n"
                aggregationSQL += "        AND\n"
                aggregationSQL += "        dt.t <= (ts.sint) \n"
                aggregationSQL += "    )\n"
                aggregationSQL += "    GROUP BY ts.sint\n"
                aggregationSQL += "    ORDER BY ts.sint"
                sql = aggregationSQL % (", ".join(aggrCols), filter.eventTime[0][0], sqlInt, hopBefore, hop, sql, sqlInt)
                
            else:
                self.aggregate_function = None
                
            #print sql.replace('\n','')
            
            try:
                data_res = pgdb.select(sql)
            except:
                raise Exception("SQL: %s"%(sql))
            

            #------------------------------------            
            #--------- APPEND DATA IN ARRAY -----
            #------------------------------------            
            #append data
            for line in data_res:
                if self.procedureType=="insitu-fixed-point":
                    data_array = [line["t"]]
                elif self.procedureType=="insitu-mobile-point":
                    if self.qualityIndex==True:
                        data_array = [line["t"],line["x"],line["y"],line["z"],line["posqi"]]
                    else:
                        data_array = [line["t"],line["x"],line["y"],line["z"]]
                data_array.extend([line[field] for field in valeFieldName])
                self.data.append(data_array)
            
        #-----------------------------------------                
        #CASE "virtual"
        #-----------------------------------------       
        elif self.procedureType in ["virtual"]:
            
            
            self.aggregate_function = filter.aggregate_function
            self.aggregate_interval = filter.aggregate_interval
            self.aggregate_nodata = filter.aggregate_nodata
            self.aggregate_nodata_qi = filter.aggregate_nodata_qi
                        
            vpFolder = os.path.join(os.path.join(filter.sosConfig.virtual_processes_folder,self.name))
            
            if not os.path.isfile("%s/%s.py" % (vpFolder,self.name)):
                raise Exception("Virtual procedure folder does not contain any Virtual Procedure code for %s" % self.name)
                
            #----- VIRTUAL PROCESS LOADING -----
            try:
                sys.path.append(vpFolder)
            except:
                raise Exception("error in loading virtual procedure path")
            #import procedure process
            exec "import %s as vproc" %(self.name)
            
            # Initialization of virtual procedure will load the source data
            vp = vproc.istvp()
            vp._configure(filter, pgdb)
            # Calculate virtual procedure data
            vp.calculateObservations(self)
Exemplo n.º 7
0
def applyFunction(ob, filter):
    import copy
    try:
        # Create array container
        begin = iso.parse_datetime(filter.eventTime[0][0])
        end = iso.parse_datetime(filter.eventTime[0][1])
        duration = iso.parse_duration(filter.aggregate_interval)
        result = {}        
        dt = begin
        fields = len(ob.observedProperty)# + 1 # +1 timestamp field not mentioned in the observedProperty array
        
        while dt < end:
            dt2 = dt + duration
            result[dt2]=[]
            for c in range(fields):
                result[dt2].append([])
            
            d = 0
            data = copy.copy(ob.data)
            while len(data) > 0:
                tmp = data.pop(d)
                if dt < tmp[0] and tmp[0] <= dt2:
                    ob.data.pop(d)
                    for c in range(fields):
                        result[dt2][c].append(float(tmp[c+1]))
                elif dt > tmp[0]:
                    ob.data.pop(d)
                elif dt2 < tmp[0]:
                    break
                    
            dt = dt2
            
        data = []
        
        for r in sorted(result):
            record = [r]
            for v in range(len(result[r])):
                if ob.observedProperty[v].split(":")[-1]=="qualityIndex":
                    if len(result[r][v])==0:
                        record.append(filter.aggregate_nodata_qi)
                    else:
                        record.append(int(min(result[r][v])))
                else:
                    val = None
                    if len(result[r][v])==0:
                        val = filter.aggregate_nodata
                    elif filter.aggregate_function.upper() == 'SUM':
                        val = sum(result[r][v])
                    elif filter.aggregate_function.upper() == 'MAX':
                        val = max(result[r][v])
                    elif filter.aggregate_function.upper() == 'MIN':
                        val = min(result[r][v])
                    elif filter.aggregate_function.upper() == 'AVG':
                        val = round(sum(result[r][v])/len(result[r][v]),4)
                    elif filter.aggregate_function.upper() == 'COUNT':
                        val = len(result[r][v])
                    record.append(val)
            data.append(record)
                
        ob.data = data
        
    except Exception as e:
        raise Exception("Error while applying aggregate function on virtual procedures: %s" % (e))
Exemplo n.º 8
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)
Exemplo n.º 9
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 requestObject.has_key("observedproperty"):
                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 requestObject.has_key("procedure"):
                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 requestObject.has_key("offering"):
                    prcs = requestObject["offering"].split(",")
                    if self.procedure == 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 requestObject.has_key("responseformat"):
                    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 requestObject.has_key("crs"):
                    try:
                        self.srsName = requestObject["crs"].split(':')[-1]

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

                    if not self.srsName 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 requestObject.has_key("featureofinterest"):
                    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 requestObject.has_key("spatialfilter"):

                    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 requestObject.has_key("offering"):
                    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 requestObject.has_key("responseformat"):
                    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 not requestObject.has_key("offering"):
                    raise sosException.SOSException(
                        "MissingParameterValue", "offering",
                        "Parameter \"offering\" is mandatory with multiplicity 1"
                    )

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

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

                # OPTIONAL SRS FILTER
                if requestObject.has_key("srsname"):
                    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 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(
                                "InvalidParameterValue", "eventTime",
                                "Parameter \"eventTime\" bad formatted")

                # FEATURES OF INTEREST FILTER
                if requestObject.has_key("featureofinterest"):
                    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 requestObject.has_key("result"):
                    self.result = sosUtils.ogcCompCons2PostgisSql(
                        requestObject["result"])

                # RESULT MODEL
                if requestObject.has_key("resultmodel"):
                    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 requestObject.has_key("responsemode"):
                    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 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("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 requestObject.has_key("aggregatefunction"):
                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 requestObject.has_key("aggregatenodata"):
                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 requestObject.has_key("aggregatenodataqi"):
                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 requestObject.has_key("qualityindex"):
                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 requestObject.has_key("qualityfilter"):
                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 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
Exemplo n.º 10
0
    def executePost(self, db=True):
        if self.procedurename is None:
            raise Exception(
                "POST action without procedure name not allowed")

        # Create data array
        data = self.waEnviron['wsgi_input'].split(";")

        # Assigned id always in the first position
        assignedid = data[0]

        if len(data) == 4:  # regular time series
            mode = self.MODE_REGULAR
            start = iso.parse_datetime(data[1])
            step = iso.parse_duration(data[2])
            tmp_data = []
            data = data[3].split("@")
            for idx in range(0, len(data)):
                tmp_data.append([
                    (start + (step * idx)).isoformat()
                ] + data[idx].split(","))
            data = tmp_data

        elif len(data) == 2:  # irregular time series
            mode = self.MODE_IRREGULAR
            data = [i.split(",") for i in data[1].split("@")]

        else:
            raise Exception(
                "Body content wrongly formatted. Please read the docs.")

        try:
            conn = databaseManager.PgDB(
                self.serviceconf.connection['user'],
                self.serviceconf.connection['password'],
                self.serviceconf.connection['dbname'],
                self.serviceconf.connection['host'],
                self.serviceconf.connection['port']
            )
            sql = """
                SELECT
                    procedures.id_prc,
                    proc_obs.id_pro,
                    proc_obs.constr_pro,
                    procedures.stime_prc,
                    procedures.etime_prc
                FROM
                    %s.procedures,
                    %s.proc_obs
                WHERE
                    proc_obs.id_prc_fk = procedures.id_prc
            """ % (self.servicename, self.servicename)
            sql += """
              AND
                assignedid_prc = %s
              ORDER BY
                proc_obs.id_pro ASC;
            """
            rows = conn.select(sql, (assignedid,))

            if len(rows) == 0:
                raise Exception(
                    "Procedure with aid %s not found." % assignedid)

            # check if procedure observations length is ok
            if len(rows) != (len(data[0])-1):
                raise Exception(
                    "Array length missmatch with procedures "
                    "observation number")

            insertEventTime = """
                INSERT INTO %s.event_time (id_prc_fk, time_eti)
            """ % (self.servicename)
            insertEventTime += """
                VALUES (%s, %s::TIMESTAMPTZ) RETURNING id_eti;
            """

            deleteEventTime = """
                DELETE FROM %s.event_time
            """ % (self.servicename)
            deleteEventTime += """
                WHERE id_prc_fk = %s
                AND time_eti = %s::TIMESTAMPTZ
            """

            insertMeasure = """
                INSERT INTO %s.measures(
                    id_eti_fk,
                    id_qi_fk,
                    id_pro_fk,
                    val_msr
                )
            """ % (self.servicename)
            insertMeasure += """
                VALUES (%s, 100, %s, %s);
            """

            updateBeginPosition = """
                UPDATE %s.procedures""" % (self.servicename)
            updateBeginPosition += """
                SET stime_prc=%s::TIMESTAMPTZ WHERE id_prc=%s
            """
            updateEndPosition = """
                UPDATE %s.procedures""" % (self.servicename)
            updateEndPosition += """
                SET etime_prc=%s::TIMESTAMPTZ WHERE id_prc=%s
            """

            id_prc = rows[0][0]
            bp = rows[0][3]
            bpu = False
            ep = rows[0][4]
            epu = False

            for observation in data:
                id_eti = conn.executeInTransaction(
                    insertEventTime, (
                        id_prc, observation[0]))

                for idx in range(0, len(rows)):
                    conn.executeInTransaction(
                        insertMeasure, (
                            int(id_eti[0][0]),  # id_eti
                            int(rows[idx][1]),  # id_pro
                            float(observation[(idx+1)])))

                if (bp is None) or (bp == '') or (
                        iso.parse_datetime(observation[0]) < bp):
                    bp = iso.parse_datetime(observation[0])
                    bpu = True

                if (ep is None) or (ep == '') or (
                        iso.parse_datetime(observation[0]) > ep):
                    ep = iso.parse_datetime(observation[0])
                    epu = True

            if bpu:
                conn.executeInTransaction(
                    updateBeginPosition, (bp.isoformat(), id_prc))

            if epu:
                conn.executeInTransaction(
                    updateEndPosition, (ep.isoformat(), id_prc))

            conn.commitTransaction()

            # self.setData(ret)
            self.setMessage("Thanks for data")

        except Exception as e:
            traceback.print_exc(file=sys.stderr)
            conn.rollbackTransaction()
            raise Exception(
                "Error in fast insert (%s): %s" % (type(e), e))