OpenPaperMaps

From OpenStreetMap Wiki
Jump to: navigation, search
New map
Styles
Rendered maps
Example markers
Example markers

This projects is based on the initial work from Graham Jones on townguide (http://www.townguide2.webhop.net/), a web application with a Python renderer that lets you set up a bounding box from OSM data to render it and embed it into a PDF.

This projects uses the original renderer from that application and follows the Django pluggable app pattern to bring a flexible solution to create customizable maps.

Some of its features are:

  • Selection of a bounding box to render a piece of OSM data
  • Paper size selection
  • Style selection and sharing
  • For small areas, grid decoration and POI/street index features are available
  • POI Markers

OpenPaperMaps consists currently of three modules: Townguide which is a wrapper around Mapnik and Reportlab to embed maps created with OSM data on a PDF, djtownguide which is a Django application that provides a web interface to its features and mapnikstyleshare another Django application, which gives djtownguide the capability to select a style, plus some minor styling abilities to the maps.

Full list of required dependencies

 easy_install psycopg2
 easy_install MySQL-Python
 easy_install twisted
 easy_install reportlab
 easy_install pycairo
 easy_install Django  
 easy_install aggdraw
 easy_install lxml
 easy_install PIL
 easy_install cssutils

How to install

  • First, install a version of Mapnik. For this project you can use Mapnik 0.7.1 or above

for this project. I recommend using Mapnik2 since it introduces the use of scaling factors to render map objects. This is very useful since this way the rendered map quality is better suited to the area of the selected paper.

  • While installing Mapnik you must have installed libxml2. The Python bindings for this module are also used:
 sudo apt-get install libxml2 libxslt-dev
  • Checkout mapnik_osm. This includes the symbols that OSM uses, plus its original stylesheet.
 cd ~/mapdata/
 svn co http://svn.openstreetmap.org/applications/rendering/mapnik/ mapnik_osm
  • Download the needed shapefiles (also check the get_coastlines.sh script in mapnik_osm)
 tar -xvzf world_boundaries-spherical.tgz
 mv world_boundaries ~/mapdata
 tar -xvjf processed_p.tar.bz2
 mv processed_p.dbf processed_p.index processed_p.shp processed_p.shx ~/mapdata/world_boundaries
 tar -xvjf shoreline_300.tar.bz2
 mv shoreline_300.dbf shoreline_300.index shoreline_300.shp shoreline_300.shx ~/mapdata/world_boundaries
  • Checkout the project from SVN:
 svn checkout http://townguide.googlecode.com/svn/branches/GSoC10/ openpapermaps
 cd openpapermaps
 
  • In order to draw the markers on the map you will need to install aggdraw.

Unfortunately, it seems that when trying to install it with `easy_install aggdraw` the freetype support is not enabled thus you will need to install it from source.

svn co http://svn.effbot.org/public/tags/aggdraw-1.2a3-20060212
#Edit `setup.py` and change FREETYPE_ROOT to suit your environment (on mine FREETYPE_ROOT="/usr" seemed to work just fine)
export CFLAGS="-fpermissive"   
python setup.py build_ext -i
sudo python setup.py install
 

Now let's install the modules of this project.

  • Install townguide-py
 cd townguide-py
 python setup.py install
  • Install djtownguide
 cd djtownguide
 python setup.py install
  • Install mapnikstyleshare
 cd mapnik-styleshare
 python setup.py install

If you want to use the Cascadenik, you should add the branches to your path rather than installing them.

  • Add each module to your PYTHONPATH, e.g.
 export PYTHONPATH=/home/username/openpapermaps:$PYTHONPATH
 export PYTHONPATH=/home/username/openpapermaps/cascadenik-openpapermaps:$PYTHONPATH
 export PYTHONPATH=/home/username/openpapermaps/cascadenik-xmlbad-openpapermaps:$PYTHONPATH

Configuring the OpenPaperMaps Django project

Inside of the `openpapermaps` folder you can find an example Django project that is configured to use djtownguide and mapnikstyleshare. In order to use it copy `settings.py.example` and set up the following:

First, create the folders where the maps and style thumbnails will be saved. These need to be writable by Django.

cd openpapermaps 
mkdir rendered_maps
mkdir style_images
chmod 777 rendered_maps
chmod 777 style_images

The folder where you save the styles also needs to be writable by Django:

chmod 777 ~/mapdata/mapnik_osm/

Django settings:

    # Set up the required parameters to connect to your database
    DATABASE_ENGINE = 'mysql'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
    DATABASE_NAME = 'openpapermaps'     # Or path to database file if using sqlite3.
    DATABASE_USER =              # Not used with sqlite3.
    DATABASE_PASSWORD =          # Not used with sqlite3.
    # NOTE: Both djtownguide and mapnikstyleshare follow the Django pluggable app pattern
    # thus you can also choose to only use one of them.
    INSTALLED_APPS = (
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.sites',
   'djtownguide',
   'mapnikstyleshare',
   #'south',  # use of south is completely optional
   )

djtownguide settings:

   # Folder where the rendered maps will be saved
   TOWNGUIDE_OUTPUT_DIR = os.path.join(PROJECT_ROOT, 'rendered_maps')
   TOWNGUIDE_DEFAULT_OSM_XML_STYLE = '/home/username/mapdata/mapnik_osm/osm_styles/osm.xml'
   # Parameters to connect to the PostGIS database.
   TOWNGUIDE_POSTGIS_USERNAME = 'mapnik'
   TOWNGUIDE_POSTGIS_DB = 'mapnik'
   DJTOWNGUIDE_MEDIA_PREFIX = '/maps/' # Starting url for djtownguide assets
   # API Key to use the search feature from Google Maps.
   # http://code.google.com/apis/maps/signup.html
   DJTOWNGUIDE_GOOGLE_API_KEY = "{api key}"
   
   # If you use the option to make the database grow on demand
   # by downloading extracts from the XAPI include the path to the default.style here.
   OSM2PGSQL_DEFAULT_STYLE_DIR = '/home/username/osm2pgsql/'

mapnikstyleshare options

   # Starting url for mapnikstyleshare assets
   MAPNIKSTYLESHARE_MEDIA_PREFIX = '/mapstyles/' 
   # Path to the folder where the thumbnails of the styles will be saved
   MAPNIKSTYLESHARE_STYLE_IMAGES_DIR = os.path.join(PROJECT_ROOT, 'style_images')
   
   # Path to the folder where the stylesheets will be saved so that 
   # so that townguide can use them if both apps are installed together
   OSM_STYLES_OUTPUT_DIR = '/home/username/mapdata/mapnik_osm/osm_styles/'
   # If you are using Mapnik2 you can opt to choose MAPNIK2_STYLES
   # which will upgrade the stylesheets on the fly so that Mapnik2 
   # can be used for the backend of all the application.
   USE_MAPNIK2_STYLES = True    			  
  • Create the database for your project. NOTE: I haven't tested with other databases,

If you're using mysql you can create it like this:

  CREATE DATABASE openpapermaps CHARACTER SET utf8;

I think you can make it work with postgresql by setting the tababase in settings.py to postgresql-pscycopg2. You need to change the database access restrictions as described in the [Mapnik/PostGIS] wiki page to avoid 'access denied' errors. (GJ 05sep2010

  • Run `python manage.py syncdb` to create the tables in the database
  • Run the development server with `python manage.py runserver` to test your installation

Starting the daemon

The daemon is a Twisted application that fetches the latest submitted maps and renders them with mapnik.

To start it:

cd openpapermaps
twistd -y townguide-daemon.py

You can modify the behavior of the daemon on the fly by connecting to its process with: `telnet localhost 2323`

Now enter one of the following options:

.renderlatest  => forcefully renders the latest job without waiting
.start, .stop => They start/stop the periodic fetching of jobs
.timeout 40 => In miliseconds, this tells the daemon how much should it wait before going to fetch another batch of jobs
.download 30 => If you don't count with a full database already, you can try downloading the data for map with id=30 like this.
.renderjob 30 => This is the same as re-customizing the map through the web interface.

If you want to debug the daemon it is useful to do `tail twistd.log -f`

Starting the django application with twisted

Instead of using the development server of Django, you can use the one from Twisted web. You can start the server like this:

   twistd -ny server.py --pidfile django.pid --logfile django.log

Further work

This initial work that I did for GSoC was very fun in doing, and some of the features that I would like to be working in the near future are:

  • Optimize cluster markers: The clustering algorithm needs to be improved and also consider what are some of the best practices in Cartography to solve this problem.
  • Optimize selected area for selected paper size (or, how to deal with big maps): Currently the user is free to select whatever area she wants through the OpenLayers interface. So if the user selects a very map with very large width and small height, the map will be scaled so that the area that the user asked will be rendered in the PDF. Another option would be to split the map onto several pages though an intuitive user interface for this needs to be thought out first.
  • Support for custom tags: I initially thought of the application as either growing on demand using the XAPI service or provided with a full database by using a service like Mapbox. There also scenario where a user might be interested in drawing markers using custom tags that were added to the postgis database using hstore.
  • Cascadenik Editor: With the help of some recent changes that were done on the `xmlbad` branch of Cascadenik, I though of creating a sample editor where you can test out some of features of Cascadenik stylesheets. Currently this editor is part of the Mapnikstyleshare though I'm thinking of using some of it to create an app to test and learn Cascadenik Styles. It would be very cool to have something akin to (http://www.w3schools.com/css/tryit.asp?filename=trycss_syntax1) to test out this kind of styles and learn its features.

Support

For support on this project you can contact: wquevedo [ at ] acm.org, or add a ticket at http://redmine.openpapermaps.com

Specs

The current specs of the project can be accessed here:

Functional Specs:

http://redmine.openpapermaps.com/attachments/17/functional_specs.pdf or https://github.com/wallyqs/mapnik-osm-stuff/raw/master/specs/functional_specs.pdf

Design Specs:

http://redmine.openpapermaps.com/attachments/18/design_spec.pdf or https://github.com/wallyqs/mapnik-osm-stuff/raw/master/specs/design_specs/design_spec.pdf

Related

Redmine of the project: http://redmine.openpapermaps.com/

Nicholas Marichal's initial idea: User_talk:Nicolasmarichal

State of the Map Conference by Mike Migurski: http://vimeo.com/5593879

Indiemapper: http://indiemapper.com/

Townguide: http://www.townguide2.webhop.net/

Walking Papers Maposmatic