cambios n el horiario del taxibus

arreglado buscador de asti

arreglado buscador con la ñ

añadido 2 niveles de colores en cuestas

añadido 2 niveles de umbrales en la configuracion de alturas
This commit is contained in:
2026-08-28 13:53:19 +02:00
parent 3a629de887
commit b52cea97b1
9 changed files with 150 additions and 11 deletions

View File

@@ -53,6 +53,8 @@ public partial class PlanificadorRutas : ComponentBase
private const double PendienteMaximaEsfuerzoPorcentaje = 80.0; private const double PendienteMaximaEsfuerzoPorcentaje = 80.0;
private const double FactorEquilibradoAndarBusPorDefecto = 6.0; private const double FactorEquilibradoAndarBusPorDefecto = 6.0;
private const double UmbralPendienteSubidaRutaPorDefecto = 2.0; private const double UmbralPendienteSubidaRutaPorDefecto = 2.0;
private const double UmbralPendienteSubidaMediaRutaPorDefecto = 5.0;
private const double UmbralPendienteSubidaFuerteRutaPorDefecto = 10.0;
private const double UmbralPendienteBajadaRutaPorDefecto = 5.0; private const double UmbralPendienteBajadaRutaPorDefecto = 5.0;
private const double UmbralAlturaAlertaPendienteRutaMetrosPorDefecto = 6.0; private const double UmbralAlturaAlertaPendienteRutaMetrosPorDefecto = 6.0;
private const double MetrosPorPiso = 3.0; private const double MetrosPorPiso = 3.0;
@@ -368,6 +370,8 @@ public partial class PlanificadorRutas : ComponentBase
private bool _mostrarConfiguracionPendientesRuta = false; private bool _mostrarConfiguracionPendientesRuta = false;
private bool _panelRutasMovilContraido = false; private bool _panelRutasMovilContraido = false;
private double _umbralPendienteSubidaRuta = UmbralPendienteSubidaRutaPorDefecto; private double _umbralPendienteSubidaRuta = UmbralPendienteSubidaRutaPorDefecto;
private double _umbralPendienteSubidaMediaRuta = UmbralPendienteSubidaMediaRutaPorDefecto;
private double _umbralPendienteSubidaFuerteRuta = UmbralPendienteSubidaFuerteRutaPorDefecto;
private double _umbralPendienteBajadaRuta = UmbralPendienteBajadaRutaPorDefecto; private double _umbralPendienteBajadaRuta = UmbralPendienteBajadaRutaPorDefecto;
private double _umbralAlturaAlertaPendienteRutaMetros = UmbralAlturaAlertaPendienteRutaMetrosPorDefecto; private double _umbralAlturaAlertaPendienteRutaMetros = UmbralAlturaAlertaPendienteRutaMetrosPorDefecto;
private double _alturaPendientePositivaSignificativaRutaMetros = 0.0; private double _alturaPendientePositivaSignificativaRutaMetros = 0.0;

View File

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

View File

