agrobot_base/AgroBase/OperationControl/Mapas/Controller/MapaOperacaoController.Rend...

1050 lines
17 KiB
C#

using Mapsui;
using Mapsui.Layers;
using OperationControl.Controls;
using OperationControl.Mapas.Interaction;
using OperationControl.Mapas.Models;
using OperationControl.Mapas.Rendering;
namespace OperationControl.Mapas
{
public sealed partial class MapaOperacaoController
{
/*
* =========================================================
* API PRINCIPAL DE RENDER
* =========================================================
*/
/// <summary>
/// Prepara completamente um MapViewControl para
/// representar o estado atual do subsistema de mapas.
///
/// Use este método quando:
/// - entrar em uma tela;
/// - trocar de seção;
/// - trocar mapa ativo;
/// - carregar mapa novo;
/// - receber mapa do rover.
/// </summary>
public void PrepararMapa(MapViewControl? mapaControl, MapaModoInteracao modoInteracao = MapaModoInteracao.Visualizacao, bool enquadrarDocumento = false)
{
if (mapaControl?.Mapa?.Map == null)
{
return;
}
RegistrarMapa(mapaControl);
MapaModoInteracao modoEfetivo = _estadoEdicao.EmEdicao && _mapasEmEdicao.Contains(mapaControl) ? MapaModoInteracao.Edicao : modoInteracao;
AplicarModoInteracao(mapaControl, modoEfetivo);
/*
* Se esta View estiver atualmente em edição,
* sua fonte visual é DocumentoTrabalho.
*/
if (
_estadoEdicao.EmEdicao &&
_mapasEmEdicao.Contains(
mapaControl
)
)
{
RenderizarEdicaoNoMapa(
mapaControl
);
RenderizarMovimentoNoMapa(
mapaControl
);
RenderizarRotaRetornoNoMapa(
mapaControl
);
RenderizarReferenciasGnssNoMapa(
mapaControl
);
RenderizarBordaGnssNoMapa(
mapaControl
);
RenderizarEntidadesDinamicasNoMapa(
mapaControl
);
mapaControl.Mapa.Refresh();
return;
}
/*
* Ordem visual:
*
* 1 mapa operacional
* 2 rastro / MPC
* 3 retorno
* 4 referência GNSS
* 5 Base/Rover
*/
RenderizarWorkspaceNoMapa(
mapaControl
);
RenderizarMovimentoNoMapa(
mapaControl
);
RenderizarRotaRetornoNoMapa(
mapaControl
);
RenderizarReferenciasGnssNoMapa(
mapaControl
);
RenderizarBordaGnssNoMapa(
mapaControl
);
RenderizarEntidadesDinamicasNoMapa(
mapaControl
);
if (enquadrarDocumento)
{
EnquadrarDocumentoNoMapa(
mapaControl,
_workspace.Documento
);
}
mapaControl.Mapa.Refresh();
}
public void RegistrarMapa(MapViewControl? mapaControl)
{
if (mapaControl?.Mapa?.Map == null)
{
return;
}
/*
* Eventos são registrados uma única vez por
* instância de MapViewControl.
*/
if (!_mapasRegistrados.Add(mapaControl))
{
return;
}
mapaControl.MapaNovoViewportAlterado += OnMapaNovoViewportAlterado;
mapaControl.MapaNovoRuaClicada += OnMapaNovoRuaClicada;
mapaControl.MapaNovoPontoRetornoClicado += OnMapaNovoPontoRetornoClicado;
mapaControl.MapaNovaEntidadeClicada += OnMapaNovaEntidadeClicada;
mapaControl.MapaEditorFerramentaSelecionada += OnMapaEditorFerramentaSelecionada;
mapaControl.MapaEditorLimparSelecaoSolicitado += OnMapaEditorLimparSelecaoSolicitado;
mapaControl.MapaEditorRetanguloSelecionado += OnMapaEditorRetanguloSelecionado;
mapaControl.MapaEditorPoligonoRecorteDefinido += OnMapaEditorPoligonoRecorteDefinido;
mapaControl.MapaEditorDesfazerSolicitado += OnMapaEditorDesfazerSolicitado;
mapaControl.MapaEditorRefazerSolicitado += OnMapaEditorRefazerSolicitado;
mapaControl.MapaEditorExcluirSelecionadasSolicitado += OnMapaEditorExcluirSelecionadasSolicitado;
mapaControl.MapaEditorAplicarEdicaoSolicitado += OnMapaEditorAplicarEdicaoSolicitado;
mapaControl.MapaEditorCancelarEdicaoSolicitado += OnMapaEditorCancelarEdicaoSolicitado;
mapaControl.MapaEditorEscopoRecorteAlterado += OnMapaEditorEscopoRecorteAlterado;
mapaControl.MapaEditorBordaGnssAcaoSolicitada += OnMapaEditorBordaGnssAcaoSolicitada;
mapaControl.MapaEditorRestaurarFonteSolicitado += OnMapaEditorRestaurarFonteSolicitado;
}
/*
* =========================================================
* WORKSPACE
* =========================================================
*/
private void RenderizarWorkspaceNoMapa(
MapViewControl mapaControl)
{
if (
mapaControl?.Mapa?.Map == null
)
{
return;
}
/*
* Remove somente o render deste Mapsui.
*/
if (
_rendersMapa.TryGetValue(
mapaControl,
out var renderAnterior
)
)
{
mapaControl
.Mapa
.Map
.Layers
.Remove(
renderAnterior.Layer
);
_rendersMapa.Remove(
mapaControl
);
}
else
{
/*
* Guarda adicional durante a migração.
*/
var layerAnterior =
mapaControl
.Mapa
.Map
.Layers
.FirstOrDefault(
x =>
x.Name ==
MapaRenderService
.NomeCamadaPadrao
);
if (layerAnterior != null)
{
mapaControl
.Mapa
.Map
.Layers
.Remove(
layerAnterior
);
}
}
if (!_workspace.PossuiMapa)
{
mapaControl.DefinirCamadaMapaNovo(
null
);
return;
}
var render =
_renderService
.CriarCamada(
_workspace.Documento!
);
_renderService
.AplicarSelecao(
render,
_workspace.Selecao
);
mapaControl
.Mapa
.Map
.Layers
.Add(
render.Layer
);
mapaControl
.DefinirCamadaMapaNovo(
render.Layer
);
_rendersMapa[
mapaControl
] =
render;
}
private void InvalidarRendersWorkspace()
{
foreach (
var item
in _rendersMapa.ToArray())
{
try
{
MapViewControl mapaControl =
item.Key;
MapaRenderResult render =
item.Value;
if (
mapaControl.Mapa?.Map
!= null
)
{
mapaControl
.Mapa
.Map
.Layers
.Remove(
render.Layer
);
mapaControl
.DefinirCamadaMapaNovo(
null
);
mapaControl
.Mapa
.Refresh();
}
}
catch (Exception ex)
{
Log(
"[MAPA][RENDER][INVALIDAR][ERRO] " +
ex.Message
);
}
}
_rendersMapa.Clear();
}
private void AtualizarEstiloSelecaoRua(
string ruaId)
{
foreach (
var item
in _rendersMapa.ToArray())
{
try
{
_renderService
.AtualizarEstiloRua(
item.Value,
_workspace.Selecao,
ruaId
);
item.Key
.Mapa
.Refresh();
}
catch (Exception ex)
{
Log(
"[MAPA][SELECAO][RENDER][ERRO] " +
ex.Message
);
}
}
}
/*
* =========================================================
* ROTA DE RETORNO
* =========================================================
*/
private void RenderizarRotaRetornoNoMapa(
MapViewControl mapaControl)
{
if (
mapaControl?.Mapa?.Map == null
)
{
return;
}
if (
_layersRetorno.TryGetValue(
mapaControl,
out var camada
)
)
{
_rotaRenderService
.AtualizarCamada(
camada,
_workspace.RotaRetorno
);
}
else
{
camada =
_rotaRenderService
.CriarCamada(
_workspace.RotaRetorno
);
mapaControl
.Mapa
.Map
.Layers
.Add(
camada
);
_layersRetorno[
mapaControl
] =
camada;
}
}
private void RenderizarRotasRegistradas()
{
foreach (
var mapa
in _mapasRegistrados.ToArray())
{
RenderizarRotaRetornoNoMapa(
mapa
);
GarantirEntidadesNoTopo(
mapa
);
mapa.Mapa.Refresh();
}
}
private void InvalidarRendersRotaRetorno()
{
foreach (
var item
in _layersRetorno.ToArray())
{
try
{
var mapaControl =
item.Key;
var camada =
item.Value;
if (
mapaControl.Mapa?.Map
!= null
)
{
mapaControl
.Mapa
.Map
.Layers
.Remove(
camada
);
mapaControl
.Mapa
.Refresh();
}
}
catch (Exception ex)
{
Log(
"[MAPA][RETORNO][INVALIDAR][ERRO] " +
ex.Message
);
}
}
_layersRetorno.Clear();
}
/*
* =========================================================
* ENTIDADES DINÂMICAS
* =========================================================
*/
private void RenderizarEntidadesDinamicasNoMapa(
MapViewControl mapaControl)
{
if (
mapaControl?.Mapa?.Map == null
)
{
return;
}
double resolution =
1.0;
try
{
resolution =
mapaControl
.Mapa
.Map
.Navigator
.Viewport
.Resolution;
}
catch
{
resolution =
1.0;
}
if (
_layersEntidades.TryGetValue(
mapaControl,
out var camada
)
)
{
_entidadeRenderService
.AtualizarCamada(
camada,
_estadoDinamico,
resolution
);
}
else
{
camada =
_entidadeRenderService
.CriarCamada(
_estadoDinamico,
resolution
);
mapaControl
.Mapa
.Map
.Layers
.Add(
camada
);
_layersEntidades[
mapaControl
] =
camada;
}
mapaControl
.DefinirCamadaEntidadesDinamicasNova(
camada
);
GarantirEntidadesNoTopo(
mapaControl
);
}
private void GarantirEntidadesNoTopo(
MapViewControl mapaControl)
{
if (
mapaControl?.Mapa?.Map == null
)
{
return;
}
if (
!_layersEntidades.TryGetValue(
mapaControl,
out var camada
)
)
{
return;
}
var layers =
mapaControl
.Mapa
.Map
.Layers;
if (!layers.Contains(camada))
return;
/*
* Fazemos isso somente em pontos de
* composição do mapa, não no mouse move.
*/
layers.Remove(
camada
);
layers.Add(
camada
);
}
/*
* =========================================================
* MOVIMENTO
* =========================================================
*/
private void RenderizarMovimentoNoMapa(
MapViewControl mapaControl)
{
if (
mapaControl?.Mapa?.Map == null
)
{
return;
}
/*
* RASTRO
*/
if (
_layersRastro.TryGetValue(
mapaControl,
out var camadaRastro
)
)
{
_rastroRenderService
.AtualizarCamada(
camadaRastro,
_estadoMovimento
);
}
else
{
camadaRastro =
_rastroRenderService
.CriarCamada(
_estadoMovimento
);
mapaControl
.Mapa
.Map
.Layers
.Add(
camadaRastro
);
_layersRastro[
mapaControl
] =
camadaRastro;
}
/*
* PREDIÇÃO MPC
*/
if (
_layersPredicao.TryGetValue(
mapaControl,
out var camadaPredicao
)
)
{
_predicaoRenderService
.AtualizarCamada(
camadaPredicao,
_estadoMovimento
);
}
else
{
camadaPredicao =
_predicaoRenderService
.CriarCamada(
_estadoMovimento
);
mapaControl
.Mapa
.Map
.Layers
.Add(
camadaPredicao
);
_layersPredicao[
mapaControl
] =
camadaPredicao;
}
}
/*
* =========================================================
* REFERÊNCIA GNSS
* =========================================================
*/
private void RenderizarReferenciasGnssNoMapa(
MapViewControl mapaControl)
{
if (
mapaControl?.Mapa?.Map == null
)
{
return;
}
if (
_layersReferenciaGnss
.TryGetValue(
mapaControl,
out var camada
)
)
{
if (_mostrarReferenciasGnss)
{
_referenciaGnssRenderService
.AtualizarCamada(
camada,
_estadoDinamico
);
}
else
{
camada.Features =
Array.Empty<IFeature>();
}
}
else
{
camada =
_referenciaGnssRenderService
.CriarCamada(
_estadoDinamico
);
if (!_mostrarReferenciasGnss)
{
camada.Features =
Array.Empty<IFeature>();
}
mapaControl
.Mapa
.Map
.Layers
.Add(
camada
);
_layersReferenciaGnss[
mapaControl
] =
camada;
}
}
/*
* =========================================================
* ENQUADRAMENTO
* =========================================================
*/
public void EnquadrarWorkspaceNoMapa(
MapViewControl? mapaControl,
double margem = 1.15)
{
EnquadrarDocumentoNoMapa(
mapaControl,
_workspace.Documento,
margem
);
}
private void RenderizarEdicaoNoMapa(MapViewControl mapaControl)
{
if (
mapaControl?.Mapa?.Map == null ||
!_estadoEdicao.EmEdicao ||
_estadoEdicao.DocumentoTrabalho == null
)
{
return;
}
/*
* Remove qualquer render de mapa operacional
* atualmente apresentado nesta View.
*/
if (
_rendersMapa.TryGetValue(
mapaControl,
out var renderAnterior
)
)
{
mapaControl
.Mapa
.Map
.Layers
.Remove(
renderAnterior.Layer
);
_rendersMapa.Remove(
mapaControl
);
}
var render =
_edicaoRenderService
.CriarCamada(
_estadoEdicao
);
mapaControl
.Mapa
.Map
.Layers
.Add(
render.Layer
);
/*
* Para o MapViewControl, esta continua sendo
* a layer de ruas interativa.
*
* Ele não precisa saber se é missão ou edição.
*/
mapaControl
.DefinirCamadaMapaNovo(
render.Layer
);
_rendersMapa[
mapaControl
] =
render;
GarantirEntidadesNoTopo(
mapaControl
);
mapaControl
.Mapa
.Refresh();
}
private void RenderizarDocumentoEdicaoAtual()
{
foreach (
var mapa
in _mapasEmEdicao
.ToArray())
{
RenderizarEdicaoNoMapa(
mapa
);
RenderizarBordaGnssNoMapa(
mapa
);
GarantirEntidadesNoTopo(
mapa
);
mapa.Mapa.Refresh();
}
}
private void RemoverRenderEdicao(MapViewControl mapaControl)
{
if (
mapaControl?.Mapa?.Map == null
)
{
return;
}
if (
_rendersMapa.TryGetValue(
mapaControl,
out var render
)
)
{
mapaControl
.Mapa
.Map
.Layers
.Remove(
render.Layer
);
_rendersMapa.Remove(
mapaControl
);
}
mapaControl
.DefinirCamadaMapaNovo(
null
);
mapaControl
.Mapa
.Refresh();
}
private static void EnquadrarDocumentoNoMapa(
MapViewControl? mapaControl,
MapaDocumento? documento,
double margem = 1.15)
{
if (
mapaControl == null ||
documento == null
)
{
return;
}
var limites =
documento.Limites;
if (
limites == null ||
limites.IsNull
)
{
return;
}
mapaControl.EnquadrarAreaWgs84(
minLongitude:
limites.MinX,
minLatitude:
limites.MinY,
maxLongitude:
limites.MaxX,
maxLatitude:
limites.MaxY,
margem:
margem
);
}
}
}