corrigido carregamento do mapa na IHM
This commit is contained in:
parent
96c5049899
commit
db10742954
|
|
@ -46,7 +46,7 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros
|
||||||
op.Mapa = new MapasModel();
|
op.Mapa = new MapasModel();
|
||||||
|
|
||||||
_mapa = op.Mapa;
|
_mapa = op.Mapa;
|
||||||
_mapa.pnlMapa = pnlMapaWeb;
|
_mapa.DefinirPainelMapa(pnlMapaWeb);
|
||||||
_mapa.RuasSelecionadasAlteradas += Mapa_RuasSelecionadasAlteradas;
|
_mapa.RuasSelecionadasAlteradas += Mapa_RuasSelecionadasAlteradas;
|
||||||
_mapa.MapaCarregado += Mapa_MapaCarregado;
|
_mapa.MapaCarregado += Mapa_MapaCarregado;
|
||||||
|
|
||||||
|
|
@ -167,7 +167,7 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros
|
||||||
if (_mapa == null)
|
if (_mapa == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_mapa.pnlMapa = pnlMapaWeb;
|
_mapa.DefinirPainelMapa(pnlMapaWeb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Esse método já abre o diálogo, pergunta o tipo
|
* Esse método já abre o diálogo, pergunta o tipo
|
||||||
|
|
@ -341,7 +341,7 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros
|
||||||
|
|
||||||
if (object.ReferenceEquals(_mapa.pnlMapa, pnlMapaWeb))
|
if (object.ReferenceEquals(_mapa.pnlMapa, pnlMapaWeb))
|
||||||
{
|
{
|
||||||
_mapa.pnlMapa = null;
|
_mapa.DefinirPainelMapa(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
_mapa = null;
|
_mapa = null;
|
||||||
|
|
|
||||||
|
|
@ -43,15 +43,26 @@ namespace AgroBase.Forms.IHM.Operacao
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_mapasInicializados = true;
|
_mapasInicializados = true;
|
||||||
_mapaDinamico = new MapaDinamicoModel(formPai, pnlMapaDinamico);
|
|
||||||
|
_mapaDinamico =
|
||||||
|
new MapaDinamicoModel(
|
||||||
|
formPai,
|
||||||
|
pnlMapaDinamico
|
||||||
|
);
|
||||||
|
|
||||||
if (op == null)
|
if (op == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (op?.Mapa == null)
|
if (op.Parametros?.Modo != Enums.ModoOperacao.MapaGPS)
|
||||||
|
{
|
||||||
|
MostrarMapaDinamico();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.Mapa == null)
|
||||||
op.Mapa = new MapasModel();
|
op.Mapa = new MapasModel();
|
||||||
|
|
||||||
op.Mapa.pnlMapa = pnlMapaWeb;
|
op.Mapa.DefinirPainelMapa(pnlMapaWeb);
|
||||||
|
|
||||||
CarregarMapaWeb();
|
CarregarMapaWeb();
|
||||||
}
|
}
|
||||||
|
|
@ -136,6 +147,12 @@ namespace AgroBase.Forms.IHM.Operacao
|
||||||
if (op == null)
|
if (op == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (op.Parametros?.Modo != Enums.ModoOperacao.MapaGPS)
|
||||||
|
{
|
||||||
|
MostrarMapaDinamico();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MapasModel mapa = op.Mapa;
|
MapasModel mapa = op.Mapa;
|
||||||
|
|
||||||
if (mapa == null)
|
if (mapa == null)
|
||||||
|
|
@ -188,6 +205,12 @@ namespace AgroBase.Forms.IHM.Operacao
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SolicitarAtualizacaoMapaWeb()
|
||||||
|
{
|
||||||
|
CarregarMapaWeb();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void MostrarStatusAutonomia()
|
private void MostrarStatusAutonomia()
|
||||||
{
|
{
|
||||||
pnlAlertaAutonomia.Visible = false;
|
pnlAlertaAutonomia.Visible = false;
|
||||||
|
|
|
||||||
|
|
@ -120,10 +120,9 @@ namespace AgroBase.Forms.IHM
|
||||||
VoltarSolicitado(this, EventArgs.Empty);
|
VoltarSolicitado(this, EventArgs.Empty);
|
||||||
};
|
};
|
||||||
|
|
||||||
_ucParametros.ParametrosSalvos += async delegate
|
_ucParametros.ParametrosSalvos += delegate
|
||||||
{
|
{
|
||||||
_ucNavegacao.AtualizarMapaDinamico(true);
|
_ucNavegacao.AtualizarMapaDinamico(true);
|
||||||
await _ucNavegacao.AtualizarMapaWebAsync();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tabMovimentacao.Click += delegate { SelecionarAba(AbaOperacaoIHM.Movimentacao, true); };
|
tabMovimentacao.Click += delegate { SelecionarAba(AbaOperacaoIHM.Movimentacao, true); };
|
||||||
|
|
@ -152,6 +151,7 @@ namespace AgroBase.Forms.IHM
|
||||||
case AbaOperacaoIHM.Navegacao:
|
case AbaOperacaoIHM.Navegacao:
|
||||||
lblContextoAba.Text = "Mapa, GNSS, trajetória e autonomia por corredor";
|
lblContextoAba.Text = "Mapa, GNSS, trajetória e autonomia por corredor";
|
||||||
ExibirConteudo(_ucNavegacao);
|
ExibirConteudo(_ucNavegacao);
|
||||||
|
_ucNavegacao.SolicitarAtualizacaoMapaWeb();
|
||||||
break;
|
break;
|
||||||
case AbaOperacaoIHM.Parametros:
|
case AbaOperacaoIHM.Parametros:
|
||||||
lblContextoAba.Text = "Parâmetros da operação atual e configuração local";
|
lblContextoAba.Text = "Parâmetros da operação atual e configuração local";
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using static AgroBase.Models.Enums;
|
using static AgroBase.Models.Enums;
|
||||||
|
|
@ -60,6 +61,10 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
private TaskCompletionSource<bool> _navegacaoTask;
|
private TaskCompletionSource<bool> _navegacaoTask;
|
||||||
|
|
||||||
|
private readonly SemaphoreSlim _browserInitLock = new SemaphoreSlim(1, 1);
|
||||||
|
private readonly SemaphoreSlim _navigationLock = new SemaphoreSlim(1, 1);
|
||||||
|
|
||||||
|
|
||||||
public MapasModel()
|
public MapasModel()
|
||||||
{
|
{
|
||||||
mapaService = new MapasService();
|
mapaService = new MapasService();
|
||||||
|
|
@ -245,83 +250,279 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
private async Task InicializarBrowserAsync()
|
private async Task InicializarBrowserAsync()
|
||||||
{
|
{
|
||||||
if (_browserInicializado && browser != null && !browser.IsDisposed)
|
if (_disposed)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (pnlMapa == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
"O painel de mapa não foi definido.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pnlMapa.InvokeRequired)
|
if (pnlMapa.InvokeRequired)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("InicializarBrowserAsync deve ser chamado " + "na thread da interface.");
|
throw new InvalidOperationException(
|
||||||
|
"InicializarBrowserAsync deve ser chamado na thread da interface.");
|
||||||
}
|
}
|
||||||
|
|
||||||
browser = new WebView2();
|
await _browserInitLock.WaitAsync();
|
||||||
browser.Dock = DockStyle.Fill;
|
|
||||||
browser.Margin = Padding.Empty;
|
|
||||||
browser.Visible = false;
|
|
||||||
pnlMapa.Controls.Add(browser);
|
|
||||||
browser.BringToFront();
|
|
||||||
|
|
||||||
await browser.EnsureCoreWebView2Async();
|
try
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Outra chamada pode ter inicializado enquanto esta
|
||||||
|
* aguardava o lock.
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
_browserInicializado &&
|
||||||
|
browser != null &&
|
||||||
|
!browser.IsDisposed &&
|
||||||
|
browser.CoreWebView2 != null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
browser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
|
/*
|
||||||
browser.CoreWebView2.Settings.AreDevToolsEnabled = true;
|
* Remove uma instância anterior incompleta,
|
||||||
browser.CoreWebView2.Settings.IsStatusBarEnabled = false;
|
* se por algum motivo ela existir.
|
||||||
browser.CoreWebView2.WebMessageReceived -= CoreWebView2_WebMessageReceived;
|
*/
|
||||||
browser.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;
|
if (browser != null)
|
||||||
browser.NavigationCompleted -= Browser_NavigationCompleted;
|
{
|
||||||
browser.NavigationCompleted += Browser_NavigationCompleted;
|
try
|
||||||
pnlMapa.Resize -= PnlMapa_Resize;
|
{
|
||||||
pnlMapa.Resize += PnlMapa_Resize;
|
browser.NavigationCompleted -=
|
||||||
|
Browser_NavigationCompleted;
|
||||||
|
|
||||||
|
if (browser.CoreWebView2 != null)
|
||||||
|
{
|
||||||
|
browser.CoreWebView2.WebMessageReceived -=
|
||||||
|
CoreWebView2_WebMessageReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browser.Parent != null)
|
||||||
|
{
|
||||||
|
browser.Parent.Controls.Remove(browser);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!browser.IsDisposed)
|
||||||
|
{
|
||||||
|
browser.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Estamos descartando uma instância incompleta.
|
||||||
|
}
|
||||||
|
|
||||||
|
browser = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_browserInicializado = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IMPORTANTE:
|
||||||
|
*
|
||||||
|
* inicializa em variável LOCAL.
|
||||||
|
*
|
||||||
|
* Assim nenhuma outra chamada consegue trocar
|
||||||
|
* a instância que estamos aguardando.
|
||||||
|
*/
|
||||||
|
var novoBrowser = new WebView2
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
Margin = Padding.Empty,
|
||||||
|
Visible = false
|
||||||
|
};
|
||||||
|
|
||||||
|
pnlMapa.Controls.Add(novoBrowser);
|
||||||
|
novoBrowser.BringToFront();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await novoBrowser.EnsureCoreWebView2Async();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A tela/modelo pode ter sido destruída
|
||||||
|
* durante o await.
|
||||||
|
*/
|
||||||
|
if (_disposed || novoBrowser.IsDisposed)
|
||||||
|
{
|
||||||
|
if (!novoBrowser.IsDisposed)
|
||||||
|
{
|
||||||
|
novoBrowser.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var core = novoBrowser.CoreWebView2;
|
||||||
|
|
||||||
|
if (core == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
"O WebView2 concluiu a inicialização, " +
|
||||||
|
"mas CoreWebView2 permaneceu indisponível.");
|
||||||
|
}
|
||||||
|
|
||||||
|
core.Settings.AreDefaultContextMenusEnabled = false;
|
||||||
|
core.Settings.AreDevToolsEnabled = true;
|
||||||
|
core.Settings.IsStatusBarEnabled = false;
|
||||||
|
|
||||||
|
core.WebMessageReceived -=
|
||||||
|
CoreWebView2_WebMessageReceived;
|
||||||
|
|
||||||
|
core.WebMessageReceived +=
|
||||||
|
CoreWebView2_WebMessageReceived;
|
||||||
|
|
||||||
|
novoBrowser.NavigationCompleted -=
|
||||||
|
Browser_NavigationCompleted;
|
||||||
|
|
||||||
|
novoBrowser.NavigationCompleted +=
|
||||||
|
Browser_NavigationCompleted;
|
||||||
|
|
||||||
|
pnlMapa.Resize -=
|
||||||
|
PnlMapa_Resize;
|
||||||
|
|
||||||
|
pnlMapa.Resize +=
|
||||||
|
PnlMapa_Resize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Só agora publicamos a instância
|
||||||
|
* completamente inicializada.
|
||||||
|
*/
|
||||||
|
browser = novoBrowser;
|
||||||
|
|
||||||
_browserInicializado = true;
|
_browserInicializado = true;
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (novoBrowser.Parent != null)
|
||||||
|
{
|
||||||
|
novoBrowser.Parent.Controls.Remove(
|
||||||
|
novoBrowser);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!novoBrowser.IsDisposed)
|
||||||
|
{
|
||||||
|
novoBrowser.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_browserInitLock.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task NavegarParaMapaAsync()
|
private async Task NavegarParaMapaAsync()
|
||||||
{
|
{
|
||||||
if (browser == null || browser.CoreWebView2 == null)
|
await _navigationLock.WaitAsync();
|
||||||
|
|
||||||
|
TaskCompletionSource<bool> navegacaoAtual = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WebView2 browserAtual = browser;
|
||||||
|
|
||||||
|
if (
|
||||||
|
browserAtual == null ||
|
||||||
|
browserAtual.IsDisposed ||
|
||||||
|
browserAtual.CoreWebView2 == null
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_paginaCarregada = false;
|
_paginaCarregada = false;
|
||||||
|
|
||||||
_navegacaoTask = new TaskCompletionSource<bool>();
|
navegacaoAtual =
|
||||||
|
new TaskCompletionSource<bool>(
|
||||||
|
TaskCreationOptions.RunContinuationsAsynchronously
|
||||||
|
);
|
||||||
|
|
||||||
string uriComVersao = new Uri(mapaService.CaminhoHtml).AbsoluteUri + "?v=" + DateTime.UtcNow.Ticks;
|
_navegacaoTask = navegacaoAtual;
|
||||||
|
|
||||||
browser.CoreWebView2.Navigate(uriComVersao);
|
string uriComVersao =
|
||||||
|
new Uri(mapaService.CaminhoHtml).AbsoluteUri +
|
||||||
|
"?v=" +
|
||||||
|
DateTime.UtcNow.Ticks;
|
||||||
|
|
||||||
Task timeout = Task.Delay(TimeSpan.FromSeconds(10));
|
browserAtual.CoreWebView2.Navigate(uriComVersao);
|
||||||
|
|
||||||
Task concluida = await Task.WhenAny(_navegacaoTask.Task, timeout);
|
Task timeout =
|
||||||
|
Task.Delay(TimeSpan.FromSeconds(10));
|
||||||
|
|
||||||
|
Task concluida =
|
||||||
|
await Task.WhenAny(
|
||||||
|
navegacaoAtual.Task,
|
||||||
|
timeout
|
||||||
|
);
|
||||||
|
|
||||||
if (concluida == timeout)
|
if (concluida == timeout)
|
||||||
{
|
{
|
||||||
_navegacaoTask.TrySetCanceled();
|
navegacaoAtual.TrySetCanceled();
|
||||||
throw new TimeoutException("O mapa não concluiu o carregamento no tempo esperado.");
|
|
||||||
|
throw new TimeoutException(
|
||||||
|
"O mapa não concluiu o carregamento no tempo esperado.");
|
||||||
}
|
}
|
||||||
|
|
||||||
await _navegacaoTask.Task;
|
await navegacaoAtual.Task;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
navegacaoAtual != null &&
|
||||||
|
ReferenceEquals(
|
||||||
|
_navegacaoTask,
|
||||||
|
navegacaoAtual
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_navegacaoTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_navigationLock.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Browser_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
|
private void Browser_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
|
||||||
{
|
{
|
||||||
if (_navegacaoTask == null)
|
var navegacao = _navegacaoTask;
|
||||||
|
|
||||||
|
if (navegacao == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!(sender is WebView2 browserEvento))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (browserEvento.IsDisposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!e.IsSuccess)
|
if (!e.IsSuccess)
|
||||||
{
|
{
|
||||||
_navegacaoTask.TrySetException(new InvalidOperationException("Falha ao abrir o HTML do mapa. " + "Erro WebView2: " + e.WebErrorStatus));
|
navegacao.TrySetException(
|
||||||
|
new InvalidOperationException(
|
||||||
|
"Falha ao abrir o HTML do mapa. " +
|
||||||
|
"Erro WebView2: " +
|
||||||
|
e.WebErrorStatus
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_paginaCarregada = true;
|
_paginaCarregada = true;
|
||||||
browser.Visible = true;
|
|
||||||
browser.BringToFront();
|
|
||||||
|
|
||||||
_navegacaoTask.TrySetResult(true);
|
browserEvento.Visible = true;
|
||||||
|
browserEvento.BringToFront();
|
||||||
|
|
||||||
|
navegacao.TrySetResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task EnviarMapaParaJavascriptAsync()
|
private async Task EnviarMapaParaJavascriptAsync()
|
||||||
|
|
@ -755,6 +956,48 @@ namespace AgroBase.Models
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void DefinirPainelMapa(Panel painel)
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pnlMapa = painel;
|
||||||
|
|
||||||
|
if (
|
||||||
|
painel == null ||
|
||||||
|
painel.IsDisposed ||
|
||||||
|
browser == null ||
|
||||||
|
browser.IsDisposed
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (painel.InvokeRequired)
|
||||||
|
{
|
||||||
|
painel.BeginInvoke(
|
||||||
|
new Action<Panel>(DefinirPainelMapa),
|
||||||
|
painel
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ReferenceEquals(browser.Parent, painel))
|
||||||
|
{
|
||||||
|
if (browser.Parent != null)
|
||||||
|
{
|
||||||
|
browser.Parent.Controls.Remove(browser);
|
||||||
|
}
|
||||||
|
|
||||||
|
painel.Controls.Add(browser);
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.Dock = DockStyle.Fill;
|
||||||
|
browser.BringToFront();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
|
|
@ -762,6 +1005,10 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
|
|
||||||
|
_browserInicializado = false;
|
||||||
|
_paginaCarregada = false;
|
||||||
|
_mapaEnviado = false;
|
||||||
|
|
||||||
if (pnlMapa != null)
|
if (pnlMapa != null)
|
||||||
{
|
{
|
||||||
pnlMapa.Resize -=
|
pnlMapa.Resize -=
|
||||||
|
|
|
||||||
|
|
@ -1349,7 +1349,7 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
var ruasSelecionadas = parametros.RuasPercorrer ?? new List<string>();
|
var ruasSelecionadas = parametros.RuasPercorrer ?? new List<string>();
|
||||||
|
|
||||||
if (parametros.Mapa != null)
|
if (parametros.Mapa != null && parametros.Modo == ModoOperacao.MapaGPS)
|
||||||
{
|
{
|
||||||
novaOp.Mapa = new MapasModel();
|
novaOp.Mapa = new MapasModel();
|
||||||
novaOp.Mapa.DefinirRuasSelecionadas(novaOp, ruasSelecionadas);
|
novaOp.Mapa.DefinirRuasSelecionadas(novaOp, ruasSelecionadas);
|
||||||
|
|
|
||||||
|
|
@ -867,6 +867,8 @@ namespace AgroBase.Services
|
||||||
let camadaTrajetoriaPlanejada = null;
|
let camadaTrajetoriaPlanejada = null;
|
||||||
let camadaRastroRover = null;
|
let camadaRastroRover = null;
|
||||||
let camadaRastroBase = null;
|
let camadaRastroBase = null;
|
||||||
|
let camadaTrajetoGps = null;
|
||||||
|
let pontosTrajetoGps = [];
|
||||||
let pontosRastroRover = [];
|
let pontosRastroRover = [];
|
||||||
let pontosRastroBase = [];
|
let pontosRastroBase = [];
|
||||||
let ultimaPosicaoBase = null;
|
let ultimaPosicaoBase = null;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue