image

Live Sample
Source Code

Se desejar acesse o post original em Oren Gal Post

Neste último post sobre a impressão, eu vou mostrar como eu levei as instruções de condução (parte 1, parte 2), e conseguiu reunir todos em seguida, em várias páginas. Cada DD tem seu próprio mapa e destaque dentro (com uma maior largura).
Nossa jornada começa onde terminou parte 2. Nós temos uma rota que passa entre os pontos ‘n’ e contém instruções de direção ‘m’. Todas as direções têm comprimentos, exceto o primeiro (início), o último (final) e cada ponto médio tem mais dois (chegam, partem). Nós não precisamos de mapas para estes DD então organizá-los em conjunto:

  1. private void arrange_text_direction()
  2. {
  3. string pCurText = "";
  4. for (int i = 0; i < f_glob.mGraphicRoute.Graphics.Count; i++)
  5. {
  6. Graphic g = f_glob.mGraphicRoute.Graphics[i];
  7. GraphicTag pTag = (GraphicTag)g.MapTip.Tag;
  8. string pText = pTag._address;
  9. if (pCurText != "")
  10. pCurText += "\n";
  11. if (pText.Length < 54)
  12. {
  13. pCurText += pText;
  14. }
  15. else
  16. {
  17. pCurText += pText.Substring(0, 54) + "\n";
  18. pCurText += pText.Substring(54);
  19. }
  20. if ((g.Geometry.Extent.Width > 0 && i != f_glob.mGraphicRoute.Graphics.Count – 2) || (i == f_glob.mGraphicRoute.Graphics.Count – 1))
  21. {
  22. _text_block_directions.Add(pCurText);
  23. pCurText = "";
  24. }
  25. }
  26. }

