añadidos atajos ctrl + alt + f para guardar datos de fabrica
añadidos atajos ctrl + alt + z para abrir zonas de exclusion añadido superficio de terreno en el punto z
This commit is contained in:
@@ -49,6 +49,8 @@ public partial class PlanificadorRutas : ComponentBase, IDisposable
|
|||||||
|
|
||||||
try { await JS.InvokeVoidAsync("initBrilloMapa", _dotRef); } catch (Exception ex) { Console.WriteLine("initBrilloMapa: " + ex); }
|
try { await JS.InvokeVoidAsync("initBrilloMapa", _dotRef); } catch (Exception ex) { Console.WriteLine("initBrilloMapa: " + ex); }
|
||||||
try { await JS.InvokeVoidAsync("initAltInspector", _dotRef); } catch (Exception ex) { Console.WriteLine("initAltInspector: " + ex); }
|
try { await JS.InvokeVoidAsync("initAltInspector", _dotRef); } catch (Exception ex) { Console.WriteLine("initAltInspector: " + ex); }
|
||||||
|
try { await JS.InvokeVoidAsync("initZonasShortcut", _dotRef); } catch (Exception ex) { Console.WriteLine("initZonasShortcut: " + ex); }
|
||||||
|
try { await JS.InvokeVoidAsync("initFabricaShortcut", _dotRef); } catch (Exception ex) { Console.WriteLine("initFabricaShortcut: " + ex); }
|
||||||
try { await JS.InvokeVoidAsync("rt.setDotNetHelper", _dotRef); } catch (Exception ex) { Console.WriteLine("rt.setDotNetHelper: " + ex); }
|
try { await JS.InvokeVoidAsync("rt.setDotNetHelper", _dotRef); } catch (Exception ex) { Console.WriteLine("rt.setDotNetHelper: " + ex); }
|
||||||
try { await JS.InvokeVoidAsync("rt.blockLeafletDoubleClick"); } catch (Exception ex) { Console.WriteLine("rt.blockLeafletDoubleClick: " + ex); }
|
try { await JS.InvokeVoidAsync("rt.blockLeafletDoubleClick"); } catch (Exception ex) { Console.WriteLine("rt.blockLeafletDoubleClick: " + ex); }
|
||||||
try { await JS.InvokeVoidAsync("rt.initMobileMapControls"); } catch (Exception ex) { Console.WriteLine("rt.initMobileMapControls: " + ex); }
|
try { await JS.InvokeVoidAsync("rt.initMobileMapControls"); } catch (Exception ex) { Console.WriteLine("rt.initMobileMapControls: " + ex); }
|
||||||
|
|||||||
@@ -1400,7 +1400,7 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
private bool _elevPopupMinimizado = false;
|
private bool _elevPopupMinimizado = false;
|
||||||
|
|
||||||
|
|
||||||
private const string _versionApp = "(v-20260908a)";
|
private const string _versionApp = "(v-20260908b)";
|
||||||
|
|
||||||
|
|
||||||
private double? _paradaElevIdee;
|
private double? _paradaElevIdee;
|
||||||
|
|||||||
@@ -1541,6 +1541,8 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
_inspectorElevLocal2 = null;
|
_inspectorElevLocal2 = null;
|
||||||
_inspectorElevLocal1 = null;
|
_inspectorElevLocal1 = null;
|
||||||
_inspectorLugaresCercanos = Array.Empty<LugarGeocodificadoCercano>();
|
_inspectorLugaresCercanos = Array.Empty<LugarGeocodificadoCercano>();
|
||||||
|
_inspectorSuperficieTexto = null;
|
||||||
|
_inspectorSuperficieCargando = true;
|
||||||
_popupInspectorVisible = true;
|
_popupInspectorVisible = true;
|
||||||
|
|
||||||
ObtenerElevacionesLocalesComparativasPorLote(new[] { (lat, lon) });
|
ObtenerElevacionesLocalesComparativasPorLote(new[] { (lat, lon) });
|
||||||
@@ -1558,6 +1560,8 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
await ActualizarMarcadoresInspectorJsAsync();
|
await ActualizarMarcadoresInspectorJsAsync();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
|
||||||
|
_ = CompletarSuperficiePuntoInspectorAsync(lat, lon, versionInspector);
|
||||||
|
|
||||||
if (_inspectorPuntoAnterior is { } puntoAnterior)
|
if (_inspectorPuntoAnterior is { } puntoAnterior)
|
||||||
_ = CompletarDatosPuntoInspectorAnteriorAsync(puntoAnterior, versionInspector);
|
_ = CompletarDatosPuntoInspectorAnteriorAsync(puntoAnterior, versionInspector);
|
||||||
|
|
||||||
@@ -1648,6 +1652,8 @@ public partial class PlanificadorRutas : ComponentBase
|
|||||||
_popupInspectorVisible = false;
|
_popupInspectorVisible = false;
|
||||||
_inspectorPuntoAnterior = null;
|
_inspectorPuntoAnterior = null;
|
||||||
_inspectorLugaresCercanos = Array.Empty<LugarGeocodificadoCercano>();
|
_inspectorLugaresCercanos = Array.Empty<LugarGeocodificadoCercano>();
|
||||||
|
_inspectorSuperficieCargando = false;
|
||||||
|
_inspectorSuperficieTexto = null;
|
||||||
|
|
||||||
try { await JS.InvokeVoidAsync("rt.clearInspectorMarkers"); } catch { }
|
try { await JS.InvokeVoidAsync("rt.clearInspectorMarkers"); } catch { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ public partial class PlanificadorRutas
|
|||||||
_zonasExclusionCaminata.Find(zona => zona.Id == _zonaExclusionSeleccionada);
|
_zonasExclusionCaminata.Find(zona => zona.Id == _zonaExclusionSeleccionada);
|
||||||
private bool _modoDibujoExclusionCaminata =>
|
private bool _modoDibujoExclusionCaminata =>
|
||||||
_mostrarHerramientaZonas && ZonaExclusionSeleccionada is { Cerrada: false };
|
_mostrarHerramientaZonas && ZonaExclusionSeleccionada is { Cerrada: false };
|
||||||
private int NumeroZonasExclusion => _zonasExclusionCaminata.Count(zona => zona.Cerrada);
|
|
||||||
|
|
||||||
private List<List<double[]>>? ObtenerPoligonosExclusionCaminata()
|
private List<List<double[]>>? ObtenerPoligonosExclusionCaminata()
|
||||||
{
|
{
|
||||||
@@ -37,6 +36,17 @@ public partial class PlanificadorRutas
|
|||||||
await ActualizarEditorExclusionCaminataAsync();
|
await ActualizarEditorExclusionCaminataAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JSInvokable]
|
||||||
|
public async Task AlternarHerramientaZonas()
|
||||||
|
{
|
||||||
|
if (_mostrarHerramientaZonas)
|
||||||
|
await CerrarHerramientaZonasAsync();
|
||||||
|
else
|
||||||
|
await AbrirHerramientaZonasAsync();
|
||||||
|
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task CerrarHerramientaZonasAsync()
|
private async Task CerrarHerramientaZonasAsync()
|
||||||
{
|
{
|
||||||
_zonasExclusionCaminata.RemoveAll(zona => !zona.Cerrada);
|
_zonasExclusionCaminata.RemoveAll(zona => !zona.Cerrada);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
using RutasDBUS.Modelos.Planificacion;
|
using RutasDBUS.Modelos.Planificacion;
|
||||||
@@ -7,6 +8,96 @@ namespace RutasDBUS.Components.Pages;
|
|||||||
public partial class PlanificadorRutas
|
public partial class PlanificadorRutas
|
||||||
{
|
{
|
||||||
private int _versionConsultaSuperficieSegmento;
|
private int _versionConsultaSuperficieSegmento;
|
||||||
|
private bool _inspectorSuperficieCargando;
|
||||||
|
private string? _inspectorSuperficieTexto;
|
||||||
|
private readonly ConcurrentDictionary<string, Task<InformacionSueloTramo?>> _superficiePuntosInspectorCache = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Consulta la superficie del camino más cercano a un punto Z. Valhalla necesita
|
||||||
|
/// una traza, por eso se construye una pequeña línea centrada en el punto.
|
||||||
|
/// </summary>
|
||||||
|
private async Task CompletarSuperficiePuntoInspectorAsync(
|
||||||
|
double latitud,
|
||||||
|
double longitud,
|
||||||
|
int versionInspector)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var informacion = await ObtenerSuperficiePuntoInspectorCacheadaAsync(latitud, longitud);
|
||||||
|
if (versionInspector != _versionInspector
|
||||||
|
|| !_popupInspectorVisible
|
||||||
|
|| Math.Abs(_inspectorLat - latitud) > 0.00000001
|
||||||
|
|| Math.Abs(_inspectorLon - longitud) > 0.00000001)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_inspectorSuperficieTexto = FormatearSuperficiePuntoInspector(informacion);
|
||||||
|
_inspectorSuperficieCargando = false;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (versionInspector != _versionInspector
|
||||||
|
|| !_popupInspectorVisible
|
||||||
|
|| Math.Abs(_inspectorLat - latitud) > 0.00000001
|
||||||
|
|| Math.Abs(_inspectorLon - longitud) > 0.00000001)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_inspectorSuperficieTexto = "No disponible";
|
||||||
|
_inspectorSuperficieCargando = false;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<InformacionSueloTramo?> ObtenerSuperficiePuntoInspectorCacheadaAsync(
|
||||||
|
double latitud,
|
||||||
|
double longitud)
|
||||||
|
{
|
||||||
|
var clave = $"{latitud:0.000000}|{longitud:0.000000}";
|
||||||
|
return _superficiePuntosInspectorCache.GetOrAdd(
|
||||||
|
clave,
|
||||||
|
_ => ClienteValhalla.ObtenerInformacionSueloAsync(
|
||||||
|
CrearTrazaSondaSuperficie(latitud, longitud)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double[,] CrearTrazaSondaSuperficie(double latitud, double longitud)
|
||||||
|
{
|
||||||
|
const double semilongitudMetros = 12.0;
|
||||||
|
const double metrosPorGrado = 111_320.0;
|
||||||
|
|
||||||
|
var deltaLatitud = semilongitudMetros / metrosPorGrado;
|
||||||
|
|
||||||
|
return new double[,]
|
||||||
|
{
|
||||||
|
{ latitud - deltaLatitud, longitud },
|
||||||
|
{ latitud, longitud },
|
||||||
|
{ latitud + deltaLatitud, longitud }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatearSuperficiePuntoInspector(InformacionSueloTramo? informacion)
|
||||||
|
{
|
||||||
|
if (informacion is null || !informacion.Disponible || informacion.Segmentos.Count == 0)
|
||||||
|
return "No disponible";
|
||||||
|
|
||||||
|
var superficies = informacion.Segmentos
|
||||||
|
.Select(segmento =>
|
||||||
|
{
|
||||||
|
var uso = string.IsNullOrWhiteSpace(segmento.Uso)
|
||||||
|
? ""
|
||||||
|
: $" ({segmento.Uso})";
|
||||||
|
return $"{segmento.Superficie}{uso}";
|
||||||
|
})
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return superficies.Count == 0
|
||||||
|
? "No disponible"
|
||||||
|
: string.Join(" · ", superficies);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Consulta la superficie únicamente del segmento de elevación que se acaba de seleccionar.
|
/// Consulta la superficie únicamente del segmento de elevación que se acaba de seleccionar.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.JSInterop;
|
||||||
using RutasDBUS.Modelos.Historial;
|
using RutasDBUS.Modelos.Historial;
|
||||||
using RutasDBUS.Servicios.Configuracion;
|
using RutasDBUS.Servicios.Configuracion;
|
||||||
|
|
||||||
@@ -34,4 +35,18 @@ public partial class PlanificadorRutas
|
|||||||
AplicarConfiguracionLocal(predeterminada);
|
AplicarConfiguracionLocal(predeterminada);
|
||||||
_modoConfiguracionHistorial = ModoConfiguracionHistorial.Actual;
|
_modoConfiguracionHistorial = ModoConfiguracionHistorial.Actual;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JSInvokable]
|
||||||
|
public async Task GuardarConfiguracionFabricaDesdeAtajoAsync()
|
||||||
|
{
|
||||||
|
if (!_configuracionLocalCargada)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var actual = CrearConfiguracionLocal();
|
||||||
|
if (!await ValoresFabrica.GuardarAsync(actual))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_configuracionFabrica = actual.Clonar();
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,15 +228,6 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button type="button"
|
|
||||||
class="map-zones-toggle @(_mostrarHerramientaZonas ? "is-active" : "")"
|
|
||||||
title="Zonas a evitar: @NumeroZonasExclusion"
|
|
||||||
aria-label="Abrir zonas a evitar"
|
|
||||||
aria-pressed="@_mostrarHerramientaZonas"
|
|
||||||
@onclick="AbrirHerramientaZonasAsync">
|
|
||||||
<span aria-hidden="true">⬡</span>
|
|
||||||
<span>Zonas</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
@* STACK DE POPUPS (izquierda) *@
|
@* STACK DE POPUPS (izquierda) *@
|
||||||
@if (_paradaClicada is not null || _itinerarioClicado is not null || _popupInspectorVisible)
|
@if (_paradaClicada is not null || _itinerarioClicado is not null || _popupInspectorVisible)
|
||||||
@@ -455,6 +446,17 @@
|
|||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="inspector-surface-row">
|
||||||
|
<b>Superficie:</b>
|
||||||
|
@if (_inspectorSuperficieCargando)
|
||||||
|
{
|
||||||
|
<span class="muted">Consultando...</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span>@(_inspectorSuperficieTexto ?? "No disponible")</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
@if (_inspectorLugaresCercanos.Count > 0)
|
@if (_inspectorLugaresCercanos.Count > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,6 +37,42 @@ public sealed class ServicioValoresFabrica
|
|||||||
finally { _bloqueo.Release(); }
|
finally { _bloqueo.Release(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> GuardarAsync(ConfiguracionHistorialRuta config)
|
||||||
|
{
|
||||||
|
if (!EsValida(config))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
await _bloqueo.WaitAsync();
|
||||||
|
var temporal = _ruta + ".tmp";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var directorio = Path.GetDirectoryName(_ruta);
|
||||||
|
if (!string.IsNullOrWhiteSpace(directorio))
|
||||||
|
Directory.CreateDirectory(directorio);
|
||||||
|
|
||||||
|
await using (var archivo = File.Create(temporal))
|
||||||
|
{
|
||||||
|
await JsonSerializer.SerializeAsync(
|
||||||
|
archivo,
|
||||||
|
config,
|
||||||
|
new JsonSerializerOptions { WriteIndented = true });
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Move(temporal, _ruta, overwrite: true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or JsonException)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("No se pudieron guardar los valores de fabrica: {Tipo}", ex.GetType().Name);
|
||||||
|
try { if (File.Exists(temporal)) File.Delete(temporal); } catch { }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_bloqueo.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static bool EsValida(ConfiguracionHistorialRuta config)
|
private static bool EsValida(ConfiguracionHistorialRuta config)
|
||||||
{
|
{
|
||||||
static bool Positivo(double? valor) => valor is { } v && double.IsFinite(v) && v > 0;
|
static bool Positivo(double? valor) => valor is { } v && double.IsFinite(v) && v > 0;
|
||||||
|
|||||||
@@ -1363,6 +1363,10 @@ html, body {
|
|||||||
color: #9ca3af;
|
color: #9ca3af;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inspector-surface-row {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
/* LISTA DE TRAMOS TIPO “DIRECCIONES” CON NÚMEROS */
|
/* LISTA DE TRAMOS TIPO “DIRECCIONES” CON NÚMEROS */
|
||||||
|
|
||||||
.lista-tramos-ruta {
|
.lista-tramos-ruta {
|
||||||
|
|||||||
@@ -14,7 +14,10 @@ window.initAltInspector = function (dotNetHelper) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("keydown", function (e) {
|
document.addEventListener("keydown", function (e) {
|
||||||
if (e.key === "Z" || e.key === "z") setInspectorActive(true);
|
if (!e.ctrlKey && !e.altKey && !e.metaKey && !e.shiftKey &&
|
||||||
|
(e.key === "Z" || e.key === "z")) {
|
||||||
|
setInspectorActive(true);
|
||||||
|
}
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
document.addEventListener("keyup", function (e) {
|
document.addEventListener("keyup", function (e) {
|
||||||
@@ -26,6 +29,36 @@ window.initAltInspector = function (dotNetHelper) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.initZonasShortcut = function (dotNetHelper) {
|
||||||
|
if (window.rt && window.rt._zonasShortcutInicializado) return;
|
||||||
|
|
||||||
|
window.rt = window.rt || {};
|
||||||
|
window.rt._zonasShortcutInicializado = true;
|
||||||
|
|
||||||
|
document.addEventListener("keydown", function (e) {
|
||||||
|
if (e.repeat || e.code !== "KeyZ" || !e.ctrlKey || !e.altKey || e.shiftKey) return;
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
dotNetHelper.invokeMethodAsync("AlternarHerramientaZonas").catch(function () { });
|
||||||
|
}, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.initFabricaShortcut = function (dotNetHelper) {
|
||||||
|
if (window.rt && window.rt._fabricaShortcutInicializado) return;
|
||||||
|
|
||||||
|
window.rt = window.rt || {};
|
||||||
|
window.rt._fabricaShortcutInicializado = true;
|
||||||
|
|
||||||
|
document.addEventListener("keydown", function (e) {
|
||||||
|
if (e.repeat || e.code !== "KeyF" || !e.ctrlKey || !e.altKey || e.shiftKey || e.metaKey) return;
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
dotNetHelper.invokeMethodAsync("GuardarConfiguracionFabricaDesdeAtajoAsync").catch(function () { });
|
||||||
|
}, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user