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 } }; } } }