We ended up going pretty lean on the exporter. The method we implemented is as followsprivate void Map2PDF_Click(object sender, RoutedEventArgs e)
{
/* // Don't need the ExportPDF dialog anymore
CMC_Viewer.Views.ExportPDF map2pdf = new CMC_Viewer.Views.ExportPDF();
map2pdf.SetMap(this.Map);
map2pdf.Show();
* */
// Display save-as dialog
SaveFileDialog dialog = new SaveFileDialog();
dialog.Filter = "PDF|*.pdf";
if (!dialog.ShowDialog().Value)
{
return;
}
// Create a new dynamic layer from the same map service as current tiled layer
ArcGISTiledMapServiceLayer tiled = this.Map.Layers[0] as ArcGISTiledMapServiceLayer;
ArcGISDynamicMapServiceLayer dynamic = new ArcGISDynamicMapServiceLayer()
{
Url = tiled.Url,
ImageFormat = ArcGISDynamicMapServiceLayer.RestImageFormat.JPG
};
// When the dynamic layer has initialized create the in-memory PDF document
dynamic.Initialized += (a, b) =>
{
dynamic.GetUrl(this.Map.Extent,
(int)this.Map.ActualWidth,
(int)this.Map.ActualHeight,
delegate(string url, int width, int height, Envelope extent)
{
// Download a new image of identical to what is currently displayed in the map
WebClient webClient = new WebClient();
webClient.OpenReadCompleted += (c, f) =>
{
// Use the dispatcher to force execution in the UI thread
Dispatcher.BeginInvoke(delegate()
{
// Create the PDF document, set document information properties
PdfDocument document = new PdfDocument();
document.Info.Title = "Map";
// Create a new page with the same dimensions as the browser map
PdfPage page = new PdfPage(document)
{
Height = new XUnit(this.Map.ActualHeight, XGraphicsUnit.Presentation),
Width = new XUnit(this.Map.ActualWidth, XGraphicsUnit.Presentation)
};
document.Pages.Add(page);
// Create a graphics object for writing to the page
XGraphics graphics = XGraphics.FromPdfPage(page);
// Add the map image to the page
XImage image = XImage.FromStream(f.Result);
graphics.DrawImage(image, 0d, 0d);
// Save the PDF document to the user specified filename
document.Save(dialog.OpenFile());
// Notify the user that we're done
MessageBox.Show("Map saved to '" + dialog.SafeFileName + "'");
});
};
webClient.OpenReadAsync(new Uri(url));
});
};
dynamic.Initialize();
}
We found that the size of the map to be exported has to be set better than in other examples. Anyway, the code above produces a high quality map.