Portanto, agora temos ‘m – (n-1) * 2’ mapas para impressão. Minha idéia era fazer uma lista de tela e criar uma para cada página. Cada página vai conter um cabeçalho e seis mapas. Cada mapa vai ser uma realidade a tela de um sub e contem: mapa, rota em destaque, outras rotas, pontos, barreiras, linha de escala e, claro, o DD.

  1. public partial class cls_print : FloatableWindow
  2. {
  3. int _cur_page = -1;
  4. int _cur_dd = -1;
  5. List<Canvas> _pages = new List<Canvas>();
  6. List<string> _text_block_directions = new List<string>();
  7. public cls_print()
  8. {
  9. InitializeComponent();
  10. }
  11. public void show_me()
  12. {
  13. arrange_text_direction();
  14. _pages.Clear();
  15. _cur_dd = 0;
  16. _cur_page = 1;
  17. Boolean pContinue = true;
  18. while (pContinue)
  19. {
  20. pContinue = fill_cur_page();
  21. _cur_page++;
  22. }
  23. add_header_grids();
  24. fill_print_canvas();
  25. Show(false);
  26. }

Agora é tempo de diversão. Começamos a encher todos os mapas página à página até chegarmos seis deles. Se tivermos, quebrar e começar uma nova página. Em cada página, adicionar um mapa, em seguida, definir o grau de acordo com a parte de rotas, em seguida, adicionar peças gráficas – pontos, barreiras e linha de escala. No final, adicione o DD no topo do mapa em uma fronteira com textblock.

  1. private Boolean fill_cur_page()
  2. {
  3. Boolean pReturnValue = true;
  4. Canvas pPageCanvas = new Canvas();
  5. int pMapsInPage = 0;
  6. while (pMapsInPage < 6)
  7. {
  8. if (_cur_dd == f_glob.mGraphicRoute.Graphics.Count)
  9. {
  10. pReturnValue = false;
  11. break;
  12. }
  13. Polyline pPolyline = (Polyline)f_glob.mGraphicRoute.Graphics[_cur_dd].Geometry;
  14. if (pPolyline.Extent.Width > 0)
  15. {
  16. Envelope pEnv = pPolyline.Extent.Expand(1.25);
  17. if (pEnv.Width < 300)
  18. pEnv = new Envelope(pEnv.XMin – 150, pEnv.YMin – 150, pEnv.XMax + 150, pEnv.YMax + 150);
  19. Canvas pMapCanvas = new Canvas() { Width = 330, Height = 330 };
  20. Map pMap = new Map() { Width = 330, Height = 330 };
  21. ArcGISTiledMapServiceLayer pTiled = new ArcGISTiledMapServiceLayer();
  22. pTiled.Url = ((ArcGISTiledMapServiceLayer)f_glob.mMap.Layers[0]).Url;
  23. pTiled.Initialize();
  24. pMap.Layers.Add(pTiled);
  25. pMap.Extent = pEnv;
  26. pMap.IsHitTestVisible = false;
  27. pMap.IsLogoVisible = false;
  28. pMap.BorderBrush = new SolidColorBrush(Colors.Red);
  29. pMap.BorderThickness = new Thickness(3);
  30. GraphicsLayer pGraphicsLayer = new GraphicsLayer();
  31. foreach (Graphic g in f_glob.mGraphicRoute.Graphics)
  32. {
  33. if (g == f_glob.mGraphicRoute.Graphics[_cur_dd])
  34. {
  35. Graphic g1 = new Graphic() { Symbol = new DashedLineSymbol(Colors.Blue, 5), Geometry = pPolyline };
  36. pGraphicsLayer.Graphics.Add(g1);
  37. }
  38. else
  39. {
  40. Graphic g1 = new Graphic() { Symbol = new DashedLineSymbol(Colors.Blue, 1), Geometry = g.Geometry };
  41. pGraphicsLayer.Graphics.Add(g1);
  42. }
  43. }
  44. foreach (Graphic g in f_glob.mGraphicsPushpins.Graphics)
  45. {
  46. Graphic g1 = new Graphic() { Symbol = new Pushpinsymbol(f_glob.mGraphicsPushpins.Graphics.IndexOf(g) + 1), Geometry = g.Geometry };
  47. pGraphicsLayer.Graphics.Add(g1);
  48. }
  49. foreach (Graphic g in f_glob.mGraphicsBarriers.Graphics)
  50. {
  51. Graphic g1 = new Graphic() { Symbol = new BarrierSymbol(), Geometry = g.Geometry };
  52. pGraphicsLayer.Graphics.Add(g1);
  53. }
  54. pMap.Layers.Add(pGraphicsLayer);
  55. pMapCanvas.Children.Add(pMap);
  56. ScaleLine pScaleLine = new ScaleLine()
  57. {
  58. Margin = new Thickness(10, 290, 10, 10),
  59. Map = pMap
  60. };
  61. pMapCanvas.Children.Add(pScaleLine);
  62. TextBlock pDirectionBlock = new TextBlock() { Width = 318 };
  63. pDirectionBlock.Text = _text_block_directions[0]; ;
  64. pDirectionBlock.Margin = new Thickness(3, 3, 3, 3);
  65. pDirectionBlock.Foreground = new SolidColorBrush(Colors.Black);
  66. pDirectionBlock.FontWeight = FontWeights.Bold;
  67. pDirectionBlock.FontSize = 10;
  68. _text_block_directions.RemoveAt(0);
  69. Border pBorder = new Border() { Background = new SolidColorBrush(Colors.Yellow) };
  70. pBorder.Margin = new Thickness(3, 3, 3, 3);
  71. pBorder.Child = pDirectionBlock;
  72. pBorder.Opacity = 0.6;
  73. pMapCanvas.Children.Add(pBorder);
  74. pMapsInPage++;
  75. if (pMapsInPage == 1) pMapCanvas.Margin = new Thickness(30, 50, 0, 0);
  76. if (pMapsInPage == 2) pMapCanvas.Margin = new Thickness(30, 414, 0, 0);
  77. if (pMapsInPage == 3) pMapCanvas.Margin = new Thickness(30, 768, 0, 0);
  78. if (pMapsInPage == 4) pMapCanvas.Margin = new Thickness(430, 50, 0, 0);
  79. if (pMapsInPage == 5) pMapCanvas.Margin = new Thickness(430, 414, 0, 0);
  80. if (pMapsInPage == 6) pMapCanvas.Margin = new Thickness(430, 768, 0, 0);
  81. pPageCanvas.Children.Add(pMapCanvas);
  82. }
  83. _cur_dd++;
  84. }
  85. if (pMapsInPage > 0)
  86. {
  87. ScaleTransform pScaleTransform = new ScaleTransform();
  88. pScaleTransform.ScaleX = 0.4;
  89. pScaleTransform.ScaleY = 0.4;
  90. pPageCanvas.RenderTransform = pScaleTransform;
  91. _pages.Add(pPageCanvas);
  92. }
  93. return pReturnValue;
  94. }

O passo final é adicionar cabeçalho para cada página:

  1. private void add_header_grids()
  2. {
  3. for (int i = 0; i < _pages.Count; i++)
  4. {
  5. Grid pHeaderGrid = new Grid() { Width = 793, Height = 71 };
  6. TextBlock pHeaderTitle = new TextBlock()
  7. {
  8. Text = "Driving Directions",
  9. HorizontalAlignment = HorizontalAlignment.Left,
  10. VerticalAlignment = VerticalAlignment.Top,
  11. Margin = new Thickness(30, 10, 0, 0),
  12. FontSize = 24.0,
  13. Height = 30.0,
  14. Foreground = new SolidColorBrush(Colors.Blue)
  15. };
  16. pHeaderGrid.Children.Add(pHeaderTitle);
  17. TextBlock pHeaderPageCounter = new TextBlock()
  18. {
  19. Text = string.Concat("Page ", i + 1, " of ", _pages.Count),
  20. HorizontalAlignment = HorizontalAlignment.Right,
  21. VerticalAlignment = VerticalAlignment.Top,
  22. Margin = new Thickness(0, 10, 40, 0),
  23. FontSize = 19.0,
  24. Height = 25.0,
  25. Foreground = new SolidColorBrush(Colors.Blue)
  26. };
  27. pHeaderGrid.Children.Add(pHeaderPageCounter);
  28. _pages[i].Children.Insert(0, pHeaderGrid);
  29. }
  30. }

Certo. Todas as páginas estão cheias de mapas e dados. Estamos prontos para impressão. Agora é tempo para uma pré-visualização. A idéia aqui é colocar todas as páginas em uma grande pilha em cima do outro. Todos receberão opacidade 0,0, exceto o que nós escolhemos e ele vai ficar 1.0.

  1. private void fill_print_canvas()
  2. {
  3. m_canvas_print.Children.Clear();
  4. for (int i = 1; i <= _pages.Count; i++)
  5. {
  6. Canvas pPageCanvas = _pages[i – 1];
  7. m_canvas_print.Children.Add(pPageCanvas);
  8. }
  9. m_btn_next_page_Click(null, null);
  10. }
  11. private void m_btn_next_page_Click(object sender, RoutedEventArgs e)
  12. {
  13. if (sender == null)
  14. _cur_page = 1;
  15. else
  16. if (_cur_page < _pages.Count)
  17. _cur_page++;
  18. for (int i = 1; i <= _pages.Count; i++)
  19. {
  20. Canvas pPageCanvas = _pages[i – 1];
  21. pPageCanvas.Opacity = (_cur_page == i ? 1.0 : 0.0);
  22. }
  23. Title = "Page " + _cur_page + " of " + _pages.Count;
  24. }
  25. private void m_btn_prev_page_Click(object sender, RoutedEventArgs e)
  26. {
  27. if (sender == null)
  28. _cur_page = 1;
  29. else
  30. if (_cur_page > 1)
  31. _cur_page–;
  32. for (int i = 1; i <= _pages.Count; i++)
  33. {
  34. Canvas pPageCanvas = _pages[i – 1];
  35. pPageCanvas.Opacity = (_cur_page == i ? 1.0 : 0.0);
  36. }
  37. Title = "Page " + _cur_page + " of " + _pages.Count;
  38. }
  39. private void m_btn_print_Click(object sender, RoutedEventArgs e)
  40. {
  41. _cur_page = 1;
  42. PrintDocument pPrintDocument = new PrintDocument();
  43. pPrintDocument.PrintPage += new EventHandler<PrintPageEventArgs>(pPrintDocument_PrintPage);
  44. pPrintDocument.Print("Driving Directions");
  45. this.Visibility = Visibility.Collapsed;
  46. }
  47. void pPrintDocument_PrintPage(object sender, PrintPageEventArgs e)
  48. {
  49. if (_cur_page > _pages.Count)
  50. {
  51. PrintDocument pPrintDocument = (PrintDocument)sender;
  52. pPrintDocument.PrintPage -= new EventHandler<PrintPageEventArgs>(pPrintDocument_PrintPage);
  53. return;
  54. }
  55. ScaleTransform scaleTransform = new ScaleTransform();
  56. scaleTransform.ScaleX = 1;
  57. scaleTransform.ScaleY = 1;
  58. _pages[_cur_page – 1].RenderTransform = scaleTransform;
  59. _pages[_cur_page – 1].Opacity = 1.0;
  60. e.PageVisual = _pages[_cur_page – 1];
  61. e.HasMorePages = (_cur_page < _pages.Count);
  62. _cur_page++;
  63. }

Qualquer dúvida deixe um comentários, espero que essa sequencia de post tenha mostrado pra você como podemos usar Silverlight para Geolocalização, tudo de bom e até a próxima.

#Silverlight pra dentro da cabeça. Não deixe de me seguir no Twitter.

Washington Azevedo | Consultor em Arquitetura/Desenvolvimento RIA

clip_image0044clip_image0064clip_image0084