GraphHopper调研笔记

news2024/11/16 21:47:21


一、 GraphHopper

GraphHopper是一种快速且内存有效的Java导航引擎,默认使用OSM和GTFS数据,也可导入其他的数据源。支持CH(Contraction Hierarchies)、A*、Dijkstra算法。

1、应用介绍

graphhopper有以下几种常见的地图应用:

(1) 把一个GPS点垂直投影到最近的道路上

(2)根据输入的两个GPS点进行路径规划,支持设置起点的离开方向和终点的到达方向

(3)根据一个GPS点和给定的时间范围给出等时圈的点

2、功能介绍

2.1 创建地图

2.1.1 示例代码

ghLoc是OSM格式的地图路径

cachePath是读取OSM地图之后的地图缓存,下次可以直接使用缓存中的地图

static GraphHopper createGraphHopperInstance(String ghLoc,String cachePath) {
        GraphHopper hopper = new GraphHopper();
        // OSM 文件路径
        hopper.setOSMFile(ghLoc);
        // 读取完OSM数据之后会构建路线图,此处配置图的存储路径
        hopper.setGraphHopperLocation(cachePath);
        hopper.setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest").setTurnCosts(false));
        hopper.importOrLoad();
        return hopper;
    }

2.2点投影到路上的Node

2.2.1 示例代码

        EncodingManager encodingManager = hopper.getEncodingManager();
        BooleanEncodedValue accessEnc = encodingManager.getBooleanEncodedValue(VehicleAccess.key("car"));
        DecimalEncodedValue speedEnc = encodingManager.getDecimalEncodedValue(VehicleSpeed.key("car"));

        // snap some GPS coordinates to the routing graph and build a query graph
        FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc);
        Snap snap = hopper.getLocationIndex().findClosest(24.48183200, 118.18120700, new 			                       DefaultSnapFilter(weighting, encodingManager.getBooleanEncodedValue(Subnetwork.key("car"))));
        System.out.println(snap.getClosestNode());
        BaseGraph baseGraph = hopper.getBaseGraph();
        NodeAccess nodeAccess = baseGraph.getNodeAccess();
        double lon = nodeAccess.getLon(4312);
        double lat = nodeAccess.getLat(4312);
        System.out.println(lon+","+lat+";");

2.3路径规划

2.3.1示例代码

public static void routing(GraphHopper hopper, String from, String to) {
        String[] fromPoint = from.split(",");
        double fromLon = Double.parseDouble(fromPoint[0]);
        double fromLat = Double.parseDouble(fromPoint[1]);
        String[] toPoint = to.split(",");
        double toLon = Double.parseDouble(toPoint[0]);
        double toLat = Double.parseDouble(toPoint[1]);

        // simple configuration of the request object
        GHRequest req = new GHRequest(fromLat, fromLon, toLat, toLon).
                // note that we have to specify which profile we are using even when there is only one like here
                        setProfile("car").
                // define the language for the turn instructions
                        setLocale(Locale.CHINA);
        GHResponse rsp = hopper.route(req);

        // handle errors
        if (rsp.hasErrors())
            throw new RuntimeException(rsp.getErrors().toString());

        // use the best path, see the GHResponse class for more possibilities.
        ResponsePath path = rsp.getBest();

        // 导航结果点位集合
        PointList pointList = path.getPoints();
        // 总距离 m
        double distance = path.getDistance();
        // 总耗时 ms
        long timeInMs = path.getTime();

        System.out.println("路线点位: ");

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < pointList.size(); ++i) {
            if (i > 0) {
                sb.append("; ");
            }
            sb.append(pointList.getLon(i));
            sb.append(',');
            sb.append(pointList.getLat(i));
            if (pointList.is3D()) {
                sb.append(',');
                sb.append(pointList.getEle(i));
            }
        }
        System.out.println(sb.toString()+"\n------------------------");
        System.out.println("总距离: " + distance + ", 总用时: " + timeInMs);


        Translation tr = hopper.getTranslationMap().getWithFallBack(Locale.CHINA);
        InstructionList il = path.getInstructions();
        // iterate over all turn instructions
        for (Instruction instruction : il) {
            System.out.println("distance " + instruction.getDistance() + " for instruction: " + instruction.getTurnDescription(tr));
        }
    }

