关键词:高德地图、离线地图、离线路径规划、多途径点、JAVA、SpringBoot、GraphHopper、OpenStreetMap
目录
效果预览
使用OpenStreetMap(OSM)下载地图路网资源
使用GraphHopper实现多途径点路径规划
具体实现代码
高德地图内网部署请参考我之前的文章,传送门:高德地图离线加载解决方案(内网部署)+本地地图瓦片加载_高德地图离线瓦片_深海的鲸同学 luvi的博客-CSDN博客
完整项目Demo已提交至Gitee仓库,传送门:离线路径规划: Java SpringBoot项目使用GraphHopper实现多途径点路径规划
效果预览
使用OpenStreetMap(OSM)下载地图路网资源
https://www.openstreetmap.org/进入osm官网:https://www.openstreetmap.org/
数据下载窗口如下所示,其中上半部分为研究区域选择界面,下半部分则为多种数据下载方式的选择界面。
我们可以通过拉动屏幕所显示的地图范围或直接在下图所示框内修改经、纬度的方式,对研究区域加以选择,此外,还可以点击经、纬度框下方的蓝色文字,通过手动划定矩形区域的方式选择研究区域范围
范围选定后,我们可以直接点击屏幕左侧的“Export”按钮导出数据;但需要注意,在研究区域过大时,这一方法将会失效,需要自行探索最大范围进行下载。
此处下载的地图路网资源后缀为 .oem 的文件
如果需要全国路网图,你们又找不到在哪下载的话评论区留下邮箱,我发过去,文件1g。路网资源过大,对电脑的性能要求也是非常高的,所以小项目或指定区域内不建议使用全国路网
使用GraphHopper实现多途径点路径规划
SpringBoot项目,首先安装如下依赖
<dependency>
<groupId>***.graphhopper</groupId>
<artifactId>graphhopper-core</artifactId>
<version>4.0</version>
</dependency>
<dependency>
<groupId>***.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.34</version>
</dependency>
GraphHopper我没有进行太多了解,与这个相关的文章较少,未发现多途径点路径规划的相关介绍(如有相关的实践经验希望在评论区留下相关使用方式或文档),但是可以通过其他方式实现多途径点问题
[[94.88686342315677,36.408548095275435],[94.91853494720462,36.40633760017791],[94.90291376190189,36.40088017112323]]
多途径点的格式如上,二维数组,我们可以将数组中每每两项组合作为 起点 与 终点 分别进行路径规划,并对所有的规划结果利用JSONArray保存,最终返回多点的规划结果。
具体实现代码如下:
@PostMapping("/way")
public static JSONObject list(@RequestBody Point point) throws FileNotFoundException {
GraphHopper hopper = new GraphHopper();
// OSM 文件路径
hopper.setOSMFile("E:\\osm\\gem.osm");
// 读取完OSM数据之后会构建路线图,此处配置图的存储路径
hopper.setGraphHopperLocation("resources");
// 支持car、bike、foot三种交通方式的导航
hopper.setProfiles(new Profile("car").setWeighting("fastest").setTurnCosts(false));
//设置汽车
hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("car"));
// 加载地图数据
hopper.importOrLoad();
double distance = 0;
long timeInMs = 0;
JSONArray pathWay = new JSONArray();
// 对多途径点分别两两分组规划路径
for (int i = 1; i < point.getPathWay().length; i++) {
double[] p = point.getPathWay()[i-1];
double[] p2 = point.getPathWay()[i];
if(i==1)
pathWay.add(p);
double startLat = p[1];
double startLng = p[0];
double endLat = p2[1];
double endLng = p2[0];
GHRequest req = new GHRequest(startLat, startLng, endLat, endLng)
.setProfile("car");
GHResponse rsp = hopper.route(req);
// 报错处理
if (rsp.hasErrors())
throw new RuntimeException(rsp.getErrors().toString());
// 使用最佳路径,请参阅GHResponse类以了解更多可能性。
ResponsePath path = rsp.getBest();
PointList pointList = path.getPoints();
for (int j = 0; j < pointList.size(); ++j) {
JSONArray ja = new JSONArray();
ja.add(pointList.getLon(j)+0.001);
ja.add(pointList.getLat(j)-0.0004);
pathWay.add(ja);
}
// 对两两分组的规划结果进行保存
pathWay.add(p2);
distance += path.getDistance();
timeInMs += path.getTime();
}
// 返回最终结果
JSONObject jsonObject = new JSONObject();
jsonObject.put("code",200);
jsonObject.put("distance",distance+"米");
jsonObject.put("time",timeInMs+"毫秒");
jsonObject.put("path",pathWay);
return jsonObject;
}
demo已提交至gitee(回到顶部查看地址),可自行下载运行修改