Merge Embalse

This commit is contained in:
Amin Chaloukh 2024-10-17 20:19:50 +02:00
commit b24b59f619
5 changed files with 140 additions and 6 deletions

View File

@ -11,6 +11,10 @@ export default class Api {
return Api._makeReq(`/embalses/${id}`);
}
static async embalsesNearby(lat: string, lon: string): Promise<Embalse[]> {
return Api._makeReq(`/embalsesCercanos/${lat}/${lon}`);
}
static async _makeReq<T>(endpoint: string): Promise<T[]> {
let hasMore = true;

View File

@ -0,0 +1,36 @@
import OWMResponse from "../interfaces/OWMResponse";
/**
* Wrapper para recibir los datos del clima de OpenWeatherMap
*/
export default class OpenWeather {
static async week(lat: string, lon: string): Promise<string> {
const res = await fetch('https://api.openweathermap.org/data/2.5/forecast?lat=' + lat + '&lon=' + lon + '&appid=' + import.meta.env.VITE_OWM_KEY);
if (!res.ok) {
throw new Error("API Error");
}
const json = await res.json() as OWMResponse;
let rains = 0;
json.list.forEach((el) => {
if (el.weather[0].id === 500) {
rains++;
}
});
let probability = '';
if (rains > json.list.length / 2) {
// Bien
probability = 'Sabiendo que ha llovido un total de ' + rains + ' días, podemos predecir que el caudal será alto';
} else {
// Mal
probability = 'Sabiendo que ha llovido un total de ' + rains + ' días, podemos predecir que el caudal será bajo';
}
return probability;
}
}

View File

@ -0,0 +1,68 @@
export default interface OWMResponse {
cod: string
message: number
cnt: number
list: Weather[]
city: City
}
export interface Weather {
dt: number
main: Main
weather: Weather[]
clouds: Clouds
wind: Wind
visibility: number
pop: number
sys: Sys
dt_txt: string
}
export interface Main {
temp: number
feels_like: number
temp_min: number
temp_max: number
pressure: number
sea_level: number
grnd_level: number
humidity: number
temp_kf: number
}
export interface Weather {
id: number
main: string
description: string
icon: string
}
export interface Clouds {
all: number
}
export interface Wind {
speed: number
deg: number
gust: number
}
export interface Sys {
pod: string
}
export interface City {
id: number
name: string
coord: Coord
country: string
population: number
timezone: number
sunrise: number
sunset: number
}
export interface Coord {
lat: number
lon: number
}

View File

@ -6,18 +6,21 @@ import Loader from "../partials/Loader";
import Api from "../helpers/Api";
import Card from "../partials/Card";
import { FaSolidLocationDot, FaSolidMapLocationDot, FaSolidWater } from "solid-icons/fa";
import OpenWeather from "../helpers/OpenWeather";
interface CustomParams extends Params {
id: string;
}
function Embalse() {
const params = useParams<CustomParams>();
const [embalse, setEmbalse] = createSignal<EmbalseType>();
const [prediction, setPrediction] = createSignal('');
onMount(() => {
getEmbalse();
getEmbalse().then(async () => {
setPrediction(await OpenWeather.week(embalse()!.x, embalse()!.y));
});
});
const getEmbalse = async () => {
@ -26,6 +29,17 @@ function Embalse() {
setEmbalse(res[0]);
}
const getPercentage = () => {
const perc = Math.round(embalse()!.agua_actual / embalse()!.agua_total * 100);
return (
<span classList={{
'has-text-danger': perc <= 50,
'has-text-warning': perc > 50 && perc < 70,
'has-text-success': perc >= 70
}}>{perc}%</span>
)
}
return (
<>
<Navbar />
@ -59,10 +73,15 @@ function Embalse() {
<>
<p><b>Actual</b>: {embalse()!.agua_actual} l/m2</p>
<p><b>Total</b>: {embalse()!.agua_total} l/m2</p>
<p><b>Porcentaje</b>: {embalse()!.agua_actual / embalse()!.agua_total * 100}%</p>
<p><b>Porcentaje</b>: {getPercentage()}</p>
</>
</Card>
</div>
<div class="column is-narrow">
<Card title="Predicción" icon={<FaSolidCircleInfo />}>
<p>{prediction()}</p>
</Card>
</div>
</div>
</div>
</div>

View File

@ -1,9 +1,12 @@
import { createSignal, onCleanup, onMount } from "solid-js";
import L from 'leaflet';
import { useNavigate } from "@solidjs/router";
import L, { Icon } from 'leaflet';
import { FaSolidLocationPin } from "solid-icons/fa";
import Navbar from "../partials/Navbar";
import Api from "../helpers/Api";
function Finder() {
const navigate = useNavigate();
const [pos, setPos] = createSignal<[number, number]>([0, 0]);
const [geo, setGeo] = createSignal(true);
@ -73,7 +76,7 @@ function Finder() {
* Escribe los puntos relevantes
* (Mi ubicación y los embalses cercanos)
*/
const handleLocation = () => {
const handleLocation = async () => {
me.setLatLng(pos());
if (first) {
map.setView(pos(), 9);
@ -90,7 +93,11 @@ function Finder() {
markers = [];
}
// TODO: Hacer petición y sacar markers
const res = await Api.embalsesNearby(pos()[0].toString(), pos()[1].toString());
res.forEach((c) => {
L.marker([parseFloat(c.x), parseFloat(c.y)]).on("click", () => navigate('/embalses/' + c.id)).addTo(map);
})
}
/**