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("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.blockLeafletDoubleClick"); } catch (Exception ex) { Console.WriteLine("rt.blockLeafletDoubleClick: " + 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 const string _versionApp = "(v-20260908a)";
|
||||
private const string _versionApp = "(v-20260908b)";
|
||||
|
||||
|
||||
private double? _paradaElevIdee;
|
||||
|
||||
@@ -1541,6 +1541,8 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
_inspectorElevLocal2 = null;
|
||||
_inspectorElevLocal1 = null;
|
||||
_inspectorLugaresCercanos = Array.Empty<LugarGeocodificadoCercano>();
|
||||
_inspectorSuperficieTexto = null;
|
||||
_inspectorSuperficieCargando = true;
|
||||
_popupInspectorVisible = true;
|
||||
|
||||
ObtenerElevacionesLocalesComparativasPorLote(new[] { (lat, lon) });
|
||||
@@ -1558,6 +1560,8 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
await ActualizarMarcadoresInspectorJsAsync();
|
||||
StateHasChanged();
|
||||
|
||||
_ = CompletarSuperficiePuntoInspectorAsync(lat, lon, versionInspector);
|
||||
|
||||
if (_inspectorPuntoAnterior is { } puntoAnterior)
|
||||
_ = CompletarDatosPuntoInspectorAnteriorAsync(puntoAnterior, versionInspector);
|
||||
|
||||
@@ -1648,6 +1652,8 @@ public partial class PlanificadorRutas : ComponentBase
|
||||
_popupInspectorVisible = false;
|
||||
_inspectorPuntoAnterior = null;
|
||||
_inspectorLugaresCercanos = Array.Empty<LugarGeocodificadoCercano>();
|
||||
_inspectorSuperficieCargando = false;
|
||||
_inspectorSuperficieTexto = null;
|
||||
|
||||
try { await JS.InvokeVoidAsync("rt.clearInspectorMarkers"); } catch { }
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ public partial class PlanificadorRutas
|
||||
_zonasExclusionCaminata.Find(zona => zona.Id == _zonaExclusionSeleccionada);
|
||||
private bool _modoDibujoExclusionCaminata =>
|
||||
_mostrarHerramientaZonas && ZonaExclusionSeleccionada is { Cerrada: false };
|
||||
private int NumeroZonasExclusion => _zonasExclusionCaminata.Count(zona => zona.Cerrada);
|
||||
|
||||
private List<List<double[]>>? ObtenerPoligonosExclusionCaminata()
|
||||
{
|
||||
@@ -37,6 +36,17 @@ public partial class PlanificadorRutas
|
||||
await ActualizarEditorExclusionCaminataAsync();
|
||||
}
|
||||
|
||||
[JSInvokable]
|
||||
public async Task AlternarHerramientaZonas()
|
||||
{
|
||||
if (_mostrarHerramientaZonas)
|
||||
await CerrarHerramientaZonasAsync();
|
||||
else
|
||||
await AbrirHerramientaZonasAsync();
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task CerrarHerramientaZonasAsync()
|
||||
{
|
||||
_zonasExclusionCaminata.RemoveAll(zona => !zona.Cerrada);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Globalization;
|
||||
using Microsoft.JSInterop;
|
||||
using RutasDBUS.Modelos.Planificacion;
|
||||
@@ -7,6 +8,96 @@ namespace RutasDBUS.Components.Pages;
|
||||
public partial class PlanificadorRutas
|
||||
{
|
||||
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>
|
||||
/// Consulta la superficie únicamente del segmento de elevación que se acaba de seleccionar.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using RutasDBUS.Modelos.Historial;
|
||||
using RutasDBUS.Servicios.Configuracion;
|
||||
|
||||
@@ -34,4 +35,18 @@ public partial class PlanificadorRutas
|
||||
AplicarConfiguracionLocal(predeterminada);
|
||||
_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>
|
||||
}
|
||||
|
||||
<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>
|
||||
@* STACK DE POPUPS (izquierda) *@
|
||||
@if (_paradaClicada is not null || _itinerarioClicado is not null || _popupInspectorVisible)
|
||||
@@ -455,6 +446,17 @@
|
||||
</span>
|
||||
}
|
||||
</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)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,42 @@ public sealed class ServicioValoresFabrica
|
||||
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)
|
||||
{
|
||||
static bool Positivo(double? valor) => valor is { } v && double.IsFinite(v) && v > 0;
|
||||
|
||||
@@ -1363,6 +1363,10 @@ html, body {
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.inspector-surface-row {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
/* LISTA DE TRAMOS TIPO “DIRECCIONES” CON NÚMEROS */
|
||||
|
||||
.lista-tramos-ruta {
|
||||
|
||||
@@ -14,7 +14,10 @@ window.initAltInspector = function (dotNetHelper) {
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
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