Accessing ncSOS with OWSLib


In [1]:
from owslib.sos import SensorObservationService
import pdb
from owslib.etree import etree
import pandas as pd
import datetime as dt

In [28]:
# usgs woods hole
# buoy data (single current meter)
url='http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/1211-A1H.cdf'
url='http://www.neracoos.org/cgi-bin/sos/V1.0/oostethys_sos.cgi?service=SOS'
sos = SensorObservationService(url)
contents = sos.contents

In [29]:
sos.contents


Out[29]:
{'44039': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fa1d90>,
 '44060': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fa1e10>,
 '44098': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fa1ed0>,
 'A01': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fa1cd0>,
 'ALL_PLATFORMS': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fa1bd0>,
 'ARTG': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fa1ad0>,
 'B01': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fa1f90>,
 'CDIP154': <owslib.swe.observation.sos100.SosObservationOffering at 0x2e53c90>,
 'CDIP176': <owslib.swe.observation.sos100.SosObservationOffering at 0x2e53c10>,
 'CML': <owslib.swe.observation.sos100.SosObservationOffering at 0x2580ed0>,
 'CO2': <owslib.swe.observation.sos100.SosObservationOffering at 0x2580d90>,
 'D02': <owslib.swe.observation.sos100.SosObservationOffering at 0x25801d0>,
 'E01': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac0d0>,
 'E02': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac190>,
 'EXRX': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac250>,
 'F01': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac310>,
 'F02': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac3d0>,
 'GREAT_BAY': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac490>,
 'I01': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac550>,
 'LDLC3': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac610>,
 'M01': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac6d0>,
 'MDS02': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac790>,
 'N01': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac850>,
 'SMB-MO-01': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac910>,
 'SMB-MO-04': <owslib.swe.observation.sos100.SosObservationOffering at 0x2fac9d0>,
 'SMB-MO-05': <owslib.swe.observation.sos100.SosObservationOffering at 0x2faca90>,
 'WLIS': <owslib.swe.observation.sos100.SosObservationOffering at 0x2facb50>}

In [30]:
off = sos.offerings[1]
off.name


Out[30]:
'44060'

In [31]:
off.response_formats


Out[31]:
['text/xml; subtype="om/1.0.0"']

In [32]:
off.observed_properties


Out[32]:
['urn:ogc:def:phenomenon:mmisw.org:cf:wind_speed',
 'urn:ogc:def:phenomenon:mmisw.org:cf:wind_gust',
 'urn:ogc:def:phenomenon:mmisw.org:cf:wind_from_direction',
 'urn:ogc:def:phenomenon:mmisw.org:cf:sea_water_temperature',
 'urn:ogc:def:phenomenon:mmisw.org:cf:sea_level_pressure',
 'urn:ogc:def:phenomenon:mmisw.org:cf:air_temperature']

In [33]:
# 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 [34]:
#pdb.set_trace()
response = sos.get_observation(offerings=['A01'],
                                 responseFormat='text/xml;schema="om/1.0.0"',
                                 observedProperties=['wind_speed'])

In [35]:
sos.get_observation?

In [13]:
print response


<?xml version="1.0"?>
<om:ObservationCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:om="http://www.opengis.net/om/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:swe="http://www.opengis.net/swe/1.0.1" xsi:schemaLocation="http://www.opengis.net/om/1.0 http://schemas.opengis.net/om/1.0.0/om.xsd" gml:id="NERACOOS_sensor">

  <gml:description>WIND_SPEED measurements from Univ. of Maine A01</gml:description>
  <gml:name>WIND_SPEED measurements from Univ. of Maine A01</gml:name>
  <gml:boundedBy>
      <gml:Envelope srsName="urn:ogc:def:crs:EPSG:6.5:4326">
