Skip to content

Commit

Permalink
Merge pull request #13 from ecmwf/feature/add_wkt_support
Browse files Browse the repository at this point in the history
Feature/add wkt support
  • Loading branch information
awarde96 authored Feb 28, 2024
2 parents 6e18d7a + 60ec8fa commit d75b1d9
Show file tree
Hide file tree
Showing 6 changed files with 699 additions and 50 deletions.
4 changes: 4 additions & 0 deletions eccovjson/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import eccovjson.decoder.Shapefile
import eccovjson.decoder.TimeSeries
import eccovjson.decoder.VerticalProfile
import eccovjson.decoder.Wkt
import eccovjson.encoder.BoundingBox
import eccovjson.encoder.Frame
import eccovjson.encoder.Path
import eccovjson.encoder.Shapefile
import eccovjson.encoder.TimeSeries
import eccovjson.encoder.VerticalProfile
import eccovjson.encoder.Wkt

features_encoder = {
"pointseries": eccovjson.encoder.TimeSeries.TimeSeries,
Expand All @@ -18,6 +20,7 @@
"shapefile": eccovjson.encoder.Shapefile.Shapefile,
"frame": eccovjson.encoder.Frame.Frame,
"path": eccovjson.encoder.Path.Path,
"wkt": eccovjson.encoder.Wkt.Wkt,
}
features_decoder = {
"pointseries": eccovjson.decoder.TimeSeries.TimeSeries,
Expand All @@ -26,6 +29,7 @@
"shapefile": eccovjson.decoder.Shapefile.Shapefile,
"frame": eccovjson.decoder.Frame.Frame,
"path": eccovjson.decoder.Path.Path,
"wkt": eccovjson.decoder.Wkt.Wkt,
}


Expand Down
67 changes: 67 additions & 0 deletions eccovjson/decoder/Wkt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import xarray as xr

from .decoder import Decoder


class Wkt(Decoder):
def __init__(self, covjson):
super().__init__(covjson)
self.domains = self.get_domains()
self.ranges = self.get_ranges()

def get_domains(self):
domains = []
for coverage in self.coverage.coverages:
domains.append(coverage["domain"])
return domains

def get_ranges(self):
ranges = []
for coverage in self.coverage.coverages:
ranges.append(coverage["ranges"])
return ranges

def get_values(self):
values = {}
for parameter in self.parameters:
values[parameter] = []
for range in self.ranges:
values[parameter].append(range[parameter]["values"])
# values[parameter] = [
# value for sublist in values[parameter] for value in sublist
# ]
return values

def get_coordinates(self):
return self.domains[0]["axes"]

def to_geopandas(self):
pass

def to_xarray(self):
dims = ["points"]
dataarraydict = {}

# Get coordinates
x = []
y = []
for coord in self.get_coordinates()["composite"]["values"]:
x.append(float(coord[0]))
y.append(float(coord[1]))

# Get values
for parameter in self.parameters:
dataarray = xr.DataArray(self.get_values()[parameter][0], dims=dims)
dataarray.attrs["type"] = self.get_parameter_metadata(parameter)["type"]
dataarray.attrs["units"] = self.get_parameter_metadata(parameter)["unit"]["symbol"]
dataarray.attrs["long_name"] = self.get_parameter_metadata(parameter)["description"]
dataarraydict[dataarray.attrs["long_name"]] = dataarray

ds = xr.Dataset(
dataarraydict,
coords=dict(points=(["points"], list(range(0, len(x)))), x=(["points"], x), y=(["points"], y)),
)
for mars_metadata in self.mars_metadata[0]:
ds.attrs[mars_metadata] = self.mars_metadata[0][mars_metadata]

return ds
104 changes: 104 additions & 0 deletions eccovjson/encoder/Wkt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import pandas as pd

from .encoder import Encoder


class Wkt(Encoder):
def __init__(self, type, domaintype):
super().__init__(type, domaintype)
self.covjson["domainType"] = "MultiPoint"

def add_coverage(self, mars_metadata, coords, values):
new_coverage = {}
new_coverage["mars:metadata"] = {}
new_coverage["type"] = "Coverage"
new_coverage["domain"] = {}
new_coverage["ranges"] = {}
self.add_mars_metadata(new_coverage, mars_metadata)
self.add_domain(new_coverage, coords)
self.add_range(new_coverage, values)
self.covjson["coverages"].append(new_coverage)

def add_domain(self, coverage, coords):
coverage["domain"]["type"] = "Domain"
coverage["domain"]["axes"] = {}
coverage["domain"]["axes"]["t"] = {}
coverage["domain"]["axes"]["t"]["values"] = coords["t"]
coverage["domain"]["axes"]["composite"] = {}
coverage["domain"]["axes"]["composite"]["dataType"] = "tuple"
coverage["domain"]["axes"]["composite"]["coordinates"] = self.covjson["referencing"][0]["coordinates"]
coverage["domain"]["axes"]["composite"]["values"] = coords["composite"]

def add_range(self, coverage, values):
for parameter in values.keys():
param = self.convert_param_id_to_param(parameter)
coverage["ranges"][param] = {}
coverage["ranges"][param]["type"] = "NdArray"
coverage["ranges"][param]["dataType"] = "float"
coverage["ranges"][param]["shape"] = [len(values[parameter])]
coverage["ranges"][param]["axisNames"] = [str(param)]
coverage["ranges"][param]["values"] = values[parameter] # [values[parameter]]

def add_mars_metadata(self, coverage, metadata):
coverage["mars:metadata"] = metadata

def from_xarray(self, dataset):
pass

def from_polytope(self, result):
ancestors = [val.get_ancestors() for val in result.leaves]
values = [val.result for val in result.leaves]

columns = []
df_dict = {}
# Create empty dataframe
for feature in ancestors[0]:
columns.append(str(feature).split("=")[0])
df_dict[str(feature).split("=")[0]] = []

# populate dataframe
for ancestor in ancestors:
for feature in ancestor:
df_dict[str(feature).split("=")[0]].append(str(feature).split("=")[1])
values = [val.result for val in result.leaves]
df_dict["values"] = values
df = pd.DataFrame(df_dict)

params = df["param"].unique()

for param in params:
self.add_parameter(param)

self.add_reference(
{
"coordinates": ["x", "y", "z"],
"system": {
"type": "GeographicCRS",
"id": "http://www.opengis.net/def/crs/OGC/1.3/CRS84",
},
}
)

mars_metadata = {}
mars_metadata["class"] = df["class"].unique()[0]
mars_metadata["expver"] = df["expver"].unique()[0]
mars_metadata["levtype"] = df["levtype"].unique()[0]
mars_metadata["type"] = df["type"].unique()[0]
mars_metadata["domain"] = df["domain"].unique()[0]
mars_metadata["stream"] = df["stream"].unique()[0]

range_dict = {}
coords = {}
coords["composite"] = []
coords["t"] = df["date"].unique()[0]

for param in params:
df_param = df[df["param"] == param]
range_dict[param] = df_param["values"].values.tolist()

df_param = df[df["param"] == params[0]]
for row in df_param.iterrows():
coords["composite"].append([row[1]["latitude"], row[1]["longitude"]])

self.add_coverage(mars_metadata, coords, range_dict)
return self.covjson
Loading

0 comments on commit d75b1d9

Please sign in to comment.