Install 2 different Styles on your Tileserver and Leaflet

This is an example configuration on how to run two different map styles (OSMBright and openstreetmap-carto) on one renderd and leaflet server. For an instruction on how to install a tileserver with openstreetmap-carto and leaflet, see here, for instructions for OSMBright, click here.

osm-multiple-styles

renderd.conf

Each style has an own section with an own tiledir and URI. Make sure that both tiledirs exists and is owned by the user which runs renderd.

[renderd]
socketname=/var/run/renderd/renderd.sock
num_threads=4
tile_dir=/var/lib/mod_tile
stats_file=/var/run/renderd/renderd.stats

[mapnik]
plugins_dir=/usr/lib/mapnik/2.2/input
font_dir=/usr/share/fonts/truetype
font_dir_recurse=1

[default]
URI=/osm_tiles-carto/
TILEDIR=/var/lib/mod_tile-carto
XML=/usr/local/src/openstreetmap-carto-2.29.1/style.xml
HOST=localhost
TILESIZE=256
;HTCPHOST=proxy.openstreetmap.org
;** config options used by mod_tile, but not renderd **
;MINZOOM=0
;MAXZOOM=18
;TYPE=png image/png
;DESCRIPTION=This is a description of the tile layer used in the tile json request
;ATTRIBUTION=&copy;<a href=\"http://www.openstreetmap.org/\">OpenStreetMap</a> and <a href=\"http://wiki.openstreetmap.org/wiki/Contributors\">contributors</a>, <a href=\"http://opendatacommons.org/licenses/odbl/\">ODbL</a>
;SERVER_ALIAS=http://localhost/
;CORS=http://www.openstreetmap.org
;ASPECTX=1
;ASPECTY=1
;SCALE=1.0

[defaultbr]
URI=/osm_tiles/
TILEDIR=/var/lib/mod_tile
XML=/usr/local/share/maps/style/OSMBright/OSMBright.xml
HOST=localhost
TILESIZE=256
;HTCPHOST=proxy.openstreetmap.org
;** config options used by mod_tile, but not renderd **
;MINZOOM=0
;MAXZOOM=18
;TYPE=png image/png
;DESCRIPTION=This is a description of the tile layer used in the tile json request
;ATTRIBUTION=&copy;<a href=\"http://www.openstreetmap.org/\">OpenStreetMap</a> and <a href=\"http://wiki.openstreetmap.org/wiki/Contributors\">contributors</a>, <a href=\"http://opendatacommons.org/licenses/odbl/\">ODbL</a>
;SERVER_ALIAS=http://localhost/
;CORS=http://www.openstreetmap.org
;ASPECTX=1
;ASPECTY=1
;SCALE=1.0

The tiles in http://localhost/osm_tiles are now rendered with OSMBright and http://localhost/osm_tiles-carto with openstreetmap.carto.

Leaflet

<!DOCTYPE html>
<html>
<head>
<title>Full Screen Leaflet Map</title>
<meta charset="utf-8" />
<link
rel="stylesheet"
href="./leaflet.css"
/>
<style>
body {
padding: 0;
margin: 0;
}
html, body, #map {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>

<script
src="./leaflet.js">
</script>

<script>
var osmLink= '<a href="http://openstreetmap.org">OpenStreetMap</a>';

var osmUrlcarto = './osm_tiles-carto/{z}/{x}/{y}.png',
osmUrlbright = './osm_tiles/{z}/{x}/{y}.png',
osmAttrib = '&copy; ' + osmLink + ' Contributors';

var osmMAPcarto = L.tileLayer(osmUrlcarto, {attribution: osmAttrib}),
osmMAPbright = L.tileLayer(osmUrlbright, {attribution: osmAttrib});

var map = L.map('map', {layers: [osmMAPbright]}).setView([48.4394, 14.7703], 14);
var baseLayers = {
"OSM Carto" : osmMAPcarto,
"OSM Bright" : osmMAPbright
};
L.control.layers(baseLayers).addTo(map);
</script>
</body>
</html>

 

 

HowTo: Tileserver with openstreetmap.org Style and Leaflet on Debian Jessie

Here i want to describe how i set up my own little Maps-Server just like openstreetmap.org or maps.google.com based on OpenStreetMap.
It is running on an average notebook (8GB RAM, i7, 1TB HDD, no SSD), without any fancy optimization and even in a chroot. It is not very fast and i just use it with Austria (the whole Planet would be way too big, there is no chance that this would work on this ordinary Notebook).
Ovarall i am very pleased and it is fast enough for one user to use it.