@@ -49,6 +49,8 @@ public partial class PlanificadorRutas
public int? VersionFuenteElevacion { get; set; } public int? VersionFuenteElevacion { get; set; }
public int? VersionPendientes { get; set; } public int? VersionPendientes { get; set; }
public double? UmbralPendienteSubidaRuta { get; set; } public double? UmbralPendienteSubidaRuta { get; set; }
public double? UmbralPendienteSubidaMediaRuta { get; set; }
public double? UmbralPendienteSubidaFuerteRuta { get; set; }
public double? UmbralPendienteBajadaRuta { get; set; } public double? UmbralPendienteBajadaRuta { get; set; }
public double? UmbralAlturaAlertaPendienteRutaMetros { get; set; } public double? UmbralAlturaAlertaPendienteRutaMetros { get; set; }
// Compatibilidad con configuraciones guardadas cuando el umbral se expresaba en pisos. // Compatibilidad con configuraciones guardadas cuando el umbral se expresaba en pisos.
@@ -167,6 +169,8 @@ public partial class PlanificadorRutas
VersionFuenteElevacion = VersionPersistenciaFuenteElevacion, VersionFuenteElevacion = VersionPersistenciaFuenteElevacion,
VersionPendientes = VersionPersistenciaPendientes, VersionPendientes = VersionPersistenciaPendientes,
UmbralPendienteSubidaRuta = _umbralPendienteSubidaRuta, UmbralPendienteSubidaRuta = _umbralPendienteSubidaRuta,
UmbralPendienteSubidaMediaRuta = _umbralPendienteSubidaMediaRuta,
UmbralPendienteSubidaFuerteRuta = _umbralPendienteSubidaFuerteRuta,
UmbralPendienteBajadaRuta = _umbralPendienteBajadaRuta, UmbralPendienteBajadaRuta = _umbralPendienteBajadaRuta,
UmbralAlturaAlertaPendienteRutaMetros = _umbralAlturaAlertaPendienteRutaMetros, UmbralAlturaAlertaPendienteRutaMetros = _umbralAlturaAlertaPendienteRutaMetros,
VelocidadPieKmH = _velocidadPieKmH, VelocidadPieKmH = _velocidadPieKmH,
@@ -262,6 +266,17 @@ public partial class PlanificadorRutas
_umbralPendienteSubidaRuta = Math.Abs(umbralSubida - 3.0) < 0.0001 _umbralPendienteSubidaRuta = Math.Abs(umbralSubida - 3.0) < 0.0001
? UmbralPendienteSubidaRutaPorDefecto ? UmbralPendienteSubidaRutaPorDefecto
: NormalizarUmbralPendienteRuta(umbralSubida); : NormalizarUmbralPendienteRuta(umbralSubida);
_umbralPendienteSubidaMediaRuta =
config.UmbralPendienteSubidaMediaRuta is { } umbralSubidaMedia &&
double.IsFinite(umbralSubidaMedia)
? NormalizarUmbralPendienteRuta(umbralSubidaMedia)
: UmbralPendienteSubidaMediaRutaPorDefecto;
_umbralPendienteSubidaFuerteRuta =
config.UmbralPendienteSubidaFuerteRuta is { } umbralSubidaFuerte &&
double.IsFinite(umbralSubidaFuerte)
? NormalizarUmbralPendienteRuta(umbralSubidaFuerte)
: UmbralPendienteSubidaFuerteRutaPorDefecto;
NormalizarOrdenUmbralesColorSubidaRuta();
if (config.UmbralPendienteBajadaRuta is { } umbralBajada && double.IsFinite(umbralBajada)) if (config.UmbralPendienteBajadaRuta is { } umbralBajada && double.IsFinite(umbralBajada))
_umbralPendienteBajadaRuta = _umbralPendienteBajadaRuta =
Math.Abs(umbralBajada - 3.0) < 0.0001 || Math.Abs(umbralBajada - 3.0) < 0.0001 ||
@@ -391,6 +406,8 @@ public partial class PlanificadorRutas
_mostrarElevacionesRutaConfiguracion = true; _mostrarElevacionesRutaConfiguracion = true;
_fuenteElevacionCalculo = FuenteElevacionLocal5; _fuenteElevacionCalculo = FuenteElevacionLocal5;
_umbralPendienteSubidaRuta = UmbralPendienteSubidaRutaPorDefecto; _umbralPendienteSubidaRuta = UmbralPendienteSubidaRutaPorDefecto;
_umbralPendienteSubidaMediaRuta = UmbralPendienteSubidaMediaRutaPorDefecto;
_umbralPendienteSubidaFuerteRuta = UmbralPendienteSubidaFuerteRutaPorDefecto;
_umbralPendienteBajadaRuta = UmbralPendienteBajadaRutaPorDefecto; _umbralPendienteBajadaRuta = UmbralPendienteBajadaRutaPorDefecto;
_umbralAlturaAlertaPendienteRutaMetros = UmbralAlturaAlertaPendienteRutaMetrosPorDefecto; _umbralAlturaAlertaPendienteRutaMetros = UmbralAlturaAlertaPendienteRutaMetrosPorDefecto;
_velocidadPieKmH = 3.6; _velocidadPieKmH = 3.6;
@@ -444,6 +461,8 @@ public partial class PlanificadorRutas
_mostrarElevacionesRutaConfiguracion = true; _mostrarElevacionesRutaConfiguracion = true;
_fuenteElevacionCalculo = FuenteElevacionLocal5; _fuenteElevacionCalculo = FuenteElevacionLocal5;
_umbralPendienteSubidaRuta = UmbralPendienteSubidaRutaPorDefecto; _umbralPendienteSubidaRuta = UmbralPendienteSubidaRutaPorDefecto;
_umbralPendienteSubidaMediaRuta = UmbralPendienteSubidaMediaRutaPorDefecto;
_umbralPendienteSubidaFuerteRuta = UmbralPendienteSubidaFuerteRutaPorDefecto;
_umbralPendienteBajadaRuta = UmbralPendienteBajadaRutaPorDefecto; _umbralPendienteBajadaRuta = UmbralPendienteBajadaRutaPorDefecto;
_umbralAlturaAlertaPendienteRutaMetros = UmbralAlturaAlertaPendienteRutaMetrosPorDefecto; _umbralAlturaAlertaPendienteRutaMetros = UmbralAlturaAlertaPendienteRutaMetrosPorDefecto;
_velocidadPieKmH = 3.6; _velocidadPieKmH = 3.6;

