agrobot_base/AgroBase/OperationControl/Mapas/Rendering/MapaCriacaoRenderService.cs

413 lines
11 KiB
C#

using Mapsui;
using Mapsui.Layers;
using Mapsui.Nts;
using Mapsui.Projections;
using Mapsui.Styles;
using NetTopologySuite.Geometries;
using OperationControl.Mapas.Creation;
using Brush = Mapsui.Styles.Brush;
using Color = Mapsui.Styles.Color;
using Font = Mapsui.Styles.Font;
using Pen = Mapsui.Styles.Pen;
namespace OperationControl.Mapas.Rendering
{
/// <summary>
/// Preview georreferenciado do mapa ainda em levantamento.
///
/// Regras visuais:
/// - ruas concluídas: verde;
/// - rua atual: ciano e mais espessa;
/// - pontos da rua atual: marcadores numerados;
/// - primeira posição de cada rua: etiqueta R1, R2...
///
/// Nada aqui altera o MapaWorkspace.
/// </summary>
public sealed class MapaCriacaoRenderService
{
public const string NomeCamada =
"MapaCriacaoPreview";
public MemoryLayer CriarCamada(
MapaEstadoCriacao estado)
{
if (estado == null)
{
throw new ArgumentNullException(
nameof(estado)
);
}
return new MemoryLayer
{
Name =
NomeCamada,
Features =
CriarFeatures(
estado
)
};
}
public void AtualizarCamada(
MemoryLayer camada,
MapaEstadoCriacao estado)
{
if (camada == null)
{
throw new ArgumentNullException(
nameof(camada)
);
}
if (estado == null)
{
throw new ArgumentNullException(
nameof(estado)
);
}
camada.Features =
CriarFeatures(
estado
);
}
private static IEnumerable<IFeature>
CriarFeatures(
MapaEstadoCriacao estado)
{
var features =
new List<IFeature>();
if (!estado.EmCriacao)
{
return features;
}
for (
int indiceRua = 0;
indiceRua < estado.Ruas.Count;
indiceRua++
)
{
MapaRuaCriacao rua =
estado.Ruas[indiceRua];
if (
rua == null ||
rua.Pontos.Count == 0
)
{
continue;
}
bool atual =
indiceRua ==
estado.IndiceRuaAtual;
Color corLinha =
atual
? new Color(
0,
210,
255,
255
)
: new Color(
95,
207,
128,
255
);
/*
* LINHA DA RUA
*/
if (
rua.Pontos.Count >= 2
)
{
Coordinate[] coordenadas =
rua
.Pontos
.Select(
ponto =>
{
var mercator =
SphericalMercator
.FromLonLat(
ponto.Longitude,
ponto.Latitude
);
return new Coordinate(
mercator.x,
mercator.y
);
}
)
.ToArray();
var featureLinha =
new GeometryFeature
{
Geometry =
new LineString(
coordenadas
)
};
featureLinha["Tipo"] =
"MapaCriacaoRua";
featureLinha["Rua"] =
rua.Numero;
featureLinha.Styles.Add(
new VectorStyle
{
Line =
new Pen(
corLinha,
atual ? 5 : 3
)
}
);
features.Add(
featureLinha
);
}
/*
* MARCADOR DO INÍCIO DA RUA
*/
MapaPontoCriacao primeiro =
rua.Pontos[0];
var inicioMercator =
SphericalMercator
.FromLonLat(
primeiro.Longitude,
primeiro.Latitude
);
var marcadorRua =
new PointFeature(
inicioMercator.x,
inicioMercator.y
);
marcadorRua["Tipo"] =
"MapaCriacaoInicioRua";
marcadorRua["label"] =
$"R{rua.Numero}";
marcadorRua.Styles.Add(
new SymbolStyle
{
SymbolType =
SymbolType.Ellipse,
SymbolScale =
atual
? 1.25
: 1.0,
Fill =
new Brush(
corLinha
),
Outline =
new Pen(
Color.White,
2
)
}
);
marcadorRua.Styles.Add(
new LabelStyle
{
LabelColumn =
"label",
ForeColor =
Color.White,
BackColor =
null,
HorizontalAlignment =
LabelStyle
.HorizontalAlignmentEnum
.Center,
VerticalAlignment =
LabelStyle
.VerticalAlignmentEnum
.Center,
Font =
new Font
{
Size = 10
}
}
);
features.Add(
marcadorRua
);
/*
* PONTOS DA RUA ATUAL
*
* Nas ruas concluídas evitamos centenas de marcadores
* para manter o mapa limpo e leve.
*/
if (!atual)
{
continue;
}
for (
int indicePonto = 0;
indicePonto < rua.Pontos.Count;
indicePonto++
)
{
MapaPontoCriacao ponto =
rua.Pontos[indicePonto];
var mercator =
SphericalMercator
.FromLonLat(
ponto.Longitude,
ponto.Latitude
);
var featurePonto =
new PointFeature(
mercator.x,
mercator.y
);
featurePonto["Tipo"] =
"MapaCriacaoPonto";
featurePonto["Rua"] =
rua.Numero;
featurePonto["Ordem"] =
indicePonto + 1;
featurePonto["label"] =
(indicePonto + 1)
.ToString();
featurePonto.Styles.Add(
new SymbolStyle
{
SymbolType =
SymbolType.Ellipse,
SymbolScale =
0.95,
Fill =
new Brush(
new Color(
0,
210,
255,
255
)
),
Outline =
new Pen(
Color.White,
2
)
}
);
featurePonto.Styles.Add(
new LabelStyle
{
LabelColumn =
"label",
ForeColor =
Color.White,
BackColor =
null,
HorizontalAlignment =
LabelStyle
.HorizontalAlignmentEnum
.Center,
VerticalAlignment =
LabelStyle
.VerticalAlignmentEnum
.Center,
Font =
new Font
{
Size = 9
}
}
);
features.Add(
featurePonto
);
}
}
return features;
}
}
}