Skip to content

Commit

Permalink
added apis of NDBC and NOAA
Browse files Browse the repository at this point in the history
  • Loading branch information
roeldegoede committed Nov 3, 2023
1 parent 18fa9db commit 5382026
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 28 deletions.
20 changes: 17 additions & 3 deletions cht_observations/_ndbc.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
from cht_observations.observation_stations import StationSource
from NDBC.NDBC import DataBuoy

from cht_observations import utils

class Source(StationSource):
def __init__(self):
self.db = DataBuoy()

def list_stations(self):
pass
def get_active_stations(self):
url = "https://www.ndbc.noaa.gov/activestations.xml"
obj = utils.xml2obj(url)
station_list = []
for station in obj.station:
station_list.append({"name": station.name,
"id": station.id,
"lon": float(station.lon),
"lat": float(station.lat)})
self.active_stations = station_list
return station_list

def get_meta_data(self, id):
self.db.set_station_id(id)
return getattr(self.db, "station_info", None)
try:
meta_data = self.db.station_info
except:
meta_data = None
return meta_data

def get_data(self, id, variable=None):
pass
56 changes: 50 additions & 6 deletions cht_observations/_noaa_coops.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,64 @@
from cht_observations.observation_stations import StationSource
from noaa_coops import Station
from noaa_coops import Station, get_stations_from_bbox

import requests

class Source(StationSource):
def __init__(self):
pass

def list_stations(self):
pass
def get_active_stations(self):
data_url = "https://api.tidesandcurrents.noaa.gov/mdapi/prod/webapi/stations.json"
response = requests.get(data_url)
json_dict = response.json()

station_list = []
for station_dict in json_dict["stations"]:
station_list.append({"name": station_dict["name"],
"id": station_dict["id"],
"lon": float(station_dict["lng"]),
"lat": float(station_dict["lat"])})

self.active_stations = station_list
return station_list

def get_meta_data(self, id):
pass
station = Station(id=id)
meta_data = station.metadata
return meta_data

def get_data(
self, station_id, tstart, tstop, varname="water_level", units="SI", datum="MSL"
self,
id:int,
tstart,
tstop,
varname:str ="water_level",
units:str="SI",
datum:str="MSL"
):
""""
Get data from NOAA COOPS
Parameters
----------
id : str
Station ID
tstart : datetime
Start time
tstop : datetime
Stop time
varname : str
Variable name
units : str
Units
datum : str
Datum, e.g. MSL or NAVD
Returns
-------
df : pandas.DataFrame
Data frame with data
""""
t0_string = tstart.strftime("%Y%m%d")
t1_string = tstop.strftime("%Y%m%d")

Expand All @@ -24,7 +68,7 @@ def get_data(
if units == "SI":
units = "metric"

station = Station(id=station_id)
station = Station(id=id)
df = station.get_data(
begin_date=t0_string,
end_date=t1_string,
Expand Down
39 changes: 20 additions & 19 deletions cht_observations/observation_stations.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
"""
Example:
import datetime
import cht_observations.observation_stations as obs
coops = obs.source("noaa_coops")
t0 = datetime.datetime(2015, 1, 1)
t1 = datetime.datetime(2015, 1, 10)
df = coops.get_data("9447130", t0, t1)
"""

import geopandas as gpd
import pandas as pd
import shapely

class StationSource:
def __init__(self):
pass
self.active_stations = []

def list_stations(self):
def get_active_stations(self):
pass

def get_meta_data(self):
Expand All @@ -25,13 +16,23 @@ def get_meta_data(self):
def get_data(self):
pass

def gdf(self):
gdf_list = []
# Loop through points
for station in self.active_stations:
name = station["name"]
x = station["lon"]
y = station["lat"]
id = station["id"]
point = shapely.geometry.Point(x, y)
d = {"id": id, "name": name, "geometry": point}
gdf_list.append(d)
return gpd.GeoDataFrame(gdf_list, crs=4326)

def source(name):
if name == "ndbc":
from cht_observations._ndbc import Source

from ._ndbc import Source
return Source()
elif name == "noaa_coops":
from cht_observations._noaa_coops import Source

return Source()
from ._noaa_coops import Source
return Source()
57 changes: 57 additions & 0 deletions cht_observations/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from datetime import datetime

import urllib
import xml.etree.ElementTree as ET

def xml2py(node):

name = node.tag

pytype = type(name, (object, ), {})
pyobj = pytype()

for attr in node.attrib.keys():
setattr(pyobj, attr, node.get(attr))

if node.text and node.text.strip() != '' and node.text.strip() != '\n':
setattr(pyobj, 'text', node.text)
setattr(pyobj, 'value', node.text)
# Convert
if node.attrib:
if "type" in node.attrib.keys():
if node.attrib["type"] == "float":
lst = node.text.split(",")
if len(lst)==1:
pyobj.value = float(node.text)
else:
float_list = [float(s) for s in lst]
pyobj.value = float_list
elif node.attrib["type"] == "int":
if "," in node.text:
pyobj.value = [int(s) for s in node.text.split(',')]
else:
pyobj.value = int(node.text)
elif node.attrib["type"] == "datetime":
pyobj.value = datetime.strptime(node.text,
'%Y%m%d %H%M%S')

for cn in node:
if not hasattr(pyobj, cn.tag):
setattr(pyobj, cn.tag, [])
getattr(pyobj, cn.tag).append(xml2py(cn))

return pyobj

def xml2obj(file_name):
"""Converts an xml file to a python object. """

if file_name[0:4] == "http":
with urllib.request.urlopen(file_name) as f:
tree = ET.parse(f)
xml_root = tree.getroot()
else:
xml_root = ET.parse(file_name).getroot()
obj = xml2py(xml_root)

return obj

11 changes: 11 additions & 0 deletions examples/example_noaa_coops.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""
Example: NOAA COOPS
"""

import datetime
import cht_observations.observation_stations as obs

coops = obs.source("noaa_coops")
t0 = datetime.datetime(2015, 1, 1)
t1 = datetime.datetime(2015, 1, 10)
df = coops.get_data("9447130", t0, t1)

0 comments on commit 5382026

Please sign in to comment.