from datetime import datetime, timedelta
import pandas as pd
from pyoos.collectors.ioos.swe_sos import IoosSweSos

# convenience function to build record style time series representation
def flatten_element(p):
    rd = {'time':p.time}
    for m in p.members:
        rd[m['standard']] = m['value']
    return rd

"""
Explanation: https://www.wakari.io/sharing/bundle/emayorga/pyoos_ioos_sos_demo1
Using Pyoos to access Axiom 52North IOOS SOS "Stable Demo"
Examine the offerings; then query, parse and examine a "network offering" (all stations)
Use the same approach to access time series data from an ncSOS end point and a 52North IOOS SOS end point (the Axiom stable demo). ncSOS can only return one station in the response, while 52North SOS can return multiple stations when a network-offering request is made.
Emilio Mayorga, 2/12/2014 
(2/20/2014: Updated bundled Wakari environment to pyoos 0.6)
End of explanation
"""


url52n = 'http://ioossos.axiomalaska.com/52n-sos-ioos-stable/sos/kvp'
collector52n = IoosSweSos(url52n)
offerings52n = collector52n.server.offerings

# Examine the first offering
of0 = offerings52n[0]
of0.id, of0.name, of0.begin_position, of0.end_position, of0.observed_properties, of0.procedures

# Examine the second offering
of1 = offerings52n[1]
of1.id, of1.name, of1.begin_position, of1.end_position, of1.observed_properties, of1.procedures

vars(of1)

"""
Explanation: 52N IOOS SOS Stable Demo -- network offering (multi-station) data request
Create pyoos "collector" that connects to the SOS end point and parses GetCapabilities (offerings)
End of explanation
"""


# Use the network:test:all offering to query across all stations
# Set and apply filters, then "collect"
collector52n.start_time = of0.begin_position
collector52n.end_time   = of0.end_position
#collector52n.variables=of0.observed_properties   # 2 obsprops, each of a different feature type
# For now, query only the variable that returns timeSeries; pyoos can't handle timeSeriesProfile yet
collector52n.variables=['http://mmisw.org/ont/cf/parameter/air_temperature']
offeringname = ['urn:ioos:network:test:all']
respfrmt = 'text/xml; subtype="om/1.0.0/profiles/ioos_sos/1.0"'

obs52n=collector52n.collect(offerings=offeringname, responseFormat=respfrmt)
obs52n

# 'stations' should be a Paegan 'StationCollection' with list of Paegan 'Station' elements
stations=obs52n[0].feature
print 'Station Object:', type(stations)
print 'Feature Type:', obs52n[0].feature_type
print 'Number of station in StationCollection:', len(stations.elements)
# stations returned in the network offering response
stations.elements

# Examine one station; list its unique observed properties (variables) 
station52n_0 = stations.elements['urn:ioos:station:test:0']
station52n_0.get_unique_members()

# List and show one data value element
station52n_0.elements[0].time, station52n_0.elements[0].members

# Extract and parse units string
unitsraw = station52n_0.elements[0].members[0]['units']
units = unitsraw.split(':')[-1]
print unitsraw, '  |  ', units

"""
Explanation: Set up request filters (selections), issue "collect" request (GetObservation -- get time series data), and examine the response
End of explanation
"""


# First station
flattened52n_0 = map(flatten_element, station52n_0.elements)
n52n_0df=pd.DataFrame.from_records(flattened52n_0, index=['time'])
n52n_0df.head()

# A second station
station52n_5 = stations.elements['urn:ioos:station:test:5']
flattened52n_5 = map(flatten_element, station52n_5.elements)
n52n_5df=pd.DataFrame.from_records(flattened52n_5, index=['time'])

# Plot data from first station using plot method on DataFrame
# Note the datetime x-axis labels are much nicer here (pandas) 
# than on the next plot (bare matplotlib)
n52n_0df.plot(figsize(12,5))
ylabel(units);

# Joint plot of time series from two stations in the network response, using matplotlib
op = n52n_0df.columns[0]
plot(n52n_0df.index, n52n_0df[op], '-b',
     n52n_5df.index, n52n_5df[op], '-r')
ylabel(units)
legend([station52n_0.uid, station52n_5.uid]);

"""
Explanation: Read time series data for two stations, ingest into Pandas DataFrames, then create plots
End of explanation
"""


