722 lines
18 KiB
C#
722 lines
18 KiB
C#
using NetTopologySuite.Geometries;
|
|
using OperationControl.Controls;
|
|
using OperationControl.Mapas.Editing;
|
|
using OperationControl.Mapas.Interaction;
|
|
|
|
namespace OperationControl.Mapas
|
|
{
|
|
public sealed partial class MapaOperacaoController
|
|
{
|
|
/*
|
|
* =========================================================
|
|
* CONFIGURAÇÃO DE INTERAÇÃO
|
|
* =========================================================
|
|
*/
|
|
|
|
/// <summary>
|
|
/// Define explicitamente como o MapViewControl deve
|
|
/// interpretar a interação do operador.
|
|
///
|
|
/// Se a View estiver em uma sessão de edição ativa,
|
|
/// o modo Edicao tem prioridade até a sessão terminar.
|
|
/// </summary>
|
|
public void DefinirModoInteracao(
|
|
MapViewControl? mapaControl,
|
|
MapaModoInteracao modo)
|
|
{
|
|
if (
|
|
mapaControl?.Mapa?.Map == null
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
RegistrarMapa(
|
|
mapaControl
|
|
);
|
|
|
|
|
|
MapaModoInteracao modoEfetivo =
|
|
_estadoEdicao.EmEdicao &&
|
|
_mapasEmEdicao.Contains(
|
|
mapaControl
|
|
)
|
|
? MapaModoInteracao.Edicao
|
|
: modo;
|
|
|
|
|
|
AplicarModoInteracao(
|
|
mapaControl,
|
|
modoEfetivo
|
|
);
|
|
}
|
|
|
|
|
|
private void AplicarModoInteracao(
|
|
MapViewControl mapaControl,
|
|
MapaModoInteracao modo)
|
|
{
|
|
if (
|
|
mapaControl.ModoInteracao ==
|
|
modo
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
var anterior =
|
|
mapaControl.ModoInteracao;
|
|
|
|
|
|
mapaControl.DefinirModoInteracao(
|
|
modo
|
|
);
|
|
|
|
|
|
Log(
|
|
"[MAPA][INTERACAO] " +
|
|
$"Anterior={anterior} | " +
|
|
$"Atual={modo}"
|
|
);
|
|
}
|
|
|
|
|
|
/*
|
|
* =========================================================
|
|
* RUA
|
|
* =========================================================
|
|
*/
|
|
|
|
private void OnMapaNovoRuaClicada(string ruaId)
|
|
{
|
|
try
|
|
{
|
|
/*
|
|
* =============================================
|
|
* MODO EDIÇÃO
|
|
* =============================================
|
|
*
|
|
* A seleção operacional fica completamente
|
|
* intocada.
|
|
*/
|
|
if (_estadoEdicao.EmEdicao)
|
|
{
|
|
/*
|
|
* Uma rua só responde ao clique direto
|
|
* enquanto a ferramenta Selecionar
|
|
* estiver ativa.
|
|
*/
|
|
if (
|
|
_ferramentaEdicaoAtual !=
|
|
MapaFerramentaEdicao.Selecionar
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AlternarRuaEdicao(
|
|
ruaId
|
|
);
|
|
|
|
|
|
Log(
|
|
"[MAPA][EDICAO][CLIQUE] " +
|
|
$"Rua={ruaId} | " +
|
|
$"Selecionadas=" +
|
|
$"{QuantidadeRuasSelecionadasEdicao}"
|
|
);
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* =============================================
|
|
* MODO NORMAL
|
|
* =============================================
|
|
*/
|
|
AlternarRuaOperacao(
|
|
ruaId
|
|
);
|
|
|
|
|
|
string ruas =
|
|
string.Join(
|
|
" -> ",
|
|
ObterRuasPercorrer()
|
|
);
|
|
|
|
|
|
Log(
|
|
"[MAPA][CLIQUE] " +
|
|
$"Rua={ruaId} | " +
|
|
$"Percurso=[{ruas}]"
|
|
);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log(
|
|
"[MAPA][CLIQUE][ERRO] " +
|
|
ex.Message
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* =========================================================
|
|
* RETORNO
|
|
* =========================================================
|
|
*/
|
|
|
|
private void OnMapaNovoPontoRetornoClicado(
|
|
double latitude,
|
|
double longitude)
|
|
{
|
|
try
|
|
{
|
|
AlternarPontoRetorno(
|
|
latitude,
|
|
longitude
|
|
);
|
|
|
|
|
|
double distancia =
|
|
ObterDistanciaRotaRetornoMetros();
|
|
|
|
|
|
Log(
|
|
"[MAPA][RETORNO][CLIQUE] " +
|
|
$"Pontos={QuantidadePontosRetorno} | " +
|
|
$"Distancia={distancia:F2} m"
|
|
);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log(
|
|
"[MAPA][RETORNO][CLIQUE][ERRO] " +
|
|
ex.Message
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* =========================================================
|
|
* ENTIDADE
|
|
* =========================================================
|
|
*/
|
|
|
|
private void OnMapaNovaEntidadeClicada(
|
|
string entidadeId)
|
|
{
|
|
try
|
|
{
|
|
var entidade =
|
|
ObterEntidade(
|
|
entidadeId
|
|
);
|
|
|
|
|
|
if (entidade == null)
|
|
return;
|
|
|
|
|
|
Log(
|
|
"[MAPA][ENTIDADE][CLIQUE] " +
|
|
$"Id={entidade.Id} | " +
|
|
$"Tipo={entidade.Tipo}"
|
|
);
|
|
|
|
|
|
/*
|
|
* Fim da responsabilidade do mapa.
|
|
*
|
|
* Dock decidirá o que significa
|
|
* selecionar Base ou Rover.
|
|
*/
|
|
EntidadeClicada?
|
|
.Invoke(
|
|
entidade.Id
|
|
);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log(
|
|
"[MAPA][ENTIDADE][CLIQUE][ERRO] " +
|
|
ex.Message
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* =========================================================
|
|
* VIEWPORT
|
|
* =========================================================
|
|
*/
|
|
|
|
private void OnMapaNovoViewportAlterado(
|
|
MapViewControl mapaControl)
|
|
{
|
|
/*
|
|
* Somente entidades dependem da resolução
|
|
* atual para manter tamanho visual adequado.
|
|
*/
|
|
RenderizarEntidadesDinamicasNoMapa(
|
|
mapaControl
|
|
);
|
|
|
|
|
|
mapaControl
|
|
.Mapa
|
|
.Refresh();
|
|
}
|
|
|
|
|
|
private void OnMapaEditorFerramentaSelecionada(MapViewControl mapaControl, MapaFerramentaEdicao ferramenta)
|
|
{
|
|
if (
|
|
!_estadoEdicao.EmEdicao ||
|
|
!_mapasEmEdicao.Contains(
|
|
mapaControl
|
|
)
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
DefinirFerramentaEdicao(
|
|
ferramenta
|
|
);
|
|
}
|
|
|
|
|
|
private void OnMapaEditorLimparSelecaoSolicitado(MapViewControl mapaControl)
|
|
{
|
|
if (
|
|
!_estadoEdicao.EmEdicao ||
|
|
!_mapasEmEdicao.Contains(
|
|
mapaControl
|
|
)
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
LimparSelecaoEdicao();
|
|
}
|
|
|
|
|
|
private void OnMapaEditorRetanguloSelecionado(MapViewControl mapaControl, MapaRetanguloSelecao retangulo)
|
|
{
|
|
if (
|
|
!_estadoEdicao.EmEdicao ||
|
|
!_mapasEmEdicao.Contains(
|
|
mapaControl
|
|
) ||
|
|
_ferramentaEdicaoAtual !=
|
|
MapaFerramentaEdicao
|
|
.SelecionarRetangulo
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
try
|
|
{
|
|
var encontrados =
|
|
_edicaoService
|
|
.SelecionarPorRetangulo(
|
|
_estadoEdicao,
|
|
|
|
retangulo
|
|
.MinLatitude,
|
|
|
|
retangulo
|
|
.MinLongitude,
|
|
|
|
retangulo
|
|
.MaxLatitude,
|
|
|
|
retangulo
|
|
.MaxLongitude,
|
|
|
|
substituirSelecao:
|
|
true
|
|
);
|
|
|
|
|
|
foreach (
|
|
var mapa
|
|
in _mapasEmEdicao
|
|
.ToArray())
|
|
{
|
|
if (
|
|
_rendersMapa.TryGetValue(
|
|
mapa,
|
|
out var render
|
|
)
|
|
)
|
|
{
|
|
_edicaoRenderService
|
|
.AplicarSelecao(
|
|
render,
|
|
_estadoEdicao
|
|
);
|
|
|
|
|
|
mapa.Mapa.Refresh();
|
|
}
|
|
}
|
|
|
|
|
|
SincronizarCockpitEdicao();
|
|
|
|
|
|
EstadoEdicaoAlterado?
|
|
.Invoke();
|
|
|
|
|
|
Log(
|
|
"[MAPA][EDICAO][RETANGULO] " +
|
|
$"Encontradas={encontrados.Count} | " +
|
|
$"Selecionadas=" +
|
|
$"{QuantidadeRuasSelecionadasEdicao}"
|
|
);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log(
|
|
"[MAPA][EDICAO][RETANGULO][ERRO] " +
|
|
ex.Message
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
private void OnMapaEditorPoligonoRecorteDefinido(MapViewControl mapaControl, MapaPoligonoRecorte recorte)
|
|
{
|
|
bool ferramentaPoligono =
|
|
_ferramentaEdicaoAtual ==
|
|
MapaFerramentaEdicao.RecorteLivre
|
|
||
|
|
_ferramentaEdicaoAtual ==
|
|
MapaFerramentaEdicao.RecortePorPontos;
|
|
|
|
|
|
if (
|
|
!_estadoEdicao.EmEdicao ||
|
|
!_mapasEmEdicao.Contains(
|
|
mapaControl
|
|
) ||
|
|
!ferramentaPoligono
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
if (
|
|
recorte == null ||
|
|
recorte.QuantidadePontos < 3
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
try
|
|
{
|
|
/*
|
|
* Fronteira UI → domínio.
|
|
*
|
|
* DTO:
|
|
* Latitude / Longitude
|
|
*
|
|
* NTS:
|
|
* X = longitude
|
|
* Y = latitude
|
|
*/
|
|
Coordinate[] pontos =
|
|
recorte
|
|
.Pontos
|
|
.Select(
|
|
p =>
|
|
new Coordinate(
|
|
p.Longitude,
|
|
p.Latitude
|
|
)
|
|
)
|
|
.ToArray();
|
|
|
|
|
|
/*
|
|
* V1:
|
|
* o próprio polígono define o escopo.
|
|
*
|
|
* Depois adicionaremos a opção
|
|
* "Somente ruas selecionadas".
|
|
*/
|
|
if (_estadoRecorte.SomenteSelecionadas && !_estadoEdicao.PossuiSelecao)
|
|
{
|
|
Log(
|
|
"[MAPA][EDICAO][RECORTE][IGNORADO] " +
|
|
"Escopo=SomenteSelecionadas | " +
|
|
"Nenhuma rua selecionada."
|
|
);
|
|
|
|
|
|
SincronizarCockpitEdicao();
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
MapaResultadoRecorte resultado =
|
|
_edicaoService
|
|
.RecortarPorPoligono(
|
|
_estadoEdicao,
|
|
pontos,
|
|
somenteSelecionadas: _estadoRecorte.SomenteSelecionadas
|
|
);
|
|
|
|
|
|
/*
|
|
* Mesmo sem alteração podemos ter
|
|
* ruas ambíguas importantes para log.
|
|
*/
|
|
if (!resultado.HouveAlteracao)
|
|
{
|
|
string tipoRecorte =
|
|
_ferramentaEdicaoAtual ==
|
|
MapaFerramentaEdicao.RecorteLivre
|
|
? "RECORTE-LIVRE"
|
|
: "RECORTE-PONTOS";
|
|
|
|
Log(
|
|
$"[MAPA][EDICAO][{tipoRecorte}] " +
|
|
$"Escopo={_estadoRecorte.Escopo} | " +
|
|
resultado
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* É alteração estrutural/geometria.
|
|
*
|
|
* Não basta atualizar estilo.
|
|
*/
|
|
RenderizarDocumentoEdicaoAtual();
|
|
|
|
|
|
SincronizarCockpitEdicao();
|
|
|
|
|
|
EstadoEdicaoAlterado?
|
|
.Invoke();
|
|
|
|
|
|
Log(
|
|
"[MAPA][EDICAO][RECORTE-LIVRE] " +
|
|
resultado
|
|
);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
/*
|
|
* O MapaEdicaoService já restaura
|
|
* o snapshot transacional em caso
|
|
* de erro.
|
|
*/
|
|
Log(
|
|
"[MAPA][EDICAO][RECORTE-LIVRE][ERRO] " +
|
|
ex.Message
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
private void OnMapaEditorDesfazerSolicitado(MapViewControl mapaControl)
|
|
{
|
|
if (
|
|
!_estadoEdicao.EmEdicao ||
|
|
!_mapasEmEdicao.Contains(
|
|
mapaControl
|
|
)
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
DesfazerEdicao();
|
|
}
|
|
|
|
|
|
private void OnMapaEditorRefazerSolicitado(MapViewControl mapaControl)
|
|
{
|
|
if (
|
|
!_estadoEdicao.EmEdicao ||
|
|
!_mapasEmEdicao.Contains(
|
|
mapaControl
|
|
)
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
RefazerEdicao();
|
|
}
|
|
|
|
|
|
private void OnMapaEditorExcluirSelecionadasSolicitado(MapViewControl mapaControl)
|
|
{
|
|
if (
|
|
!_estadoEdicao.EmEdicao ||
|
|
!_mapasEmEdicao.Contains(
|
|
mapaControl
|
|
) ||
|
|
!_estadoEdicao.PossuiSelecao
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
RemoverRuasSelecionadasEdicao();
|
|
}
|
|
|
|
|
|
private void OnMapaEditorAplicarEdicaoSolicitado(MapViewControl mapaControl)
|
|
{
|
|
if (!_estadoEdicao.EmEdicao || !_mapasEmEdicao.Contains(mapaControl))
|
|
{
|
|
return;
|
|
}
|
|
|
|
AplicarEdicao();
|
|
}
|
|
|
|
|
|
private void OnMapaEditorCancelarEdicaoSolicitado(MapViewControl mapaControl)
|
|
{
|
|
if (!_estadoEdicao.EmEdicao || !_mapasEmEdicao.Contains(mapaControl))
|
|
{
|
|
return;
|
|
}
|
|
|
|
CancelarEdicao(mapaControl);
|
|
}
|
|
|
|
|
|
private void OnMapaEditorEscopoRecorteAlterado(MapViewControl mapaControl, MapaEscopoRecorte escopo)
|
|
{
|
|
if (!_estadoEdicao.EmEdicao || !_mapasEmEdicao.Contains(mapaControl))
|
|
return;
|
|
|
|
_estadoRecorte.Escopo = escopo;
|
|
|
|
SincronizarCockpitEdicao();
|
|
|
|
|
|
Log(
|
|
"[MAPA][EDICAO][RECORTE][ESCOPO] " +
|
|
$"Atual={escopo}"
|
|
);
|
|
}
|
|
|
|
|
|
private void OnMapaEditorBordaGnssAcaoSolicitada(MapViewControl mapaControl, MapaAcaoBordaGnss acao)
|
|
{
|
|
if (
|
|
!_estadoEdicao.EmEdicao ||
|
|
!_mapasEmEdicao.Contains(mapaControl) ||
|
|
_ferramentaEdicaoAtual != MapaFerramentaEdicao.RecorteBordaGnss
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
switch (acao)
|
|
{
|
|
case MapaAcaoBordaGnss
|
|
.RegistrarPonto:
|
|
|
|
RegistrarPontoBordaGnssManual();
|
|
break;
|
|
|
|
|
|
case MapaAcaoBordaGnss
|
|
.RemoverUltimo:
|
|
|
|
RemoverUltimoPontoBordaGnss();
|
|
break;
|
|
|
|
|
|
case MapaAcaoBordaGnss
|
|
.Finalizar:
|
|
|
|
FinalizarCapturaBordaGnss();
|
|
break;
|
|
|
|
|
|
case MapaAcaoBordaGnss
|
|
.Continuar:
|
|
|
|
ContinuarCapturaBordaGnss();
|
|
break;
|
|
|
|
|
|
case MapaAcaoBordaGnss
|
|
.Descartar:
|
|
|
|
DescartarCapturaBordaGnss();
|
|
break;
|
|
|
|
|
|
case MapaAcaoBordaGnss.Aplicar:
|
|
AplicarBordaGnss();
|
|
break;
|
|
|
|
|
|
case MapaAcaoBordaGnss.DefinirModoManual:
|
|
DefinirModoCapturaBordaGnss(MapaModoCapturaGnss.Manual);
|
|
break;
|
|
|
|
|
|
case MapaAcaoBordaGnss.DefinirModoAutomatico:
|
|
DefinirModoCapturaBordaGnss(MapaModoCapturaGnss.Automatico);
|
|
break;
|
|
|
|
|
|
case MapaAcaoBordaGnss.IniciarGravacaoAutomatica:
|
|
IniciarGravacaoBordaGnssAutomatica();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
private void OnMapaEditorRestaurarFonteSolicitado(MapViewControl mapaControl)
|
|
{
|
|
if (!_estadoEdicao.EmEdicao || !_mapasEmEdicao.Contains(mapaControl))
|
|
{
|
|
return;
|
|
}
|
|
|
|
RestaurarMapaFonteEdicao();
|
|
}
|
|
|
|
|
|
}
|
|
} |