This HowTo is based on switchosm and debianwiki. I think that about 90% will be the same.

First, lets take a look at the result:
tileserver

This whole map here is running offline, without the need of any internet connection. You will realize that there is no search field and no navigation option. This is because it basically just displays tiles. Maybe i will look into adding navigation and a search bar in the future (there are Leaflet PlugIns for that or projects like nominatim).

Whats needed:

  • Mapnik to render tiles
  • Postgresql with postgis for the map data (it will be importet with osm2pgsql from some .osm.pbf file)
  • openstreetmap-carto, a Carto Style for Mapnik, which is basically like a CSS and tells Mapnik how it should render the map
    There are other styles like OSM Bright too.
  • Apache2 with mod_tile and renderd to serve the tiles
  • Leaflet to create a map out of tiles

Install some requirements

We will take as much as possible from the package manager, but we still have to compile things like mod_tile from source, so we need seome dev packages.

apt-get install libboost-all-dev subversion git-core tar unzip wget bzip2 build-essential autoconf libtool libxml2-dev libgeos-dev libgeos++-dev libpq-dev libbz2-dev libproj-dev munin-node munin libprotobuf-c-dev protobuf-c-compiler libfreetype6-dev libpng12-dev libtiff5-dev libicu-dev libgdal-dev libcairo-dev libcairomm-1.0-dev apache2 apache2-dev libagg-dev liblua5.2-dev ttf-unifont lua5.1 liblua5.1-0-dev 

Install postgresql

apt-get install postgresql postgresql-contrib postgis postgresql-9.3-postgis-2.1 osm2pgsql

Install mapnik and node-carto

apt-get install python-mapnik libmapnik-dev maptnik-utils node-carto curl

Install basic OpenStreetMap tools (it’s needed for the openstreetmap-carto style)

apt-get install osmosis gdal-bin

Setup Database

Start postgresql if it’s not already running:

/etc/init.d/postgresql start

First we have to change the postgresql tamplate to use UTF8.

su - postgres
psql -U postgres
postgres=# update pg_database set datallowconn = TRUE where datname = 'template0';
UPDATE 1
postgres=# \c template0
You are now connected to database "template0".
template0=# update pg_database set datistemplate = FALSE where datname = 'template1';
UPDATE 1
template0=# drop database template1;
DROP DATABASE
template0=# create database template1 with template = template0 encoding = 'UTF8';
CREATE DATABASE
template0=# update pg_database set datistemplate = TRUE where datname = 'template1';
UPDATE 1
template0=# \c template1
You are now connected to database "template1".
template1=# update pg_database set datallowconn = FALSE where datname = 'template0';
UPDATE 1
exit

Now we can create the Database. Our username will be tilesrv

su - postgres
createuser tilesrv
createdb -E UTF8 -O tilesrv gis
exit

Create the unix user:

sudo useradd -m tiesrv
sudo passwd tilesrv

Setup postgis in postgresql

su - postgres
psql
\c gis
CREATE EXTENSION postgis;
ALTER TABLE geometry_columns OWNER TO username;
ALTER TABLE spatial_ref_sys OWNER TO username;
\q
exit

Install mod_tile and rendr

There is no Debian Package for mod_tile, so we have to compile it from source

su - root
cd /usr/local/src
git clone git://github.com/openstreetmap/mod_tile.git
cd mod_tile
./autogen.sh
./configure
make
make install
make install-mod_tile
ldconfig
exit

Install openstreetmap-carto Style

We will download openstreetmap-carto from git (this needs to be done before importing the data with osm2pgsql because the style-file describes what data goes where into the database).

su - root
cd /usr/local/src
wget https://github.com/gravitystorm/openstreetmap-carto/archive/v2.29.1.tar.gz
tar -xzf v2.29.1.tar.gz

Now we need to build a style for mapnik out of openstreetmap-carto

cd ~/openstreetmap-carto-2.29.1/
./get-shapefiles.sh
#if your database is not named gis, you need to change it in ./project.mml before doing the next step
carto project.mml &gt; style.xml
exit

Import OpenStreetMap Data to postgresql

We need to download OpenStreetMap data, don’t pick the whole planet.osm.pbf. Pick something smaller from geofabrik.de, like Austria.

mkdir /usr/local/share/maps/austria
chown tilesrv /usr/local/share/maps/austria
cd /usr/local/share/maps/austria
wget http://download.geofabrik.de/europe/austria-latest.osm.pbf

