- andar equilibraod separado del calculo
- comienzo de penalizacoin en 200m - centrado de origen
This commit is contained in:
@@ -48,6 +48,7 @@ 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 UmbralPendienteSubidaRutaPorDefecto = 2.0;
|
||||
private const double UmbralPendienteBajadaRutaPorDefecto = 5.0;
|
||||
@@ -56,12 +57,12 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
|
||||
private double _velocidadPieKmH = 3.6;
|
||||
private double _factorPenalizacionDistanciaPie = FactorPenalizacionDistanciaPiePorDefecto;
|
||||
private double _parametroPenalizacionDistanciaPieMetros = 100.0;
|
||||
private double _parametroPenalizacionDistanciaPieMetros = ParametroPenalizacionDistanciaPieMetrosPorDefecto;
|
||||
private double _coeficienteEsfuerzoAltura = CoeficienteEsfuerzoAlturaPorDefecto;
|
||||
private double _pesoTransbordoRankingMinutos = 4.0;
|
||||
private double _factorEquilibradoAndarBus = 12.0;
|
||||
private string _factorPenalizacionDistanciaPieTextoEdicion = "1.35";
|
||||
private string _parametroPenalizacionDistanciaPieTextoEdicion = "100";
|
||||
private string _parametroPenalizacionDistanciaPieTextoEdicion = "200";
|
||||
private string _coeficienteEsfuerzoAlturaTextoEdicion = "8.20";
|
||||
private string _pesoTransbordoRankingTextoEdicion = "4,0";
|
||||
private string _factorEquilibradoAndarBusTextoEdicion = "12";
|
||||
@@ -461,21 +462,47 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Construye paradas for variante.
|
||||
/// Construye el payload JS de paradas de una variante.
|
||||
/// </summary>
|
||||
private static List<object> BuildStopsDesdeParadas(IEnumerable<Parada> paradas)
|
||||
private List<object> BuildStopsForVariante(InfoVariante v)
|
||||
{
|
||||
var paradasOrdenadas = paradas.ToList();
|
||||
var stops = new List<object>(paradasOrdenadas.Count);
|
||||
for (var indice = 0; indice < paradasOrdenadas.Count; indice++)
|
||||
if (v?.CodigosParadas is null || v.CodigosParadas.Count == 0)
|
||||
return new List<object>();
|
||||
|
||||
return BuildStopsParaRangoVariante(v, 0, v.CodigosParadas.Count - 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construye el payload JS de paradas recorridas por un tramo concreto.
|
||||
/// </summary>
|
||||
private List<object> BuildStopsForTramoBus(TramoBus tramo)
|
||||
{
|
||||
var parada = paradasOrdenadas[indice];
|
||||
if (tramo?.Variante?.CodigosParadas is null || tramo.Variante.CodigosParadas.Count == 0)
|
||||
return new List<object>();
|
||||
|
||||
var ultimoIndice = tramo.Variante.CodigosParadas.Count - 1;
|
||||
var inicio = Math.Clamp(Math.Min(tramo.IndiceInicio, tramo.IndiceFin), 0, ultimoIndice);
|
||||
var fin = Math.Clamp(Math.Max(tramo.IndiceInicio, tramo.IndiceFin), 0, ultimoIndice);
|
||||
return BuildStopsParaRangoVariante(tramo.Variante, inicio, fin);
|
||||
}
|
||||
|
||||
private List<object> BuildStopsParaRangoVariante(InfoVariante variante, int inicio, int fin)
|
||||
{
|
||||
var stops = new List<object>();
|
||||
var codigosVistos = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
for (var indice = inicio; indice <= fin; indice++)
|
||||
{
|
||||
var codigo = variante.CodigosParadas[indice];
|
||||
if (!codigosVistos.Add(codigo) || !_paradaByCode.TryGetValue(codigo, out var parada))
|
||||
continue;
|
||||
|
||||
stops.Add(new
|
||||
{
|
||||
lat = parada.Latitud,
|
||||
lon = parada.Longitud,
|
||||
code = parada.Codigo,
|
||||
bearing = CalcularRumboParada(paradasOrdenadas, indice)
|
||||
bearing = CalcularRumboParada(variante, indice)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -483,21 +510,121 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calcula el sentido de marcha hacia la siguiente parada; en la terminal conserva el rumbo de llegada.
|
||||
/// Obtiene la tangente local de la geometria real al salir de la parada.
|
||||
/// En la terminal usa la tangente de llegada del ultimo trayecto.
|
||||
/// </summary>
|
||||
private static double? CalcularRumboParada(IReadOnlyList<Parada> paradas, int indice)
|
||||
private double? CalcularRumboParada(InfoVariante variante, int indiceParada)
|
||||
{
|
||||
var actual = paradas[indice];
|
||||
for (var siguiente = indice + 1; siguiente < paradas.Count; siguiente++)
|
||||
var idsTrayectos = variante.Variante?.IdsTrayectos;
|
||||
if (idsTrayectos is not null)
|
||||
{
|
||||
var rumbo = CalcularRumboGrados(actual, paradas[siguiente]);
|
||||
if (indiceParada >= 0 &&
|
||||
indiceParada < idsTrayectos.Count &&
|
||||
RedBusServicio.Trayectos.TryGetValue(idsTrayectos[indiceParada], out var trayectoSalida))
|
||||
{
|
||||
var rumboSalida = CalcularRumboGeometriaTrayecto(trayectoSalida.Posiciones, desdeInicio: true);
|
||||
if (rumboSalida is not null)
|
||||
return rumboSalida;
|
||||
}
|
||||
|
||||
var indiceTrayectoLlegada = indiceParada - 1;
|
||||
if (indiceTrayectoLlegada >= 0 &&
|
||||
indiceTrayectoLlegada < idsTrayectos.Count &&
|
||||
RedBusServicio.Trayectos.TryGetValue(idsTrayectos[indiceTrayectoLlegada], out var trayectoLlegada))
|
||||
{
|
||||
var rumboLlegada = CalcularRumboGeometriaTrayecto(trayectoLlegada.Posiciones, desdeInicio: false);
|
||||
if (rumboLlegada is not null)
|
||||
return rumboLlegada;
|
||||
}
|
||||
}
|
||||
|
||||
return CalcularRumboParadaPorCoordenadas(variante, indiceParada);
|
||||
}
|
||||
|
||||
private static double? CalcularRumboGeometriaTrayecto(
|
||||
IReadOnlyList<double[]> posiciones,
|
||||
bool desdeInicio)
|
||||
{
|
||||
var puntos = posiciones
|
||||
.Where(punto =>
|
||||
punto is { Length: >= 2 } &&
|
||||
double.IsFinite(punto[0]) &&
|
||||
double.IsFinite(punto[1]))
|
||||
.ToList();
|
||||
|
||||
if (puntos.Count < 2)
|
||||
return null;
|
||||
|
||||
const double distanciaMinimaRumboMetros = 3.0;
|
||||
double? rumboCorto = null;
|
||||
|
||||
if (desdeInicio)
|
||||
{
|
||||
var origen = puntos[0];
|
||||
for (var indice = 1; indice < puntos.Count; indice++)
|
||||
{
|
||||
var destino = puntos[indice];
|
||||
var rumbo = CalcularRumboGrados(origen[0], origen[1], destino[0], destino[1]);
|
||||
if (rumbo is null)
|
||||
continue;
|
||||
|
||||
rumboCorto ??= rumbo;
|
||||
if (CalcularDistanciaMetros(origen[0], origen[1], destino[0], destino[1]) >= distanciaMinimaRumboMetros)
|
||||
return rumbo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var destino = puntos[^1];
|
||||
for (var indice = puntos.Count - 2; indice >= 0; indice--)
|
||||
{
|
||||
var origen = puntos[indice];
|
||||
var rumbo = CalcularRumboGrados(origen[0], origen[1], destino[0], destino[1]);
|
||||
if (rumbo is null)
|
||||
continue;
|
||||
|
||||
rumboCorto ??= rumbo;
|
||||
if (CalcularDistanciaMetros(origen[0], origen[1], destino[0], destino[1]) >= distanciaMinimaRumboMetros)
|
||||
return rumbo;
|
||||
}
|
||||
}
|
||||
|
||||
return rumboCorto;
|
||||
}
|
||||
|
||||
private double? CalcularRumboParadaPorCoordenadas(InfoVariante variante, int indice)
|
||||
{
|
||||
if (indice < 0 ||
|
||||
indice >= variante.CodigosParadas.Count ||
|
||||
!_paradaByCode.TryGetValue(variante.CodigosParadas[indice], out var actual))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (var siguiente = indice + 1; siguiente < variante.CodigosParadas.Count; siguiente++)
|
||||
{
|
||||
if (!_paradaByCode.TryGetValue(variante.CodigosParadas[siguiente], out var paradaSiguiente))
|
||||
continue;
|
||||
|
||||
var rumbo = CalcularRumboGrados(
|
||||
actual.Latitud,
|
||||
actual.Longitud,
|
||||
paradaSiguiente.Latitud,
|
||||
paradaSiguiente.Longitud);
|
||||
if (rumbo is not null)
|
||||
return rumbo;
|
||||
}
|
||||
|
||||
for (var anterior = indice - 1; anterior >= 0; anterior--)
|
||||
{
|
||||
var rumbo = CalcularRumboGrados(paradas[anterior], actual);
|
||||
if (!_paradaByCode.TryGetValue(variante.CodigosParadas[anterior], out var paradaAnterior))
|
||||
continue;
|
||||
|
||||
var rumbo = CalcularRumboGrados(
|
||||
paradaAnterior.Latitud,
|
||||
paradaAnterior.Longitud,
|
||||
actual.Latitud,
|
||||
actual.Longitud);
|
||||
if (rumbo is not null)
|
||||
return rumbo;
|
||||
}
|
||||
@@ -505,19 +632,23 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
return null;
|
||||
}
|
||||
|
||||
private static double? CalcularRumboGrados(Parada origen, Parada destino)
|
||||
private static double? CalcularRumboGrados(
|
||||
double latitudOrigenGrados,
|
||||
double longitudOrigenGrados,
|
||||
double latitudDestinoGrados,
|
||||
double longitudDestinoGrados)
|
||||
{
|
||||
if (!double.IsFinite(origen.Latitud) ||
|
||||
!double.IsFinite(origen.Longitud) ||
|
||||
!double.IsFinite(destino.Latitud) ||
|
||||
!double.IsFinite(destino.Longitud))
|
||||
if (!double.IsFinite(latitudOrigenGrados) ||
|
||||
!double.IsFinite(longitudOrigenGrados) ||
|
||||
!double.IsFinite(latitudDestinoGrados) ||
|
||||
!double.IsFinite(longitudDestinoGrados))
|
||||
{
|
||||
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 latitudOrigen = latitudOrigenGrados * Math.PI / 180.0;
|
||||
var latitudDestino = latitudDestinoGrados * Math.PI / 180.0;
|
||||
var diferenciaLongitud = (longitudDestinoGrados - longitudOrigenGrados) * 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);
|
||||
@@ -529,33 +660,6 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
return (rumbo + 360.0) % 360.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construye las paradas visibles recorridas por una variante completa.
|
||||
/// </summary>
|
||||
private List<Parada> BuildParadasForVariante(InfoVariante v)
|
||||
{
|
||||
var stops = new List<Parada>(v?.CodigosParadas?.Count ?? 0);
|
||||
if (v?.CodigosParadas is null) return stops;
|
||||
|
||||
var codigosVistos = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var cod in v.CodigosParadas)
|
||||
{
|
||||
if (!codigosVistos.Add(cod))
|
||||
continue;
|
||||
|
||||
if (_paradaByCode.TryGetValue(cod, out var parada))
|
||||
stops.Add(parada);
|
||||
}
|
||||
|
||||
return stops;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construye el payload JS de paradas de una variante.
|
||||
/// </summary>
|
||||
private List<object> BuildStopsForVariante(InfoVariante v)
|
||||
=> BuildStopsDesdeParadas(BuildParadasForVariante(v));
|
||||
|
||||
/// <summary>
|
||||
/// Construye las paradas visibles recorridas por un tramo concreto de bus.
|
||||
/// </summary>
|
||||
@@ -1061,14 +1165,16 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
/// <summary>
|
||||
/// Ajusta rutas js.
|
||||
/// </summary>
|
||||
private async Task FitRoutesJsAsync(IReadOnlyList<double[]>? coordenadas = null)
|
||||
private async Task FitRoutesJsAsync(
|
||||
IReadOnlyList<double[]>? coordenadas = null,
|
||||
double[]? centroPreferido = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (coordenadas is null)
|
||||
if (coordenadas is null && centroPreferido is null)
|
||||
await JS.InvokeVoidAsync("rt.fitRoutes");
|
||||
else
|
||||
await JS.InvokeVoidAsync("rt.fitRoutes", coordenadas);
|
||||
await JS.InvokeVoidAsync("rt.fitRoutes", coordenadas, centroPreferido);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
@@ -1267,11 +1373,19 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
|
||||
var parametros = CrearParametrosPenalizacionActuales();
|
||||
|
||||
var distanciaCorregidaBase = alternativa.EsSoloAPie
|
||||
? UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(alternativa.DistanciaSoloAPie, parametros)
|
||||
: UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(alternativa.DistanciaPieInicioAprox, parametros)
|
||||
+ UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(alternativa.DistanciaPieTransbordosAprox, parametros)
|
||||
+ UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(alternativa.DistanciaPieFinAprox, parametros);
|
||||
IEnumerable<double> distanciasPiePorTramo = alternativa.EsSoloAPie
|
||||
? new[] { alternativa.DistanciaSoloAPie }
|
||||
: alternativa.DistanciasPiePorTramoAprox.Count > 0
|
||||
? alternativa.DistanciasPiePorTramoAprox
|
||||
: new[]
|
||||
{
|
||||
alternativa.DistanciaPieInicioAprox,
|
||||
alternativa.DistanciaPieTransbordosAprox,
|
||||
alternativa.DistanciaPieFinAprox
|
||||
};
|
||||
var distanciaCorregidaBase = UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaTotalMetros(
|
||||
distanciasPiePorTramo,
|
||||
parametros);
|
||||
var esfuerzoExtra = double.IsFinite(alternativa.EsfuerzoExtraPendienteMetros)
|
||||
? Math.Max(0, alternativa.EsfuerzoExtraPendienteMetros)
|
||||
: 0;
|
||||
@@ -1391,12 +1505,19 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
alternativa.DistanciaSoloAPie);
|
||||
}
|
||||
|
||||
var distanciasPiePorTramo = alternativa.DistanciasPiePorTramoAprox.Count > 0
|
||||
? alternativa.DistanciasPiePorTramoAprox.ToArray()
|
||||
: new[]
|
||||
{
|
||||
alternativa.DistanciaPieInicioAprox,
|
||||
alternativa.DistanciaPieTransbordosAprox,
|
||||
alternativa.DistanciaPieFinAprox
|
||||
};
|
||||
|
||||
return UtilidadesTransitoDbus.CalcularCosteConPenalizacionPieSegundos(
|
||||
duracionReal,
|
||||
parametros,
|
||||
alternativa.DistanciaPieInicioAprox,
|
||||
alternativa.DistanciaPieTransbordosAprox,
|
||||
alternativa.DistanciaPieFinAprox);
|
||||
distanciasPiePorTramo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -432,16 +432,29 @@ public partial class PlanificadorRutas
|
||||
if (!await AsegurarHistorialLocalCargadoAsync())
|
||||
return;
|
||||
|
||||
var item = _historialLocal.FirstOrDefault(x => x.Id == id);
|
||||
if (item is null)
|
||||
var indiceEliminado = _historialLocal.FindIndex(x => x.Id == id);
|
||||
if (indiceEliminado < 0)
|
||||
return;
|
||||
|
||||
_historialLocal.Remove(item);
|
||||
|
||||
if (_historialLocalSeleccionadoId == id)
|
||||
_historialLocalSeleccionadoId = string.Empty;
|
||||
var estabaSeleccionado = _historialLocalSeleccionadoId == id;
|
||||
_historialLocal.RemoveAt(indiceEliminado);
|
||||
|
||||
await PersistirHistorialLocalAsync();
|
||||
|
||||
if (estabaSeleccionado)
|
||||
{
|
||||
if (_historialLocal.Count == 0)
|
||||
{
|
||||
_historialLocalSeleccionadoId = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
var siguiente = _historialLocal[Math.Min(indiceEliminado, _historialLocal.Count - 1)];
|
||||
await AplicarRegistroHistorialAsync(siguiente);
|
||||
SeleccionarHistorialLocal(siguiente.Id);
|
||||
}
|
||||
}
|
||||
|
||||
MostrarMensajeHistorial("Combinacion eliminada del historial personal.");
|
||||
}
|
||||
|
||||
@@ -473,6 +486,8 @@ public partial class PlanificadorRutas
|
||||
{
|
||||
try
|
||||
{
|
||||
var indiceEliminado = _historialCompartido.FindIndex(x => x.Id == id);
|
||||
var estabaSeleccionado = _historialCompartidoSeleccionadoId == id;
|
||||
var ok = await HistorialRutasCompartidoService.EliminarAsync(id);
|
||||
if (!ok)
|
||||
{
|
||||
@@ -481,9 +496,22 @@ public partial class PlanificadorRutas
|
||||
}
|
||||
|
||||
await CargarHistorialCompartidoAsync();
|
||||
_historialCompartido.RemoveAll(x => x.Id == id);
|
||||
|
||||
if (_historialCompartidoSeleccionadoId == id)
|
||||
if (estabaSeleccionado)
|
||||
{
|
||||
if (_historialCompartido.Count == 0)
|
||||
{
|
||||
_historialCompartidoSeleccionadoId = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
var indiceSiguiente = Math.Clamp(indiceEliminado, 0, _historialCompartido.Count - 1);
|
||||
var siguiente = _historialCompartido[indiceSiguiente];
|
||||
await AplicarRegistroHistorialAsync(siguiente);
|
||||
SeleccionarHistorialCompartido(siguiente.Id);
|
||||
}
|
||||
}
|
||||
|
||||
MostrarMensajeHistorial("Combinacion eliminada del historial compartido.");
|
||||
}
|
||||
|
||||
@@ -1204,7 +1204,7 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
private bool _elevPopupMinimizado = false;
|
||||
|
||||
|
||||
private const string _versionApp = "(v-20260727a)";
|
||||
private const string _versionApp = "(v-20260728a)";
|
||||
|
||||
|
||||
private double? _paradaElevG;
|
||||
|
||||
@@ -192,7 +192,10 @@ public partial class PlanificadorRutas
|
||||
? FactorPenalizacionDistanciaPiePorDefecto
|
||||
: factor;
|
||||
if (config.ParametroPenalizacionDistanciaPieMetros is { } parametro && double.IsFinite(parametro))
|
||||
_parametroPenalizacionDistanciaPieMetros = parametro;
|
||||
_parametroPenalizacionDistanciaPieMetros =
|
||||
Math.Abs(parametro - 100.0) < 0.0001
|
||||
? ParametroPenalizacionDistanciaPieMetrosPorDefecto
|
||||
: parametro;
|
||||
if (config.CoeficienteEsfuerzoAltura is { } coeficienteAltura && double.IsFinite(coeficienteAltura))
|
||||
_coeficienteEsfuerzoAltura =
|
||||
Math.Abs(coeficienteAltura - 1.6) < 0.0001 ||
|
||||
@@ -315,7 +318,7 @@ public partial class PlanificadorRutas
|
||||
_maxTransbordosPermitidos = 3;
|
||||
|
||||
_factorPenalizacionDistanciaPie = FactorPenalizacionDistanciaPiePorDefecto;
|
||||
_parametroPenalizacionDistanciaPieMetros = 100.0;
|
||||
_parametroPenalizacionDistanciaPieMetros = ParametroPenalizacionDistanciaPieMetrosPorDefecto;
|
||||
_coeficienteEsfuerzoAltura = CoeficienteEsfuerzoAlturaPorDefecto;
|
||||
_pesoTransbordoRankingMinutos = 4.0;
|
||||
_factorEquilibradoAndarBus = 12.0;
|
||||
@@ -365,7 +368,7 @@ public partial class PlanificadorRutas
|
||||
_maxTransbordosPermitidos = 3;
|
||||
|
||||
_factorPenalizacionDistanciaPie = FactorPenalizacionDistanciaPiePorDefecto;
|
||||
_parametroPenalizacionDistanciaPieMetros = 100.0;
|
||||
_parametroPenalizacionDistanciaPieMetros = ParametroPenalizacionDistanciaPieMetrosPorDefecto;
|
||||
_coeficienteEsfuerzoAltura = CoeficienteEsfuerzoAlturaPorDefecto;
|
||||
_pesoTransbordoRankingMinutos = 4.0;
|
||||
_factorEquilibradoAndarBus = 12.0;
|
||||
|
||||
@@ -463,7 +463,7 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
await CerrarPopupsAsync();
|
||||
|
||||
ThrowIfPintadoObsoleto(versionPintado);
|
||||
await FitRoutesJsAsync();
|
||||
await FitRoutesJsAsync(centroPreferido: _coordenadasOrigen);
|
||||
ThrowIfPintadoObsoleto(versionPintado);
|
||||
StateHasChanged();
|
||||
}
|
||||
@@ -505,7 +505,7 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
if (paradasTramo.Count == 0)
|
||||
continue;
|
||||
|
||||
var stops = BuildStopsDesdeParadas(paradasTramo);
|
||||
var stops = BuildStopsForTramoBus(tramo);
|
||||
|
||||
var id = $"route_stops_{indice}_{tramo.Variante.Linea.Codigo}_{tramo.Variante.CodigoItinerario}_{NormalizarSentidoCodigo(tramo.Variante.Sentido?.Codigo)}";
|
||||
var color = ColorCssDesdeVariante(tramo.Variante);
|
||||
|
||||
@@ -20,6 +20,7 @@ public sealed class AlternativaRuta
|
||||
public double DistanciaPieFinAprox { get; set; }
|
||||
public double DistanciaPieTotalAprox =>
|
||||
DistanciaPieInicioAprox + DistanciaPieTransbordosAprox + DistanciaPieFinAprox;
|
||||
public List<double> DistanciasPiePorTramoAprox { get; set; } = new();
|
||||
|
||||
public List<double[,]> LineasPieCalculoElevacion { get; set; } = new();
|
||||
public double EsfuerzoExtraPendienteMetros { get; set; }
|
||||
|
||||
@@ -24,7 +24,7 @@ public sealed class ParametrosPlanificadorRuta
|
||||
public int MargenTransbordoSegundos { get; set; } = 120;
|
||||
public int SegundosPorParadaBus { get; set; } = 30;
|
||||
public double FactorPenalizacionDistanciaPie { get; set; } = 1.35;
|
||||
public double ParametroPenalizacionDistanciaPieMetros { get; set; } = 100.0;
|
||||
public double ParametroPenalizacionDistanciaPieMetros { get; set; } = 200.0;
|
||||
public double PesoTransbordoRankingMinutos { get; set; } = 4.0;
|
||||
public double FactorEquilibradoAndarBus { get; set; } = 12.0;
|
||||
|
||||
|
||||
@@ -714,13 +714,16 @@ public sealed class BuscadorRutasTemporalesDbus
|
||||
};
|
||||
|
||||
var duracionEstimada = Math.Max(0, (estadoDestino.Llegada - instanteSalida).TotalSeconds) + destino.TiempoAPie;
|
||||
var distanciasPieTransbordos = ObtenerDistanciasPieTransbordos(estadoDestino);
|
||||
var distanciasPiePorTramo = ConstruirDistanciasPiePorTramo(
|
||||
origen.DistanciaAPie,
|
||||
distanciasPieTransbordos,
|
||||
destino.DistanciaAPie);
|
||||
var puntuacionCoste = UtilidadesTransitoDbus.CalcularCosteConPenalizacionesRankingSegundos(
|
||||
duracionEstimada,
|
||||
parametros,
|
||||
numeroTransbordos,
|
||||
origen.DistanciaAPie,
|
||||
estadoDestino.DistanciaPieTransbordos,
|
||||
destino.DistanciaAPie);
|
||||
distanciasPiePorTramo.ToArray());
|
||||
|
||||
var resultado = new ResultadoBusquedaRutaBusDbus
|
||||
{
|
||||
@@ -731,6 +734,7 @@ public sealed class BuscadorRutasTemporalesDbus
|
||||
DistanciaPieFin = destino.DistanciaAPie,
|
||||
TiempoPieFin = destino.TiempoAPie,
|
||||
DistanciaPieTransbordos = estadoDestino.DistanciaPieTransbordos,
|
||||
DistanciasPieTransbordosPorTramo = distanciasPieTransbordos,
|
||||
TiempoEsperaInicialSegundos = estadoDestino.TiempoEsperaInicialSegundos,
|
||||
TiempoEsperaTransbordosSegundos = estadoDestino.TiempoEsperaTransbordosSegundos,
|
||||
DuracionEstimadaSegundos = duracionEstimada,
|
||||
@@ -816,10 +820,12 @@ public sealed class BuscadorRutasTemporalesDbus
|
||||
ParametrosPlanificadorRuta parametros)
|
||||
{
|
||||
var distanciaBus = Math.Max(0, resultado.RutaBus.DistanciaTotalBus);
|
||||
var distanciaAndando =
|
||||
UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(resultado.DistanciaPieInicio, parametros)
|
||||
+ UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(resultado.DistanciaPieTransbordos, parametros)
|
||||
+ UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(resultado.DistanciaPieFin, parametros);
|
||||
var distanciaAndando = UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaTotalMetros(
|
||||
ConstruirDistanciasPiePorTramo(
|
||||
resultado.DistanciaPieInicio,
|
||||
resultado.DistanciasPieTransbordosPorTramo,
|
||||
resultado.DistanciaPieFin),
|
||||
parametros);
|
||||
var factor = double.IsFinite(parametros.FactorEquilibradoAndarBus)
|
||||
? Math.Max(0, parametros.FactorEquilibradoAndarBus)
|
||||
: 12.0;
|
||||
@@ -830,6 +836,45 @@ public sealed class BuscadorRutasTemporalesDbus
|
||||
: double.PositiveInfinity;
|
||||
}
|
||||
|
||||
private static List<double> ObtenerDistanciasPieTransbordos(EstadoBusquedaParadaDbus estadoDestino)
|
||||
{
|
||||
var distancias = new List<double>();
|
||||
var cursor = estadoDestino;
|
||||
while (cursor is not null)
|
||||
{
|
||||
if (cursor.Movimiento is MovimientoPieTransbordoDbus movimiento &&
|
||||
double.IsFinite(movimiento.DistanciaMetros) &&
|
||||
movimiento.DistanciaMetros > 0)
|
||||
{
|
||||
distancias.Add(movimiento.DistanciaMetros);
|
||||
}
|
||||
|
||||
cursor = cursor.EstadoAnterior;
|
||||
}
|
||||
|
||||
distancias.Reverse();
|
||||
return distancias;
|
||||
}
|
||||
|
||||
private static List<double> ConstruirDistanciasPiePorTramo(
|
||||
double distanciaInicio,
|
||||
IEnumerable<double> distanciasTransbordos,
|
||||
double distanciaFin)
|
||||
{
|
||||
var distancias = new List<double>();
|
||||
AgregarDistancia(distanciaInicio);
|
||||
foreach (var distancia in distanciasTransbordos)
|
||||
AgregarDistancia(distancia);
|
||||
AgregarDistancia(distanciaFin);
|
||||
return distancias;
|
||||
|
||||
void AgregarDistancia(double distancia)
|
||||
{
|
||||
if (double.IsFinite(distancia) && distancia > 0)
|
||||
distancias.Add(distancia);
|
||||
}
|
||||
}
|
||||
|
||||
private static double CalcularDistanciaBusEstado(EstadoBusquedaParadaDbus estadoDestino)
|
||||
{
|
||||
var distancia = 0.0;
|
||||
@@ -1345,6 +1390,11 @@ public sealed class ResultadoBusquedaRutaBusDbus
|
||||
/// </summary>
|
||||
public double DistanciaPieTransbordos { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Distancias peatonales de cada transbordo, sin agregarlas antes de penalizarlas.
|
||||
/// </summary>
|
||||
public IReadOnlyList<double> DistanciasPieTransbordosPorTramo { get; init; } = Array.Empty<double>();
|
||||
|
||||
/// <summary>
|
||||
/// Espera inicial acumulada.
|
||||
/// </summary>
|
||||
|
||||
@@ -295,6 +295,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
DistanciaPieInicioAprox = candidataBus.DistanciaPieInicio,
|
||||
DistanciaPieFinAprox = candidataBus.DistanciaPieFin,
|
||||
DistanciaPieTransbordosAprox = candidataBus.DistanciaPieTransbordos,
|
||||
DistanciasPiePorTramoAprox = ConstruirDistanciasPiePorTramo(candidataBus),
|
||||
TiempoPieInicio = candidataBus.TiempoPieInicio,
|
||||
TiempoPieFin = candidataBus.TiempoPieFin,
|
||||
TiempoEsperaInicialSegundos = candidataBus.TiempoEsperaInicialSegundos,
|
||||
@@ -992,6 +993,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
DistanciaPieFin = destino.DistanciaAPie,
|
||||
TiempoPieFin = destino.TiempoAPie,
|
||||
DistanciaPieTransbordos = transferencia.DistanciaMetros,
|
||||
DistanciasPieTransbordosPorTramo = new[] { transferencia.DistanciaMetros },
|
||||
TiempoEsperaInicialSegundos = esperaInicial,
|
||||
TiempoEsperaTransbordosSegundos = esperaTotalTransbordos,
|
||||
DuracionEstimadaSegundos = duracionTotal,
|
||||
@@ -1343,6 +1345,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
DistanciaPieFin = baseRuta.DistanciaPieFin,
|
||||
TiempoPieFin = baseRuta.TiempoPieFin,
|
||||
DistanciaPieTransbordos = baseRuta.DistanciaPieTransbordos,
|
||||
DistanciasPieTransbordosPorTramo = baseRuta.DistanciasPieTransbordosPorTramo.ToArray(),
|
||||
TiempoEsperaInicialSegundos = esperaInicial,
|
||||
TiempoEsperaTransbordosSegundos = baseRuta.TiempoEsperaTransbordosSegundos,
|
||||
DuracionEstimadaSegundos = duracionTotal,
|
||||
@@ -1350,9 +1353,10 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
duracionTotal,
|
||||
parametros,
|
||||
numeroTransbordos,
|
||||
ConstruirDistanciasPiePorTramo(
|
||||
origen.DistanciaAPie,
|
||||
baseRuta.DistanciaPieTransbordos,
|
||||
baseRuta.DistanciaPieFin),
|
||||
ObtenerDistanciasPieTransbordosPorTramo(baseRuta),
|
||||
baseRuta.DistanciaPieFin).ToArray()),
|
||||
RutaBus = ruta
|
||||
};
|
||||
|
||||
@@ -1518,9 +1522,9 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
|
||||
var distanciaAndando = parametros is null
|
||||
? Math.Max(0, resultado.DistanciaPieTotal)
|
||||
: UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(resultado.DistanciaPieInicio, parametros)
|
||||
+ UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(resultado.DistanciaPieTransbordos, parametros)
|
||||
+ UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(resultado.DistanciaPieFin, parametros);
|
||||
: UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaTotalMetros(
|
||||
ConstruirDistanciasPiePorTramo(resultado),
|
||||
parametros);
|
||||
var factor = parametros is not null && double.IsFinite(parametros.FactorEquilibradoAndarBus)
|
||||
? Math.Max(0, parametros.FactorEquilibradoAndarBus)
|
||||
: 12.0;
|
||||
@@ -1531,6 +1535,42 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
: double.PositiveInfinity;
|
||||
}
|
||||
|
||||
private static List<double> ConstruirDistanciasPiePorTramo(ResultadoBusquedaRutaBusDbus resultado)
|
||||
=> ConstruirDistanciasPiePorTramo(
|
||||
resultado.DistanciaPieInicio,
|
||||
ObtenerDistanciasPieTransbordosPorTramo(resultado),
|
||||
resultado.DistanciaPieFin);
|
||||
|
||||
private static IReadOnlyList<double> ObtenerDistanciasPieTransbordosPorTramo(
|
||||
ResultadoBusquedaRutaBusDbus resultado)
|
||||
{
|
||||
if (resultado.DistanciasPieTransbordosPorTramo.Count > 0)
|
||||
return resultado.DistanciasPieTransbordosPorTramo;
|
||||
|
||||
return double.IsFinite(resultado.DistanciaPieTransbordos) && resultado.DistanciaPieTransbordos > 0
|
||||
? new[] { resultado.DistanciaPieTransbordos }
|
||||
: Array.Empty<double>();
|
||||
}
|
||||
|
||||
private static List<double> ConstruirDistanciasPiePorTramo(
|
||||
double distanciaInicio,
|
||||
IEnumerable<double> distanciasTransbordos,
|
||||
double distanciaFin)
|
||||
{
|
||||
var distancias = new List<double>();
|
||||
AgregarDistancia(distanciaInicio);
|
||||
foreach (var distancia in distanciasTransbordos)
|
||||
AgregarDistancia(distancia);
|
||||
AgregarDistancia(distanciaFin);
|
||||
return distancias;
|
||||
|
||||
void AgregarDistancia(double distancia)
|
||||
{
|
||||
if (double.IsFinite(distancia) && distancia > 0)
|
||||
distancias.Add(distancia);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool DebeBuscarTransbordosRobustos(
|
||||
IReadOnlyList<ResultadoBusquedaRutaBusDbus> candidatasBus,
|
||||
IReadOnlyList<ParadaCandidata> candidatasOrigen,
|
||||
@@ -2033,6 +2073,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
ProveedorRuta = "v1",
|
||||
LineaSoloAPie = osrm.linea,
|
||||
LineasPieCalculoElevacion = new List<double[,]> { osrm.linea },
|
||||
DistanciasPiePorTramoAprox = new List<double> { osrm.distancia },
|
||||
DistanciaSoloAPie = osrm.distancia,
|
||||
DuracionSoloAPie = duracion,
|
||||
DuracionTotalAproxSegundos = duracion,
|
||||
@@ -2052,6 +2093,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
ProveedorRuta = "v2",
|
||||
LineaSoloAPie = valhalla.linea,
|
||||
LineasPieCalculoElevacion = new List<double[,]> { valhalla.linea },
|
||||
DistanciasPiePorTramoAprox = new List<double> { valhalla.distancia },
|
||||
DistanciaSoloAPie = valhalla.distancia,
|
||||
DuracionSoloAPie = duracion,
|
||||
DuracionTotalAproxSegundos = duracion,
|
||||
@@ -2091,6 +2133,23 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
});
|
||||
}
|
||||
|
||||
private static void AgregarDistanciaPiePorTramo(AlternativaRuta alternativa, double distanciaMetros)
|
||||
{
|
||||
if (double.IsFinite(distanciaMetros) && distanciaMetros > 0)
|
||||
alternativa.DistanciasPiePorTramoAprox.Add(distanciaMetros);
|
||||
}
|
||||
|
||||
private static void AcumularDistanciaPieEnPrimerTramo(AlternativaRuta alternativa, double distanciaMetros)
|
||||
{
|
||||
if (!double.IsFinite(distanciaMetros) || distanciaMetros <= 0)
|
||||
return;
|
||||
|
||||
if (alternativa.DistanciasPiePorTramoAprox.Count == 0)
|
||||
alternativa.DistanciasPiePorTramoAprox.Add(distanciaMetros);
|
||||
else
|
||||
alternativa.DistanciasPiePorTramoAprox[0] += distanciaMetros;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recalcula una alternativa de bus usando caminatas exactas y horarios reales.
|
||||
/// </summary>
|
||||
@@ -2105,6 +2164,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
return double.PositiveInfinity;
|
||||
|
||||
alternativa.LineasPieCalculoElevacion.Clear();
|
||||
alternativa.DistanciasPiePorTramoAprox.Clear();
|
||||
alternativa.EsfuerzoExtraPendienteMetros = 0;
|
||||
|
||||
var tramosBus = alternativa.AlternativaBus.Tramos;
|
||||
@@ -2155,6 +2215,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
alternativa.DistanciaPieInicioAprox = acceso.distancia > 0
|
||||
? acceso.distancia
|
||||
: UtilidadesTransitoDbus.CalcularDistanciaMetros(origenLatLon[0], origenLatLon[1], paradaInicioBus.Latitud, paradaInicioBus.Longitud);
|
||||
AgregarDistanciaPiePorTramo(alternativa, alternativa.DistanciaPieInicioAprox);
|
||||
alternativa.TiempoPieInicio = UtilidadesTransitoDbus.EstimarDuracionPieSegundos(alternativa.DistanciaPieInicioAprox, parametros);
|
||||
total += alternativa.TiempoPieInicio;
|
||||
cursor = UtilidadesTransitoDbus.AddSecondsSafe(cursor, alternativa.TiempoPieInicio);
|
||||
@@ -2229,10 +2290,12 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
{
|
||||
alternativa.DistanciaPieInicioAprox += distanciaTransferencia;
|
||||
alternativa.TiempoPieInicio += UtilidadesTransitoDbus.EstimarDuracionPieSegundos(distanciaTransferencia, parametros);
|
||||
AcumularDistanciaPieEnPrimerTramo(alternativa, distanciaTransferencia);
|
||||
}
|
||||
else
|
||||
{
|
||||
alternativa.DistanciaPieTransbordosAprox += distanciaTransferencia;
|
||||
AgregarDistanciaPiePorTramo(alternativa, distanciaTransferencia);
|
||||
}
|
||||
|
||||
var duracionTransferencia = UtilidadesTransitoDbus.EstimarDuracionPieSegundos(distanciaTransferencia, parametros);
|
||||
@@ -2345,6 +2408,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
alternativa.DistanciaPieFinAprox = salidaFinal.distancia > 0
|
||||
? salidaFinal.distancia
|
||||
: UtilidadesTransitoDbus.CalcularDistanciaMetros(puntoUltimaLlegada[0], puntoUltimaLlegada[1], destinoLatLon[0], destinoLatLon[1]);
|
||||
AgregarDistanciaPiePorTramo(alternativa, alternativa.DistanciaPieFinAprox);
|
||||
alternativa.TiempoPieFin = UtilidadesTransitoDbus.EstimarDuracionPieSegundos(alternativa.DistanciaPieFinAprox, parametros);
|
||||
total += alternativa.TiempoPieFin;
|
||||
|
||||
@@ -2462,6 +2526,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
DistanciaPieFin = candidataBase.DistanciaPieFin,
|
||||
TiempoPieFin = candidataBase.TiempoPieFin,
|
||||
DistanciaPieTransbordos = candidataBase.DistanciaPieTransbordos,
|
||||
DistanciasPieTransbordosPorTramo = candidataBase.DistanciasPieTransbordosPorTramo.ToArray(),
|
||||
TiempoEsperaInicialSegundos = esperaInicial,
|
||||
TiempoEsperaTransbordosSegundos = candidataBase.TiempoEsperaTransbordosSegundos,
|
||||
DuracionEstimadaSegundos = duracionEstimada,
|
||||
@@ -2469,9 +2534,10 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
duracionEstimada,
|
||||
parametros,
|
||||
rutaDirecta.NumeroTransbordos,
|
||||
ConstruirDistanciasPiePorTramo(
|
||||
origenDirecto.DistanciaAPie,
|
||||
candidataBase.DistanciaPieTransbordos,
|
||||
candidataBase.DistanciaPieFin),
|
||||
ObtenerDistanciasPieTransbordosPorTramo(candidataBase),
|
||||
candidataBase.DistanciaPieFin).ToArray()),
|
||||
RutaBus = rutaDirecta
|
||||
};
|
||||
|
||||
@@ -3156,9 +3222,22 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
private static double CalcularDistanciaAndandoCorregidaMetros(
|
||||
AlternativaRuta alternativa,
|
||||
ParametrosPlanificadorRuta parametros)
|
||||
=> UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(alternativa.DistanciaPieInicioAprox, parametros)
|
||||
+ UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(alternativa.DistanciaPieTransbordosAprox, parametros)
|
||||
+ UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaMetros(alternativa.DistanciaPieFinAprox, parametros);
|
||||
=> UtilidadesTransitoDbus.CalcularDistanciaPieCorregidaTotalMetros(
|
||||
ObtenerDistanciasPiePorTramo(alternativa),
|
||||
parametros);
|
||||
|
||||
private static IReadOnlyList<double> ObtenerDistanciasPiePorTramo(AlternativaRuta alternativa)
|
||||
{
|
||||
if (alternativa.DistanciasPiePorTramoAprox.Count > 0)
|
||||
return alternativa.DistanciasPiePorTramoAprox;
|
||||
|
||||
return ConstruirDistanciasPiePorTramo(
|
||||
alternativa.DistanciaPieInicioAprox,
|
||||
alternativa.DistanciaPieTransbordosAprox > 0
|
||||
? new[] { alternativa.DistanciaPieTransbordosAprox }
|
||||
: Array.Empty<double>(),
|
||||
alternativa.DistanciaPieFinAprox);
|
||||
}
|
||||
|
||||
private static double DuracionVisibleOrdenacion(AlternativaRuta alternativa)
|
||||
=> double.IsFinite(alternativa.DuracionTotalAproxSegundos)
|
||||
@@ -3355,9 +3434,7 @@ public sealed class PlanificadorRutasServicio : IPlanificadorRutas
|
||||
alternativa.DuracionTotalAproxSegundos,
|
||||
parametros,
|
||||
alternativa.NumeroTransbordosReales,
|
||||
alternativa.DistanciaPieInicioAprox,
|
||||
alternativa.DistanciaPieTransbordosAprox,
|
||||
alternativa.DistanciaPieFinAprox);
|
||||
ObtenerDistanciasPiePorTramo(alternativa).ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -316,7 +316,7 @@ internal static class UtilidadesTransitoDbus
|
||||
: 1.35;
|
||||
var parametroBaseMetros = double.IsFinite(parametros.ParametroPenalizacionDistanciaPieMetros)
|
||||
? Math.Abs(parametros.ParametroPenalizacionDistanciaPieMetros)
|
||||
: 100.0;
|
||||
: 200.0;
|
||||
|
||||
if (parametroBaseMetros <= 0)
|
||||
parametroBaseMetros = 1.0;
|
||||
@@ -325,6 +325,22 @@ internal static class UtilidadesTransitoDbus
|
||||
return Math.Max(distanciaMetros, corregida);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aplica la correccion a cada tramo peatonal por separado y suma los resultados.
|
||||
/// </summary>
|
||||
public static double CalcularDistanciaPieCorregidaTotalMetros(
|
||||
IEnumerable<double> distanciasPieMetros,
|
||||
ParametrosPlanificadorRuta parametros)
|
||||
{
|
||||
var total = 0.0;
|
||||
foreach (var distancia in distanciasPieMetros)
|
||||
total += CalcularDistanciaPieCorregidaMetros(distancia, parametros);
|
||||
|
||||
return double.IsFinite(total) && total >= 0
|
||||
? total
|
||||
: double.PositiveInfinity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calcula un coste interno que penaliza de forma progresiva la caminata sin cambiar el tiempo real.
|
||||
/// </summary>
|
||||
|
||||
@@ -322,7 +322,7 @@ window.rt.drawRoute = function (id, coords, options) {
|
||||
}
|
||||
};
|
||||
|
||||
window.rt.fitRoutes = function (coords) {
|
||||
window.rt.fitRoutes = function (coords, preferredCenter) {
|
||||
const map = window.__rtLeafletMap;
|
||||
if (!map || !window.L) return false;
|
||||
|
||||
@@ -364,7 +364,14 @@ window.rt.fitRoutes = function (coords) {
|
||||
const geometryBounds = window.L.latLngBounds(points);
|
||||
if (!geometryBounds.isValid()) return false;
|
||||
|
||||
map.panTo(geometryBounds.getCenter(), {
|
||||
const center = Array.isArray(preferredCenter)
|
||||
&& preferredCenter.length >= 2
|
||||
&& Number.isFinite(Number(preferredCenter[0]))
|
||||
&& Number.isFinite(Number(preferredCenter[1]))
|
||||
? window.L.latLng(Number(preferredCenter[0]), Number(preferredCenter[1]))
|
||||
: geometryBounds.getCenter();
|
||||
|
||||
map.panTo(center, {
|
||||
animate: true,
|
||||
duration: 0.35
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user