OpenPaperMaps
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
- Mapnik, or Mapnik2 (Recommended link: https://trac.mapnik.org/wiki/UbuntuInstallation, for Mapnik2: https://trac.mapnik.org/wiki/Mapnik2)
- PostGIS enabled database with the 900913 projection enabled.
- World boundaries shapefiles
- osm2psql default.style file
- mapnik_osm (svn co https://svn.openstreetmap.org/applications/rendering/mapnik/)
- Required Python modules:
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 https://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/