En un tutorial anterior, expliqué el proceso de creación de su propio servidor de teselas OSM en Debian 10. Este tutorial le mostrará cómo configurar el servidor de codificación geográfica de Nominatim en Debian 10. Nominatim proporciona la función 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 python3-setuptools python3-dev python3-pip python3-psycopg2 python3-tidylib git clang-tidy postgresql-server-dev-11
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
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: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.
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 4:Configurar Apache
Edite el archivo de configuración del servidor de teselas.
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
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.
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 a postgres
usuario.
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
Configurar trabajo cron para 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.
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: 'Moon', placeholder: 'Search here...', geocoder: geocoder }).addTo(map); var marker; setTimeout(function() { control.setQuery('Earth'); }, 12000);
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