搭建本地OSM地图服务器

测试环境

  • 2024.12.22 Ubuntu 24.04.1 LTS + Apache2 2.4.58
  • 2024.01.04 Ubuntu 22.04.3 LTS + Apache2 2.4.52

依赖

2204

1
2
3
4
5
6
sudo apt install screen locate libapache2-mod-tile renderd git tar \
unzip wget bzip2 apache2 lua5.1 mapnik-utils python3-mapnik \
python3-psycopg2 python3-yaml gdal-bin npm fonts-noto-cjk \
fonts-noto-hinted fonts-noto-unhinted fonts-unifont fonts-hanazono \
postgresql postgresql-contrib postgis postgresql-14-postgis-3 \
postgresql-14-postgis-3-scripts osm2pgsql net-tools curl

2404

1
2
3
4
5
6
sudo apt install screen locate libapache2-mod-tile renderd git tar \
unzip wget bzip2 apache2 lua5.1 mapnik-utils python3-mapnik \
python3-psycopg2 python3-yaml gdal-bin npm fonts-noto-cjk \
fonts-noto-hinted fonts-noto-unhinted fonts-unifont fonts-hanazono \
postgresql postgresql-contrib postgis postgresql-16-postgis-3 \
postgresql-16-postgis-3-scripts osm2pgsql net-tools curl
  • postgres用于保存数据
  • renderd是渲染进程
  • apache2提供www服务
  • mod-tile基于apache2提供切片服务,决定什么时候该切片、把什么切片

创建数据库

1
2
3
4
5
6
7
8
9
10
11
sudo -u postgres -i #以root登陆psotgres
createuser _renderd #创建新用户
createdb -E UTF8 -O _renderd gis #创建数据库
psql #此时终端显示postgres=#
\c gis #此时提示You are now connected to database "gis" as user "postgres". 终端显示gis-#
CREATE EXTENSION postgis; #提示CREATE EXTENSION
CREATE EXTENSION hstore; #提示CREATE EXTENSION
ALTER TABLE geometry_columns OWNER TO _renderd; #提示ALTER TABLE
ALTER TABLE spatial_ref_sys OWNER TO _renderd; #提示ALTER TABLE
\q #退出psql
exit #退出root

Mapnik

测试安装状态

1
2
3
python3 #进入python环境
>>> import mapnik #导入库,没有保存就正常
>>> quit() #退出环境

样式表配置

1
2
3
4
5
6
7
8
mkdir ~/src #创建文件夹
cd ~/src
git clone https://github.com/gravitystorm/openstreetmap-carto #下载库 17.32MB
cd openstreetmap-carto
git checkout v5.9.0 #官方的新版本在使用新格式
sudo npm install -g carto #安装编译器
carto -v #查看版本 1.2.0
carto project.mml > mapnik.xml #有一些警告

加载数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
mkdir ~/data
cd ~/data
wget https://download.geofabrik.de/asia/azerbaijan-latest.osm.pbf # 35.6MB
chmod o+rx ~
sudo -u _renderd osm2pgsql -d gis --create --slim -G --hstore \
--tag-transform-script ~/src/openstreetmap-carto/openstreetmap-carto.lua \
-C 2500 --number-processes 1 -S ~/src/openstreetmap-carto/openstreetmap-carto.style \
~/data/azerbaijan-latest.osm.pbf

#以下为我的输出
2024-01-03 11:07:52 osm2pgsql version 1.6.0
2024-01-03 11:07:52 Database version: 14.10 (Ubuntu 14.10-0ubuntu0.22.04.1)
2024-01-03 11:07:52 PostGIS version: 3.2
2024-01-03 11:07:52 Setting up table 'planet_osm_point'
2024-01-03 11:07:52 Setting up table 'planet_osm_line'
2024-01-03 11:07:52 Setting up table 'planet_osm_polygon'
2024-01-03 11:07:52 Setting up table 'planet_osm_roads'
2024-01-03 11:08:20 Reading input files done in 28s.
2024-01-03 11:08:20 Processed 5151545 nodes in 16s - 322k/s
2024-01-03 11:08:20 Processed 477473 ways in 11s - 43k/s
2024-01-03 11:08:20 Processed 2957 relations in 1s - 3k/s
2024-01-03 11:08:21 Clustering table 'planet_osm_point' by geometry...
2024-01-03 11:08:22 Creating geometry index on table 'planet_osm_point'...
2024-01-03 11:08:22 Creating osm_id index on table 'planet_osm_point'...
2024-01-03 11:08:22 Analyzing table 'planet_osm_point'...
2024-01-03 11:08:22 Clustering table 'planet_osm_line' by geometry...
2024-01-03 11:08:37 Creating geometry index on table 'planet_osm_line'...
2024-01-03 11:08:39 Creating osm_id index on table 'planet_osm_line'...
2024-01-03 11:08:39 Analyzing table 'planet_osm_line'...
2024-01-03 11:08:39 Clustering table 'planet_osm_polygon' by geometry...
2024-01-03 11:08:41 Creating geometry index on table 'planet_osm_polygon'...
2024-01-03 11:08:42 Creating osm_id index on table 'planet_osm_polygon'...
2024-01-03 11:08:42 Analyzing table 'planet_osm_polygon'...
2024-01-03 11:08:42 Clustering table 'planet_osm_roads' by geometry...
2024-01-03 11:08:42 Creating geometry index on table 'planet_osm_roads'...
2024-01-03 11:08:42 Creating osm_id index on table 'planet_osm_roads'...
2024-01-03 11:08:42 Analyzing table 'planet_osm_roads'...
2024-01-03 11:08:42 Done postprocessing on table 'planet_osm_nodes' in 0s
2024-01-03 11:08:42 Building index on table 'planet_osm_ways'
2024-01-03 11:08:56 Done postprocessing on table 'planet_osm_ways' in 13s
2024-01-03 11:08:56 Building index on table 'planet_osm_rels'
2024-01-03 11:08:56 Done postprocessing on table 'planet_osm_rels' in 0s
2024-01-03 11:08:56 All postprocessing on table 'planet_osm_point' done in 0s.
2024-01-03 11:08:56 All postprocessing on table 'planet_osm_line' done in 16s.
2024-01-03 11:08:56 All postprocessing on table 'planet_osm_polygon' done in 2s.
2024-01-03 11:08:56 All postprocessing on table 'planet_osm_roads' done in 0s.
2024-01-03 11:08:56 osm2pgsql took 64s (1m 4s) overall.
  • -d gis 使用数据库
  • –create 创建数据库
  • slim 渲染表
  • G 表布局
  • hstore 多折线如何处理
  • tag-transform-script
  • C 2500 为导入过程分配osm2pgsql 2.5Gb内存,可以修改
  • number-processes 使用的CPU核心数
  • 最后的参数为需要加载的文件

