I would like to render subset of OpenStreetMap features over big area into one image, no sub-tiles.

System: Devuan ascii 64bit (alike Debian 9), 64GB RAM, headless (SSH only)

There is what I already have

  1. Map in .osm format (14GiB)

  2. installed and functional postgresql 9.6.9 with the postgis extensions

  3. osm2pgsql import went fine

    osm2pgsql -s -d gis -C 22000 ./file.osm


psql gis
gis=# SELECT nspname || '.' || relname AS "relation",
    pg_size_pretty(pg_relation_size(C.oid)) AS "size"
  FROM pg_class C
  LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
  WHERE nspname NOT IN ('pg_catalog', 'information_schema')
  ORDER BY pg_relation_size(C.oid) DESC
  LIMIT 20;

 public.planet_osm_nodes         | 4048 MB
 public.planet_osm_ways_nodes    | 3718 MB
 public.planet_osm_ways          | 2003 MB
 public.planet_osm_polygon       | 1804 MB
 public.planet_osm_nodes_pkey    | 1666 MB
 public.planet_osm_polygon_index | 638 MB
 public.planet_osm_line          | 539 MB
 public.planet_osm_point         | 282 MB
 public.planet_osm_point_index   | 187 MB
 public.planet_osm_line_index    | 187 MB
 public.planet_osm_roads         | 170 MB
 public.planet_osm_ways_pkey     | 157 MB
 public.planet_osm_polygon_pkey  | 122 MB
 public.planet_osm_point_pkey    | 75 MB
 public.planet_osm_rels          | 73 MB
 pg_toast.pg_toast_45676         | 58 MB
 public.planet_osm_rels_parts    | 49 MB
 pg_toast.pg_toast_45680         | 47 MB
 public.planet_osm_line_pkey     | 33 MB
 pg_toast.pg_toast_45675         | 33 MB
  1. compiled mapnik 3.0.20 and mapnik-python-3.0.x

  2. python script (source: https://wiki.openstreetmap.org/wiki/Mapnik/Rendering_OSM_XML_data_directly (changed to use psql instead of .osm))


#!/usr/bin/env python

from mapnik import *

mapfile = 'power.xml'
map_output = 'mymap.tiff'

m = Map(1*1024,1*1024)
load_map(m, mapfile)
bbox=(Envelope( 12.08,48.54,18.86,51.06 ))

#print 'Scale = ' , m.scale()
render_to_file(m, map_output)
  1. power.xml (referenced from the python script above)


<?xml version="1.0" encoding="utf-8"?>
<Map background-color="#ffffff" srs="+proj=latlong +datum=WGS84">
  <FontSet name="book-fonts">
    <Font face-name="DejaVu Sans Book" />
  <Style name="highways">
      <Filter>[highway] &lt;&gt;''</Filter>
      <LineSymbolizer stroke="#ff0000" stroke-width="2" stroke-linejoin="round"
        stroke-linecap="round" />
      <Filter>[highway] &lt;&gt;''</Filter>
      <TextSymbolizer fontset-name="book-fonts" size="9" fill="#0000" halo-radiu
s="1" placement="line" />
  <Layer name="highways" status="on" srs="+proj=latlong +datum=WGS84">
      <Parameter name="type">postgis</Parameter>
      <Parameter name="host">localhost</Parameter>
      <Parameter name="dbname">gis</Parameter>
      <Parameter name="user">root</Parameter>
      <Parameter name="table">(select highway from planet_osm_line) as road</Par
      <Parameter name="password">root</Parameter>
  1. Trying to render it:


python ./render.py 
Segmentation fault
  1. Another method - nik4.py (source: https://github.com/Zverik/Nik4 ) is also failing miserably:


python ./nik4.py -c 15 50 -z 10 -d 1024 768 -f png256 ./mapnik_pt.xml ./image.png
Traceback (most recent call last):
  File "./nik4.py", line 629, in <module>
  File "./nik4.py", line 395, in run
    mapnik.load_map_from_string(m, style_xml.encode("utf-8"), False, style_path)
RuntimeError: Postgis Plugin: ERROR:  column "line" does not exist
LINE 2:       route='ferry' or line='ferry') as routes LIMIT 0
in executeQuery Full sql was: 'SELECT * FROM (select way, route from planet_osm_line where
      route='ferry' or line='ferry') as routes LIMIT 0'
  encountered during parsing of layer 'ferry-routes' in Layer

Already answered questions

  • Does Envelope() match the .osm coordinates? Yes.

<bounds minlon="12.08477" minlat="48.54292" maxlon="18.86321" maxlat="51.06426" origin="0.41"/>

Any ideas what I made wrong? How are you rendering one-big-image maps?

If my way is completely wrong, please suggest better way. The ultimate goal is to render for example all roads and all rivers into one big image for A1 poster.

  • I think the problem is the the meta-topology between ways and nodes in the OSM data; you'd need to select the input from at least those two planet_osm_* tables (you should probably check what mapniks load_map/render_to_file function expects exactly). – ThingumaBob Aug 11 '18 at 21:25

I strongly recommend you to look at QGIS for this type of work (https://qgis.org). A GIS (Geographic Information System) like QGIS is actually designed for this type of work: to style and layout large maps and output them to an image format or PDF for printing purposes.

Most tools in the OpenStreetMap world, are not geared to this kind of work, but solely create tiled output for webservices, which means that putting them to work for printing purposes, always results in a more or less hackish solution.

QGIS does not suffer from these drawbacks if you use it to access the PostGIS data directly using QGIS's PostGIS database connection options, as you will be accessing and styling the vector data in your OpenStreetMap database directly in that case. It should allow you to relatively easily style and output your desired map to the custom format you desire.

  • Thanks, but QGIS looks like a GUI application and from the man page it seems that direct scripting from Bash is not possible. Since the rendering machine is headless, I will need to take a look if there is some python API... – sachy Aug 14 '18 at 21:42
  • You undoubtedly already found it, but for reference, here is another GIS Stackexchange thread full of links to useful resources for PyQGIS: gis.stackexchange.com/questions/250035/…. And this seems useful as well: qgistutorials.com/en/docs/getting_started_with_pyqgis.html – Marco_B Aug 15 '18 at 20:52

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.