* instructions given in the Appendix C of INSTALL file * Cascadenik patch for mapnik 2 * scripts to fix installation with current libraries and datas --- INSTALL | 168 ++++++++++++++++++++ ...t.py-to-make-it-compatible-with-mapnik-2..patch | 108 +++++++++++++ stylesheet/toner/correct_label_fonts.sh | 8 + stylesheet/toner/correct_mml.sh | 26 +++ 4 files changed, 310 insertions(+) create mode 100644 stylesheet/toner/0001-Fixes-output.py-to-make-it-compatible-with-mapnik-2..patch create mode 100755 stylesheet/toner/correct_label_fonts.sh create mode 100755 stylesheet/toner/correct_mml.sh
diff --git a/INSTALL b/INSTALL index d749fc0..d67d58e 100644 --- a/INSTALL +++ b/INSTALL @@ -377,3 +377,171 @@ Note that in addition to the MapQuest Europe stylesheet (mapquest-eu.xml), the Git repository also contains the MapQuest US and MapQuest UK stylesheets (mapquest-us.xml and mapquest-uk.xml), that you can similarly add to your ocitysmap.conf file. + +Appendix C: installation of the Stamen Toner stylesheet +------------------------------------------------------- + +Toner is a black and white stylesheet initialy provided by Stamen +(http://maps.stamen.com/#toner). The instructions below detail how to install +this stylesheets, making the assumption that ocitysmap is properly configured +and running with the default OSM stylesheet. + + 1. Cascadenik installation + +Cascadenik implements cascading stylesheets for Mapnik. Cascadenik is a +requisite for Toner stylesheet. + + # install dependancies + sudo aptitude install python-cssutils python-imaging + # clone the repository + git clone https://github.com/mapnik/Cascadenik.git + cd Cascadenik/ + git checkout mapnik2 # switch to mapnik2 branch + +When tested (rev. 7dc2587) Cascadenik mapnik2 branch was not fully functionnal +(at least with mapnik 2.1). If no correction has been made since a patch is +provided to fix that: + + git checkout 7dc2587 + git am --signoff < /path/to/ocitysmap/stylesheet/toner/0001-Fixes-output.py-to-make-it-compatible-with-mapnik-2..patch + +Then you can install it: + + python setup.py install + + 2. Coastline table + +Toner stylesheet reads the coastline datas in the postgis database. We need to +import it in our database. + + cd path/to/mapnik-osm/world_boundaries + shp2pgsql -s 900913 -I processed_p.shp coastline \ + | psql -U maposmatic -d maposmatic -h localhost + + 3. Natural Earth Data database + +Toner stylesheet uses many data from the natural earth database +(http://www.naturalearthdata.com/). We are going to import all theses datas +inside another postgis database. + + mkdir naturalearth + cd naturalearth + wget http://kelso.it/x/nevector # download all Natural Earth Data shape + # files cf. http://www.naturalearthdata.com/downloads/ + unzip nevector + sudo su postgres + # create db + createdb -E UTF-8 -O maposmatic naturalearth + # add geographic extensions + psql -f /usr/share/postgresql/9.1/contrib/postgis-1.5/postgis.sql \ + -d naturalearth + psql -f /usr/share/postgresql/9.1/contrib/postgis_comments.sql \ + -d naturalearth + psql -f /usr/share/postgresql/9.1/contrib/postgis-1.5/spatial_ref_sys.sql \ + -d naturalearth + # fix permissions + echo "ALTER TABLE geometry_columns OWNER TO maposmatic; + ALTER TABLE spatial_ref_sys OWNER TO maposmatic;" | psql -d naturalearth + + # import data from shapefiles + for FILE in `find . -name *.shp`; do \ + BASE=`basename $FILE .shp`; \ + shp2pgsql -W LATIN1 -s 900913 -I $FILE $BASE \ + | psql naturalearth; done + + # fix permissions + for FILE in `find . -name *.shp`; do BASE=`basename $FILE .shp`; \ + echo "ALTER TABLE "$BASE" OWNER TO maposmatic;" \ + | psql -d naturalearth ; done + + 4. Install Toner + + git clone https://github.com/Citytracking/toner.git + +The installation has been tested with the commit 58369be + + git checkout 58369be + + 4.1 Install toner specific datas + +Toner stylesheet is provided with some labels and some roads. We are +importing them in the naturalearth database. + + cd /path/to/toner/ + # fixes manualy set database parameters with ours + sed -i 's/psql -d toner -U osm/psql -h localhost -d naturalearth -U maposmatic/' \ + import_toner_v2_shps.sh + # if you don't want to type too many times the database pass + vim ~/.pgpass + + localhost::naturalearth:maposmatic:maposmatic_password + + chmod 0600 ~/.pgpass + # import + sh import_toner_v2_shps.sh + + 4.2 Specific planet views + +A specific view is used for motorway in the OSM database. + + cd /path/to/toner/osm + psql -h localhost -U maposmatic maposmatic < motorways.pgsql + +Other views are necessary. + + cd /path/to/toner/mapnik/ + psql -h localhost -U maposmatic maposmatic < views.pgsql + + 4.3 Stylesheet generation + + cd /path/to/toner/mapnik/ + + # replace MS fonts with DejaVu + /path/to/ocitysmap/stylesheet/toner/correct_label_fonts.sh + + # fix the mml file: + # - change table names with our tables + # - add the ability to specifiy a password to naturalearth database + # - set manualy an extent when estimate_extent is set to false + /path/to/ocitysmap/stylesheet/toner/correct_mml.sh + + # configure database access + vim style-toner-standard.mml + + (...) + <!ENTITY nev_host "localhost"> + <!ENTITY nev_name "naturalearth"> + <!ENTITY nev_user "maposmatic"> + <!ENTITY nev_pass "maposmatic_password"> + + <!ENTITY osm_host "localhost"> + <!ENTITY osm_port "5432"> + <!ENTITY osm_name "maposmatic"> + <!ENTITY osm_user "maposmatic"> + <!ENTITY osm_pass "maposmatic_password"> + + <!ENTITY included_data_host "localhost"> + <!ENTITY included_data_port "5432"> + <!ENTITY included_data_name "naturalearth"> + <!ENTITY included_data_user "maposmatic"> + <!ENTITY included_data_pass "maposmatic_password"> + (...) + + # generate the stylesheet + /path/to/cascadenik/cascadenik-compile.py style-toner-standard.mml \ + /tmp/style-toner-standard-mapnik2.xml + mv /tmp/style-toner-standard-mapnik2.xml /path/to/toner/mapnik/ + + 5. ocitysmap configuration + +Edit properly the configuration file. + + vim /home/$USER/.ocitysmap.conf + + [Toner] + name: Toner + description: Stamen Toner stylesheet + path: /path/to/toner/mapnik/style-toner-standard-mapnik2.xml + +Don't forget to add "Toner" to the available_stylesheets variable, which lists +all available stylesheets. diff --git a/stylesheet/toner/0001-Fixes-output.py-to-make-it-compatible-with-mapnik-2..patch b/stylesheet/toner/0001-Fixes-output.py-to-make-it-compatible-with-mapnik-2..patch new file mode 100644 index 0000000..2a85401 --- /dev/null +++ b/stylesheet/toner/0001-Fixes-output.py-to-make-it-compatible-with-mapnik-2..patch @@ -0,0 +1,108 @@ +From a886e5018e0e4413bd9ffc18ec7c792fca53cf24 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=89tienne=20Loks?= <[email protected]> +Date: Sun, 15 Apr 2012 01:47:10 +0200 +Subject: [PATCH] Fixes output.py to make it compatible with mapnik 2.1 + +Change TextSymbolizer attributes to make them compatible with new +version of Mapnik. +--- + cascadenik/output.py | 42 +++++++++++++++++++++--------------------- + 1 file changed, 21 insertions(+), 21 deletions(-) + +diff --git a/cascadenik/output.py b/cascadenik/output.py +index a696df9..77a9f2b 100644 +--- a/cascadenik/output.py ++++ b/cascadenik/output.py +@@ -232,7 +232,7 @@ class LineSymbolizer: + + class TextSymbolizer: + def __init__(self, name, face_name, size, color, wrap_width=None, \ +- label_spacing=None, label_position_tolerance=None, max_char_angle_delta=None, \ ++ label_spacing=None, label_position_tolerance=None, maximum_angle_char_delta=None, \ + halo_color=None, halo_radius=None, dx=None, dy=None, avoid_edges=None, \ + minimum_distance=None, allow_overlap=None, label_placement=None, \ + character_spacing=None, line_spacing=None, text_transform=None, fontset=None, \ +@@ -247,7 +247,7 @@ class TextSymbolizer: + assert wrap_width is None or type(wrap_width) is int + assert label_spacing is None or type(label_spacing) is int + assert label_position_tolerance is None or type(label_position_tolerance) is int +- assert max_char_angle_delta is None or type(max_char_angle_delta) is int ++ assert maximum_angle_char_delta is None or type(maximum_angle_char_delta) is int + assert halo_color is None or halo_color.__class__ is style.color + assert halo_radius is None or type(halo_radius) is int + assert dx is None or type(dx) is int +@@ -271,7 +271,7 @@ class TextSymbolizer: + self.wrap_width = wrap_width + self.label_spacing = label_spacing + self.label_position_tolerance = label_position_tolerance +- self.max_char_angle_delta = max_char_angle_delta ++ self.maximum_angle_char_delta = maximum_angle_char_delta + self.halo_color = halo_color + self.halo_radius = halo_radius + self.dx = dx +@@ -312,23 +312,23 @@ class TextSymbolizer: + sym = mapnik.TextSymbolizer(expr, self.face_name, self.size, + mapnik.Color(str(self.color))) + +- sym.wrap_width = self.wrap_width or sym.wrap_width +- sym.label_spacing = self.label_spacing or sym.label_spacing +- sym.label_position_tolerance = self.label_position_tolerance or sym.label_position_tolerance +- sym.max_char_angle_delta = self.max_char_angle_delta or sym.max_char_angle_delta +- sym.halo_fill = mapnik.Color(str(self.halo_color)) if self.halo_color else sym.halo_fill +- sym.halo_radius = self.halo_radius or sym.halo_radius +- sym.character_spacing = self.character_spacing or sym.character_spacing +- sym.line_spacing = self.line_spacing or sym.line_spacing +- sym.avoid_edges = self.avoid_edges.value if self.avoid_edges else sym.avoid_edges +- sym.force_odd_labels = self.force_odd_labels.value if self.force_odd_labels else sym.force_odd_labels +- sym.minimum_distance = self.minimum_distance or sym.minimum_distance +- sym.allow_overlap = self.allow_overlap.value if self.allow_overlap else sym.allow_overlap ++ sym.placements.defaults.wrap_width = self.wrap_width or sym.placements.defaults.wrap_width ++ sym.placements.defaults.label_spacing = self.label_spacing or sym.placements.defaults.label_spacing ++ sym.placements.defaults.label_position_tolerance = self.label_position_tolerance or sym.placements.defaults.label_position_tolerance ++ sym.placements.defaults.maximum_angle_char_delta = self.maximum_angle_char_delta or sym.placements.defaults.maximum_angle_char_delta ++ sym.format.halo_fill = mapnik.Color(str(self.halo_color)) if self.halo_color else sym.format.halo_fill ++ sym.format.halo_radius = self.halo_radius or sym.format.halo_radius ++ sym.format.character_spacing = self.character_spacing or sym.format.character_spacing ++ sym.format.line_spacing = self.line_spacing or sym.format.line_spacing ++ sym.placements.defaults.avoid_edges = self.avoid_edges.value if self.avoid_edges else sym.placements.defaults.avoid_edges ++ sym.placements.defaults.force_odd_labels = self.force_odd_labels.value if self.force_odd_labels else sym.placements.defaults.force_odd_labels ++ sym.placements.defaults.minimum_distance = self.minimum_distance or sym.placements.defaults.minimum_distance ++ sym.placements.defaults.allow_overlap = self.allow_overlap.value if self.allow_overlap else sym.placements.defaults.allow_overlap + if self.label_placement: +- sym.label_placement = mapnik.label_placement.names.get(self.label_placement,mapnik.label_placement.POINT_PLACEMENT) ++ sym.placements.defaults.label_placement = mapnik.label_placement.names.get(self.label_placement,mapnik.label_placement.POINT_PLACEMENT) + # note-renamed in Mapnik2 to 'text_transform' + if self.text_transform: +- sym.text_transform = convert_enums.get(self.text_transform,mapnik.text_transform.NONE) ++ sym.format.text_transform = convert_enums.get(self.text_transform,mapnik.text_transform.NONE) + if self.vertical_alignment: + # match the logic in load_map.cpp for conditionally applying vertical_alignment default + default_vertical_alignment = mapnik.vertical_alignment.MIDDLE +@@ -337,10 +337,10 @@ class TextSymbolizer: + elif self.dy < 0.0: + default_vertical_alignment = mapnik.vertical_alignment.TOP + +- sym.vertical_alignment = mapnik.vertical_alignment.names.get(self.vertical_alignment, ++ sym.placements.defaults.vertical_alignment = mapnik.vertical_alignment.names.get(self.vertical_alignment, + default_vertical_alignment) + if self.justify_alignment: +- sym.justify_alignment = mapnik.justify_alignment.names.get(self.justify_alignment, ++ sym.placements.defaults.justify_alignment = mapnik.justify_alignment.names.get(self.justify_alignment, + mapnik.justify_alignment.MIDDLE) + + if self.fontset: +@@ -349,9 +349,9 @@ class TextSymbolizer: + sys.stderr.write('\nCascadenik debug: Warning, FontSets will be ignored as they are not yet supported in Mapnik via Python...\n') + + try: +- sym.displacement = (self.dx or 0.0, self.dy or 0.0) ++ sym.placements.defaults.displacement = (self.dx or 0.0, self.dy or 0.0) + except: +- sym.displacement(self.dx or 0.0, self.dy or 0.0) ++ sym.placements.defaults.displacement(self.dx or 0.0, self.dy or 0.0) + + return sym + +-- +1.7.9.5 + diff --git a/stylesheet/toner/correct_label_fonts.sh b/stylesheet/toner/correct_label_fonts.sh new file mode 100755 index 0000000..7e6aedb --- /dev/null +++ b/stylesheet/toner/correct_label_fonts.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +sed -i 's/Italic/Oblique/' labels.mss +sed -i 's/Arial Unicode MS Regular/DejaVu Sans/' labels.mss +sed -i 's/Arial Regular/DejaVu Sans/' labels.mss +sed -i 's/Arial Unicode MS/DejaVu Sans/' labels.mss +sed -i 's/Arial Regular/DejaVu/' labels.mss +sed -i 's/Arial Bold/DejaVu Sans Bold/' labels.mss diff --git a/stylesheet/toner/correct_mml.sh b/stylesheet/toner/correct_mml.sh new file mode 100755 index 0000000..d1d4173 --- /dev/null +++ b/stylesheet/toner/correct_mml.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +sed -i 's|<Parameter name="password"></Parameter>|<Parameter name="password">\&nev_pass;</Parameter>|' style-toner-standard.mml +sed -i 's/land_110m/ne_110m_land/' style-toner-standard.mml +sed -i 's/land_50m/ne_50m_land/' style-toner-standard.mml +sed -i "s/admin_0_countries_110m</ne_110m_admin_0_countries</" style-toner-standard.mml +sed -i "s/admin_0_countries_50m</ne_50m_admin_0_countries</" style-toner-standard.mml +sed -i "s/admin_0_countries_10m</ne_10m_admin_0_countries</" style-toner-standard.mml +sed -i 's/admin_1_states_provinces_lines_110m/ne_110m_admin_1_states_provinces_lines_shp/' style-toner-standard.mml +sed -i 's/admin_1_states_provinces_lines_50m/ne_50m_admin_1_states_provinces_lines_shp/' style-toner-standard.mml +sed -i 's/admin_1_states_provinces_lines_10m/ne_10m_admin_1_states_provinces_lines_shp/' style-toner-standard.mml +sed -i 's/admin_1_states_provinces_110m/ne_110m_admin_1_states_provinces_shp/' style-toner-standard.mml +sed -i 's/admin_1_states_provinces_50m/ne_50m_admin_1_states_provinces_shp/' style-toner-standard.mml +sed -i 's/admin_1_states_provinces_10m/ne_10m_admin_1_states_provinces_shp/' style-toner-standard.mml + +sed -i 's/lakes_110m/ne_110m_lakes/' style-toner-standard.mml +sed -i 's/lakes_50m/ne_50m_lakes/' style-toner-standard.mml +sed -i 's/lakes_10m/ne_10m_lakes/' style-toner-standard.mml + +sed -i 's/geography_marine_polys_110m/ne_110m_geography_marine_polys/' style-toner-standard.mml +sed -i 's/geography_marine_polys_50m/ne_50m_geography_marine_polys/' style-toner-standard.mml +sed -i 's/geography_marine_polys_10m/ne_10m_geography_marine_polys/' style-toner-standard.mml + +sed -i 's/coastline_10m/ne_10m_coastline/' style-toner-standard.mml + +sed -i 's|<Parameter name="estimate_extent">false</Parameter>|<Parameter name="estimate_extent">false</Parameter>\n <Parameter name="extent">\&epsg900913_extent;</Parameter>|' style-toner-standard.mml -- 1.7.9.5
