在Ubuntu20.04上设置OSM地理编码服务器

  • 技术文档
  • 2022.03.23
  • 浏览:91

在之前的教程中,我解释了在Ubuntu 20.04上构建自己的OSM tile服务器的过程。本教程将向您展示如何在Ubuntu20.04上设置Namingm地理编码服务器。Nagnitm为OpenStreetMap提供搜索功能,因此如果访客在搜索框中输入地址,将返回该地址的纬度/经度位置。

注意:如果你要为整个星球安装Namingm,那么你应该为Namingm启动另一台服务器,因为它还需要64GB的RAM和1TB的SSD。

第一步:从源代码构建提名

安装依赖项包以构建Nagnitm。

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

创建提名用户。(无需为此用户创建密码。)

sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim

更改为/srv/m/目录。

cd /srv/nominatim/

向您自己的用户帐户授予权限。

sudo apt install acl  sudo setfacl -R -m u:username:rwx /srv/nominatim/

从官方网站下载提名。

wget https://nominatim.org/release/Nominatim-3.5.1.tar.bz2

取出柏油球。

tar xvf Nominatim-3.5.1.tar.bz2

创建构建目录。

mkdir build

更改到此目录并配置生成环境。

cd build  cmake /srv/nominatim/Nominatim-3.5.1

编译源代码。

make

Build Nominatim From Source

第2步:配置提名

Nagnitm的默认配置文件是/srv/Nagnitm/build/settings/settings。php。我们可以创建一个本地。php文件,并在那里添加我们的修改。

sudo nano /srv/nominatim/build/settings/local.php

在文件中添加以下行。

<?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');

上述配置定义了

  • 相对于磁贴服务器的Namingm实例的路径。
  • 默认纬度、经度和缩放级别。
  • OSM磁贴服务器的URL。默认情况下,提名使用公共资源https://tile.openstreetmap.org磁贴服务器。在这里,我使用自己的磁贴服务器。

您还可以查看/srv/namitm/build/settings/settings。php文件,并在需要时添加自己的自定义项。例如,如果要导入大型数据集(欧洲、北美、planet等),最好启用节点位置的平面节点存储,这样节点坐标将存储在一个简单的文件中,而不是数据库中,从而节省导入时间和磁盘存储。

@define('CONST_Osm2pgsql_Flatnode_File', '/srv/nominatim/flatnode.file');

保存并关闭文件。

第3步:安装和配置PostgreSQL

注意:如果OSM tile server和Nagnitm安装在同一台服务器上,则可以跳过此步骤,因为您在设置OSM tile server时已经完成了此操作。

我们将使用PostgreSQL存储地图数据。PostGIS是PostgreSQL的地理空间扩展。运行以下命令来安装它们。

sudo apt install postgresql postgresql-contrib postgis postgresql-12-postgis-3

然后我们需要调整PostgreSQL以获得最佳性能。编辑主配置文件。

sudo nano /etc/postgresql/12/main/postgresql.conf

在该文件中查找以下参数并使用以下值。

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

保存并关闭文件。重新启动PostgreSQL以使更改生效。

sudo systemctl restart postgresql

请注意,导入OSM数据库后,应打开fsync和full_page_write,否则可能会损坏数据库。

默认情况下,PostgreSQL会尝试在RAM中使用巨大的页面。然而,Linux默认情况下不会分配巨大的页面。检查PostgreSQL的进程ID。

sudo head -1 /var/lib/postgresql/12/main/postmaster.pid

样本输出:

7031

然后检查该进程ID的峰值。

grep ^VmPeak /proc/7031/status

样本输出:

VmPeak: 16282784 kB

这是PostgreSQL将使用的峰值内存大小。现在检查Linux中巨大页面的大小。

cat /proc/meminfo | grep -i huge

样本输出:

AnonHugePages:         0 kB ShmemHugePages:        0 kB HugePages_Total:       0 HugePages_Free:        0 HugePages_Rsvd:        0 HugePages_Surp:        0 Hugepagesize:       2048 kB Hugetlb:               0 kB

