agrobot_base/AgroBase/OperationControl/Mapas/Services/MapaEntidadeDinamicaService.cs

419 lines
9.2 KiB
C#

using OperationControl.Mapas.Models;
using static AgroBase.Models.Enums;
namespace OperationControl.Mapas.Services
{
public sealed class MapaEntidadeDinamicaService
{
public MapaEntidadeDinamica DefinirBase(
MapaEstadoDinamico estado,
string id,
string nome,
double? latitude,
double? longitude,
double? heading = null,
double? latitudeBruta = null,
double? longitudeBruta = null)
{
return DefinirEntidade(
estado,
id,
MapaTipoEntidadeDinamica.Base,
nome,
latitude,
longitude,
heading,
latitudeBruta,
longitudeBruta
);
}
public MapaEntidadeDinamica DefinirRover(
MapaEstadoDinamico estado,
string id,
string nome,
double? latitude,
double? longitude,
double? heading = null,
double? latitudeBruta = null,
double? longitudeBruta = null)
{
return DefinirEntidade(
estado,
id,
MapaTipoEntidadeDinamica.Rover,
nome,
latitude,
longitude,
heading,
latitudeBruta,
longitudeBruta
);
}
public void AtualizarPosicao(
MapaEstadoDinamico estado,
string id,
double? latitude,
double? longitude,
double? heading = null,
double? latitudeBruta = null,
double? longitudeBruta = null)
{
var entidade =
ObterObrigatoria(
estado,
id
);
if (
latitude.HasValue &&
longitude.HasValue
)
{
ValidarCoordenada(
latitude.Value,
longitude.Value
);
entidade.Latitude =
latitude.Value;
entidade.Longitude =
longitude.Value;
}
if (
heading.HasValue &&
double.IsFinite(
heading.Value
)
)
{
entidade.Heading =
NormalizarHeading(
heading.Value
);
}
if (
latitudeBruta.HasValue &&
longitudeBruta.HasValue
)
{
ValidarCoordenada(
latitudeBruta.Value,
longitudeBruta.Value
);
entidade.LatitudeBruta =
latitudeBruta.Value;
entidade.LongitudeBruta =
longitudeBruta.Value;
}
}
public void AtualizarStatus(
MapaEstadoDinamico estado,
string id,
StatusOperacao status,
bool? pulverizando = null)
{
var entidade =
ObterObrigatoria(
estado,
id
);
entidade.Status =
status;
if (pulverizando.HasValue)
{
entidade.Pulverizando =
pulverizando.Value;
}
}
public void DefinirFoco(
MapaEstadoDinamico estado,
string? id)
{
ValidarEstado(
estado
);
foreach (
var entidade
in estado.EntidadesMutaveis.Values)
{
entidade.EmFoco =
false;
}
if (
string.IsNullOrWhiteSpace(id)
)
{
return;
}
if (
estado.EntidadesMutaveis.TryGetValue(
id.Trim(),
out var selecionada
)
)
{
selecionada.EmFoco =
true;
}
}
public MapaEntidadeDinamica?
Obter(
MapaEstadoDinamico estado,
string id)
{
ValidarEstado(
estado
);
if (
string.IsNullOrWhiteSpace(id)
)
{
return null;
}
estado.EntidadesMutaveis
.TryGetValue(
id.Trim(),
out var entidade
);
return entidade;
}
public bool Remover(
MapaEstadoDinamico estado,
string id)
{
ValidarEstado(
estado
);
if (
string.IsNullOrWhiteSpace(id)
)
{
return false;
}
return estado
.EntidadesMutaveis
.Remove(
id.Trim()
);
}
private MapaEntidadeDinamica
DefinirEntidade(
MapaEstadoDinamico estado,
string id,
MapaTipoEntidadeDinamica tipo,
string nome,
double? latitude,
double? longitude,
double? heading,
double? latitudeBruta,
double? longitudeBruta)
{
ValidarEstado(
estado
);
if (
string.IsNullOrWhiteSpace(id)
)
{
throw new ArgumentException(
"O ID da entidade não foi informado.",
nameof(id)
);
}
string idCanonico =
id.Trim();
if (
!estado.EntidadesMutaveis
.TryGetValue(
idCanonico,
out var entidade
)
)
{
entidade =
new MapaEntidadeDinamica
{
Id =
idCanonico
};
estado.EntidadesMutaveis[
idCanonico
] =
entidade;
}
entidade.Tipo =
tipo;
entidade.Nome =
string.IsNullOrWhiteSpace(nome)
? idCanonico
: nome.Trim();
AtualizarPosicao(
estado,
idCanonico,
latitude,
longitude,
heading,
latitudeBruta,
longitudeBruta
);
return entidade;
}
private static MapaEntidadeDinamica
ObterObrigatoria(
MapaEstadoDinamico estado,
string id)
{
ValidarEstado(
estado
);
if (
string.IsNullOrWhiteSpace(id)
)
{
throw new ArgumentException(
"O ID da entidade não foi informado.",
nameof(id)
);
}
if (
!estado.EntidadesMutaveis
.TryGetValue(
id.Trim(),
out var entidade
)
)
{
throw new InvalidOperationException(
$"A entidade '{id}' não existe."
);
}
return entidade;
}
private static void ValidarCoordenada(
double latitude,
double longitude)
{
if (
!double.IsFinite(latitude) ||
latitude < -90.0 ||
latitude > 90.0
)
{
throw new ArgumentOutOfRangeException(
nameof(latitude),
"Latitude WGS84 inválida."
);
}
if (
!double.IsFinite(longitude) ||
longitude < -180.0 ||
longitude > 180.0
)
{
throw new ArgumentOutOfRangeException(
nameof(longitude),
"Longitude WGS84 inválida."
);
}
}
private static double NormalizarHeading(
double heading)
{
double normalizado =
heading % 360.0;
if (normalizado < 0)
{
normalizado +=
360.0;
}
return normalizado;
}
private static void ValidarEstado(
MapaEstadoDinamico estado)
{
if (estado == null)
{
throw new ArgumentNullException(
nameof(estado)
);
}
}
}
}