Añadido horario simualdo con advertencia a lostaxibus

añadido desseleccion de segmentos y iluminado del mismo

añadido limites nuevos en lugares y ordenes alfabeticos

quitado acalarion b5m

defectos de L5 y maximos al 80%

formula cambiada a 5.2 y division por distancia de bus

dsitancia con z anteriores
This commit is contained in:
2026-08-27 14:55:37 +02:00
parent 49c5d23ace
commit 3a629de887
20 changed files with 1219 additions and 43 deletions

View File

@@ -49,7 +49,8 @@ public partial class PlanificadorRutas : ComponentBase
// CONFIG
private const double FactorPenalizacionDistanciaPiePorDefecto = 1.35;
private const double ParametroPenalizacionDistanciaPieMetrosPorDefecto = 200.0;
private const double CoeficienteEsfuerzoAlturaPorDefecto = 8.2;
private const double CoeficienteEsfuerzoAlturaPorDefecto = 5.2;
private const double PendienteMaximaEsfuerzoPorcentaje = 80.0;
private const double FactorEquilibradoAndarBusPorDefecto = 6.0;
private const double UmbralPendienteSubidaRutaPorDefecto = 2.0;
private const double UmbralPendienteBajadaRutaPorDefecto = 5.0;
@@ -64,7 +65,7 @@ public partial class PlanificadorRutas : ComponentBase
private double _factorEquilibradoAndarBus = FactorEquilibradoAndarBusPorDefecto;
private string _factorPenalizacionDistanciaPieTextoEdicion = "1.35";
private string _parametroPenalizacionDistanciaPieTextoEdicion = "200";
private string _coeficienteEsfuerzoAlturaTextoEdicion = "8.20";
private string _coeficienteEsfuerzoAlturaTextoEdicion = "5.20";
private string _pesoTransbordoRankingTextoEdicion = "4,0";
private string _factorEquilibradoAndarBusTextoEdicion = "6";
private double _velocidadBusKmH = 16.0;
@@ -234,7 +235,10 @@ public partial class PlanificadorRutas : ComponentBase
if (pendientePorcentaje.Value < umbralSubida)
return distanciaMetros.Value;
var pendiente = pendientePorcentaje.Value / 100.0;
var pendienteLimitadaPorcentaje = Math.Min(
pendientePorcentaje.Value,
PendienteMaximaEsfuerzoPorcentaje);
var pendiente = pendienteLimitadaPorcentaje / 100.0;
var factorConPotencia = Math.Pow(1.0 + pendiente, coeficiente);
var esfuerzo = distanciaMetros.Value * factorConPotencia;
return double.IsFinite(esfuerzo)

View File

@@ -76,7 +76,7 @@ public partial class PlanificadorRutas
try
{
await Task.Delay(120, ct);
var sugerencias = await CrearSugerenciasBusquedaAsync(texto, 20, ct);
var sugerencias = await CrearSugerenciasBusquedaAsync(texto, 50, ct);
if (ct.IsCancellationRequested || version != _versionSugerenciasBusqueda)
return;
@@ -160,7 +160,9 @@ public partial class PlanificadorRutas
.Concat(lugares.Select(CrearSugerenciaLugar))
.GroupBy(sugerencia => NormalizarClaveSugerencia(sugerencia), StringComparer.Ordinal)
.Select(grupo => grupo.First())
.Take(Math.Clamp(maxResultados, 1, 20))
.OrderBy(sugerencia => sugerencia.Titulo, StringComparer.CurrentCultureIgnoreCase)
.ThenBy(sugerencia => sugerencia.Subtitulo, StringComparer.CurrentCultureIgnoreCase)
.Take(Math.Clamp(maxResultados, 1, 50))
.ToList();
}
@@ -247,8 +249,8 @@ public partial class PlanificadorRutas
TextoEntrada = lugar.Nombre,
Titulo = lugar.Nombre,
Subtitulo = string.IsNullOrWhiteSpace(lugar.Subtitulo)
? $"{lugar.Tipo} · {lugar.Fuente}"
: $"{lugar.Subtitulo} · {lugar.Fuente}",
? lugar.Tipo
: lugar.Subtitulo,
Tipo = lugar.Tipo,
Fuente = lugar.Fuente,
Latitud = lugar.Latitud,

View File