创建索引

1
2
cd ~/src/openstreetmap-carto/
sudo -u _renderd psql -d gis -f indexes.sql #输出CREATE INDEX 16次

导入功能

1
2
cd ~/src/openstreetmap-carto/
sudo -u _renderd psql -d gis -f functions.sql #输出CREATE FUNCTION 3次

下载shapefile

此文件提供国家边界

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
cd ~/src/openstreetmap-carto/
mkdir data
sudo chown _renderd data
sudo -u _renderd scripts/get-external-data.py #文件很大,你要忍一下
# 以下为我的输出
INFO:root:Starting load of external data into database
INFO:root:Checking table simplified_water_polygons
INFO:root: Download complete (23795202 bytes)
INFO:root: Decompressing file
INFO:root: Importing into database
INFO:root: Import complete
INFO:root:Checking table water_polygons
INFO:root: Download complete (847964073 bytes)
INFO:root: Decompressing file
INFO:root: Importing into database
INFO:root: Import complete
INFO:root:Checking table icesheet_polygons
INFO:root: Download complete (52393148 bytes)
INFO:root: Decompressing file
INFO:root: Importing into database
INFO:root: Import complete
INFO:root:Checking table icesheet_outlines
INFO:root: Download complete (53057255 bytes)
INFO:root: Decompressing file
INFO:root: Importing into database
INFO:root: Import complete
INFO:root:Checking table ne_110m_admin_0_boundary_lines_land
INFO:root: Download complete (57325 bytes)
INFO:root: Decompressing file
INFO:root: Importing into database
INFO:root: Import complete

设置服务器

1
2
3
cd ~/src/openstreetmap-carto/
scripts/get-fonts.sh #安装字体,安装不了也不影响使用。
vim /etc/renderd.conf

添加配置

1
2
3
4
5
6
[s2o]
URI=/hot/
XML=/home/accountname/src/openstreetmap-carto/mapnik.xml # 注意修改
HOST=localhost
TILESIZE=256
MAXZOOM=20

调试信息

1
sudo vim /usr/lib/systemd/system/renderd.service

在service字段添加

1
Environment=G_MESSAGES_DEBUG=all

重启

1
2
3
sudo systemctl daemon-reload
sudo systemctl restart renderd
sudo systemctl restart apache2

在/var/log/syslog中可以看到

1
2
3
Jan  3 11:39:03 hyper-vm apachectl[10696]: [Wed Jan 03 11:39:03.138282 2024] [tile:notice] [pid 10696:tid 140362100856704] Loading tile config s2o at /hot/ for zooms 0 - 20 from tile directory /var/cache/renderd/tiles with extension .png and mime type image/png
Jan 3 11:39:03 hyper-vm apachectl[10696]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
Jan 3 11:39:03 hyper-vm systemd[1]: Started The Apache HTTP Server.

瓦片

用浏览器打开localhost

apache2主页

查看世界地图localhost/hot/0/0/0.png

地图瓦片

地图

1
2
3
cd /var/www/html
sudo wget https://raw.githubusercontent.com/SomeoneElseOSM/mod_tile/switch2osm/extra/sample_leaflet.html
sudo nano sample_leaflet.html

使用浏览器打开localhost/sample_leaflet.html

地图

同时在syslog中可以查看信息。