我们可以计算出我们需要多少巨大的页面。将VmPeak值除以巨大页面的大小:16282784KB/2048KB=7950。编辑/etc/sysctl。conf文件。

sudo nano /etc/sysctl.conf

添加以下行以分配7950个大页面。

vm.nr_hugepages = 7950

保存并关闭文件。然后应用更改。

sudo sysctl -p

如果你再次查看meminfo,

cat /proc/meminfo | grep -i huge

我们可以看到有7950个巨大的页面可用。

AnonHugePages:         0 kB ShmemHugePages:        0 kB HugePages_Total:    7950 HugePages_Free:     7950 HugePages_Rsvd:        0 HugePages_Surp:        0 Hugepagesize:       2048 kB 

重新启动PostgreSQL以使用大型页面。

sudo systemctl restart postgresql

第4步:导入OSM数据库

下载维基百科重要性转储文件,这将提高Nomatim搜索结果的质量。

cd /srv/nominatim/Nominatim-3.5.1/data  wget https://www.nominatim.org/data/wikimedia-importance.sql.gz

下载美国和英国邮政编码数据。

wget https://www.nominatim.org/data/us_postcode_data.sql.gz  wget https://www.nominatim.org/data/gb_postcode_data.sql.gz

下载国家代码数据文件。

wget -O country_osm_grid.sql.gz https://www.nominatim.org/data/country_grid.sql.gz

然后需要下载一个OSM文件并将其导入PostgreSQL。你可以去http://download.geofabrik.de下载你需要的摘录。也可以在磁贴服务器设置过程中使用PBF文件。

在PostgreSQL中创建www数据用户,这样web服务器将对数据库具有只读访问权限。

sudo -u postgres createuser www-data

向postgres用户授予权限。

sudo setfacl -R -m u:postgres:rwx /srv/nominatim/

切换到postgres用户。

sudo -u postgres -i

并运行以下命令将OSM提取导入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

Nominatim import speed for planet pbf on AMD EPYC 7282

导入数据库后,索引过程将开始。总共有30个等级。

nominatim-indexing-process-20.04

完成后,运行以下命令进行验证。

/srv/nominatim/build/utils/check_import_finished.php

nominatim import osm database

退出postgres用户。

exit

第5步:设置Apache

如果OSM磁贴服务器上安装了Namingm,则编辑磁贴服务器配置文件。

sudo nano /etc/apache2/sites-enabled/tileserver_site-le-ssl.conf

在VirtualHost标记之间添加以下行。

<Directory "/srv/nominatim/build/website"&gt;   Options FollowSymLinks MultiViews   AddType application/json   .php   DirectoryIndex search.php   Require all granted </Directory>  alias /nominatim /srv/nominatim/build/website 

保存并关闭文件。然后重新加载Apache。

sudo systemctl reload apache2

如果要在单独的服务器上设置Namingm,则需要安装Apache和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

为提名创建虚拟主机。

sudo nano /etc/apache2/sites-enabled/nominatim.conf

在此文件中添加以下行。

<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> 

保存并关闭文件。然后重启Apache。

sudo systemctl restart apache2

现在参观https://tile.yourdomain.com/nominatim.您将看到您的Nomatim实例。

nominatim setup with own tile server

CSS文件位于/srv/namitm/build/website/CSS/search。css,如果你想定制外观。

第6步:更新提名数据库

为了使Namingm数据库保持最新,我们需要安装Pyosmium。它可以从默认的软件存储库中获得,但建议使用pip3安装最新版本。

sudo pip3 install osmium

这将安装一个二进制文件/usr/local/bin/pyosmium获取更改。编辑配置文件。

sudo nano /srv/nominatim/build/settings/local.php

添加以下行以指定pyosmium get changes的位置。

@define('CONST_Pyosmium_Binary', '/usr/local/bin/pyosmium-get-changes');

接下来,我们需要告诉Namingm在哪里下载更新。默认情况下,它被配置为从https://planet.openstreetmap.org/replication/minute.如果您从geofabrik下载了OSM PBF文件。de,那么最好也从那里下载更新。