@@ -30,6 +30,10 @@ public partial class PlanificadorRutas
private TipoReferenciaHistorial _tipoReferenciaHistorial;
private string _historialReferenciaId = string.Empty;
private bool _rutaActualDerivadaDeHistorial;
private readonly List<PasoDerivacionHistorial> _pasosDerivacionHistorial = new();
private RegistroHistorialRuta? _escenarioBaseDerivacionHistorial;
private bool _mostrarInformacionDerivacionHistorial;
private int _indicePasoDerivacionSeleccionado = -1;
private string _mensajeHistorial = string.Empty;
private bool _mensajeHistorialEsError = false;
private bool _mostrarHistorialRutas = false;
@@ -53,6 +57,17 @@ public partial class PlanificadorRutas
Compartido
}
private sealed record PasoDerivacionHistorial(
int Numero,
DateTime FechaUtc,
RegistroHistorialRuta Escenario);
private sealed record CambioDerivacionHistorial(
string Campo,
string ValorAnterior,
string ValorActual,
string Detalle);
private sealed class ResultadoStorageNavegador
{
[JsonPropertyName("ok")]
@@ -113,6 +128,7 @@ public partial class PlanificadorRutas
{
_versionAperturaHistorial++;
_mostrarHistorialRutas = false;
_mostrarInformacionDerivacionHistorial = false;
_historialLocalCargando = false;
StopRefrescoHistorialCompartido();
await RestaurarConfiguracionTemporalHistorialAsync();
@@ -834,13 +850,27 @@ public partial class PlanificadorRutas
private void ConfirmarDerivacionHistorial()
{
_rutaActualDerivadaDeHistorial = ExisteReferenciaHistorialActual();
if (_rutaActualDerivadaDeHistorial &&
_tipoReferenciaHistorial == TipoReferenciaHistorial.Compartido)
{
RegistrarPasoDerivacionHistorialActual();
}
}
private void EstablecerReferenciaHistorial(TipoReferenciaHistorial tipo, string id)
{
ReiniciarSeguimientoDerivacionHistorial();
_tipoReferenciaHistorial = tipo;
_historialReferenciaId = id;
_rutaActualDerivadaDeHistorial = false;
if (tipo == TipoReferenciaHistorial.Compartido)
{
var compartida = _historialCompartido.FirstOrDefault(item =>
string.Equals(item.Id, id, StringComparison.OrdinalIgnoreCase));
if (compartida is not null)
_escenarioBaseDerivacionHistorial = ClonarEscenarioHistorial(compartida);
}
}
private void LimpiarReferenciaHistorial()
@@ -848,6 +878,7 @@ public partial class PlanificadorRutas
_tipoReferenciaHistorial = TipoReferenciaHistorial.Ninguna;
_historialReferenciaId = string.Empty;
_rutaActualDerivadaDeHistorial = false;
ReiniciarSeguimientoDerivacionHistorial();
}
private bool ExisteReferenciaHistorialActual()
@@ -884,11 +915,265 @@ public partial class PlanificadorRutas
_ => (string.Empty, -1)
};
return indice >= 0
? $"Ruta actual derivada del Historial {nombre} n.º {indice + 1}."
if (indice < 0)
return string.Empty;
var numeroDerivacion = _tipoReferenciaHistorial == TipoReferenciaHistorial.Compartido &&
_pasosDerivacionHistorial.Count > 0
? $" · Derivación n.º {_pasosDerivacionHistorial.Count}"
: string.Empty;
return $"Ruta actual derivada del Historial {nombre} n.º {indice + 1}{numeroDerivacion}.";
}
private bool PuedeMostrarInformacionDerivacionHistorial =>
_rutaActualDerivadaDeHistorial &&
_tipoReferenciaHistorial == TipoReferenciaHistorial.Compartido &&
_escenarioBaseDerivacionHistorial is not null &&
_pasosDerivacionHistorial.Count > 0;
private int IndiceHistorialCompartidoReferencia =>
_historialCompartido.FindIndex(item => string.Equals(
item.Id,
_historialReferenciaId,
StringComparison.OrdinalIgnoreCase));
private PasoDerivacionHistorial? PasoDerivacionSeleccionado =>
_indicePasoDerivacionSeleccionado >= 0 &&
_indicePasoDerivacionSeleccionado < _pasosDerivacionHistorial.Count
? _pasosDerivacionHistorial[_indicePasoDerivacionSeleccionado]
: null;
private void AbrirInformacionDerivacionHistorial()
{
if (!PuedeMostrarInformacionDerivacionHistorial)
return;
_indicePasoDerivacionSeleccionado = _pasosDerivacionHistorial.Count - 1;
_mostrarInformacionDerivacionHistorial = true;
}
private void CerrarInformacionDerivacionHistorial()
{
_mostrarInformacionDerivacionHistorial = false;
}
private void SeleccionarPasoDerivacionHistorial(int indice)
{
if (indice < 0 || indice >= _pasosDerivacionHistorial.Count)
return;
_indicePasoDerivacionSeleccionado = indice;
}
private void ReiniciarSeguimientoDerivacionHistorial()
{
_pasosDerivacionHistorial.Clear();
_escenarioBaseDerivacionHistorial = null;
_indicePasoDerivacionSeleccionado = -1;
_mostrarInformacionDerivacionHistorial = false;
}
private void RegistrarPasoDerivacionHistorialActual()
{
_escenarioBaseDerivacionHistorial ??= _historialCompartido
.FirstOrDefault(item => string.Equals(
item.Id,
_historialReferenciaId,
StringComparison.OrdinalIgnoreCase)) is { } compartida
? ClonarEscenarioHistorial(compartida)
: null;
if (_escenarioBaseDerivacionHistorial is null)
return;
var actual = ConstruirRegistroHistorialActual();
if (actual is null)
return;
var anterior = _pasosDerivacionHistorial.Count > 0
? _pasosDerivacionHistorial[^1].Escenario
: _escenarioBaseDerivacionHistorial;
if (string.Equals(
CalcularClaveEscenario(anterior),
CalcularClaveEscenario(actual),
StringComparison.OrdinalIgnoreCase))
{
return;
}
_pasosDerivacionHistorial.Add(new PasoDerivacionHistorial(
_pasosDerivacionHistorial.Count + 1,
DateTime.UtcNow,
ClonarEscenarioHistorial(actual)));
_indicePasoDerivacionSeleccionado = _pasosDerivacionHistorial.Count - 1;
}
private RegistroHistorialRuta? ObtenerEscenarioAnteriorDerivacion(
PasoDerivacionHistorial paso)
{
var indice = paso.Numero - 1;
if (indice <= 0)
return _escenarioBaseDerivacionHistorial;
return indice - 1 < _pasosDerivacionHistorial.Count
? _pasosDerivacionHistorial[indice - 1].Escenario
: null;
}
private IReadOnlyList<CambioDerivacionHistorial> ObtenerCambiosDerivacion(
RegistroHistorialRuta? anterior,
RegistroHistorialRuta actual)
{
if (anterior is null)
return Array.Empty<CambioDerivacionHistorial>();
var cambios = new List<CambioDerivacionHistorial>();
AgregarCambioPuntoDerivacion(
cambios,
"Origen",
anterior.OrigenTexto,
anterior.OrigenLatitud,
anterior.OrigenLongitud,
actual.OrigenTexto,
actual.OrigenLatitud,
actual.OrigenLongitud);
AgregarCambioPuntoDerivacion(
cambios,
"Destino",
anterior.DestinoTexto,
anterior.DestinoLatitud,
anterior.DestinoLongitud,
actual.DestinoTexto,
actual.DestinoLatitud,
actual.DestinoLongitud);
AgregarCambioTextoDerivacion(
cambios,
"Fecha y hora",
FormatearFechaHoraComparacionDerivacion(anterior),
FormatearFechaHoraComparacionDerivacion(actual));
AgregarCambioTextoDerivacion(
cambios,
"Modo",
FormatearModoHistorial(anterior),
FormatearModoHistorial(actual));
AgregarCambioTextoDerivacion(
cambios,
"Factor Equilib. A",
FormatearFactorDerivacion(anterior),
FormatearFactorDerivacion(actual));
AgregarCambioTextoDerivacion(
cambios,
"Horarios",
anterior.UsarHorariosTeoricos ? "Activados" : "Desactivados",
actual.UsarHorariosTeoricos ? "Activados" : "Desactivados");
AgregarCambioTextoDerivacion(
cambios,
"Líneas utilizables",
FormatearLineasDerivacion(anterior),
FormatearLineasDerivacion(actual));
return cambios;
}
private static void AgregarCambioPuntoDerivacion(
ICollection<CambioDerivacionHistorial> cambios,
string campo,
string textoAnterior,
double latitudAnterior,
double longitudAnterior,
string textoActual,
double latitudActual,
double longitudActual)
{
var distancia = CalcularDistanciaMetros(
latitudAnterior,
longitudAnterior,
latitudActual,
longitudActual);
if (!double.IsFinite(distancia) || distancia < 0.5)
return;
cambios.Add(new CambioDerivacionHistorial(
campo,
FormatearPuntoDerivacion(textoAnterior, latitudAnterior, longitudAnterior),
FormatearPuntoDerivacion(textoActual, latitudActual, longitudActual),
$"Desplazado {FormatearDistanciaDerivacion(distancia)}"));
}
private static void AgregarCambioTextoDerivacion(
ICollection<CambioDerivacionHistorial> cambios,
string campo,
string? valorAnterior,
string? valorActual)
{
var anterior = string.IsNullOrWhiteSpace(valorAnterior) ? "-" : valorAnterior.Trim();
var actual = string.IsNullOrWhiteSpace(valorActual) ? "-" : valorActual.Trim();
if (string.Equals(anterior, actual, StringComparison.OrdinalIgnoreCase))
return;
cambios.Add(new CambioDerivacionHistorial(campo, anterior, actual, string.Empty));
}
private static string FormatearPuntoDerivacion(
string texto,
double latitud,
double longitud)
{
var nombre = string.IsNullOrWhiteSpace(texto) ? "Punto del mapa" : texto.Trim();
return $"{nombre} · {latitud.ToString("0.000000", CultureInfo.InvariantCulture)}, " +
longitud.ToString("0.000000", CultureInfo.InvariantCulture);
}
private static string FormatearDistanciaDerivacion(double distanciaMetros)
=> distanciaMetros >= 1000
? $"{(distanciaMetros / 1000.0).ToString("0.000", CultureInfo.InvariantCulture)} km"
: $"{Math.Round(distanciaMetros).ToString("0", CultureInfo.InvariantCulture)} m";
private static string FormatearFechaHoraComparacionDerivacion(RegistroHistorialRuta item)
=> item.UsarHoraSimulada
? FormatearHoraReferenciaHistorial(item)
: "Fecha y hora actuales";
private static string FormatearFactorDerivacion(RegistroHistorialRuta item)
=> item.FactorEquilibradoAndarBus is { } factor && double.IsFinite(factor) && factor > 0
? factor.ToString("0.##", CultureInfo.InvariantCulture)
: "-";
private static string FormatearLineasDerivacion(RegistroHistorialRuta item)
{
if (!item.ActivarFiltroLineas)
return "Todas";
var lineas = NormalizarLineasHistorial(item.LineasPermitidas);
return lineas.Count == 0
? "Ninguna"
: string.Join(", ", lineas);
}
private static RegistroHistorialRuta ClonarEscenarioHistorial(RegistroHistorialRuta item)
=> new()
{
Id = item.Id,
OrigenTexto = item.OrigenTexto,
DestinoTexto = item.DestinoTexto,
OrigenLatitud = item.OrigenLatitud,
OrigenLongitud = item.OrigenLongitud,
DestinoLatitud = item.DestinoLatitud,
DestinoLongitud = item.DestinoLongitud,
UsarHorariosTeoricos = item.UsarHorariosTeoricos,
UsarHoraSimulada = item.UsarHoraSimulada,
FechaSimulada = item.FechaSimulada,
HoraSimulada = item.HoraSimulada,
CriterioPrioritarioRuta = item.CriterioPrioritarioRuta,
PreferenciaEtiquetaRuta = item.PreferenciaEtiquetaRuta,
FactorEquilibradoAndarBus = item.FactorEquilibradoAndarBus,
ActivarFiltroLineas = item.ActivarFiltroLineas,
LineasPermitidas = item.LineasPermitidas.ToList(),
FechaCreacionUtc = item.FechaCreacionUtc,
FechaActualizacionUtc = item.FechaActualizacionUtc
};
private async Task CompartirEscenarioActualAsync()
{
var actual = ConstruirRegistroHistorialActual()

View File

@@ -0,0 +1,35 @@
using System.Globalization;
namespace RutasDBUS.Components.Pages;
public partial class PlanificadorRutas
{
private PuntoInspectorAnterior? _inspectorPuntoAnterior;
private sealed record PuntoInspectorAnterior(
double Latitud,
double Longitud,
double? ElevacionIdee,
double? ElevacionLocal5,
double? ElevacionLocal2,
double? ElevacionLocal1);
private double? ObtenerElevacionPuntoInspectorAnterior(PuntoInspectorAnterior punto)
=> UsarElevacionLocal1ParaCalculo
? punto.ElevacionLocal1
: UsarElevacionLocal2ParaCalculo
? punto.ElevacionLocal2
: UsarElevacionLocal5ParaCalculo
? punto.ElevacionLocal5
: punto.ElevacionIdee;
private static string FormatearDistanciaPuntoInspector(double distanciaMetros)
=> distanciaMetros < 1000
? distanciaMetros.ToString("0.0", CultureInfo.InvariantCulture) + " m"
: (distanciaMetros / 1000.0).ToString("0.000", CultureInfo.InvariantCulture) + " km";
private static string FormatearAlturaPuntoInspector(double? altura)
=> altura is { } valor
? valor.ToString("0.00", CultureInfo.InvariantCulture) + " m"
: "-";
}

View File

@@ -1202,7 +1202,7 @@ public partial class PlanificadorRutas : ComponentBase
private bool _elevPopupMinimizado = false;
private const string _versionApp = "(v-20260825b)";
private const string _versionApp = "(v-20260827b)";
private double? _paradaElevIdee;

View File

@@ -10,6 +10,8 @@ public partial class PlanificadorRutas
private const string ClaveConfiguracionLocal = "rutasdbus.planificador.config.v1";
private const int VersionPersistenciaFactorEquilibrado = 2;
private const int VersionPersistenciaPendientes = 2;
private const int VersionPersistenciaCoeficienteEsfuerzo = 1;
private const int VersionPersistenciaFuenteElevacion = 1;
private bool _configuracionLocalCargada = false;
private bool _mostrarConfirmacionRestablecer = false;
@@ -38,11 +40,13 @@ public partial class PlanificadorRutas
public double? FactorPenalizacionDistanciaPie { get; set; }
public double? ParametroPenalizacionDistanciaPieMetros { get; set; }
public double? CoeficienteEsfuerzoAltura { get; set; }
public int? VersionCoeficienteEsfuerzo { get; set; }
public double? PesoTransbordoRankingMinutos { get; set; }
public double? FactorEquilibradoAndarBus { get; set; }
public int? VersionFactorEquilibrado { get; set; }
public bool? MostrarElevacionesRuta { get; set; }
public string? FuenteElevacionCalculo { get; set; }
public int? VersionFuenteElevacion { get; set; }
public int? VersionPendientes { get; set; }
public double? UmbralPendienteSubidaRuta { get; set; }
public double? UmbralPendienteBajadaRuta { get; set; }
@@ -154,11 +158,13 @@ public partial class PlanificadorRutas
FactorPenalizacionDistanciaPie = _factorPenalizacionDistanciaPie,
ParametroPenalizacionDistanciaPieMetros = _parametroPenalizacionDistanciaPieMetros,
CoeficienteEsfuerzoAltura = _coeficienteEsfuerzoAltura,
VersionCoeficienteEsfuerzo = VersionPersistenciaCoeficienteEsfuerzo,
PesoTransbordoRankingMinutos = _pesoTransbordoRankingMinutos,
FactorEquilibradoAndarBus = _factorEquilibradoAndarBus,
VersionFactorEquilibrado = VersionPersistenciaFactorEquilibrado,
MostrarElevacionesRuta = _mostrarElevacionesRutaConfiguracion,
FuenteElevacionCalculo = _fuenteElevacionCalculo,
VersionFuenteElevacion = VersionPersistenciaFuenteElevacion,
VersionPendientes = VersionPersistenciaPendientes,
UmbralPendienteSubidaRuta = _umbralPendienteSubidaRuta,
UmbralPendienteBajadaRuta = _umbralPendienteBajadaRuta,
@@ -218,11 +224,15 @@ public partial class PlanificadorRutas
Math.Abs(parametro - 100.0) < 0.0001
? ParametroPenalizacionDistanciaPieMetrosPorDefecto
: parametro;
var migrarCoeficienteEsfuerzo =
(config.VersionCoeficienteEsfuerzo ?? 0) < VersionPersistenciaCoeficienteEsfuerzo;
if (config.CoeficienteEsfuerzoAltura is { } coeficienteAltura && double.IsFinite(coeficienteAltura))
_coeficienteEsfuerzoAltura =
Math.Abs(coeficienteAltura - 1.6) < 0.0001 ||
Math.Abs(coeficienteAltura - 5.2) < 0.0001 ||
Math.Abs(coeficienteAltura - 9.2) < 0.0001
migrarCoeficienteEsfuerzo &&
(Math.Abs(coeficienteAltura - 1.6) < 0.0001 ||
Math.Abs(coeficienteAltura - 5.2) < 0.0001 ||
Math.Abs(coeficienteAltura - 8.2) < 0.0001 ||
Math.Abs(coeficienteAltura - 9.2) < 0.0001)
? CoeficienteEsfuerzoAlturaPorDefecto
: coeficienteAltura;
if (config.PesoTransbordoRankingMinutos is { } pesoTransbordo && double.IsFinite(pesoTransbordo))
@@ -239,11 +249,14 @@ public partial class PlanificadorRutas
? true
: config.MostrarElevacionesRuta ?? true;
_mostrarElevacionesRutaConfiguracion = _mostrarElevacionesRuta;
_fuenteElevacionCalculo = migrarValoresPendientes &&
(string.IsNullOrWhiteSpace(config.FuenteElevacionCalculo) ||
string.Equals(config.FuenteElevacionCalculo, FuenteElevacionLocal5, StringComparison.OrdinalIgnoreCase) ||
string.Equals(config.FuenteElevacionCalculo, "local", StringComparison.OrdinalIgnoreCase))
? FuenteElevacionLocal1
var migrarFuenteElevacion =
(config.VersionFuenteElevacion ?? 0) < VersionPersistenciaFuenteElevacion;
_fuenteElevacionCalculo = migrarFuenteElevacion &&
string.Equals(
config.FuenteElevacionCalculo,
FuenteElevacionLocal1,
StringComparison.OrdinalIgnoreCase)
? FuenteElevacionLocal5
: NormalizarFuenteElevacion(config.FuenteElevacionCalculo);
if (config.UmbralPendienteSubidaRuta is { } umbralSubida && double.IsFinite(umbralSubida))
_umbralPendienteSubidaRuta = Math.Abs(umbralSubida - 3.0) < 0.0001
@@ -376,7 +389,7 @@ public partial class PlanificadorRutas
_pesoTransbordoRankingMinutos = 4.0;
_factorEquilibradoAndarBus = FactorEquilibradoAndarBusPorDefecto;
_mostrarElevacionesRutaConfiguracion = true;
_fuenteElevacionCalculo = FuenteElevacionLocal1;
_fuenteElevacionCalculo = FuenteElevacionLocal5;
_umbralPendienteSubidaRuta = UmbralPendienteSubidaRutaPorDefecto;
_umbralPendienteBajadaRuta = UmbralPendienteBajadaRutaPorDefecto;
_umbralAlturaAlertaPendienteRutaMetros = UmbralAlturaAlertaPendienteRutaMetrosPorDefecto;
@@ -429,7 +442,7 @@ public partial class PlanificadorRutas
_pesoTransbordoRankingMinutos = 4.0;
_factorEquilibradoAndarBus = FactorEquilibradoAndarBusPorDefecto;
_mostrarElevacionesRutaConfiguracion = true;
_fuenteElevacionCalculo = FuenteElevacionLocal1;
_fuenteElevacionCalculo = FuenteElevacionLocal5;
_umbralPendienteSubidaRuta = UmbralPendienteSubidaRutaPorDefecto;
_umbralPendienteBajadaRuta = UmbralPendienteBajadaRutaPorDefecto;
_umbralAlturaAlertaPendienteRutaMetros = UmbralAlturaAlertaPendienteRutaMetrosPorDefecto;

View File

@@ -188,7 +188,7 @@ public partial class PlanificadorRutas : ComponentBase
private const string FuenteElevacionLocal1 = "local1";
private const string FuenteElevacionIdee = "idee";
private const int TiempoMaximoIdeeSegundos = 10;
private string _fuenteElevacionCalculo = FuenteElevacionLocal1;
private string _fuenteElevacionCalculo = FuenteElevacionLocal5;
// IDEE: en el correo indican que 6 decimales es suficiente
private const int ELEV_IDEE_DECIMALES_CACHE = 6;
@@ -217,7 +217,7 @@ public partial class PlanificadorRutas : ComponentBase
return FuenteElevacionLocal5;
}
return FuenteElevacionLocal1;
return FuenteElevacionLocal5;
}
private bool ElevacionLocal5Disponible
@@ -1519,6 +1519,16 @@ public partial class PlanificadorRutas : ComponentBase
/// </summary>
private async Task MostrarInspectorAsync(double lat, double lon)
{
_inspectorPuntoAnterior = _popupInspectorVisible
? new PuntoInspectorAnterior(
_inspectorLat,
_inspectorLon,
_inspectorElevIdee,
_inspectorElevLocal5,
_inspectorElevLocal2,
_inspectorElevLocal1)
: null;
var versionInspector = ++_versionInspector;
_inspectorLat = lat;
_inspectorLon = lon;
@@ -1629,6 +1639,7 @@ public partial class PlanificadorRutas : ComponentBase
{
_versionInspector++;
_popupInspectorVisible = false;
_inspectorPuntoAnterior = null;
_inspectorLugaresCercanos = Array.Empty<LugarGeocodificadoCercano>();
try { await JS.InvokeVoidAsync("rt.clearInspectorMarkers"); } catch { }

View File

@@ -218,6 +218,26 @@ public partial class PlanificadorRutas : ComponentBase
string ItinerarioClave);
private List<ProximaSalidaVm> _nextDeps = new();
private bool HorariosTaxibusSimuladosVisibles
=> _nextDeps.Any(salida => TaxibusDbus.EsExpedicionSimulada(salida.ExpId));
private static string ObtenerAvisoTaxibus(AlternativaRuta alternativa)
{
var lineasTaxibus = alternativa.AlternativaBus?.Tramos
.Select(tramo => tramo.Variante.Linea)
.Where(linea => TaxibusDbus.EsLinea(linea.Codigo))
.Distinct()
.ToList();
if (lineasTaxibus is not { Count: > 0 })
return string.Empty;
return lineasTaxibus.Any(linea => linea.HorarioSimulado)
? TaxibusDbus.MensajeHorarioSimulado
: TaxibusDbus.MensajeReserva;
}
/// <summary>
/// Gestiona toggle hora simulada.
/// </summary>

View File

@@ -299,6 +299,13 @@
</button>
</div>
@if (HorariosTaxibusSimuladosVisibles)
{
<div class="taxibus-notice taxibus-notice--schedule" role="status">
<strong>Taxibús:</strong> @TaxibusDbus.MensajeHorarioSimulado
</div>
}
<div style="max-height: 220px; overflow-y: auto; border: 1px solid rgba(255,255,255,.12); border-radius: 6px; padding: .35rem .5rem; scroll-behavior: smooth;">
<ul style="margin:0; padding-left:1.1rem;">
@foreach (var x in NextDepsOrdenados)
@@ -401,6 +408,29 @@
}
</div>
@if (_inspectorPuntoAnterior is { } puntoAnterior)
{
var distanciaPuntoAnterior = CalcularDistanciaMetros(
puntoAnterior.Latitud,
puntoAnterior.Longitud,
_inspectorLat,
_inspectorLon);
var elevacionPuntoAnterior = ObtenerElevacionPuntoInspectorAnterior(puntoAnterior);
<div class="inspector-previous-point">
<div class="inspector-previous-point__distance">
<b>Distancia al punto Z anterior:</b>
@FormatearDistanciaPuntoInspector(distanciaPuntoAnterior)
</div>
<div class="inspector-previous-point__details">
<span>Punto anterior</span>
<span>Lat: @puntoAnterior.Latitud.ToString("0.000000", CultureInfo.InvariantCulture)</span>
<span>Lon: @puntoAnterior.Longitud.ToString("0.000000", CultureInfo.InvariantCulture)</span>
<span>@EtiquetaFuenteElevacionCalculo: @FormatearAlturaPuntoInspector(elevacionPuntoAnterior)</span>
</div>
</div>
}
@if (_inspectorLugaresCercanos.Count > 0)
{
<div class="inspector-address-list">
@@ -741,6 +771,7 @@
@if (_opcionesRuta.Count > 0 && _indiceAlternativaSeleccionada >= 0 && _indiceAlternativaSeleccionada < _opcionesRuta.Count)
{
var alt = _opcionesRuta[_indiceAlternativaSeleccionada];
var avisoTaxibus = ObtenerAvisoTaxibus(alt);
@if (MostrarAlertaPendientesPositivasSignificativas)
{
@@ -753,6 +784,13 @@
</div>
}
@if (!string.IsNullOrWhiteSpace(avisoTaxibus))
{
<div class="taxibus-notice" role="status">
<strong>Taxibús:</strong> @avisoTaxibus
</div>
}
@* ========= RESUMEN BONITO ARRIBA (único) ========= *@
<p class="route-main-text">
@if (alt.EsSoloAPie)
@@ -1162,7 +1200,15 @@
{
<div class="history-derived-note">
<span class="history-derived-marker" aria-hidden="true">*</span>
<span>@textoReferenciaDerivada</span>
<span class="history-derived-note__text">@textoReferenciaDerivada</span>
@if (PuedeMostrarInformacionDerivacionHistorial)
{
<button type="button"
class="history-derived-info-btn"
@onclick="AbrirInformacionDerivacionHistorial">
Info
</button>
}
</div>
}
@@ -1198,6 +1244,126 @@
</div>
}
@if (_mostrarInformacionDerivacionHistorial &&
_escenarioBaseDerivacionHistorial is not null &&
PasoDerivacionSeleccionado is { } pasoDerivacion)
{
var cambiosRespectoOriginal = ObtenerCambiosDerivacion(
_escenarioBaseDerivacionHistorial,
pasoDerivacion.Escenario);
var escenarioAnterior = ObtenerEscenarioAnteriorDerivacion(pasoDerivacion);
var cambiosRespectoAnterior = ObtenerCambiosDerivacion(
escenarioAnterior,
pasoDerivacion.Escenario);
var textoComparacionAnterior = pasoDerivacion.Numero <= 1
? "Respecto al Historial Compartido original"
: $"Respecto a la Derivación n.º {pasoDerivacion.Numero - 1}";
<div class="custom-modal-backdrop history-derivation-backdrop"
@onclick="CerrarInformacionDerivacionHistorial">
<div class="custom-modal-card history-derivation-modal"
@onclick:stopPropagation="true">
<div class="history-derivation-modal__header">
<div>
<div class="custom-modal-title">Cambios de la derivación</div>
<div class="history-derivation-modal__source">
Historial Compartido n.º @(IndiceHistorialCompartidoReferencia + 1)
</div>
</div>
<button type="button"
class="config-close-btn"
title="Cerrar"
aria-label="Cerrar"
@onclick="CerrarInformacionDerivacionHistorial">
&times;
</button>
</div>
<div class="history-derivation-steps" aria-label="Derivaciones registradas">
@foreach (var paso in _pasosDerivacionHistorial)
{
var indicePaso = paso.Numero - 1;
<button type="button"
class="history-derivation-step @(indicePaso == _indicePasoDerivacionSeleccionado ? "history-derivation-step--selected" : "")"
@onclick="() => SeleccionarPasoDerivacionHistorial(indicePaso)">
Der. @paso.Numero
</button>
}
</div>
<div class="history-derivation-selected">
<strong>Derivación n.º @pasoDerivacion.Numero</strong>
<span>@pasoDerivacion.FechaUtc.ToLocalTime().ToString("dd/MM/yyyy HH:mm:ss")</span>
</div>
<section class="history-derivation-comparison">
<h6>Respecto al Historial Compartido original</h6>
@if (cambiosRespectoOriginal.Count == 0)
{
<div class="history-derivation-no-changes">Sin cambios registrados.</div>
}
else
{
@foreach (var cambio in cambiosRespectoOriginal)
{
<div class="history-derivation-change">
<div class="history-derivation-change__heading">
<strong>@cambio.Campo</strong>
@if (!string.IsNullOrWhiteSpace(cambio.Detalle))
{
<span>@cambio.Detalle</span>
}
</div>
<div class="history-derivation-change__value">
<span>Antes</span>
<div>@cambio.ValorAnterior</div>
</div>
<div class="history-derivation-change__value">
<span>Ahora</span>
<div>@cambio.ValorActual</div>
</div>
</div>
}
}
</section>
@if (pasoDerivacion.Numero > 1)
{
<section class="history-derivation-comparison">
<h6>@textoComparacionAnterior</h6>
@if (cambiosRespectoAnterior.Count == 0)
{
<div class="history-derivation-no-changes">Sin cambios respecto a la anterior.</div>
}
else
{
@foreach (var cambio in cambiosRespectoAnterior)
{
<div class="history-derivation-change">
<div class="history-derivation-change__heading">
<strong>@cambio.Campo</strong>
@if (!string.IsNullOrWhiteSpace(cambio.Detalle))
{
<span>@cambio.Detalle</span>
}
</div>
<div class="history-derivation-change__value">
<span>Antes</span>
<div>@cambio.ValorAnterior</div>
</div>
<div class="history-derivation-change__value">
<span>Ahora</span>
<div>@cambio.ValorActual</div>
</div>
</div>
}
}
</section>
}
</div>
</div>
}
<!-- CONFIG -->
@* <button class="config-toggle-btn" @onclick="ToggleConfigPanel">⚙</button>
*@
@@ -1309,7 +1475,7 @@
<div class="line-filter">
<label class="line-filter__toggle">
<input type="checkbox" @bind="_activarRangoLineas" @bind:after="PersistirConfiguracionAsync" />
<span>Aplicar lineas utilizables:</span>
<span>Utiliza las siguientes líneas:</span>
</label>
@if (_activarRangoLineas)
@@ -1651,15 +1817,15 @@
disabled="@_pintandoElevacionesRuta"
@bind="_fuenteElevacionCalculo"
@bind:after="OnFuenteElevacionChangedAsync">
<option value="@FuenteElevacionIdee">Altura (G)</option>
<option value="@FuenteElevacionIdee">G</option>
<option value="@FuenteElevacionLocal5" disabled="@(!ElevacionLocal5Disponible)">
Altura (L5)@(!ElevacionLocal5Disponible ? " - no disponible" : string.Empty)
L5@(!ElevacionLocal5Disponible ? " - no disponible" : string.Empty)
</option>
<option value="@FuenteElevacionLocal2" disabled="@(!ElevacionLocal2Disponible)">
Altura (L2)@(!ElevacionLocal2Disponible ? " - no disponible" : string.Empty)
L2@(!ElevacionLocal2Disponible ? " - no disponible" : string.Empty)
</option>
<option value="@FuenteElevacionLocal1" disabled="@(!ElevacionLocal1Disponible)">
Altura (L1)@(!ElevacionLocal1Disponible ? " - no disponible" : string.Empty)
L1@(!ElevacionLocal1Disponible ? " - no disponible" : string.Empty)
</option>
</select>
</label>