Now we can import this data to the postgresql database.
This will take some time. On my 8GB RAM Notebook without SSD it took 5 hours to import Austria! There are some pages and articles on how to tune your system on the OpenStreetMap wiki, so that it will take not as much time, like changing buffer sizes in /etc/postgresql/9.4/main/postgresql.conf.
You will need to adjust the -C value according to your RAM size.

su - tilesrv
osm2pgsql --slim -d gis -C 8000 --hstore -S /usr/local/srv/openstreetmap-carto-2.29.1/openstreetmap-carto.style /usr/local/share/maps/austria/austria-latest.osm.pbf

This is how osm2pgsql is beheaving when everything is fine:

$ time osm2pgsql --slim -d gis -C 8000 --number-processes 3 S /usr/local/srv/openstreetmap-carto-2.29.1/openstreetmap-carto.style /usr/local/share/maps/austria/austria-latest.osm.pbf
osm2pgsql SVN version 0.86.0 (64bit id space)

Using projection SRS 900913 (Spherical Mercator)
Setting up table: planet_osm_point
NOTICE:  table "planet_osm_point" does not exist, skipping
NOTICE:  table "planet_osm_point_tmp" does not exist, skipping
Setting up table: planet_osm_line
NOTICE:  table "planet_osm_line" does not exist, skipping
NOTICE:  table "planet_osm_line_tmp" does not exist, skipping
Setting up table: planet_osm_polygon
NOTICE:  table "planet_osm_polygon" does not exist, skipping
NOTICE:  table "planet_osm_polygon_tmp" does not exist, skipping
Setting up table: planet_osm_roads
NOTICE:  table "planet_osm_roads" does not exist, skipping
NOTICE:  table "planet_osm_roads_tmp" does not exist, skipping
Using built-in tag processing pipeline
Allocating memory for dense node cache
Allocating dense node cache in one big chunk
Allocating memory for sparse node cache
Sharing dense sparse
Node-cache: cache=8000MB, maxblocks=1024000*8192, allocation method=11
Mid: pgsql, scale=100 cache=8000
Setting up table: planet_osm_nodes
NOTICE:  table "planet_osm_nodes" does not exist, skipping
Setting up table: planet_osm_ways
NOTICE:  table "planet_osm_ways" does not exist, skipping
Setting up table: planet_osm_rels
NOTICE:  table "planet_osm_rels" does not exist, skipping

Reading in file: /usr/local/share/maps/austria/austria-latest.osm.pbf
Processing: Node(50300k 118.9k/s) Way(5427k 24.90k/s) Relation(99170 8.95/s)  parse time: 11722s

Node stats: total(50300269), max(4449627239) in 423s
Way stats: total(5427806), max(447905198) in 218s
Relation stats: total(99178), max(6648485) in 11081s
Committing transaction for planet_osm_point
Committing transaction for planet_osm_line
Committing transaction for planet_osm_polygon
Committing transaction for planet_osm_roads

Going over pending ways...
3675813 ways are pending

Using 3 helper-processes
Helper process 1 out of 3 initialised
Helper process 2 out of 3 initialised
Helper process 0 out of 3 initialised
Process 0 finished processing 1225271 ways in 829 sec
Process 2 finished processing 1225271 ways in 831 sec
Process 1 finished processing 1225271 ways in 831 sec

All child processes exited

3675813 Pending ways took 836s at a rate of 4396.91/s
Committing transaction for planet_osm_point
Committing transaction for planet_osm_line
Committing transaction for planet_osm_polygon
Committing transaction for planet_osm_roads

Going over pending relations...
0 relations are pending

Using 3 helper-processes
Process 2 finished processing 0 relations in 4 sec
Process 1 finished processing 0 relations in 4 sec
Process 0 finished processing 0 relations in 4 sec

All child processes exited
0 Pending relations took 4s at a rate of 0.00/s

Sorting data and creating indexes for planet_osm_point
node cache: stored: 50300269(100.00%), storage efficiency: 52.02% (dense blocks: 12150, sparse nodes: 42121688), hit rate: 100.00%
Sorting data and creating indexes for planet_osm_line
Sorting data and creating indexes for planet_osm_polygon
Sorting data and creating indexes for planet_osm_roads
Stopping table: planet_osm_nodes
Stopped table: planet_osm_nodes in 0s
Stopping table: planet_osm_ways
Building index on table: planet_osm_ways (fastupdate=off)
Stopping table: planet_osm_rels
Building index on table: planet_osm_rels (fastupdate=off)
Analyzing planet_osm_point finished
Analyzing planet_osm_roads finished
Analyzing planet_osm_line finished
Copying planet_osm_point to cluster by geometry finished
Creating geometry index on  planet_osm_point
Stopped table: planet_osm_rels in 77s
Copying planet_osm_roads to cluster by geometry finished
Creating geometry index on  planet_osm_roads
Creating osm_id index on  planet_osm_roads
Creating indexes on  planet_osm_roads finished
All indexes on  planet_osm_roads created  in 353s
Completed planet_osm_roads
Creating osm_id index on  planet_osm_point
Creating indexes on  planet_osm_point finished
All indexes on  planet_osm_point created  in 399s
Completed planet_osm_point
Analyzing planet_osm_polygon finished
Copying planet_osm_line to cluster by geometry finished
Creating geometry index on  planet_osm_line
Creating osm_id index on  planet_osm_line
Creating indexes on  planet_osm_line finished
All indexes on  planet_osm_line created  in 734s
Completed planet_osm_line
Copying planet_osm_polygon to cluster by geometry finished
Creating geometry index on  planet_osm_polygon
Creating osm_id index on  planet_osm_polygon
Creating indexes on  planet_osm_polygon finished
All indexes on  planet_osm_polygon created  in 1715s
Completed planet_osm_polygon
Stopped table: planet_osm_ways in 5640s

Osm2pgsql took 18205s overall
816.43user 65.39system 5:03:25elapsed 4%CPU (0avgtext+0avgdata 1029488maxresident)k
1009456inputs+0outputs (35major+452435minor)pagefaults 0swaps

Configure renderd

The renderd settings are in /usr/local/etc/renderd.conf, you need to check at least the following lines:

socketname=/var/run/renderd/renderd.sock
plugins_dir=/usr/lib/mapnik/2.2/input
font_dir=/usr/share/fonts/truetype
TILEDIR=/var/lib/mod_tile
XML=/usr/local/src/openstreetmap-carto-2.29.1/style.xml
HOST=localhost

And we need to create the directories for renderd

mkdir /var/run/renderd
chown tilesrv /var/run/renderd
mkdir /var/lib/mod_tile
chown tilesrv /var/lib/mod_tile

Configure Apache (mod_tile)

Now we have to configure Apache2.
Create a file /etc/apache2/conf-available/mod_tile.conf which contains:

LoadModule tile_module /usr/lib/apache2/modules/mod_tile.so

And add following lines to the section of /etc/apache2/sites-available/000-default.conf

LoadTileConfigFile /usr/local/etc/renderd.conf
ModTileRenderdSocketName /var/run/renderd/renderd.sock
# Timeout before giving up for a tile to be rendered
ModTileRequestTimeout 0
# Timeout before giving up for a tile to be rendered that is otherwise missing
ModTileMissingRequestTimeout 30

Enable the mod_tile configuration and restart Apache:

a2enconf mod_tile
/etc/init.d/apache2 restart

First test

Run renderd as user tilesrv:

su - tilesrv
renderd -f -c /usr/local/etc/renderd.conf

In a second console, reload apache2

service apache2 reload

Browse to http://localhost/osm_tiles/0/0/0.png and you should see a small picture of the world.

Install init-file for renderd

We want to autosrat renderd, so we need to install the init-script

cp /usr/local/src/mod_tile/debian/renderd.init /etc/init.d/renderd
chmod +x /etc/init.d/renderd

The init file /etc/init.d/renderd needs to be configured, change following lines:

DAEMON=/usr/local/bin/$NAME
DAEMON_ARGS=" -c /usr/local/etc/renderd.conf"
RUNASUSER=tilesrv

Start renderd:

/etc/init.d/renderd start

Install Leaflet

Last but not least we need install some fancy slippy map on our webserver. We choose Leaflet.
It should be usable without internet, so we download it.

cd /var/www/html
wget https://unpkg.com/leaflet@1.0.1/dist/leaflet.js
wget https://unpkg.com/leaflet@1.0.1/dist/leaflet.css

Now we create our /var/www/html/index.html file which will display a leaflet map in fullscreen:


Full Screen Leaflet Map

&nbsp;
<div id="map"></div>
&nbsp;

Be sure to set the location in .setView, which is displayed first when visiting the site, to some tile with high zoomlevel which is available in your Map-Data.

Start everything

Restart all necessary services

/etc/init.d/postgresql restart
/etc/init.d/renderd restart
/etc/init.d/apache2 restart

Now everything is ready and you can browse to http://localhost
Be aware that the map will be very slow and you have to wait a few minutes for tiles with low zoomlevels. Don’t get impatient. Keep it open and wait. It will get faster over time when the server already rendered some tiles.