287 lines
7.0 KiB
C#
287 lines
7.0 KiB
C#
using Mapsui;
|
|
using Mapsui.Layers;
|
|
using Mapsui.Nts;
|
|
using Mapsui.Projections;
|
|
using Mapsui.Styles;
|
|
using NetTopologySuite.Geometries;
|
|
using OperationControl.Mapas.Models;
|
|
using Color = Mapsui.Styles.Color;
|
|
using Pen = Mapsui.Styles.Pen;
|
|
|
|
namespace OperationControl.Mapas.Rendering
|
|
{
|
|
public sealed class MapaRastroRenderService
|
|
{
|
|
public const string NomeCamada =
|
|
"MapaRastroNovo";
|
|
|
|
|
|
/*
|
|
* Mesma ideia da paleta do legado:
|
|
* cada RoverId recebe uma cor estável.
|
|
*
|
|
* A cor é responsabilidade de render,
|
|
* portanto não precisa entrar no domínio.
|
|
*/
|
|
private static readonly Color[] Paleta =
|
|
{
|
|
new Color(0, 191, 255, 255), // DeepSkyBlue
|
|
new Color(50, 205, 50, 255), // LimeGreen
|
|
new Color(255, 215, 0, 255), // Gold
|
|
new Color(255, 165, 0, 255), // Orange
|
|
new Color(147, 112, 219, 255), // MediumPurple
|
|
new Color(0, 255, 255, 255), // Cyan
|
|
new Color(255, 0, 255, 255), // Magenta
|
|
new Color(0, 255, 127, 255), // SpringGreen
|
|
new Color(255, 127, 80, 255), // Coral
|
|
new Color(255, 255, 0, 255) // Yellow
|
|
};
|
|
|
|
|
|
public MemoryLayer CriarCamada(
|
|
MapaEstadoMovimento estado)
|
|
{
|
|
if (estado == null)
|
|
{
|
|
throw new ArgumentNullException(
|
|
nameof(estado)
|
|
);
|
|
}
|
|
|
|
|
|
return new MemoryLayer
|
|
{
|
|
Name = NomeCamada,
|
|
Features = CriarFeatures(
|
|
estado
|
|
),
|
|
Style = null
|
|
};
|
|
}
|
|
|
|
|
|
public void AtualizarCamada(
|
|
MemoryLayer camada,
|
|
MapaEstadoMovimento estado)
|
|
{
|
|
if (camada == null)
|
|
{
|
|
throw new ArgumentNullException(
|
|
nameof(camada)
|
|
);
|
|
}
|
|
|
|
if (estado == null)
|
|
{
|
|
throw new ArgumentNullException(
|
|
nameof(estado)
|
|
);
|
|
}
|
|
|
|
|
|
camada.Features =
|
|
CriarFeatures(
|
|
estado
|
|
);
|
|
}
|
|
|
|
|
|
private static List<IFeature>
|
|
CriarFeatures(
|
|
MapaEstadoMovimento estado)
|
|
{
|
|
var features =
|
|
new List<IFeature>();
|
|
|
|
|
|
foreach (
|
|
var movimento
|
|
in estado.Rovers)
|
|
{
|
|
Color corRover =
|
|
ObterCorRover(
|
|
movimento.RoverId
|
|
);
|
|
|
|
|
|
foreach (
|
|
var trecho
|
|
in movimento.Trechos)
|
|
{
|
|
if (
|
|
trecho == null ||
|
|
trecho.Pontos.Count < 2
|
|
)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
|
|
var coordenadas =
|
|
new List<Coordinate>();
|
|
|
|
|
|
foreach (
|
|
var ponto
|
|
in trecho.Pontos)
|
|
{
|
|
var mercator =
|
|
SphericalMercator
|
|
.FromLonLat(
|
|
ponto.Longitude,
|
|
ponto.Latitude
|
|
);
|
|
|
|
|
|
coordenadas.Add(
|
|
new Coordinate(
|
|
mercator.x,
|
|
mercator.y
|
|
)
|
|
);
|
|
}
|
|
|
|
|
|
if (
|
|
coordenadas.Count < 2
|
|
)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
|
|
var feature =
|
|
new GeometryFeature
|
|
{
|
|
Geometry =
|
|
new LineString(
|
|
coordenadas
|
|
.ToArray()
|
|
)
|
|
};
|
|
|
|
|
|
feature["RoverId"] =
|
|
movimento.RoverId;
|
|
|
|
feature["Tipo"] =
|
|
"Rastro";
|
|
|
|
feature["Pulverizando"] =
|
|
trecho.Pulverizando
|
|
? "1"
|
|
: "0";
|
|
|
|
|
|
feature.Styles.Add(
|
|
CriarEstilo(
|
|
corRover,
|
|
trecho.Pulverizando
|
|
)
|
|
);
|
|
|
|
|
|
features.Add(
|
|
feature
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
return features;
|
|
}
|
|
|
|
|
|
private static VectorStyle CriarEstilo(
|
|
Color cor,
|
|
bool pulverizando)
|
|
{
|
|
/*
|
|
* Mantemos a semântica visual do legado:
|
|
*
|
|
* normal:
|
|
* mais transparente e fino
|
|
*
|
|
* pulverizando:
|
|
* opaco e mais grosso
|
|
*/
|
|
Color corLinha =
|
|
pulverizando
|
|
? new Color(
|
|
cor.R,
|
|
cor.G,
|
|
cor.B,
|
|
255
|
|
)
|
|
: new Color(
|
|
cor.R,
|
|
cor.G,
|
|
cor.B,
|
|
180
|
|
);
|
|
|
|
|
|
return new VectorStyle
|
|
{
|
|
Line =
|
|
new Pen(
|
|
corLinha,
|
|
pulverizando
|
|
? 4
|
|
: 2
|
|
)
|
|
};
|
|
}
|
|
|
|
|
|
private static Color ObterCorRover(
|
|
string roverId)
|
|
{
|
|
if (
|
|
string.IsNullOrWhiteSpace(
|
|
roverId
|
|
)
|
|
)
|
|
{
|
|
return Paleta[0];
|
|
}
|
|
|
|
|
|
/*
|
|
* Hash determinístico.
|
|
*
|
|
* Não usamos string.GetHashCode()
|
|
* porque ele não precisa ser estável
|
|
* entre execuções do processo.
|
|
*/
|
|
uint hash =
|
|
2166136261;
|
|
|
|
|
|
foreach (
|
|
char caractere
|
|
in roverId
|
|
.Trim()
|
|
.ToUpperInvariant())
|
|
{
|
|
unchecked
|
|
{
|
|
hash ^= caractere;
|
|
hash *= 16777619;
|
|
}
|
|
}
|
|
|
|
|
|
int indice =
|
|
(int)(
|
|
hash %
|
|
(uint)Paleta.Length
|
|
);
|
|
|
|
|
|
return Paleta[
|
|
indice
|
|
];
|
|
}
|
|
}
|
|
} |