Je suis nouveau dans le monde fascinant des SIG, et je fais des recherches sur l'ensemble du sujet depuis quelques jours. Mon objectif est de servir des cartes à l'échelle de la planète avec des données OSM sur mes propres serveurs.
Ma pile est:
- Postgres + Postgis - Pour le stockage, la transformation et le traitement des données SIG.
- Mapnik - Bibliothèque pour rendre les tuiles
- Tilestache - Servir et mettre en cache les tuiles
- Nginx - Proxy inverse de Tilestache
- Brochure ( Slippy carte client)
Pour importer et styliser des données OSM, j'utilise
- Fichier PBF (Extraire / Planète)
- osm2pgsql
- CartoCSS
- openstreetmap-carto
- Kosmtik - Carte graphique pour le développement / débogage
Étant donné que le fichier complet de la planète est énorme, j'utilise actuellement un extrait de Sao Paulo , qui est assez bon / assez petit pour les tests.
Avant d'atteindre le problème que je rencontre, je vais vous guider à travers les étapes que j'ai prises jusqu'à présent:
Ce qui a fonctionné
PostgreSQL et PostGIS sont correctement installés. J'utilise 9,6 pour le premier, 2,3 pour le second. J'ai également ajouté les extensions postgis_topology
et hstore
, qui seront utilisées plus tard.
J'ai installé osm2pgsql 0.92.0. Pour importer l'extrait de Sao Paulo, j'utilise
osm2pgsql -G U <user> -d <db> -C 1000 -W --hstore --style openstreetmap-carto.style --tag-transform-script openstreetmap-carto.lua <pbf>
Les hstore
, style
et les tag-transform-script
arguments sont nécessaires pour l'utilisation correcte du style de l' OSM, comme décrit ici .
Comme décrit dans l'installation openstreetmap-carto, j'ai également ajouté des index personnalisés et téléchargé les fichiers de formes et les polices nécessaires (à l'exception des emoji).
J'ai vérifié que les données d'extrait sont correctement chargées dans la base de données en utilisant QGIS. J'ai pu visualiser et interroger tous les points, polygones, lignes et routes. Tout est là.
Problèmes
La prochaine étape consiste à rendre les tuiles, et c'est là que j'ai des problèmes. J'ai mapnik et python-mapnik 3.x, ainsi que carto 0.18.2.
À partir de project.mml de l'OSM , j'ai généré mon propre project.xml en utilisant carto
. J'ai apporté les modifications suivantes au résultat:
- Ajoutez le nom d'utilisateur Postgres (paramètre
user
sur le XML de Mapnik ). Les informations de connexion restantes sont récupérées à partir de ~ / .pgpass . - Remplacer le répertoire relatif
data/<shape>.shp
par/full/path/data/<shape>.shp
- Remplacer le répertoire relatif
symbols/<symbol>.svg
par/full/path/symbols/<symbol>.svg
J'ai en quelque sorte testé ces changements: des répertoires incorrects pour les fichiers de formes et les symboles soulèveront une erreur lorsque Mapnik essaie de charger le style. Il en va de même pour les informations de base de données incorrectes.
Et voici le problème: chaque tuile rendue par Mapnik est "vierge" (fond bleu, qui est le fond défini pour OSM). Voici ce que j'ai essayé de résoudre ce problème:
Les choses que j'ai essayées
Peut-être que le style généré n'est pas valide d'une manière ou d'une autre. Peut-être qu'un polygone / une forme (l'océan?) En recouvre un autre.
J'ai installé Kosmtik, et cela a bien fonctionné! J'ai pu parcourir l'extrait, inspecter les données, zoomer et dézoomer à tous les niveaux.
Peut-être que je génère des tuiles au mauvais endroit
J'ai configuré TileStache avec Mapnik comme fournisseur. Ensuite, j'ai mis en place des règles de redirection à partir http://[abc].tile.openstreetmap.org
de l' http://myserver/<layer>
utilisation de switcheroo, comme décrit ici . Cela signifie que l'accès openstreetmaps.org
aurait toutes les tuiles rendues sur mon serveur.
Fait intéressant, le zoom 1 fonctionne (celui avec 4 tuiles). Je suppose qu'il utilise uniquement le fichier de formes planète / monde, qui a été téléchargé avec le style. Tout le reste, quel que soit le zoom ou l'emplacement, est rendu "vide". Ainsi, même lorsque vous naviguez à l'emplacement de l'extrait, il ne s'affichera pas correctement.
Notez que, lors de l'utilisation de Kosmtik, j'ai pu voir le nom de l'extrait aussi bas que le zoom 4.
Peut - être que je génère des tuiles au mauvais endroit
Les projections sont difficiles. Peut-être qu'il y a quelque chose qui est "mal traduit" quelque part.
J'ai donc analysé les demandes de Kosmtik (car elles fonctionnaient). Il utilise la bibliothèque Modestmaps, qui se traduit au format Slippy ( <zoom>/<x>/<y>
), même format utilisé par Leaflet, TileStache et openstreetmap.org
.
Par exemple, demander 17/48561/74357.png
sur Kosmtik fonctionne, mais la même tuile retourne comme "vide" sur TileStache. Ma théorie était que TileStache le traduisait d'une manière ou d'une autre en dehors de la zone d'extrait. (Même si TileStache utilisait "mercator sphérique" comme projection).
J'ai donc décidé d'utiliser directement les liaisons python de Mapnik. Jusqu'à présent, j'ai géré trois types de projections différents, voici ce que je sais d'eux. Corrigez-moi si j'ai tort, s'il-vous plait:
- EPSG4326 / WGS84 - Projection lon / lat habituelle, identique à celle utilisée sur le GPS. L'unité est les degrés.
- EPSG3857 / {Web, Google, Pseudo} mercator / 900913 - Utilisé sur la plupart des cartes Web en mosaïque. L'unité est en mètres (et non en "vrais" mètres, car elle se déforme fortement près des pôles).
- "Format glissant" - Pas une projection, mais encore un autre format à traduire.
Ainsi, le Slippy 17/48561/74357
serait proche -46.632(lon), -23.531(lat)
d'EPSG4326 et proche -5191050.49, -2696361.67
d'EPSG3875 / Google Mercator.
En utilisant python, j'ai généré ces tuiles de coordonnées directement sur Mapnik. Le résultat était toujours des tuiles vierges. Je crois que j'utilise les bonnes projections (plus à ce sujet plus tard).
Tout d'abord, une chose à noter. Il est clair que le problème n'est pas dans Mapnik, ni dans le style. D'une part, Kosmtik utilise Mapnik comme backend, et cela fonctionne très bien. Deuxièmement, si je génère intentionnellement une tuile en dehors de la zone d'extrait sur Kostmik, j'obtiens une tuile vierge, comme prévu.
Cela m'amène à croire que j'utilise la mauvaise projection dans le script python de Mapnik et TileStache. Avant d'afficher le code, une remarque sur OSM (encore une fois, veuillez me corriger si je me trompe):
- Les données «natives» OSM sont stockées dans EPSG4326
- osm2pgsql importe des données OSM au format EPSG3857, et c'est la projection sur Postgis.
- Le style de Mapnik (XML) a deux projections, entrée et sortie, expliquées ici :
- La projection d'entrée est définie au niveau de l'objet Carte et correspond au "système de coordonnées dans lequel la carte est rendue"
- La projection de sortie est définie au niveau de l'objet Layer et doit être identique à mes données.
Le XML de Mapnik qui en résulte a:
<Map srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over" background-color="#b5d0d0">
#snip#
<Layer name="world" #snip# srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over">
Donc, selon moi, les projections d'entrée et de sortie sont en "merc" (3857), et c'est correct! Mes données sont stockées avec 3857, et la carte résultante devrait être à 3857.
Enfin, voici les différents appels Mapnik que j'ai essayés:
Box2d avec 3857 coordonnées:
map = mapnik.Map(800, 800)
bbox = Box2d(-5191050.49, -2696361.67, -5191059.49, -2696370.70)
mapnik.load_map(map, '/path/to/style.xml')
map.zoom_to_box(bbox)
mapnik.render_to_file(map, 'output.png') # Blank
Box2d avec 4326 coordonnées transformées en 3857
merc = mapnik.Projection('+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over')
longlat = mapnik.Projection('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
bbox = mapnik.Box2d(-23.53, -46.63, -24.03, -47.03)
transform = mapnik.ProjTransform(longlat, merc)
merc_bbox = transform.forward(bbox)
# load, zoom, render -> Blank
J'ai aussi essayé avec différents styles. Le résultat est toujours vide, mais c'est inattendu car je pense que ces coordonnées seraient dans mon extrait. Lorsque vous essayez de rendre des coordonnées en dehors de l'extrait, il s'affiche correctement comme vide.
Quoi qu'il en soit, je suis perdu et je me demandais si quelqu'un pouvait faire la lumière, je dois manquer quelque chose. Mais jusqu'à présent, je me bats avec ce problème depuis plus de 24 heures et je n'ai aucune idée de ce qui pourrait mal se passer.