Compare commits
2
Commits
db69e1bb22
...
2e9e86541a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e9e86541a | ||
|
|
aec2290b69 |
+2
-1
@@ -35,7 +35,8 @@
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
"src/styles.scss",
|
||||
"node_modules/leaflet/dist/leaflet.css"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
|
||||
Generated
+23
@@ -16,7 +16,9 @@
|
||||
"@angular/material": "^21.2.11",
|
||||
"@angular/platform-browser": "^21.2.0",
|
||||
"@angular/router": "^21.2.0",
|
||||
"@types/leaflet": "^1.9.21",
|
||||
"chart.js": "^4.5.1",
|
||||
"leaflet": "^1.9.4",
|
||||
"moment": "^2.30.1",
|
||||
"ng2-charts": "^10.0.0",
|
||||
"rxjs": "~7.8.0",
|
||||
@@ -4051,6 +4053,21 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/geojson": {
|
||||
"version": "7946.0.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",
|
||||
"integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/leaflet": {
|
||||
"version": "1.9.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz",
|
||||
"integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitejs/plugin-basic-ssl": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.4.tgz",
|
||||
@@ -6089,6 +6106,12 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/leaflet": {
|
||||
"version": "1.9.4",
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/listr2": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz",
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
"@angular/material": "^21.2.11",
|
||||
"@angular/platform-browser": "^21.2.0",
|
||||
"@angular/router": "^21.2.0",
|
||||
"@types/leaflet": "^1.9.21",
|
||||
"chart.js": "^4.5.1",
|
||||
"leaflet": "^1.9.4",
|
||||
"moment": "^2.30.1",
|
||||
"ng2-charts": "^10.0.0",
|
||||
"rxjs": "~7.8.0",
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { Home } from './components/home/home';
|
||||
import { MapaEstacions } from './components/mapa-estacions/mapa-estacions';
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: '', component: Home },
|
||||
{ path: 'mapa', component: MapaEstacions },
|
||||
{ path: '**', redirectTo: '' }
|
||||
];
|
||||
|
||||
@@ -67,6 +67,11 @@
|
||||
<button class="menu-action secondary" (click)="requestLocation(); closeMenu()">
|
||||
📍 Usar la meva ubicació
|
||||
</button>
|
||||
|
||||
<!-- Botón de mapa de estaciones -->
|
||||
<button class="menu-action secondary" (click)="openMap(); closeMenu()">
|
||||
🗺️ Mapa d'estacions
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component, OnInit, signal } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { MeteocatService } from '../../services/meteocat.service';
|
||||
import { Municipi } from '../../models/municipi.model';
|
||||
import { PrediccioDiaria } from '../../models/prediccio-diaria.model';
|
||||
@@ -38,9 +39,23 @@ export class Home implements OnInit {
|
||||
showGpsModal = signal(false);
|
||||
gpsPermissionAsked = signal(false);
|
||||
|
||||
constructor(private meteocatService: MeteocatService) {}
|
||||
constructor(
|
||||
private meteocatService: MeteocatService,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
// Verificar si viene un municipio desde el mapa
|
||||
this.route.queryParams.subscribe(params => {
|
||||
if (params['municipi']) {
|
||||
this.municipiCodi.set(params['municipi']);
|
||||
this.gpsPermissionAsked.set(true);
|
||||
this.loadWeatherData(params['municipi']);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
// Verificar si ya se pidió permiso GPS antes
|
||||
const gpsRejected = localStorage.getItem('gpsRejected');
|
||||
const gpsAsked = localStorage.getItem('gpsAsked');
|
||||
@@ -292,4 +307,8 @@ export class Home implements OnInit {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
openMap(): void {
|
||||
this.router.navigate(['/mapa']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<div class="mapa-container">
|
||||
<!-- Header con título y botón volver -->
|
||||
<div class="header">
|
||||
<button class="back-button" (click)="goBack()">
|
||||
← Tornar
|
||||
</button>
|
||||
<h1>Mapa d'Estacions XEMA</h1>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
|
||||
<!-- Filtros -->
|
||||
<div class="filters">
|
||||
<label class="filter-checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
[checked]="showOperatives()"
|
||||
(change)="toggleOperatives()"
|
||||
/>
|
||||
<span class="checkbox-label">
|
||||
<span class="status-dot green"></span>
|
||||
Operatives ({{ estacions().filter(e => e.estat === 'Operativa').length }})
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<label class="filter-checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
[checked]="showBaixaTemporal()"
|
||||
(change)="toggleBaixaTemporal()"
|
||||
/>
|
||||
<span class="checkbox-label">
|
||||
<span class="status-dot orange"></span>
|
||||
Baixa temporal ({{ estacions().filter(e => e.estat === 'Baixa temporal').length }})
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<span class="total-count">
|
||||
Mostrant: {{ getFilteredCount() }} / {{ estacions().length }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Loading -->
|
||||
@if (loading()) {
|
||||
<div class="loading">
|
||||
<div class="spinner"></div>
|
||||
<p>Carregant estacions...</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Error -->
|
||||
@if (error()) {
|
||||
<div class="error">
|
||||
<p>{{ error() }}</p>
|
||||
<button (click)="loadEstacions()">Tornar a intentar</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Mapa -->
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
<!-- Leyenda -->
|
||||
<div class="legend">
|
||||
<div class="legend-item">
|
||||
<span class="legend-icon">🌡️</span>
|
||||
<span>Estació meteorològica</span>
|
||||
</div>
|
||||
<div class="legend-note">
|
||||
Fes clic en un marcador per veure el temps d'aquell municipi
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,305 @@
|
||||
.mapa-container {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: linear-gradient(180deg, #072d59 0%, #56556a 100%);
|
||||
color: white;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 15px;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
backdrop-filter: blur(10px);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
|
||||
@media (min-width: 768px) {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.spacer {
|
||||
width: 80px; // Para balancear el botón
|
||||
|
||||
@media (min-width: 768px) {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.back-button {
|
||||
padding: 8px 16px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: white;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
padding: 10px 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
padding: 12px 15px;
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
align-items: center;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
padding: 15px 20px;
|
||||
gap: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
margin-right: 6px;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
|
||||
&.green {
|
||||
background: #4caf50;
|
||||
box-shadow: 0 0 6px rgba(76, 175, 80, 0.6);
|
||||
}
|
||||
|
||||
&.orange {
|
||||
background: #ff9800;
|
||||
box-shadow: 0 0 6px rgba(255, 152, 0, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.total-count {
|
||||
margin-left: auto;
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.map {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.loading, .error {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 4px solid rgba(255, 255, 255, 0.3);
|
||||
border-top-color: white;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.error button {
|
||||
margin-top: 20px;
|
||||
padding: 12px 24px;
|
||||
background: white;
|
||||
color: #4a90e2;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.legend {
|
||||
padding: 10px 15px;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
|
||||
@media (min-width: 768px) {
|
||||
padding: 12px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
margin-bottom: 6px;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.legend-icon {
|
||||
font-size: 18px;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.legend-note {
|
||||
font-size: 11px;
|
||||
opacity: 0.7;
|
||||
margin-top: 4px;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
// Estilos para los marcadores personalizados
|
||||
:host ::ng-deep {
|
||||
.custom-marker {
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.marker-pin {
|
||||
width: 30px;
|
||||
height: 42px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50% 50% 50% 0;
|
||||
transform: rotate(-45deg);
|
||||
left: 3px;
|
||||
top: 0;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
&.green::before {
|
||||
background: #4caf50;
|
||||
}
|
||||
|
||||
&.orange::before {
|
||||
background: #ff9800;
|
||||
}
|
||||
|
||||
.marker-icon {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 8px;
|
||||
font-size: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Tooltips
|
||||
.leaflet-tooltip {
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
padding: 8px 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
|
||||
&::before {
|
||||
border-top-color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
.station-tooltip {
|
||||
strong {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.status {
|
||||
display: inline-block;
|
||||
margin-top: 4px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
|
||||
&.operativa {
|
||||
background: rgba(76, 175, 80, 0.3);
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
&.baixa-temporal {
|
||||
background: rgba(255, 152, 0, 0.3);
|
||||
color: #ff9800;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
import { Component, OnInit, AfterViewInit, OnDestroy, signal } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Router } from '@angular/router';
|
||||
import * as L from 'leaflet';
|
||||
import { MeteocatService } from '../../services/meteocat.service';
|
||||
import { EstacioXema } from '../../models/estacio-xema.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mapa-estacions',
|
||||
imports: [CommonModule],
|
||||
templateUrl: './mapa-estacions.html',
|
||||
styleUrl: './mapa-estacions.scss',
|
||||
})
|
||||
export class MapaEstacions implements OnInit, AfterViewInit, OnDestroy {
|
||||
private map: L.Map | null = null;
|
||||
private markers: L.Marker[] = [];
|
||||
|
||||
estacions = signal<EstacioXema[]>([]);
|
||||
loading = signal(true);
|
||||
error = signal<string | null>(null);
|
||||
|
||||
// Filtros
|
||||
showOperatives = signal(true);
|
||||
showBaixaTemporal = signal(true);
|
||||
|
||||
constructor(
|
||||
private meteocatService: MeteocatService,
|
||||
private router: Router
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadEstacions();
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.initMap();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.map) {
|
||||
this.map.remove();
|
||||
}
|
||||
}
|
||||
|
||||
loadEstacions(): void {
|
||||
this.loading.set(true);
|
||||
this.meteocatService.getAllEstacions().subscribe({
|
||||
next: (estacions) => {
|
||||
this.estacions.set(estacions);
|
||||
this.loading.set(false);
|
||||
if (this.map) {
|
||||
this.addMarkers();
|
||||
}
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error loading estacions:', err);
|
||||
this.error.set('Error al carregar les estacions meteorològiques');
|
||||
this.loading.set(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initMap(): void {
|
||||
// Crear mapa centrado en Cataluña
|
||||
this.map = L.map('map', {
|
||||
center: [41.8, 1.5],
|
||||
zoom: 8,
|
||||
minZoom: 7,
|
||||
maxZoom: 18
|
||||
});
|
||||
|
||||
// Añadir capa de OpenStreetMap
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(this.map);
|
||||
|
||||
// Añadir marcadores si ya se cargaron las estaciones
|
||||
if (this.estacions().length > 0) {
|
||||
this.addMarkers();
|
||||
}
|
||||
}
|
||||
|
||||
addMarkers(): void {
|
||||
if (!this.map) return;
|
||||
|
||||
// Limpiar marcadores anteriores
|
||||
this.markers.forEach(marker => marker.remove());
|
||||
this.markers = [];
|
||||
|
||||
const filteredEstacions = this.estacions().filter(estacio => {
|
||||
if (estacio.estat === 'Operativa' && this.showOperatives()) return true;
|
||||
if (estacio.estat === 'Baixa temporal' && this.showBaixaTemporal()) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
filteredEstacions.forEach(estacio => {
|
||||
if (!estacio.coordenadesLatitud || !estacio.coordenadesLongitud) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Icono personalizado según estado
|
||||
const iconColor = estacio.estat === 'Operativa' ? 'green' : 'orange';
|
||||
const icon = L.divIcon({
|
||||
className: 'custom-marker',
|
||||
html: `
|
||||
<div class="marker-pin ${iconColor}">
|
||||
<div class="marker-icon">🌡️</div>
|
||||
</div>
|
||||
`,
|
||||
iconSize: [30, 42],
|
||||
iconAnchor: [15, 42],
|
||||
popupAnchor: [0, -42]
|
||||
});
|
||||
|
||||
const marker = L.marker(
|
||||
[estacio.coordenadesLatitud, estacio.coordenadesLongitud],
|
||||
{ icon }
|
||||
).addTo(this.map!);
|
||||
|
||||
// Tooltip (hover)
|
||||
marker.bindTooltip(`
|
||||
<div class="station-tooltip">
|
||||
<strong>${estacio.nom}</strong><br/>
|
||||
${estacio.emplacament || ''}<br/>
|
||||
<span class="status ${estacio.estat.toLowerCase().replace(' ', '-')}">${estacio.estat}</span>
|
||||
</div>
|
||||
`, {
|
||||
direction: 'top',
|
||||
offset: [0, -42]
|
||||
});
|
||||
|
||||
// Popup (click) - navegar al municipio
|
||||
marker.on('click', () => {
|
||||
if (estacio.municipiCodi) {
|
||||
this.navigateToMunicipi(estacio.municipiCodi);
|
||||
}
|
||||
});
|
||||
|
||||
this.markers.push(marker);
|
||||
});
|
||||
}
|
||||
|
||||
navigateToMunicipi(municipiCodi: string): void {
|
||||
// Cerrar el mapa y volver a Home con el municipio seleccionado
|
||||
this.router.navigate(['/'], {
|
||||
queryParams: { municipi: municipiCodi }
|
||||
});
|
||||
}
|
||||
|
||||
toggleOperatives(): void {
|
||||
this.showOperatives.set(!this.showOperatives());
|
||||
this.addMarkers();
|
||||
}
|
||||
|
||||
toggleBaixaTemporal(): void {
|
||||
this.showBaixaTemporal.set(!this.showBaixaTemporal());
|
||||
this.addMarkers();
|
||||
}
|
||||
|
||||
getFilteredCount(): number {
|
||||
return this.estacions().filter(estacio => {
|
||||
if (estacio.estat === 'Operativa' && this.showOperatives()) return true;
|
||||
if (estacio.estat === 'Baixa temporal' && this.showBaixaTemporal()) return true;
|
||||
return false;
|
||||
}).length;
|
||||
}
|
||||
|
||||
goBack(): void {
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,15 @@ export interface EstacioXema {
|
||||
tipus: string;
|
||||
coordenadesLatitud: number;
|
||||
coordenadesLongitud: number;
|
||||
altitud?: number;
|
||||
municipi?: string;
|
||||
comarca?: string;
|
||||
provincia?: string;
|
||||
xarxa?: string;
|
||||
estat?: string;
|
||||
dataInici?: string;
|
||||
dataFi?: string;
|
||||
distancia?: number; // Calculado dinámicamente para estación más cercana
|
||||
altitud: number;
|
||||
emplacament: string;
|
||||
municipiCodi: string;
|
||||
comarcaId: number;
|
||||
provinciaCodi: string;
|
||||
xarxaCodi: string;
|
||||
estat: string;
|
||||
dataInici: string | null;
|
||||
dataFi: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user