Wednesday 24 February 2016

Overlaying Historical Maps using the Google Maps API

This post is part of a series documenting my experience Learning the Google Maps API.

Straight up, overlays were the main reason I wanted to learn the Google Maps API. Markers are cool and all, but there are number of ways you can generate maps with a set of markers and info windows and embed them on a website, even with limited JavaScript skills, without having to code them from scratch.

When it comes to Overlays, however, we're talking unique custom maps.  It also has direct, immediate relevance to libraries that have historical maps in their collection.

Where I work we have digitised a set of Real Estate Subdivision Maps that cover the local area. Here's an example of what they look like.


These maps are really useful for people researching house histories as they can tell you when an individual plot of land was first sold. As such anyone looking at these would typically have a location as their starting point for finding the map (their house), making a map based interface perfect.

So my idea was to take this image and overlay it on a Google Map.  This involves resizing and rotating the image until it aligns perfectly over A Google Map.  I also wanted the user to be able to control the opacity of the overlay so that they can adjust how much of the base map is visible through the image, as well as zoom in and out on the map to see the detail on the subdivision map.

Here's the final result.

See the Pen Google Maps API Custom Overlay by Martin Boyce (@boycetrus) on CodePen.
You can view this example full screen on Codepen.

How did we get here?

So what's involved in getting something like this working?  I'm not going to explain the code - if you want to learn how to write the javascript I would recommend working your way through the tutorial that I used: Google Maps API for designers.

Rather, the rest of this post will discuss the strategy or techniques used and the implications for doing something like this on a large scale (we have hundreds of these Real Estate Subdivision maps digitised).

Problem 1 - Aligning the Map

The subdivision map shown above is not oriented with north at the top.  I couldn't just layer the map over the base map as it would never line up. So the first step is to create a new image from the original digitised map that is rotated and resized to fit perfectly over a scaled Google Map.  This involves a a reasonable amount of fiddling with Photoshop (or something similar). First I created a screenshot of the right area from Google Maps and scaled it up (as the original image needs to be quite large to allow for zooming in). Then I layered the subdivision map image over the top, rotated and aligned it so that it sat as close as possible to perfectly over the Google Map base layer. Finally, I created a transparent png image from the aligned subdivision map.

What I ended up with was a very large version of an image that looks like this.



Problem 2 - Creating Map Tiles

Google maps is made up of millions of individual image tiles, each one being a 256 x 256 pixels square.  For each zoom level on Google Maps there is a separate set of map tiles. You need to cut the original image in multiple sets of square tiles for each zoom level the overlay is displayed on.  So the rotated image shown above was used to generate the necessary tile images, one set for each zoom level.

Folder structure of the image tiles after processing. Each top level folder corresponds to a zoom level on Google maps.

There ends up being hundreds of individual images. Thankfully there is software to do the job.  I used MapTiler (maptiler.org) as recommended in the tutorial. I guess there would be other options but when I grokked what was involved I just went with Maptiler.  I used the free version and if you check out the finished map you can see that each tile is watermarked. If I was going to do more I would just purchase the software as it isn't that expensive and it will save you hours and hours of work. it is just not something you would do manually.

Problem 3 - Hosting the Map Tiles online

In order for Google maps to be able to use the newly created map tiles all those hundreds of 256px x 256px images need to be available on the web.  I used our public folder of our dropbox account to store and serve the tiles.  If we were to create tiles for the hundreds of subdivision maps we have in our collection we would need quite a bit of storage space for images and may need to find an alternative hosting arrangement.

Problem 4 - Writing the Code

Once all the required map tiles are prepared and online I could start writing the actual code that displays the custom overlay on the map. It turns out that it wasn't that difficult to get the code working and it was possibly the quickest part of the whole process.  Preparing the images and map tiles is far more laborious.

All that was left was to add some sort of control interface that allows users to adjust the opacity of the overlay. It took a little digging in the API documentation and around the web to work out how to control the opacity of the overlay but once I figured that out it was straightforward to hook that up to the range slider as the user interface.

And in the end I'm pretty happy with how it turned out.

Doing this on a larger scale

It's one thing to do this for a single map but is it feasible to do this on a larger scale?  We have hundreds of these maps that cover the Sutherland Shire in Sydney.  There are literally thousands of man hours involved in orienting all those maps to the Google Maps base layer and subsequently generating the tiles.

Once I realised this I started looking around the API documentation and discovered an alternative.  It's possible to create what Google calls a Ground Overlay.  Instead of creating individual tiles for each zoom level, you can just overlay a single image aligned to a box of lat/long coordinates. I've created a version of our Como Subdivision Map as a Ground Overlay on Codepen.

The problem with using this method is that the image file being overlaid has to be very large
in order to maintain sufficient detail when a user zooms in to the map. In this case I think the original png image is over 5Mb, which means that the map is much slower to load than using individual 256 x256 tiles.  And it is still necessary to spend time rotating and orienting the original scanned image to find the coordinates needed for the map.

Towards a functioning interface for subdivision maps

With so many individual maps it's not possible to overlay them all on a single Google Map. When the map is zoomed out there will be too much overlap between maps to be usable.

It is necessary to create some other way for users to find the subdivision map they are looking for and then before displaying the map as an overlay.  I think this would require some metadata being created for each map and then a method (or multiple ways) to search and filter the maps to locate the appropriate map.

Once again, this probably involves hundreds of man hours working through each map to create necessary metadata.

Putting aside the number of hours required, her's an initial idea.

Provide an interface for users to search for a street address.

  1. Google Maps has the ability to Geocode addresses and return lat/long coordinates.
  2. Compared the returned lat/long pair with the bounding box of each map and find maps that contain the location.
  3. Then generate the overlay on a map.


I'd love to hear what you think of the example I've created or if you have any ideas for an interface for lots of maps, ways to improve, etc. Let me know in the comments.

No comments:

Post a Comment