Restricciones de seleccion de paradas.
señal de dereivacion de historial. importante: cambiod e formula, desaparece distancia equilibrada y el factor pasa a dividir a la distancia en bus
This commit is contained in:
@@ -151,7 +151,7 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Expone el factor que convierte metros andando a metros equivalentes de bus en el modo equilibrado.
|
/// Expone el factor que reduce el peso de la distancia en bus en el modo equilibrado.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private string FactorEquilibradoAndarBusTexto
|
private string FactorEquilibradoAndarBusTexto
|
||||||
{
|
{
|
||||||
@@ -164,8 +164,8 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
if (!double.TryParse(texto, NumberStyles.Float, CultureInfo.InvariantCulture, out var valor))
|
if (!double.TryParse(texto, NumberStyles.Float, CultureInfo.InvariantCulture, out var valor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (double.IsFinite(valor))
|
if (double.IsFinite(valor) && valor > 0)
|
||||||
_factorEquilibradoAndarBus = Math.Max(0, valor);
|
_factorEquilibradoAndarBus = valor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1420,25 +1420,6 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
return EstimarDuracionPieSegundos(distanciaCorregida);
|
return EstimarDuracionPieSegundos(distanciaCorregida);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Calcula la aportacion de todos los tramos andando a la distancia equilibrada.
|
|
||||||
/// </summary>
|
|
||||||
private double CalcularDistanciaEquilibradaAndandoAlternativa(AlternativaRuta? alternativa)
|
|
||||||
{
|
|
||||||
if (alternativa is null)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
var distanciaAndando = CalcularDistanciaCorregidaAlternativa(alternativa);
|
|
||||||
var factor = double.IsFinite(_factorEquilibradoAndarBus)
|
|
||||||
? Math.Max(0, _factorEquilibradoAndarBus)
|
|
||||||
: FactorEquilibradoAndarBusPorDefecto;
|
|
||||||
var distanciaEquilibrada = Math.Max(0, distanciaAndando) * factor;
|
|
||||||
|
|
||||||
return double.IsFinite(distanciaEquilibrada)
|
|
||||||
? distanciaEquilibrada
|
|
||||||
: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private double CalcularScoreEquilibradoFactor(AlternativaRuta? alternativa)
|
private double CalcularScoreEquilibradoFactor(AlternativaRuta? alternativa)
|
||||||
{
|
{
|
||||||
if (alternativa is null)
|
if (alternativa is null)
|
||||||
@@ -1453,11 +1434,14 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
distanciaBus = Math.Max(0, alternativa.AlternativaBus.DistanciaTotalBus);
|
distanciaBus = Math.Max(0, alternativa.AlternativaBus.DistanciaTotalBus);
|
||||||
}
|
}
|
||||||
|
|
||||||
var distanciaEquilibradaAndando = CalcularDistanciaEquilibradaAndandoAlternativa(alternativa);
|
var distanciaAndando = CalcularDistanciaCorregidaAlternativa(alternativa);
|
||||||
|
var factor = double.IsFinite(_factorEquilibradoAndarBus) && _factorEquilibradoAndarBus > 0
|
||||||
|
? _factorEquilibradoAndarBus
|
||||||
|
: FactorEquilibradoAndarBusPorDefecto;
|
||||||
var penalizacionTransbordos = UtilidadesTransitoDbus.CalcularPenalizacionTransbordosRankingMetros(
|
var penalizacionTransbordos = UtilidadesTransitoDbus.CalcularPenalizacionTransbordosRankingMetros(
|
||||||
alternativa.NumeroTransbordosReales,
|
alternativa.NumeroTransbordosReales,
|
||||||
CrearParametrosPenalizacionActuales());
|
CrearParametrosPenalizacionActuales());
|
||||||
var score = distanciaBus + distanciaEquilibradaAndando + penalizacionTransbordos;
|
var score = distanciaAndando + (distanciaBus / factor) + penalizacionTransbordos;
|
||||||
return double.IsFinite(score) && score >= 0
|
return double.IsFinite(score) && score >= 0
|
||||||
? score
|
? score
|
||||||
: double.PositiveInfinity;
|
: double.PositiveInfinity;
|
||||||
@@ -1469,7 +1453,7 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
if (!double.IsFinite(score))
|
if (!double.IsFinite(score))
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
||||||
return (score / 1000.0).ToString("0.000", CultureInfo.InvariantCulture);
|
return score.ToString("0", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RecalcularRutaEquilibradaTrasCambioFactorAsync()
|
private async Task RecalcularRutaEquilibradaTrasCambioFactorAsync()
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ public partial class PlanificadorRutas
|
|||||||
private CancellationTokenSource? _historialCompartidoCts;
|
private CancellationTokenSource? _historialCompartidoCts;
|
||||||
private string _historialLocalSeleccionadoId = string.Empty;
|
private string _historialLocalSeleccionadoId = string.Empty;
|
||||||
private string _historialCompartidoSeleccionadoId = string.Empty;
|
private string _historialCompartidoSeleccionadoId = string.Empty;
|
||||||
|
private TipoReferenciaHistorial _tipoReferenciaHistorial;
|
||||||
|
private string _historialReferenciaId = string.Empty;
|
||||||
|
private bool _rutaActualDerivadaDeHistorial;
|
||||||
private string _mensajeHistorial = string.Empty;
|
private string _mensajeHistorial = string.Empty;
|
||||||
private bool _mensajeHistorialEsError = false;
|
private bool _mensajeHistorialEsError = false;
|
||||||
private bool _mostrarHistorialRutas = false;
|
private bool _mostrarHistorialRutas = false;
|
||||||
@@ -43,6 +46,13 @@ public partial class PlanificadorRutas
|
|||||||
private string _resumenErrorHistorialLocal = string.Empty;
|
private string _resumenErrorHistorialLocal = string.Empty;
|
||||||
private string _detalleErrorHistorialLocal = string.Empty;
|
private string _detalleErrorHistorialLocal = string.Empty;
|
||||||
|
|
||||||
|
private enum TipoReferenciaHistorial
|
||||||
|
{
|
||||||
|
Ninguna,
|
||||||
|
Personal,
|
||||||
|
Compartido
|
||||||
|
}
|
||||||
|
|
||||||
private sealed class ResultadoStorageNavegador
|
private sealed class ResultadoStorageNavegador
|
||||||
{
|
{
|
||||||
[JsonPropertyName("ok")]
|
[JsonPropertyName("ok")]
|
||||||
@@ -400,6 +410,11 @@ public partial class PlanificadorRutas
|
|||||||
_historialLocal.AddRange(items);
|
_historialLocal.AddRange(items);
|
||||||
if (!_historialLocal.Any(x => x.Id == _historialLocalSeleccionadoId))
|
if (!_historialLocal.Any(x => x.Id == _historialLocalSeleccionadoId))
|
||||||
_historialLocalSeleccionadoId = string.Empty;
|
_historialLocalSeleccionadoId = string.Empty;
|
||||||
|
if (_tipoReferenciaHistorial == TipoReferenciaHistorial.Personal &&
|
||||||
|
!_historialLocal.Any(x => x.Id == _historialReferenciaId))
|
||||||
|
{
|
||||||
|
LimpiarReferenciaHistorial();
|
||||||
|
}
|
||||||
_historialLocalCargado = true;
|
_historialLocalCargado = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,11 +647,18 @@ public partial class PlanificadorRutas
|
|||||||
if (_historialCompartido.Count == 0)
|
if (_historialCompartido.Count == 0)
|
||||||
{
|
{
|
||||||
_historialCompartidoSeleccionadoId = string.Empty;
|
_historialCompartidoSeleccionadoId = string.Empty;
|
||||||
|
if (_tipoReferenciaHistorial == TipoReferenciaHistorial.Compartido)
|
||||||
|
LimpiarReferenciaHistorial();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_historialCompartido.Any(x => x.Id == _historialCompartidoSeleccionadoId))
|
if (!_historialCompartido.Any(x => x.Id == _historialCompartidoSeleccionadoId))
|
||||||
_historialCompartidoSeleccionadoId = string.Empty;
|
_historialCompartidoSeleccionadoId = string.Empty;
|
||||||
|
if (_tipoReferenciaHistorial == TipoReferenciaHistorial.Compartido &&
|
||||||
|
!_historialCompartido.Any(x => x.Id == _historialReferenciaId))
|
||||||
|
{
|
||||||
|
LimpiarReferenciaHistorial();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
@@ -783,12 +805,14 @@ public partial class PlanificadorRutas
|
|||||||
{
|
{
|
||||||
_historialLocalSeleccionadoId = id;
|
_historialLocalSeleccionadoId = id;
|
||||||
_historialCompartidoSeleccionadoId = string.Empty;
|
_historialCompartidoSeleccionadoId = string.Empty;
|
||||||
|
EstablecerReferenciaHistorial(TipoReferenciaHistorial.Personal, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SeleccionarHistorialCompartido(string id)
|
private void SeleccionarHistorialCompartido(string id)
|
||||||
{
|
{
|
||||||
_historialLocalSeleccionadoId = string.Empty;
|
_historialLocalSeleccionadoId = string.Empty;
|
||||||
_historialCompartidoSeleccionadoId = id;
|
_historialCompartidoSeleccionadoId = id;
|
||||||
|
EstablecerReferenciaHistorial(TipoReferenciaHistorial.Compartido, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LimpiarSeleccionHistorial()
|
private void LimpiarSeleccionHistorial()
|
||||||
@@ -797,6 +821,74 @@ public partial class PlanificadorRutas
|
|||||||
_historialCompartidoSeleccionadoId = string.Empty;
|
_historialCompartidoSeleccionadoId = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool PrepararDerivacionHistorialParaRecalculo()
|
||||||
|
{
|
||||||
|
var procedeDeHistorial = _tipoReferenciaHistorial != TipoReferenciaHistorial.Ninguna &&
|
||||||
|
!string.IsNullOrWhiteSpace(_historialReferenciaId);
|
||||||
|
|
||||||
|
_rutaActualDerivadaDeHistorial = false;
|
||||||
|
LimpiarSeleccionHistorial();
|
||||||
|
return procedeDeHistorial;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfirmarDerivacionHistorial()
|
||||||
|
{
|
||||||
|
_rutaActualDerivadaDeHistorial = ExisteReferenciaHistorialActual();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EstablecerReferenciaHistorial(TipoReferenciaHistorial tipo, string id)
|
||||||
|
{
|
||||||
|
_tipoReferenciaHistorial = tipo;
|
||||||
|
_historialReferenciaId = id;
|
||||||
|
_rutaActualDerivadaDeHistorial = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LimpiarReferenciaHistorial()
|
||||||
|
{
|
||||||
|
_tipoReferenciaHistorial = TipoReferenciaHistorial.Ninguna;
|
||||||
|
_historialReferenciaId = string.Empty;
|
||||||
|
_rutaActualDerivadaDeHistorial = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ExisteReferenciaHistorialActual()
|
||||||
|
=> _tipoReferenciaHistorial switch
|
||||||
|
{
|
||||||
|
TipoReferenciaHistorial.Personal =>
|
||||||
|
_historialLocal.Any(x => x.Id == _historialReferenciaId),
|
||||||
|
TipoReferenciaHistorial.Compartido =>
|
||||||
|
_historialCompartido.Any(x => x.Id == _historialReferenciaId),
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
|
||||||
|
private bool EsReferenciaDerivadaHistorialPersonal(string id)
|
||||||
|
=> _rutaActualDerivadaDeHistorial &&
|
||||||
|
_tipoReferenciaHistorial == TipoReferenciaHistorial.Personal &&
|
||||||
|
string.Equals(_historialReferenciaId, id, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
private bool EsReferenciaDerivadaHistorialCompartido(string id)
|
||||||
|
=> _rutaActualDerivadaDeHistorial &&
|
||||||
|
_tipoReferenciaHistorial == TipoReferenciaHistorial.Compartido &&
|
||||||
|
string.Equals(_historialReferenciaId, id, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
private string TextoReferenciaHistorialDerivado()
|
||||||
|
{
|
||||||
|
if (!_rutaActualDerivadaDeHistorial)
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
var (nombre, indice) = _tipoReferenciaHistorial switch
|
||||||
|
{
|
||||||
|
TipoReferenciaHistorial.Personal =>
|
||||||
|
("Personal", _historialLocal.FindIndex(x => x.Id == _historialReferenciaId)),
|
||||||
|
TipoReferenciaHistorial.Compartido =>
|
||||||
|
("Compartido", _historialCompartido.FindIndex(x => x.Id == _historialReferenciaId)),
|
||||||
|
_ => (string.Empty, -1)
|
||||||
|
};
|
||||||
|
|
||||||
|
return indice >= 0
|
||||||
|
? $"Ruta actual derivada del Historial {nombre} n.º {indice + 1}."
|
||||||
|
: string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task CompartirEscenarioActualAsync()
|
private async Task CompartirEscenarioActualAsync()
|
||||||
{
|
{
|
||||||
var actual = ConstruirRegistroHistorialActual()
|
var actual = ConstruirRegistroHistorialActual()
|
||||||
@@ -854,6 +946,11 @@ public partial class PlanificadorRutas
|
|||||||
|
|
||||||
var estabaSeleccionado = _historialLocalSeleccionadoId == id;
|
var estabaSeleccionado = _historialLocalSeleccionadoId == id;
|
||||||
_historialLocal.RemoveAt(indiceEliminado);
|
_historialLocal.RemoveAt(indiceEliminado);
|
||||||
|
if (_tipoReferenciaHistorial == TipoReferenciaHistorial.Personal &&
|
||||||
|
string.Equals(_historialReferenciaId, id, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
LimpiarReferenciaHistorial();
|
||||||
|
}
|
||||||
|
|
||||||
await PersistirHistorialLocalAsync();
|
await PersistirHistorialLocalAsync();
|
||||||
|
|
||||||
@@ -924,6 +1021,11 @@ public partial class PlanificadorRutas
|
|||||||
|
|
||||||
await CargarHistorialCompartidoAsync();
|
await CargarHistorialCompartidoAsync();
|
||||||
_historialCompartido.RemoveAll(x => x.Id == id);
|
_historialCompartido.RemoveAll(x => x.Id == id);
|
||||||
|
if (_tipoReferenciaHistorial == TipoReferenciaHistorial.Compartido &&
|
||||||
|
string.Equals(_historialReferenciaId, id, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
LimpiarReferenciaHistorial();
|
||||||
|
}
|
||||||
|
|
||||||
if (estabaSeleccionado)
|
if (estabaSeleccionado)
|
||||||
{
|
{
|
||||||
@@ -973,9 +1075,11 @@ public partial class PlanificadorRutas
|
|||||||
_criterioPrioritarioRuta = NormalizarCriterioRuta(item.CriterioPrioritarioRuta, item.PreferenciaEtiquetaRuta);
|
_criterioPrioritarioRuta = NormalizarCriterioRuta(item.CriterioPrioritarioRuta, item.PreferenciaEtiquetaRuta);
|
||||||
SincronizarPreferenciaDesdeCriterioRuta();
|
SincronizarPreferenciaDesdeCriterioRuta();
|
||||||
|
|
||||||
if (item.FactorEquilibradoAndarBus is { } factorEquilibrado && double.IsFinite(factorEquilibrado))
|
if (item.FactorEquilibradoAndarBus is { } factorEquilibrado &&
|
||||||
|
double.IsFinite(factorEquilibrado) &&
|
||||||
|
factorEquilibrado > 0)
|
||||||
{
|
{
|
||||||
_factorEquilibradoAndarBus = Math.Max(0, factorEquilibrado);
|
_factorEquilibradoAndarBus = factorEquilibrado;
|
||||||
SincronizarTextosPenalizacionPie();
|
SincronizarTextosPenalizacionPie();
|
||||||
|
|
||||||
if (_configuracionTemporalPreviaHistorial is not null)
|
if (_configuracionTemporalPreviaHistorial is not null)
|
||||||
@@ -1063,8 +1167,9 @@ public partial class PlanificadorRutas
|
|||||||
HoraSimulada = TimeOnly.FromDateTime(ahora).ToString("HH:mm:ss", CultureInfo.InvariantCulture),
|
HoraSimulada = TimeOnly.FromDateTime(ahora).ToString("HH:mm:ss", CultureInfo.InvariantCulture),
|
||||||
CriterioPrioritarioRuta = _criterioPrioritarioRuta,
|
CriterioPrioritarioRuta = _criterioPrioritarioRuta,
|
||||||
PreferenciaEtiquetaRuta = _preferenciaEtiquetaRuta,
|
PreferenciaEtiquetaRuta = _preferenciaEtiquetaRuta,
|
||||||
FactorEquilibradoAndarBus = double.IsFinite(_factorEquilibradoAndarBus)
|
FactorEquilibradoAndarBus = double.IsFinite(_factorEquilibradoAndarBus) &&
|
||||||
? Math.Max(0, _factorEquilibradoAndarBus)
|
_factorEquilibradoAndarBus > 0
|
||||||
|
? _factorEquilibradoAndarBus
|
||||||
: FactorEquilibradoAndarBusPorDefecto,
|
: FactorEquilibradoAndarBusPorDefecto,
|
||||||
ActivarFiltroLineas = _activarRangoLineas,
|
ActivarFiltroLineas = _activarRangoLineas,
|
||||||
LineasPermitidas = ObtenerLineasPermitidasSeleccionadas().ToList(),
|
LineasPermitidas = ObtenerLineasPermitidasSeleccionadas().ToList(),
|
||||||
@@ -1194,8 +1299,10 @@ public partial class PlanificadorRutas
|
|||||||
var fecha = item.UsarHoraSimulada ? item.FechaSimulada?.Trim() ?? string.Empty : string.Empty;
|
var fecha = item.UsarHoraSimulada ? item.FechaSimulada?.Trim() ?? string.Empty : string.Empty;
|
||||||
var hora = item.UsarHoraSimulada ? item.HoraSimulada?.Trim() ?? string.Empty : string.Empty;
|
var hora = item.UsarHoraSimulada ? item.HoraSimulada?.Trim() ?? string.Empty : string.Empty;
|
||||||
var criterio = NormalizarCriterioRuta(item.CriterioPrioritarioRuta, item.PreferenciaEtiquetaRuta);
|
var criterio = NormalizarCriterioRuta(item.CriterioPrioritarioRuta, item.PreferenciaEtiquetaRuta);
|
||||||
var factorEquilibrado = item.FactorEquilibradoAndarBus is { } factor && double.IsFinite(factor)
|
var factorEquilibrado = item.FactorEquilibradoAndarBus is { } factor &&
|
||||||
? Math.Max(0, factor).ToString("0.######", CultureInfo.InvariantCulture)
|
double.IsFinite(factor) &&
|
||||||
|
factor > 0
|
||||||
|
? factor.ToString("0.######", CultureInfo.InvariantCulture)
|
||||||
: string.Empty;
|
: string.Empty;
|
||||||
var lineas = item.ActivarFiltroLineas
|
var lineas = item.ActivarFiltroLineas
|
||||||
? string.Join(",", NormalizarLineasHistorial(item.LineasPermitidas))
|
? string.Join(",", NormalizarLineasHistorial(item.LineasPermitidas))
|
||||||
|
|||||||
@@ -1202,7 +1202,7 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
private bool _elevPopupMinimizado = false;
|
private bool _elevPopupMinimizado = false;
|
||||||
|
|
||||||
|
|
||||||
private const string _versionApp = "(v-20260807b)";
|
private const string _versionApp = "(v-20260825b)";
|
||||||
|
|
||||||
|
|
||||||
private double? _paradaElevIdee;
|
private double? _paradaElevIdee;
|
||||||
|
|||||||
@@ -227,11 +227,13 @@ public partial class PlanificadorRutas
|
|||||||
: coeficienteAltura;
|
: coeficienteAltura;
|
||||||
if (config.PesoTransbordoRankingMinutos is { } pesoTransbordo && double.IsFinite(pesoTransbordo))
|
if (config.PesoTransbordoRankingMinutos is { } pesoTransbordo && double.IsFinite(pesoTransbordo))
|
||||||
_pesoTransbordoRankingMinutos = Math.Abs(pesoTransbordo - 8.0) < 0.0001 ? 4.0 : Math.Max(0, pesoTransbordo);
|
_pesoTransbordoRankingMinutos = Math.Abs(pesoTransbordo - 8.0) < 0.0001 ? 4.0 : Math.Max(0, pesoTransbordo);
|
||||||
if (config.FactorEquilibradoAndarBus is { } factorEquilibrado && double.IsFinite(factorEquilibrado))
|
if (config.FactorEquilibradoAndarBus is { } factorEquilibrado &&
|
||||||
|
double.IsFinite(factorEquilibrado) &&
|
||||||
|
factorEquilibrado > 0)
|
||||||
_factorEquilibradoAndarBus = (config.VersionFactorEquilibrado ?? 0) < VersionPersistenciaFactorEquilibrado &&
|
_factorEquilibradoAndarBus = (config.VersionFactorEquilibrado ?? 0) < VersionPersistenciaFactorEquilibrado &&
|
||||||
Math.Abs(factorEquilibrado - 12.0) < 0.0001
|
Math.Abs(factorEquilibrado - 12.0) < 0.0001
|
||||||
? FactorEquilibradoAndarBusPorDefecto
|
? FactorEquilibradoAndarBusPorDefecto
|
||||||
: Math.Max(0, factorEquilibrado);
|
: factorEquilibrado;
|
||||||
var migrarValoresPendientes = (config.VersionPendientes ?? 0) < VersionPersistenciaPendientes;
|
var migrarValoresPendientes = (config.VersionPendientes ?? 0) < VersionPersistenciaPendientes;
|
||||||
_mostrarElevacionesRuta = migrarValoresPendientes
|
_mostrarElevacionesRuta = migrarValoresPendientes
|
||||||
? true
|
? true
|
||||||
|
|||||||
@@ -1270,9 +1270,123 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
var listaOrdenada = ordenadas.ToList();
|
var listaOrdenada = ordenadas.ToList();
|
||||||
_opcionesRuta.Clear();
|
_opcionesRuta.Clear();
|
||||||
_opcionesRuta.AddRange(listaOrdenada);
|
_opcionesRuta.AddRange(listaOrdenada);
|
||||||
|
FiltrarAlternativasBusRedundantes();
|
||||||
RenumerarEtiquetasGenericasOpcionesRuta();
|
RenumerarEtiquetasGenericasOpcionesRuta();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Conserva la mejor alternativa de cada direccion de acceso a una misma linea
|
||||||
|
/// y descarta rutas en bus que no ahorran ninguna distancia andando.
|
||||||
|
/// </summary>
|
||||||
|
private void FiltrarAlternativasBusRedundantes()
|
||||||
|
{
|
||||||
|
if (_opcionesRuta.Count <= 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var distanciaSoloPie = _opcionesRuta
|
||||||
|
.Where(opcion => opcion.EsSoloAPie &&
|
||||||
|
double.IsFinite(opcion.DistanciaSoloAPie) &&
|
||||||
|
opcion.DistanciaSoloAPie > 0)
|
||||||
|
.Select(opcion => opcion.DistanciaSoloAPie)
|
||||||
|
.DefaultIfEmpty(double.PositiveInfinity)
|
||||||
|
.Min();
|
||||||
|
|
||||||
|
var conservadas = new List<AlternativaRuta>(_opcionesRuta.Count);
|
||||||
|
foreach (var candidata in _opcionesRuta)
|
||||||
|
{
|
||||||
|
if (candidata.EsSoloAPie)
|
||||||
|
{
|
||||||
|
conservadas.Add(candidata);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (double.IsFinite(distanciaSoloPie) &&
|
||||||
|
double.IsFinite(candidata.DistanciaPieTotalAprox) &&
|
||||||
|
candidata.DistanciaPieTotalAprox >= distanciaSoloPie)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var repiteDireccionAcceso = conservadas.Any(referencia =>
|
||||||
|
!referencia.EsSoloAPie &&
|
||||||
|
EsMismaLineaInicial(referencia, candidata) &&
|
||||||
|
CaminanEnLaMismaDireccionDesdeOrigen(referencia, candidata));
|
||||||
|
|
||||||
|
if (!repiteDireccionAcceso)
|
||||||
|
conservadas.Add(candidata);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conservadas.Count == _opcionesRuta.Count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_opcionesRuta.Clear();
|
||||||
|
_opcionesRuta.AddRange(conservadas);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool EsMismaLineaInicial(
|
||||||
|
AlternativaRuta referencia,
|
||||||
|
AlternativaRuta candidata)
|
||||||
|
{
|
||||||
|
var tramoReferencia = referencia.AlternativaBus?.Tramos.FirstOrDefault();
|
||||||
|
var tramoCandidata = candidata.AlternativaBus?.Tramos.FirstOrDefault();
|
||||||
|
if (tramoReferencia is null || tramoCandidata is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return string.Equals(
|
||||||
|
UtilidadesTransitoDbus.LineaCodigoStr(tramoReferencia.Variante),
|
||||||
|
UtilidadesTransitoDbus.LineaCodigoStr(tramoCandidata.Variante),
|
||||||
|
StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
tramoReferencia.Variante.CodigoItinerario == tramoCandidata.Variante.CodigoItinerario;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CaminanEnLaMismaDireccionDesdeOrigen(
|
||||||
|
AlternativaRuta referencia,
|
||||||
|
AlternativaRuta candidata)
|
||||||
|
{
|
||||||
|
if (_coordenadasOrigen is null ||
|
||||||
|
_coordenadasOrigen.Length < 2 ||
|
||||||
|
referencia.OrigenParada is null ||
|
||||||
|
candidata.OrigenParada is null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var latitudOrigen = _coordenadasOrigen[0];
|
||||||
|
var longitudOrigen = _coordenadasOrigen[1];
|
||||||
|
if (!double.IsFinite(latitudOrigen) || !double.IsFinite(longitudOrigen))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var metrosPorGradoLatitud = 111_320d;
|
||||||
|
var metrosPorGradoLongitud =
|
||||||
|
metrosPorGradoLatitud * Math.Cos(latitudOrigen * Math.PI / 180d);
|
||||||
|
|
||||||
|
var referenciaX =
|
||||||
|
(referencia.OrigenParada.Longitud - longitudOrigen) * metrosPorGradoLongitud;
|
||||||
|
var referenciaY =
|
||||||
|
(referencia.OrigenParada.Latitud - latitudOrigen) * metrosPorGradoLatitud;
|
||||||
|
var candidataX =
|
||||||
|
(candidata.OrigenParada.Longitud - longitudOrigen) * metrosPorGradoLongitud;
|
||||||
|
var candidataY =
|
||||||
|
(candidata.OrigenParada.Latitud - latitudOrigen) * metrosPorGradoLatitud;
|
||||||
|
|
||||||
|
var moduloReferencia = Math.Sqrt(
|
||||||
|
referenciaX * referenciaX + referenciaY * referenciaY);
|
||||||
|
var moduloCandidata = Math.Sqrt(
|
||||||
|
candidataX * candidataX + candidataY * candidataY);
|
||||||
|
if (!double.IsFinite(moduloReferencia) ||
|
||||||
|
!double.IsFinite(moduloCandidata) ||
|
||||||
|
moduloReferencia < 1d ||
|
||||||
|
moduloCandidata < 1d)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cosenoDireccion =
|
||||||
|
(referenciaX * candidataX + referenciaY * candidataY) /
|
||||||
|
(moduloReferencia * moduloCandidata);
|
||||||
|
return double.IsFinite(cosenoDireccion) && cosenoDireccion >= 0d;
|
||||||
|
}
|
||||||
|
|
||||||
private void RenumerarEtiquetasGenericasOpcionesRuta()
|
private void RenumerarEtiquetasGenericasOpcionesRuta()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < _opcionesRuta.Count; i++)
|
for (var i = 0; i < _opcionesRuta.Count; i++)
|
||||||
@@ -1744,8 +1858,8 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
|
|
||||||
_mostrarElevacionesRuta = _mostrarElevacionesRutaConfiguracion;
|
_mostrarElevacionesRuta = _mostrarElevacionesRutaConfiguracion;
|
||||||
|
|
||||||
if (!_aplicandoRegistroHistorial)
|
var confirmarDerivacionHistorial = !_aplicandoRegistroHistorial &&
|
||||||
LimpiarSeleccionHistorial();
|
PrepararDerivacionHistorialParaRecalculo();
|
||||||
|
|
||||||
var cronometroCalculo = System.Diagnostics.Stopwatch.StartNew();
|
var cronometroCalculo = System.Diagnostics.Stopwatch.StartNew();
|
||||||
_panelRutasMovilContraido = _mostrarBuscadorMapa;
|
_panelRutasMovilContraido = _mostrarBuscadorMapa;
|
||||||
@@ -1872,6 +1986,8 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
{
|
{
|
||||||
await RegistrarEscenarioActualEnHistorialLocalAsync();
|
await RegistrarEscenarioActualEnHistorialLocalAsync();
|
||||||
}
|
}
|
||||||
|
if (confirmarDerivacionHistorial)
|
||||||
|
ConfirmarDerivacionHistorial();
|
||||||
await ActualizarResumenTecnicoRutaAsync(CancellationToken.None);
|
await ActualizarResumenTecnicoRutaAsync(CancellationToken.None);
|
||||||
_tiempoUltimoCalculoRuta = cronometroCalculo.Elapsed;
|
_tiempoUltimoCalculoRuta = cronometroCalculo.Elapsed;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
|||||||
@@ -1151,6 +1151,8 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
|
|
||||||
_coordenadasOrigen = null;
|
_coordenadasOrigen = null;
|
||||||
_coordenadasDestino = null;
|
_coordenadasDestino = null;
|
||||||
|
LimpiarSeleccionHistorial();
|
||||||
|
LimpiarReferenciaHistorial();
|
||||||
_textoBusquedaOrigen = string.Empty;
|
_textoBusquedaOrigen = string.Empty;
|
||||||
_textoBusquedaDestino = string.Empty;
|
_textoBusquedaDestino = string.Empty;
|
||||||
_ubicacionOrigenSeleccionada = null;
|
_ubicacionOrigenSeleccionada = null;
|
||||||
|
|||||||
@@ -913,7 +913,6 @@
|
|||||||
: _duracionTotalSegundos;
|
: _duracionTotalSegundos;
|
||||||
var dRecta = DistanciaLineaRectaOrigenDestino();
|
var dRecta = DistanciaLineaRectaOrigenDestino();
|
||||||
var dCorregida = CalcularDistanciaCorregidaAlternativa(altSeleccionada);
|
var dCorregida = CalcularDistanciaCorregidaAlternativa(altSeleccionada);
|
||||||
var dEquilibradaAndando = CalcularDistanciaEquilibradaAndandoAlternativa(altSeleccionada);
|
|
||||||
var xyzOrigen = FormatearResumenXYZOrigen();
|
var xyzOrigen = FormatearResumenXYZOrigen();
|
||||||
var xyzDestino = FormatearResumenXYZDestino();
|
var xyzDestino = FormatearResumenXYZDestino();
|
||||||
var callejeroOrigen = FormatearResumenCallejeroOrigen();
|
var callejeroOrigen = FormatearResumenCallejeroOrigen();
|
||||||
@@ -934,7 +933,7 @@
|
|||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (dRecta > 0 || dCorregida > 0 || dEquilibradaAndando > 0)
|
@if (dRecta > 0 || dCorregida > 0)
|
||||||
{
|
{
|
||||||
<div class="muted" style="font-size:0.75rem;margin-top:4px;">
|
<div class="muted" style="font-size:0.75rem;margin-top:4px;">
|
||||||
@if (dRecta > 0)
|
@if (dRecta > 0)
|
||||||
@@ -945,10 +944,6 @@
|
|||||||
{
|
{
|
||||||
<div>d.Corregida a pie: @FormatearDistanciaDetalleRuta(dCorregida)</div>
|
<div>d.Corregida a pie: @FormatearDistanciaDetalleRuta(dCorregida)</div>
|
||||||
}
|
}
|
||||||
@if (dEquilibradaAndando > 0)
|
|
||||||
{
|
|
||||||
<div>d.Equilib. A: @FormatearDistanciaDetalleRuta(dEquilibradaAndando)</div>
|
|
||||||
}
|
|
||||||
@if (!string.IsNullOrWhiteSpace(scoreEquilibradoSeleccionado))
|
@if (!string.IsNullOrWhiteSpace(scoreEquilibradoSeleccionado))
|
||||||
{
|
{
|
||||||
<div>Score equilibrado A: @scoreEquilibradoSeleccionado</div>
|
<div>Score equilibrado A: @scoreEquilibradoSeleccionado</div>
|
||||||
@@ -1067,12 +1062,18 @@
|
|||||||
{
|
{
|
||||||
var item = _historialLocal[i];
|
var item = _historialLocal[i];
|
||||||
var numeroPersonal = i + 1;
|
var numeroPersonal = i + 1;
|
||||||
|
var esReferenciaDerivada = EsReferenciaDerivadaHistorialPersonal(item.Id);
|
||||||
|
|
||||||
<div class="history-item @(item.Id == _historialLocalSeleccionadoId ? "history-item--selected" : "")">
|
<div class="history-item @(item.Id == _historialLocalSeleccionadoId ? "history-item--selected" : "") @(esReferenciaDerivada ? "history-item--derived-source" : "")">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="history-item-main history-item-main--numbered"
|
class="history-item-main history-item-main--numbered"
|
||||||
@onclick="() => CargarHistorialLocalAsync(item.Id)">
|
@onclick="() => CargarHistorialLocalAsync(item.Id)">
|
||||||
<span class="history-item-number">@numeroPersonal.</span>
|
<span class="history-item-number">
|
||||||
|
@numeroPersonal.@if (esReferenciaDerivada)
|
||||||
|
{
|
||||||
|
<span class="history-derived-marker" title="La ruta actual parte de este historial">*</span>
|
||||||
|
}
|
||||||
|
</span>
|
||||||
<span class="history-item-text">@TextoOpcionHistorial(item)</span>
|
<span class="history-item-text">@TextoOpcionHistorial(item)</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -1129,12 +1130,18 @@
|
|||||||
{
|
{
|
||||||
var item = _historialCompartido[i];
|
var item = _historialCompartido[i];
|
||||||
var numeroCompartido = i + 1;
|
var numeroCompartido = i + 1;
|
||||||
|
var esReferenciaDerivada = EsReferenciaDerivadaHistorialCompartido(item.Id);
|
||||||
|
|
||||||
<div class="history-item @(item.Id == _historialCompartidoSeleccionadoId ? "history-item--selected" : "")">
|
<div class="history-item @(item.Id == _historialCompartidoSeleccionadoId ? "history-item--selected" : "") @(esReferenciaDerivada ? "history-item--derived-source" : "")">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="history-item-main history-item-main--numbered"
|
class="history-item-main history-item-main--numbered"
|
||||||
@onclick="() => CargarHistorialCompartidoAsync(item.Id)">
|
@onclick="() => CargarHistorialCompartidoAsync(item.Id)">
|
||||||
<span class="history-item-number">@numeroCompartido.</span>
|
<span class="history-item-number">
|
||||||
|
@numeroCompartido.@if (esReferenciaDerivada)
|
||||||
|
{
|
||||||
|
<span class="history-derived-marker" title="La ruta actual parte de este historial">*</span>
|
||||||
|
}
|
||||||
|
</span>
|
||||||
<span class="history-item-text">@TextoOpcionHistorial(item)</span>
|
<span class="history-item-text">@TextoOpcionHistorial(item)</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -1150,7 +1157,17 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (!string.IsNullOrWhiteSpace(_mensajeHistorial))
|
@{ var textoReferenciaDerivada = TextoReferenciaHistorialDerivado(); }
|
||||||
|
@if (!string.IsNullOrWhiteSpace(textoReferenciaDerivada))
|
||||||
|
{
|
||||||
|
<div class="history-derived-note">
|
||||||
|
<span class="history-derived-marker" aria-hidden="true">*</span>
|
||||||
|
<span>@textoReferenciaDerivada</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (!string.IsNullOrWhiteSpace(_mensajeHistorial) &&
|
||||||
|
(string.IsNullOrWhiteSpace(textoReferenciaDerivada) || _mensajeHistorialEsError))
|
||||||
{
|
{
|
||||||
<div class="history-feedback @(_mensajeHistorialEsError ? "history-feedback--error" : "")">
|
<div class="history-feedback @(_mensajeHistorialEsError ? "history-feedback--error" : "")">
|
||||||
@_mensajeHistorial
|
@_mensajeHistorial
|
||||||
@@ -1499,9 +1516,9 @@
|
|||||||
<div class="config-dual-labeled">
|
<div class="config-dual-labeled">
|
||||||
<label class="config-dual-labeled__field">
|
<label class="config-dual-labeled__field">
|
||||||
<span>Equilib. A</span>
|
<span>Equilib. A</span>
|
||||||
<input type="number" class="config-input" step="0.1" min="0"
|
<input type="number" class="config-input" step="0.1" min="0.1"
|
||||||
placeholder="6"
|
placeholder="6"
|
||||||
title="Factor del modo equilibrado"
|
title="Divisor de la distancia en bus en el modo equilibrado"
|
||||||
@bind="FactorEquilibradoAndarBusTexto" @bind:event="oninput"
|
@bind="FactorEquilibradoAndarBusTexto" @bind:event="oninput"
|
||||||
@onblur="OnBlurFactorEquilibradoAndarBus" />
|
@onblur="OnBlurFactorEquilibradoAndarBus" />
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public sealed class ParametrosPlanificadorRuta
|
|||||||
public double FactorPenalizacionDistanciaPie { get; set; } = 1.35;
|
public double FactorPenalizacionDistanciaPie { get; set; } = 1.35;
|
||||||
public double ParametroPenalizacionDistanciaPieMetros { get; set; } = 200.0;
|
public double ParametroPenalizacionDistanciaPieMetros { get; set; } = 200.0;
|
||||||
public double PesoTransbordoRankingMinutos { get; set; } = 4.0;
|
public double PesoTransbordoRankingMinutos { get; set; } = 4.0;
|
||||||
|
// Divisor aplicado a la distancia en bus dentro del score equilibrado.
|
||||||
public double FactorEquilibradoAndarBus { get; set; } = 6.0;
|
public double FactorEquilibradoAndarBus { get; set; } = 6.0;
|
||||||
|
|
||||||
// selección candidatas
|
// selección candidatas
|
||||||
|
|||||||
@@ -315,8 +315,10 @@ public sealed class ServicioHistorialRutasCompartido : IHistorialRutasCompartido
|
|||||||
var criterio = NormalizarTextoClave(item.CriterioPrioritarioRuta);
|
var criterio = NormalizarTextoClave(item.CriterioPrioritarioRuta);
|
||||||
if (string.IsNullOrWhiteSpace(criterio))
|
if (string.IsNullOrWhiteSpace(criterio))
|
||||||
criterio = NormalizarTextoClave(item.PreferenciaEtiquetaRuta);
|
criterio = NormalizarTextoClave(item.PreferenciaEtiquetaRuta);
|
||||||
var factorEquilibrado = item.FactorEquilibradoAndarBus is { } factor && double.IsFinite(factor)
|
var factorEquilibrado = item.FactorEquilibradoAndarBus is { } factor &&
|
||||||
? Math.Max(0, factor).ToString("0.######", CultureInfo.InvariantCulture)
|
double.IsFinite(factor) &&
|
||||||
|
factor > 0
|
||||||
|
? factor.ToString("0.######", CultureInfo.InvariantCulture)
|
||||||
: string.Empty;
|
: string.Empty;
|
||||||
var lineas = item.ActivarFiltroLineas
|
var lineas = item.ActivarFiltroLineas
|
||||||
? string.Join(",", NormalizarLineas(item.LineasPermitidas))
|
? string.Join(",", NormalizarLineas(item.LineasPermitidas))
|
||||||
|
|||||||
@@ -826,14 +826,15 @@ public sealed class BuscadorRutasTemporalesDbus
|
|||||||
resultado.DistanciasPieTransbordosPorTramo,
|
resultado.DistanciasPieTransbordosPorTramo,
|
||||||
resultado.DistanciaPieFin),
|
resultado.DistanciaPieFin),
|
||||||
parametros);
|
parametros);
|
||||||
var factor = double.IsFinite(parametros.FactorEquilibradoAndarBus)
|
var factor = double.IsFinite(parametros.FactorEquilibradoAndarBus) &&
|
||||||
? Math.Max(0, parametros.FactorEquilibradoAndarBus)
|
parametros.FactorEquilibradoAndarBus > 0
|
||||||
|
? parametros.FactorEquilibradoAndarBus
|
||||||
: 6.0;
|
: 6.0;
|
||||||
var penalizacionTransbordos = UtilidadesTransitoDbus.CalcularPenalizacionTransbordosRankingMetros(
|
var penalizacionTransbordos = UtilidadesTransitoDbus.CalcularPenalizacionTransbordosRankingMetros(
|
||||||
UtilidadesTransitoDbus.ContarTransbordosReales(resultado.RutaBus.Tramos),
|
UtilidadesTransitoDbus.ContarTransbordosReales(resultado.RutaBus.Tramos),
|
||||||
parametros);
|
parametros);
|
||||||
|
|
||||||
var score = distanciaBus + (distanciaAndando * factor) + penalizacionTransbordos;
|
var score = distanciaAndando + (distanciaBus / factor) + penalizacionTransbordos;
|
||||||
return double.IsFinite(score) && score >= 0
|
return double.IsFinite(score) && score >= 0
|
||||||
? score
|
? score
|
||||||
: double.PositiveInfinity;
|
: double.PositiveInfinity;
|
||||||
|
|||||||
@@ -1543,8 +1543,10 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
|||||||
: UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaTotalMetros(
|
: UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaTotalMetros(
|
||||||
ConstruirDistanciasPiePorTramo(resultado),
|
ConstruirDistanciasPiePorTramo(resultado),
|
||||||
parametros);
|
parametros);
|
||||||
var factor = parametros is not null && double.IsFinite(parametros.FactorEquilibradoAndarBus)
|
var factor = parametros is not null &&
|
||||||
? Math.Max(0, parametros.FactorEquilibradoAndarBus)
|
double.IsFinite(parametros.FactorEquilibradoAndarBus) &&
|
||||||
|
parametros.FactorEquilibradoAndarBus > 0
|
||||||
|
? parametros.FactorEquilibradoAndarBus
|
||||||
: 6.0;
|
: 6.0;
|
||||||
var penalizacionTransbordos = parametros is null
|
var penalizacionTransbordos = parametros is null
|
||||||
? 0
|
? 0
|
||||||
@@ -1552,7 +1554,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
|||||||
UtilidadesTransitoDbus.ContarTransbordosReales(resultado.RutaBus.Tramos),
|
UtilidadesTransitoDbus.ContarTransbordosReales(resultado.RutaBus.Tramos),
|
||||||
parametros);
|
parametros);
|
||||||
|
|
||||||
var score = distanciaBus + (distanciaAndando * factor) + penalizacionTransbordos;
|
var score = distanciaAndando + (distanciaBus / factor) + penalizacionTransbordos;
|
||||||
return double.IsFinite(score) && score >= 0
|
return double.IsFinite(score) && score >= 0
|
||||||
? score
|
? score
|
||||||
: double.PositiveInfinity;
|
: double.PositiveInfinity;
|
||||||
@@ -3244,14 +3246,15 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
|||||||
|
|
||||||
var distanciaBus = Math.Max(0, alternativa.AlternativaBus.DistanciaTotalBus);
|
var distanciaBus = Math.Max(0, alternativa.AlternativaBus.DistanciaTotalBus);
|
||||||
var distanciaAndando = CalcularDistanciaAndandoCorregidaMetros(alternativa, parametros);
|
var distanciaAndando = CalcularDistanciaAndandoCorregidaMetros(alternativa, parametros);
|
||||||
var factor = double.IsFinite(parametros.FactorEquilibradoAndarBus)
|
var factor = double.IsFinite(parametros.FactorEquilibradoAndarBus) &&
|
||||||
? Math.Max(0, parametros.FactorEquilibradoAndarBus)
|
parametros.FactorEquilibradoAndarBus > 0
|
||||||
|
? parametros.FactorEquilibradoAndarBus
|
||||||
: 6.0;
|
: 6.0;
|
||||||
var penalizacionTransbordos = UtilidadesTransitoDbus.CalcularPenalizacionTransbordosRankingMetros(
|
var penalizacionTransbordos = UtilidadesTransitoDbus.CalcularPenalizacionTransbordosRankingMetros(
|
||||||
alternativa.NumeroTransbordosReales,
|
alternativa.NumeroTransbordosReales,
|
||||||
parametros);
|
parametros);
|
||||||
|
|
||||||
var score = distanciaBus + (distanciaAndando * factor) + penalizacionTransbordos;
|
var score = distanciaAndando + (distanciaBus / factor) + penalizacionTransbordos;
|
||||||
return double.IsFinite(score) && score >= 0
|
return double.IsFinite(score) && score >= 0
|
||||||
? score
|
? score
|
||||||
: double.PositiveInfinity;
|
: double.PositiveInfinity;
|
||||||
@@ -3508,8 +3511,8 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Firma orientada a UI: agrupa alternativas con la misma secuencia de lineas y sentidos
|
/// Firma orientada a UI: agrupa solo alternativas con el mismo recorrido visible.
|
||||||
/// aunque cambie la parada exacta.
|
/// Las paradas forman parte de la identidad porque cambian el acceso a pie y sus pendientes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static string CrearFirmaFamiliaRutaBus(RutaBusAlternativa alternativa)
|
private static string CrearFirmaFamiliaRutaBus(RutaBusAlternativa alternativa)
|
||||||
{
|
{
|
||||||
@@ -3518,7 +3521,8 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
|||||||
{
|
{
|
||||||
var linea = UtilidadesTransitoDbus.LineaCodigoStr(tramo.Variante);
|
var linea = UtilidadesTransitoDbus.LineaCodigoStr(tramo.Variante);
|
||||||
var sentido = UtilidadesTransitoDbus.NormalizarSentidoCodigo(tramo.Variante.Sentido?.Codigo);
|
var sentido = UtilidadesTransitoDbus.NormalizarSentidoCodigo(tramo.Variante.Sentido?.Codigo);
|
||||||
var parte = $"{linea}.{tramo.Variante.CodigoItinerario}-{sentido}";
|
var parte = $"{linea}.{tramo.Variante.CodigoItinerario}-{sentido}:" +
|
||||||
|
$"{tramo.CodigoParadaInicio}>{tramo.CodigoParadaFin}";
|
||||||
if (partes.Count == 0 || !string.Equals(partes[^1], parte, StringComparison.OrdinalIgnoreCase))
|
if (partes.Count == 0 || !string.Equals(partes[^1], parte, StringComparison.OrdinalIgnoreCase))
|
||||||
partes.Add(parte);
|
partes.Add(parte);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1232,6 +1232,24 @@ html, body {
|
|||||||
background: rgba(21,128,61,.18);
|
background: rgba(21,128,61,.18);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.history-item--derived-source .history-item-main {
|
||||||
|
border-color: rgba(245,158,11,.72);
|
||||||
|
background: rgba(120,53,15,.17);
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-derived-marker {
|
||||||
|
color: #fbbf24;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-derived-note {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: .35rem;
|
||||||
|
font-size: .76rem;
|
||||||
|
color: #fcd34d;
|
||||||
|
}
|
||||||
|
|
||||||
.history-item-action,
|
.history-item-action,
|
||||||
.history-item-delete {
|
.history-item-delete {
|
||||||
flex: 0 0 32px;
|
flex: 0 0 32px;
|
||||||
|
|||||||
Reference in New Issue
Block a user