Dalam tutorial sebelumnya, saya menjelaskan proses membangun server ubin OSM Anda sendiri di Ubuntu 20.04. Tutorial ini akan menunjukkan kepada Anda cara mengatur server Nominatim Geocoding di Ubuntu 20.04. Nominatim menyediakan fungsionalitas pencarian untuk OpenStreetMap, jadi jika pengunjung memasukkan alamat di kotak pencarian, lokasi garis lintang/garis bujur untuk alamat tersebut akan dikembalikan.
Catatan: Jika Anda akan menyiapkan Nominatim untuk seluruh planet, maka Anda harus memutar server lain untuk Nominatim, karena itu juga akan membutuhkan RAM 64GB dan SSD 1TB.
Langkah 1:Bangun Nominatim Dari Sumber
Instal paket ketergantungan untuk membangun 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
Buat nominatim
pengguna. (Tidak perlu membuat kata sandi untuk pengguna ini.)
sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim
Ubah ke /srv/nominatim/
direktori.
cd /srv/nominatim/
Berikan izin ke akun pengguna Anda sendiri.
sudo apt install acl sudo setfacl -R -m u:username:rwx /srv/nominatim/
Unduh Nominatim dari situs resminya.
wget https://nominatim.org/release/Nominatim-3.5.1.tar.bz2
Ekstrak tarballnya.
tar xvf Nominatim-3.5.1.tar.bz2
Buat build
direktori.
mkdir build
Ubah ke direktori ini dan konfigurasikan lingkungan build.
cd build cmake /srv/nominatim/Nominatim-3.5.1
Kompilasi kode sumber.
make
Langkah 2:Konfigurasi Nominatim
File konfigurasi default untuk Nominatim adalah /srv/nominatim/build/settings/settings.php
. Kita dapat membuat local.php
file dan tambahkan modifikasi kami di sana.
sudo nano /srv/nominatim/build/settings/local.php
Tambahkan baris berikut dalam file.
<?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');
Konfigurasi di atas mendefinisikan
- Jalur instance Nominatim relatif terhadap server ubin Anda.
- Lintang, bujur, dan tingkat zoom default.
- URL server ubin OSM Anda. Secara default, Nominatim menggunakan
https://tile.openstreetmap.org
publik server ubin. Di sini saya menggunakan server ubin saya sendiri.
Anda juga dapat melihat /srv/nominatim/build/settings/settings.php
file dan tambahkan kustomisasi Anda sendiri jika diperlukan. Misalnya, jika Anda akan mengimpor kumpulan data besar (Eropa, Amerika Utara, planet, dll.), sebaiknya aktifkan penyimpanan simpul datar dari lokasi simpul, jadi koordinat simpul akan disimpan dalam file sederhana alih-alih file database, menghemat waktu impor dan penyimpanan disk.
@define('CONST_Osm2pgsql_Flatnode_File', '/srv/nominatim/flatnode.file');
Simpan dan tutup file.
Langkah 3:Instal dan Konfigurasi PostgreSQL
Catatan :Jika server ubin OSM dan Nominatim diinstal pada server yang sama, maka Anda dapat melewati langkah ini, karena Anda telah melakukannya saat menyiapkan server ubin OSM.
Kami akan menggunakan PostgreSQL untuk menyimpan data peta. PostGIS adalah ekstensi geospasial untuk PostgreSQL. Jalankan perintah berikut untuk menginstalnya.
sudo apt install postgresql postgresql-contrib postgis postgresql-12-postgis-3
Kemudian kita perlu menyetel PostgreSQL untuk kinerja maksimal. Edit file konfigurasi utama.
sudo nano /etc/postgresql/12/main/postgresql.conf
Temukan parameter berikut dalam file ini dan gunakan nilai berikut.
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
Simpan dan tutup file. Mulai ulang PostgreSQL agar perubahan diterapkan.
sudo systemctl restart postgresql
Perhatikan bahwa Anda harus mengaktifkan fsync
dan full_page_write
setelah mengimpor database OSM, atau Anda berisiko merusak database.
Secara default, PostgreSQL akan mencoba menggunakan halaman besar di RAM. Namun, Linux secara default tidak mengalokasikan halaman yang besar. Periksa ID proses PostgreSQL.
sudo head -1 /var/lib/postgresql/12/main/postmaster.pid
Contoh keluaran:
7031
Kemudian periksa nilai VmPeak dari ID proses ini.
grep ^VmPeak /proc/7031/status
Contoh keluaran:
VmPeak: 16282784 kB
Ini adalah ukuran memori puncak yang akan digunakan oleh PostgreSQL. Sekarang periksa ukuran halaman besar di Linux.
cat /proc/meminfo | grep -i huge
Contoh keluaran:
AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 0 kB
Kita bisa menghitung berapa banyak halaman yang kita butuhkan. Bagi nilai VmPeak dengan ukuran halaman besar:16282784 kB / 2048 kB =7950. Edit /etc/sysctl.conf
berkas.
sudo nano /etc/sysctl.conf
Tambahkan baris berikut untuk mengalokasikan 7950 halaman besar.
vm.nr_hugepages = 7950
Simpan dan tutup file. Kemudian terapkan perubahannya.
sudo sysctl -p
Jika Anda memeriksa meminfo lagi,
cat /proc/meminfo | grep -i huge
Kita bisa melihat ada 7.950 halaman besar yang tersedia.
AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 7950 HugePages_Free: 7950 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
Mulai ulang PostgreSQL untuk menggunakan halaman besar.
sudo systemctl restart postgresql
Langkah 4:Impor Basis Data OSM
Unduh file dump kepentingan Wikipedia, yang akan meningkatkan kualitas hasil pencarian Nomiatim.
cd /srv/nominatim/Nominatim-3.5.1/data wget https://www.nominatim.org/data/wikimedia-importance.sql.gz
Unduh data kode pos AS dan Inggris.
wget https://www.nominatim.org/data/us_postcode_data.sql.gz wget https://www.nominatim.org/data/gb_postcode_data.sql.gz
Unduh file data kode negara.
wget -O country_osm_grid.sql.gz https://www.nominatim.org/data/country_grid.sql.gz
Kemudian Anda perlu mengunduh file OSM dan mengimpornya ke PostgreSQL. Anda dapat pergi ke http://download.geofabrik.de untuk mengunduh ekstrak yang Anda butuhkan. Anda juga dapat menggunakan file PBF selama proses penyiapan server ubin.
Buat www-data
pengguna di PostgreSQL, sehingga server web akan memiliki akses read-only ke database.
sudo -u postgres createuser www-data
Berikan izin ke postgres
pengguna.
sudo setfacl -R -m u:postgres:rwx /srv/nominatim/
Beralih ke postgres
pengguna.
sudo -u postgres -i
Dan jalankan perintah berikut untuk mengimpor ekstrak OSM ke 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
Setelah mengimpor database, proses pengindeksan akan dimulai. Ada total 30 peringkat.
Setelah selesai, jalankan perintah berikut untuk memverifikasi.
/srv/nominatim/build/utils/check_import_finished.php
Keluar dari postgres
pengguna.
exit
Langkah 5:Siapkan Apache
Jika Nominatim diinstal pada server ubin OSM, maka edit file konfigurasi server ubin.
sudo nano /etc/apache2/sites-enabled/tileserver_site-le-ssl.conf
Tambahkan baris berikut di antara VirtualHost
tag.
<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
Simpan dan tutup file. Kemudian muat ulang Apache.
sudo systemctl reload apache2
Jika Anda menyiapkan Nominatim di server terpisah, Anda perlu menginstal Apache dan 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
Buat host virtual untuk Nominatim.
sudo nano /etc/apache2/sites-enabled/nominatim.conf
Tambahkan baris berikut dalam file ini.
<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>
Simpan dan tutup file. Kemudian restart Apache.
sudo systemctl restart apache2
Sekarang kunjungi https://tile.yourdomain.com/nominatim
. Anda akan melihat instance Nomiatim Anda.
File CSS terletak di /srv/nominatim/build/website/css/search.css
, jika Anda ingin menyesuaikan tampilan.
Langkah 6:Perbarui Basis Data Nominatim
Untuk menjaga agar database Nominatim tetap mutakhir, kita perlu menginstal Pyosmium
. Ini tersedia dari repositori perangkat lunak default, tetapi disarankan untuk menginstal versi terbaru menggunakan pip3.
sudo pip3 install osmium
Ini akan menginstal /usr/local/bin/pyosmium-get-changes
biner . Edit file konfigurasi Nominatim.
sudo nano /srv/nominatim/build/settings/local.php
Tambahkan baris berikut untuk menentukan lokasi pyosmium-get-changes
.
@define('CONST_Pyosmium_Binary', '/usr/local/bin/pyosmium-get-changes');
Selanjutnya, kami perlu memberi tahu Nominatim tempat mengunduh pembaruan. Secara default, ini dikonfigurasi untuk mengunduh pembaruan dari https://planet.openstreetmap.org/replication/minute
. Jika Anda mengunduh file OSM PBF dari geofabrik.de, sebaiknya unduh juga pembaruan dari sana.
Untuk menemukan URL pembaruan untuk peta Anda sendiri, buka https://download.geofabrik.de/ dan temukan wilayah Anda. Kemudian temukan URL untuk .osc.gz
berkas.
URL ini adalah URL pembaruan.
Tambahkan baris berikut di /srv/nominatim/build/settings/local.php
mengajukan. Anda harus menggunakan URL pembaruan Anda sendiri.
// 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');
Simpan dan tutup file. Berikan izin ke postgres
pengguna.
sudo setfacl -R -m "u:postgres:rwx" /srv/nominatim/build/
Kemudian swith ke pengguna postgres.
sudo -u postgres -i
Inisialisasi proses pembaruan.
/srv/nominatim/build/utils/update.php --init-updates
Perbarui basis data Nominatim.
/srv/nominatim/build/utils/update.php --import-osmosis-all
Langkah 7:Siapkan Cron Job Untuk Pembaruan Otomatis
Edit file Crontab pengguna root.
sudo crontab -e
Tambahkan baris berikut dalam file ini.
@daily sudo -u postgres /srv/nominatim/build/utils/update.php --import-osmosis-all
Simpan dan tutup file. Jika Anda tidak ingin memperbarui database Nominatim secara otomatis, cukup hapus baris di atas dari file Crontab Anda.
Cara Menambahkan Fungsi Pencarian ke Slippy Map
Saya berasumsi peta slippy Anda ditampilkan menggunakan perpustakaan JavaScript Leaflet. Untuk menambahkan fungsionalitas pencarian ke peta Anda, Anda perlu menggunakan plugin geocoding Leaflet. Saya akan menunjukkan cara menggunakan Geocoder Kontrol Leaflet. Sebenarnya sangat sederhana.
Misalkan Anda menggunakan kode HTML berikut untuk menampilkan peta slippy Anda.
<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>
Sekarang Anda perlu menambahkan dua baris berikut di header HTML untuk menggunakan Leaflet Control Geocoder pengaya.
<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>
Kemudian tambahkan fungsi berikut ke <script>...</script>
kode sehingga fungsi pencarian akan ditambahkan ke peta Anda.
L.Control.geocoder().addTo(map);
Kode HTML terakhir terlihat seperti ini:
<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>
Simpan dan tutup file. Kemudian muat ulang peta di browser web Anda, Anda akan melihat tombol pencarian di sudut kanan atas.
Secara default, Leaflet Control Geocoder menggunakan https://nominatim.openstreetmap.org
publik layanan geocoding. Untuk membuatnya menggunakan layanan geocoding Nominatim Anda sendiri, hapus baris berikut.
L.Control.geocoder().addTo(map);
Tambahkan baris berikut sebagai gantinya. Ganti URL dengan URL layanan geocoding Nominatim Anda. Perhatikan bahwa Anda tidak boleh meninggalkan garis miring.
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);
Posisi default adalah topright
. Anda dapat mengubahnya ke topleft
jika Anda mau.
Anda juga dapat menambahkan kode berikut untuk geocoding terbalik. Saat pengunjung mengklik sebuah titik di peta, nama alamat tersebut akan muncul.
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(); } } }); });
Simpan dan tutup file. Kemudian muat ulang peta di browser web Anda.
Meningkatkan Akurasi Pencarian Terbalik
Ada dua jenis pencarian di Nominatim:
- teruskan pencarian, alias geocoding, mengembalikan garis lintang dan garis bujur untuk sebuah alamat
- penelusuran terbalik , alias geocoding terbalik, mengembalikan alamat untuk garis lintang dan garis bujur, yaitu saat pengunjung mengeklik suatu titik di peta.
Jika Anda melakukan pencarian terbalik, pin penanda dan pop-up tidak berada di dekat posisi pada peta yang Anda klik, Anda perlu meningkatkan tingkat zoom. map.getZoom() fungsi akan mendapatkan tampilan peta saat ini , yang disetel dengan setView() berfungsi seperti itu
var map = L.map('map').setView([54,1],6);
Tingkat zoom disetel ke 6
, yang akan memberikan akurasi yang buruk untuk pencarian terbalik. Kami dapat membuat kode tingkat zoom untuk pencarian terbalik seperti ini:
geocoder.reverse(e.latlng, map.options.crs.scale(21), function(results)
yaitu mengubah map.getZoom() ke 21. Tingkat zoom maksimum untuk pencarian terbalik adalah 21. Anda dapat memilih tingkat zoom lain yang sesuai dengan kebutuhan Anda.
Pemecahan Masalah
Jika fungsi pencarian di peta Anda tidak berfungsi, Anda dapat memeriksa konsol browser web Anda untuk mencari tahu apa yang salah. Beberapa orang mungkin melihat 406 tidak dapat diterima atau CORS tidak diizinkan kesalahan. Pastikan Anda telah menyetel jenis MIME yang benar untuk .php
dalam file konfigurasi Apache. Beberapa orang mungkin memiliki baris berikut, yang dapat menyebabkan kesalahan di atas.
AddType text/html .php
Seharusnya
AddType application/json .php
Setelah mengubah jenis MIME. Muat ulang Apache agar perubahan diterapkan.
sudo systemctl reload apache2