瓦片服务器

开放街道地图 (OSM) 是一个用户贡献的世界地图。您可以将其视为谷歌地图的开源自托管替代方案。本教程将向您展示如何在 Linux 上构建自己的开放街道地图瓦片服务器,这样您就有原始数据和最终地图产品。安装和流畅运行开放街道地图服务器所需的最低硬件配置:2 个虚拟中央处理器、2 GB 内存和 12 GB 硬盘空间。

z1x0y0 z1x1y0 z1x0y1 z1x1y1

1. 创建管理员账号

首先,创建一个Linux服务器,比如Ubuntu或者Debian。本教程已在 Debian 12 和 11 上测试通过。在其他系统上可能要稍加修改。您的云提供商可能会给你一个root账号。但是,不推荐一直使用root账号;您应该创建一个新的sudo用户。通过下面这些命令创建新用户,您需要把用户名替换为你自己的用户名.

adduser yournewuser
#上面的用户创建后,把他加到sudo组
usermod -aG sudo yournewuser

如果您的root账号已经设置了SSH钥,您可以把SSH钥拷贝给新用户。这样的话,新用户可以用同样的钥登录服务器。 运行以下命令拷贝钥。您需要替换yournewuser为您新用户的名字。

# 拷贝root的SSH钥给这个用户
mkdir -p /home/yournewuser/.ssh
chown yournewuser:yournewuser /home/yournewuser/.ssh
chmod 700 /home/yournewuser/.ssh
cat /root/.ssh/authorized_keys >> /home/yournewuser/.ssh/authorized_keys
chown yournewuser:yournewuser /home/yournewuser/.ssh/authorized_keys
chmod 600 /home/yournewuser/.ssh/authorized_keys

测试你的新管理员用户可以登录到Linux服务器。用您的信息替换相应的内容。

ssh yournewuser@server_ip -i ~/.ssh/path-to-private-key

2. 安装PostgreSQL数据库服务器和PostGIS扩展

我们将使用PostgreSQL来存储地图数据。PostgreSQL团队始终致力于在每个新版本中提升性能。请运行以下5条命令来安装最新版本的PostgreSQL。

echo "deb [signed-by=/etc/apt/keyrings/postgresql.asc] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list

sudo mkdir -p /etc/apt/keyrings/

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo tee /etc/apt/keyrings/postgresql.asc

sudo apt update

sudo apt install -y postgresql-contrib-15 postgresql-15 postgresql-client-15

然后安装PostGIS,它是PostgreSQL的地理空间扩展。

sudo apt install postgis postgresql-15-postgis-3

对于 Debian 11,PostgreSQL 15 可能不存在;您可以将其替换为 13。PostgreSQL数据库服务器将自动启动并监听127.0.0.1和5432端口。Postgres安装过程中,操作系统会自动创建postgres用户。该用户是PostgreSQL数据库服务器的超级用户。默认情况下,该用户没有密码,也无需设置密码,因为您可以使用sudo命令切换到postgres用户并登录PostgreSQL服务器。

sudo -u postgres -i

现在您可以创建PostgreSQL数据库用户osm。

createuser osm

然后创建一个名为gis的数据库,同时将osm设置为该数据库的所有者。请不要更改数据库名称。其他工具(例如renderd和Mapnik)假定存在一个名为gis的数据库。

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用户,以便瓦片服务器可以以osm用户身份运行。以下命令将创建一个没有密码的系统用户。

sudo adduser --system --group --home /home/osm/ osm

3. 下载地图样式表和地图数据

切换到osm的主目录。

cd /home/osm/

用以下命令授予您的默认用户对该文件夹的访问权限。将username替换为您的用户名。

sudo apt install acl
sudo setfacl -R -m u:username:rwx /home/osm/

使用git下载最新的CartoCSS地图样式表到osm用户的主目录。

sudo apt install git

git clone https://github.com/gravitystorm/openstreetmap-carto.git

开放街道地图Carto正在从osm2pgsql换到flex。要获取在osm.org上发布的版本(5.9.0),您需要执行类似以下操作:

cd /home/osm/openstreetmap-carto
git config --global --add safe.directory /home/osm/openstreetmap-carto
git pull --all
git switch --detach v5.9.0

您也可以用git先克隆到本地机器,再上传到服务器。请参考以下命令:

scp -i osrmOpen openstreetmap-carto.zip yourusername@[2a01:4ff:f0:7b77::1]:/home/osm/
sudo apt install unzip
unzip filename.zip

