介绍
OpenStreetMap项目由数千名用户收集和汇总的原始地图数据组成,但其开放访问政策引发了一系列附加项目,这些项目集体涵盖了商业地图服务通常提供的许多功能。
使用基于OpenStreetMap的软件而不是商业解决方案的最明显的优点是经济方便,因为OpenStreetMap是免费的(如啤酒和语音)软件。
本教程涵盖了 Web 服务的配置和维护,可以回答如下的问题:
- 最接近一对坐标的街道是什么?
- 从A点到B点的最佳途径是什么?
- 从A点到B点需要多长时间才能乘车或步行?
使这成为可能的软件是一个开源项目,名为 Open Source Routing Machine (OSRM),它基于OpenStreetMap数据。
前提条件
要遵循本教程,您将需要:
- 一个 Ubuntu 14.04 Droplet.
- 一个 sudo 非 root 用户,您可以通过遵循 本教程创建一个 sudo 非 root 用户。
本教程中的一些操作,例如从源头构建OSRM和预处理阶段,具有记忆密集性. 在低记忆力Dropplets中,这些操作可能会失败,这就是为什么需要分配一个交换文件的原因。
网页服务通常在运行时不需要额外的交换,所以在安装完成后可以删除这个交换文件. 然而,在服务大型地图时,可能确实需要一个小型的交换文件,特别是在低内存的Dropplets中。
步骤 1 – 更新和安全性
在此步骤中,我们将为服务器配置更新。
因此,我们首先通过运行以下命令来升级系统中的所有包。
1sudo apt-get update
2sudo apt-get upgrade
然后,我们打开Ubuntu的未经监督的安全升级. 要做到这一点,我们首先需要安装必要的软件包。
1sudo apt-get install unattended-upgrades
接下来,通过编辑文件 /etc/apt/apt.conf.d/10periodic
打开自动升级,我们需要使用 sudo
,因为这是一个全系统的配置文件。
1sudo nano /etc/apt/apt.conf.d/10periodic
在文件的末尾添加下列行,然后保存并关闭它。
1APT::Periodic::Unattended-Upgrade "1";
步骤 2 — 下载地图导出
在此步骤中,我们将选择和下载地图导出。
为了保持一切清洁,创建一个专用目录,在其中构建代码,处理地图等是一个好主意。
1mkdir osrm
移动到新目录。
1cd osrm
我们的网页服务将基于从OpenStreetMap导出地图,有几种可能的方式来获取地图导出。
第一种选择是将浏览器指向OpenStreetMap的 出口页面,缩放感兴趣的区域,然后点击 Export(如果原生导出不起作用,您可能需要使用其他来源之一;过渡API是一个很好的选择)。
但是,你可以从OSRM网站获得的出口量有限制,所以你可能想下载一份已完成的出口。 一些服务,如 Geofabrik和 Mapzen提供针对大多数用例的好国家和选择的大都市地区的更新和已完成的地图出口。
无论您使用哪种方法,请复制出口的URL,然后将其下载到您的Droplet。
1wget -O map.osm url_of_the_export
您现在应该在工作目录中有名为map.osm的文件。
步骤3 - 安装依赖性
在此步骤中,我们将安装OSRM的依赖。
OSRM必须从源头编译,所以我们首先需要安装必要的构建机器。幸运的是,Ubuntu配备了一个叫做build-essential
的方便元包,其中包含所需的编译工具链。此外,我们还需要git
来抓住OSRM的源代码,并CMake
来生成构建系统。
1sudo apt-get install build-essential git cmake
OSRM是一个相当复杂的软件,也依赖于多个库,我们可以使用以下命令安装所需的依赖。
1sudo apt-get install libboost-all-dev libtbb-dev liblua5.2-dev libluabind-dev libstxxl-dev libxml2 libxml2-dev libosmpbf-dev libbz2-dev libprotobuf-dev
Lua 被用来定义自定义速度档案脚本,例如定义在二级道路上,在没有限制的情况下,汽车平均速度为 80 公里/小时,在铁路上,平均速度为 50 公里/小时 STXXL 是 C++ 标准库的版本,它使用磁盘空间作为内存,用于操纵大型文件。
步骤 4 – 编译 OSRM
在此步骤中,我们将获取OSRM的源代码并编译它。
由于OSRM的构建系统是CMake,一旦安装了依赖性,可以很容易地生成构建文件并编译OSRM。
首先,我们从项目的 页面中克隆源代码。 该项目由几个存储库组成,处理不同的功能。
1git clone https://github.com/Project-OSRM/osrm-backend.git
接下来,进入代码目录。
1cd osrm-backend
下一步是使用CMake生成构建文件,建议在源代码根中构建一个专用的构建
目录中构建OSRM,以避免污染源目录的临时构建文件。
创建一个构建目录。
1mkdir build
进入构建目录。
1cd build
最后,我们将用cmake
生成构建文件,该命令将在build
目录树中生成多个目录和Makefiles。
1cmake ..
如果您在这里收到错误,请确保您通过前提条件中的说明启用了交换。
接下来,编译和安装OSRM。
1sudo make install
注:这可能需要5到10分钟。
用sudo
构建是必要的,因为安装目标将复制系统的二进制路径中的某些执行,包括我们需要的某些执行。
- 'osrm-extract' 打开地图文件并在数据上运行第一步的预处理步骤。
- 'osrm-prepare' 处理 'osrm-extract' 的输出并根据给定的 Lua 速度配置计算所有地图边缘的旅行时间。
步骤 5 – 配置 STXXL
在此步骤中,我们将为 STXXL 创建一个配置文件。
在运行网络服务之前,我们需要预先处理我们的地图输出,因为我们已经在系统路径中安装了所需的二进制,所以我们可以从任何地方执行此操作,为本教程的目的,我们将在我们创建的osrm
目录的根部运行预处理。
首先,转到osrm
目录。
1cd ~/osrm
由于这个原因,OSRM使用一个名为 STXXL的库来绘制其在硬盘上的内部操作。STXXL依赖于一个名为 .stxxl
的配置文件,该文件生活在您正在运行软件的相同目录中,以确定有多少空间用于STXXL数据结构。 根据我们的Droplet的容量和我们想要处理的地图的大小,我们需要写一个合适的 .stxxl
配置文件,为操作分配足够的内存。
创建并打开.stxxl
进行编辑。
1nano .stxxl
该文件必须包含一个单行格式disk=path,capacity,access
,其中path
是分配文件将放置的路径,capacity
是文件的容量,access
是文件访问实现。
这里是.stxxl 文件的例子. 您可以将其粘贴到.stxxl 中,但您可能希望根据您正在使用的地图和 Droplet 的大小更改文件的大小。
1disk=/tmp/stxxl,10G,syscall
保存并关闭.stxxl
。
步骤 6 - 提取地图
在此步骤中,我们将提取地图。
osrm-extract
命令预计地图输出的路径作为一个论点,并假定在工作目录中存在一个适当的速度配置文件脚本,名为profile.lua
。
OSRM 后端分布包括在存储库的配置文件
目录下的一些默认速度配置文件,在本教程中,我们将使用car.lua
配置文件,这对大多数用例都很好。
由于速度配置文件脚本可能取决于配置文件库中定义的某些Lua函数,我们还通过运行以下两个命令在同一目录中创建一个符号链接。
1ln -s osrm-backend/profiles/car.lua profile.lua
2ln -s osrm-backend/profiles/lib
我们的地图导出名为map.osm
,接下来运行:
1osrm-extract map.osm
此步骤在预处理目录中生成一大堆文件,包括map.osrm
,这是下一步的输入。
步骤7 - 计算旅行时间
在此步骤中,我们将计算地图的旅行时间。
此步骤由osrm-prepare
命令执行,该命令再次使用速度配置程序来计算地图图图的每个边缘的旅行时间。
1osrm-prepare map.osrm
此步骤还会产生 Web 服务所需的一些额外文件,我们将在下一节中设置。
步骤 8 – 运行并测试 Web 服务
在此步骤中,我们将运行OSRM并测试它是否通过浏览器工作。
OSRM后端配有最终命令osrm-routed
,可以读取处理的地图,并允许通过Web服务API进行查询。
1osrm-routed map.osrm
现在,通过将您的浏览器指向 http://your_server_ip:5000
,您现在应该能够看到 Web 服务在行动中. 它将显示一个错误消息,如 {"status_message":"Query string malformed near position 0","status":400}
因为您不使用正确的查询格式。
作为测试,在您的地图边界中选择一组纬度和长度坐标,然后转到以下URL,用您选择的坐标取代纬度
和长度
。
1http://your_server_ip:5000/nearest?loc=latitude,longitude
您应该看到类似于此的 JSON 输出:
1{
2 "name": "street_name",
3 "mapped_coordinate": [
4 latitude,
5 longitude
6 ],
7 "status":0
8}
如果您收到错误消息,您可能已经选择了地图边界之外的一组坐标,或者查询语法可能是错误的。
您现在可以使用CTRL+C
停止osrm-routed
。
步骤 9 – 设置 Nginx
在此步骤中,我们将设置 Nginx 以与osrm-routed
一起工作。
现在我们有一个工作网页服务,但通过指定端口来查询它很麻烦. 此外,如果我们决定用不同的速度配置处理不同的地图或地图,我们希望避免需要记住一组端口。
Nginx 是一个高性能的 Web 服务器,它也可以作为代理服务器,并作为我们的 Web 服务的网关。
首先,我们安装了 Nginx。
1sudo apt-get install nginx
接下来,我们为我们的 Web 服务添加了一个配置文件。 Nginx 使用两个目录为其网站特定的配置文件: /etc/nginx/sites-available
(所有可以服务的网站)和 /etc/nginx/sites-enabled
(所有正在服务的网站)。
因此,首先,我们将为OSRM添加一个配置fime为可用站点
。
1sudo nano /etc/nginx/sites-available/osrm.conf
我们的配置文件将定义一个指向我们的Web服务的上游
和一个服务器,该服务器在端口80上收听并将查询的子集重定向到我们的上游。
将 Follow 配置文件粘贴到 osrm.conf
. 您需要指定两个变量,这些变量在下面被突出:您的服务器 IP 和路径(将用于访问 Web 服务,如在 http://your_server_ip/example_path
)。
1upstream osrm {
2 server 0.0.0.0:5000;
3}
4
5server {
6 listen 80;
7 server_name your_server_ip;
8
9 location /example_path {
10 proxy_pass http://osrm/;
11 proxy_set_header Host $http_host;
12 }
13}
一旦您保存了文件,请转到网站启用
目录。
1cd /etc/nginx/sites-enabled
然后我们可以链接到osrm.conf
文件。
1sudo ln -s /etc/nginx/sites-available/osrm.conf
接下来,重新加载配置。
1sudo service nginx reload
最后,重新启动 Nginx。
1sudo service nginx restart
现在重新运行osrm-routed
。
1osrm-routed ~/osrm/map.osrm
您应该能够通过将我们的浏览器指向http://your_server_ip/example_path
来访问 Web 服务. 请注意,您不再需要指定端口。
通过添加更多的上游和位置,并通过指定-p
或-port
的端口运行osrm-routed
,我们可以运行更多的Web服务实例,并将它们绑定到不同的路径。
步骤 10 – 安装和配置监控程序
在此步骤中,我们将安装和配置 Supervisor 以保持 Nginx 运行,使我们的 Web 服务通过重新启动可用。
然而,我们已经手动启动了它,所以如果我们退出系统,它将停止运转. 为了使我们的网络服务通过重新启动生存,并在一般情况下使它们从可能的故障中恢复,我们可以使用名为 Supervisor的工具。
Supervisor 是一个过程控制系统,主要负责保持服务正常运行,设置很容易,首先,我们安装 Supervisor 本身。
1sudo apt-get install supervisor
然后,我们将我们的 Web 服务添加到 Supervisor 控制的服务池中,添加一个新的配置文件。
1sudo nano /etc/supervisor/conf.d/osrm.conf
配置文件必须包含我们希望监督的每个 Web 服务的此表单的定义,并且每个 Web 服务的程序名称必须不同。
将下面的配置粘贴到osrm.conf
文件中,然后保存并关闭它。
1[program:osrm]
2directory=/home/osrm/osrm
3command=/usr/local/bin/osrm-routed -p 5000 map.osrm
4user=osrm
这个配置说的是,我们希望用户osrm
保持命令/usr/local/bin/osrm-routed -p 5000 map.osrm
运行,并且它必须从指定的目录中运行,/home/osrm/osrm
(这就是我们如何在命令中指定map.osrm
作为相对路径)。
保存并关闭文件后,重新启动 Supervisor。
1sudo service supervisor restart
然后我们可以通过运行来检查网络服务的状态:
1sudo supervisorctl status
如果一切都很好,我们应该看到类似的东西
1osrm RUNNING pid 12698, uptime 0:00:40
因为上游指向端口5000,Nginx将能够在指定的路径上服务它。
结论
本教程讨论了 OSRM 后端的安装,但进一步的文档可在 此页找到。
在写作时,OSRM后端仍处于测试阶段,并对单个查询中可包含的位置数量有某些硬编码限制(目前为100个,影响时间矩阵API)。
根据您的地图的大小和 Droplet 的容量,您可能需要分配一个更大的交换文件或增加.stxxl 配置文件的容量,以便 Web 服务正常工作。