Docker快速部署Graphhopper实现离线地图路径规划

前情提要:

去年的时候做了一个结合本地地图服务的CVRP项目。但是该服务需要配置本地环境,工作量极大,耗时很长。

今天带来的方法借助docker可以快速部署地图服务,节约90%的时间。

该方法需要借助Docker实现,所需需要提前安装好Docker。关于Docker的安装可以参考我的其他教程。

还需要提前下载好地图文件。可以去https://www.openstreetmap.org/下载。

最终实现效果如下:

#1. 通过Docker hub拉取镜像

打开命令行工具(例如,终端、命令提示符或PowerShell),然后运行以下命令来从Docker Hub拉取israelhikingmap/graphhopper镜像:

1
docker pull israelhikingmap/graphhopper:latest

2. 运行Docker

在下载好地图数据后可以进行该操作。例如,我的地图数据存储在”D:\open_street_map\china-latest.osm.pbf”

1
docker run -p 8989:8989 -v D:\/open_street_map:/graphhopper/mapdata  israelhikingmap/graphhopper --input mapdata/china-latest.osm.pbf --host 0.0.0.0

3. 内存溢出问题

因为地图数据很大,所以可能出现内存相关报错。这时可以多分配一些内存。加上-e JAVA_OPTS=”-Xmx4g -Xms4g”即可。

使用本地地图服务

经过上述步骤之后,本地服务即可成功运行。打开浏览器地址栏输入‘http://localhost:8989/maps/?profile=car)’后即可使用该服务。

有了这样的一个本地服务之后,有哪些玩法呢?

TSP项目

可以做一个本地的旅游路线规划求解器。通过这样一个函数即可获取两点之间的实际路径距离。

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
def lanlon_to_distance(lat1,lon1,lat2,lon2):
"""
将经纬度传入本地服务器,根据路网数据,在本地进行路径规划,返回两点之间的路径距离以及时间

Args:
lat1 (float): 地点1纬度
lon1 (float): 地点1经度
lat2 (float): 地点2纬度
lon2 (float): 地点2纬度
"""

url_head = 'http://127.0.0.1:8989/route?point='
url_tail = '&profile=car&layer=OpenStreetMap'
url = url_head + str(lat1) + ',' + str(lon1) + '&point=' + str(lat2) + ',' + str(lon2) + url_tail
headers = {'Connection':'close'}
response = requests.get(url,headers=headers)

try:
info = response.json()['paths'][0]
except:
print(response.json())
# print(info) # 获取json
# print(info['distance']) # 获取路径距离,单位为米
# print(info['time']) # 获取路径时间,单位为毫秒
distance = info['distance']/1000 # 距离单位转为千米
return distance

有了路径距离之后,可以使用各种算法求解。

求解出最优路径之后,还可以通过该服务来展示路线。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def generate_url(route_lonlat):
"""生成一条路径可视化的网页链接

Args:
route (_type_): 路径的经纬度坐标列表

Returns:
_type_: 网页链接,可视化展示每辆车的行驶路线
"""
url = ''
url_head = 'http://127.0.0.1:8989/maps/?point='
url_tail = '&profile=car&layer=OpenStreetMap'
if len(route_lonlat) > 2:
url = url_head + str(route_lonlat[0][1]) + ',' + str(route_lonlat[0][0])
for i in range(1,len(route_lonlat)):
url = url + '&point=' + str(route_lonlat[i][1]) + ',' + str(route_lonlat[i][0])
url += url_tail
return url

生成的链接点进去即可可视化展示路线。

参考文章

本地部署Graphhopper实现离线地图路径规划功能(小白放心食用版) | TUUG WORLD (john-start.github.io)

本地部署Graphhopper实现离线地图路径规划功能(小白放心食用版)_graphhopper 离线地图导航-CSDN博客