Añadido filtro de prohibicion de caminos por poligono dibujado

This commit is contained in:
2026-09-07 12:02:52 +02:00
parent bb9a407c04
commit d13ff13da1
10 changed files with 489 additions and 20 deletions

View File

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

View File

@@ -1659,6 +1659,12 @@ public partial class PlanificadorRutas : ComponentBase
{
var lat = e.location.latitude;
var lon = e.location.longitude;
if (_modoDibujoExclusionCaminata)
{
await OnExclusionPolygonMapClick(lat, lon);
return;
}
// Inspector (Z) sigue siendo click simple inmediato
if (_inspectorActivo)
@@ -1921,6 +1927,8 @@ public partial class PlanificadorRutas : ComponentBase
ParametroPenalizacionDistanciaPieMetros = _parametroPenalizacionDistanciaPieMetros,
PesoTransbordoRankingMinutos = _pesoTransbordoRankingMinutos,
FactorEquilibradoAndarBus = _factorEquilibradoAndarBus,
UsarValhallaParaCaminatas = _walkProvider == ProveedorCaminata.Valhalla,
PoligonosExclusionCaminata = ObtenerPoligonosExclusionCaminata(),
VelocidadBusKmH = _velocidadBusKmH,
MinutosPorTransbordo = _minutosTransbordo,
MargenTransbordoSegundos = Math.Clamp(_margenTransbordoSegundos, 0, 1800),

View File

@@ -0,0 +1,115 @@
using Microsoft.JSInterop;
namespace RutasDBUS.Components.Pages;
public partial class PlanificadorRutas
{
private bool _modoDibujoExclusionCaminata;
private bool _poligonoExclusionCaminataCerrado;
private readonly List<double[]> _verticesExclusionCaminata = new();
private bool PuedeProbarExclusionCaminata =>
_walkProvider == ProveedorCaminata.Valhalla &&
_hayRutaValida &&
_opcionesRuta.Count > 0 &&
_indiceAlternativaSeleccionada >= 0 &&
_indiceAlternativaSeleccionada < _opcionesRuta.Count &&
(_opcionesRuta[_indiceAlternativaSeleccionada].EsSoloAPie ||
_tramosRuta.Any(tramo => tramo.Tipo.StartsWith("A pie", StringComparison.OrdinalIgnoreCase)));
private bool PoligonoExclusionCaminataValido =>
_verticesExclusionCaminata.Count >= 3 && _poligonoExclusionCaminataCerrado;
private List<List<double[]>>? ObtenerPoligonosExclusionCaminata()
{
if (!PoligonoExclusionCaminataValido)
return null;
return new List<List<double[]>>
{
_verticesExclusionCaminata
.Select(punto => new[] { punto[1], punto[0] })
.Append(new[] { _verticesExclusionCaminata[0][1], _verticesExclusionCaminata[0][0] })
.ToList()
};
}
private async Task IniciarDibujoExclusionCaminataAsync()
{
if (!PuedeProbarExclusionCaminata)
return;
_modoDibujoExclusionCaminata = true;
_poligonoExclusionCaminataCerrado = false;
_verticesExclusionCaminata.Clear();
await JS.InvokeVoidAsync("rt.beginExclusionPolygonEditor");
StateHasChanged();
}
private async Task CancelarDibujoExclusionCaminataAsync()
{
_modoDibujoExclusionCaminata = false;
_poligonoExclusionCaminataCerrado = false;
_verticesExclusionCaminata.Clear();
await JS.InvokeVoidAsync("rt.clearExclusionPolygonEditor");
StateHasChanged();
}
private async Task DeshacerVerticeExclusionCaminataAsync()
{
if (_verticesExclusionCaminata.Count == 0 || _poligonoExclusionCaminataCerrado)
return;
_verticesExclusionCaminata.RemoveAt(_verticesExclusionCaminata.Count - 1);
await ActualizarEditorExclusionCaminataAsync();
}
private async Task CerrarPoligonoExclusionCaminataAsync()
{
if (_verticesExclusionCaminata.Count < 3)
return;
_poligonoExclusionCaminataCerrado = true;
await JS.InvokeVoidAsync("rt.closeExclusionPolygonEditor");
StateHasChanged();
}
private async Task CalcularRutaEvitandoPoligonoCaminataAsync()
{
if (!PoligonoExclusionCaminataValido)
return;
_modoDibujoExclusionCaminata = false;
await JS.InvokeVoidAsync("rt.finishExclusionPolygonEditor");
_omitirRegistroHistorialEnSiguienteCalculo = true;
await CalcularRutaCompletaAsync();
}
[JSInvokable]
public async Task OnExclusionPolygonMapClick(double latitud, double longitud)
{
if (!_modoDibujoExclusionCaminata || _poligonoExclusionCaminataCerrado)
return;
_verticesExclusionCaminata.Add(new[] { latitud, longitud });
await ActualizarEditorExclusionCaminataAsync();
}
[JSInvokable]
public Task OnExclusionPolygonVertexDragged(int indice, double latitud, double longitud)
{
if (indice >= 0 && indice < _verticesExclusionCaminata.Count)
{
_verticesExclusionCaminata[indice][0] = latitud;
_verticesExclusionCaminata[indice][1] = longitud;
}
return InvokeAsync(StateHasChanged);
}
private async Task ActualizarEditorExclusionCaminataAsync()
{
await JS.InvokeVoidAsync("rt.updateExclusionPolygonEditor", _verticesExclusionCaminata);
StateHasChanged();
}
}

View File

@@ -847,6 +847,54 @@
</div>
}
@if (PuedeProbarExclusionCaminata)
{
<div class="route-exclusion-tool" role="region" aria-label="Evitar zona andando">
<div class="route-exclusion-tool__header">
<strong>Probar evitando una zona andando</strong>
<span class="muted">v2</span>
</div>
@if (!_modoDibujoExclusionCaminata && !PoligonoExclusionCaminataValido)
{
<button type="button" class="btn-ghost route-exclusion-tool__button"
title="Dibujar una zona para evitarla en la siguiente búsqueda"
@onclick="IniciarDibujoExclusionCaminataAsync">
Dibujar zona a evitar
</button>
}
else
{
<div class="route-exclusion-tool__status">
@if (_poligonoExclusionCaminataCerrado)
{
<span>Zona cerrada con @_verticesExclusionCaminata.Count vértices. Puedes arrastrarlos.</span>
}
else
{
<span>Pulsa en el mapa para añadir vértices: @_verticesExclusionCaminata.Count.</span>
}
</div>
<div class="route-exclusion-tool__actions">
@if (!_poligonoExclusionCaminataCerrado)
{
<button type="button" class="btn-ghost" @onclick="DeshacerVerticeExclusionCaminataAsync"
disabled="@(_verticesExclusionCaminata.Count == 0)">Deshacer punto</button>
<button type="button" class="btn-ghost route-exclusion-tool__close" @onclick="CerrarPoligonoExclusionCaminataAsync"
disabled="@(_verticesExclusionCaminata.Count < 3)">Cerrar zona</button>
}
@if (PoligonoExclusionCaminataValido)
{
<button type="button" class="btn-primary route-exclusion-tool__calculate" @onclick="CalcularRutaEvitandoPoligonoCaminataAsync">
Calcular alternativa
</button>
}
<button type="button" class="btn-ghost" @onclick="CancelarDibujoExclusionCaminataAsync">Cancelar</button>
</div>
}
</div>
}
@* ========= RESUMEN BONITO ARRIBA (único) ========= *@
<p class="route-main-text">
@if (alt.EsSoloAPie)