要查找自己地图的更新URL,请转到https://download.geofabrik.de/找到你所在的地区。然后找到该文件的URL。osc。gz文件。

nominatim update database

此URL是更新URL。

Nominatim Replication URL

在/srv/namignm/build/settings/local中添加以下行。php文件。您需要使用自己的更新URL。

// base URL of the replication service @define('CONST_Replication_Url', ''); // 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');

保存并关闭文件。向postgres用户授予权限。

sudo setfacl -R -m "u:postgres:rwx" /srv/nominatim/build/

然后切换到postgres用户。

sudo -u postgres -i

初始化更新过程。

/srv/nominatim/build/utils/update.php --init-updates

更新我的数据库。

/srv/nominatim/build/utils/update.php --import-osmosis-all

第7步:设置Cron作业以进行自动更新

编辑root用户的Crontab文件。

sudo crontab -e

在此文件中添加以下行。

@daily sudo -u postgres /srv/nominatim/build/utils/update.php --import-osmosis-all

保存并关闭文件。如果不想自动更新Nagnitm数据库,只需从Crontab文件中删除上面的一行即可。

如何在拖沓的地图上添加搜索功能

我假设你的slippy地图是使用传单JavaScript库显示的。要将搜索功能添加到地图中,需要使用传单地理编码插件。我将向您展示如何使用传单控制地理编码器。其实很简单。

假设您使用以下HTML代码来显示拖拉地图。

<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>

现在,您需要在HTML标题中添加以下两行,以使用传单控制地理编码器插件。

<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>

然后将以下函数添加到<;脚本></脚本>;将搜索功能添加到地图中。

L.Control.geocoder().addTo(map);

最终的HTML代码如下所示:

<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>

保存并关闭文件。然后在web浏览器中重新加载地图,您应该会在右上角看到一个搜索按钮。

默认情况下,传单控制地理编码器使用公共https://nominatim.openstreetmap.org地理编码服务。要使用您自己的地理编码服务,请删除以下行。

L.Control.geocoder().addTo(map);

改为添加以下行。将该URL替换为您的提名地理编码服务的URL。请注意,不应省略尾随的斜杠。

      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); 

默认位置为右上角。如果你愿意,可以把它改成左上角。

您还可以为反向地理编码添加以下代码。当访客点击地图上的某个点时,该地址的名称就会出现。

      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();             }           }         });       }); 

保存并关闭文件。然后在web浏览器中重新加载地图。

提高反向搜索的准确性

提名中有两种类型的搜索:

  • 前向搜索,又名地理编码,返回地址的纬度和经度
  • 反向搜索,又名反向地理编码,返回纬度和经度的地址,即当访问者点击地图上的某个点时。

如果进行反向搜索,则标记针和弹出窗口与您单击的地图上的位置不在同一位置,则需要增加缩放级别。地图。getZoom()函数将获取当前的地图视图,该视图由setView()函数设置,如下所示

var map = L.map('map').setView([54,1],6);

缩放级别设置为6,这将导致反向搜索的精度较低。我们可以对反向搜索的缩放级别进行硬编码,如下所示:

geocoder.reverse(e.latlng, map.options.crs.scale(21), function(results)

i、 换张地图。getZoom()到21。反向搜索的最大缩放级别为21。您可以选择另一个缩放级别以满足您的需要。

故障排除

如果地图上的搜索功能不起作用,您可以检查web浏览器的控制台,找出哪里出了问题。有些人可能会认为406不可接受或CORS不允许出现错误。确保为设置了正确的MIME类型。Apache配置文件中的php。有些人可能有下面这句话,这可能会导致上述错误。

AddType text/html .php

应该是的

AddType application/json .php

更改MIME类型后。重新加载Apache以使更改生效。

sudo systemctl reload apache2

收尾

我希望本教程能帮助你在Ubuntu20.04上安装Namingm地理编码服务器。和往常一样,如果你觉得这篇文章很有用,那么订阅我们的免费时事通讯以获得更多提示和窍门。当心?