Java SpringBoot项目 GraphHopper 实现地图多途径点离线路径规划

云端漫步 2024-09-09 ⋅ 15 阅读

简介

在现实生活中,我们经常需要规划一系列途径点的路径,比如送货人员需要尽快地到达多个目的地,或者旅行者想要游览多个景点。利用离线路径规划算法可以帮助我们高效地规划出最优路径。

本篇博客将介绍如何借助Java SpringBoot和GraphHopper实现地图多途径点的离线路径规划功能。

GraphHopper概述

GraphHopper是一个开源的路线规划引擎,它能够根据地图数据和路径规划算法,快速计算出两点之间的最短路径。

开发环境准备

在开始之前,我们需要准备以下开发环境:

  • JDK 8+
  • Maven
  • IntelliJ IDEA(或其他Java开发工具)

引入依赖

首先,我们需要创建一个SpringBoot项目,并在pom.xml文件中引入GraphHopper的依赖:

<dependency>
    <groupId>com.graphhopper</groupId>
    <artifactId>graphhopper-web</artifactId>
    <version>2.1</version>
</dependency>

集成GraphHopper

在SpringBoot项目中,我们可以创建一个GraphHopperService类,用于集成GraphHopper:

import com.graphhopper.GraphHopper;
import com.graphhopper.GraphHopperConfig;
import com.graphhopper.config.ProfileConfig;
import com.graphhopper.config.RoutingConfig;
import com.graphhopper.routing.ProfileResolver;
import com.graphhopper.routing.util.EncodingManager;
import com.graphhopper.routing.util.FlagEncoder;
import com.graphhopper.routing.util.FlagEncoderFactory;
import com.graphhopper.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class GraphHopperService {
    private static final Logger logger = LoggerFactory.getLogger(GraphHopperService.class);
    private GraphHopper graphHopper;

    public GraphHopperService() {
        // 创建一个GraphHopper对象
        graphHopper = new GraphHopper();
        // 设置地图数据文件路径
        graphHopper.setDataReaderFile("path/to/map-data.osm.pbf");
        // 设置路径规划的配置项
        GraphHopperConfig config = new GraphHopperConfig();
        config.putObject("profiles.import_enabled", false);
        config.putObject("routing.non_ch.max_waypoint_distance", "2km");
        config.putObject("prepare.min_network_size", 2);
        config.putObject("routing.ch.disabling_allowed", true);
        config.putObject("prepare.min_one_way_network_size", 2);
        config.merge(GraphHopperConfig.readFromStream(getClass().getResourceAsStream("/config.yml")));
        graphHopper.init(config);
        graphHopper.setStorage(new MMapStorage("path/to/graph-cache", config.has("graph.dataaccess")));
    }

    public GHResponse calculatePath(GHRequest request) {
        return graphHopper.route(request);
    }
}

GraphHopperService类中,我们通过设置地图数据文件路径、路径规划的配置项以及缓存路径来初始化GraphHopper对象。

编写Controller

接下来,我们需要编写一个Controller类,用于接收并处理路径规划的请求:

import com.graphhopper.PathWrapper;
import com.graphhopper.routing.util.EncodingManager;
import com.graphhopper.util.PointList;
import com.graphhopper.util.shapes.GHPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/api")
public class PathController {
    private GraphHopperService graphHopperService;

    @Autowired
    public PathController(GraphHopperService graphHopperService) {
        this.graphHopperService = graphHopperService;
    }

    @PostMapping("/path")
    public ResponseEntity<ApiResponse> calculatePath(@RequestBody PathRequest pathRequest) {
        try {
            GHRequest request = new GHRequest();
            request.setAlgorithm(Algorithms.DIJKSTRA_BI);
            request.setWeighting("fastest");
            request.setVehicle(EncodingManager.createFlagEncoder("car"));
            List<GHPoint> points = new ArrayList<>();
            pathRequest.getWaypoints().forEach(waypoint -> points.add(new GHPoint(waypoint.getLat(), waypoint.getLng())));
            request.setPoints(points);
            GHResponse response = graphHopperService.calculatePath(request);
            if (response.hasErrors()) {
                ApiResponse apiResponse = new ApiResponse(false, "Failed to calculate path");
                return new ResponseEntity<>(apiResponse, HttpStatus.INTERNAL_SERVER_ERROR);
            }
            PathWrapper pathWrapper = response.getBest();
            PointList pointList = pathWrapper.getPoints();
            List<Coordinate> coordinates = new ArrayList<>();
            for (int i = 0; i < pointList.getSize(); i++) {
                coordinates.add(new Coordinate(pointList.getLatitude(i), pointList.getLongitude(i)));
            }
            ApiResponse apiResponse = new ApiResponse(true, "Successfully calculated path", coordinates);
            return new ResponseEntity<>(apiResponse, HttpStatus.OK);
        } catch (Exception e) {
            ApiResponse apiResponse = new ApiResponse(false, "Failed to calculate path");
            return new ResponseEntity<>(apiResponse, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

PathController类中,我们通过@PostMapping注解将/api/path路径映射为计算路径的接口。在接收到路径规划请求后,我们需要将起点、途径点和终点都设置到GHRequest对象中,然后调用graphHopperService.calculatePath()方法计算最短路径。

请求数据

为了测试路径规划功能,我们可以使用Postman或其他RESTful API工具发送以下请求:

POST /api/path
Content-Type: application/json

{
    "waypoints": [
        {"lat": 30.000, "lng": 104.000},
        {"lat": 31.000, "lng": 105.000},
        {"lat": 32.000, "lng": 106.000}
    ]
}

结果展示

通过上述步骤,我们已经成功实现了地图多途径点的离线路径规划功能。当我们发送路径规划请求时,服务器将返回一个包含最短路径坐标的JSON响应。

总结

本篇博客介绍了如何利用Java SpringBoot和GraphHopper实现地图多途径点的离线路径规划。通过集成GraphHopper,并编写相应的Controller,我们能够方便地规划出多途径点之间的最短路径。

希望读者能够通过本篇博客了解到如何使用Java SpringBoot和GraphHopper实现离线路径规划,并能够在实际项目中应用到多途径点路径规划的场景中。


全部评论: 0

    我有话说: