using Mapsui;
using Mapsui.Layers;
using Mapsui.Nts;
using Mapsui.Styles;
using NetTopologySuite.Geometries;
using OperationControl.Mapas.Models;
using Brush = Mapsui.Styles.Brush;
using Color = Mapsui.Styles.Color;
using Font = Mapsui.Styles.Font;
using Pen = Mapsui.Styles.Pen;
namespace OperationControl.Mapas.Rendering
{
///
/// Representação visual da rota manual de retorno.
///
/// Não possui estado operacional.
/// A fonte da verdade continua sendo MapaRotaRetorno.
///
public sealed class MapaRotaRetornoRenderService
{
public const string NomeCamada =
"MapaRotaRetornoNovo";
public MemoryLayer CriarCamada(
MapaRotaRetorno rota)
{
if (rota == null)
{
throw new ArgumentNullException(
nameof(rota)
);
}
return new MemoryLayer
{
Name = NomeCamada,
Features = CriarFeatures(rota)
};
}
public void AtualizarCamada(
MemoryLayer camada,
MapaRotaRetorno rota)
{
if (camada == null)
{
throw new ArgumentNullException(
nameof(camada)
);
}
if (rota == null)
{
throw new ArgumentNullException(
nameof(rota)
);
}
camada.Features =
CriarFeatures(
rota
);
}
private static IEnumerable
CriarFeatures(
MapaRotaRetorno rota)
{
var features =
new List();
/*
* Primeiro desenhamos a linha da rota.
*
* A linha só existe visualmente.
* O domínio continua sendo apenas a sequência
* de MapaPontoRetorno.
*/
if (rota.Pontos.Count >= 2)
{
var coordenadas =
rota.Pontos
.Select(
ponto =>
{
var mercator =
Mapsui.Projections
.SphericalMercator
.FromLonLat(
ponto.Longitude,
ponto.Latitude
);
return new Coordinate(
mercator.x,
mercator.y
);
}
)
.ToArray();
var linha =
new LineString(
coordenadas
);
var featureLinha =
new GeometryFeature
{
Geometry = linha
};
featureLinha["Tipo"] =
"RotaRetorno";
featureLinha.Styles.Add(
CriarEstiloLinha()
);
features.Add(
featureLinha
);
}
/*
* Depois entram os pontos numerados.
*
* Como são adicionados depois da linha,
* ficam visualmente por cima dela.
*/
for (
int i = 0;
i < rota.Pontos.Count;
i++)
{
MapaPontoRetorno ponto =
rota.Pontos[i];
var mercator =
Mapsui.Projections
.SphericalMercator
.FromLonLat(
ponto.Longitude,
ponto.Latitude
);
var feature =
new PointFeature(
mercator.x,
mercator.y
);
feature["Tipo"] =
"PontoRetorno";
feature["Ordem"] =
i + 1;
feature["label"] =
(i + 1).ToString();
feature.Styles.Add(
CriarEstiloPonto()
);
feature.Styles.Add(
CriarEstiloLabel()
);
features.Add(
feature
);
}
return features;
}
private static VectorStyle
CriarEstiloLinha()
{
return new VectorStyle
{
Line =
new Pen(
Color.Red,
3
)
};
}
private static SymbolStyle
CriarEstiloPonto()
{
return new SymbolStyle
{
SymbolType =
SymbolType.Ellipse,
SymbolScale =
1.2,
Fill =
new Brush(
Color.Red
),
Outline =
new Pen(
Color.White,
2
)
};
}
private static LabelStyle
CriarEstiloLabel()
{
return new LabelStyle
{
LabelColumn =
"label",
ForeColor =
Color.White,
BackColor =
null,
HorizontalAlignment =
LabelStyle
.HorizontalAlignmentEnum
.Center,
VerticalAlignment =
LabelStyle
.VerticalAlignmentEnum
.Center,
Offset =
new Offset(
0,
0
),
Font =
new Font
{
Size = 12
}
};
}
}
}