然后运行以下命令之一,以PBF (ProtoBufBinary)格式下载地图数据。

中国安徽省 (38MB)

wget -c https://download.geofabrik.de/asia/china/anhui-latest.osm.pbf

中国江西省 (45MB)

wget -c https://download.geofabrik.de/asia/china/jiangxi-latest.osm.pbf

如果您需要其他国家/州/省/市的地图,请访问http://download.geofabrik.de

4. 优化PostgreSQL服务器性能

默认情况下,PostgreSQL会尝试使用内存中的大页。但是,Linux默认情况下不分配大页。请检查PostgreSQL的进程ID。

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

示例输出:

922

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

grep ^VmPeak /proc/922/status

示例输出:

VmPeak: 1093416 kB

这是PostgreSQL使用的内存峰值。现在检查Linux下大页大小:

cat /proc/meminfo | grep -i huge

示例输出:

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

我们可以算出需要多少个大页。将内存峰值除以大页大小:1093416 kB / 2048 kB = 534。然后我们需要编辑系统控制文件来更改Linux内核参数。我们不直接编辑/etc/sysctl.conf文件,而是创建一个自定义配置文件,这样在升级软件包时,您的自定义配置不会被覆盖。

sudo touch /etc/sysctl.d/60-custom.conf

然后运行以下命令分配 534 个大页。

echo "vm.nr_hugepages = 534" | sudo tee -a /etc/sysctl.d/60-custom.conf

保存并关闭文件,使更改生效。

sudo sysctl -p /etc/sysctl.d/60-custom.conf

如果你再次查看内存信息,

cat /proc/meminfo | grep -i huge

我们可以看到有 534 个大页可供使用。

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

重启PostgreSQL以使用大页。

sudo systemctl restart postgresql

在远程服务器上使用屏幕

由于导入过程可能需要很长时间,您的电脑可能会断开网络连接,我们建议使用屏幕工具来保持会话连接。在Debian 12上安装屏幕:

sudo apt install screen

然后启动屏幕:

screen

首次启动时,您会看到一段介绍文字,按任意键Enter即可结束。之后,您就可以像往常一样运行命令了。

5. 将地图数据导入PostgreSQL

要导入地图数据,我们需要安装osm2pgsql,一个可以将开放地图数据转换为PostGIS数据库的工具。

sudo apt install osm2pgsql

授予postgres用户权限:

sudo setfacl -R -m u:postgres:rwx /home/osm/

切换到postgres用户。

sudo -u postgres -i

运行以下命令将地图样式表和地图数据加载到gis数据库中。请将anhui-latest.osm.pbf替换为您自己的地图数据文件。

osm2pgsql --slim -d gis --hstore --multi-geometry --number-processes 2 --tag-transform-script /home/osm/openstreetmap-carto/openstreetmap-carto.lua --style /home/osm/openstreetmap-carto/openstreetmap-carto.style -C 1790 /home/osm/anhui-latest.osm.pbf

其中

命令输出:

        2025-11-07 03:11:31  osm2pgsql 版本 1.8.0
        2025-11-07 03:11:31  数据库版本: 15.14 (Debian 15.14-1.pgdg12+1)
        2025-11-07 03:11:31  PostGIS 版本: 3.6
        2025-11-07 03:11:31  正在设置表 planet_osm_point
        2025-11-07 03:11:31  正在设置表 planet_osm_line
        2025-11-07 03:11:31  正在设置表 planet_osm_polygon
        2025-11-07 03:11:32  正在设置表 planet_osm_roads
        处理:节点(9710k 1213.8k/s) 路径(0k 0.00k/s) 关系(0 0.0/s)
        ……

导入过程中,内存使用量将逐渐增加。

现在您可能不需要在服务器上执行其他操作了。由于您正在使用屏幕,您可以按Ctrl+A,松开这两个键,然后按D键即可脱离当前的屏幕会话。您将看到类似如下的消息:

[已从 155499.pts-0.tile 分离]

这告诉我们之前的会话ID是155499。您可以退出SSH会话,甚至关闭计算机。不要担心,开放街道地图导入过程仍在运行。当您需要返回查看导入进度时,通过SSH连接到您的服务器,运行以下命令来获取之前的屏幕会话ID。

screen -ls

示例输出:

        screen 工具运行于:
            155499.pts-0.tile       (2025年11月7日 上午3:08:27)(已分离)
        1 Socket 在 /run/screen/S-xtao.

您可以重新连接到之前的屏幕会话。

screen -r 155499

这样您就可以继续工作了。导入完成后,请授予osm用户对gis数据库的所有权限。

psql -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO osm;" -d gis

退出postgres用户。

exit

6. 安装renderd和mod_tile

renderd是一个从PostgreSQL数据库渲染开放街道地图瓦片的守护进程。mod_tile是一个Apache模块,用于向客户网页浏览器提供地图瓦片。我们可以从默认的Debian 12软件仓库安装它们。

sudo apt install apache2 libapache2-mod-tile renderd

删除 /etc/apache2/sites-enabled/* 中的默认符号链接。接下来,为瓦片服务器创建一个虚拟主机。

sudo vi /etc/apache2/sites-available/tileserver_site.conf

请将以下几行添加到些文件中。请将tile.your-domain.com替换为您的实际域名。别忘了添加DNS A记录或者AAAA记录。

        <VirtualHost *:80>
            ServerName tile.your-domain.com   
            DocumentRoot /var/www/html/
            LogLevel info
         
            <Directory /var/cache/renderd/tiles>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Require all granted

                ModTileTileDir /var/cache/renderd/tiles
                LoadTileConfigFile /etc/renderd.conf
                ModTileEnableStats On
                ModTileBulkMode Off
                ModTileRequestTimeout 99
                ModTileMissingRequestTimeout 99
                ModTileMaxLoadOld 2
                ModTileMaxLoadMissing 5
                ModTileRenderdSocketName /run/renderd/renderd.sock
                ModTileCacheDurationMax 6048000
                ModTileCacheDurationDirty 9000
                ModTileCacheDurationMinimum 108000
                ModTileCacheDurationMediumZoom 13 864000
                ModTileCacheDurationLowZoom 9 5184000
                ModTileCacheLastModifiedFactor 0.80
                ModTileEnableTileThrottling Off
                ModTileEnableTileThrottlingXForward 0
                ModTileThrottlingTiles 10000 1
                ModTileThrottlingRenders 128 0.2
            </Directory>
        </VirtualHost>
        

保存并关闭文件。启用此虚拟主机。

sudo a2ensite tileserver_site.conf

重新载入Apache以使更改生效。

sudo systemctl reload apache2

渲染守护进程将自动启动,如下所示:

systemctl status renderd

7. 生成Mapnik样式表

安装所需软件包:

sudo apt install curl unzip gdal-bin mapnik-utils libmapnik-dev python3-pip nodejs npm

然后使用npm安装carto包:

sudo npm install -g carto

安装yaml和psycopg2 Python 模块。

sudo apt install python3-pretty-yaml python3-yaml python3-psycopg2

根据需要分配虚拟内存:

        sudo fallocate  -l  4G /debianswapfile ; sudo chmod 600 /debianswapfile ; 
        sudo mkswap /debianswapfile && sudo swapon /debianswapfile ; 
        sudo sed -i '$a\/debianswapfile  swap  swap  defaults 0 0' /etc/fstab
        

切换到postgres用户:

sudo -u postgres -i

进入carto样式目录:

cd /home/osm/openstreetmap-carto/

获取形状文件:

scripts/get-external-data.py

示例输出:

        信息:root:开始将外部数据加载到数据库
        信息:root:正在检查表 simplified_water_polygons
        信息:root:下载完成(24027516 字节)
        信息:root:正在解压缩文件
        信息:root:正在导入数据库
        信息:root:导入完成
        信息:root:正在检查表 water_polygons
        信息:root:下载完成(904406003 字节)
        信息:root:正在解压缩文件
        ......
        

如果您的服务器只有 IPv6,默认的下载链接可能不工作。您可以更改external-data.yml文件中的链接,并在支持 IPv6 的服务器上准备数据。

现在使用carto地图样式表编译器生成Mapnik XML样式表。

carto project.mml > style.xml

授予osm用户对gis数据库的所有权限。

psql -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO osm;" -d gis

退出postgres用户。

exit

在5.9.0版“开放街道地图 Carto”(2024年10月),一些函数必须手动导入到数据库。如下所示:

cd /home/osm/openstreetmap-carto/
sudo -u osm psql -d gis -f functions.sql

从5.3.0版开始,需要手动添加一些额外的索引来加快地图渲染过程:

sudo -u postgres psql -d gis -f indexes.sql

它会生成16条索引。

8. 安装字体

您需要安装字体dejavu包。

sudo apt install fonts-dejavu fonts-dejavu-web

Debian 11 系统中没有 fonts-dejavu-web 字体包。您可以用 ttf-unifont 代替。要显示统一码字符,包含中文和日文字符,请安装以下软件包。

sudo apt install fonts-noto-cjk fonts-noto-cjk-extra fonts-noto-hinted fonts-noto-unhinted fonts-unifont fonts-hanazono

9. 配置renderd

编辑renderd配置文件。

sudo vi /etc/renderd.conf

在[renderd]部分,根据服务器上的处理器核心数更改线程数。

num_threads=2

添加默认图层。以分号开头的行(;)是注释。

; 添加图层:
[default]
URI=/osm/
XML=/home/osm/openstreetmap-carto/style.xml
HOST=tile.your-domain.com

默认情况下,renderd 允许的最大缩放级别为 18。如果您需要缩放级别 19,请在 [default] 部分添加以下行。

MAXZOOM=19

保存并关闭文件。然后为renderd服务创建一个新目录。

sudo mkdir /etc/systemd/system/renderd.service.d/

在此目录下创建自定义配置文件。

sudo vi /etc/systemd/system/renderd.service.d/custom.conf

在此文件中添加以下几行。

[Service]
User=osm

保存并关闭文件。更改/run/renderd/和/var/cache/renderd/tiles/目录的所有权。

sudo chown osm /var/cache/renderd/tiles/ -R

sudo chown osm /run/renderd/ -R

然后重启renderd服务。

sudo systemctl daemon-reload
sudo systemctl restart renderd

你需要查看renderd的日志。

sudo journalctl -eu renderd

重启后,请确保renderd没在日志中产生错误,否则地图将不会显示。

在浏览器地址栏输入

tile.your-domain.com/osm/0/0/0.png

你应该能看到世界地图。恭喜!你已成功搭建了自己的开放街道地图瓦片服务器。

world map

10. 显示您的瓦片式网络地图

在开放街道地图术语中,瓦片式网络地图也称为滑动地图。您可以使用两个免费开源的JavaScript地图库来搭建瓦片服务器:OpenLayerLeaflet. Leaflet在优势在于它易于使用,并且能让您的地图在移动设备上完美呈现。

OpenLayer

首先,进入到网络根目录。

cd /var/www/html

接下来,编辑index.html文件。如果您还在使用屏幕工具,请先退出来。

sudo vi /var/www/html/index.html

将以下代码粘贴到文件中。替换红色文件,并根据需要调整经纬度和缩放级别。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>无障碍地图</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v5.3.0/css/ol.css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/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">前往地图</a>
  <div id="map" class="map" tabindex="0"></div>
  <button id="zoom-out">缩小</button>
  <button id="zoom-in">放大</button>
  <script>
    var map = new ol.Map({
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM({
             url: 'http://tile.your-domain.com/osm/{z}/{x}/{y}.png'
          })
       })
     ],
     target: 'map',
     controls: ol.control.defaults({
        attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
          collapsible: false
        })
     }),
    view: new ol.View({
       center: [13024380, 3763310],
       zoom: 10
    })
 });

  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>
        

保存并关闭文件。现在,您可以在浏览器地址栏输入您的子域名来查看您的滑动地图。

tile.your-domain.com

Leaflet

首先, 去网络根目录。

cd /var/www/html/

下载leaflet.css 和 leaflet.js:

sudo wget https://unpkg.com/leaflet@1.7.1/dist/leaflet.css
sudo wget https://unpkg.com/leaflet@1.7.1/dist/leaflet.js

下载一些图片到images文件夹:

sudo mkdir images
cd images
sudo wget https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png
sudo wget https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon-2x.png
sudo wget https://unpkg.com/leaflet@1.7.1/dist/images/marker-shadow.png

接下来,编辑index.html文件。

sudo vi /var/www/index.html

将以下HTML代码粘贴到文件中。替换红色文本,并根据需要调整经纬度和缩放级别。
    <html>
    <head>
    <meta charset="UTF-8">
    <title>我的开放街道图</title>
    <link rel="stylesheet" type="text/css" href="leaflet.css"/>
    <script src="leaflet.js"></script>
    <style>
       html{height:100%;}
       body{height:100%;}
       #map{height:100%;}
    </style>
    </head>

    <body>
      <div id="map"></div>
      <script>
        var map = L.map('map').setView([32,117],7);
        L.tileLayer('http://tile.your-domain.org/osm/{z}/{x}/{y}.png',{maxZoom:18}).addTo(map);
    </script>
    </body>
    </html>
        

11. 启用HTTPS

要加密HTTP流量,我们可以从Let’s Encrypt获取并安装免费的TLS证书。首先在Debian 12上安装Let’s Encrypt客户端(certbot)。

sudo apt install certbot

由于我们使用的是Apache网络服务器,因此我们也需要安装Apache插件。

sudo apt install python3-certbot-apache

然后运行以下命令来获取并安装TLS证书。

sudo certbot --apache --agree-tos --email your-account@example.com -d tile.your-domain.com

证书安装完成后,刷新网页,您将在地址栏看到一个锁形图标。

默认情况下,Let's Encrypt 会将 HTTP 请求重定向到 HTTPS。如果您想保留 HTTP,可以删除 tileserver_site.conf 文件中自动生成的重写规则。

12. 启用 HTTP2

为了进一步提升地图加载性能,您可以启用HTTP2协议。首先,您需要启用HTTP2模块。

sudo a2enmod http2

然后打开SSL虚拟主机文件。

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

将以下指令放在开始 <VirtualHost *:443> 标签之后。

Protocols h2 http/1.1

保存并关闭文件。然后重启Apache以使更改生效。

sudo systemctl restart apache2

为了让mod_tile生成的瓦片永不过期,您可以在相应的缓存目录中创建一个名为planet-import-complete的文件,并为其设置一个非常旧的时间戳。这样可以欺骗mod_tile,使它误以为上次数据导入是在很久以前,因此所有缓存的瓦片都被视为最新版本,不会被自动重新渲染。

使用带有-t标志的touch命令创建文件,并为其设置一个非常旧的时间戳。时间格式为YYYYMMDDhhmm.SS。

sudo touch -t 198001010000.00 /var/cache/renderd/tiles/planet-import-complete

此命令将在mod_tile缓存目录中创建一个具有指定时间戳的空文件。

如何更新GIS数据库

停止渲染:

sudo systemctl stop renderd

您可以开始使用屏幕工具。

切换到postgres用户。

sudo -u postgres -i

删除gis数据库。

dropdb gis;

创建一个新数据库。

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

下载地图。

wget http://download.geofabrik.de/asia/china/jiangxi-latest.osm.pbf

导入地图数据。

osm2pgsql --slim -d gis --hstore --multi-geometry --number-processes 2 --tag-transform-script /home/osm/openstreetmap-carto/openstreetmap-carto.lua --style /home/osm/openstreetmap-carto/openstreetmap-carto.style -C 790 /var/lib/postgresql/jiangxi-latest.osm.pbf

导入完成后,请授予osm用户对gis数据库的所有权限。

psql -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO osm;" -d gis

进入carto样式目录:

cd /home/osm/openstreetmap-carto/

获取形状文件:

scripts/get-external-data.py

请授予osm用户对gis数据库的所有权限。

psql -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO osm;" -d gis

退出postgres用户。

exit

加载一些函数和索引:

cd /home/osm/openstreetmap-carto/
sudo -u osm psql -d gis -f functions.sql
sudo -u postgres psql -d gis -f indexes.sql

重启renderd进程。

sudo systemctl restart renderd

PostgreSQL和网络服务器在不同的主机上

如果您使用蔚蓝PostgreSQL数据库,您需要在蔚蓝PostgreSQL数据库设置中启用postgis 和 hstore扩展,并添加一个防火墙规则允许您网络服务器的IP地址。

创建数据库用户osm:

CREATE USER osm;

在PostgreSQL上创建gis数据库:

CREATE DATABASE gis WITH OWNER "osm" ENCODING 'UTF8';

连接到gis数据库,并创建postgis 和 hstore 扩展:

CREATE EXTENSION postgis;
CREATE EXTENSION hstore;

是时候使用屏幕工具了。导入地图数据:

cd /home/osm/openstreetmap-carto
HOSTNAME=umd.postgres.database.azure.com # 将其设置为实际的 IP 地址或主机名
osm2pgsql --slim -C 790 --numer-processes 2 --multi-geometry --hstore --style openstreetmap-carto.style --tag-transform-script openstreetmap-carto.lua -d gis -H $HOSTNAME -U postgres [.osm 或 .pbf file]

示例:

PGPASSWORD=pass1234 osm2pgsql --slim -C 790 --number-processes 2 --multi-geometry --hstore --style openstreetmap-carto.style --tag-transform-script openstreetmap-carto.lua -d gis -H $HOSTNAME -U xtao /home/osm/anhui-latest.osm.pbf

切换到postgres用户。

sudo -u postgres -i

进入到carto样式目录:

cd /home/osm/openstreetmap-carto/

获取形状文件:

PGPASSWORD=pass1234 scripts/get-external-data.py -H $HOSTNAME -U xtao

如果您PostgreSQL 和 Apache 网络服务器位于不同的主机上,则需要编辑 project.mml 文件:

vi /home/osm/openstreetmap-carto/project.mml

找出以下几行:
        osm2pgsql: &osm2pgsql
          type: "postgis"
          dbname: "gis"
          key_field: ""
          geometry_field: "way"
          srid: *srid
          extent: "-20037508,-20037508,20037508,20037508"       
        

指定PostgreSQL 数据库服务器的主机名、用户名和密码:

        osm2pgsql: &osm2pgsql
          type: "postgis"
          host: "10.0.0.2"
          user: "yourusername"
          password: "yourpassword"
          dbname: "gis"
          key_field: ""
          geometry_field: "way"
          srid: *srid
          extent: "-20037508,-20037508,20037508,20037508"
        

保存并关闭文件。然后使用carto地图样式表编译器构建 Mapnik XML样式表。

carto project.mml > style.xml

添加函数和索引来处理和加快 project.mml 中的查询。

HOSTNAME=localhost # 将其设置为实际的 IP 地址或主机名
cd /home/osm/openstreetmap-carto
psql -U postgres -h $HOSTNAME -d gis -f functions.sql
psql -U postgres -h $HOSTNAME -d gis -f indexes.sql

示例:

PGPASSWORD=pass1234 psql -U xtao -h $HOSTNAME -d gis -f functions.sql
PGPASSWORD=pass1234 psql -U xtao -h $HOSTNAME -d gis -f indexes.sql

退出postgres用户。

exit

重启 Apache 主机上的渲染守护进程。

sudo systemctl restart renderd

你需要检查 renderd 的日志。确保 renderd 在日志中没有产生任何错误,否则地图将无法显示。

sudo journalctl -eu renderd

如何创建 PostgreSQL 数据库并允许连接

切换到 postgres 用户,然后连接到 PostgreSQL:

sudo -u postgres -i
psql

创建一个新的用户角色(例如 app_user)和一个数据库(例如 app_db),并分配一个密码:

CREATE USER app_user WITH ENCRYPTED PASSWORD 'your_password';
CREATE DATABASE app_db;
ALTER DATABASE app_db OWNERTO app_user;

在 PostgreSQL 数据库服务器上,编辑主配置文件。

vi /etc/postgresql/13/main/postgresql.conf

添加以下行以设置 PostgreSQL 监听所有接口。

listen_addresses = '*'

保存并关闭文件。然后编辑PostgreSQL客户端身份验证配置文件。

vi /etc/postgresql/13/main/pg_hba.conf

在文件末尾添加以下行,允许 app_user 用户从本地计算机登录。将 10.0.0.1 替换为本地计算机的 IP 地址。
        host   app_db   app_user   10.0.0.1/32   md5
保存并关闭文件。然后重启PostgreSQL。

sudo systemctl restart postgresql

故障排除

重启机器后,渲染守护进程可能无法工作,您需要重置文件夹/run/renderd/的权限并重启renderd服务。原因是 /run/renderd/ 文件夹权限在以下文件中设置:

/usr/lib/tmpfiles.d/renderd.conf

将此文件中的用户更改为 osm 而非 _renderd,这样renderd服务就能正确绑定 .sock 文件,并且您重启系统后也不用手动更改/run/renderd/的所有权。

把:

        d   /run/renderd    0755    _renderd    _renderd    -   -
        
更改为:
        d   /run/renderd    0755    osm    osm    -   -
        

下一步

希望这篇教程能帮助你在 Linux 上搭建开放街道地图瓦片服务器。你可能还需要设置开源路径规划引擎来提供导航功能,或者搭建 Nominatim 地理编码服务器来提供搜索功能。。