I recently made a 25000 x 25000 pixel Google Map to hang on my wall and track all the places I’ve explored in the city.

Final map hanging on wall

The final product took 30 minutes for my laptop to generate, 45 minutes to print, and cost about $50 in materials.

All of the code I used is available on GitHub. I cleaned up the script a bit from the original, but don’t expect it to work on your computer without slight modifications.

Creating the Image

The program currently requires Python 3.5+ because I love type hints. It uses the Selenium library for browser automation, and the Pillow library for image manipulation.

Before running, the program needs a few things from the user:

  • Figure out what percent to crop from each side of a screenshot to hide all unwanted, non-map elements (taskbars, extra displays, GUI elements)
  • Figure out a good starting point (top-left coordinate) for the map, and how many rows / columns should be used to capture the desired area

Once provided with that information, the program does the following:

  • Figure out how much to adjust the latitude and longitude each screenshot so that the final grid of images will line up perfectly
  • Visit Google Maps, wait for it to load, and take each screenshot
  • Loop through the grid of saved images and combine them into one huge image

The main script is only 132 lines long, 40 of which are comments, if you want to check it out for yourself.

Printing and building

The build was fairly straightforward, and was supposed to be a trial run. However, the results came out so well that I decided to just keep this version.

Materials and costs:

  • 4 square feet of white vinyl = $8
  • 4 square feet of ink = $20
  • 3.5’ x 4.5’ sheet of foam board = $12
  • 500 assorted map tacks = $7

The build:

Map printing in plotter Map on drafting table Map at super close 1-inch block Map with dog Duct taping card stock together Hanging on the wall

Future considerations

If I continue using this program for more than a one-off project, I need to consider the following changes:

  • Instead of using rows and columns to determine the size of the map, pass a latitude_end and longitude_end and have the program figure out the rows and columns.
  • Replace pyscreenshot.grab with a hand-rolled image cropping function, since Selenium already provides basic screenshot functionality.
  • Allow for adjustable zoom levels, instead of hard-coding it to 18z.
  • Allow for Google Earth images in addition to Google Maps.