V předchozím tutoriálu jsem vysvětlil proces vytváření vlastního OSM dlaždicového serveru na Debianu 10. Tento tutoriál vám ukáže, jak nastavit Nominatim Geocoding server na Debianu 10. Nominatim poskytuje vyhledávací funkci pro OpenStreetMap, takže pokud návštěvník vstoupí adresu ve vyhledávacím poli, vrátí se zeměpisná šířka/délka pro danou adresu.
Krok 1:Sestavení Nominatim ze zdroje
Nainstalujte balíčky závislostí pro sestavení 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 python3-setuptools python3-dev python3-pip python3-psycopg2 python3-tidylib git clang-tidy postgresql-server-dev-11
Vytvořte nominatim
uživatel. (Pro tohoto uživatele není třeba vytvářet heslo.)
sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim
Změňte na /srv/nominatim/
adresář.
cd /srv/nominatim/
Udělte oprávnění svému vlastnímu uživatelskému účtu.
sudo apt install acl sudo setfacl -R -m u:username:rwx /srv/nominatim/
Stáhněte si Nominatim z oficiálních stránek.
wget https://nominatim.org/release/Nominatim-3.5.1.tar.bz2
Extrahujte tarball.
tar xvf Nominatim-3.5.1.tar.bz2
Vytvořte build
adresář.
mkdir build
Přejděte do tohoto adresáře a nakonfigurujte prostředí sestavení.
cd build cmake /srv/nominatim/Nominatim-3.5.1
Zkompilujte zdrojový kód.
make
Krok 2:Konfigurace Nominatim
Výchozí konfigurační soubor pro Nominatim je /srv/nominatim/build/settings/settings.php
. Můžeme vytvořit local.php
soubor a přidejte tam naše úpravy.
sudo nano /srv/nominatim/build/settings/local.php
Přidejte do souboru následující řádky.
<?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');
Výše uvedená konfigurace definuje
- Cesta instance Nominatim vzhledem k vašemu dlaždicovému serveru.
- Výchozí zeměpisná šířka, délka a úroveň přiblížení.
- Adresa URL vašeho dlaždicového serveru OSM. Ve výchozím nastavení Nominatim používá veřejný
openstreetmap.org
dlaždicový server. Zde používám svůj vlastní dlaždicový server.
Můžete se také podívat na /srv/nominatim/build/settings/settings.php
soubor a v případě potřeby přidejte vlastní přizpůsobení. Pokud se například chystáte importovat velký soubor dat (Evropa, Severní Amerika, planeta atd.), je dobrým zvykem povolit ukládání umístění uzlů v plochých uzlových bodech, takže souřadnice uzlů budou uloženy v jednoduchém souboru namísto databáze, což vám ušetří čas při importu a úložiště na disku.
@define('CONST_Osm2pgsql_Flatnode_File', '/srv/nominatim/flatnode.file');
Uložte a zavřete soubor.
Krok 3:Import databáze OSM
Stáhněte si soubor výpisu důležitosti Wikipedie, který zlepší kvalitu výsledků vyhledávání Nomiatim.
cd /srv/nominatim/Nominatim-3.5.1/data wget https://www.nominatim.org/data/wikimedia-importance.sql.gz
Stáhněte si data poštovních směrovacích čísel USA a Spojeného království.
wget https://www.nominatim.org/data/us_postcode_data.sql.gz wget https://www.nominatim.org/data/gb_postcode_data.sql.gz
Stáhněte si datový soubor s kódem země.
wget -O country_osm_grid.sql.gz https://www.nominatim.org/data/country_grid.sql.gz
Poté si musíte stáhnout soubor OSM a importovat jej do PostgreSQL. Potřebný výpis si můžete stáhnout na http://download.geofabrik.de. Soubor PBF můžete také použít během procesu nastavení dlaždicového serveru.
Vytvořte www-data
uživatel v PostgreSQL, takže webový server bude mít přístup k databázi pouze pro čtení.
sudo -u postgres createuser www-data
Udělte oprávnění postgres
uživatel.
sudo setfacl -R -m u:postgres:rwx /srv/nominatim/
Přepněte na postgres
uživatel.
sudo -u postgres -i
A spusťte následující příkaz pro import OSM extraktů do 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
Po importu databáze začne proces indexování.
Po dokončení spusťte následující příkaz pro ověření.
/srv/nominatim/build/utils/check_import_finished.php
Ukončete postgres
uživatel.
exit
Krok 4:Nastavení Apache
Upravte konfigurační soubor dlaždicového serveru.
sudo nano /etc/apache2/sites-enabled/tileserver_site-le-ssl.conf
Přidejte následující řádky mezi VirtualHost
značky.
<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
Uložte a zavřete soubor. Poté znovu načtěte Apache.
sudo systemctl reload apache2
Nyní navštivte https://tile.yourdomain.com/nominatim
. Zobrazí se vaše instance Nomiatim.
Soubor CSS se nachází na adrese /srv/nominatim/build/website/css/search.css
, pokud chcete upravit vzhled.
Aktualizovat databázi Nominatim
Aby byla databáze Nominatim aktuální, musíme nainstalovat Pyosmium
. Je k dispozici z výchozího softwarového úložiště, ale doporučujeme nainstalovat nejnovější verzi pomocí pip3.
sudo pip3 install osmium
Tím se nainstaluje binární /usr/local/bin/pyosmium-get-changes
. Upravte konfigurační soubor Nominatim.
sudo nano /srv/nominatim/build/settings/local.php
Přidejte následující řádek k určení umístění pyosmium-get-changes
.
@define('CONST_Pyosmium_Binary', '/usr/local/bin/pyosmium-get-changes');
Dále musíme Nominatim sdělit, kde stáhnout aktualizace. Ve výchozím nastavení je nakonfigurováno pro stahování aktualizací z https://planet.openstreetmap.org/replication/minute
. Pokud jste si stáhli soubor OSM PBF z geofabrik.de, pak je lepší stahovat aktualizace také odtud.
Chcete-li najít aktualizační URL pro svou vlastní mapu, přejděte na https://download.geofabrik.de/ a vyhledejte svůj region. Poté najděte adresu URL pro .osc.gz
soubor.
Tato adresa URL je adresa URL aktualizace.
Přidejte následující řádek do /srv/nominatim/build/settings/local.php
soubor. Musíte použít vlastní adresu URL pro aktualizaci.
// 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');
Uložte a zavřete soubor. Udělte oprávnění postgres
uživatel.
sudo setfacl -R -m "u:postgres:rwx" /srv/nominatim/build/
Poté přepněte na postgres
uživatel.
sudo -u postgres -i
Inicializujte proces aktualizace.
/srv/nominatim/build/utils/update.php --init-updates
Aktualizujte databázi Nominatim.
/srv/nominatim/build/utils/update.php --import-osmosis-all
Nastavit úlohu Cron pro automatickou aktualizaci
Upravte soubor Crontab uživatele root.
sudo crontab -e
Přidejte do tohoto souboru následující řádek.
@daily sudo -u postgres /srv/nominatim/build/utils/update.php --import-osmosis-all
Uložte a zavřete soubor.
Jak přidat funkci vyhledávání do kluzké mapy
Předpokládám, že vaše kluzká mapa je zobrazena pomocí knihovny Leaflet JavaScript. Chcete-li do mapy přidat funkci vyhledávání, musíte použít plugin pro geokódování Leaflet. Ukážu vám, jak používat Leaflet Control Geocoder. Je to vlastně velmi jednoduché.
Předpokládejme, že jste k zobrazení své kluzké mapy použili následující HTML kód.
<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>
Nyní musíte do záhlaví HTML přidat následující dva řádky, abyste mohli používat Geocoder pro ovládání letáku 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>
Poté přidejte následující funkci do <script>...</script>
kód, takže funkce vyhledávání bude přidána do vaší mapy.
L.Control.geocoder().addTo(map);
Výsledný HTML kód vypadá takto:
<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>
Uložte a zavřete soubor. Poté znovu načtěte mapu ve svém webovém prohlížeči, v pravém horním rohu by se mělo zobrazit tlačítko vyhledávání.
Ve výchozím nastavení Leaflet Control Geocoder používá veřejný https://nominatim.openstreetmap.org
služba geokódování. Chcete-li, aby používal vaši vlastní geokódovací službu Nominatim, odstraňte následující řádek.
L.Control.geocoder().addTo(map);
Místo toho přidejte následující řádky. Nahraďte URL adresou URL vaší geokódovací služby Nominatim. Nezapomeňte, že byste neměli vynechávat koncové lomítko.
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: 'Moon', placeholder: 'Search here...', geocoder: geocoder }).addTo(map); var marker; setTimeout(function() { control.setQuery('Earth'); }, 12000);
Můžete také přidat následující kód pro zpětné geokódování. Když návštěvník klikne na bod na mapě, zobrazí se název této adresy.
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(); } } }); });
Uložte a zavřete soubor. Poté znovu načtěte mapu ve svém webovém prohlížeči.
Zlepšit přesnost zpětného vyhledávání
V Nominatim jsou dva typy vyhledávání:
- vyhledávání vpřed aka geocoding, vrací zeměpisnou šířku a délku pro adresu
- zpětné vyhledávání , neboli reverzní geokódování, vrací adresu pro zeměpisnou šířku a délku, tj. když návštěvník klikne na bod na mapě.
Pokud provedete zpětné vyhledávání, špendlík a vyskakovací okno nejsou v bezprostřední blízkosti pozice na mapě, na kterou jste klikli, musíte zvýšit úroveň přiblížení. map.getZoom() funkce získá aktuální zobrazení mapy , která se nastavuje pomocí setView() fungovat takto
var map = L.map('map').setView([54,1],6);
Úroveň přiblížení je nastavena na 6
, což bude poskytovat špatnou přesnost pro zpětné vyhledávání. Můžeme pevně zakódovat úroveň přiblížení pro zpětné vyhledávání takto:
geocoder.reverse(e.latlng, map.options.crs.scale(21), function(results)
tj. změňte map.getZoom() do 21. Maximální úroveň přiblížení pro zpětné vyhledávání je 21. Můžete si vybrat jinou úroveň přiblížení, aby vyhovovala vašim potřebám.
Odstraňování problémů
Pokud funkce vyhledávání na vaší mapě nefunguje, můžete zkontrolovat konzoli webového prohlížeče a zjistit, co se pokazilo. Některým lidem se může zobrazit 406 nepřijatelné nebo CORS není povoleno chyba. Ujistěte se, že jste nastavili správný typ MIME pro .php
v konfiguračním souboru Apache. Někteří lidé mohou mít následující řádek, který může způsobit výše uvedené chyby.
AddType text/html .php
Mělo by to být
AddType application/json .php
Po změně typu MIME. Znovu načtěte Apache, aby se změny projevily.
sudo systemctl reload apache2