- Corregida la posición del panel para que no salga fuera de la pantalla. - Renombrado el interruptor a Visualizar Pendientes. - Aplicado el porcentaje de subida como umbral para calcular el esfuerzo. - Mostrado el umbral de subida utilizado dentro de la tabla de elevación. - Añadido al aviso el total de distancia con pendiente y la altura subida en metros y pisos. - Evitada la duplicación de acumulados al repintar las pendientes. - Cambiados los valores por defecto a subida 2 %, bajada 5 % y coeficiente 8,2. - Añadida la distancia equilibrada andando al detalle técnico. - Mostradas las distancias en kilómetros con tres decimales. - Mostrada la fecha del ZIP activo en el acceso de gestión del modelo DBUS. - Añadidas migraciones para actualizar los antiguos valores predeterminados.
278 lines
8.5 KiB
C#
278 lines
8.5 KiB
C#
using System.Globalization;
|
|
using Microsoft.AspNetCore.Components.Forms;
|
|
using Microsoft.JSInterop;
|
|
using RutasDBUS.Modelos.Importacion;
|
|
|
|
namespace RutasDBUS.Components.Pages;
|
|
|
|
public partial class PlanificadorRutas
|
|
{
|
|
private const long MaxModeloHorarioUploadBytes = 250L * 1024 * 1024;
|
|
|
|
private IReadOnlyList<ModeloHorarioDbusInfo> _modelosHorarios = Array.Empty<ModeloHorarioDbusInfo>();
|
|
private string _modeloHorarioSeleccionadoId = "";
|
|
private string _mensajeModelosHorarios = "";
|
|
private bool _modelosHorariosCargando = false;
|
|
private bool _mostrarModelosHorariosPanel = false;
|
|
|
|
private ModeloHorarioDbusInfo? ModeloHorarioActivo =>
|
|
_modelosHorarios.FirstOrDefault(modelo => modelo.Activo);
|
|
|
|
private string FechaModeloHorarioActivo =>
|
|
FormatearFechaModeloHorario(ModeloHorarioActivo?.NombreArchivo);
|
|
|
|
private static string FormatearFechaModeloHorario(string? nombreArchivo)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(nombreArchivo))
|
|
return "Sin modelo cargado";
|
|
|
|
for (var indice = nombreArchivo.Length - 8; indice >= 0; indice--)
|
|
{
|
|
if (indice > 0 && char.IsDigit(nombreArchivo[indice - 1]))
|
|
continue;
|
|
|
|
var fin = indice + 8;
|
|
if (fin < nombreArchivo.Length && char.IsDigit(nombreArchivo[fin]))
|
|
continue;
|
|
|
|
var candidata = nombreArchivo.Substring(indice, 8);
|
|
if (DateTime.TryParseExact(
|
|
candidata,
|
|
"yyyyMMdd",
|
|
CultureInfo.InvariantCulture,
|
|
DateTimeStyles.None,
|
|
out _))
|
|
{
|
|
return candidata;
|
|
}
|
|
}
|
|
|
|
return "Fecha no disponible";
|
|
}
|
|
|
|
private void AbrirModelosHorariosPanel()
|
|
{
|
|
_mostrarModelosHorariosPanel = true;
|
|
}
|
|
|
|
private void CerrarModelosHorariosPanel()
|
|
{
|
|
_mostrarModelosHorariosPanel = false;
|
|
}
|
|
|
|
private async Task CargarModelosHorariosAsync()
|
|
{
|
|
_modelosHorariosCargando = true;
|
|
|
|
try
|
|
{
|
|
_modelosHorarios = await ArchivoImportacionDbus.ListarModelosAsync();
|
|
var activo = ModeloHorarioActivo ?? _modelosHorarios.FirstOrDefault();
|
|
_modeloHorarioSeleccionadoId = activo?.Id ?? "";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_modelosHorarios = Array.Empty<ModeloHorarioDbusInfo>();
|
|
_modeloHorarioSeleccionadoId = "";
|
|
_mensajeModelosHorarios = "No se han podido leer los modelos: " + ex.Message;
|
|
}
|
|
finally
|
|
{
|
|
_modelosHorariosCargando = false;
|
|
}
|
|
}
|
|
|
|
private async Task ActualizarModelosHorariosAsync()
|
|
{
|
|
_mensajeModelosHorarios = "";
|
|
await CargarModelosHorariosAsync();
|
|
if (string.IsNullOrWhiteSpace(_mensajeModelosHorarios))
|
|
_mensajeModelosHorarios = _modelosHorarios.Count == 0
|
|
? "No hay ZIPs disponibles."
|
|
: "Lista actualizada.";
|
|
}
|
|
|
|
private async Task SeleccionarModeloHorarioAsync()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_modeloHorarioSeleccionadoId))
|
|
{
|
|
_mensajeModelosHorarios = "Selecciona un ZIP.";
|
|
return;
|
|
}
|
|
|
|
var seleccionado = _modelosHorarios
|
|
.FirstOrDefault(modelo => string.Equals(modelo.Id, _modeloHorarioSeleccionadoId, StringComparison.OrdinalIgnoreCase));
|
|
|
|
if (seleccionado?.Activo == true)
|
|
{
|
|
_mensajeModelosHorarios = "Ese modelo ya esta cargado.";
|
|
return;
|
|
}
|
|
|
|
_modelosHorariosCargando = true;
|
|
_mensajeModelosHorarios = "Cargando modelo...";
|
|
|
|
try
|
|
{
|
|
await ArchivoImportacionDbus.SeleccionarModeloAsync(_modeloHorarioSeleccionadoId);
|
|
await RecargarModeloHorarioActivoAsync();
|
|
await CargarModelosHorariosAsync();
|
|
|
|
var activo = ModeloHorarioActivo;
|
|
_mensajeModelosHorarios = activo is null
|
|
? "Modelo cargado."
|
|
: "Cargado: " + activo.NombreArchivo;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_mensajeModelosHorarios = "No se ha podido cargar el modelo: " + ex.Message;
|
|
}
|
|
finally
|
|
{
|
|
_modelosHorariosCargando = false;
|
|
}
|
|
}
|
|
|
|
private async Task SubirModeloHorarioAsync(InputFileChangeEventArgs e)
|
|
{
|
|
var archivo = e.File;
|
|
if (archivo is null)
|
|
return;
|
|
|
|
if (!archivo.Name.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
_mensajeModelosHorarios = "Solo se pueden subir archivos .zip.";
|
|
return;
|
|
}
|
|
|
|
_modelosHorariosCargando = true;
|
|
_mensajeModelosHorarios = "Subiendo ZIP...";
|
|
|
|
try
|
|
{
|
|
await using var stream = archivo.OpenReadStream(MaxModeloHorarioUploadBytes);
|
|
var modelo = await ArchivoImportacionDbus.GuardarModeloSubidoAsync(archivo.Name, stream);
|
|
|
|
_modeloHorarioSeleccionadoId = modelo.Id;
|
|
await RecargarModeloHorarioActivoAsync();
|
|
await CargarModelosHorariosAsync();
|
|
_mensajeModelosHorarios = "Subido y cargado: " + modelo.NombreArchivo;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_mensajeModelosHorarios = "No se ha podido subir el ZIP: " + ex.Message;
|
|
}
|
|
finally
|
|
{
|
|
_modelosHorariosCargando = false;
|
|
}
|
|
}
|
|
|
|
private async Task LimpiarDatosLocalesAsync()
|
|
{
|
|
bool confirmado;
|
|
try
|
|
{
|
|
confirmado = await JS.InvokeAsync<bool>(
|
|
"confirm",
|
|
"¿Seguro que quieres limpiar los datos locales de este navegador? Se borrarán historial, configuración guardada, cachés y datos locales de este sitio.");
|
|
}
|
|
catch (JSException)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!confirmado)
|
|
return;
|
|
|
|
_modelosHorariosCargando = true;
|
|
_mensajeModelosHorarios = "Limpiando datos locales...";
|
|
|
|
try
|
|
{
|
|
await JS.InvokeVoidAsync("rt.clearLocalBrowserData");
|
|
_mensajeModelosHorarios = "Datos locales borrados. Recargando...";
|
|
await InvokeAsync(StateHasChanged);
|
|
await Task.Delay(250);
|
|
await JS.InvokeVoidAsync("rt.reloadPage");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_mensajeModelosHorarios = "No se han podido limpiar los datos locales: " + ex.Message;
|
|
}
|
|
finally
|
|
{
|
|
_modelosHorariosCargando = false;
|
|
}
|
|
}
|
|
|
|
private async Task RecargarModeloHorarioActivoAsync()
|
|
{
|
|
_ctsCalculo?.Cancel();
|
|
IniciarNuevaVersionPintadoRuta();
|
|
|
|
await CerrarTodasLasPreviewsAsync();
|
|
await CerrarPopupsAsync();
|
|
|
|
if (_mapa is not null)
|
|
{
|
|
await ClearRoutesJsAsync();
|
|
try { await _mapa.Geometric.DisplayPolylinesFromArray.deleteConnectors(); } catch { }
|
|
}
|
|
|
|
ResetEstadoRuta(limpiarOpciones: true);
|
|
PlanificadorRutasServicio.InvalidarCachesModelo();
|
|
_busFilteredCache.Clear();
|
|
InvalidarBusIndex();
|
|
|
|
_itItems.Clear();
|
|
_itSeleccionadoId = null;
|
|
_itFiltro = "";
|
|
_selectItKey++;
|
|
_nextDeps.Clear();
|
|
_horariosOk = false;
|
|
_horariosError = null;
|
|
|
|
_tareaCargaRed = RedBusServicio.CargarRedAsync();
|
|
await _tareaCargaRed;
|
|
|
|
if (_usarHorariosTeoricos)
|
|
await EnsureHorariosLoadedAsync();
|
|
|
|
if (RedBusServicio.Paradas.Count > 0)
|
|
{
|
|
EnsureBusIndexBuilt();
|
|
BuildItinerariosDropdown();
|
|
SincronizarSeleccionItinerarioConFiltro();
|
|
}
|
|
|
|
_paradasPintadas = false;
|
|
if (_mapa is not null)
|
|
{
|
|
if (_mostrarParadas)
|
|
await DibujarParadasAsync();
|
|
else
|
|
await OcultarParadasAsync();
|
|
|
|
await SincronizarMarcadoresOrigenDestinoJsAsync();
|
|
_paradasPintadas = _mostrarParadas;
|
|
}
|
|
|
|
StateHasChanged();
|
|
}
|
|
|
|
private static string FormatearTamanoModelo(long bytes)
|
|
{
|
|
if (bytes >= 1024L * 1024L)
|
|
return (bytes / 1024d / 1024d).ToString("0.0", CultureInfo.InvariantCulture) + " MB";
|
|
|
|
if (bytes >= 1024L)
|
|
return (bytes / 1024d).ToString("0", CultureInfo.InvariantCulture) + " KB";
|
|
|
|
return bytes.ToString(CultureInfo.InvariantCulture) + " B";
|
|
}
|
|
|
|
private static string FormatearFechaModelo(DateTime fechaUtc)
|
|
=> fechaUtc.ToLocalTime().ToString("dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture);
|
|
}
|