cambio foco elemento compartido

poner km en los tramos de bus
line 16 oscurecida
flechas de sentido en las paradas
This commit is contained in:
2026-07-28 08:17:04 +02:00
parent f2e0b59faa
commit 8a75c583ca
8 changed files with 231 additions and 87 deletions

View File

@@ -465,13 +465,70 @@ public partial class PlanificadorRutas : ComponentBase
/// </summary>
private static List<object> BuildStopsDesdeParadas(IEnumerable<Parada> paradas)
{
var stops = new List<object>();
foreach (var parada in paradas)
stops.Add(new { lat = parada.Latitud, lon = parada.Longitud, code = parada.Codigo });
var paradasOrdenadas = paradas.ToList();
var stops = new List<object>(paradasOrdenadas.Count);
for (var indice = 0; indice < paradasOrdenadas.Count; indice++)
{
var parada = paradasOrdenadas[indice];
stops.Add(new
{
lat = parada.Latitud,
lon = parada.Longitud,
code = parada.Codigo,
bearing = CalcularRumboParada(paradasOrdenadas, indice)
});
}
return stops;
}
/// <summary>
/// Calcula el sentido de marcha hacia la siguiente parada; en la terminal conserva el rumbo de llegada.
/// </summary>
private static double? CalcularRumboParada(IReadOnlyList<Parada> paradas, int indice)
{
var actual = paradas[indice];
for (var siguiente = indice + 1; siguiente < paradas.Count; siguiente++)
{
var rumbo = CalcularRumboGrados(actual, paradas[siguiente]);
if (rumbo is not null)
return rumbo;
}
for (var anterior = indice - 1; anterior >= 0; anterior--)
{
var rumbo = CalcularRumboGrados(paradas[anterior], actual);
if (rumbo is not null)
return rumbo;
}
return null;
}
private static double? CalcularRumboGrados(Parada origen, Parada destino)
{
if (!double.IsFinite(origen.Latitud) ||
!double.IsFinite(origen.Longitud) ||
!double.IsFinite(destino.Latitud) ||
!double.IsFinite(destino.Longitud))
{
return null;
}
var latitudOrigen = origen.Latitud * Math.PI / 180.0;
var latitudDestino = destino.Latitud * Math.PI / 180.0;
var diferenciaLongitud = (destino.Longitud - origen.Longitud) * Math.PI / 180.0;
var y = Math.Sin(diferenciaLongitud) * Math.Cos(latitudDestino);
var x = Math.Cos(latitudOrigen) * Math.Sin(latitudDestino) -
Math.Sin(latitudOrigen) * Math.Cos(latitudDestino) * Math.Cos(diferenciaLongitud);
if (Math.Abs(x) < 1e-12 && Math.Abs(y) < 1e-12)
return null;
var rumbo = Math.Atan2(y, x) * 180.0 / Math.PI;
return (rumbo + 360.0) % 360.0;
}
/// <summary>
/// Construye las paradas visibles recorridas por una variante completa.
/// </summary>

View File

