-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5da3c2d
commit 33e3be9
Showing
5 changed files
with
153 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,27 @@ | ||
import importlib | ||
import glob | ||
|
||
from base_formatter import EDR_formatter | ||
|
||
def get_formatters(): | ||
|
||
def get_EDR_formatters() -> dict: | ||
""" | ||
This method should grab all available formatters and make them reachable in a dict | ||
This way we can dynamicly grab all available formats and skip configuring this. | ||
Should aliases be made available, and how do one make formatters present in openapi doc? | ||
""" | ||
pass | ||
# Get all .py files in local folder, ignore files that start with _ | ||
formatter_files = [i.strip(".py") for i in glob.glob("[!_]*.py")] | ||
|
||
available_formatters = {} | ||
|
||
formatters = [importlib.import_module(i) for i in formatter_files] | ||
|
||
for formatter in formatters: | ||
if hasattr(formatter, "formatter_name"): | ||
obj = getattr(formatter, formatter.formatter_name) | ||
if issubclass(obj, EDR_formatter): | ||
# Make instance of formatter and save | ||
available_formatters[formatter.name] = formatter() | ||
|
||
return available_formatters |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import math | ||
|
||
from datetime import timezone | ||
from itertools import groupby | ||
|
||
from covjson_pydantic.coverage import Coverage | ||
from covjson_pydantic.coverage import CoverageCollection | ||
from covjson_pydantic.domain import Axes | ||
from covjson_pydantic.domain import Domain | ||
from covjson_pydantic.domain import DomainType | ||
from covjson_pydantic.domain import ValuesAxis | ||
from covjson_pydantic.ndarray import NdArray | ||
from covjson_pydantic.observed_property import ObservedProperty | ||
from covjson_pydantic.parameter import Parameter | ||
from covjson_pydantic.reference_system import ReferenceSystem | ||
from covjson_pydantic.reference_system import ReferenceSystemConnectionObject | ||
from covjson_pydantic.unit import Unit | ||
|
||
from pydantic import AwareDatetime | ||
|
||
from base_formatter import EDR_formatter | ||
|
||
|
||
# Requierd for | ||
formatter_name = "Covjson" | ||
|
||
|
||
class Covjson(EDR_formatter): | ||
""" | ||
Class for converting protobuf object to coverage json | ||
""" | ||
|
||
def __init__(self): | ||
self.alias = ["covjson", "coveragejson"] | ||
|
||
def convert(self, response): | ||
# Collect data | ||
coverages = [] | ||
data = [self._collect_data(md.ts_mdata, md.obs_mdata) for md in response.observations] | ||
|
||
# Need to sort before using groupBy. Also sort on param_id to get consistently sorted output | ||
data.sort(key=lambda x: (x[0], x[1])) | ||
# The multiple coverage logic is not needed for this endpoint, | ||
# but we want to share this code between endpoints | ||
for (lat, lon, times), group in groupby(data, lambda x: x[0]): | ||
referencing = [ | ||
ReferenceSystemConnectionObject( | ||
coordinates=["y", "x"], | ||
system=ReferenceSystem(type="GeographicCRS", | ||
id="http://www.opengis.net/def/crs/EPSG/0/4326"), | ||
), | ||
ReferenceSystemConnectionObject( | ||
coordinates=["z"], | ||
system=ReferenceSystem(type="TemporalRS", calendar="Gregorian"), | ||
), | ||
] | ||
domain = Domain( | ||
domainType=DomainType.point_series, | ||
axes=Axes( | ||
x=ValuesAxis[float](values=[lon]), | ||
y=ValuesAxis[float](values=[lat]), | ||
t=ValuesAxis[AwareDatetime](values=times), | ||
), | ||
referencing=referencing, | ||
) | ||
|
||
parameters = {} | ||
ranges = {} | ||
for (_, _, _), param_id, unit, values in group: | ||
if all(math.isnan(v) for v in values): | ||
continue # Drop ranges if completely nan. | ||
# TODO: Drop the whole coverage if it becomes empty? | ||
values_no_nan = [v if not math.isnan(v) else None for v in values] | ||
# TODO: Improve this based on "standard name", etc. | ||
parameters[param_id] = Parameter( | ||
observedProperty=ObservedProperty(label={"en": param_id}), unit=Unit(label={"en": unit}) | ||
) # TODO: Also fill symbol? | ||
ranges[param_id] = NdArray( | ||
values=values_no_nan, axisNames=["t", "y", "x"], shape=[len(values_no_nan), 1, 1] | ||
) | ||
|
||
coverages.append(Coverage(domain=domain, parameters=parameters, ranges=ranges)) | ||
return CoverageCollection(coverages=coverages) | ||
|
||
def _collect_data(ts_mdata, obs_mdata): | ||
lat = obs_mdata[0].geo_point.lat # HACK: For now assume they all have the same position | ||
lon = obs_mdata[0].geo_point.lon | ||
tuples = ( | ||
(o.obstime_instant.ToDatetime(tzinfo=timezone.utc), float(o.value)) for o in obs_mdata | ||
) # HACK: str -> float | ||
(times, values) = zip(*tuples) | ||
param_id = ts_mdata.instrument | ||
unit = ts_mdata.unit | ||
|
||
return (lat, lon, times), param_id, unit, values |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import grpc | ||
import os | ||
|
||
import datastore_pb2_grpc as dstore_grpc | ||
|
||
|
||
def get_obsrequest(get_obs_request): | ||
with grpc.insecure_channel(f"{os.getenv('DSHOST', 'localhost')}:{os.getenv('DSPORT', '50050')}") as channel: | ||
grpc_stub = dstore_grpc.DatastoreStub(channel) | ||
response = grpc_stub.GetObservations(get_obs_request) | ||
|
||
return response |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters