Dans un tutoriel précédent, j'ai expliqué le processus de création de votre propre serveur de tuiles OSM sur Ubuntu 20.04. Ce tutoriel va vous montrer comment configurer le serveur Nominatim Geocoding sur Ubuntu 20.04. Nominatim fournit une fonctionnalité de recherche pour OpenStreetMap, donc si un visiteur entre une adresse dans un champ de recherche, la latitude/longitude de cette adresse sera renvoyée.
Remarque : Si vous envisagez de configurer Nominatim pour toute la planète, vous devez créer un autre serveur pour Nominatim, car il nécessitera également 64 Go de RAM et 1 To de SSD.
Étape 1 :Créer Nominatim à partir de la source
Installez les packages de dépendance pour construire Nominatim.
sudo apt update sudo apt install build-essential cmake g++ libboost-dev libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libproj-dev apache2 php php-pgsql libapache2-mod-php php-intl php-cgi phpunit php-codesniffer python3-setuptools python3-dev python3-pip python3-psycopg2 python3-tidylib python3-behave python-pytest pylint git clang-tidy postgresql-server-dev-12
Créer le nominatim
utilisateur. (Pas besoin de créer un mot de passe pour cet utilisateur.)
sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim
Passez au /srv/nominatim/
répertoire.
cd /srv/nominatim/
Accordez des autorisations à votre propre compte d'utilisateur.
sudo apt install acl sudo setfacl -R -m u:username:rwx /srv/nominatim/
Téléchargez Nominatim sur le site officiel.
wget https://nominatim.org/release/Nominatim-3.5.1.tar.bz2
Extrayez l'archive.
tar xvf Nominatim-3.5.1.tar.bz2
Créer le build
répertoire.
mkdir build
Accédez à ce répertoire et configurez l'environnement de construction.
cd build cmake /srv/nominatim/Nominatim-3.5.1
Compilez le code source.
make
Étape 2 : Configurer Nominatim
Le fichier de configuration par défaut pour Nominatim est /srv/nominatim/build/settings/settings.php
. Nous pouvons créer un local.php
déposer et y ajouter nos modifications.
sudo nano /srv/nominatim/build/settings/local.php
Ajoutez les lignes suivantes dans le fichier.
<?php @define('CONST_Website_BaseURL', '/nominatim/'); @define('CONST_Default_Lat', 55.0); @define('CONST_Default_Lon', 1.0); @define('CONST_Default_Zoom', 6); @define('CONST_Map_Tile_URL', 'https://tile.linuxbabe.com/osm/{z}/{x}/{y}.png');
La configuration ci-dessus définit
- Le chemin de l'instance Nominatim par rapport à votre serveur de tuiles.
- Latitude, longitude et niveau de zoom par défaut.
- URL de votre serveur de tuiles OSM. Par défaut, Nominatim utilise le public
https://tile.openstreetmap.org
serveur de tuiles. Ici, j'utilise mon propre serveur de tuiles.
Vous pouvez également consulter le /srv/nominatim/build/settings/settings.php
fichier et ajoutez vos propres personnalisations si le besoin s'en fait sentir. Par exemple, si vous allez importer un grand ensemble de données (Europe, Amérique du Nord, planète, etc.), il est recommandé d'activer le stockage des nœuds plats des emplacements des nœuds, de sorte que les coordonnées des nœuds seront stockées dans un simple fichier au lieu du base de données, ce qui vous permet d'économiser du temps d'importation et du stockage sur disque.
@define('CONST_Osm2pgsql_Flatnode_File', '/srv/nominatim/flatnode.file');
Enregistrez et fermez le fichier.
Étape 3 :Installer et configurer PostgreSQL
Remarque :Si le serveur de tuiles OSM et Nominatim sont installés sur le même serveur, alors vous pouvez ignorer cette étape, car vous l'avez déjà fait lors de la configuration du serveur de tuiles OSM.
Nous utiliserons PostgreSQL pour stocker les données cartographiques. PostGIS est une extension géospatiale de PostgreSQL. Exécutez les commandes suivantes pour les installer.
sudo apt install postgresql postgresql-contrib postgis postgresql-12-postgis-3
Ensuite, nous devons régler PostgreSQL pour des performances maximales. Modifiez le fichier de configuration principal.
sudo nano /etc/postgresql/12/main/postgresql.conf
Trouvez les paramètres suivants dans ce fichier et utilisez les valeurs suivantes.
shared_buffers = 15GB work_mem = 1GB maintenance_work_mem = 10GB effective_cache_size = 24GB synchronous_commit = off max_wal_size = 1GB checkpoint_timeout = 10min checkpoint_completion_target = 0.9 fsync = off full_page_writes = off
Enregistrez et fermez le fichier. Redémarrez PostgreSQL pour que les modifications prennent effet.
sudo systemctl restart postgresql
Notez que vous devez activer fsync
et full_page_write
après avoir importé la base de données OSM, ou vous risquez de corrompre la base de données.
Par défaut, PostgreSQL essaierait d'utiliser d'énormes pages en RAM. Cependant, Linux par défaut n'alloue pas de pages volumineuses. Vérifiez l'ID de processus de PostgreSQL.
sudo head -1 /var/lib/postgresql/12/main/postmaster.pid
Exemple de sortie :
7031
Vérifiez ensuite la valeur VmPeak de cet ID de processus.
grep ^VmPeak /proc/7031/status
Exemple de sortie :
VmPeak: 16282784 kB
Il s'agit de la taille de mémoire maximale qui sera utilisée par PostgreSQL. Vérifiez maintenant la taille d'une énorme page sous Linux.
cat /proc/meminfo | grep -i huge
Exemple de sortie :
AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 0 kB
Nous pouvons calculer le nombre de pages énormes dont nous avons besoin. Divisez la valeur VmPeak par la taille de la page énorme :16282784 Ko / 2048 Ko =7950. Modifiez /etc/sysctl.conf
fichier.
sudo nano /etc/sysctl.conf
Ajoutez la ligne suivante pour allouer 7950 énormes pages.
vm.nr_hugepages = 7950
Enregistrez et fermez le fichier. Appliquez ensuite les modifications.
sudo sysctl -p
Si vous vérifiez à nouveau le meminfo,
cat /proc/meminfo | grep -i huge
Nous pouvons voir qu'il y a 7950 énormes pages disponibles.
AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 7950 HugePages_Free: 7950 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
Redémarrez PostgreSQL pour utiliser des pages volumineuses.
sudo systemctl restart postgresql
Étape 4 :Importer la base de données OSM
Téléchargez le fichier de vidage d'importance de Wikipedia, ce qui améliorera la qualité des résultats de recherche de Nomiatim.
cd /srv/nominatim/Nominatim-3.5.1/data wget https://www.nominatim.org/data/wikimedia-importance.sql.gz
Téléchargez les données des codes postaux américains et britanniques.
wget https://www.nominatim.org/data/us_postcode_data.sql.gz wget https://www.nominatim.org/data/gb_postcode_data.sql.gz
Télécharger le fichier de données de code de pays.
wget -O country_osm_grid.sql.gz https://www.nominatim.org/data/country_grid.sql.gz
Ensuite, vous devez télécharger un fichier OSM et l'importer dans PostgreSQL. Vous pouvez vous rendre sur http://download.geofabrik.de pour télécharger l'extrait dont vous avez besoin. Vous pouvez également utiliser le fichier PBF pendant le processus de configuration du serveur de tuiles.
Créez les www-data
utilisateur dans PostgreSQL, afin que le serveur Web ait un accès en lecture seule à la base de données.
sudo -u postgres createuser www-data
Accorder l'autorisation au postgres
utilisateur.
sudo setfacl -R -m u:postgres:rwx /srv/nominatim/
Passer au postgres
utilisateur.
sudo -u postgres -i
Et exécutez la commande suivante pour importer des extraits OSM dans PostgreSQL.
cd /srv/nominatim/build/ /srv/nominatim/build/utils/setup.php --osm-file /home/osm/great-britain-latest.osm.pbf --all 2>&1 | tee setup.log
Après l'importation de la base de données, le processus d'indexation commencera. Il y a 30 rangs au total.
Une fois terminé, exécutez la commande suivante pour vérifier.
/srv/nominatim/build/utils/check_import_finished.php
Sortir de postgres
utilisateur.
exit
Étape 5 :Configurer Apache
Si Nominatim est installé sur le serveur de tuiles OSM, alors éditez le fichier de configuration du serveur de tuiles.
sudo nano /etc/apache2/sites-enabled/tileserver_site-le-ssl.conf
Ajoutez les lignes suivantes entre le VirtualHost
balises.
<Directory "/srv/nominatim/build/website"> Options FollowSymLinks MultiViews AddType application/json .php DirectoryIndex search.php Require all granted </Directory> alias /nominatim /srv/nominatim/build/website
Enregistrez et fermez le fichier. Rechargez ensuite Apache.
sudo systemctl reload apache2
Si vous configurez Nominatim sur un serveur séparé, vous devez installer Apache et PHP.
sudo apt install apache2 php7.4 libapache2-mod-php7.4 php-common php7.4-cli php7.4-common php7.4-json php7.4-opcache php7.4-readline
Créez un hôte virtuel pour Nominatim.
sudo nano /etc/apache2/sites-enabled/nominatim.conf
Ajoutez les lignes suivantes dans ce fichier.
<VirtualHost *:80> ServerName nominatim.example.com DocumentRoot /srv/nominatim/build/website <Directory "/srv/nominatim/build/website"> Options FollowSymLinks MultiViews AddType application/json .php DirectoryIndex search.php Require all granted </Directory> alias /nominatim /srv/nominatim/build/website ErrorLog ${APACHE_LOG_DIR}/nominatim_error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/nominatim_access.log combined </VirtualHost>
Enregistrez et fermez le fichier. Puis redémarrez Apache.
sudo systemctl restart apache2
Visitez maintenant https://tile.yourdomain.com/nominatim
. Vous verrez votre instance Nomiatim.
Le fichier CSS se trouve dans /srv/nominatim/build/website/css/search.css
, si vous souhaitez personnaliser l'apparence.
Étape 6 :Mettre à jour la base de données Nominatim
Pour maintenir à jour la base de données Nominatim, nous devons installer Pyosmium
. Il est disponible à partir du référentiel de logiciels par défaut, mais il est recommandé d'installer la dernière version à l'aide de pip3.
sudo pip3 install osmium
Cela installera un binaire /usr/local/bin/pyosmium-get-changes
. Modifier le fichier de configuration de Nominatim.
sudo nano /srv/nominatim/build/settings/local.php
Ajoutez la ligne suivante pour spécifier l'emplacement de pyosmium-get-changes
.
@define('CONST_Pyosmium_Binary', '/usr/local/bin/pyosmium-get-changes');
Ensuite, nous devons indiquer à Nominatim où télécharger les mises à jour. Par défaut, il est configuré pour télécharger les mises à jour depuis https://planet.openstreetmap.org/replication/minute
. Si vous avez téléchargé le fichier OSM PBF depuis geofabrik.de, il est préférable de télécharger également les mises à jour à partir de là.
Pour trouver l'URL de mise à jour de votre propre carte, rendez-vous sur https://download.geofabrik.de/ et localisez votre région. Ensuite, recherchez l'URL du .osc.gz
fichier.
Cette URL est l'URL de mise à jour.
Ajoutez la ligne suivante dans /srv/nominatim/build/settings/local.php
dossier. Vous devez utiliser votre propre URL de mise à jour.
// base URL of the replication service @define('CONST_Replication_Url', 'http://download.geofabrik.de/europe/great-britain-updates'); // How often upstream publishes diffs @define('CONST_Replication_Update_Interval', '86400'); // How long to sleep if no update found yet @define('CONST_Replication_Recheck_Interval', '900');
Enregistrez et fermez le fichier. Accorder des autorisations à postgres
utilisateur.
sudo setfacl -R -m "u:postgres:rwx" /srv/nominatim/build/
Passez ensuite à l'utilisateur postgres.
sudo -u postgres -i
Initialisez le processus de mise à jour.
/srv/nominatim/build/utils/update.php --init-updates
Mettre à jour la base de données Nominatim.
/srv/nominatim/build/utils/update.php --import-osmosis-all
Étape 7 :Configurer la tâche Cron pour la mise à jour automatique
Modifiez le fichier Crontab de l'utilisateur root.
sudo crontab -e
Ajoutez la ligne suivante dans ce fichier.
@daily sudo -u postgres /srv/nominatim/build/utils/update.php --import-osmosis-all
Enregistrez et fermez le fichier. Si vous ne souhaitez pas mettre à jour automatiquement la base de données Nominatim, supprimez simplement la ligne ci-dessus de votre fichier Crontab.
Comment ajouter une fonctionnalité de recherche à une carte glissante
Je suppose que votre carte glissante est affichée à l'aide de la bibliothèque Leaflet JavaScript. Pour ajouter une fonctionnalité de recherche à votre carte, vous devez utiliser un plug-in de géocodage Leaflet. Je vais vous montrer comment utiliser Leaflet Control Geocoder. C'est en fait très simple.
Supposons que vous utilisiez le code HTML suivant pour afficher votre carte glissante.
<html> <head> <meta charset="UTF-8"> <title>My first osm</title> <link rel="stylesheet" type="text/css" href="leaflet.css"/> <script type="text/javascript" src="leaflet.js"></script> <style> #map{width:100%;height:100%} </style> </head> <body> <div id="map"></div> <script> var map = L.map('map').setView([54,1],6); L.tileLayer('https://tile.yourdomain.com/osm/{z}/{x}/{y}.png',{maxZoom:19}).addTo(map); </script> </body> </html>
Vous devez maintenant ajouter les deux lignes suivantes dans l'en-tête HTML pour utiliser le Leaflet Control Geocoder plugin.
<link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css" /> <script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script>
Ajoutez ensuite la fonction suivante au <script>...</script>
code afin que la fonctionnalité de recherche soit ajoutée à votre carte.
L.Control.geocoder().addTo(map);
Le code HTML final ressemble à ceci :
<html> <head> <meta charset="UTF-8"> <title>My first osm</title> <link rel="stylesheet" type="text/css" href="leaflet.css"/> <link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css" /> <script type="text/javascript" src="leaflet.js"></script> <script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script> <style> #map{width:100%;height:100%} </style> </head> <body> <div id="map"></div> <script> var map = L.map('map').setView([54,1],6); L.tileLayer('https://tile.yourdomain.com/osm/{z}/{x}/{y}.png',{maxZoom:19}).addTo(map); L.Control.geocoder().addTo(map); </script> </body> </html>
Enregistrez et fermez le fichier. Rechargez ensuite la carte dans votre navigateur Web, vous devriez voir un bouton de recherche dans le coin supérieur droit.
Par défaut, Leaflet Control Geocoder utilise le https://nominatim.openstreetmap.org
public service de géocodage. Pour lui faire utiliser votre propre service de géocodage Nominatim, supprimez la ligne suivante.
L.Control.geocoder().addTo(map);
Ajoutez plutôt les lignes suivantes. Remplacez l'URL par l'URL de votre service de géocodage Nominatim. Notez que vous ne devez pas omettre la barre oblique finale.
var geocoder = L.Control.Geocoder.nominatim({serviceUrl:'https://tile.yourdomain.com/nominatim/'}); if (URLSearchParams && location.search) { // parse /?geocoder=nominatim from URL var params = new URLSearchParams(location.search); var geocoderString = params.get('geocoder'); if (geocoderString && L.Control.Geocoder[geocoderString]) { console.log('Using geocoder', geocoderString); geocoder = L.Control.Geocoder[geocoderString](); } else if (geocoderString) { console.warn('Unsupported geocoder', geocoderString); } } var control = L.Control.geocoder({ query: 'Type Address here', placeholder: 'Search here...', geocoder: geocoder, position: 'topright' }).addTo(map); var marker; setTimeout(function() { control.setQuery('Type Address here'); }, 12000);
La position par défaut est topright
. Vous pouvez le changer en topleft
si vous le souhaitez.
Vous pouvez également ajouter le code suivant pour le géocodage inversé. Lorsqu'un visiteur clique sur un point de la carte, le nom de cette adresse apparaît.
map.on('click', function(e) { geocoder.reverse(e.latlng, map.options.crs.scale(map.getZoom()), function(results) { var r = results[0]; if (r) { if (marker) { marker .setLatLng(r.center) .setPopupContent(r.html || r.name) .openPopup(); } else { marker = L.marker(r.center) .bindPopup(r.name) .addTo(map) .openPopup(); } } }); });
Enregistrez et fermez le fichier. Rechargez ensuite la carte dans votre navigateur Web.
Améliorer la précision de la recherche inversée
Il existe deux types de recherche dans Nominatim :
- recherche vers l'avant, alias géocodage, renvoie la latitude et la longitude d'une adresse
- recherche inversée , ou géocodage inversé, renvoie une adresse pour la latitude et la longitude, c'est-à-dire lorsqu'un visiteur clique sur un point de la carte.
Si vous effectuez une recherche inversée, l'épingle de marqueur et la fenêtre contextuelle ne sont pas à proximité immédiate de la position sur la carte sur laquelle vous avez cliqué, vous devez augmenter le niveau de zoom. Le map.getZoom() la fonction obtiendra la vue cartographique actuelle , qui est défini avec setView() fonctionner comme ça
var map = L.map('map').setView([54,1],6);
Le niveau de zoom est réglé sur 6
, ce qui donnera une mauvaise précision pour la recherche inversée. Nous pouvons coder en dur le niveau de zoom pour la recherche inversée comme suit :
geocoder.reverse(e.latlng, map.options.crs.scale(21), function(results)
c'est-à-dire changer map.getZoom() au 21. Le niveau de zoom maximal pour la recherche inversée est de 21. Vous pouvez choisir un autre niveau de zoom en fonction de vos besoins.
Dépannage
Si la fonctionnalité de recherche sur votre carte ne fonctionne pas, vous pouvez consulter la console de votre navigateur Web pour savoir ce qui ne va pas. Certaines personnes peuvent voir que le 406 n'est pas acceptable ou un CORS non autorisé Erreur. Assurez-vous d'avoir défini le bon type MIME pour .php
dans le fichier de configuration d'Apache. Certaines personnes peuvent avoir la ligne suivante, ce qui peut provoquer les erreurs ci-dessus.
AddType text/html .php
Cela devrait être
AddType application/json .php
Après avoir changé le type MIME. Rechargez Apache pour que les modifications prennent effet.
sudo systemctl reload apache2