Tiles Server. Renderització
Contingut
- 1 Mapnik: crea les teves pròpies tiles. Cas d'ús: Andorra
- 1.1 Software installation
- 1.2 Installing postgresql / postgis
- 1.3 Installing osm2pgsql
- 1.4 Instal·lació de Mapnik
- 1.5 Install mod_tile and renderd
- 1.6 Stylesheet configuration
- 1.7 Loading data: Andorra
- 1.8 Setting up your webserver
- 1.9 Viewing tiles
- 1.10 Aplicació mínima per navegar pel mapa d'Andorra
- 2 Dibuixar les tiles a mà
Mapnik: crea les teves pròpies tiles. Cas d'ús: Andorra
La idea és crear un mapa amb un estil propi, personalitzat. Carregar només els tags que interessin. Per exemple, es podria tenir uns tiles mínims, que només mostrin les vies principals, com el GPS Bryton 450E. També es podria generar els tiles d'una zona concreta, per ex el Berguedà.
Manually building a tile server:
Seuim aquest enllaç, que ha funcionat:
Software installation
sudo apt install libboost-all-dev 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-c0-dev protobuf-c-compiler libfreetype6-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-dev libgeotiff-epsg
Installing postgresql / postgis
Què és PostGis?: PostGIS is a spatial database extender for PostgreSQL object-relational database. It adds support for geographic objects allowing location queries to be run in SQL.
sudo apt-get install postgresql postgresql-contrib postgis postgresql-10-postgis-2.4 postgresql-10-postgis-scripts
En el tutorial es fa servir l'usuari renderaccount. S'entén que és un usuari del SO, per exemple joan:
sudo -u postgres -i (treballem amb l'usuari postgres del SO createuser joan # answer yes for superuser (although this isn't strictly necessary) createdb -E UTF8 -O joan gis
Per rederitzar les tiles: sudo -u postgres renderd -f -c /usr/local/etc/renderd.conf
$ psql \c gis CREATE EXTENSION postgis; CREATE EXTENSION hstore; ALTER TABLE geometry_columns OWNER TO joan; ALTER TABLE spatial_ref_sys OWNER TO joan; \q exit (tornem a l'usuari normal del SO)
Evidentment, l'usuari joan ha de ser un usuari del SO. En el cas de què no ho sigui, ara seria el moment de fer-ho:
sudo useradd -m joan sudo passwd joan
Installing osm2pgsql
És l'eina que ens permetrà migrar les dades OSM i convertir-les a un format PostgreSQL.
Crearem dins del home la carpeta src/, i d'aquí penjaran diferents projectes que necessitem.
mkdir ~/src cd ~/src git clone git://github.com/openstreetmap/osm2pgsql.git cd osm2pgsql
I ara compilem el projecte. Primer necessitem les eines de compilació:
sudo apt install make cmake g++ libboost-dev libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libgeos-dev libgeos++-dev libproj-dev lua5.2 liblua5.2-dev
I ara compilem i instal·lem:
mkdir build && cd build cmake .. make sudo make install
Instal·lació de Mapnik
És el software que necessitem per generar els mapes (els tiles). Recordem que OSM és tan sols una base de dades amb informació geogràfica. Amb Mapnik podem posar totes aquestes dades sobre un mapa, amb diferents nivells de zoom.
sudo apt-get install autoconf apache2-dev libtool libxml2-dev libbz2-dev libgeos-dev libgeos++-dev libproj-dev gdal-bin libmapnik-dev mapnik-utils python-mapnik
Comprovem que tenim Mapnik instal·lat correctament:
python >>> import mapnik >>> >>> quit()
No cal tenir la última versió de Python. Amb una versió 2.7 també funciona.
Install mod_tile and renderd
- mod_tile is an Apache module that handles requests for tiles
- renderd is a daemon that actually renders tiles when mod_tile requests them.
Què té que veure aquest projecte amb Apache? doncs molt. Estem fent una aplicació web per visualitzar mapes. Els tiles no estan creats. Es creen (es renderitzen) a mida que es demanen. Per tant, davant d'un request d'un determinat tile, es llença l'aplicació que renderitza el tile.
cd ~/src git clone -b switch2osm git://github.com/SomeoneElseOSM/mod_tile.git cd mod_tile ./autogen.sh configure make sudo make install sudo make install-mod_tile sudo ldconfig
La última línia, ldconfig:
NAME ldconfig - configure dynamic linker run-time bindings SYNOPSIS /sbin/ldconfig [-nNvXV] [-f conf] [-C cache] [-r root] directory... /sbin/ldconfig -l [-v] library... /sbin/ldconfig -p DESCRIPTION ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line
Stylesheet configuration
Aquí definirem com volem visualitzar el mapa. De moment, només ens interessarà la plantilla per defecte. Però és aquí on podrem definir quina és la informació que volem visualitzar en els nostres mapes. I quin és el look que han de tenir.
cd ~/src git clone git://github.com/gravitystorm/openstreetmap-carto.git cd openstreetmap-carto sudo apt install npm nodejs sudo npm install -g carto carto -v
M'ha quedat instal·lada la versió 1.2.0.
carto project.mml > mapnik.xml
You now have a Mapnik XML stylesheet at /home/joan/src/openstreetmap-carto/mapnik.xml. Aquest és el fitxer XML important.
Loading data: Andorra
Elegim Andorra perquè és petit, per fer proves.
mkdir ~/data cd ~/data wget https://download.geofabrik.de/asia/azerbaijan-latest.osm.pbf
Introduïm la informació que hem descarregat d'Andorra a la base de dades:
osm2pgsql -d gis --create --slim -G --hstore --tag-transform-script ~/src/openstreetmap-carto/openstreetmap-carto.lua -C 2500 --number-processes 1 -S ~/src/openstreetmap-carto/openstreetmap-carto.style ~/data/andorra-latest.osm.pbf
Shapefile download. Necessitem descarregar informació addicional:
cd ~/src/openstreetmap-carto/ scripts/get-shapefiles.py
Fonts. Necessitem descarregar fonts addicionals.
sudo apt-get install fonts-noto-cjk fonts-noto-hinted fonts-noto-unhinted ttf-unifont
Setting up your webserver
Configure renderd. The config file for renderd is /usr/local/etc/renderd.conf.
sudo nano /usr/local/etc/renderd.conf num_threads=4 XML=/home/joan/src/openstreetmap-carto/mapnik.xml URI=/hot/
Configuring Apache
sudo mkdir /var/lib/mod_tile sudo chown joan /var/lib/mod_tile sudo mkdir /var/run/renderd sudo chown joan /var/run/renderd sudo nano /etc/apache2/conf-available/mod_tile.conf afegir: LoadModule tile_module /usr/lib/apache2/modules/mod_tile.so sudo a2enconf mod_tile
sudo nano /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
sudo service apache2 reload sudo service apache2 reload
(dues vegades?)
Running renderd for the first time Next, we’ll run renderd to try and render some tiles. Initially we’ll run it in the foreground so that we can see any errors as they occur:
$ renderd -f -c /usr/local/etc/renderd.conf
I ja podem visualitzar alguna tile:
Running renderd in the background:
La idea és que funcioni el renderd a mida que anem navegant en la zona d'interès.
nano ~/src/mod_tile/debian/renderd.init sudo cp ~/src/mod_tile/debian/renderd.init /etc/init.d/renderd sudo chmod u+x /etc/init.d/renderd sudo cp ~/src/mod_tile/debian/renderd.service /lib/systemd/system/
sudo /etc/init.d/renderd start
I si volem que arrenqui en l'inici de sistema:
sudo systemctl enable renderd
Viewing tiles
A mida que anem navegant, podem veure com es van creant les tiles:
tail -f /var/log/syslog | grep " TILE "
I podem veure les tiles a:
tile_dir=/var/lib/mod_tile
Podem provar altres url, com ara:
- http://localhost/hot/1/0/0.png -> es genera el tile que correspon a Amèrica del Nord
... Feb 26 16:13:51 joan renderd[5048]: DEBUG: START TILE ajt 10 512-519 376-383, new metatile Feb 26 16:13:51 joan renderd[5048]: DEBUG: DONE TILE ajt 8 120-127 96-103 in 0.415 seconds Feb 26 16:13:52 joan renderd[5048]: DEBUG: DONE TILE ajt 10 512-519 376-383 in 1.326 seconds Feb 26 16:13:52 joan renderd[5048]: DEBUG: START TILE ajt 10 520-527 376-383, new metatile Feb 26 16:13:53 joan renderd[5048]: DEBUG: DONE TILE ajt 10 520-527 376-383 in 0.504 seconds ...
Ho podem fer amb Leaflet o bé amb Openlayers.
script leaflet_andorra.html:
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script> <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" /> <style> html, body { height: 100%; padding: 0; margin: 0; } #map { /* configure the size of the map */ width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> <script> // initialize Leaflet var map = L.map('map').setView({lon: 1.5549, lat: 42.5546}, 2); // add the OpenStreetMap tiles L.tileLayer('http://localhost/hot/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>' }).addTo(map); // show the scale bar on the lower left corner L.control.scale().addTo(map); // show a marker on the map L.marker({lon: 0, lat: 0}).bindPopup('The center of the world').addTo(map); </script> </body> </html>
script openlayers_andorra.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>Simple Map</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css" type="text/css"> <style> html, body { height: 100%; padding: 0; margin: 0; } #map { /* configure the size of the map */ width: 100%; height: 100%; } </style> <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x --> <script src="http://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script> <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script> </head> <body> <div id="map" class="map"></div> <div id="popup" style="padding: 10px;background-color: white;"></div> <script> var map = new ol.Map({ layers: [ new ol.layer.Tile({ // This illustrates a custom tiles source but for using // official OpenStreetMap server new ol.source.OSM() // instead of new ol.source.XYZ(...) is enough source: new ol.source.XYZ({ attributions: [ ol.source.OSM.ATTRIBUTION, 'Tiles courtesy of ' + '<a href="http://openstreetmap.org">' + 'OpenStreetMap' + '</a>' ], url: 'http://localhost/hot/{z}/{x}/{y}.png' }) }) ], controls: ol.control.defaults({ // Set to display OSM attributions on the bottom right control attributionOptions: { collapsed: false } }).extend([ new ol.control.ScaleLine() // Add scale line to the defaults controls ]), target: 'map', view: new ol.View({ center: ol.proj.fromLonLat([0, 0]), zoom: 2 }) }); // Add vector layer with a feature and a style using an icon var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector({ features: [ new ol.Feature({ geometry: new ol.geom.Point( ol.proj.fromLonLat([0, 0]) ), name: 'The center of the world' }) ] }), style: new ol.style.Style({ image: new ol.style.Icon({ anchor: [0.5, 46], anchorXUnits: 'fraction', anchorYUnits: 'pixels', src: 'http://openlayers.org/en/latest/examples/data/icon.png' }) }) }); map.addLayer(vectorLayer); // Overlay to manage popup on the top of the map var popup = document.getElementById('popup'); var overLay = new ol.Overlay({ element: popup, position: ol.proj.fromLonLat([0, 0]) }); map.addOverlay(overLay); // Manage click on the map to display/hide popup map.on('click', function(e) { var info = []; map.forEachFeatureAtPixel(e.pixel, function (feature) { info.push(feature.get('name')); }); if (info.length > 0) { popup.innerHTML = info.join(','); popup.style.display = 'inline'; } else { popup.innerHTML = ' '; popup.style.display = 'none'; } }); </script> </body> </html>
Dibuixar les tiles a mà
(TBD)
https://openlayersbook.github.io/ https://wiki.openstreetmap.org/wiki/Tile_servers https://www.thunderforest.com/maps/opencyclemap/ https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png 3 exemples de renderització: https://b.tile.openstreetmap.org/3/4/2.png https://tile.thunderforest.com/cycle/3/4/2.png?apikey=f695b42354e84626afef4de11a5d6080 http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/3/4/2 -> compte! és una altra zona http://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png http://www.cach.ly/help/index.php/Custom_Tile_URL https://wiki.openstreetmap.org/wiki/Slippy_Map I aquí està explicat com ha de ser el format dels tiles: https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames Per ex: Bagà és 42.2575/1.8676 i ho vull visualitzar amb un zoom de 14. On és la tile que em mostra aquesta informació? n = 2 ^ zoom xtile = n * ((lon_deg + 180) / 360) ytile = n * (1 - (log(tan(lat_rad) + sec(lat_rad)) / π)) / 2 2^14 = 16384 x = 16384((1.8676+180) / 360) = 8277 y = 16384* (1-(ln(tg(0.03259)+sec(0.03259))/pi))/2 = 6066 https://b.tile.openstreetmap.org/14/8277/6066.png Això és el que necessito: http://tools.geofabrik.de/map/#12/41.9194/1.8279&type=Geofabrik_Standard&grid=1 També: https://openlayers.org/en/latest/examples/canvas-tiles.html
creat per Joan Quintana Compte, febrer 2020