Cambio de algoritmia en el descarte de paradas posibles antes del recalculo de soluciones: se analiza las 48 paradas de cada arista en bsuqueda de rutas directas scoreandolas antes de entrar en el recorrido BFS con transbordos.
configuraciones guardadas cambios hora simualda en central
This commit is contained in:
@@ -0,0 +1,156 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using RutasDBUS.Modelos.Historial;
|
||||||
|
|
||||||
|
namespace RutasDBUS.Components.Pages;
|
||||||
|
|
||||||
|
public partial class PlanificadorRutas
|
||||||
|
{
|
||||||
|
private ConfiguracionHistorialRuta? _configuracionAvanzadaAplicada;
|
||||||
|
private readonly List<(string Campo, string Antes, string Despues)> _cambiosConfiguracionSinGuardar = new();
|
||||||
|
private bool _editandoConfiguracionAvanzada;
|
||||||
|
private bool _forzarPersistenciaConfiguracion;
|
||||||
|
private bool _mostrarConfirmacionCerrarConfiguracion;
|
||||||
|
|
||||||
|
private static readonly HashSet<string> PropiedadesFueraConfiguracionAvanzada = new(StringComparer.Ordinal)
|
||||||
|
{
|
||||||
|
nameof(ConfiguracionHistorialRuta.MostrarParadas),
|
||||||
|
nameof(ConfiguracionHistorialRuta.UsarColorRealLineaEnItinerarios),
|
||||||
|
nameof(ConfiguracionHistorialRuta.CriterioPrioritarioRuta),
|
||||||
|
nameof(ConfiguracionHistorialRuta.PreferenciaEtiquetaRuta)
|
||||||
|
};
|
||||||
|
|
||||||
|
private void ToggleConfigPanel()
|
||||||
|
{
|
||||||
|
if (!_mostrarConfigAvanzada)
|
||||||
|
{
|
||||||
|
_configuracionAvanzadaAplicada = CrearConfiguracionLocal().Clonar();
|
||||||
|
_editandoConfiguracionAvanzada = true;
|
||||||
|
_cambiosConfiguracionSinGuardar.Clear();
|
||||||
|
_mostrarConfirmacionCerrarConfiguracion = false;
|
||||||
|
_mostrarConfigAvanzada = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SolicitarCierreConfiguracionAvanzada();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool SolicitarCierreConfiguracionAvanzada()
|
||||||
|
{
|
||||||
|
ActualizarCambiosConfiguracionSinGuardar();
|
||||||
|
if (_cambiosConfiguracionSinGuardar.Count > 0)
|
||||||
|
{
|
||||||
|
_mostrarConfirmacionCerrarConfiguracion = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CerrarConfiguracionAvanzada();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ActualizarCambiosConfiguracionSinGuardar()
|
||||||
|
{
|
||||||
|
_cambiosConfiguracionSinGuardar.Clear();
|
||||||
|
if (_configuracionAvanzadaAplicada is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var actual = CrearConfiguracionLocal();
|
||||||
|
foreach (var propiedad in typeof(ConfiguracionHistorialRuta).GetProperties())
|
||||||
|
{
|
||||||
|
if (propiedad.Name.StartsWith("Version", StringComparison.Ordinal) ||
|
||||||
|
PropiedadesFueraConfiguracionAvanzada.Contains(propiedad.Name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var valorAntes = propiedad.GetValue(_configuracionAvanzadaAplicada);
|
||||||
|
var valorDespues = propiedad.GetValue(actual);
|
||||||
|
if (JsonSerializer.Serialize(valorAntes) == JsonSerializer.Serialize(valorDespues))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var nombre = Regex.Replace(propiedad.Name, "([a-z0-9])([A-Z])", "$1 $2");
|
||||||
|
_cambiosConfiguracionSinGuardar.Add((
|
||||||
|
nombre,
|
||||||
|
FormatearValorConfiguracion(valorAntes),
|
||||||
|
FormatearValorConfiguracion(valorDespues)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatearValorConfiguracion(object? valor)
|
||||||
|
=> valor switch
|
||||||
|
{
|
||||||
|
null => "-",
|
||||||
|
bool booleano => booleano ? "Sí" : "No",
|
||||||
|
IEnumerable<int> numeros => numeros.Any() ? string.Join(", ", numeros) : "Ninguno",
|
||||||
|
IFormattable formateable => formateable.ToString(null, CultureInfo.InvariantCulture),
|
||||||
|
_ => valor.ToString() ?? "-"
|
||||||
|
};
|
||||||
|
|
||||||
|
private void CancelarCierreConfiguracionAvanzada()
|
||||||
|
{
|
||||||
|
_mostrarConfirmacionCerrarConfiguracion = false;
|
||||||
|
_cambiosConfiguracionSinGuardar.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DescartarCambiosConfiguracionAvanzadaAsync()
|
||||||
|
{
|
||||||
|
if (_configuracionAvanzadaAplicada is not null)
|
||||||
|
{
|
||||||
|
var actual = CrearConfiguracionLocal();
|
||||||
|
var restaurada = _configuracionAvanzadaAplicada.Clonar();
|
||||||
|
|
||||||
|
restaurada.MostrarParadas = actual.MostrarParadas;
|
||||||
|
restaurada.UsarColorRealLineaEnItinerarios = actual.UsarColorRealLineaEnItinerarios;
|
||||||
|
restaurada.CriterioPrioritarioRuta = actual.CriterioPrioritarioRuta;
|
||||||
|
restaurada.PreferenciaEtiquetaRuta = actual.PreferenciaEtiquetaRuta;
|
||||||
|
AplicarConfiguracionLocal(restaurada);
|
||||||
|
|
||||||
|
if (_usarHoraSimulada)
|
||||||
|
StopClock();
|
||||||
|
else
|
||||||
|
StartClock();
|
||||||
|
|
||||||
|
await RefrescarHoraUIAsync();
|
||||||
|
await PersistirConfiguracionConfirmadaAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
CerrarConfiguracionAvanzada();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CerrarConfiguracionAvanzada()
|
||||||
|
{
|
||||||
|
_mostrarConfirmacionCerrarConfiguracion = false;
|
||||||
|
_mostrarConfiguracionPendientesRuta = false;
|
||||||
|
_selectorColorPendienteRuta = null;
|
||||||
|
_cambiosConfiguracionSinGuardar.Clear();
|
||||||
|
_configuracionAvanzadaAplicada = null;
|
||||||
|
_editandoConfiguracionAvanzada = false;
|
||||||
|
_mostrarConfigAvanzada = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task PersistirConfiguracionConfirmadaAsync()
|
||||||
|
{
|
||||||
|
var forzarAnterior = _forzarPersistenciaConfiguracion;
|
||||||
|
_forzarPersistenciaConfiguracion = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await PersistirConfiguracionAsync();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_forzarPersistenciaConfiguracion = forzarAnterior;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MarcarConfiguracionAvanzadaComoGuardada()
|
||||||
|
{
|
||||||
|
if (!_editandoConfiguracionAvanzada)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_configuracionAvanzadaAplicada = CrearConfiguracionLocal().Clonar();
|
||||||
|
_cambiosConfiguracionSinGuardar.Clear();
|
||||||
|
_mostrarConfirmacionCerrarConfiguracion = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,10 +39,6 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
private const string DashArrayPiePunteado = "1 7";
|
private const string DashArrayPiePunteado = "1 7";
|
||||||
|
|
||||||
private bool _mostrarConfigAvanzada = false;
|
private bool _mostrarConfigAvanzada = false;
|
||||||
/// <summary>
|
|
||||||
/// Alterna la configuracion panel.
|
|
||||||
/// </summary>
|
|
||||||
private void ToggleConfigPanel() => _mostrarConfigAvanzada = !_mostrarConfigAvanzada;
|
|
||||||
|
|
||||||
private int _nivelBrilloMapa = 0;
|
private int _nivelBrilloMapa = 0;
|
||||||
|
|
||||||
@@ -332,7 +328,7 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
{
|
{
|
||||||
new RealTimeMap.BasemapLayer
|
new RealTimeMap.BasemapLayer
|
||||||
{
|
{
|
||||||
url = "https://osm.tecnosis.net/osm_tiles/{z}/{x}/{y}.png",
|
url = "http://192.168.41.12/osm_tiles/{z}/{x}/{y}.png",
|
||||||
attribution = "© OpenStreetMap",
|
attribution = "© OpenStreetMap",
|
||||||
title = "",
|
title = "",
|
||||||
detectRetina = true
|
detectRetina = true
|
||||||
|
|||||||
@@ -150,7 +150,8 @@ public partial class PlanificadorRutas
|
|||||||
_mostrarInformacionDerivacionHistorial = false;
|
_mostrarInformacionDerivacionHistorial = false;
|
||||||
_historialLocalCargando = false;
|
_historialLocalCargando = false;
|
||||||
StopRefrescoHistorialCompartido();
|
StopRefrescoHistorialCompartido();
|
||||||
await RestaurarConfiguracionTemporalHistorialAsync();
|
// Cerrar el panel no debe separar la configuracion visible de la ruta calculada.
|
||||||
|
// La configuracion previa solo se recupera al elegir expresamente "Actual".
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1572,25 +1573,13 @@ public partial class PlanificadorRutas
|
|||||||
{
|
{
|
||||||
ModoConfiguracionHistorial.Guardada => CrearConfiguracionGuardadaHistorial(item),
|
ModoConfiguracionHistorial.Guardada => CrearConfiguracionGuardadaHistorial(item),
|
||||||
ModoConfiguracionHistorial.Predeterminada =>
|
ModoConfiguracionHistorial.Predeterminada =>
|
||||||
CrearConfiguracionPredeterminadaParaHistorial(item),
|
CrearConfiguracionPredeterminadaParaHistorial(),
|
||||||
_ => null
|
_ => null
|
||||||
};
|
};
|
||||||
|
|
||||||
if (configuracionHistorial is not null)
|
if (configuracionHistorial is not null)
|
||||||
{
|
|
||||||
AplicarConfiguracionLocal(configuracionHistorial);
|
AplicarConfiguracionLocal(configuracionHistorial);
|
||||||
|
|
||||||
// El factor cargado desde un historial ya se conservaba al cerrar el panel.
|
|
||||||
if (_modoConfiguracionHistorial == ModoConfiguracionHistorial.Guardada &&
|
|
||||||
_configuracionTemporalPreviaHistorial is not null)
|
|
||||||
{
|
|
||||||
_configuracionTemporalPreviaHistorial.FactorEquilibradoAndarBus =
|
|
||||||
_factorEquilibradoAndarBus;
|
|
||||||
_configuracionTemporalPreviaHistorial.VersionFactorEquilibrado =
|
|
||||||
VersionPersistenciaFactorEquilibrado;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_busFilteredCache.Clear();
|
_busFilteredCache.Clear();
|
||||||
|
|
||||||
SincronizarSegundosPorParadaConHorarios();
|
SincronizarSegundosPorParadaConHorarios();
|
||||||
@@ -1654,29 +1643,8 @@ public partial class PlanificadorRutas
|
|||||||
return configuracion;
|
return configuracion;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfiguracionHistorialRuta CrearConfiguracionPredeterminadaParaHistorial(
|
private ConfiguracionHistorialRuta CrearConfiguracionPredeterminadaParaHistorial()
|
||||||
RegistroHistorialRuta item)
|
=> CrearConfiguracionPredeterminadaHistorial();
|
||||||
{
|
|
||||||
var predeterminada = CrearConfiguracionPredeterminadaHistorial();
|
|
||||||
var guardada = CrearConfiguracionGuardadaHistorial(item);
|
|
||||||
predeterminada.UsarHoraSimulada = guardada.UsarHoraSimulada;
|
|
||||||
|
|
||||||
if (guardada.UsarHoraSimulada)
|
|
||||||
{
|
|
||||||
predeterminada.FechaSimulada = guardada.FechaSimulada;
|
|
||||||
predeterminada.HoraSimulada = guardada.HoraSimulada;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var ahora = DateTime.Now;
|
|
||||||
predeterminada.FechaSimulada = DateOnly.FromDateTime(ahora)
|
|
||||||
.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
|
|
||||||
predeterminada.HoraSimulada = TimeOnly.FromDateTime(ahora)
|
|
||||||
.ToString("HH:mm:ss", CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
return predeterminada;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CapturarConfiguracionTemporalAntesDeHistorial()
|
private void CapturarConfiguracionTemporalAntesDeHistorial()
|
||||||
{
|
{
|
||||||
@@ -1687,37 +1655,6 @@ public partial class PlanificadorRutas
|
|||||||
_configuracionParametrosActualesHistorial = CrearConfiguracionLocal();
|
_configuracionParametrosActualesHistorial = CrearConfiguracionLocal();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RestaurarConfiguracionTemporalHistorialAsync()
|
|
||||||
{
|
|
||||||
var configuracionPrevia = _configuracionTemporalPreviaHistorial;
|
|
||||||
_configuracionTemporalPreviaHistorial = null;
|
|
||||||
_configuracionParametrosActualesHistorial = null;
|
|
||||||
|
|
||||||
if (configuracionPrevia is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var mostrarParadasAntes = _mostrarParadas;
|
|
||||||
AplicarConfiguracionLocal(configuracionPrevia);
|
|
||||||
|
|
||||||
if (_mapa is not null && mostrarParadasAntes != _mostrarParadas)
|
|
||||||
{
|
|
||||||
if (_mostrarParadas)
|
|
||||||
await DibujarParadasAsync();
|
|
||||||
else
|
|
||||||
await OcultarParadasAsync();
|
|
||||||
|
|
||||||
await SincronizarMarcadoresOrigenDestinoJsAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
StopClock();
|
|
||||||
if (_usarHoraSimulada)
|
|
||||||
await RefrescarHoraUIAsync();
|
|
||||||
else
|
|
||||||
StartClock();
|
|
||||||
|
|
||||||
await PersistirConfiguracionAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private RegistroHistorialRuta? ConstruirRegistroHistorialActual()
|
private RegistroHistorialRuta? ConstruirRegistroHistorialActual()
|
||||||
{
|
{
|
||||||
if (_coordenadasOrigen is null || _coordenadasDestino is null)
|
if (_coordenadasOrigen is null || _coordenadasDestino is null)
|
||||||
|
|||||||
@@ -1506,7 +1506,7 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
private bool _elevPopupMinimizado = false;
|
private bool _elevPopupMinimizado = false;
|
||||||
|
|
||||||
|
|
||||||
private const string _versionApp = "(v-20260916a)";
|
private const string _versionApp = "(v-20260917a)";
|
||||||
|
|
||||||
|
|
||||||
private double? _paradaElevIdee;
|
private double? _paradaElevIdee;
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ public partial class PlanificadorRutas
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task PersistirConfiguracionAsync()
|
private async Task PersistirConfiguracionAsync()
|
||||||
{
|
{
|
||||||
if (!_configuracionLocalCargada)
|
if (!_configuracionLocalCargada ||
|
||||||
|
(_editandoConfiguracionAvanzada && !_forzarPersistenciaConfiguracion))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -454,7 +455,8 @@ public partial class PlanificadorRutas
|
|||||||
SincronizarTextosPenalizacionPie();
|
SincronizarTextosPenalizacionPie();
|
||||||
SincronizarSegundosPorParadaConHorarios();
|
SincronizarSegundosPorParadaConHorarios();
|
||||||
await RefrescarHoraUIAsync();
|
await RefrescarHoraUIAsync();
|
||||||
await PersistirConfiguracionAsync();
|
await PersistirConfiguracionConfirmadaAsync();
|
||||||
|
MarcarConfiguracionAvanzadaComoGuardada();
|
||||||
await PersistirModoConfiguracionHistorialAsync();
|
await PersistirModoConfiguracionHistorialAsync();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
@@ -476,7 +478,8 @@ public partial class PlanificadorRutas
|
|||||||
SincronizarTextosPenalizacionPie();
|
SincronizarTextosPenalizacionPie();
|
||||||
SincronizarSegundosPorParadaConHorarios();
|
SincronizarSegundosPorParadaConHorarios();
|
||||||
await RefrescarHoraUIAsync();
|
await RefrescarHoraUIAsync();
|
||||||
await PersistirConfiguracionAsync();
|
await PersistirConfiguracionConfirmadaAsync();
|
||||||
|
MarcarConfiguracionAvanzadaComoGuardada();
|
||||||
await PersistirModoConfiguracionHistorialAsync();
|
await PersistirModoConfiguracionHistorialAsync();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1302,8 +1302,14 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task RecalcularConParametros()
|
private async Task RecalcularConParametros()
|
||||||
{
|
{
|
||||||
if (_coordenadasOrigen is null || _coordenadasDestino is null) return;
|
await PersistirConfiguracionConfirmadaAsync();
|
||||||
await PersistirConfiguracionAsync();
|
MarcarConfiguracionAvanzadaComoGuardada();
|
||||||
|
|
||||||
|
if (_coordenadasOrigen is null || _coordenadasDestino is null)
|
||||||
|
{
|
||||||
|
StateHasChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_mapa is not null)
|
if (_mapa is not null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,7 +96,9 @@ public partial class PlanificadorRutas
|
|||||||
|
|
||||||
private async Task AbrirHerramientaZonasAsync()
|
private async Task AbrirHerramientaZonasAsync()
|
||||||
{
|
{
|
||||||
_mostrarConfigAvanzada = false;
|
if (_mostrarConfigAvanzada && !SolicitarCierreConfiguracionAvanzada())
|
||||||
|
return;
|
||||||
|
|
||||||
_mostrarHerramientaZonas = true;
|
_mostrarHerramientaZonas = true;
|
||||||
await ActualizarEditorExclusionCaminataAsync();
|
await ActualizarEditorExclusionCaminataAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,21 +15,12 @@ public partial class PlanificadorRutas
|
|||||||
private bool _guardandoFabrica;
|
private bool _guardandoFabrica;
|
||||||
|
|
||||||
private ConfiguracionHistorialRuta CrearConfiguracionPredeterminadaHistorial()
|
private ConfiguracionHistorialRuta CrearConfiguracionPredeterminadaHistorial()
|
||||||
{
|
=> _configuracionFabrica?.Clonar() ?? CrearConfiguracionBaseHistorial();
|
||||||
var config = _configuracionFabrica?.Clonar() ?? CrearConfiguracionBaseHistorial();
|
|
||||||
var ahora = DateTime.Now;
|
|
||||||
config.FechaSimulada = ahora.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
|
|
||||||
config.HoraSimulada = ahora.ToString("HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AplicarValoresFabricaConservandoSeleccion()
|
private void AplicarValoresFabricaConservandoSeleccion()
|
||||||
{
|
{
|
||||||
var actual = CrearConfiguracionLocal();
|
var actual = CrearConfiguracionLocal();
|
||||||
var predeterminada = CrearConfiguracionPredeterminadaHistorial();
|
var predeterminada = CrearConfiguracionPredeterminadaHistorial();
|
||||||
predeterminada.UsarHoraSimulada = actual.UsarHoraSimulada;
|
|
||||||
predeterminada.FechaSimulada = actual.FechaSimulada;
|
|
||||||
predeterminada.HoraSimulada = actual.HoraSimulada;
|
|
||||||
predeterminada.CriterioPrioritarioRuta = actual.CriterioPrioritarioRuta;
|
predeterminada.CriterioPrioritarioRuta = actual.CriterioPrioritarioRuta;
|
||||||
predeterminada.PreferenciaEtiquetaRuta = actual.PreferenciaEtiquetaRuta;
|
predeterminada.PreferenciaEtiquetaRuta = actual.PreferenciaEtiquetaRuta;
|
||||||
AplicarConfiguracionLocal(predeterminada);
|
AplicarConfiguracionLocal(predeterminada);
|
||||||
|
|||||||
@@ -1968,7 +1968,7 @@
|
|||||||
|
|
||||||
<div class="config-actions-row">
|
<div class="config-actions-row">
|
||||||
<button class="btn-ghost" @onclick="RecalcularConParametros">
|
<button class="btn-ghost" @onclick="RecalcularConParametros">
|
||||||
Recalcular
|
Guardar y recalcular
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="btn-ghost btn-ghost--secondary" @onclick="PedirConfirmacionRestablecer">
|
<button class="btn-ghost btn-ghost--secondary" @onclick="PedirConfirmacionRestablecer">
|
||||||
@@ -2389,6 +2389,34 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@if (_mostrarConfirmacionCerrarConfiguracion)
|
||||||
|
{
|
||||||
|
<div class="custom-modal-backdrop" @onclick="CancelarCierreConfiguracionAvanzada">
|
||||||
|
<div class="custom-modal-card config-unsaved-confirmation"
|
||||||
|
@onclick:stopPropagation="true"
|
||||||
|
role="dialog"
|
||||||
|
aria-modal="true"
|
||||||
|
aria-label="Cambios de configuración sin guardar">
|
||||||
|
<div class="custom-modal-title">Cambios sin guardar</div>
|
||||||
|
<p>Si cierras la configuración avanzada, se perderán estos cambios:</p>
|
||||||
|
<div class="config-unsaved-changes">
|
||||||
|
@foreach (var cambio in _cambiosConfiguracionSinGuardar)
|
||||||
|
{
|
||||||
|
<div><b>@cambio.Campo:</b> @cambio.Antes → @cambio.Despues</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="custom-modal-actions">
|
||||||
|
<button class="btn-ghost" @onclick="CancelarCierreConfiguracionAvanzada">
|
||||||
|
Seguir editando
|
||||||
|
</button>
|
||||||
|
<button class="btn-ghost btn-ghost--secondary" @onclick="DescartarCambiosConfiguracionAvanzadaAsync">
|
||||||
|
Descartar cambios
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
@if (_fabricaPendiente is not null || _mensajeFabrica is not null)
|
@if (_fabricaPendiente is not null || _mensajeFabrica is not null)
|
||||||
{
|
{
|
||||||
<div class="custom-modal-backdrop" @onclick="CancelarGuardadoFabrica">
|
<div class="custom-modal-backdrop" @onclick="CancelarGuardadoFabrica">
|
||||||
|
|||||||
@@ -125,8 +125,20 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
|||||||
}
|
}
|
||||||
|
|
||||||
var alternativasSoloPie = await CrearAlternativasSoloPieAsync(origenLatLon, destinoLatLon, parametros);
|
var alternativasSoloPie = await CrearAlternativasSoloPieAsync(origenLatLon, destinoLatLon, parametros);
|
||||||
var candidatasOrigen = await SeleccionarCandidatasAsync(indiceTransito, origenLatLon[0], origenLatLon[1], parametros, ct);
|
var seleccionOrigen = await SeleccionarCandidatasAsync(
|
||||||
var candidatasDestino = await SeleccionarCandidatasAsync(indiceTransito, destinoLatLon[0], destinoLatLon[1], parametros, ct);
|
indiceTransito,
|
||||||
|
origenLatLon[0],
|
||||||
|
origenLatLon[1],
|
||||||
|
parametros,
|
||||||
|
ct);
|
||||||
|
var seleccionDestino = await SeleccionarCandidatasAsync(
|
||||||
|
indiceTransito,
|
||||||
|
destinoLatLon[0],
|
||||||
|
destinoLatLon[1],
|
||||||
|
parametros,
|
||||||
|
ct);
|
||||||
|
var candidatasOrigen = seleccionOrigen.Principales;
|
||||||
|
var candidatasDestino = seleccionDestino.Principales;
|
||||||
|
|
||||||
if (candidatasOrigen.Count == 0 || candidatasDestino.Count == 0)
|
if (candidatasOrigen.Count == 0 || candidatasDestino.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -167,8 +179,8 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
|||||||
{
|
{
|
||||||
var directasRobustas = BuscarDirectasRobustasConHorario(
|
var directasRobustas = BuscarDirectasRobustasConHorario(
|
||||||
indiceTransito,
|
indiceTransito,
|
||||||
candidatasOrigen,
|
seleccionOrigen.Amplias,
|
||||||
candidatasDestino,
|
seleccionDestino.Amplias,
|
||||||
instanteSalida,
|
instanteSalida,
|
||||||
parametros);
|
parametros);
|
||||||
var continuidadesCirculares = BuscarContinuidadesCircularesConHorario(
|
var continuidadesCirculares = BuscarContinuidadesCircularesConHorario(
|
||||||
@@ -2017,7 +2029,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selecciona las paradas cercanas mas prometedoras.
|
/// Selecciona las paradas cercanas mas prometedoras.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task<List<ParadaCandidata>> SeleccionarCandidatasAsync(
|
private async Task<(List<ParadaCandidata> Principales, List<ParadaCandidata> Amplias)> SeleccionarCandidatasAsync(
|
||||||
IndiceTransitoDbus indiceTransito,
|
IndiceTransitoDbus indiceTransito,
|
||||||
double latitud,
|
double latitud,
|
||||||
double longitud,
|
double longitud,
|
||||||
@@ -2064,7 +2076,11 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
|||||||
|
|
||||||
if (!validarExclusionesV2 &&
|
if (!validarExclusionesV2 &&
|
||||||
(!parametros.UsarOsrmParaRanking || parametros.ActivarRangoLineas || parametros.ActivarRangoItinerarios))
|
(!parametros.UsarOsrmParaRanking || parametros.ActivarRangoLineas || parametros.ActivarRangoItinerarios))
|
||||||
return SeleccionarCandidatasConCoberturaPatrones(candidatas, maximo, indiceTransito, parametros);
|
{
|
||||||
|
return (
|
||||||
|
SeleccionarCandidatasConCoberturaPatrones(candidatas, maximo, indiceTransito, parametros),
|
||||||
|
candidatas);
|
||||||
|
}
|
||||||
|
|
||||||
var semaforo = new SemaphoreSlim(4, 4);
|
var semaforo = new SemaphoreSlim(4, 4);
|
||||||
var tareas = candidatas.Select(async candidata =>
|
var tareas = candidatas.Select(async candidata =>
|
||||||
@@ -2113,7 +2129,9 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
|||||||
.ThenBy(x => x.DistanciaEuclidea)
|
.ThenBy(x => x.DistanciaEuclidea)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return SeleccionarCandidatasConCoberturaPatrones(candidatasOrdenadas, maximo, indiceTransito, parametros);
|
return (
|
||||||
|
SeleccionarCandidatasConCoberturaPatrones(candidatasOrdenadas, maximo, indiceTransito, parametros),
|
||||||
|
candidatasOrdenadas);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1413,9 +1413,12 @@ html, body {
|
|||||||
.btn-ghost.inspector-walk-eye { display: inline-flex; padding: 2px 5px; min-height: 0; vertical-align: middle; margin-left: 5px; }
|
.btn-ghost.inspector-walk-eye { display: inline-flex; padding: 2px 5px; min-height: 0; vertical-align: middle; margin-left: 5px; }
|
||||||
.inspector-walk-eye[aria-pressed="true"] { color: #22d3ee; border-color: #22d3ee; }
|
.inspector-walk-eye[aria-pressed="true"] { color: #22d3ee; border-color: #22d3ee; }
|
||||||
|
|
||||||
.fabrica-confirmacion { width: min(560px, calc(100vw - 24px)); max-height: calc(100dvh - 32px); overflow-y: auto; }
|
.fabrica-confirmacion,
|
||||||
.fabrica-cambios { max-height: 45dvh; overflow-y: auto; font-size: .8rem; overflow-wrap: anywhere; }
|
.config-unsaved-confirmation { width: min(560px, calc(100vw - 24px)); max-height: calc(100dvh - 32px); overflow-y: auto; }
|
||||||
.fabrica-cambios > div { padding: 5px 0; border-bottom: 1px solid #374151; }
|
.fabrica-cambios,
|
||||||
|
.config-unsaved-changes { max-height: 45dvh; overflow-y: auto; font-size: .8rem; overflow-wrap: anywhere; }
|
||||||
|
.fabrica-cambios > div,
|
||||||
|
.config-unsaved-changes > div { padding: 5px 0; border-bottom: 1px solid #374151; }
|
||||||
|
|
||||||
.route-score-detail-line {
|
.route-score-detail-line {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
@@ -2196,6 +2199,14 @@ html, body {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.config-actions-row .btn-ghost:first-child {
|
||||||
|
flex-grow: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-actions-row .btn-ghost:last-child {
|
||||||
|
flex-grow: .85;
|
||||||
|
}
|
||||||
|
|
||||||
.custom-modal-backdrop {
|
.custom-modal-backdrop {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const TILE_CACHE = 'tile-cache-v1';
|
const TILE_CACHE = 'tile-cache-v1';
|
||||||
const TILE_PREFIX = 'https://osm.tecnosis.net/osm_tiles/';
|
const TILE_PREFIX = 'http://192.168.41.12/osm_tiles/';
|
||||||
|
|
||||||
self.addEventListener('install', event => {
|
self.addEventListener('install', event => {
|
||||||
self.skipWaiting();
|
self.skipWaiting();
|
||||||
|
|||||||
@@ -20,6 +20,30 @@ var baseMethod = typeof(PlanificadorRutas).GetMethod("CrearConfiguracionBaseHist
|
|||||||
var defaults = (ConfiguracionHistorialRuta)baseMethod.Invoke(null, null)!;
|
var defaults = (ConfiguracionHistorialRuta)baseMethod.Invoke(null, null)!;
|
||||||
Check(defaults.PesoTransbordoRankingMinutos == 6, "Penalizacion inicial de 6 minutos");
|
Check(defaults.PesoTransbordoRankingMinutos == 6, "Penalizacion inicial de 6 minutos");
|
||||||
|
|
||||||
|
var panelSinCambios = new PlanificadorRutas();
|
||||||
|
var alternarPanel = typeof(PlanificadorRutas).GetMethod(
|
||||||
|
"ToggleConfigPanel",
|
||||||
|
BindingFlags.Instance | BindingFlags.NonPublic)!;
|
||||||
|
var solicitarCierre = typeof(PlanificadorRutas).GetMethod(
|
||||||
|
"SolicitarCierreConfiguracionAvanzada",
|
||||||
|
BindingFlags.Instance | BindingFlags.NonPublic)!;
|
||||||
|
alternarPanel.Invoke(panelSinCambios, null);
|
||||||
|
Check(
|
||||||
|
solicitarCierre.Invoke(panelSinCambios, null) is true,
|
||||||
|
"Configuracion avanzada sin cambios se cierra directamente");
|
||||||
|
|
||||||
|
var panelConCambios = new PlanificadorRutas();
|
||||||
|
alternarPanel.Invoke(panelConCambios, null);
|
||||||
|
typeof(PlanificadorRutas)
|
||||||
|
.GetField("_velocidadPieKmH", BindingFlags.Instance | BindingFlags.NonPublic)!
|
||||||
|
.SetValue(panelConCambios, 4.2);
|
||||||
|
Check(
|
||||||
|
solicitarCierre.Invoke(panelConCambios, null) is false &&
|
||||||
|
(bool)typeof(PlanificadorRutas)
|
||||||
|
.GetField("_mostrarConfirmacionCerrarConfiguracion", BindingFlags.Instance | BindingFlags.NonPublic)!
|
||||||
|
.GetValue(panelConCambios)!,
|
||||||
|
"Configuracion avanzada avisa antes de descartar cambios");
|
||||||
|
|
||||||
var folder = Path.Combine(Path.GetTempPath(), "rutasdbus-regression-" + Guid.NewGuid().ToString("N"));
|
var folder = Path.Combine(Path.GetTempPath(), "rutasdbus-regression-" + Guid.NewGuid().ToString("N"));
|
||||||
IConfiguration Config() => new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string?>
|
IConfiguration Config() => new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string?>
|
||||||
{
|
{
|
||||||
@@ -37,7 +61,29 @@ try
|
|||||||
await File.WriteAllTextAsync(file, JsonSerializer.Serialize(defaults));
|
await File.WriteAllTextAsync(file, JsonSerializer.Serialize(defaults));
|
||||||
var loaded = await Service().CargarAsync();
|
var loaded = await Service().CargarAsync();
|
||||||
Check(loaded?.PesoTransbordoRankingMinutos == 9, "Valores compartidos entre instancias");
|
Check(loaded?.PesoTransbordoRankingMinutos == 9, "Valores compartidos entre instancias");
|
||||||
Check(loaded is { FechaSimulada: null, HoraSimulada: null }, "Los valores de fabrica no fijan la fecha y hora");
|
Check(loaded is { FechaSimulada: null, HoraSimulada: null }, "Valores antiguos sin fecha y hora siguen siendo validos");
|
||||||
|
|
||||||
|
var guardadaConFecha = defaults.Clonar();
|
||||||
|
guardadaConFecha.FechaSimulada = "2026-09-16";
|
||||||
|
guardadaConFecha.HoraSimulada = "13:40:00";
|
||||||
|
Check(await Service().GuardarAsync(guardadaConFecha), "Los valores de fabrica permiten guardar fecha y hora");
|
||||||
|
var cargadaConFecha = await Service().CargarAsync();
|
||||||
|
Check(
|
||||||
|
cargadaConFecha is { FechaSimulada: "2026-09-16", HoraSimulada: "13:40:00" },
|
||||||
|
"Los valores de fabrica recuperan la fecha y hora guardadas");
|
||||||
|
|
||||||
|
var pagina = new PlanificadorRutas();
|
||||||
|
typeof(PlanificadorRutas)
|
||||||
|
.GetField("_configuracionFabrica", BindingFlags.Instance | BindingFlags.NonPublic)!
|
||||||
|
.SetValue(pagina, cargadaConFecha);
|
||||||
|
var crearPredeterminada = typeof(PlanificadorRutas).GetMethod(
|
||||||
|
"CrearConfiguracionPredeterminadaHistorial",
|
||||||
|
BindingFlags.Instance | BindingFlags.NonPublic)!;
|
||||||
|
var predeterminada = (ConfiguracionHistorialRuta)crearPredeterminada.Invoke(pagina, null)!;
|
||||||
|
Check(
|
||||||
|
predeterminada is { FechaSimulada: "2026-09-16", HoraSimulada: "13:40:00" },
|
||||||
|
"Restaurar conserva la fecha y hora de los valores de fabrica");
|
||||||
|
|
||||||
File.WriteAllText(file, "{incompleto");
|
File.WriteAllText(file, "{incompleto");
|
||||||
Check(await Service().CargarAsync() is null, "JSON danado permite usar valores base");
|
Check(await Service().CargarAsync() is null, "JSON danado permite usar valores base");
|
||||||
}
|
}
|
||||||
@@ -183,32 +229,50 @@ var page = new PlanificadorRutas();
|
|||||||
var flags = BindingFlags.Instance | BindingFlags.NonPublic;
|
var flags = BindingFlags.Instance | BindingFlags.NonPublic;
|
||||||
var fabricaHistorial = (ConfiguracionHistorialRuta)baseMethod.Invoke(null, null)!;
|
var fabricaHistorial = (ConfiguracionHistorialRuta)baseMethod.Invoke(null, null)!;
|
||||||
fabricaHistorial.FactorEquilibradoAndarBus = 6;
|
fabricaHistorial.FactorEquilibradoAndarBus = 6;
|
||||||
|
fabricaHistorial.UsarHoraSimulada = true;
|
||||||
|
fabricaHistorial.FechaSimulada = "2026-09-16";
|
||||||
|
fabricaHistorial.HoraSimulada = "13:40:00";
|
||||||
typeof(PlanificadorRutas).GetField("_configuracionFabrica", flags)!.SetValue(page, fabricaHistorial);
|
typeof(PlanificadorRutas).GetField("_configuracionFabrica", flags)!.SetValue(page, fabricaHistorial);
|
||||||
var crearPredeterminadaHistorial = typeof(PlanificadorRutas).GetMethod(
|
var crearPredeterminadaHistorial = typeof(PlanificadorRutas).GetMethod(
|
||||||
"CrearConfiguracionPredeterminadaParaHistorial", flags)!;
|
"CrearConfiguracionPredeterminadaParaHistorial", flags)!;
|
||||||
|
var crearGuardadaHistorial = typeof(PlanificadorRutas).GetMethod(
|
||||||
|
"CrearConfiguracionGuardadaHistorial", flags)!;
|
||||||
var configuracionGuardada = fabricaHistorial.Clonar();
|
var configuracionGuardada = fabricaHistorial.Clonar();
|
||||||
configuracionGuardada.UsarHoraSimulada = true;
|
configuracionGuardada.UsarHoraSimulada = true;
|
||||||
configuracionGuardada.FechaSimulada = "2026-04-08";
|
configuracionGuardada.FechaSimulada = "2026-04-08";
|
||||||
configuracionGuardada.HoraSimulada = "08:46:17";
|
configuracionGuardada.HoraSimulada = "08:46:17";
|
||||||
configuracionGuardada.FactorEquilibradoAndarBus = 99;
|
configuracionGuardada.FactorEquilibradoAndarBus = 99;
|
||||||
var registroConHora = new RegistroHistorialRuta { Configuracion = configuracionGuardada };
|
var registroConHora = new RegistroHistorialRuta { Configuracion = configuracionGuardada };
|
||||||
var predeterminadaConHora = (ConfiguracionHistorialRuta)crearPredeterminadaHistorial.Invoke(
|
var predeterminadaHistorial = (ConfiguracionHistorialRuta)crearPredeterminadaHistorial.Invoke(page, null)!;
|
||||||
|
Check(predeterminadaHistorial.UsarHoraSimulada &&
|
||||||
|
predeterminadaHistorial.FechaSimulada == "2026-09-16" &&
|
||||||
|
predeterminadaHistorial.HoraSimulada == "13:40:00" &&
|
||||||
|
predeterminadaHistorial.FactorEquilibradoAndarBus == 6,
|
||||||
|
"Predeterminada usa tambien la fecha y hora de fabrica");
|
||||||
|
var guardada = (ConfiguracionHistorialRuta)crearGuardadaHistorial.Invoke(
|
||||||
page, new object[] { registroConHora })!;
|
page, new object[] { registroConHora })!;
|
||||||
Check(predeterminadaConHora.UsarHoraSimulada &&
|
Check(guardada.UsarHoraSimulada &&
|
||||||
predeterminadaConHora.FechaSimulada == "2026-04-08" &&
|
guardada.FechaSimulada == "2026-04-08" &&
|
||||||
predeterminadaConHora.HoraSimulada == "08:46:17" &&
|
guardada.HoraSimulada == "08:46:17" &&
|
||||||
predeterminadaConHora.FactorEquilibradoAndarBus == 6,
|
guardada.FactorEquilibradoAndarBus == 99,
|
||||||
"Predeterminada conserva solo la fecha y hora simuladas del historial");
|
"Guardada conserva la fecha, hora y parametros del historial");
|
||||||
configuracionGuardada.UsarHoraSimulada = false;
|
var paginaCierreHistorial = new PlanificadorRutas();
|
||||||
configuracionGuardada.FechaSimulada = "2020-01-01";
|
typeof(PlanificadorRutas).GetField("_mostrarHistorialRutas", flags)!
|
||||||
configuracionGuardada.HoraSimulada = "01:02:03";
|
.SetValue(paginaCierreHistorial, true);
|
||||||
var predeterminadaSinHora = (ConfiguracionHistorialRuta)crearPredeterminadaHistorial.Invoke(
|
typeof(PlanificadorRutas).GetField("_factorEquilibradoAndarBus", flags)!
|
||||||
page, new object[] { registroConHora })!;
|
.SetValue(paginaCierreHistorial, 99.0);
|
||||||
Check(!predeterminadaSinHora.UsarHoraSimulada &&
|
var configuracionAnteriorHistorial = fabricaHistorial.Clonar();
|
||||||
predeterminadaSinHora.FechaSimulada == DateOnly.FromDateTime(DateTime.Now)
|
configuracionAnteriorHistorial.FactorEquilibradoAndarBus = 6;
|
||||||
.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture) &&
|
typeof(PlanificadorRutas).GetField("_configuracionTemporalPreviaHistorial", flags)!
|
||||||
predeterminadaSinHora.HoraSimulada != "01:02:03",
|
.SetValue(paginaCierreHistorial, configuracionAnteriorHistorial);
|
||||||
"Predeterminada usa la hora actual cuando el historial no tenia simulacion");
|
var alternarHistorial = typeof(PlanificadorRutas).GetMethod("ToggleHistorialPanel", flags)!;
|
||||||
|
await (Task)alternarHistorial.Invoke(paginaCierreHistorial, null)!;
|
||||||
|
Check(
|
||||||
|
!(bool)typeof(PlanificadorRutas).GetField("_mostrarHistorialRutas", flags)!
|
||||||
|
.GetValue(paginaCierreHistorial)! &&
|
||||||
|
(double)typeof(PlanificadorRutas).GetField("_factorEquilibradoAndarBus", flags)!
|
||||||
|
.GetValue(paginaCierreHistorial)! == 99.0,
|
||||||
|
"Cerrar el historial conserva la configuracion de la ruta visible");
|
||||||
typeof(PlanificadorRutas).GetField("_factorEquilibradoAndarBus", flags)!.SetValue(page, 6.0);
|
typeof(PlanificadorRutas).GetField("_factorEquilibradoAndarBus", flags)!.SetValue(page, 6.0);
|
||||||
typeof(PlanificadorRutas).GetField("_factorPenalizacionDistanciaPie", flags)!.SetValue(page, 1.8);
|
typeof(PlanificadorRutas).GetField("_factorPenalizacionDistanciaPie", flags)!.SetValue(page, 1.8);
|
||||||
typeof(PlanificadorRutas).GetField("_parametroPenalizacionDistanciaPieMetros", flags)!.SetValue(page, 200.0);
|
typeof(PlanificadorRutas).GetField("_parametroPenalizacionDistanciaPieMetros", flags)!.SetValue(page, 200.0);
|
||||||
|
|||||||
Reference in New Issue
Block a user