vltf mailrss

How to extract tiles from online maps

Jun 2014

Sometimes aerial imagery is released under a permissive license, but it is only made available through an online Flash or JavaScript viewer. Fortunately, it is easy enough to get at the imagery beneath these maps and reuse it in mashups or visualizations.

Black and white aerial imagery of Christchurch city centre

We’ll be using 1941–2011 imagery of Christchurch as an example. These aerials are available under a Creative Commons Attribution license from Environment Canterbury.

Finding where the tiles are hidden

Open the Web Inspector in Chrome or Firefox (Right-click ➝ Inspect Element) and select the Network tab. Now pan around the map until requests start flowing in. Most of these are for the individual tiles that make up the background imagery.

This is what we’re looking for:

Right-click to get the URL of any of these images. Here’s an example:

http://gis.ecan.govt.nz/arcgis/rest/services/Imagery/
SN152_Christchurch_19411014/MapServer/tile/13/109384/41276

To use these tiles elsewhere, substitute in the labels {z}, {x} and {y} to show which parts of the URL represent zoom level, x and y coordinates. Usually I guess the order and correct it later. For these tiles the template was:

http://gis.ecan.govt.nz/arcgis/rest/services/Imagery/
SN152_Christchurch_19411014/MapServer/tile/{z}/{y}/{x}

Metadata from ArcGIS map server

If the URL contains something like /arcgis/rest or /MapServer, there’s a good chance you can find more info about the imagery and possibly uncover other layers which are unused. In fact, many more layers can be found by searching specifically for these types of pages.

A list of all the imagery available on this server is shown at:

http://gis.ecan.govt.nz/arcgis/rest/

And more information about this specific layer, including a license, zoom levels, extents and a spatial reference, can be found at:

http://gis.ecan.govt.nz/arcgis/rest/services/Imagery/
SN152_Christchurch_19411014/MapServer

Using the tiles in Leaflet

Often, tiles use Spherical Mercator projection (the same as OpenStreetMap). If this is the case Leaflet is able to calculate {x}, {y} and {z} values without any extra configuration—the template URL is all you need.

Dealing with projections

The ArcGIS map server page for these tiles shows the spatial reference is 2193, which means NZTM. New Zealand imagery is often projected using NZTM because it results in slightly less distortion. This is a bit of a pain because it makes combining the tiles with other sources more difficult.

We’ll need to supply some more information to position the tiles correctly, as well as including scripts for Proj4js and Proj4Leaflet to handle map projection.

Here is the JavaScript needed to use these tiles in Leaflet:

var crs = new L.Proj.CRS(
  'EPSG:2193',
  '+proj=tmerc +lat_0=0 +lon_0=173 +k=0.9996 +x_0=1600000' +
    '+y_0=10000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m',
  {
    origin: [-4020900, 19998100],
    resolutions: [
      529.1677250021168,
      264.5838625010584,
      198.43789687579377,
      132.2919312505292,
      66.1459656252646,
      26.458386250105836,
      13.229193125052918,
      6.614596562526459,
      5.291677250021167,
      3.9687579375158752,
      2.6458386250105836,
      2.116670900008467,
      1.0583354500042335,
      0.5291677250021167,
      0.26458386250105836
    ]
  }
);

var tileLayer = new L.TileLayer(
  'http://gis.ecan.govt.nz/arcgis/rest/services/Imagery/' +
    'SN152_Christchurch_19411014/MapServer/tile/{z}/{y}/{x}',
  {
    minZoom: 4,
    maxZoom: 14,
    continuousWorld: true
  }
);

var map = L.map('map', {
  center: new L.LatLng(-43.528, 172.626),
  zoom: 12,
  crs: crs
});

map.addLayer(tileLayer);

The Proj4 string (+proj=tmerc +lat_0=0 +lon_0=173…) describes how to transform between latitude/longitude and NZTM. I looked this one up on spatialreference.org.

Next are the origin and list of resolutions. These came from the ArcGIS map server page and describe which zoom levels are available.

Finally, I specified the tile URL template we discovered earlier and limited the zoom levels using maxZoom and minZoom to only show the best imagery.

Demo of the finished map.

Next steps

A map tile breaks out of a crappy locked down map and strolls off, whistling

The imagery is now freed from its original web viewer and Leaflet can be used to mash more data into the map. I’m currently working on a plugin to combine several tile layers of different projections on the same map.