def sos_observation_xml(url, version='1.0.0', xml=None, offerings=[], responseFormat=None, observedProperties=[], eventTime=None, feature=None, allProperties=False): """Return the XML from a SOS GetObservation request. Parameters ---------- url : string Full HTTP address of SOS version: string Version number of the SOS (e.g. 1.0.0) offerings : list selected offerings from SOS; defaults to all available responseFormat : string desire format for result data observedProperties : list filters results for selected properties from SOS; defaults to first one (unless allProperties is True) eventTime : string filters results for a specified instant or period. Use ISO format YYYY-MM-DDTHH:mm:ss+-HH Periods of time (start and end) are separated by "/"; e.g. 2009-06-26T10:00:00+01/2009-06-26T11:00:00+01 feature : string filters results for the ID of a feature_of_interest allProperties : boolean if allProperties is True, filters results for all properties (and ignores any items in the observedProperties) """ # GetCapabilites of SOS _sos = SensorObservationService(url, version=version or '1.0.0', xml=xml or None) # process any supplied offerings if offerings: for off in _sos.offerings: # look for matching IDs _offerings = [off for off in _sos.offerings if off.id in offerings] else: _offerings = [] # get offering IDs to be used offerings_objs = _offerings or _sos.offerings sos_offerings = [off.id for off in offerings_objs] responseFormat = responseFormat or offerings_objs[0].response_formats[0] if not allProperties: observedProperties = observedProperties or [offering.observed_properties[0]] else: observedProperties = offering.observed_properties eventTime = eventTime if feature: return _sos.get_observation( offerings=sos_offerings, responseFormat=responseFormat, observedProperties=observedProperties, eventTime=eventTime, FEATUREOFINTEREST=feature) else: return _sos.get_observation( offerings=sos_offerings, responseFormat=responseFormat, observedProperties=observedProperties, eventTime=eventTime)
def test_sos_20_bom_gov_au(): # Setup service = SensorObservationService(SERVICE_URL, version='2.0.0') id = service.identification # Check basic service metadata assert id.service == 'SOS' assert id.title == 'KISTERS KiWIS SOS2' assert id.keywords == [] assert service.provider.name == 'Provider Name' assert service.provider.contact.name == 'Name' assert service.provider.contact.position is None assert len(service.operations) == 5 assert service.get_operation_by_name('GetObservation').methods[0]['url'] == \ 'http://bom.gov.au/waterdata/services?datasource=0' response = service.get_observation( featureOfInterest='http://bom.gov.au/waterdata/services/stations/181.1', offerings=['http://bom.gov.au/waterdata/services/tstypes/Pat4_PC_1'], observedProperties=['http://bom.gov.au/waterdata/services/parameters/Water Course Discharge'], eventTime='om:phenomenonTime,2016-01-01T00:00:00+10/2016-03-05T00:00:00+10') # Process WaterML Response from owslib.etree import etree from owslib.swe.observation.sos200 import SOSGetObservationResponse from owslib.swe.observation.waterml2 import MeasurementTimeseriesObservation et = etree.fromstring(response) parsed_response = SOSGetObservationResponse(et) assert len(parsed_response.observations) > 0 for o in parsed_response.observations: assert isinstance(o, MeasurementTimeseriesObservation)
def syncvesk(): sensors = {} service = SensorObservationService(SOSURL, version=SOSVERSION) get_obs = service.get_operation_by_name('GetObservation') describe_sensor = service.get_operation_by_name('DescribeSensor') sensor_ids = describe_sensor.parameters['procedure']['values'] for sensor_id in sensor_ids: response = service.describe_sensor( outputFormat='http://www.opengis.net/sensorML/1.0.1', procedure=sensor_id) tr = etree.fromstring(response) element = tr.find('.//' + nspath_eval('sml:SensorML', namespaces)) ds = SensorML(element) name = ds.members[0].name sensors[sensor_id] = name offerings = [off.id for off in service.offerings] _observed_properties = list( set(op for off in service.offerings for op in off.observed_properties)) observed_properties = SOS_PARAMS.keys() end_time = datetime.now() # - timedelta(hours=120*10) start_time = end_time - timedelta(hours=12) temporalFilter = "om:phenomenonTime,{}/{}".format(start_time.isoformat(), end_time.isoformat()) response_format = 'application/json' _namespaces = "xmlns(om,http://www.opengis.net/om/2.0)" _response = service.get_observation(offerings=offerings, responseFormat=response_format, observedProperties=observed_properties, namespaces=_namespaces, temporalFilter=temporalFilter) response = json.loads(_response) for obs in response['observations']: location = obs['featureOfInterest']['name']['value'] _parameter = obs['observableProperty'] parameter = SOS_PARAMS.get(_parameter) timestamp = obs['phenomenonTime'] network = 'CNR' value = float(obs['result']['value']) rjson = { 'location': location, 'parameter': parameter, "timestamp": timestamp, 'network': network, "value": value } _write([rjson]) pass pass
class IoosSweSos(Collector): def __init__(self, url, xml=None): super(IoosSweSos,self).__init__() self.server = Sos(url, xml=xml) def metadata(self, **kwargs): callback = kwargs.get("feature_name_callback", None) or str kwargs['outputFormat'] = 'text/xml;subtype="sensorML/1.0.1"' responses = [] if self.features is not None: for feature in self.features: kwargs['procedure'] = callback(feature) responses.append(SensorML(self.server.describe_sensor(**kwargs))) return responses def setup_params(self, **kwargs): params = kwargs # TODO: BBOX needs to be implemented as an OGC Filter. # This page has a good example: http://opendap.co-ops.nos.noaa.gov/ioos-dif-sos/index.jsp # Click on "Collection" in the POST example to see what it should look like. # Requires changing from GET to POST... if self.bbox is not None: print "BBOX requests for IOOS SWE SOS services are not yet implemented" if self.start_time is not None: params["eventTime"] = self.start_time.strftime('%Y-%m-%dT%H:%M:%SZ') if self.end_time is not None: params["eventTime"] += "/%s" % self.end_time.strftime('%Y-%m-%dT%H:%M:%SZ') if self.variables is None or len(self.variables) < 1: raise ValueError("You must set a filter for at least one variable (observedProperty)") else: ops = ",".join(self.variables) if isinstance(ops, basestring): ops = [ops] params["observedProperties"] = ops return params def collect(self, **kwargs): kwargs["responseFormat"] = 'text/xml;subtype="om/1.0.0/profiles/ioos_sos/1.0"' return IoosGetObservation(self.raw(**kwargs)).feature def raw(self, **kwargs): params = self.setup_params(**kwargs) return self.server.get_observation(**params)
class NdbcSos(Collector): def __init__(self, **kwargs): super(NdbcSos,self).__init__() if kwargs.get('test') is True: url = 'http://sdftest.ndbc.noaa.gov/sos/server.php' else: url = 'http://sdf.ndbc.noaa.gov/sos/server.php' self.server = Sos(url) def get_metadata(self, **kwargs): response = self.server.describe_sensor(**kwargs) return IoosDescribeSensor(response) def get_describe_sensor_output_formats(self): return self.server.get_operation_by_name('DescribeSensor').parameters['outputFormat']['values'] def get_data(self, **kwargs): response = self.get_raw_data(**kwargs) return IoosSwe(response) def get_raw_data(self, **kwargs): return self.server.get_observation(**kwargs)
class CoopsSos(Collector): def __init__(self, **kwargs): super(CoopsSos,self).__init__() url = 'http://opendap.co-ops.nos.noaa.gov/ioos-dif-sos/SOS' self.server = Sos(url) def get_metadata(self, **kwargs): response = self.server.describe_sensor(**kwargs) return IoosDescribeSensor(response) def get_describe_sensor_output_formats(self): return self.server.get_operation_by_name('DescribeSensor').parameters['outputFormat']['values'] #def get_data(self, **kwargs): # response = self.get_raw_data(**kwargs) # return IoosDif(response) def get_raw_data(self, **kwargs): res = self.server.get_observation(**kwargs) if res[41:56] == "ExceptionReport": res = -1 return res
class CoopsSos(Collector): def __init__(self, **kwargs): super(CoopsSos, self).__init__() url = 'http://opendap.co-ops.nos.noaa.gov/ioos-dif-sos/SOS' self.server = Sos(url) def get_metadata(self, **kwargs): response = self.server.describe_sensor(**kwargs) return IoosDescribeSensor(response) def get_describe_sensor_output_formats(self): return self.server.get_operation_by_name( 'DescribeSensor').parameters['outputFormat']['values'] #def get_data(self, **kwargs): # response = self.get_raw_data(**kwargs) # return IoosDif(response) def get_raw_data(self, **kwargs): res = self.server.get_observation(**kwargs) if res[41:56] == "ExceptionReport": res = -1 return res
class NdbcSos(Collector): def __init__(self, **kwargs): super(NdbcSos, self).__init__() if kwargs.get('test') is True: url = 'http://sdftest.ndbc.noaa.gov/sos/server.php' else: url = 'http://sdf.ndbc.noaa.gov/sos/server.php' self.server = Sos(url) def get_metadata(self, **kwargs): response = self.server.describe_sensor(**kwargs) return IoosDescribeSensor(response) def get_describe_sensor_output_formats(self): return self.server.get_operation_by_name( 'DescribeSensor').parameters['outputFormat']['values'] def get_data(self, **kwargs): response = self.get_raw_data(**kwargs) return IoosSwe(response) def get_raw_data(self, **kwargs): return self.server.get_observation(**kwargs)
# <codecell> off.observed_properties # <codecell> # the get observation request below works. How can we recreate this using OWSLib? # http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/1211-A1H.cdf?service=SOS&version=1.0.0&request=GetObservation&responseFormat=text%2Fxml%3Bsubtype%3D%22om%2F1.0.0%22&offering=1211-A1H&observedProperty=u_1205&procedure=urn:ioos:station:gov.usgs:1211-A1H # <codecell> start = '2011-08-26T16:00:00Z' stop = '2011-08-26T17:00:00Z' response = usgs.get_observation(offerings=['9141wh-a'], responseFormat='text/xml;schema="om/1.0.0"', observedProperties=['Tx_1211'], procedure='urn:ioos:station:gov.usgs:9141wh-a', eventTime='%s/%s' % (start, stop)) # <codecell> #pdb.set_trace() start = '2011-08-26T16:00:00Z' stop = '2011-08-26T17:00:00Z' response = usgs.get_observation(offerings=['9141wh-a'], responseFormat='text/xml;schema="om/1.0.0"', observedProperties=['u_1205'], eventTime='%s/%s' % (start, stop)) # <codecell>
def main(): parsed_obs = dict() layerscount = 0 service = SensorObservationService(options['url'], version=options['version'], username=options['username'], password=options['password']) if any(value is True and key in ['o', 'v', 'p', 't'] for key, value in flags.items()): soslib.get_description(service, options, flags) soslib.check_missing_params(options['offering'], options['output']) if options['granularity'] != '': import grass.temporal as tgis tgis.init() seconds_granularity = int( tgis.gran_to_gran(options['granularity'], '1 second', True)) else: seconds_granularity = 1 target = soslib.get_target_crs() run_command('g.remove', 'f', type='vector', name=options['output']) new = VectorTopo(options['output']) for off in options['offering'].split(','): # TODO: Find better way than iteration (at best OWSLib upgrade) out = soslib.handle_not_given_options(service, off, options['procedure'], options['observed_properties'], options['event_time']) procedure, observed_properties, event_time = out if flags['s']: create_maps(_, off, _, new, _, _, service, target, _, procedure) else: try: obs = service.get_observation( offerings=[off], responseFormat=options['response_format'], observedProperties=observed_properties, procedure=procedure, eventTime=event_time, timeout=int(options['timeout']), username=options['username'], password=options['password']) except: # TODO: catch errors properly (e.g. timeout) grass.fatal('Request did not succeed!') try: if options['version'] in ['1.0.0', '1.0'] and str( options['response_format'] ) == 'text/xml;subtype="om/1.0.0"': for prop in observed_properties: parsed_obs.update( {prop: soslib.xml2geojson(obs, prop, flags['i'])}) elif str(options['response_format']) == 'application/json': for prop in observed_properties: parsed_obs.update( {prop: soslib.json2geojson(obs, prop)}) except AttributeError: if sys.version_info[0] >= 3: sys.tracebacklimit = None else: sys.tracebacklimit = 0 raise AttributeError( 'There is no data for at least one of your procedures, ' 'could you change the time parameter, observed ' 'properties, procedures or offerings') except ValueError as e: if sys.version_info[0] >= 3: sys.tracebacklimit = None else: sys.tracebacklimit = 0 raise e create_maps(parsed_obs, off, layerscount, new, seconds_granularity, event_time, service, target, observed_properties) layerscount += len(parsed_obs) return 0
off = sos.offerings[1] off.name # <codecell> off.response_formats # <codecell> off.observed_properties # <codecell> #pdb.set_trace() response = sos.get_observation(offerings=['A01'], responseFormat='text/xml;schema="om/1.0.0"', observedProperties=['significant_wave_height']) # <codecell> print response[0:1400] # <codecell> def parse_om_xml(response): # extract data and time from OM-XML response root = etree.fromstring(response) # root.findall(".//{%(om)s}Observation" % root.nsmap ) values = root.find(".//{%(swe)s}values" % root.nsmap ) date_value = array( [ (dt.datetime.strptime(d,"%Y-%m-%dT%H:%M:%SZ"),float(v)) for d,v in [l.split(',') for l in values.text.split()]] )
def main(): parsed_obs = dict() service = SensorObservationService(options['url'], version=options['version'], username=options['username'], password=options['password']) if any(value is True and key in ['o', 'v', 'p', 't'] for key, value in flags.iteritems()): get_description(service, options, flags) if options['offering'] == '' or options['output'] == '': if sys.version >= (3, 0): sys.tracebacklimit = None else: sys.tracebacklimit = 0 raise AttributeError( "You have to define any flags or use 'output' and 'offering' " "parameters to get the data") if options['granularity'] != '': import grass.temporal as tgis tgis.init() secondsGranularity = int( tgis.gran_to_gran(options['granularity'], '1 second', True)) else: secondsGranularity = 1 if options['resolution'] == '': resolution = None else: resolution = float(options['resolution']) if options['bbox'] != '': bbox = options['bbox'].split(',') run_command('g.region', n=float(bbox[0]), e=float(bbox[1]), s=float(bbox[2]), w=float(bbox[3]), res=resolution) else: grass.warning('You have not setted the bounding box. Bounding box will' ' be automatically based on procedure geometries for ' 'every map.') for off in options['offering'].split(','): # TODO: Find better way than iteration (at best OWSLib upgrade) procedure, observed_properties, event_time = handle_not_given_options( service, off, options['procedure'], options['observed_properties'], options['event_time']) event_time = 'T'.join(event_time.split(' ')) obs = service.get_observation( offerings=[off], responseFormat=options['response_format'], observedProperties=[observed_properties], procedure=procedure, eventTime=event_time, username=options['username'], password=options['password']) try: if options['version'] in ['1.0.0', '1.0'] and \ str(options['response_format']) == 'text/xml;subtype="om/1.0.0"': for property in observed_properties.split(','): parsed_obs.update({property: xml2geojson(obs, property)}) elif str(options['response_format']) == 'application/json': for property in observed_properties.split(','): parsed_obs.update({property: json2geojson(obs, property)}) except AttributeError: if sys.version >= (3, 0): sys.tracebacklimit = None else: sys.tracebacklimit = 0 raise AttributeError('There is no data for at least one of your ' 'procedures, could you change the time ' 'parameter, observed properties, ' 'procedures or offerings') create_maps(parsed_obs, off, secondsGranularity, resolution) return 0
class IoosSweSos(Collector): def __init__(self, url, xml=None): super(IoosSweSos, self).__init__() self.server = Sos(url, xml=xml) def metadata(self, output_format=None, feature_name_callback=None, **kwargs): """ Gets SensorML objects for all procedures in your filtered features. You should override the default output_format for servers that do not respond properly. """ callback = feature_name_callback or str if output_format is None: output_format = 'text/xml; subtype="sensorML/1.0.1/profiles/ioos_sos/1.0"' responses = [] if self.features is not None: for feature in self.features: ds_kwargs = kwargs.copy() ds_kwargs.update({ 'outputFormat': output_format, 'procedure': callback(feature) }) responses.append( SensorML(self.server.describe_sensor(**ds_kwargs))) return responses def metadata_plus_exceptions(self, output_format=None, feature_name_callback=None, **kwargs): """ Gets SensorML objects for all procedures in your filtered features. Return two dictionaries for service responses keyed by 'feature': responses: values are SOS DescribeSensor response text response_failures: values are exception text content furnished from ServiceException, ExceptionReport You should override the default output_format for servers that do not respond properly. """ callback = feature_name_callback or str if output_format is None: output_format = 'text/xml; subtype="sensorML/1.0.1/profiles/ioos_sos/1.0"' responses = {} response_failures = {} if self.features is not None: for feature in self.features: ds_kwargs = kwargs.copy() ds_kwargs.update({ 'outputFormat': output_format, 'procedure': callback(feature) }) try: responses[feature] = (SensorML( self.server.describe_sensor(**ds_kwargs))) except (ServiceException, ExceptionReport) as e: response_failures[feature] = str(e) return (responses, response_failures) def setup_params(self, **kwargs): params = kwargs if self.bbox is not None: params["featureOfInterest"] = "BBOX:%s,%s,%s,%s" % ( self.bbox[0], self.bbox[1], self.bbox[2], self.bbox[3]) if self.start_time is not None: params["eventTime"] = self.start_time.strftime( '%Y-%m-%dT%H:%M:%SZ') if self.end_time is not None: params["eventTime"] += "/%s" % self.end_time.strftime( '%Y-%m-%dT%H:%M:%SZ') if self.variables is None or len(self.variables) < 1: raise ValueError( "You must set a filter for at least one variable (observedProperty)" ) else: ops = ",".join(self.variables) if isinstance(ops, string_types): ops = [ops] params["observedProperties"] = ops return params def collect(self, **kwargs): # there is an unfortunate difference in how 52N and ncSOS handle the response format. # 52N expects subtype, ncSOS expects schema. # consult the observed properties and getcaps to figure out which should be used if none passed if 'responseFormat' not in kwargs: # iterate offerings and see if we need to change to subtype off_dict = {off.name: off for off in self.server.offerings} response_format = None for offering in kwargs.get('offerings', []): if offering not in off_dict: continue ioos_formats = [ rf for rf in off_dict[offering].response_formats if 'ioos_sos/1.0' in rf ] if not len(ioos_formats): raise Exception( "No ioos_sos/1.0 response format found for offering {}" .format(offering)) if response_format != ioos_formats[0]: response_format = ioos_formats[0] kwargs["responseFormat"] = response_format return IoosGetObservation(self.raw(**kwargs)).observations def raw(self, **kwargs): params = self.setup_params(**kwargs) return self.server.get_observation(**params)
# <codecell> off.observed_properties # <codecell> # the get observation request below works. How can we recreate this using OWSLib? # http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/1211-A1H.cdf?service=SOS&version=1.0.0&request=GetObservation&responseFormat=text%2Fxml%3Bsubtype%3D%22om%2F1.0.0%22&offering=1211-A1H&observedProperty=u_1205&procedure=urn:ioos:station:gov.usgs:1211-A1H # <codecell> start = '2011-08-26T16:00:00Z' stop = '2011-08-26T17:00:00Z' response = usgs.get_observation(offerings=['9141wh-a'], responseFormat='text/xml;schema="om/1.0.0"', observedProperties=['Tx_1211'], procedure='urn:ioos:station:gov.usgs:9141wh-a', eventTime='%s/%s' % (start,stop)) # <codecell> #pdb.set_trace() start = '2011-08-26T16:00:00Z' stop = '2011-08-26T17:00:00Z' response = usgs.get_observation(offerings=['9141wh-a'], responseFormat='text/xml;schema="om/1.0.0"', observedProperties=['u_1205'], eventTime='%s/%s' % (start,stop)) # <codecell>
def main(): parsed_obs = dict() service = SensorObservationService(options['url'], version=options['version'], username=options['username'], password=options['password']) if any(value is True and key in ['o', 'v', 'p', 't'] for key, value in flags.iteritems()): get_description(service, options, flags) if options['offering'] == '' or options['output'] == '': if sys.version >= (3, 0): sys.tracebacklimit = None else: sys.tracebacklimit = 0 raise AttributeError("You have to define any flags or use 'output' and" " 'offering' parameters to get the data") if options['granularity'] != '': import grass.temporal as tgis tgis.init() secondsGranularity = int( tgis.gran_to_gran(options['granularity'], '1 second', True)) else: secondsGranularity = 1 for off in options['offering'].split(','): # TODO: Find better way than iteration (at best OWSLib upgrade) procedure, observed_properties, event_time = handle_not_given_options( service, off, options['procedure'], options['observed_properties'], options['event_time']) event_time = 'T'.join(event_time.split(' ')) obs = service.get_observation( offerings=[off], responseFormat=options['response_format'], observedProperties=observed_properties, procedure=procedure, eventTime=event_time, username=options['username'], password=options['password']) try: if options['version'] in ['1.0.0', '1.0'] and str( options['response_format'] ) == 'text/xml;subtype="om/1.0.0"': for prop in observed_properties: parsed_obs.update({prop: xml2geojson(obs, prop)}) elif str(options['response_format']) == 'application/json': for prop in observed_properties: parsed_obs.update({prop: json2geojson(obs, prop)}) except AttributeError: if sys.version >= (3, 0): sys.tracebacklimit = None else: sys.tracebacklimit = 0 raise AttributeError('There is no data for at least one of your ' 'procedures, could you change the time ' 'parameter, observed properties, ' 'procedures or offerings') create_maps(parsed_obs, off, secondsGranularity) return 0
off = usgs.offerings[1] off.name # <codecell> off.response_formats # <codecell> off.observed_properties # <codecell> #pdb.set_trace() response = usgs.get_observation(offerings=['2651-A'], responseFormat='text/xml;subtype="om/1.0.0"', observedProperties=['http://mmisw.org/ont/cf/parameter/air_temperature']) # <codecell> print response[0:2000] # <codecell> def parse_om_xml(response): # extract data and time from OM-XML response root = etree.fromstring(response) # root.findall(".//{%(om)s}Observation" % root.nsmap ) values = root.find(".//{%(swe)s}values" % root.nsmap ) date_value = np.array( [ (dt.datetime.strptime(d,"%Y-%m-%dT%H:%M:%SZ"),float(v)) for d,v in [l.split(',') for l in values.text.split()]] )
def main(): parsed_obs = dict() service = SensorObservationService(options['url'], version=options['version'], username=options['username'], password=options['password']) if any(value is True and key in ['o', 'v', 'p', 't'] for key, value in flags.items()): soslib.get_description(service, options, flags) soslib.check_missing_params(options['offering'], options['output']) if options['granularity'] != '': import grass.temporal as tgis tgis.init() seconds_granularity = int( tgis.gran_to_gran(options['granularity'], '1 second', True)) else: seconds_granularity = 1 if options['resolution'] == '': a = grass.read_command('g.region', flags='gf') resolution = float(a.split('nsres=')[1].split(' ')[0]) run_command('g.message', flags='w', message='No resolution was setted. Using the resolution ' '{} (nres of your current setting).'.format(resolution)) else: resolution = float(options['resolution']) if options['bbox'] != '': bbox = options['bbox'].split(',') run_command('g.region', n=float(bbox[0]), e=float(bbox[1]), s=float(bbox[2]), w=float(bbox[3]), res=resolution) else: grass.warning('You have not setted the bounding box. Bounding box will' ' be automatically based on procedure geometries for ' 'every map.') target = soslib.get_target_crs() for off in options['offering'].split(','): # TODO: Find better way than iteration (at best OWSLib upgrade) out = soslib.handle_not_given_options(service, off, options['procedure'], options['observed_properties'], options['event_time']) procedure, observed_properties, event_time = out if flags['s']: create_maps(_, off, _, resolution, _, service, target, procedure) else: try: obs = service.get_observation( offerings=[off], responseFormat=options['response_format'], observedProperties=observed_properties, procedure=procedure, eventTime=event_time, username=options['username'], password=options['password']) except: # TODO: catch errors properly (e.g. timeout) grass.fatal('Request did not succeed!') try: if options['version'] in ['1.0.0', '1.0'] and \ options['response_format'] == 'text/xml;subtype="om/1.0.0"': for prop in observed_properties: parsed_obs.update( {prop: soslib.xml2geojson(obs, prop)}) elif str(options['response_format']) == 'application/json': for prop in observed_properties: parsed_obs.update( {prop: soslib.json2geojson(obs, prop)}) except AttributeError: if sys.version_info[0] >= 3: sys.tracebacklimit = None else: sys.tracebacklimit = 0 raise AttributeError( 'There is no data for at least one of your procedures, ' 'could you change the time parameter, observed ' 'properties, procedures or offerings') except ValueError as e: if sys.version_info[0] >= 3: sys.tracebacklimit = None else: sys.tracebacklimit = 0 raise e create_maps(parsed_obs, off, seconds_granularity, resolution, event_time, service, target) return 0
def getSeriesSOS200(sos_url, station_number, offering_number, property_number, starting_time_string, ending_time_string): dates = [] values = [] get_cap_resp1 = requests.get(sos_url + '?REQUEST=GetCapabilities&SERVICE=SOS&ACCEPTVERSIONS=2.0.0', stream=True) sos1 = SensorObservationService(None,xml=get_cap_resp1.content, version="2.0.0") ####### ####### DEFINING REQUEST PARAMETERS ####### WGS84bbox_set=set(WGS84conversion(off) for off in sos1.offerings) WGS84bbox_list=list(WGS84bbox_set) # selecting STATION station = WGS84bbox_list[station_number] # selecting OFFERINGS off = GetOfferingsList(sos1, station).offering_list[offering_number] offerings = [off.id] selected_offering = off.id # selecting OBSERVED PROPERTIES prop = off.observed_properties[property_number] observedProperties = [prop] # selecting FORMAT " omFormat = 'http://www.opengis.net/om/2.0' waterml2Format = 'http://www.opengis.net/waterml/2.0' jsonFormat = 'application/json' # namespaces for request namespaces = 'xmlns(om,http://www.opengis.net/om/2.0)' # selecting TIMEPERIOD user_starting_time = dateutil.parser.parse(starting_time_string) user_ending_time = dateutil.parser.parse(ending_time_string) ####### ####### REQUEST PARAMETERS ARE NOW DEFINED ####### period_starting_time = user_starting_time iso_period_starting_time = period_starting_time.isoformat() period_ending_time = period_starting_time + datetime.timedelta(seconds = 43200) unit = '' while period_ending_time <= user_ending_time: iso_period_starting_time = period_starting_time.isoformat() iso_period_ending_time = period_ending_time.isoformat() event_time = "om:phenomenonTime,"+str(iso_period_starting_time)+"/"+str(iso_period_ending_time) response1 = None while response1 is None: try: response1 = sos1.get_observation(offerings=offerings, responseFormat=omFormat, observedProperties=observedProperties, timeout=600, namespaces=namespaces, eventTime=event_time) except: pass xml_tree1 = etree.fromstring(response1) parsed_response1 = owslib.swe.observation.sos200.SOSGetObservationResponse(xml_tree1) unit = parsed_response1.observations[0].get_result().uom for i, obs in enumerate(parsed_response1.observations): if obs.resultTime is not None and obs.get_result().value is not None: dates.append(obs.resultTime) values.append(obs.get_result().value) # print ">> obsr [%d]: "%i, obs.get_result().value, obs.get_result().uom, obs.resultTime, type(obs) else: pass period_starting_time += datetime.timedelta(seconds = 43200) period_ending_time += datetime.timedelta(seconds = 43200) print period_ending_time, user_ending_time return dates, values, selected_offering, prop, unit
off = usgs.offerings[1] off.name # <codecell> off.response_formats # <codecell> off.observed_properties # <codecell> #pdb.set_trace() response = usgs.get_observation(offerings=['2651-A'], responseFormat='text/xml;schema="om/1.0.0"', observedProperties=['T_20'], procedure='urn:ioos:sensor:gov.usgs.cmgp:2651-A') # <codecell> print response[0:2000] # <codecell> def parse_om_xml(response): # extract data and time from OM-XML response root = etree.fromstring(response) # root.findall(".//{%(om)s}Observation" % root.nsmap ) values = root.find(".//{%(swe)s}values" % root.nsmap ) date_value = np.array( [ (dt.datetime.strptime(d,"%Y-%m-%dT%H:%M:%SZ"),float(v)) for d,v in [l.split(',') for l in values.text.split()]] )
# In[52]: off.procedures # In[53]: # the get observation request below works. How can we recreate this using OWSLib? # http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/1211-A1H.cdf?service=SOS&version=1.0.0&request=GetObservation&responseFormat=text%2Fxml%3Bsubtype%3D%22om%2F1.0.0%22&offering=1211-A1H&observedProperty=u_1205&procedure=urn:ioos:station:gov.usgs:1211-A1H # In[54]: #pdb.set_trace() response = usgs.get_observation(offerings=['1211-AA'], responseFormat='text/xml;subtype="om/1.0.0"', observedProperties=['http://mmisw.org/ont/cf/parameter/eastward_sea_water_velocity'], procedure='urn:ioos:station:gov.usgs:1211-AA') # In[55]: print(response[0:4000]) # In[56]: # usgs woods hole ADCP data # url='http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/9111aqd-a.nc' # adcp = SensorObservationService(url)
class IoosSweSos(Collector): def __init__(self, url, xml=None): super(IoosSweSos, self).__init__() self.server = Sos(url, xml=xml) def metadata(self, output_format=None, feature_name_callback=None, **kwargs): """ Gets SensorML objects for all procedures in your filtered features. You should override the default output_format for servers that do not respond properly. """ callback = feature_name_callback or str if output_format is None: output_format = 'text/xml; subtype="sensorML/1.0.1/profiles/ioos_sos/1.0"' responses = [] if self.features is not None: for feature in self.features: ds_kwargs = kwargs.copy() ds_kwargs.update({'outputFormat': output_format, 'procedure' : callback(feature)}) responses.append(SensorML(self.server.describe_sensor(**ds_kwargs))) return responses def setup_params(self, **kwargs): params = kwargs if self.bbox is not None: params["featureOfInterest"] = "BBOX:%s,%s,%s,%s" % (self.bbox[0], self.bbox[1], self.bbox[2], self.bbox[3]) if self.start_time is not None: params["eventTime"] = self.start_time.strftime('%Y-%m-%dT%H:%M:%SZ') if self.end_time is not None: params["eventTime"] += "/%s" % self.end_time.strftime('%Y-%m-%dT%H:%M:%SZ') if self.variables is None or len(self.variables) < 1: raise ValueError("You must set a filter for at least one variable (observedProperty)") else: ops = ",".join(self.variables) if isinstance(ops, basestring): ops = [ops] params["observedProperties"] = ops return params def collect(self, **kwargs): # there is an unfortunate difference in how 52N and ncSOS handle the response format. # 52N expects subtype, ncSOS expects schema. # consult the observed properties and getcaps to figure out which should be used if none passed if 'responseFormat' not in kwargs: # iterate offerings and see if we need to change to subtype off_dict = {off.name : off for off in self.server.offerings} response_format = None for offering in kwargs.get('offerings', []): if offering not in off_dict: continue ioos_formats = [rf for rf in off_dict[offering].response_formats if 'ioos_sos/1.0' in rf] if not len(ioos_formats): raise StandardError("No ioos_sos/1.0 response format found for offering %s" % offering) if response_format != ioos_formats[0]: response_format = ioos_formats[0] kwargs["responseFormat"] = response_format return IoosGetObservation(self.raw(**kwargs)).observations def raw(self, **kwargs): params = self.setup_params(**kwargs) return self.server.get_observation(**params)
# In[52]: off.procedures # In[53]: # the get observation request below works. How can we recreate this using OWSLib? # http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/1211-A1H.cdf?service=SOS&version=1.0.0&request=GetObservation&responseFormat=text%2Fxml%3Bsubtype%3D%22om%2F1.0.0%22&offering=1211-A1H&observedProperty=u_1205&procedure=urn:ioos:station:gov.usgs:1211-A1H # In[54]: #pdb.set_trace() response = usgs.get_observation( offerings=['1211-AA'], responseFormat='text/xml;subtype="om/1.0.0"', observedProperties=[ 'http://mmisw.org/ont/cf/parameter/eastward_sea_water_velocity' ], procedure='urn:ioos:station:gov.usgs:1211-AA') # In[55]: print(response[0:4000]) # In[56]: # usgs woods hole ADCP data # url='http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/9111aqd-a.nc' # adcp = SensorObservationService(url) # In[57]: