1

I have a pre-tiled Slippy map data source.

How can I render a non-tiled raster image for a given bounding box, without having to add each PNG file and its extents manually in something like Mapnik or GDAL?

0

There is several ways to to create a single raster image from a slippy map source. MOBAC (http://mobac.sourceforge.net/) and SAS Planet (http://www.sasgis.org/) allow you to consume a service and export into multiple formats such as geoTiff. MOBAC is probably the easiest to configure and use, whilst SAS Planet has more functionality.

The other option is to use GDAL_WMS (http://www.gdal.org/frmt_wms.html) via the command line.

In all cases ensure that you have permission from the copyright owner to consume the data in this way...

  • GDAL_WMS is exactly what I was looking for, thanks! I must have missed it reading the GDAL documentation. And we do have permission to use the data source, no issue on that case. – F.X. Oct 8 '15 at 7:07
2

For further reference, here is what I ended up doing.

First, create an XML file called datasource.xml that points to my pre-tiled source :

<GDAL_WMS>
  <Service name="TMS">
    <ServerUrl>http://example.com/${z}/${x}/${y}.png</ServerUrl>
    <Format>png</Format>
    <Transparent>TRUE</Transparent>
  </Service>
  <DataWindow>
    <UpperLeftX>-20037508.34</UpperLeftX>
    <UpperLeftY>20037508.34</UpperLeftY>
    <LowerRightX>20037508.34</LowerRightX>
    <LowerRightY>-20037508.34</LowerRightY>
    <TileLevel>10</TileLevel>
    <TileCountX>1</TileCountX>
    <TileCountY>1</TileCountY>
    <YOrigin>bottom</YOrigin>
  </DataWindow>
  <Projection>EPSG:3857</Projection>
  <MaxConnections>4</MaxConnections>
  <BlockSizeX>256</BlockSizeX>
  <BlockSizeY>256</BlockSizeY>
  <BandsCount>4</BandsCount>
  <ZeroBlockHttpCodes>204,303,400,403,404,500,501</ZeroBlockHttpCodes>
  <ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>

This file can be opened directly by GDAL or even QGIS.

Note: I wasn't able to specify the real extents of the data source without having GDAL try to download everything at the largest resolution to resample it, so the extents are the same as the OSM example from the GDAL WMS driver documentation.

Then, I used Mapnik to render the map, since I want to add vector symbols later on:

import mapnik

# Create and configure the map
m = mapnik.Map(600, 300)
m.background = mapnik.Color('steelblue')
m.srs = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"  # noqa

# We need to add a style to the raster, otherwise it won't
# be displayed by Mapnik.
s = mapnik.Style()
r = mapnik.Rule()
r.symbols.append(mapnik.RasterSymbolizer())
s.rules.append(r)
m.append_style('Style', s)

# Load the data-source using Mapnik's GDAL plugin.
ds = mapnik.Gdal(file="datasource.xml")
layer = mapnik.Layer('world')
layer.datasource = ds
layer.styles.append('Style')
layer.srs = m.srs
m.layers.append(layer)

# Zoom to the real extents.
ext = mapnik.Box2d(xmin, ymin, xmax, ymax)
cx, cy = ext.center().x, ext.center().y
m.zoom_to_box(ext)
m.pan_and_zoom(300, 100, 0.01)

# Finally, render the full map.
mapnik.render_to_file(m, 'world.png', 'png')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.