<!-- overwrite these with your actual offering ROI -->
          <gml:lowerCorner>42.5232 -70.5655</gml:lowerCorner>
          <gml:upperCorner>42.5232 -70.5655</gml:upperCorner>
      </gml:Envelope>
  </gml:boundedBy>
  <om:member>
      <om:Observation gml:id="NERACOOS_A01">
          <gml:description>WIND_SPEED measurements from Univ. of Maine A01</gml:description>
          <gml:name>WIND_SPEED measurements from Univ. of Maine A01</gml:name>
          <gml:boundedBy>
              <gml:Envelope srsName="urn:ogc:def:crs:EPSG:6.5:4326">
                  <!-- overwrite these with your actual offering  ROI -->
                  <gml:lowerCorner>42.5232 -70.5655</gml:lowerCorner>
                  <gml:upperCorner>42.5232 -70.5655</gml:upperCorner>
              </gml:Envelope>
          </gml:boundedBy>     
          <!-- Observation time -->
          <om:samplingTime><gml:TimeInstant xsi:type="gml:TimeInstantType"><gml:timePosition>2014-02-10T23:00:00Z</gml:timePosition></gml:TimeInstant></om:samplingTime>
          <!-- Sensor description (SensorML) -->
          <om:procedure xlink:href="urn:ogc:neracoos.org:def:source:mooring:A01"/>
         <!-- Observed Property, can be multiple -->
         <om:observedProperty>
         <swe:CompositePhenomenon dimension="1" gml:id="BUOY_OBSERVABLES">
               <gml:name>Buoy Observables</gml:name>
          <swe:component xlink:href="urn:ogc:def:phenomenon:mmisw.org:cf:wind_speed"/></swe:CompositePhenomenon>
          </om:observedProperty>
          <om:featureOfInterest xlink:href="urn:ogc:def:object:feature:FOI_A01"/>
           <!-- Result Structure, Encoding, and Data -->
           <om:result>
               <swe:DataArray>
                   <swe:elementCount>
                       <swe:Count>
                             <swe:value>1</swe:value>  <!-- Number of Records here -->
                         </swe:Count>
                     </swe:elementCount>
                     <swe:elementType name="A01Observations">
                         <swe:DataRecord>
                            <swe:field name="PlatformName">
                                <swe:Quantity definition="urn:mmisw.org#platform"/>
                            </swe:field>
                            <!--  Time -->
                            <swe:field name="time">
                                <swe:Time definition="urn:ogc:phenomenon:time:iso8601"/>
                            </swe:field>
                            <swe:field name="latitude">
                                <swe:Quantity definition="urn:ogc:phenomenon:latitude:wgs84">
                                    <swe:uom code="deg"/>
                                </swe:Quantity>
                            </swe:field>
                            <swe:field name="longitude">
                                <swe:Quantity definition="urn:ogc:phenomenon:longitude:wgs84">
                                     <swe:uom code="deg"/> 
                                </swe:Quantity>
                            </swe:field>
                            <swe:field name="depth">
                                     <swe:Quantity definition="http://mmisw.org/cf#depth" referenceFrame="urn:ogc:def:crs:EPSG:6.15:5113">
                                     <swe:uom code="m"/>
                                 </swe:Quantity>
                            </swe:field>
                            <!--  Observable fields -->
                            
                         <swe:field name="observedProperty1">
                                <swe:Quantity definition="urn:ogc:def:phenomenon:mmisw.org:cf:wind_speed">
                                    <swe:uom code="m.s-1"/>                    
                                </swe:Quantity>
                            </swe:field></swe:DataRecord>
                     </swe:elementType>
                     <swe:encoding>
                         <swe:TextBlock blockSeparator=" " decimalSeparator="." tokenSeparator=","/>
                     </swe:encoding>
                     <swe:values>A01,2014-02-10T23:00:00Z,42.5232,-70.5655,-4,7.92999982833862</swe:values>
                 </swe:DataArray>
             </om:result>
         </om:Observation>
     </om:member>
</om:ObservationCollection>


In [15]:
root = etree.fromstring(response)
values = root.find(".//{%(swe)s}values" % root.nsmap )

In [23]:
values.text.split()


Out[23]:
['A01,2014-02-10T23:00:00Z,42.5232,-70.5655,-4,7.92999982833862']

In [25]:
# usgs woods hole ADCP data
# url='http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/9111aqd-a.nc'
# adcp = SensorObservationService(url)

In [24]:
# need to figure out how to write something similar to this for oostethys
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 )
    dv = array( [ (b,dt.datetime.strptime(d,"%Y-%m-%dT%H:%M:%SZ"),float(lat),float(lon),float(dep),float(v))
            for b,d,lat,lon,dep,v in [l.split(',') for l in values.text.split()]] )
    return dv

In [25]:
dv = parse_om_xml(response)

In [26]:
dv


Out[26]:
array([['A01', datetime.datetime(2014, 2, 10, 23, 0), 42.5232, -70.5655,
        -4.0, 7.92999982833862]], dtype=object)

In [28]:
ts = pd.Series(data,index=time)

In [29]:
ts.plot(figsize(12,4))


Out[29]:
<matplotlib.axes.AxesSubplot at 0x2ffd990>

In [30]:
''' this doesn't work
# Try adding a time range to the getobs request:

start = '1976-12-302T00:00:00Z'
stop = '1977-01-07T00:00:00Z'

response = usgs.get_observation(offerings=['1211-A1H'],
                                 responseFormat='text/xml;subtype="om/1.0.0"',
                                 observedProperties=['u_1205'],
                                 procedure='urn:ioos:station:gov.usgs:1211-A1H',
                                 eventTime='%s/%s' % (start,stop)
''';

In [30]: