本文介绍在Ubuntu 18.04操作系统上安装并设置OpenStreetMap(OSM)服务器,你可以将其视为Google地图的开源和自托管替代方案,这样你就不必使用专有的地图服务了。建议在设置之前执行sudo apt update; sudo apt upgrade命令更新系统,可以通过SSH登录服务器并运行命令。
OpenStreetMap功能和硬件要求 1、OpenStreetMap功能 OpenStreetMap数据覆盖全世界,可以轻松支持任何国家或每个国家/地区的用户。 OpenStreetMap每天每小时更新一次,这些更新可供你实时使用。 OpenStreetMap数据是免费和开放的 - 没有订阅费,也没有页面浏览费。 OpenStreetMap数据丰富而详细,包含大量与实地人员相关的数据。 2、硬件要求 所需的RAM和磁盘空间取决于你要使用的国家/地区的地图,例如: 英国地图至少需要4GRAM和60GB磁盘空间。 整个行星地图至少需要24GRAM和1TB磁盘空间。 如果要预先渲染切片以加快Web浏览器中的地图加载,则需要更多磁盘空间,强烈建议这样做。另外需要注意的是,将整个行星等大型地图数据导入PostgreSQL数据库需要很长时间,考虑添加更多RAM,尤其是使用SSD而不是旋转硬盘来加速导入过程。
一、安装PostgreSQL数据库和PostGIS扩展 我们将使用PostgreSQL来存储地图数据,PostGIS是PostgreSQL的地理空间扩展,运行以下命令进行安装: sudo apt install postgresql postgresql-contrib postgis postgresql-10-postgis-2.4 PostgreSQL数据库将自动启动并侦听127.0.0.1:5432,postgres用户将在安装过程中在操作系统上创建,它是PostgreSQL数据库的超级用户,默认情况下,此用户没有密码,因此无需设置密码,因为你可以使用sudo切换到postgres用户并登录PostgreSQL服务器: sudo -u postgres -i 现在可以创建PostgreSQL数据库用户osm: createuser osm 然后创建一个名为gis的数据库,同时将osm作为数据库的所有者,-E UTF8指定要在数据库中使用的字符编码方案是UTF8: createdb -E UTF8 -O osm gis 接下来,为gis数据库创建postgis和hstore扩展: psql -c "CREATE EXTENSION postgis;" -d gis psql -c "CREATE EXTENSION hstore;" -d gis 将osm设置为表所有者: psql -c "ALTER TABLE spatial_ref_sys OWNER TO osm;" -d gis 退出postgres用户: exit 在你的操作系统上创建osm用户,以便tile服务器可以作为osm用户运行: sudo adduser osm 参考:在Ubuntu 18.04/Ubuntu 16.04上安装PostgreSQL 11的说明。
二、下载地图样式表和地图数据 切换到osm用户: su - osm 将最新的CartoCSS地图样式表下载到osm用户的主目录,地址在这里,你始终可以使用以下链接进行下载,只需替换版本号即可: wget https://github.com/gravitystorm/openstreetmap-carto/archive/v4.20.0.tar.gz 提取它: tar xvf v4.20.0.tar.gz 接下来,运行以下命令以PBF(ProtoBufBinary)格式下载整个行星(44G)的地图数据: wget -c http://planet.openstreetmap.org/pbf/planet-latest.osm.pbf 如果你想要个别国家/州/省/市的地图,请访问http://download.geofabrik.de,此外,BBBike.org以不同的格式提供全球200多个城市和地区的摘录,例如,使用以下命令下载Great Britain(985M)的地图数据: wget -c http://download.geofabrik.de/europe/great-britain-latest.osm.pbf 从osm用户退出: exit 附:导入地图数据之前的建议 导入地图数据需要大量的RAM,如果你的物理内存很小,可以轻松添加交换文件以防止出现内存不足问题,首先,我们使用fallocate命令来创建文件,例如,在根文件系统中创建一个名为swapfile且具有2G容量的文件(如果要导入大型地图,请增加swapfile的大小): sudo fallocate -l 2G /swapfile 然后确保只有root才能读写它: sudo chmod 600 /swapfile 将其格式化为交换: sudo mkswap /swapfile 输出: Setting up swapspace version 1, size = 2097148 KiB no label, UUID=h32b3e10-0779-4865-9ea0-6e2af8f3kea9 启用交换文件: sudo swapon /swapfile 导入过程可能需要一些时间,建议配置SSH keepalive,以免丢失SSH连接,这很容易做到,只需在本地Linux计算机上打开SSH客户端配置文件即可: sudo nano /etc/ssh/ssh_config 并将以下文本粘贴到文件末尾: ServerAliveInterval 60 然后保存文件并连接到你的Ubuntu 18.04服务器,你还可以通过VNC访问远程服务器,以防止断开连接中断导入过程。
三、将地图数据导入PostgreSQL 要导入地图数据,我们需要安装osm2pgsql,它将OpenStreetMap数据转换为支持postGIS的PostgreSQL数据库: sudo apt install osm2pgsql 接下来,转向osm用户: su - osm 运行以下命令以将地图样式表和地图数据加载到gis数据库中,用你自己的地图数据文件替换great-britain-latest.osm.pbf: osm2pgsql --slim -d gis --hstore --multi-geometry --number-processes 8 --tag-transform-script /home/osm/openstreetmap-carto-4.20.0/openstreetmap-carto.lua --style /home/osm/openstreetmap-carto-4.20.0/openstreetmap-carto.style -C 16384 /home/osm/great-britain-latest.osm.pbf 相关说明: --username osm:指定数据库用户。 --slim:以苗条模式而不是普通模式运行,如果要在将来使用OSM更改文件(OSC)更新地图数据,则需要此选项。 -d gis:选择数据库。 --hstore:将不带列的标记添加到PostgreSQL表的其他hstore(键/值)列。 --multi-geometry:在postgresql表中生成多几何特征。 --style:指定样式文件的位置。 --number-processes:服务器上的CPU核心数。 -C选项以兆字节为单位指定缓存大小,较大的缓存大小导致更快的导入速度,但你需要有足够的RAM来使用缓存,例如,我的服务器有16GB的可用RAM,所以我可以指定-C 16384。 最后,需要指定地图数据文件的位置。 如果要导入大型地图数据,请使用--drop选项和--flat-nodes选项来提高导入速度: osm2pgsql --slim -d gis --drop --flat-nodes nodes.cache --hstore --multi-geometry --number-processes 8 --tag-transform-script /home/osm/openstreetmap-carto-4.20.0/openstreetmap-carto.lua --style /home/osm/openstreetmap-carto-4.20.0/openstreetmap-carto.style -C 16384 /home/osm/great-britain-latest.osm.pbf RAM使用率将在导入过程中逐渐增加,完成后,退出osm用户: exit
四、安装mod_tile和Renderd mod_tile是服务切片所需的Apache模块,renderd是渲染OpenStreetMap切片的渲染守护进程,默认的Ubuntu存储库(参考:Ubuntu存储库的定义及启用和禁用Ubuntu存储库的方法)不包含mod_tile和renderd,但我们可以从OSM PPA安装它们: sudo add-apt-repository ppa:osmadmins/ppa sudo apt install libapache2-mod-tile renderd 在安装过程中,它将安装Apache Web服务器并为mod_tile创建一个Apache配置(/etc/apache2/sites-available/tileserver_site.conf),渲染守护程序将自动启动,如下所示: systemctl status renderd
五、生成Mapnik样式表和安装Fonts 1、生成Mapnik样式表 安装所需的包: sudo apt install curl unzip gdal-bin mapnik-utils libmapnik-dev nodejs npm sudo npm install -g carto 切换到osm用户: su - osm cd进入carto样式目录: cd /home/osm/openstreetmap-carto-4.20.0/ 获取shapefile: scripts/get-shapefiles.py 现在使用carto map stylesheet编译器构建Mapnik xml样式表: carto project.mml > style.xml 退出osm用户: exit 2、安装Fonts 需要安装ttf-dejavu软件包: sudo apt install ttf-dejavu 要显示非拉丁字符,请安装以下软件包: sudo apt install fonts-noto-cjk fonts-noto-hinted fonts-noto-unhinted ttf-unifont
六、配置renderd 编辑renderd配置文件: sudo nano /etc/renderd.conf 在[renderd]部分中,根据服务器上的CPU核心数更改为线程数: num_threads=4 在[default]部分中,将XML和HOST的值更改为以下值: XML=/home/osm/openstreetmap-carto-4.20.0/style.xml HOST=map.your-domain.com 在[mapnik]部分中,将plugins_dir的值更改为以下内容: plugins_dir=/usr/lib/mapnik/3.0/input/ 可以使用以下命令打印默认输入插件目录: mapnik-config --input-plugins 如果要显示非拉丁字符,最好将字体设置更改为以下内容: font_dir=/usr/share/fonts/truetype font_dir_recurse=true 保存并关闭文件,然后编辑init脚本文件: sudo nano /etc/init.d/renderd 更改以下变量,这是从PostgreSQL数据库加载地图数据所必需的: RUNASUSER=osm 保存文件,将osm设置为/var/lib/mod_tile/目录的所有者,该目录将保存呈现的切片文件: sudo chown osm:osm /var/lib/mod_tile/ -R 然后重新启动renderd服务: sudo systemctl daemon-reload sudo systemctl restart renderd 需要检查renderd的日志: sudo journalctl -eu renderd 确保renderd不会在日志中产生任何错误,否则将不会显示地图。
七、配置Apache 编辑OSM虚拟主机文件: sudo nano /etc/apache2/sites-available/tileserver_site.conf 将ServerName更改为你自己的域名,例如map.yourdomain.com,你还需要为此子域创建DNS A记录: ServerName map.yourdomain.com 保存并关闭文件,重启Apache: sudo systemctl restart apache2 然后在你的Web浏览器地址栏中输入: map.your-domain.com/osm/0/0/0.png 这个时候可以看到成果了,已成功构建了自己的OSM tile server,如下图:
参考:在Ubuntu 18.04服务器上安装LAMP Stack的方法[Apache、MySQL、PHP]。 显示你的平铺Web地图的说明: 平铺网络地图在OpenStreetMap术语中也称为滑动地图,你可以使用两个免费和开源的JavaScript映射库,用于你的tile server:OpenLayer和Leaflet,Leaflet的优点是它易于使用,你的地图将适合移动设备。 1、OpenLayer 要使用OpenLayer显示你的滑动地图,请从openlayer.org下载JavaScript和CSS并将其解压缩到Web根文件夹: cd /var/www/ sudo wget https://github.com/openlayers/openlayers/releases/download/v5.3.0/v5.3.0.zip sudo unzip v5.3.0.zip 接下来,创建index.html文件: sudo nano /var/www/index.html 将以下HTML代码粘贴到文件中,请根据自己的情况替换map.yourdomain.com及map.yourdomain.com/v5.3.0并根据需要调整经度,纬度和缩放级别: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Accessible Map</title> <link rel="stylesheet" href="http://map.yourdomain.com/v5.3.0/css/ol.css" type="text/css"> <script src="http://map.yourdomain.com/v5.3.0/build/ol.js"></script> <style> a.skiplink { position: absolute; clip: rect(1px, 1px, 1px, 1px); padding: 0; border: 0; height: 1px; width: 1px; overflow: hidden; } a.skiplink:focus { clip: auto; height: auto; width: auto; background-color: #fff; padding: 0.3em; } #map:focus { outline: #4A74A8 solid 0.15em; } </style> </head> <body> <a class="skiplink" href="#map">Go to map</a> <div id="map" class="map" tabindex="0"></div> <button id="zoom-out">Zoom out</button> <button id="zoom-in">Zoom in</button> <script> var map = new ol.Map({ layers: [ new ol.layer.Tile({ source: new ol.source.OSM({ url: 'http://map.yourdomain.com/osm/{z}/{x}/{y}.png' }) }) ], target: 'map', controls: ol.control.defaults({ attributionOptions: /** @type {olx.control.AttributionOptions} */ ({ collapsible: false }) }), view: new ol.View({ center: [244780.24508882355, 7386452.183179816], zoom:5 }) }); document.getElementById('zoom-out').onclick = function() { var view = map.getView(); var zoom = view.getZoom(); view.setZoom(zoom - 1); }; document.getElementById('zoom-in').onclick = function() { var view = map.getView(); var zoom = view.getZoom(); view.setZoom(zoom + 1); }; </script> </body> </html> 保存并关闭文件,现在,可以通过在浏览器地址栏中输入子域来查看你的滑动地图: map.yourdomain.com 或者: map.yourdomain.com/index.html 2、Leaflet 要使用Leftlet显示你的滑动地图,请从leftletjs.com下载JavaScript和CSS并将其解压缩到Web根文件夹: cd /var/www/ sudo wget http://cdn.leafletjs.com/leaflet/v1.4.0/leaflet.zip sudo unzip leaflet.zip 接下来,创建index.html文件: sudo nano /var/www/index.html 将以下HTML代码粘贴到文件中,替换map.yourdomain.com并根据需要调整经度,纬度和缩放级别: <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([53.555,9.899],5); L.tileLayer('http://map.yourdomain.com/osm_tiles/{z}/{x}/{y}.png',{maxZoom:18}).addTo(map); </script> </body> </html> 保存并关闭文件,现在,可以通过在浏览器中输入服务器IP地址来查看你的slippy地图: map.yourdomain.com 或者: map.yourdomain.com/index.html
3、Pre-render Tiles 即时渲染切片会增加Web浏览器中的地图加载时间,要预渲染切片而不是动态渲染,请使用以下render_list命令,使用-z和-Z选项指定缩放级别,并根据服务器上的CPU核心数替换线程数, Render_list通过向渲染守护程序发送请求来呈现地图图块列表,预渲染的切片将缓存在/var/lib/mod_tile目录中: render_list -m default -a -z 0 -Z 12 --num-threads=8 4、启用HTTPS 要加密HTTP流量,我们可以从Let's Encrypt获取并安装免费的TLS证书,首先,在Ubuntu 18.04上安装Let的加密客户端(certbot),参考使用Certbot:在Linux上安装letsencrypt的最简单方法: sudo add-apt-repository ppa:certbot/certbot sudo apt install certbot 由于我们使用的是Apache Web服务器,因此我们还需要安装Apache插件: sudo apt install python3-certbot-apache 然后运行以下命令以获取并安装TLS证书: sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --must-staple --email your-account@example.com -d map.yourdomain.com 安装证书后,刷新网页,你将在地址栏中看到成功,如下图:
如果你在Firefox地址栏中看到黄色三角形,则表示网址仍在使用HTTP,你需要编辑index.html文件并用HTTPS替换所有HTTP协议。 5、启用HTTP2 为了进一步提高地图加载性能,可以启用HTTP2协议,首先需要启用HTTP2模块: sudo a2enmod http2 然后打开SSL主机文件: sudo nano /etc/apache2/sites-enabled/tileserver_site-le-ssl.conf 在打开<VirtualHost *:443>标记后放置以下指令: Protocols h2 http/1.1 保存并关闭文件,然后重新启动Apache以使更改生效: sudo systemctl restart apache2 至此,设置全部完成。
相关主题 |