How to print a map?

Within this forum we want to offer discussions all around our .NET based Map control including all .Net-language specific questions concerning calls of the xServer-API. Attention: xServer-relevant concepts can be found in further forums such as xRoute or xTour.
Post Reply
User avatar
Bernd Welter
Site Admin
Posts: 2695
Joined: Mon Apr 14, 2014 10:28 am
Contact:

How to print a map?

Post by Bernd Welter »

Hi there,

a customer asked me how to print a map without displaying it in his user frontend.
At least for xServer.NET I found a method to create a print.

Code: Select all

private void btnPrintToursResponse_Map_Click(object sender, EventArgs e)
{
      map.PrintMap(true, "My first Map");
}
But can I get a proper description from a more generic perspective? In the past I was able to create "Image from Stream" based on MemoryStreams and all business data such as icons, lines and areas have already been part of the "mapping request".

Nowadays everyone uses rest services to create interactive mapping frontends:
  • more than just a single image is requested
  • all business data is rendered on top through the mapping framework
But how to "render" the images in memory based approaches?

Bernd
Attachments
MyFirstMap.pdf
Printed via xServer.NET / C#. The regular "print to pdf" dialogue was triggered and produced this PDF.
(928.98 KiB) Downloaded 280 times
Bernd Welter
Technical Partner Manager Developer Components
PTV Logistics - Germany

Bernd at... The Forum,LinkedIn, Youtube, StackOverflow
I like the smell of PTV Developer in the morning... :twisted:
User avatar
Bernd Welter
Site Admin
Posts: 2695
Joined: Mon Apr 14, 2014 10:28 am
Contact:

Re: How to print a map?

Post by Bernd Welter »

Here's some sample code from my guru Oliver - it is based on xServer.NET and you can use it both for
  • PTV Developer - in this case ensure to provide a valid API key in line 37.
  • XMap2 (I went for a local url)
What is also important to be aware of:
:!: Oliver did choose a specific initialization sequence. Keep it!
:!: WIth this approach the application needs to be "[StaThread]" (whatever that means ;-))

Best regards and many thanks to Oliver.

Code: Select all

using Ptv.XServer.Controls.Map;
using Ptv.XServer.Controls.Map.Layers.Shapes;
using Ptv.XServer.Controls.Map.Layers.Tiled;
using Ptv.XServer.Controls.Map.Symbols;
using Ptv.XServer.Controls.Map.TileProviders;
using Ptv.XServer.Controls.Map.Tools;
using System;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace GenerateMap
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Point location = new Point(8.403951, 49.00921);

            var mapView = new MapView();
            mapView.Name = "Map";
            var p = GeoTransform.WGSToPtvMercator(location);
            mapView.SetXYZ(p.X, p.Y, 12, false);
            mapView.Printing = true;
            var sz = new Size(600, 400);

            var apiKey = Properties.Settings.Default.DeveloperApiKey;
            var basel = new TiledLayer("Road")
            {
                TiledProvider = new RemoteTiledProvider
                {
                    MinZoom = 0,
                    MaxZoom = 22,
                    RequestBuilderDelegate = (x, y, z) =>
                       $"https://api.myptv.com/rastermaps/v1/image-tiles/{z}/{x}/{y}?style=silkysand&apiKey={apiKey}",
                    //$"http://127.0.0.1:50000/services/rest/XMap/tile/{z}/{x}/{y}",
                },
                IsBaseMapLayer = true,
            };

            var pin = new Pin
            {
                Color = Colors.Green,
                Width = 40,
                Height = 40,
            };

            ShapeCanvas.SetAnchor(pin, LocationAnchor.RightBottom);
            ShapeCanvas.SetLocation(pin, location);

            var myLayer = new ShapeLayer("MyLayer");
            myLayer.Shapes.Add(pin);

            basel.AddToMapView(mapView);
            myLayer.AddToMapView(mapView);

            mapView.Measure(sz);
            mapView.Arrange(new Rect(new Point(0, 0), sz));
            mapView.UpdateLayout();

            var renderTargetBitmap = new RenderTargetBitmap((int)sz.Width, (int)sz.Height, 96d, 96d, PixelFormats.Default);
            renderTargetBitmap.Render(mapView);

            var jpegBitmapEncoder = new JpegBitmapEncoder();
            jpegBitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));

            var ms = new MemoryStream();
            jpegBitmapEncoder.Save(ms);
            ms.Close();
            var bytes = ms.ToArray();

            var fileName = Path.GetTempPath() + "\\Img" + Guid.NewGuid() + ".jpg";

            File.WriteAllBytes(fileName, bytes);

            // open the image
            System.Diagnostics.Process.Start(fileName);
        }
    }
}
Bernd Welter
Technical Partner Manager Developer Components
PTV Logistics - Germany

Bernd at... The Forum,LinkedIn, Youtube, StackOverflow
I like the smell of PTV Developer in the morning... :twisted:
Post Reply