基于GraphHopper搭建离线路径规划服务并可视化

本文详细介绍如何在本地搭建GraphHopper服务,实现路径规划功能。包括服务的启动配置、地图数据加载、路径请求参数设置及可视化展示。利用OpenStreetMap数据和特定的配置文件,通过简单的命令行操作即可启动服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图:

说明:

       上篇已经说到如何在本机开启GraphHopper服务了,地址在这:基于Leaflet和GraphHopper实现离线路径规划_leaflet电子海图 openseamap 路径规划-优快云博客 ,里面的第一步就是,总结一下就是:一个jar包,一份pbf格式的数据,一个配置文件,然后在cmd窗口下跑一条命令。两个需要注意的地方:1.如果你想做全国的路径规划,先到OpenStreetMap上下载全国路网数据, 由于数据过大,跑的时候可能出现内存问题,可以试试加上-Xmx2g -Xms2g,我的命令:java -Xmx2g -Xms2g -Dgraphhopper.datareader.file=china-latest.osm.pbf -jar graphhopper-web-0.11.0.jar server config-example.yml  2.如果想让您本机的服务其他机器都能访问,注意修改配置文件最后的:bindHost: localhost 把localhost改成你的机器IP地址

服务启动之后,cmd窗口有提示打开localhost:8989

       到现在为止,后台工作已经完成,下面就是前台请求以及可视化工作。url请求地址仿照着拼就行了,前边是协议+IP+端口,后面参数根据选的点自己拼,不需要key,要注意参数points_encoded,他默认是true,也就是说返回来的点数据都是加密的,看你需求了,不想加密的话设为false。我的一个完整URl:

Request URL:

http://localhost:8989/route?point=52.53032100669386,13.344612121582031&point=52.527710210603935,13.409500122070314&type=json&locale=zh-CN&vehicle=car&weighting=fastest&points_encoded=false

主要代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>离线路径规划</title>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="./lib/leaflet/leaflet.css" />
  <link rel="stylesheet" href="lib/leaflet/leaflet.contextmenu.css"/>
  <script src="./lib/leaflet/leaflet.js"></script>
  <script src="./lib/leaflet/leaflet-ant-path.js" type="text/javascript"></script>
  <script src="./lib/leaflet/leaflet.contextmenu.js"></script>
</head>

<style>
  * { margin: 0; padding: 0; }
  html, body { height: 100%; }
  #mapid { width:100%; height:100%; }
</style>

<body>
<div id="mapid" ></div>
<script>
  var map = L.map('mapid', {
    center: [52.52207,13.374481],
    zoom: 13,
    crs: L.CRS.EPSG3857,
    layers: [
      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
      })
    ],
    contextmenu: true,
    contextmenuItems: [{
      text: '设置为起点',
      callback: setStartPoint
    }, {
      text: '设置为中间点',
      callback: setWaypoints
    }, '-', {
      text: '设置为终点',
      callback: setStopPoint
    }, {
      text: '开始规划',
      callback: calcRoute
    }]
  });
  var _startPoint,_stopPoint,_wayPoints = [];
  var _points = [];//用于存储所有点
  function setStartPoint(event){
    _startPoint = event.latlng;
    var _icon = L.icon({iconUrl:'./lib/img/start.png'})
    L.marker(_startPoint,{icon:_icon}).addTo(map);
  }
  function setWaypoints(event){
    _wayPoints.push(event.latlng);
    var _icon = L.icon({iconUrl:'./lib/img/way.png'})
    L.marker(event.latlng,{icon:_icon}).addTo(map);
  }
  function setStopPoint(event){
    _stopPoint = event.latlng;
    var _icon = L.icon({iconUrl:'./lib/img/stop.png'})
    L.marker(_stopPoint,{icon:_icon}).addTo(map);
  }
  function calcRoute() {
    var url = _buildRouteUrl();
    if(url == null || url == undefined){
      return;
    }else{
      var request,me = this;
      if (window.XMLHttpRequest) {
        request = new XMLHttpRequest();
      } else {
        request = new ActiveXObject('Microsoft.XMLHTTP');
      }

      request.onreadystatechange = function () { // 状态发生变化时,函数被回调
        if (request.readyState === 4) { // 成功完成
          // 判断响应结果:
          if (request.status === 200) {
            // 成功,通过responseText拿到响应的文本:
            return _success(request.responseText);
          } else {
            // 失败,根据响应码判断失败原因:
            return _fail(request.status);
          }
        } else {
          // HTTP请求还在继续...
        }
      }
      // 发送请求:
      request.open('GET', url);
      request.send();
      //alert('请求已发送,请等待响应...');
    }
  }

  function _buildRouteUrl(){
    var wayPoints = _setPointsSequence();
    if(wayPoints == null || wayPoints == undefined){
      return;
    }else{
      var locs = [],
        i,
        baseUrl;
      for (i = 0; i < wayPoints.length; i++) {
        locs.push('point=' + wayPoints[i].lat + ',' + wayPoints[i].lng);
      }
      baseUrl = 'http://localhost:8989' + '/route?' + locs.join('&');
      return baseUrl +  '&type=json&locale=zh-CN&vehicle=car&weighting=fastest&points_encoded=false';
    }
  }
  function _setPointsSequence(){
    var me = this;
    if(this._startPoint == null || this._startPoint == undefined){
      alert("请先设置起点");
      return;
    }
    if(this._stopPoint == null || this._stopPoint == undefined){
      alert("请先设置终点");
      return;
    }
    this._points.push(this._startPoint);
    if(this._wayPoints.length > 0){
      for(let i=0;i<me._wayPoints.length;i++){
        me._points.push(me._wayPoints[i]);
      }
    }
    this._points.push(this._stopPoint);
    return this._points;
  }
  function _success(text){
    this._responseResult = text;
    var json = JSON.parse(text);
    var lnglats = json.paths[0].points.coordinates;//(lng,lat)
    var latlngs = [];//(lat,lng)
    for(let j=0;j<lnglats.length;j++){
      var lnglat = lnglats[j];
      var latlng = [];
      latlng[0] = lnglat[1];
      latlng[1] = lnglat[0];
      latlngs.push(latlng);
    }
    var path = L.polyline.antPath(latlngs,{color: "#A52A2A", pulseColor: "#0000FF"});
    path.addTo(map);
    return text;
  }
  function _fail(code){
    alert('请求失败,' + 'Error code: ' + code);
    return code;
  }

</script>
</body>
</html>

进行可视化的时候用到了两个插件:一个是右键菜单,一个线动画

源文件下载地址:https://download.youkuaiyun.com/download/wml00000/10787367

GraphHopper在线API测试:https://explorer.graphhopper.com/

路径规划设置障碍区域:https://docs.graphhopper.com/#section/Limit-rules-to-certain-areas

参数:

{
  "points": [
    [
      11.539421,
      48.118477
    ],
    [
      11.559023,
      48.12228
    ]
  ],
  "snap_preventions": [
    "motorway",
    "ferry",
    "tunnel"
  ],
  "details": [
    "road_class",
    "surface"
  ],
  "profile": "car",
  "locale": "en",
  "instructions": true,
  "calc_points": true,
  "points_encoded": false,
  "ch.disable": true,
  "custom_model": {
    "speed": [
      {
        "if": "true",
        "limit_to": "100"
      }
    ],
    "priority": [
      {
        "if": "in_custom1",
        "multiply_by": "0"
      }
    ],
    "areas": {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "id": "custom1",
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [
                  11.547064,
                  48.119694
                ],
                [
                  11.549746,
                  48.119833
                ],
                [
                  11.549488,
                  48.118014
                ],
                [
                  11.547779,
                  48.117728
                ],
                [
                  11.547064,
                  48.119694
                ]
              ]
            ]
          }
        }
      ]
    }
  }
}

DVWA(Damn Vulnerable Web Application)是一个用于学习和练习网络安全的靶场平台,下面是DVWA的搭建过程: 1. 安装环境: - 首先,你需要将 DVWA 下载到你的 Web 服务器上。你可以在 GitHub 上找到 DVWA 的源码。 - 将下载好的源码放置在你的 Web 服务器根目录下。 2. 配置数据库: - 打开 DVWA 文件夹中的 `config` 子文件夹,将 `config.inc.php.dist` 文件重命名为 `config.inc.php`。 - 编辑 `config.inc.php` 文件,配置数据库连接信息。输入你的 MySQL 数据库主机名、用户名、密码和数据库名称,保存文件。 3. 初始化数据库: - 在浏览器中访问 DVWA 的 URL,如 `http://your-ip-address/dvwa`。 - 首次访问时,DVWA 会自动检测你的环境引导你初始化数据库。点击 "Create / Reset Database" 按钮进行初始化。 4. 设置安全性级别: - 初始化数据库后,DVWA 会跳转到登录页面。使用默认的管理员用户名和密码(admin/password)登录。 - 在 "DVWA Security" 标签页中,选择安全性级别。初始情况下,选择 `low` 级别以方便学习和实践。 5. 开始使用 DVWA: - 确认安全性级别后,在 DVWA 主界面上你将看到各种漏洞和挑战,比如 SQL 注入、跨站点脚本(XSS)、文件包含等。 - 选择你感兴趣的漏洞或挑战,按照提示进行测试和实践。 请注意,在搭建 DVWA 靶场之前,确保你已经具备了运行 Web 服务器和 MySQL 数据库的环境,且已经正确配置了相关的服务。此外,为了安全起见,建议在局域网或虚拟机环境中使用 DVWA 进行学习和实践。 希望以上信息能对你有所帮助!如果有任何其他问题,请随时提问。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值