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:
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:
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.
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.
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):
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).
We’ve open sourced the carto-print project. Feel free to add any comment or suggestion. Contributions, of course, are welcome.
Please fill out the below form and we'll be in touch real soon.