@@ -29,6 +29,7 @@ public partial class PlanificadorRutas
private bool _mostrarHistorialRutas = false;
private bool _refrescandoHistorialCompartido = false;
private bool _omitirRegistroHistorialEnSiguienteCalculo = false;
private bool _aplicandoRegistroHistorial = false;
private string? _historialCompartidoPendienteEliminarId;
private ConfiguracionLocalPlanificador? _configuracionTemporalPreviaHistorial;
private Task<bool>? _tareaCargaHistorialLocal;
@@ -181,7 +182,8 @@ public partial class PlanificadorRutas
{
_historialLocal.Clear();
_historialLocal.AddRange(items);
_historialLocalSeleccionadoId = _historialLocal.FirstOrDefault()?.Id ?? string.Empty;
if (!_historialLocal.Any(x => x.Id == _historialLocalSeleccionadoId))
_historialLocalSeleccionadoId = string.Empty;
_historialLocalCargado = true;
}
@@ -232,7 +234,7 @@ public partial class PlanificadorRutas
}
if (!_historialCompartido.Any(x => x.Id == _historialCompartidoSeleccionadoId))
_historialCompartidoSeleccionadoId = _historialCompartido[0].Id;
_historialCompartidoSeleccionadoId = string.Empty;
}
catch (Exception)
{
@@ -332,13 +334,12 @@ public partial class PlanificadorRutas
while (_historialLocal.Count > MaxItemsHistorialLocal)
_historialLocal.RemoveAt(_historialLocal.Count - 1);
_historialLocalSeleccionadoId = existente.Id;
await PersistirHistorialLocalAsync();
}
private async Task CargarHistorialLocalSeleccionadoAsync()
private async Task CargarHistorialLocalAsync(string id)
{
var item = _historialLocal.FirstOrDefault(x => x.Id == _historialLocalSeleccionadoId);
var item = _historialLocal.FirstOrDefault(x => x.Id == id);
if (item is null)
{
MostrarMensajeHistorial("No encuentro esa combinacion en tu historial personal.", esError: true);
@@ -346,18 +347,13 @@ public partial class PlanificadorRutas
}
await AplicarRegistroHistorialAsync(item);
SeleccionarHistorialLocal(id);
MostrarMensajeHistorial("Combinacion personal cargada.");
}
private async Task CargarHistorialLocalAsync(string id)
private async Task CargarHistorialCompartidoAsync(string id)
{
_historialLocalSeleccionadoId = id;
await CargarHistorialLocalSeleccionadoAsync();
}
private async Task CargarHistorialCompartidoSeleccionadoAsync()
{
var item = _historialCompartido.FirstOrDefault(x => x.Id == _historialCompartidoSeleccionadoId);
var item = _historialCompartido.FirstOrDefault(x => x.Id == id);
if (item is null)
{
MostrarMensajeHistorial("No encuentro esa combinacion en el historial compartido.", esError: true);
@@ -365,13 +361,26 @@ public partial class PlanificadorRutas
}
await AplicarRegistroHistorialAsync(item);
SeleccionarHistorialCompartido(id);
MostrarMensajeHistorial("Combinación compartida cargada.");
}
private async Task CargarHistorialCompartidoAsync(string id)
private void SeleccionarHistorialLocal(string id)
{
_historialLocalSeleccionadoId = id;
_historialCompartidoSeleccionadoId = string.Empty;
}
private void SeleccionarHistorialCompartido(string id)
{
_historialLocalSeleccionadoId = string.Empty;
_historialCompartidoSeleccionadoId = id;
await CargarHistorialCompartidoSeleccionadoAsync();
}
private void LimpiarSeleccionHistorial()
{
_historialLocalSeleccionadoId = string.Empty;
_historialCompartidoSeleccionadoId = string.Empty;
}
private async Task CompartirEscenarioActualAsync()
@@ -387,9 +396,8 @@ public partial class PlanificadorRutas
try
{
var guardado = await HistorialRutasCompartidoService.GuardarAsync(actual);
await HistorialRutasCompartidoService.GuardarAsync(actual);
await CargarHistorialCompartidoAsync();
_historialCompartidoSeleccionadoId = guardado.Id;
MostrarMensajeHistorial("Combinacion enviada al historial compartido.");
}
catch (Exception)
@@ -400,7 +408,6 @@ public partial class PlanificadorRutas
private async Task CompartirHistorialLocalAsync(string id)
{
_historialLocalSeleccionadoId = id;
var item = _historialLocal.FirstOrDefault(x => x.Id == id);
if (item is null)
{
@@ -410,9 +417,8 @@ public partial class PlanificadorRutas
try
{
var guardado = await HistorialRutasCompartidoService.GuardarAsync(item);
await HistorialRutasCompartidoService.GuardarAsync(item);
await CargarHistorialCompartidoAsync();
_historialCompartidoSeleccionadoId = guardado.Id;
MostrarMensajeHistorial("Combinacion enviada al historial compartido.");
}
catch (Exception)
@@ -433,7 +439,7 @@ public partial class PlanificadorRutas
_historialLocal.Remove(item);
if (_historialLocalSeleccionadoId == id)
_historialLocalSeleccionadoId = _historialLocal.FirstOrDefault()?.Id ?? string.Empty;
_historialLocalSeleccionadoId = string.Empty;
await PersistirHistorialLocalAsync();
MostrarMensajeHistorial("Combinacion eliminada del historial personal.");
@@ -477,7 +483,7 @@ public partial class PlanificadorRutas
await CargarHistorialCompartidoAsync();
if (_historialCompartidoSeleccionadoId == id)
_historialCompartidoSeleccionadoId = _historialCompartido.FirstOrDefault()?.Id ?? string.Empty;
_historialCompartidoSeleccionadoId = string.Empty;
MostrarMensajeHistorial("Combinacion eliminada del historial compartido.");
}
@@ -489,61 +495,69 @@ public partial class PlanificadorRutas
private async Task AplicarRegistroHistorialAsync(RegistroHistorialRuta item)
{
CapturarConfiguracionTemporalAntesDeHistorial();
_omitirRegistroHistorialEnSiguienteCalculo = true;
_textoBusquedaOrigen = item.OrigenTexto;
_textoBusquedaDestino = item.DestinoTexto;
_coordenadasOrigen = new[] { item.OrigenLatitud, item.OrigenLongitud };
_coordenadasDestino = new[] { item.DestinoLatitud, item.DestinoLongitud };
_usarHorariosTeoricos = item.UsarHorariosTeoricos;
_usarHoraSimulada = item.UsarHoraSimulada;
if (DateOnly.TryParse(item.FechaSimulada, out var fecha))
_fechaSimulada = fecha;
if (TimeOnly.TryParse(item.HoraSimulada, out var hora))
_horaSimulada = hora;
_criterioPrioritarioRuta = NormalizarCriterioRuta(item.CriterioPrioritarioRuta, item.PreferenciaEtiquetaRuta);
SincronizarPreferenciaDesdeCriterioRuta();
if (item.FactorEquilibradoAndarBus is { } factorEquilibrado && double.IsFinite(factorEquilibrado))
_aplicandoRegistroHistorial = true;
try
{
_factorEquilibradoAndarBus = Math.Max(0, factorEquilibrado);
SincronizarTextosPenalizacionPie();
CapturarConfiguracionTemporalAntesDeHistorial();
if (_configuracionTemporalPreviaHistorial is not null)
_configuracionTemporalPreviaHistorial.FactorEquilibradoAndarBus = _factorEquilibradoAndarBus;
_omitirRegistroHistorialEnSiguienteCalculo = true;
_textoBusquedaOrigen = item.OrigenTexto;
_textoBusquedaDestino = item.DestinoTexto;
_coordenadasOrigen = new[] { item.OrigenLatitud, item.OrigenLongitud };
_coordenadasDestino = new[] { item.DestinoLatitud, item.DestinoLongitud };
_usarHorariosTeoricos = item.UsarHorariosTeoricos;
_usarHoraSimulada = item.UsarHoraSimulada;
if (DateOnly.TryParse(item.FechaSimulada, out var fecha))
_fechaSimulada = fecha;
if (TimeOnly.TryParse(item.HoraSimulada, out var hora))
_horaSimulada = hora;
_criterioPrioritarioRuta = NormalizarCriterioRuta(item.CriterioPrioritarioRuta, item.PreferenciaEtiquetaRuta);
SincronizarPreferenciaDesdeCriterioRuta();
if (item.FactorEquilibradoAndarBus is { } factorEquilibrado && double.IsFinite(factorEquilibrado))
{
_factorEquilibradoAndarBus = Math.Max(0, factorEquilibrado);
SincronizarTextosPenalizacionPie();
if (_configuracionTemporalPreviaHistorial is not null)
_configuracionTemporalPreviaHistorial.FactorEquilibradoAndarBus = _factorEquilibradoAndarBus;
}
_activarRangoLineas = item.ActivarFiltroLineas;
_lineasPermitidas.Clear();
foreach (var linea in NormalizarLineasHistorial(item.LineasPermitidas))
_lineasPermitidas.Add(linea);
_busFilteredCache.Clear();
SincronizarSegundosPorParadaConHorarios();
StopClock();
if (_usarHoraSimulada)
await RefrescarHoraUIAsync();
else
StartClock();
await PersistirConfiguracionAsync();
await CerrarTodasLasPreviewsAsync();
await CerrarPopupsAsync();
if (_mapa is not null)
{
try { await _mapa.Geometric.DisplayPolylinesFromArray.deleteConnectors(); } catch { }
await ClearRoutesJsAsync();
}
await SincronizarMarcadoresOrigenDestinoJsAsync();
await CalcularRutaCompletaAsync();
}
_activarRangoLineas = item.ActivarFiltroLineas;
_lineasPermitidas.Clear();
foreach (var linea in NormalizarLineasHistorial(item.LineasPermitidas))
_lineasPermitidas.Add(linea);
_busFilteredCache.Clear();
SincronizarSegundosPorParadaConHorarios();
StopClock();
if (_usarHoraSimulada)
await RefrescarHoraUIAsync();
else
StartClock();
await PersistirConfiguracionAsync();
await CerrarTodasLasPreviewsAsync();
await CerrarPopupsAsync();
if (_mapa is not null)
finally
{
try { await _mapa.Geometric.DisplayPolylinesFromArray.deleteConnectors(); } catch { }
await ClearRoutesJsAsync();
_aplicandoRegistroHistorial = false;
}
await SincronizarMarcadoresOrigenDestinoJsAsync();
await CalcularRutaCompletaAsync();
}
private void CapturarConfiguracionTemporalAntesDeHistorial()

View File

@@ -1204,7 +1204,7 @@ public partial class PlanificadorRutas : ComponentBase
private bool _elevPopupMinimizado = false;
private const string _versionApp = "(v-20260721a)";
private const string _versionApp = "(v-20260727a)";
private double? _paradaElevG;

View File

@@ -1552,6 +1552,9 @@ public partial class PlanificadorRutas : ComponentBase
if (_mapa is null || _coordenadasOrigen is null || _coordenadasDestino is null)
return;
if (!_aplicandoRegistroHistorial)
LimpiarSeleccionHistorial();
var cronometroCalculo = System.Diagnostics.Stopwatch.StartNew();
_panelRutasMovilContraido = _mostrarBuscadorMapa;

View File

@@ -859,6 +859,13 @@ public partial class PlanificadorRutas : ComponentBase
DateTime? depT = null;
DateTime? arrT = null;
double distanciaTramo = 0;
for (int p = 1; p < lineaGeom.GetLength(0); p++)
{
distanciaTramo += CalcularDistanciaMetros(
lineaGeom[p - 1, 0], lineaGeom[p - 1, 1],
lineaGeom[p, 0], lineaGeom[p, 1]);
}
if (_usarHorariosTeoricos && _horariosOk)
{
@@ -957,21 +964,13 @@ public partial class PlanificadorRutas : ComponentBase
Descripcion = CapitalizarPalabrasClave(
$"{HHmm(depT.Value)} -> {HHmm(arrT.Value)} - Linea {codLineaItinSentidoMostrado} ({infoVariante.Linea.Nombre})."
),
DistanciaMetros = 0,
DistanciaMetros = distanciaTramo,
DuracionSegundos = durBus,
VarianteBus = infoVariante
});
}
else
{
double distanciaTramo = 0;
for (int p = 1; p < lineaGeom.GetLength(0); p++)
{
distanciaTramo += CalcularDistanciaMetros(
lineaGeom[p - 1, 0], lineaGeom[p - 1, 1],
lineaGeom[p, 0], lineaGeom[p, 1]);
}
int paradasTramo = ContarParadasRecorridas(tramo);
double extraParadasSeg = paradasTramo * Math.Max(0, _segundosPorParadaBus);
double duracionBusSegundos = EstimarDuracionBusSegundos(distanciaTramo) + extraParadasSeg;