测试类

public static void main(String[] args) {
        String osmFilePath = "D:\\work\\CODE\\soft2study/GraphHopper_study/xiamen.osm";
        //加载地图
        GraphHopper hopper = createGraphHopperInstance(osmFilePath);
        String from = "118.15531256,24.51429705";
        String to = "118.08894888,24.47891989";
        routing(hopper, from, to);
    }

2.4等时圈计算

2.3.1示例代码

2.3.2结果示例

官网的等时圈示例

在这里插入图片描述

厦门以软三为中心点 15分钟驾车的等时圈示例,红色为100m的网格端点,绿色为等时圈的点

在这里插入图片描述

3、graphhopper应用与公共交通

谷歌推出了通用公交数据标准GTFS,主要是使用固定的文本格式和字符对公交数据进行标准化

General Transit Feed Specification

它是一个可预见的中转站位置和时间的结构化数据列表。

3.1.组成元素

agency.txt (机构,运行商)必须
stops.txt (站点,出入口)必须 对应公交站点
routes.txt (路线)必须 对应公交线路
trips.txt (路趟----每一趟车)必须 对应公交时刻表

如果把route表示每一条线路,那么trip就是跑在每一个线路上的车。
比如同是地铁5号线,3点一班车,5点一班车,那么就是两个trip表示。还有上下行车次,区间车等等情况。

frequencies.txt (频率)可选

引入频率,更好的表示trip,如频率表示:7am~9am 每3分钟一趟车。而Trip直接引用frequency即可。

calendar.txt (日历)必须

日历的作用是定义trip的生效日期,比如一个trip规定一个车,在工作日是一个频率,在周末是另一个频率,日期参数就很有用了。

calendar_dates.txt (日历-日期)可选

日期的特殊情况-----节假日,在日期规定了每个工作日都是一个频率,但是偏偏周一是清明节(放假),那么这一天也是按照周末的频率来的。calendar_dates定义假期,当假期与calendar有重叠,会以calendar_dates为准。

stop_times.txt (停车-时间)必须

这是一个与trip相关的表,表示站点的到站时间,离站时间,上下车属性等等。

fare_rules.txt (票价-规定)可选

公交必定是要收费的,这个表规定收费规则。

fare_attributes.txt (票价-属性)可选

表示收费的具体规则对应的钱是多少。

shapes.txt (形状)可选

一般地图信息,都会存储一个形状信息,用于展示(渲染),形状是用经纬度点组成的数组来表示的。

transfers.txt (转车)可选

4、利用源码本地搭建graphhopper

下载源码,源码中有一个web项目,有一个Application

在这里插入图片描述

根据官网上的指导说明,需要增加两个参数,一个是server 一个是配置文件

public static void main(String[] args) throws Exception {
        args = new String[2];
        args[0] = "server";
        args[1]="config.yml";
        new GraphHopperApplication().run(args);
    }

重点是配置文件config.yml,下载的源码中有一个config-example.yml,复制重命名为自己的配置文件,我这里命名为config.yml

修改了地图的路径和缓存的路径

  # OpenStreetMap input file PBF or XML, can be changed via command line -Ddw.graphhopper.datareader.file=some.pbf
  datareader.file: "core/files/xiamen.osm"
  # Local folder used by graphhopper to store its data
  graph.location: target/isochrone-graph-cache

其中datareader.file 表示地图的路径,我这里用的osm的格式

graph.location 表示地图加载之后缓存到本地的路径

完成上面的配置之后,启动GraphHopperApplication,看到了graphhopper的图形

在这里插入图片描述在这里插入图片描述

看到了最下面的Started… 表示启动成功

在浏览器中输入:http://localhost:8989/

在这里插入图片描述

空白一大片,F12查看原因,发现是在国内请求OpenStreedMap失败的原因。

路径规划的API

http://localhost:8989/route?point=24.51429705,118.15531256&point=24.47891989,118.08894888&profile=car&type=json&points_encoded=false
API参数说明参考https://blog.csdn.net/haochajin/article/details/99963678
返回的结果示例:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/509691.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI 不会取代打工人,使用 AI 的人才会

一、被AI端掉饭碗之前&#xff0c;提升自己的硬核实力 AI工具带来了工业革命级别的效率提升&#xff0c;除了强大&#xff0c;更多的引发了打工人的集体焦虑&#xff1a;“我的活ai都能干了&#xff0c;那我做什么呢&#xff1f;” 当然&#xff0c;还有另一种更积极的解答&a…

C语言中变量的默认初始值

在对数组元素求和时&#xff0c;竟然离奇的发现错了&#xff0c;冲了一会儿浪之后才现在问题在这里 main函数代码&#xff1a; int main(void){int arr[5] {1,2,3,4,5};int res sum(arr,arr5);printf("%d",res); }求和函数&#xff08;利用双指针求的数组元素之和…

第8章 虚拟主机

第8章 虚拟主机 虚拟主机&#xff0c;就是把一台物理服务器划分成多个“虚拟”的服务器&#xff0c;这样我们的一台物理服务器就可以当做多个服务器来使用&#xff0c;从而可以配置多个网站。 Nginx提供虚拟主机的功能&#xff0c;就是为了让我们不需要安装多个Nginx&#xf…

2023年8月24-25日|2023中国绿色数据中心峰会

2023中国绿色数据中心峰会 会议背景 应对气候变化已经成为21世纪人类社会面临的紧迫挑战&#xff0c;推进绿色发展成为全球共识。2021年12月&#xff0c;国家发改委等四部门印发的《贯彻落实碳达峰碳中和目标要求推动数据中心和5G等新型基础设施绿色高质量发展实施方案》提出…

QT MD4 MD5 Sha1等几种加密方式

QT MD4 MD5 Sha1等几种加密方式 [1] QT MD4 MD5 Sha1等几种加密方式[2] qt MD5 和AES 加密一 、MD5 加密二、AES 加密和解密 [3] QT中sqlite数据库数据加密/混淆---MD5/SHA1/SHA2/SHA3&#xff08;1&#xff09;创建一个加密对象&#xff08;2&#xff09;放入要加密的数据&…

嘉立创EDA PDF文件的输出教程

在PCB生产调试期间&#xff0c;为了方便查看文件或者查询相关元件信息&#xff0c;会把PCB设计文件转换成PDF文件。下面介绍常规PDF文件的输出方式。 前期工作是需要在电脑上安装PDF阅读器&#xff0c;准备充足后按照以下步骤进行操作。 1&#xff09;执行菜单命令“导出-PDF…

企业财务管理为何需要数字化转型?

为什么企业财务管理需要数字化转型&#xff1f; 许多企业在推动各大业务部门进行数字化转型时&#xff0c;往往会忽略财务部门。然而&#xff0c;作为掌握公司核心资源与数据和推动企业数字化建设的部门&#xff0c;财务也应成为企业数字化转型的重要突破口。 这篇就用几个案…

用Leangoo领歌Scrum敏捷开发工具管理产品路线图?

那我们来看下&#xff0c;如何利用Leangoo管理产品路线图&#xff1f; 首先什么是产品路线图&#xff1f; 产品路线图是一个高层次的战略计划&#xff0c;它描述了产品在未来一段时间可能会如何发展和壮大。 产品路线图确保整个产品团队持续关注产品的目标&#xff0c;帮助产…

07-微服务部署2023系列-centos+docker部署nacos

1、创建nacos的数据库配置 1.1、创建数据库 1.2、创建用户nacos并授权数据库 参考 06 mysql 创建账户部分内容 1.3、执行数据库脚本 导入官方nacos sql语句。如果是历史有历史数据&#xff0c; 从历史数据sql导入 2、创建 bridge 网络并指定 IP 区间 2.1、创建自定义网络…

第十章 使用Samba或NFS实现共享文件

文章目录 第十章 使用Samba或NFS实现共享文件一、SAMBA文件共享服务1、SAMBA简介2、相关配置&#xff08;1&#xff09;、安装软件&#xff08;2&#xff09;、删除多余配置文件&#xff08;3&#xff09;、Samba服务验证方式 3、配置共享资源&#xff08;1&#xff09;、用于设…