1
2
3
4
5
6
7
8
9
10
Jan  3 11:52:30 hyper-vm renderd[10265]: START TILE s2o 13 5936-5943 3240-3247, new metatile
Jan 3 11:52:30 hyper-vm renderd[10265]: START TILE s2o 13 5944-5951 3240-3247, new metatile
Jan 3 11:52:30 hyper-vm renderd[10265]: START TILE s2o 13 5936-5943 3232-3239, new metatile
Jan 3 11:52:30 hyper-vm renderd[10265]: START TILE s2o 13 5944-5951 3232-3239, new metatile
Jan 3 11:52:30 hyper-vm renderd[10265]: DONE TILE s2o 13 5936-5943 3240-3247 in 0.263 seconds
Jan 3 11:52:30 hyper-vm renderd[10265]: DONE TILE s2o 13 5936-5943 3232-3239 in 0.263 seconds
Jan 3 11:52:30 hyper-vm renderd[10265]: START TILE s2o 13 5936-5943 3232-3239, age 0.00 days
Jan 3 11:52:30 hyper-vm renderd[10265]: DONE TILE s2o 13 5944-5951 3240-3247 in 0.277 seconds
Jan 3 11:52:30 hyper-vm renderd[10265]: DONE TILE s2o 13 5944-5951 3232-3239 in 0.264 seconds
Jan 3 11:52:30 hyper-vm renderd[10265]: DONE TILE s2o 13 5936-5943 3232-3239 in 0.255 seconds

瓦片地图

瓦片式,顾名思义,地图是向瓦片一样一层一层叠起来的,最顶层的只有一张图,那么这张最顶层的图由四张次级的图组成,这样一级一级套娃下来,民用最细节的应该是18级,缺点是地图数据包非常大

矢量地图

矢量图,地图由矢量信息表示,地图框架根据矢量信息绘制点、街道、大楼等图形,优点是数据小,但是资源消耗大,因为显示地图时需要将矢量点绘制成图像

加密

地图属于战略资源,国内的地图数据都是经过加密的,而且部分区域并未表示其用途

经纬高坐标系(WGS-84坐标系)

地球是个椭圆球,自传时近似于圆球。为了方便定位某个点在地球上的位置,以赤道为分割线分割南北纬,上下顶点为南北极,上下各90°;以本初子午线为分割线分割东西经,左右各180°。以海平面为0点分割海拔,没有上限,取正值;下限为马里亚纳海沟最底部深度,取赋值。

这样,就可以使用经(度)纬(度)高(度)表示一个点在地球表面的位置。

笛卡尔坐标系

地球是三维的,使用经纬高表示。但是我们需要在二维平面上表示地球(比如地图),那么经纬度高就不适用了。我们使用投影的方式将三维的点映射到二维平面上,二维平面使用笛卡尔坐标系表示。

xyz

在线地图访问时,一般地址中包含xyz值,这个值和笛卡尔坐标系xy不同。

z表示层级,一般地图是1-18级,第1级就是一张世界地图,第2级是将第1级分割为4份,每一份表示一部分;那么第18级就有4181=171798691844^{18-1}=17179869184张图片

xy表示每一级图片的坐标,比如第2级有四张图片,两行两列,那么x的范围为[1,2],同样y范围为[1,2]。

那么获取第1级瓦片图的网址为

1
https://map.com/1/1/1.png

获取第2级瓦片图片的网址为

1
2
3
4
https://map.com/1/1/2.png
https://map.com/1/2/2.png
https://map.com/2/1/2.png
https://map.com/2/2/2.png

东北天坐标系(ENU)

也叫站心坐标系以用户所在位置P为坐标原点。

坐标系定义为: X轴:指向东边 Y轴:指向北边 Z轴:指向天顶

ENU局部坐标系采用三维直角坐标系来描述地球表面,实际应用较为困难,因此一般使用简化后的二维投影坐标系来描述。在众多二维投影坐标系中,统一横轴墨卡托(The Universal Transverse Mercator ,UTM)坐标系是一种应用较为广泛的一种。UTM 坐标系统使用基于网格的方法表示坐标,它将地球分为 60 个经度区,每个区包含6度的经度范围,每个区内的坐标均基于横轴墨卡托投影,

ECEF坐标系

也叫地心地固直角坐标系。其原点为地球的质心,x轴延伸通过本初子午线(0度经度)和赤道(0deglatitude)的交点。z轴延伸通过的北极(即,与地球旋转轴重合)。y轴完成右手坐标系,穿过赤道和90度经度。

dubins曲线

Dubins曲线是在满足曲率约束和规定的始端和末端的切线方向的条件下,连接两个二维平面(即X-Y平面)的最短路径,并假设车辆行驶的道路只能向前行进。如果车辆也可以在反向行驶,则路径为Reeds–Shepp曲线。

飞机无法原地转弯、无法后退,只能向前,就算是直升机换个方向也要先转个很大的弯

所以飞机的航线需要进行规划,如果给定很多中间飞行点的话需要多次绕圈变化飞行。


搭建本地OSM地图服务器
https://blog.jackeylea.com/osm/how-to-setup-offline-osm-map-server/
作者
JackeyLea
发布于
2024年1月4日
许可协议