Skip to content

Commit

Permalink
Merge pull request #35 from Ingenjorsarbete-For-Klimatet/feature/exam…
Browse files Browse the repository at this point in the history
…ple-smhi-data

Feature/example smhi data
  • Loading branch information
mgcth authored Feb 21, 2024
2 parents 67acb03 + ccbf2a1 commit c3e942d
Show file tree
Hide file tree
Showing 6 changed files with 374 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,4 @@ dist-ssr
*.pmtiles
*.geojson
*.gpkg
*.pbf
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ dev = [
where = ["src"]
exclude = ["material"]

[tool.mypy]
ignore_missing_imports = true
[[tool.mypy.overrides]]
module = ["smhi.*"]
ignore_missing_imports = true
101 changes: 99 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { createRoot } from "react-dom/client";
import { useEffect } from "react";
import { useEffect, useState } from "react";
import DeckGL from "deck.gl/typed";
import { Map, MapProvider } from "react-map-gl";
import maplibregl from "maplibre-gl";
import { Protocol } from "pmtiles";

import { ScatterplotLayer, GeoJsonLayer } from "@deck.gl/layers";
import { interpolateYlOrRd } from "d3-scale-chromatic";
import { color } from "d3-color";
import DelaunayLayer from "./delaunay.tsx";
import { useMenuStore } from "./Store";

import { DataFilterExtension } from "@deck.gl/extensions";

const INITIAL_VIEW_STATE = {
latitude: 62.5,
longitude: 16,
Expand All @@ -26,6 +31,37 @@ export function App() {
}
});

const step = 1;
const loopLength = 2500;
const [time, setTime] = useState(0);
const [z, setZ] = useState(0);
const [animation] = useState({});
const animate = () => {
setTime((t) => (t + step) % loopLength);
if (z > 13) {
setZ(0);
}
setZ((t) => t + 1);
setTimeout(() => {
animation.id = window.requestAnimationFrame(animate); // draw next frame
}, 100);
};
useEffect(() => {
if (!true) {
window.cancelAnimationFrame(animation.id);
return;
}

animation.id = window.requestAnimationFrame(animate); // start animation
return () => window.cancelAnimationFrame(animation.id);
}, [true]);

if (z > 12) {
setZ(0);
}

console.log(z);

useEffect(() => {
let protocol: any = new Protocol();
maplibregl.addProtocol("pmtiles", protocol.tile);
Expand Down Expand Up @@ -158,9 +194,70 @@ export function App() {
return layers;
});

function hexToRGB(hex) {
const c = color(hex);
return [c.r, c.g, c.b];
}

const lays = [
// @ts-ignore
new DelaunayLayer({
data: "file_2.json",
id: "c",
getPosition: (d) => d.c,
getValue: (d) => {
return d.t[z];
},
colorScale: (x) => {
return [...hexToRGB(interpolateYlOrRd((x + 30) / 50)), 200];
},
updateTriggers: {
getValue: { z },
},
transitions: {
getValue: "interpolation",
},
}),

// new ScatterplotLayer({
// data: "file_2.json",
// id: "c",
// radiusMinPixels: 100,
// radiusMaxPixels: 100,
// getFillColor: d => {
// console.log(d.t[0])
// return [d.t[0]+100, d.t[0]+100, d.t[0]+100]
// },
// // // props added by DataFilterExtension
// // getFilterValue: f => {
// // return f.time
// // }, // in seconds
// // filterRange: [0, 1], // 12:00 - 13:00

// // // Define extensions
// // extensions: [new DataFilterExtension({filterSize: 1})]
// }),

// new ScatterplotLayer({
// id: 'scatterplot-layer',
// data: 'file.json',
// pickable: true,
// opacity: 0.6,
// filled: true,
// radiusScale: 6,
// radiusMinPixels: 1,
// radiusMaxPixels: 100,
// lineWidthMinPixels: 1,
// getPosition: d => d.c,
// getRadius: d => Math.sqrt(d.exits),
// getFillColor: d => [d.d*100, d.d*100, d.d*100],
// })
];

return (
<DeckGL
initialViewState={searchView}
layers={lays}
controller={{ inertia: 300, scrollZoom: { speed: 1, smooth: true } }}
ContextProvider={MapProvider}
onViewStateChange={({ viewState }) => {
Expand Down
79 changes: 79 additions & 0 deletions src/data_layer/smhi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""SMHI data layer."""

import json
import logging
from typing import Union, Optional
from smhi.mesan import Mesan # type: ignore
from smhi.metfcts import Metfcts # type: ignore

logger = logging.getLogger()


def get_data(client: Union[Mesan, Metfcts]) -> Optional[dict]:
"""Get data from client.
Args:
client: Mesan or Metfcts clients
"""
valid_times = client.valid_time
coordinates = client.get_geo_multipoint(1)

all_temperatures = []
for i, time in enumerate(valid_times):
try:
temperature = client.get_multipoint(time, "t", "hl", 2, 1)
all_temperatures.append(temperature["values"].to_list())
except KeyError:
logger.warning(f"No temperature data found for {time}.")

if len(all_temperatures) == 0:
logger.warning("No data saved.")
return None

features = []
for i, coord in enumerate(coordinates):
temperature = [j[i] for j in all_temperatures]
features.append(
{
"type": "Feature",
"properties": {
"t": temperature,
},
"geometry": {"type": "Point", "coordinates": coord},
}
)

return {
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {"name": "urn:ogc:def:crs:OGC:1.3:CRS84"},
},
"features": features,
}


def save_metfcts_multipoint(file: str) -> None:
"""Save Metfcts multipoint data.
Args:
file: file path for saved file
"""
client = Metfcts()
geojson = get_data(client)

with open(file, "w") as f:
json.dump(geojson, f)


def save_mesan_multipoint(file: str) -> None:
"""Save Mesan multipoint data.
Args:
file: file path for saved file
"""
client = Mesan()
geojson = get_data(client)

with open(file, "w") as f:
json.dump(geojson, f)
Loading

0 comments on commit c3e942d

Please sign in to comment.