En un tutorial anterior, expliqué el proceso de creación de su propio servidor de teselas OSM en Ubuntu 20.04. Este tutorial le mostrará cómo configurar el servidor de geocodificación de Nominatim en Ubuntu 20.04. Nominatim proporciona la funcionalidad de búsqueda para OpenStreetMap, por lo que si un visitante ingresa una dirección en un cuadro de búsqueda, se devolverá la ubicación de latitud/longitud para esa dirección.
Paso 1:Cree Nominatim desde la fuente
Instala paquetes de dependencia para compilar 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
Crea el nominatim
usuario. (No es necesario crear una contraseña para este usuario).
sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim
Cambiar a /srv/nominatim/
directorio.
cd /srv/nominatim/
Otorga permisos a tu propia cuenta de usuario.
sudo apt install acl sudo setfacl -R -m u:username:rwx /srv/nominatim/
Descarga Nominatim desde el sitio web oficial.
wget https://nominatim.org/release/Nominatim-3.5.1.tar.bz2
Extraiga el tarball.
tar xvf Nominatim-3.5.1.tar.bz2
Crea la build
directorio.
mkdir build
Cambie a este directorio y configure el entorno de compilación.
cd build cmake /srv/nominatim/Nominatim-3.5.1
Compile el código fuente.
make
Paso 2:Configurar Nominatim
El archivo de configuración predeterminado para Nominatim es /srv/nominatim/build/settings/settings.php
. Podemos crear un local.php
archivo y agregue nuestras modificaciones allí.
sudo nano /srv/nominatim/build/settings/local.php
Agregue las siguientes líneas en el archivo.
<?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 configuración anterior define
- La ruta de la instancia de Nominatim relativa a su servidor de teselas.
- Latitud, longitud y nivel de zoom predeterminados.
- URL de su servidor de teselas OSM. De forma predeterminada, Nominatim utiliza el
https://tile.openstreetmap.org
público servidor de teselas. Aquí uso mi propio servidor de teselas.
También puede echar un vistazo a /srv/nominatim/build/settings/settings.php
archivo y agregue sus propias personalizaciones si surge la necesidad. Por ejemplo, si va a importar un conjunto de datos grande (Europa, América del Norte, planeta, etc.), es una buena práctica habilitar el almacenamiento de ubicaciones de nodos en nodos planos, de modo que las coordenadas de los nodos se almacenen en un archivo simple en lugar del base de datos, ahorrándole tiempo de importación y almacenamiento en disco.
@define('CONST_Osm2pgsql_Flatnode_File', '/srv/nominatim/flatnode.file');
Guarde y cierre el archivo.
Paso 3:Instalar y configurar PostgreSQL
Nota :Si el servidor de mosaicos de OSM y Nominatim están instalados en el mismo servidor, entonces puede omitir este paso, porque ya lo hizo cuando configuró el servidor de mosaicos de OSM.
Usaremos PostgreSQL para almacenar datos de mapas. PostGIS es una extensión geoespacial de PostgreSQL. Ejecute los siguientes comandos para instalarlos.
sudo apt install postgresql postgresql-contrib postgis postgresql-12-postgis-3
Luego, debemos ajustar PostgreSQL para obtener el máximo rendimiento. Edite el archivo de configuración principal.
sudo nano /etc/postgresql/12/main/postgresql.conf
Encuentre los siguientes parámetros en este archivo y use los siguientes valores.
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
Guarde y cierre el archivo. Reinicie PostgreSQL para que los cambios surtan efecto.
sudo systemctl restart postgresql
Tenga en cuenta que debe activar fsync
y full_page_write
después de importar la base de datos de OSM, o corre el riesgo de corromper la base de datos.
De forma predeterminada, PostgreSQL intentaría usar páginas enormes en la RAM. Sin embargo, Linux por defecto no asigna páginas grandes. Compruebe el ID de proceso de PostgreSQL.
sudo head -1 /var/lib/postgresql/12/main/postmaster.pid
Salida de muestra:
7031
Luego verifique el valor de VmPeak de este ID de proceso.
grep ^VmPeak /proc/7031/status
Salida de muestra:
VmPeak: 16282784 kB
Este es el tamaño máximo de memoria que utilizará PostgreSQL. Ahora compruebe el tamaño de la página enorme en Linux.
cat /proc/meminfo | grep -i huge
Salida de muestra:
AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 0 kB
Podemos calcular cuántas páginas grandes necesitamos. Divida el valor de VmPeak por el tamaño de la página grande:16282784 kB / 2048 kB =7950. Edite /etc/sysctl.conf
archivo.
sudo nano /etc/sysctl.conf
Agregue la siguiente línea para asignar 7950 páginas grandes.
vm.nr_hugepages = 7950
Guarde y cierre el archivo. Luego aplique los cambios.
sudo sysctl -p
Si vuelves a consultar el meminfo,
cat /proc/meminfo | grep -i huge
Podemos ver que hay 7950 páginas enormes disponibles.
AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 7950 HugePages_Free: 7950 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
Reinicie PostgreSQL para usar páginas grandes.
sudo systemctl restart postgresql
Paso 4:Importar base de datos OSM
Descargue el archivo de volcado de importancia de Wikipedia, que mejorará la calidad de los resultados de búsqueda de Nomiatim.
cd /srv/nominatim/Nominatim-3.5.1/data wget https://www.nominatim.org/data/wikimedia-importance.sql.gz
Descargue los datos de los códigos postales de EE. UU. y el Reino Unido.
wget https://www.nominatim.org/data/us_postcode_data.sql.gz wget https://www.nominatim.org/data/gb_postcode_data.sql.gz
Descargar archivo de datos de código de país.
wget -O country_osm_grid.sql.gz https://www.nominatim.org/data/country_grid.sql.gz
Luego, debe descargar un archivo OSM e importarlo a PostgreSQL. Puede ir a http://download.geofabrik.de para descargar el extracto que necesita. También puede usar el archivo PBF durante el proceso de configuración del servidor de teselas.
Crea los www-data
usuario en PostgreSQL, por lo que el servidor web tendrá acceso de solo lectura a la base de datos.
sudo -u postgres createuser www-data
Otorgar permiso a postgres
usuario.
sudo setfacl -R -m u:postgres:rwx /srv/nominatim/
Cambiar a postgres
usuario.
sudo -u postgres -i
Y ejecute el siguiente comando para importar extractos de OSM a 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
Después de importar la base de datos, comenzará el proceso de indexación. Hay 30 rangos en total.
Una vez que haya terminado, ejecute el siguiente comando para verificar.
/srv/nominatim/build/utils/check_import_finished.php
Salga de postgres
usuario.
exit
Paso 5:Configurar Apache
Si Nominatim está instalado en el servidor de mosaicos de OSM, edite el archivo de configuración del servidor de mosaicos.
sudo nano /etc/apache2/sites-enabled/tileserver_site-le-ssl.conf
Agregue las siguientes líneas entre VirtualHost
etiquetas.
<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
Guarde y cierre el archivo. Luego recargar Apache.
sudo systemctl reload apache2
Si está configurando Nominatim en un servidor separado, entonces necesita instalar Apache y 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
Cree un host virtual para Nominatim.
sudo nano /etc/apache2/sites-enabled/nominatim.conf
Agregue las siguientes líneas en este archivo.
<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>
Guarde y cierre el archivo. Luego reinicie Apache.
sudo systemctl restart apache2
Ahora visita https://tile.yourdomain.com/nominatim
. Verás tu instancia de Nomiatim.
El archivo CSS se encuentra en /srv/nominatim/build/website/css/search.css
, si desea personalizar el aspecto.
Paso 6:Actualizar la base de datos de Nominatim
Para mantener actualizada la base de datos de Nominatim, debemos instalar Pyosmium
. Está disponible desde el repositorio de software predeterminado, pero se recomienda instalar la última versión usando pip3.
sudo pip3 install osmium
Esto instalará un binario /usr/local/bin/pyosmium-get-changes
. Edite el archivo de configuración de Nominatim.
sudo nano /srv/nominatim/build/settings/local.php
Agregue la siguiente línea para especificar la ubicación de pyosmium-get-changes
.
@define('CONST_Pyosmium_Binary', '/usr/local/bin/pyosmium-get-changes');
A continuación, debemos decirle a Nominatim dónde descargar las actualizaciones. De forma predeterminada, está configurado para descargar actualizaciones desde https://planet.openstreetmap.org/replication/minute
. Si descargó el archivo OSM PBF de geofabrik.de, entonces es mejor descargar también las actualizaciones desde allí.
Para encontrar la URL de actualización de su propio mapa, vaya a https://download.geofabrik.de/ y localice su región. Luego busque la URL para .osc.gz
archivo.
Esta URL es la URL de actualización.
Agrega la siguiente línea en /srv/nominatim/build/settings/local.php
expediente. Debe utilizar su propia URL de actualización.
// 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');
Guarde y cierre el archivo. Otorgar permisos a postgres
usuario.
sudo setfacl -R -m "u:postgres:rwx" /srv/nominatim/build/
Luego cambie al usuario de postgres.
sudo -u postgres -i
Inicialice el proceso de actualización.
/srv/nominatim/build/utils/update.php --init-updates
Actualice la base de datos de Nominatim.
/srv/nominatim/build/utils/update.php --import-osmosis-all
Paso 7:configurar el trabajo cron para la actualización automática
Edite el archivo Crontab del usuario root.
sudo crontab -e
Agregue la siguiente línea en este archivo.
@daily sudo -u postgres /srv/nominatim/build/utils/update.php --import-osmosis-all
Guarde y cierre el archivo. Si no desea actualizar automáticamente la base de datos de Nominatim, simplemente elimine la línea anterior de su archivo Crontab.
Cómo agregar funcionalidad de búsqueda a un mapa deslizable
Supongo que su mapa resbaladizo se muestra usando la biblioteca Leaflet JavaScript. Para agregar la funcionalidad de búsqueda a su mapa, debe usar un complemento de geocodificación de folletos. Le mostraré cómo usar Leaflet Control Geocoder. En realidad es muy simple.
Suponga que utilizó el siguiente código HTML para mostrar su mapa resbaladizo.
<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>
Ahora debe agregar las siguientes dos líneas en el encabezado HTML para usar el Geocodificador de control de folletos complemento.
<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>
Luego agregue la siguiente función al <script>...</script>
código para que la función de búsqueda se agregue a su mapa.
L.Control.geocoder().addTo(map);
El código HTML final se ve así:
<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>
Guarde y cierre el archivo. Luego vuelva a cargar el mapa en su navegador web, debería ver un botón de búsqueda en la esquina superior derecha.
De forma predeterminada, Geocodificador de control de folletos utiliza el https://nominatim.openstreetmap.org
público servicio de geocodificación. Para que use su propio servicio de geocodificación de Nominatim, elimine la siguiente línea.
L.Control.geocoder().addTo(map);
Agregue las siguientes líneas en su lugar. Reemplace la URL con la URL de su servicio de geocodificación de Nominatim. Tenga en cuenta que no debe omitir la barra diagonal final.
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 posición predeterminada es topright
. Puedes cambiarlo a topleft
si quieres.
También puede agregar el siguiente código para geocodificación inversa. Cuando un visitante haga clic en un punto del mapa, aparecerá el nombre de esa dirección.
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(); } } }); });
Guarde y cierre el archivo. A continuación, vuelva a cargar el mapa en su navegador web.
Mejorar la precisión de la búsqueda inversa
Hay dos tipos de búsqueda en Nominatim:
- búsqueda hacia adelante, también conocido como geocodificación, devuelve la latitud y la longitud de una dirección
- búsqueda inversa , también conocida como geocodificación inversa, devuelve una dirección de latitud y longitud, es decir, cuando un visitante hace clic en un punto del mapa.
Si realiza una búsqueda inversa, el pin marcador y la ventana emergente no están en la proximidad inmediata de la posición en el mapa en la que hizo clic, debe aumentar el nivel de zoom. El map.getZoom() la función obtendrá la vista de mapa actual , que se configura con setView() funcionar así
var map = L.map('map').setView([54,1],6);
El nivel de zoom está establecido en 6
, lo que dará poca precisión para la búsqueda inversa. Podemos codificar el nivel de zoom para la búsqueda inversa así:
geocoder.reverse(e.latlng, map.options.crs.scale(21), function(results)
es decir, cambiar map.getZoom() a 21. El nivel de zoom máximo para la búsqueda inversa es 21. Puede elegir otro nivel de zoom que se adapte a sus necesidades.
Resolución de problemas
Si la función de búsqueda en su mapa no funciona, puede consultar la consola de su navegador web para averiguar qué salió mal. Algunas personas pueden ver el 406 no aceptable o un CORS no permitido error. Asegúrese de haber configurado el tipo MIME correcto para .php
en el archivo de configuración de Apache. Algunas personas pueden tener la siguiente línea, lo que puede causar los errores anteriores.
AddType text/html .php
debería ser
AddType application/json .php
Después de cambiar el tipo MIME. Vuelva a cargar Apache para que los cambios surtan efecto.
sudo systemctl reload apache2