高德?不,用自己的导航

目录

1.编写目的

2.项目准备

2.1 openstreet账号

2.2 绘制路网数据并导出OSM路网文件

2.3 Jar包准备

3.Springboot项目搭建

3.1 配置jar包

3.2 实现graphhopper配置类

3.3 实现访问接口

4.功能测试


1.编写目的

        编写该文章的目的是在开发时需要用到自定义的路网导航,查阅高德、百度地图等相关网站后,并没有发现可自定义路网的导航,后来在Git上搜到了Graphhopper这个国外的开源软件,然后学习使用后实现了自定义路网导航的功能,现在记录一下自己的实现过程,以保存开发资料,并且帮助到需要实现相关功能的朋友。

2.项目准备

2.1 openstreet账号

        项目需要使用OpenStreet网站专属的OSM文件格式,所以需要在https://www.openstreetmap.org/进行在线的绘制(并没有找到好用的文件转换工具,并且国内相关教程也很少),这里需要自己在这个网站注册一个账号并登录。

2.2 绘制路网数据并导出OSM路网文件

        登录后点击编辑按钮进入编辑界面,在当前界面中可以绘制线并完成要素类型选择,如选择小道(这将仅在步行导航时才会生效)、小型等级外道路(车、步行、自行车),不同道路类型使用不同交通工具。

绘制完成后点击右上角保存按钮,完成自定义路径的保存。

然后输入更新提示信息完成数据的保存。

在主界面点击导出按钮进入导出页面,输入经纬度坐标完成目标区域的选择或选择”手动选择目标区域”来框选目标区域(注:这里最多导出50000节点),点击导出按钮完成导出操作,导出为osm文件。

2.3 Jar包准备

这里可以去gitHub自己下载Releases · graphhopper/graphhopper · GitHub,也可以使用我使用的Jar包。在置顶资源中graphhopper-web-9.0.jar

3.Springboot项目搭建

3.1 配置jar包

将jar包复制到项目路径中,这里复制到项目的lib文件夹下,并配置pom文本地路径,配置如下:

<dependency>
    <groupId>com.graphhopper</groupId>
    <artifactId>graphhopper-web</artifactId>
    <scope>system</scope>
    <version>9.0</version>
    <systemPath>${project.basedir}/lib/graphhopper-web-9.0.jar</systemPath>
</dependency>

3.2 实现graphhopper配置类

@Configuration
public class GraphhopperConfig {


    @Bean
    public GraphHopper graphHopper(){
	  //这里定义步行导航和汽车导航的文件并指定交通工具
        List<Profile> profile=new ArrayList<Profile>();
        profile.add(new Profile("foot").setVehicle("foot"));
        profile.add(new Profile("car").setVehicle("car"));

        GraphHopper graphHopper=new GraphHopper();
        //这里配置导出的osm文件
        graphHopper.setOSMFile("osm文件路径");
       //这里配置程序启动时预处理节点文件存放位置
        graphHopper.setGraphHopperLocation("预处理节点文件存放位置");
        //使用配置文件
        graphHopper.setProfiles(profile);
        graphHopper.importOrLoad();
        return graphHopper;
    }
}

        首先置顶要使用的交通工具,有三种交通工具为步行(foot)、汽车(car)、自行车(bike),这里使用foot和car进行测试.然后是配置osm文件路径,这里是导出的osm文件的位置.预处理存放位置为一个空文件夹,将会在程序启动时处理osm文件并缓存节点文件到该文件夹下,使用配置文件导入或者加载。(注:这里程序启动一次后除非删除缓存节点文件中的文件,否则节点文件不会更新,即更新路网数据时需先删除缓存的节点文件)。


3.3 实现访问接口

@GetMapping("/navigate")
public String navigate(@RequestParam("start") String start, @RequestParam("end") String end,@RequestParam("vehicle") String vehicle) {
    GHRequest request = new GHRequest()
            .setAlgorithm(Parameters.Algorithms.DIJKSTRA_BI) // 设置路径搜索算法
            .setProfile(vehicle)
            .addPoint(fromString(start))
            .addPoint(fromString(end));

    GHResponse response = graphHopper.route(request); // 计算路径

    if (response.hasErrors()) {
        return "Error: " + response.getErrors().get(0).getMessage();
    } else {
        System.err.println("距离:"+response.getBest().getDistance());
        System.err.println("时间:"+response.getBest().getTime());
        return convertToGeoJson(response.getBest().getPoints());
    }
}
//这里将,分割经纬度转换为GHPoint类
private GHPoint fromString(String str) {
    String[] parts = str.split(",");
    return new GHPoint(Double.parseDouble(parts[0]), Double.parseDouble(parts[1]));
}
//这里将路径转换为GeoJson
private String convertToGeoJson(PointList path) {
    JSONObject featureCollection = new JSONObject();
    featureCollection.put("type", "FeatureCollection");
    JSONArray features = new JSONArray();
    JSONObject feature = new JSONObject();
    feature.put("type", "Feature");
    Map<String,Object> properties=new HashMap<>();
    properties.put("Shape_Length",0.003024242688834029);
    feature.put("properties", properties);
    JSONObject geometry = new JSONObject();
    geometry.put("type", "LineString");

    JSONArray coordinates = new JSONArray();
    for (GHPoint point : path) {
        JSONArray coordinate = new JSONArray();
        coordinate.add(point.lon);
        coordinate.add(point.lat);
        coordinates.add(coordinate);
    }

    geometry.put("coordinates", coordinates);
    feature.put("geometry", geometry);
    features.add(feature);

    featureCollection.put("features", features);

    return featureCollection.toString();
}

        先构建GHRequest,在该对象中传入起始点经纬度、结束点经纬度、设置使用的vehice,即选择不同的配置文件,调用route方法获取路径响应,并通过getBest()方法获取最短路径.同时在该响应对象中还可获取如路径距离、路径时间、行走方向等信息。下面的两个方法为辅助方法分别是转换为GHPoint和转换为GeoJson方法。

4.功能测试

将结果进行可视化,这里使用在线网站:https://geojson.io/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盹猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值