环境:Ubuntu16.04
安装Nominatim
安装依赖软件
sudo apt-get install -y build-essential cmake g++ libboost-dev libboost-system-dev \ libboost-filesystem-dev libexpat1-dev zlib1g-dev libxml2-dev\ libbz2-dev libpq-dev libproj-dev \ postgresql-server-dev-9.5 postgresql-9.5-postgis-2.2 \ postgresql-contrib-9.5 \ apache2 php php-pgsql libapache2-mod-php php-pear php-db \ php-intl git
如果要运行测试,还需要安装:
sudo apt-get install -y python3-setuptools python3-dev python3-pip \ python3-psycopg2 python3-tidylib phpunit php-cgi pip3 install --user behave nose sudo pear install PHP_CodeSniffer
创建nominatim专用账号
sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim
tip: 这里没有指定密码,可以设置nominatim用户密码方便切换:
sudo passwd nominatim
官方教程用了两个变量来表示nominatim用户名和路径,可以不用切换用户,但经常要用
sudo
(虽然官方教程警告不要用root权限。。。):export USERNAME=nominatim export USERHOME=/srv/nominatim chmod a+x $USERHOME
配置Postgresql
按教程说法,修改配置文件
/etc/postgresql/9.5/main/postgresql.conf
可以获得更好的性能,对32Gb ram的机器建议的配置为:shared_buffers (2GB) maintenance_work_mem (10GB) work_mem (50MB) effective_cache_size (24GB) synchronous_commit = off checkpoint_segments = 100 # only for postgresql <= 9.4 checkpoint_timeout = 10min checkpoint_completion_target = 0.9
我机器是8G内存,不知道合适的配置,没有修改这些。
对于初次导入,需要设置:
fsync = off full_page_writes = off
初次导入后记得重新打开。设置完成后重启postgresql:
sudo systemctl restart postgresql
创建两个postgresql用户(一个导入数据,一个用于webserver的只读用户):
sudo -u postgres createuser -s $USERNAME sudo -u postgres createuser www-data
设置Apache
sudo tee /etc/apache2/conf-available/nominatim.conf << EOFAPACHECONF <Directory "$USERHOME/Nominatim/build/website"> Options FollowSymLinks MultiViews AddType text/html .php DirectoryIndex search.php Require all granted </Directory> Alias /nominatim $USERHOME/Nominatim/build/website EOFAPACHECONF
重启使设置生效:
sudo a2enconf nominatim sudo systemctl restart apache2
安装Nominatim
cd $USERHOME git clone --recursive git://github.com/openstreetmap/Nominatim.git cd Nominatim wget -O data/country_osm_grid.sql.gz https://www.nominatim.org/data/country_grid.sql.gz mkdir build cd build cmake $USERHOME/Nominatim make
配置nominatim,告诉nominatim他在服务器的位置:
tee settings/local.php << EOF <?php @define('CONST_Website_BaseURL', '/nominatim/'); EOF
导入数据
配置文件
Nominatim服务器的配置文件为settings/local.php(应该就是build文件夹下的settings文件夹,即
/srv/nominatim/Nominatim/build/settings
)。可以通过该文件进行很多配置,比如,如果数据库很大,可以添加如下设置:@define('CONST_Osm2pgsql_Flatnode_File', '/your/path/to/flatnode.file');
下载额外数据
官方教程支持wikipdedia rankings和UK postcodes,这个没尝试,可以参见官方教程
导入osm数据
切换到build目录,执行:
./utils/setup.php --osm-file <data file> --all [--osm2pgsql-cache 28000] 2>&1 | tee setup.log
--osm2pgsql-cache
不是必须的,但对于数据库很大的情况,建议加上。我执行的是:nominatim@HP:~/Nominatim/build$ ./utils/setup.php --osm-file ../Beijing.osm.pbf --all 2>&1 | tee setup.log
如果操作错误,一次没有导入成功,再次导入时记得先删除数据库再导入:
nominatim@HP:~/Nominatim/build$ dropdb nominatim
这样数据就成功导入了,接下来还可以进行和nominatim官方数据同步更新等设置,这里没有尝试。
测试
以上设置后,nominatim服务就可以正常使用了,打开浏览器访问
http://localhost/nominatim/
可以进行查询:对于经纬度查询,可以执行以下脚本:
#!/usr/bin/python3 # -*- coding: utf-8 -*- import urllib.request import urllib import re def geocodeByAddr(addr, apiurl): addr=urllib.parse.quote(addr) url=apiurl+'?q='+addr+'&format=json&limit=1' res_data = urllib.request.urlopen(url) res = res_data.read() res=str(res, encoding = "utf-8") p=r'"lat":"\d+.\d+","lon":"\d+.\d+"' div=re.search(p, res).group().split(',') p=r'\d+.\d+' lat=re.search(p,div[0]).group() lon=re.search(p,div[1]).group() return lat,lon lat,lon=geocodeByAddr('中关村','http://localhost/nominatim/') print(lat) print(lon)
结果如下: