conectado nearby
This commit is contained in:
		| @@ -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; | ||||
|  | ||||
|   | ||||
							
								
								
									
										36
									
								
								src/helpers/OpenWeather.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/helpers/OpenWeather.ts
									
									
									
									
									
										Normal 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; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										68
									
								
								src/interfaces/OWMResponse.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/interfaces/OWMResponse.ts
									
									
									
									
									
										Normal 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 | ||||
| } | ||||
| @@ -5,19 +5,22 @@ import Navbar from "../partials/Navbar"; | ||||
| import Loader from "../partials/Loader"; | ||||
| import Api from "../helpers/Api"; | ||||
| import Card from "../partials/Card"; | ||||
| import { FaSolidLocationDot, FaSolidLocationPin, FaSolidMapLocationDot, FaSolidWater } from "solid-icons/fa"; | ||||
| import { FaSolidCircleInfo, 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> | ||||
|   | ||||
| @@ -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); | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|   | ||||
		Reference in New Issue
	
	Block a user