1.數據準備
1.1.全球數據
下載地址:https://planet.openstreetmap.org/
1.2.特定區域的數據
下載地址:Geofabrik Download Server
2.安裝必要的軟件包
2.1.更新系統軟件包
sudo apt updatesudo apt upgrade
2.2.安裝所需要的軟件包
執行下面的命令,一步安裝所需要的配套軟件。
sudo apt install -y build-essential cmake g++ libboost-dev libboost-system-dev \libboost-filesystem-dev libexpat1-dev zlib1g-dev \libbz2-dev libpq-dev liblua5.3-dev lua5.3 lua-dkjson \nlohmann-json3-dev postgresql-14-postgis-3 \postgresql-contrib-14 postgresql-14-postgis-3-scripts \php-cli php-pgsql php-intl libicu-dev python3-dotenv \python3-psycopg2 python3-psutil python3-jinja2 \python3-icu python3-datrie python3-sqlalchemy \python3-asyncpg python3-yaml git
3.配置postgresql
3.1. 切換到 postgres 用戶
在 Linux 系統中,默認安裝 PostgreSQL 后會創建一個名為?postgres
?的系統用戶,你可以使用以下命令切換到該用戶:
sudo su - postgres
執行此命令后,你將進入?postgres
?用戶的環境,命令行提示符通常會改變以表明當前用戶身份。
3.2. 進入 PostgreSQL 交互環境
在?postgres
?用戶環境下,使用以下命令進入 PostgreSQL 的交互式 shell(psql
):
psql
此時,你會看到類似?postgres=#
?的提示符,表明已成功進入 PostgreSQL 數據庫管理系統。
3.3. 修改密碼
在?psql
?環境中,使用?ALTER USER
?命令來修改?postgres
?用戶的密碼。例如,要將密碼設置為?newpassword
(請將?newpassword
?替換為你實際想要設置的強密碼),執行以下命令:
ALTER USER postgres WITH PASSWORD 'newpassword';
執行完上述 SQL 語句后,如果沒有報錯,說明密碼修改成功。
3.4. 退出 PostgreSQL 交互環境和 postgres 用戶
修改完密碼后,輸入以下命令退出?psql
?交互環境:
\q
然后輸入以下命令退出?postgres
?用戶,返回到原來的用戶環境:
exit
3.5.增加www-data賬戶
sudo -u postgres createuser www-data?
如果這步不執行,后面導入數據的時候會提示www-data賬戶不存在,詳情參考5.2.2
3.6.修改postgresql.conf配置文件
默認是在:/etc/postgresql/14/main目錄下:
sudo vim /etc/postgresql/14/main/postgresql.conf
按下面修改這些配置項即可。?
shared_buffers = 2GB
work_mem = 50MB
maintenance_work_mem = 10GB
fsync = off
synchronous_commit= off
full_page_writes = off
checkpoint_timeout = 10min
checkpoint_completion_target = 0.9
effective_cache_size = 24GB
4.下載并編譯Nominatim
4.1.下載Nominatim
下載地址:https://github.com/osm-search/Nominatim
找一個自己喜歡的版本下載
下載后拷貝到服務器,解壓即可:例如我放在/opt目錄下
#進入/opt目錄
cd /opt
#我選擇的是4.5.0版本,解壓命令如下
unzip Nominatim-4.5.0.zip
進入解壓后的目錄:
cd Nominatim-4.5.0
4.2.編譯Nominatim?
在Nominatim-4.5.0目錄下創建編譯目錄/build
mkdir /opt/Nominatim-4.5.0/build
cd /opt/Nominatim-4.5.0/build
?然后執行命令:
cmake ..
這時候會提示?osm2pgsql是空的,需要下載osm2pgsql
點擊這里可以跳轉到下載地址
然后執行下載命令:
# 返回到Nominatim-4.5.0目錄下
cd /opt/Nominatim-4.5.0
#下載
git clone --recursive https://github.com/osm2pgsql-dev/osm2pgsql.git
?我們刪除/build目錄下之前編譯生成的文件,再進行編譯命令:
cd /build
cmake ..
缺少country_osm_grid.sql文件
?按照提示執行下面的命令即可:
wget -O /opt/Nominatim-4.5.0/data/country_osm_grid.sql.gz https://www.nominatim.org/data/country_grid.sql.gz
?再次清理之前的編譯文件,重新編譯:
cd /build
cmake ..
編譯完畢,執行:make
make
?最后執行下面命令完成Nominatim的編譯
sudo make install
4.3.安裝psycopg
?Nominatim 通常使用?psycopg2
,可以按照以下命令進行安裝:
pip install psycopg2-binary
?但是我的環境使用的是psycopg3,可以使用命令:
pip install psycopg[binary]
如果這步不執行會出現5.2.1問題。
5.數據導入?
5.1.執行導入
數據下載方式有兩種,一種是在/opt/Nominatim-4.5.0/data目錄下執行下載命令:
cd /opt/Nominatim-4.5.0/datawget https://planet.openstreetmap.org/pbf/planet-latest.osm.pbf
一種是下載后將文件拷貝到服務器中,建議這種,下載方式在1中已經說明。
在?/opt/Nominatim-4.5.0/data目錄下執行命令
nominatim import --osm-file planet-latest.osm.pbf
如果我們導入的數據量非常龐大,而且控制臺不希望一直開著查看輸出的進度,那么我們可以將進度打印到日志文件,導入命令如下:
nominatim import --osm-file planet-latest.osm.pbf > nominatim_import.log 2>&1
正常情況下會開始導入數據導入?
經歷很長的一段時間后,可以看到數據導入成功的提示
這時候還沒結束,還需要繼續等待,過了幾個小時后,會繼續打印日志
5.2.異常
5.2.1.No module named 'psycopg'
給出的錯誤信息?ModuleNotFoundError: No module named 'psycopg'
?可知,Python 解釋器在運行時未能找到?psycopg
?模塊,而?psycopg
?是用于與 PostgreSQL 數據庫進行交互的庫,可以使用?pip
?來安裝?psycopg
?模塊。psycopg
?有兩個主要版本,psycopg2
?是傳統版本,psycopg3
?是新版本。
Nominatim 通常使用?psycopg2
,可以按照以下命令進行安裝:
pip install psycopg2-binary
?但是我的環境使用的是psycopg3,可以使用命令:
pip install psycopg[binary]
然后再執行導入命令:
?nominatim import --osm-file planet-latest.osm.pbf
這里時候如果我們沒有清理數據庫會提示數據庫已經存在
執行清理數據庫的命令:
如果過程中執行失敗,需要重新導入都需要先執行清理數據庫的命令。
dropdb nominatim
5.2.2.www-data賬戶不存在
然后再執行一次導入命令:
?nominatim import --osm-file planet-latest.osm.pbf
發現提示www-data賬戶不存在,需要創建。執行創建用戶的命令:
sudo -u postgres createuser www-data
?創建后再次清理數據庫,執行導入操作,看到下面的進度說明我們導入開始,等待導入結束。這個是非常耗時的,確保服務器的穩定性。否則要重頭再來。
5.2.3.內存不足,導致osm2pgsql意外中斷
如果在導入過程中出現內存不足,導致osm2pgsql意外中斷,則可以采用增加虛擬內存的方式進行臨時解決,有條件的可以增加物理內存條。
Processing: Node(1004520k 357.2k/s) Way(0k 0.00k/s) Relation(0 0.0/s)Traceback (most recent call last):File "/usr/local/bin/nominatim", line 12, in <module>exit(cli.nominatim(module_dir='/usr/local/lib/nominatim/module',File "/usr/local/lib/nominatim/lib-python/nominatim_db/cli.py", line 260, in nominatimreturn get_set_parser().run(**kwargs)File "/usr/local/lib/nominatim/lib-python/nominatim_db/cli.py", line 122, in runret = args.command.run(args)File "/usr/local/lib/nominatim/lib-python/nominatim_db/clicmd/setup.py", line 86, in runreturn asyncio.run(self.async_run(args))File "/usr/lib/python3.10/asyncio/runners.py", line 44, in runreturn loop.run_until_complete(main)File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_completereturn future.result()File "/usr/local/lib/nominatim/lib-python/nominatim_db/clicmd/setup.py", line 105, in async_runself._base_import(args)File "/usr/local/lib/nominatim/lib-python/nominatim_db/clicmd/setup.py", line 171, in _base_importdatabase_import.import_osm_data(files,File "/usr/local/lib/nominatim/lib-python/nominatim_db/tools/database_import.py", line 135, in import_osm_datarun_osm2pgsql(options)File "/usr/local/lib/nominatim/lib-python/nominatim_db/tools/exec_utils.py", line 77, in run_osm2pgsqlsubprocess.run(cmd, cwd=options.get('cwd', '.'),File "/usr/lib/python3.10/subprocess.py", line 526, in runraise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '[PosixPath('/usr/local/lib/nominatim/osm2pgsql'), '--create', '--slim', '--log-progress', 'true', '--number-processes', '1', '--cache', '10210', '--style', '/usr/local/etc/nominatim/import-extratags.lua', '--output', 'flex', 'planet-latest.osm.pbf']' died with <Signals.SIGKILL: 9>.
我采用的方法是增加虛擬內存:
(1)查看當前虛擬內存使用情況
使用命令free -h
?可以查看當前系統的虛擬內存使用情況。
(2)創建新的交換文件
確定交換文件的大小和位置,例如創建一個 32GB 的交換文件在/swapfile
路徑下,使用命令:
sudo fallocate -l 32G /swapfile
你可以根據實際需求調整大小
設置文件權限,確保只有 root 用戶可以讀寫這個文件:
sudo chmod 600 /swapfile
?將新文件設為交換文件:
sudo mkswap /swapfile
?啟用交換文件:
sudo swapon /swapfile
?為了確保系統重啟后虛擬內存仍然可用,需要將交換文件添加到/etc/fstab
文件中。打開該文件:
sudo vim /etc/fstab
在文件末尾添加以下行:
/swapfile none swap sw 0 0
(3)驗證虛擬內存修改是否生效
使用命令:
free -h
查看虛擬內存是否已經成功修改并顯示在Swap
列中。
一般來說,交換文件的大小可以根據物理內存的大小來確定。在過去,通常建議交換文件大小為物理內存的 1.5 到 2 倍。例如,如果系統有 4GB 的物理內存,那么交換文件可以設置為 6GB 到 8GB。然而,隨著物理內存容量的不斷增加,這個比例可以適當降低。對于現代系統,尤其是那些擁有 8GB 或更多物理內存的系統,交換文件大小可以設置為物理內存的 0.5 到 1 倍。
因為我的物理內存是32GB,所以我這里將交換文件也設置為32GB。
5.2.4."/var/run/postgresql/.s.PGSQL.5432" failed: 權限不夠
connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: 權限不夠
(1)編輯?postgresql.conf
?文件
sudo vim /etc/postgresql/<版本號>/main/postgresql.conf
檢查?listen_addresses
?和?port
?設置
listen_addresses = 'localhost' # 或者 listen_addresses = '*'
port = 5432
保存并退出文件。
(2)編輯?pg_hba.conf
?文件
sudo vim /etc/postgresql/<版本號>/main/pg_hba.conf
確保有允許本地連接的配置項,例如:
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
這里的?trust
?表示允許無密碼連接,在生產環境中建議使用更安全的認證方式,如?md5
。
(3)重啟 PostgreSQL 服務
sudo systemctl restart postgresql
5.3.導入完畢
經歷長時間的等待(5天時間),終于將全球數據導入到了數據庫,算上下載數據,整個過程需要10來天左右,真不易。
6.部署應用服務
6.1.安裝apache2
sudo apt install -y apache2 libapache2-mod-php
6.2.創建一個web目錄
mkdir /opt/nominatim-web
數據庫導入完畢后會在data目錄下自動生成一個website的目錄,將website所有文件復制到/opt/nominatim-web
sudo cp -r /opt/Nominatim-4.5.0/data/website/ /opt/nominatim-web/
?
?6.3.配置并啟動nominatim web
在apache配置中為nominatim添加一個配置。
sudo tee /etc/apache2/conf-available/nominatim.conf << EOFAPACHECONF
<Directory "/opt/nominatim-web/website">Options FollowSymLinks MultiViewsAddType text/html .phpDirectoryIndex search.phpRequire all granted
</Directory>Alias /nominatim /opt/nominatim-web/website
EOFAPACHECONF
然后啟用配置并重啟 apache
sudo a2enconf nominatimsudo systemctl restart apache2
正常情況下,我們在瀏覽器輸入:
http://你的IP地址/nominatim//reverse?format=jsonv2&accept-language=en&lat=22.56955&lon=120.651554
?就可以返回下面的字符串:
{"place_id":193008953,"licence":"Data ? OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"way","osm_id":265424501,"lat":"22.56946435874501","lon":"120.65190743779885","place_rank":26,"category":"highway","type":"tertiary","importance":0.0533433333333333,"addresstype":"road","name":"佳興道路","display_name":"佳興道路, Taiwu Village, Taiwu, Pingtung County, 921, Taiwan","address":{"road":"佳興道路","city_district":"Taiwu Village","town":"Taiwu","county":"Pingtung County","ISO3166-2-lvl4":"TW-PIF","postcode":"921","country":"Taiwan","country_code":"tw"},"boundingbox":["22.566305","22.5732423","120.6493797","120.660727"]}
如圖:
6.4.應用程序無法通過 Unix 域套接字連接到 PostgreSQL 服務器問題排查
?瀏覽器訪問解析地址時候,如果出現下面的問題,說明應用程序無法通過 Unix 域套接字連接到 PostgreSQL 服務器,通常是由于權限問題或服務未運行導致的。
確認 PostgreSQL 服務狀態
sudo systemctl status postgresql
如果服務未運行:
sudo systemctl start postgresql
sudo systemctl enable postgresql # 開機自啟
檢查 Unix 域套接字文件權限
ls -la /var/run/postgresql/
正常輸出示例
drwxrwxr-x 2 postgres postgres 80 May 13 15:30 .
drwxr-xr-x 13 root root 420 May 13 15:30 ..
srwxrwxrwx 1 postgres postgres 0 May 13 15:30 .s.PGSQL.5432
問題排查
- 如果目錄或套接字文件不存在,可能是 PostgreSQL 未正確啟動。
- 如果權限不是?
srwxrwxrwx
,嘗試:sudo chmod 777 /var/run/postgresql/
驗證 PostgreSQL 配置
編輯?/etc/postgresql/14/main/postgresql.conf
:
sudo vim /etc/postgresql/14/main/postgresql.conf
確保以下配置正確:
unix_socket_directories = '/var/run/postgresql'
port = 5432
listen_addresses = 'localhost' # 或 '*' 允許遠程訪問
重啟服務使配置生效:
sudo systemctl restart postgresql
添加用戶到 postgres 組:
將當前用戶(如?www-data
)添加到?postgres
?組:
sudo usermod -aG postgres www-data
重新登錄會話(或重啟系統)使組變更生效。