In einem früheren Tutorial habe ich den Prozess zum Erstellen eines eigenen OSM-Kachelservers unter Ubuntu 20.04 erklärt. Dieses Tutorial zeigt Ihnen, wie Sie den Nominatim Geocoding-Server unter Ubuntu 20.04 einrichten. Nominatim stellt eine Suchfunktion für OpenStreetMap bereit, sodass, wenn ein Besucher eine Adresse in ein Suchfeld eingibt, der Breiten-/Längengrad für diese Adresse zurückgegeben wird.
Hinweis: Wenn Sie Nominatim für den gesamten Planeten einrichten, sollten Sie einen weiteren Server für Nominatim einrichten, da dieser ebenfalls 64 GB RAM und 1 TB SSD benötigt.
Schritt 1:Erstellen Sie Nominatim aus der Quelle
Installieren Sie Abhängigkeitspakete, um Nominatim zu erstellen.
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
Erstellen Sie die nominatim
Benutzer. (Für diesen Benutzer muss kein Passwort erstellt werden.)
sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim
Wechseln Sie zu /srv/nominatim/
Verzeichnis.
cd /srv/nominatim/
Gewähren Sie Ihrem eigenen Benutzerkonto Berechtigungen.
sudo apt install acl sudo setfacl -R -m u:username:rwx /srv/nominatim/
Laden Sie Nominatim von der offiziellen Website herunter.
wget https://nominatim.org/release/Nominatim-3.5.1.tar.bz2
Extrahieren Sie den Tarball.
tar xvf Nominatim-3.5.1.tar.bz2
Erstellen Sie den build
Verzeichnis.
mkdir build
Wechseln Sie in dieses Verzeichnis und konfigurieren Sie die Build-Umgebung.
cd build cmake /srv/nominatim/Nominatim-3.5.1
Kompilieren Sie den Quellcode.
make
Schritt 2:Nominatim konfigurieren
Die Standardkonfigurationsdatei für Nominatim ist /srv/nominatim/build/settings/settings.php
. Wir können eine local.php
erstellen Datei und fügen Sie dort unsere Änderungen hinzu.
sudo nano /srv/nominatim/build/settings/local.php
Fügen Sie der Datei die folgenden Zeilen hinzu.
<?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');
Die obige Konfiguration definiert
- Der Pfad der Nominatim-Instanz relativ zu Ihrem Tile-Server.
- Standardmäßiger Breitengrad, Längengrad und Zoomfaktor.
- URL Ihres OSM-Kachelservers. Standardmäßig verwendet Nominatim den öffentlichen
https://tile.openstreetmap.org
Tile-Server. Hier verwende ich meinen eigenen Tileserver.
Sie können sich auch die /srv/nominatim/build/settings/settings.php
ansehen Datei und fügen Sie bei Bedarf Ihre eigenen Anpassungen hinzu. Wenn Sie beispielsweise einen großen Datensatz (Europa, Nordamerika, Planet usw.) importieren, empfiehlt es sich, die flache Knotenspeicherung von Knotenpositionen zu aktivieren, sodass die Knotenkoordinaten in einer einfachen Datei statt in der Datei gespeichert werden Datenbank, wodurch Sie Importzeit und Speicherplatz sparen.
@define('CONST_Osm2pgsql_Flatnode_File', '/srv/nominatim/flatnode.file');
Speichern und schließen Sie die Datei.
Schritt 3:PostgreSQL installieren und konfigurieren
Hinweis :Wenn OSM-Tileserver und Nominatim auf demselben Server installiert sind, können Sie diesen Schritt überspringen, da Sie dies bereits bei der Einrichtung des OSM-Tileservers getan haben.
Wir werden PostgreSQL verwenden, um Kartendaten zu speichern. PostGIS ist eine raumbezogene Erweiterung von PostgreSQL. Führen Sie die folgenden Befehle aus, um sie zu installieren.
sudo apt install postgresql postgresql-contrib postgis postgresql-12-postgis-3
Dann müssen wir PostgreSQL für maximale Leistung optimieren. Bearbeiten Sie die Hauptkonfigurationsdatei.
sudo nano /etc/postgresql/12/main/postgresql.conf
Finden Sie die folgenden Parameter in dieser Datei und verwenden Sie die folgenden Werte.
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
Speichern und schließen Sie die Datei. Starten Sie PostgreSQL neu, damit die Änderungen wirksam werden.
sudo systemctl restart postgresql
Beachten Sie, dass Sie fsync
aktivieren sollten und full_page_write
nachdem Sie die OSM-Datenbank importiert haben, oder Sie riskieren, die Datenbank zu beschädigen.
Standardmäßig würde PostgreSQL versuchen, riesige Seiten im RAM zu verwenden. Linux weist jedoch standardmäßig keine riesigen Seiten zu. Überprüfen Sie die Prozess-ID von PostgreSQL.
sudo head -1 /var/lib/postgresql/12/main/postmaster.pid
Beispielausgabe:
7031
Überprüfen Sie dann den VmPeak-Wert dieser Prozess-ID.
grep ^VmPeak /proc/7031/status
Beispielausgabe:
VmPeak: 16282784 kB
Dies ist die maximale Speichergröße, die von PostgreSQL verwendet wird. Überprüfen Sie nun die Größe der riesigen Seite in Linux.
cat /proc/meminfo | grep -i huge
Beispielausgabe:
AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 0 kB
Wir können berechnen, wie viele riesige Seiten wir brauchen. Teilen Sie den VmPeak-Wert durch die Größe der riesigen Seite:16282784 kB / 2048 kB =7950. Bearbeiten Sie /etc/sysctl.conf
Datei.
sudo nano /etc/sysctl.conf
Fügen Sie die folgende Zeile hinzu, um 7950 riesige Seiten zuzuweisen.
vm.nr_hugepages = 7950
Speichern und schließen Sie die Datei. Wenden Sie dann die Änderungen an.
sudo sysctl -p
Wenn Sie die Meminfo erneut überprüfen,
cat /proc/meminfo | grep -i huge
Wir können sehen, dass 7950 riesige Seiten verfügbar sind.
AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 7950 HugePages_Free: 7950 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
Starten Sie PostgreSQL neu, um riesige Seiten zu verwenden.
sudo systemctl restart postgresql
Schritt 4:OSM-Datenbank importieren
Laden Sie die Wikipedia-Wichtigkeits-Dump-Datei herunter, die die Qualität der Nomiatim-Suchergebnisse verbessern wird.
cd /srv/nominatim/Nominatim-3.5.1/data wget https://www.nominatim.org/data/wikimedia-importance.sql.gz
Laden Sie Postleitzahlendaten für die USA und das Vereinigte Königreich herunter.
wget https://www.nominatim.org/data/us_postcode_data.sql.gz wget https://www.nominatim.org/data/gb_postcode_data.sql.gz
Ländercode-Datendatei herunterladen.
wget -O country_osm_grid.sql.gz https://www.nominatim.org/data/country_grid.sql.gz
Dann müssen Sie eine OSM-Datei herunterladen und in PostgreSQL importieren. Unter http://download.geofabrik.de können Sie den benötigten Extrakt herunterladen. Sie können die PBF-Datei auch während des Einrichtungsprozesses des Kachelservers verwenden.
Erstellen Sie die www-data
Benutzer in PostgreSQL, sodass der Webserver nur Lesezugriff auf die Datenbank hat.
sudo -u postgres createuser www-data
Gewähren Sie postgres
die Berechtigung Benutzer.
sudo setfacl -R -m u:postgres:rwx /srv/nominatim/
Wechseln Sie zu postgres
Benutzer.
sudo -u postgres -i
Und führen Sie den folgenden Befehl aus, um OSM-Extrakte in PostgreSQL zu importieren.
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
Nach dem Importieren der Datenbank beginnt der Indizierungsprozess. Es gibt insgesamt 30 Ränge.
Führen Sie nach Abschluss den folgenden Befehl zur Überprüfung aus.
/srv/nominatim/build/utils/check_import_finished.php
Verlassen Sie postgres
Benutzer.
exit
Schritt 5:Apache einrichten
Wenn Nominatim auf dem OSM-Kachelserver installiert ist, bearbeiten Sie die Konfigurationsdatei des Kachelservers.
sudo nano /etc/apache2/sites-enabled/tileserver_site-le-ssl.conf
Fügen Sie die folgenden Zeilen zwischen VirtualHost
hinzu Tags.
<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
Speichern und schließen Sie die Datei. Laden Sie dann Apache neu.
sudo systemctl reload apache2
Wenn Sie Nominatim auf einem separaten Server einrichten, müssen Sie Apache und PHP installieren.
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
Erstellen Sie einen virtuellen Host für Nominatim.
sudo nano /etc/apache2/sites-enabled/nominatim.conf
Fügen Sie dieser Datei die folgenden Zeilen hinzu.
<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>
Speichern und schließen Sie die Datei. Starten Sie dann Apache neu.
sudo systemctl restart apache2
Besuchen Sie nun https://tile.yourdomain.com/nominatim
. Sie sehen Ihre Nomiatim-Instanz.
Die CSS-Datei befindet sich unter /srv/nominatim/build/website/css/search.css
, wenn Sie das Aussehen anpassen möchten.
Schritt 6:Nominatim-Datenbank aktualisieren
Um die Nominatim-Datenbank aktuell zu halten, müssen wir Pyosmium
installieren . Es ist im Standard-Software-Repository verfügbar, aber es wird empfohlen, die neueste Version mit pip3 zu installieren.
sudo pip3 install osmium
Dadurch wird ein binärer /usr/local/bin/pyosmium-get-changes
installiert . Nominatim-Konfigurationsdatei bearbeiten.
sudo nano /srv/nominatim/build/settings/local.php
Fügen Sie die folgende Zeile hinzu, um den Speicherort von pyosmium-get-changes
anzugeben .
@define('CONST_Pyosmium_Binary', '/usr/local/bin/pyosmium-get-changes');
Als nächstes müssen wir Nominatim mitteilen, wo Updates heruntergeladen werden sollen. Standardmäßig ist es so konfiguriert, dass Updates von https://planet.openstreetmap.org/replication/minute
heruntergeladen werden . Wenn Sie die OSM-PBF-Datei von geofabrik.de heruntergeladen haben, dann ist es besser, auch Updates von dort herunterzuladen.
Um die Update-URL für Ihre eigene Karte zu finden, gehen Sie zu https://download.geofabrik.de/ und suchen Sie Ihre Region. Suchen Sie dann die URL für .osc.gz
Datei.
Diese URL ist die Update-URL.
Fügen Sie die folgende Zeile in /srv/nominatim/build/settings/local.php
hinzu Datei. Sie müssen Ihre eigene Update-URL verwenden.
// 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');
Speichern und schließen Sie die Datei. Erteilen Sie Berechtigungen für postgres
Benutzer.
sudo setfacl -R -m "u:postgres:rwx" /srv/nominatim/build/
Wechseln Sie dann zum Postgres-Benutzer.
sudo -u postgres -i
Update-Vorgang initialisieren.
/srv/nominatim/build/utils/update.php --init-updates
Nominatim-Datenbank aktualisieren.
/srv/nominatim/build/utils/update.php --import-osmosis-all
Schritt 7:Cron-Job für automatisches Update einrichten
Bearbeiten Sie die Crontab-Datei des Root-Benutzers.
sudo crontab -e
Fügen Sie dieser Datei die folgende Zeile hinzu.
@daily sudo -u postgres /srv/nominatim/build/utils/update.php --import-osmosis-all
Speichern und schließen Sie die Datei. Wenn Sie die Nominatim-Datenbank nicht automatisch aktualisieren möchten, entfernen Sie einfach die obige Zeile aus Ihrer Crontab-Datei.
So fügen Sie einer Slippy Map eine Suchfunktion hinzu
Ich nehme an, Ihre rutschige Karte wird mit der Leaflet-JavaScript-Bibliothek angezeigt. Um Ihrer Karte eine Suchfunktion hinzuzufügen, müssen Sie ein Leaflet-Geokodierungs-Plugin verwenden. Ich werde Ihnen zeigen, wie Sie Leaflet Control Geocoder verwenden. Es ist eigentlich ganz einfach.
Angenommen, Sie haben den folgenden HTML-Code verwendet, um Ihre Slippy Map anzuzeigen.
<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>
Jetzt müssen Sie die folgenden zwei Zeilen in den HTML-Header einfügen, um den Leaflet Control Geocoder zu verwenden 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>
Fügen Sie dann die folgende Funktion zu <script>...</script>
hinzu code, damit die Suchfunktion zu Ihrer Karte hinzugefügt wird.
L.Control.geocoder().addTo(map);
Der endgültige HTML-Code sieht so aus:
<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>
Speichern und schließen Sie die Datei. Laden Sie dann die Karte in Ihrem Webbrowser neu, Sie sollten eine Suchschaltfläche in der oberen rechten Ecke sehen.
Standardmäßig Leaflet Control Geocoder verwendet den öffentlichen https://nominatim.openstreetmap.org
Geokodierungsdienst. Um Ihren eigenen Nominatim-Geocodierungsdienst zu verwenden, löschen Sie die folgende Zeile.
L.Control.geocoder().addTo(map);
Fügen Sie stattdessen die folgenden Zeilen hinzu. Ersetzen Sie die URL durch die URL Ihres Nominatim-Geokodierungsdienstes. Beachten Sie, dass Sie den abschließenden Schrägstrich nicht weglassen sollten.
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);
Die Standardposition ist topright
. Sie können es in topleft
ändern wenn Sie möchten.
Sie können auch den folgenden Code für umgekehrte Geokodierung hinzufügen. Wenn ein Besucher auf einen Punkt auf der Karte klickt, wird der Name dieser Adresse angezeigt.
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(); } } }); });
Speichern und schließen Sie die Datei. Laden Sie dann die Karte in Ihrem Webbrowser neu.
Verbessern Sie die Genauigkeit der Rückwärtssuche
Es gibt zwei Arten von Suchen in Nominatim:
- Vorwärtssuche, alias Geokodierung, gibt Breiten- und Längengrad für eine Adresse zurück
- Umgekehrte Suche , auch Reverse Geocoding genannt, gibt eine Adresse für Breiten- und Längengrad zurück, d. h. wenn ein Besucher auf einen Punkt in der Karte klickt.
Wenn Sie eine Rückwärtssuche durchführen und sich der Markierungsstift und das Popup nicht in unmittelbarer Nähe der Position auf der Karte befinden, auf die Sie geklickt haben, müssen Sie die Zoomstufe erhöhen. Die map.getZoom() Funktion ruft die aktuelle Kartenansicht ab , die mit setView() gesetzt wird funktionieren so
var map = L.map('map').setView([54,1],6);
Die Zoomstufe ist auf 6
eingestellt , was eine schlechte Genauigkeit für die Rückwärtssuche ergibt. Wir können die Zoomstufe für die Rückwärtssuche wie folgt fest codieren:
geocoder.reverse(e.latlng, map.options.crs.scale(21), function(results)
d.h. ändern Sie map.getZoom() bis 21. Die maximale Zoomstufe für die Rückwärtssuche ist 21. Sie können je nach Bedarf eine andere Zoomstufe wählen.
Fehlerbehebung
Wenn die Suchfunktion auf Ihrer Karte nicht funktioniert, können Sie die Konsole Ihres Webbrowsers überprüfen, um herauszufinden, was schief gelaufen ist. Einige Leute sehen den 406 nicht akzeptabel oder ein CORS nicht erlaubt Error. Stellen Sie sicher, dass Sie den richtigen MIME-Typ für .php
eingestellt haben in der Apache-Konfigurationsdatei. Einige Leute haben möglicherweise die folgende Zeile, die die oben genannten Fehler verursachen kann.
AddType text/html .php
Das sollte es sein
AddType application/json .php
Nach dem Ändern des MIME-Typs. Laden Sie Apache neu, damit die Änderungen wirksam werden.
sudo systemctl reload apache2