View File

@@ -106,7 +106,10 @@ public partial class PlanificadorRutas : ComponentBase
var nuevo = ParseUmbralPendienteRuta(e.Value, actual); var nuevo = ParseUmbralPendienteRuta(e.Value, actual);
if (esSubida) if (esSubida)
{
_umbralPendienteSubidaRuta = nuevo; _umbralPendienteSubidaRuta = nuevo;
NormalizarOrdenUmbralesColorSubidaRuta();
}
else else
_umbralPendienteBajadaRuta = nuevo; _umbralPendienteBajadaRuta = nuevo;
@@ -114,6 +117,23 @@ public partial class PlanificadorRutas : ComponentBase
StateHasChanged(); StateHasChanged();
} }
private async Task CambiarUmbralColorSubidaRutaAsync(ChangeEventArgs e, bool esFuerte)
{
var actual = esFuerte
? _umbralPendienteSubidaFuerteRuta
: _umbralPendienteSubidaMediaRuta;
var nuevo = ParseUmbralPendienteRuta(e.Value, actual);
if (esFuerte)
_umbralPendienteSubidaFuerteRuta = nuevo;
else
_umbralPendienteSubidaMediaRuta = nuevo;
NormalizarOrdenUmbralesColorSubidaRuta();
await PersistirConfiguracionAsync();
StateHasChanged();
}
private async Task RecalcularRankingTrasCambioEsfuerzoPendienteAsync(bool forzarRepintado = false) private async Task RecalcularRankingTrasCambioEsfuerzoPendienteAsync(bool forzarRepintado = false)
{ {
if (_opcionesRuta.Count == 0) if (_opcionesRuta.Count == 0)
@@ -207,6 +227,23 @@ public partial class PlanificadorRutas : ComponentBase
? Math.Clamp(Math.Abs(valor), 0.0, 100.0) ? Math.Clamp(Math.Abs(valor), 0.0, 100.0)
: UmbralPendienteSubidaRutaPorDefecto; : UmbralPendienteSubidaRutaPorDefecto;
private void NormalizarOrdenUmbralesColorSubidaRuta()
{
var umbralSubida = NormalizarUmbralPendienteRuta(_umbralPendienteSubidaRuta);
var umbralMedia = double.IsFinite(_umbralPendienteSubidaMediaRuta)
? NormalizarUmbralPendienteRuta(_umbralPendienteSubidaMediaRuta)
: UmbralPendienteSubidaMediaRutaPorDefecto;
var umbralFuerte = double.IsFinite(_umbralPendienteSubidaFuerteRuta)
? NormalizarUmbralPendienteRuta(_umbralPendienteSubidaFuerteRuta)
: UmbralPendienteSubidaFuerteRutaPorDefecto;
_umbralPendienteSubidaMediaRuta = Math.Clamp(umbralMedia, umbralSubida, 100.0);
_umbralPendienteSubidaFuerteRuta = Math.Clamp(
umbralFuerte,
_umbralPendienteSubidaMediaRuta,
100.0);
}
private static double ParseUmbralAlturaAlertaPendienteRutaMetros(object? valor, double actual) private static double ParseUmbralAlturaAlertaPendienteRutaMetros(object? valor, double actual)
{ {
var texto = Convert.ToString(valor, CultureInfo.InvariantCulture)?.Replace(',', '.'); var texto = Convert.ToString(valor, CultureInfo.InvariantCulture)?.Replace(',', '.');
@@ -426,8 +463,23 @@ public partial class PlanificadorRutas : ComponentBase
var umbralSubida = NormalizarUmbralPendienteRuta(_umbralPendienteSubidaRuta); var umbralSubida = NormalizarUmbralPendienteRuta(_umbralPendienteSubidaRuta);
var umbralBajada = NormalizarUmbralPendienteRuta(_umbralPendienteBajadaRuta); var umbralBajada = NormalizarUmbralPendienteRuta(_umbralPendienteBajadaRuta);
var umbralSubidaMedia = Math.Clamp(
NormalizarUmbralPendienteRuta(_umbralPendienteSubidaMediaRuta),
umbralSubida,
100.0);
var umbralSubidaFuerte = Math.Clamp(
NormalizarUmbralPendienteRuta(_umbralPendienteSubidaFuerteRuta),
umbralSubidaMedia,
100.0);
if (pendientePorcentaje.Value >= umbralSubidaFuerte)
return ("subida-fuerte", "#000000");
if (pendientePorcentaje.Value >= umbralSubidaMedia)
return ("subida-media", "#4c1d95");
if (pendientePorcentaje.Value >= umbralSubida) if (pendientePorcentaje.Value >= umbralSubida)
return ("subida", "#000000"); return ("subida-suave", "#d946ef");
if (pendientePorcentaje.Value <= -umbralBajada) if (pendientePorcentaje.Value <= -umbralBajada)
return ("bajada", "#2563eb"); return ("bajada", "#2563eb");

View File

@@ -1831,7 +1831,10 @@
</label> </label>
<label class="pendientes-config-modal__field"> <label class="pendientes-config-modal__field">
<span>Umbral Subida (%)</span> <span class="pendientes-config-modal__threshold-label">
<span class="pendientes-config-modal__swatch pendientes-config-modal__swatch--suave" aria-hidden="true"></span>
Umbral Subida (%)
</span>
<input type="text" <input type="text"
class="config-input" class="config-input"
inputmode="decimal" inputmode="decimal"
@@ -1840,6 +1843,32 @@
@onchange="@(e => CambiarUmbralElevacionRutaAsync(e, true))" /> @onchange="@(e => CambiarUmbralElevacionRutaAsync(e, true))" />
</label> </label>
<label class="pendientes-config-modal__field">
<span class="pendientes-config-modal__threshold-label">
<span class="pendientes-config-modal__swatch pendientes-config-modal__swatch--media" aria-hidden="true"></span>
Subida Media (%)
</span>
<input type="text"
class="config-input"
inputmode="decimal"
value="@_umbralPendienteSubidaMediaRuta.ToString("0.#", CultureInfo.InvariantCulture)"
disabled="@_pintandoElevacionesRuta"
@onchange="@(e => CambiarUmbralColorSubidaRutaAsync(e, false))" />
</label>
<label class="pendientes-config-modal__field">
<span class="pendientes-config-modal__threshold-label">
<span class="pendientes-config-modal__swatch pendientes-config-modal__swatch--fuerte" aria-hidden="true"></span>
Subida Fuerte (%)
</span>
<input type="text"
class="config-input"
inputmode="decimal"
value="@_umbralPendienteSubidaFuerteRuta.ToString("0.#", CultureInfo.InvariantCulture)"
disabled="@_pintandoElevacionesRuta"
@onchange="@(e => CambiarUmbralColorSubidaRutaAsync(e, true))" />
</label>
<label class="pendientes-config-modal__field"> <label class="pendientes-config-modal__field">
<span>Umbral Bajada (%)</span> <span>Umbral Bajada (%)</span>
<input type="text" <input type="text"

View File

@@ -318,12 +318,9 @@ public sealed class GeocodificadorLocalServicio : IGeocodificadorLocalServicio
var textoBusqueda = string.Join(' ', new[] var textoBusqueda = string.Join(' ', new[]
{ {
etiqueta, etiqueta,
subtitulo,
nombre,
calle, calle,
portal, portal,
edificio, edificio
municipio
}.Where(valor => !string.IsNullOrWhiteSpace(valor))); }.Where(valor => !string.IsNullOrWhiteSpace(valor)));
entrada = new EntradaGeocodificada( entrada = new EntradaGeocodificada(
@@ -554,6 +551,12 @@ public sealed class GeocodificadorLocalServicio : IGeocodificadorLocalServicio
var sb = new StringBuilder(formD.Length); var sb = new StringBuilder(formD.Length);
foreach (var ch in formD) foreach (var ch in formD)
{ {
if (ch == marcadorEnye)
{
sb.Append(ch);
continue;
}
var uc = CharUnicodeInfo.GetUnicodeCategory(ch); var uc = CharUnicodeInfo.GetUnicodeCategory(ch);
if (uc == UnicodeCategory.NonSpacingMark) if (uc == UnicodeCategory.NonSpacingMark)
continue; continue;

View File

@@ -9,6 +9,8 @@ internal static class SimuladorHorariosTaxibus
{ {
private const string IdCalendario = "TAXIBUS_SIM_TODOS_LOS_DIAS"; private const string IdCalendario = "TAXIBUS_SIM_TODOS_LOS_DIAS";
private const int FrecuenciaMinutos = 30; private const int FrecuenciaMinutos = 30;
private const int MinutoPrimeraSalida = 7 * 60;
private const int MinutoFinServicioExclusivo = 24 * 60;
private const double VelocidadMetrosSegundo = 16_000.0 / 3_600.0; private const double VelocidadMetrosSegundo = 16_000.0 / 3_600.0;
private const int SegundosMinimosEntreParadas = 30; private const int SegundosMinimosEntreParadas = 30;
@@ -135,10 +137,12 @@ internal static class SimuladorHorariosTaxibus
ICollection<FilaExpedicionCsv> expediciones, ICollection<FilaExpedicionCsv> expediciones,
ICollection<FilaTiempoParadaCsv> tiemposParada) ICollection<FilaTiempoParadaCsv> tiemposParada)
{ {
var cantidadSalidas = 24 * 60 / FrecuenciaMinutos; var indiceSalida = 0;
for (var indiceSalida = 0; indiceSalida < cantidadSalidas; indiceSalida++) for (var minutoInicio = MinutoPrimeraSalida;
minutoInicio < MinutoFinServicioExclusivo;
minutoInicio += FrecuenciaMinutos, indiceSalida++)
{ {
var segundosInicio = indiceSalida * FrecuenciaMinutos * 60; var segundosInicio = minutoInicio * 60;
var horaInicio = HoraDesdeSegundos(segundosInicio); var horaInicio = HoraDesdeSegundos(segundosInicio);
var idExpedicion = var idExpedicion =
$"{TaxibusDbus.PrefijoExpedicionSimulada}{ruta.Id}_{indicePlantilla:00}_{indiceSalida:00}"; $"{TaxibusDbus.PrefijoExpedicionSimulada}{ruta.Id}_{indicePlantilla:00}_{indiceSalida:00}";

View File

@@ -8,7 +8,7 @@ public static class TaxibusDbus
public const string PrefijoExpedicionSimulada = "TAXIBUS_SIM_"; public const string PrefijoExpedicionSimulada = "TAXIBUS_SIM_";
public const string MensajeReserva = "Esta l\u00ednea requiere solicitud de reserva."; public const string MensajeReserva = "Esta l\u00ednea requiere solicitud de reserva.";
public const string MensajeHorarioSimulado = public const string MensajeHorarioSimulado =
"Horario provisional simulado cada 30 min. Esta l\u00ednea requiere solicitud de reserva."; "Horario provisional simulado cada 30 min, de 07:00 a 00:00. Esta l\u00ednea requiere solicitud de reserva.";
public static bool EsLinea(string? codigo) public static bool EsLinea(string? codigo)
{ {

View File

@@ -2209,6 +2209,34 @@ html, body {
text-align: center; text-align: center;
} }
.pendientes-config-modal__threshold-label {
display: inline-flex;
align-items: center;
gap: .38rem;
min-width: 0;
}
.pendientes-config-modal__swatch {
width: .68rem;
height: .68rem;
flex: 0 0 .68rem;
border: 1px solid rgba(226, 232, 240, .7);
border-radius: 2px;
box-sizing: border-box;
}
.pendientes-config-modal__swatch--suave {
background: #d946ef;
}
.pendientes-config-modal__swatch--media {
background: #4c1d95;
}
.pendientes-config-modal__swatch--fuerte {
background: #000;
}
.config-row-map-opacity { .config-row-map-opacity {
margin-top: .7rem !important; margin-top: .7rem !important;
margin-bottom: 0; margin-bottom: 0;