Exporting Maps for Printing in the Digital Maps Era

Summary

This post may describe functionality for an old version of CARTO. Find out about the latest and cloud-native version here.
Exporting Maps for Printing in the Digital Maps Era

You have probably heard about Microsoft's work this past year  in training a neural network to polygonize satellite imagery into building footprints. This work resulted in a 125M polygon dataset released as Open Data which increased by a factor of four  the coverage of building footprints in OpenStreetMap  and thus in the CARTO basemaps as well.

Today we are using this 125M polygon dataset for a very different use case. In this blog post we are going to dive deep (not too deep) into the technical workflow of using CARTO to convert a bunch of US buildings coordinates in a text file into a printable map of any US city.

We are covering three different stages on this developer journey of exporting maps for printing in the digital maps era:

  1. Data Ingestion
  2. Map Visualization and Styling
  3. Export for Printing

Data Ingestion

Regardless of whether you use a desktop application such as QGIS  a pure geospatial database such as PostGIS  or a complete Location Intelligence platform such as CARTO  you need some way to extract the raw data from wherever it is  transform it  and load it in the destination data warehouse.

In this particular case  Microsoft released the raw building footprints using a standard format (GeoJSON) which makes things easier. There is a compressed zip file for each state in the US on their USBuildingFootprints Github repository.

So what is the most efficient way for us to ingest all of the buildings across several US states into a CARTO dataset?

Recently we released the COPY API which leverages two important optimizations tailored for importing big datasets into CARTO:

  1. On the one hand it makes use of the COPY statement available in PostgreSQL  avoiding all of the overhead in a regular import API.
  2. On the other hand  it makes the most of streaming technologies  such as generators in Python. We recently published an entire blog post on the goodness of the COPY API and the CARTO Python SDK.

This code snippet makes use of Python generators and the COPY API to stream the raw US buildings data of several states directly from Github to a CARTO account.

Map Visualization and Styling

Let's say we have ingested the New York and New Jersey building footprints in a CARTO dataset called buildings. The next step is to create a visualization that allows us to export an image for printing.

In CARTO you can create a map programatically with the Maps API. Basically you need to use a map template to indicate which dataset to query  which CartoCSS styling to apply  and some other attributes used to define the view (zoom  bounding box  etc.)

Since we only have polygons in our dataset  we can go with a simple styling: black building footprints over a white background. You could of course also get creative and try other approaches (see some ideas at the end of this article).

Again  this is just a few lines of code using the CARTO Python SDK.

Exporting the Map for Printing

Now for the interesting part: exporting a CARTO map for printing.

Printing a map is not a trivial topic at all  there's a lot of stuff involved. The main issue is that designing for printing is not the same as designing for viewing on a screen. You need to take into account composition of different elements  color spaces  labels and text  a legend  attributions  and more.

While most of the design workflow can be done on specific tools for that purpose  there's one thing that has to be done at the source where the map lives  in this case in CARTO.

Today  we are focused on exporting an image of both adequate size and DPI.

CARTO provides a static maps API that allows users to generate images up to 8192x8192 pixels at a given resolution.

A single request to the static maps API could give us a 28.9 cm squared image which covers most of the cases  but if we look for large format exports we need to somehow compose different images into a single one to achieve the desired image size.

This is exactly what the carto-print Python library does.

Given a CARTO username and API key  a map ID  the bounding box and zoom level of the viewport to export  the desired size (in centimeteres)  and DPI  it makes the appropriate requests to the static maps API to compose an image of the map with Pillow.

You can also export in RGBA or CMYK color modes  depending on if you just want to share the digital image or print it.

So  exporting a 91x61 centimeter and 300 DPI image of the New York and New Jersey buildings at zoom level 12  given the buildings named map we created in the previous step would be as simple as this:

from carto.print import Printer

YOUR_CARTO_USER_NAME = ''
YOUR_CARTO_API_KEY = ''

printer = Printer(YOUR_CARTO_USER_NAME  'buildings'  YOUR_CARTO_API_KEY  91  61  12  '1.956253 48.711127 2.835159 49.012429'  300  'CMYK')
printer.export('/tmp')

The result would be something like this (click on the image below to download the full size image):

     

New York Buildings

 

Bonus Track: Let's Create a Poster Print from any BUILDER Map

And now the fun part. CARTO  as a Location Intelligence platform  leverages a set of APIs that we ourselves use to create our solutions. One of those solutions is BUILDER which enables business analysts to get insight from their data  but also allows cartographers to generate awesome visualizations.

So basically we can use the carto-print library to export an image of any BUILDER map  in any size and DPI.

Trick. You can take the ID of any BUILDER map from its URL and use it for printing with this code snippet:

'tpl_' + '_'.join(builder_map_id.split('-'))

So from this map URL:

https://public.carto.com/builder/d7e5faf0-73b5-4cbe-89cf-d09d4d645186/embed

you could generate a 100x60 cm 300DPI image:

from carto.print import Printer

printer = Printer('public'  'tpl_d7e5faf0_73b5_4cbe_89cf_d09d4d645186'  'default_public'  100  60  4  '-126.9160061933863 21.988832413579896 -64.63131131149655 51.276134257695766'  300  'CMYK')
printer.export('/tmp')

Check out some examples below from our public team BUILDER accounts (click on the images to get the full size ready to print image).

 

       
  •      
US Rivers Map
  •    
  •    
  •      
World Map
  •    
  •    
  •      
World Airlines Map
  •    
  •    
  •      
Mars Map
  •    
  •    
  •      
Cordoba Buildings Map
  •    
  •    
  •      
World Heart Map
  •    
  •    
  •      
Game of Thrones Map
  •    
  •    
  •      
New York Streets Map
  •    
  •    
  •      
New York Streets Map
  •    
  •  

We've open sourced the carto-print project. Feel free to add any comment or suggestion. Contributions  of course  are welcome.