认识 AbortController控制器对象 及其应用

参考文章1 参考文章2 一、什么是AbortController (abort 意为 中止/废弃) AbortController是一个控制器对象&#xff08;DOM API&#xff09;&#xff0c;可通过new构造函数的方式&#xff0c;生成控制器实例对象&#xff0c;根据需要终止/取消一个或多个Web请求/监听事件 通…

微信开发者工具突然打不开问题解决

今天微信小程序开发者工具 好好的在电脑里 突然就打不开了 这个问题已经上百度了 想必并不是很少遇到 可能是版本太旧 或者 其中依赖文件丢失 这个基本不用抱什么幻想 还是得重新装 先将快捷打开方式删掉 然后找到工具所在目录 把它删了 然后访问如下地址 https://mp.weixi…

日期时间选择器el-date-picker,限制可选范围,以后端接口某个时间字段为时间节点

哈喽 大家好啊 今天需要做一个时间选择器的限制&#xff0c;不然用户选择某个时间节点之前的时间 比如用户选择发货时间不允许早于收货时间&#xff08;来自后端接口&#xff09; picker-options当前时间日期选择器特有的选项参考下表object 首先申明一个时间可选对象 因为我…

黑马程序员-学成在线项目总结

黑马程序员-学成在线项目总结 收获 基础公共样式 清除默认样式&#xff0c;例如内边距、外边距、项目符号等等 设置通用样式&#xff0c;例如&#xff1a;文字样式 项目结构 注:多个css文件引入顺序&#xff0c;先清除&#xff0c;后设置 版心效果 许多网页整体都有版心居…

Java框架学习01(Spring框架)

1、什么是Spring框架&#xff1f; Spring 是一款开源的轻量级 Java 开发框架&#xff0c;旨在提高开发人员的开发效率以及系统的可维护性。 我们一般说 Spring 框架指的都是 Spring Framework&#xff0c;它是很多模块的集合&#xff0c;使用这些模块可以很方便地协助我们进行…

网络漏洞管理

网络漏洞是硬件、软件或流程中的漏洞或缺陷&#xff0c;可能威胁到网络的正常运行。漏洞会使您的业务和客户的敏感数据面临风险&#xff0c;导致黑客轻松进入、销售额下降、声誉损失和处罚。网络漏洞可以分为硬件、固件、软件和人类漏洞。如果这些实体中的任何一个没有得到适当…

关于Kerberos认证的一些攻击手法学习总结

Kerberos认证流程 前言 本文主要分享最近学习的关于域内Kerberos认证的一些攻击手法&#xff0c;以自我的理解为主&#xff0c;从原理理解切入到基本工具利用来阐述&#xff0c;个人的理解分析较为啰嗦&#xff0c;嫌太兀长的可以跳着看就好&#xff0c;还请各位谅解。如有错误…

唐毅:带领和数集团,做好科技成果与创新需求的“摆渡人”

近年来&#xff0c;人类已经进入有史以来科技创新爆发最密集最迅猛的大时代。 作为人工智能、区块链、交互技术、游戏引擎及数字孪生技术、综合智能网络、物联网等若干前沿科技领域陆续高速发展又碰撞聚变后形成的元宇宙&#xff0c;成为最具引领性的力量。在人工智能、物联网…

网安笔记06 数字签名基本概念

数字签名基本概念 R1:receiver确认、证实sender的签名&#xff0c;这个签名不能被伪造S:sender发送出签名的教习给receiver&#xff0c;不能否认他签发的消息R2:receiver堆收到的签名消息不能否认&#xff0c;收报认证T:第三方可以确认手法收发双方之间的消息传输&#xff0c;…

Django框架之视图HttpRequest对象

本文主要是记录视图的HttpRequest对象属性、方法及示例。 概述 服务器接受http请求后&#xff0c;会根据报文创建httpRequest对象&#xff0c;包含所有请求中必须的数据&#xff1b; 视图方法的第一个参数就是HttpRequest对象&#xff1b;Django创建对象后&#xff0c;调用视…