最近公司有个项目需要计算6000个点之间的驾车距离,第一时间想到的是利用Google的Distance Matrix API,但是免费Key每天只能计算2500个元素(元素 = 起点数量 * 终点数量),收费的话每1000个元素需要0.5刀,6000个点(接近3600w条边)基本就是1.8w刀。。。而且限制颇多,数据只允许本地缓存一个月,QPS限定100,每天查询元素上限10w,计算完客户早走了,基本不可用。

然后就想到了开(免)源(费)的OpenStreetMap(简称OSM),OSM是一个开源的地图库,可以在http://download.geofabrik.de/下载各国家地图包,数据还是比较全的。

有了地图数据,还需要一个寻路计算框架,找到了一个免费的库osm2po(http://osm2po.de/)

下载osm2po以后修改demo.sh或demo.bat的地图路径为你自己的pbf文件地址:

执行以后会启动一个Http服务器,默认地址http://localhost:8888/Osm2poService,打开就能看见地图界面了:

 
随便寻个路,效果还可以,国内路线看起来和高德地图差不多
 
Http访问方式只提供了这么些参数可以使用,并不是很完善,没有distance的选项,而且http的访问方式效率也不高,最好还是用Java API
 
计算两点间距离可以直接用官网示例的DefaultRouter,很简单。
多点距离在gis.stackexchange.com发现作者说有提供Distance Matrix API,emmm不错,看了下jar包的确是有一个TspDefaultMatrix的类,直接上代码:
public static void main(String[] args) throws Exception {
File graphFile = new File(args[0]);
Graph graph = new Graph(graphFile); // Somewhere in Graph
LatLon source = new LatLon(32.0452460989,118.8318873038);
LatLon target = new LatLon(31.8870800000,118.8300200000); // additional params for DefaultRouter
Properties params = new Properties();
params.setProperty("findShortestPath", "true");
params.setProperty("ignoreRestrictions", "false");
params.setProperty("ignoreOneWays", "false");
params.setProperty("heuristicFactor", "0.0"); // 0.0 Dijkstra, 1.0 good A* int[] vertexIds = findClosestVertexIds(graph, source, target);
Log log = new Log(Log.LEVEL_DEBUG).addLogWriter(new LogConsoleWriter());
TspDefaultMatrix matrix = new TspDefaultMatrix(graph, vertexIds, Float.MAX_VALUE, log, params); float[][] distances = matrix.getCosts();
for (int i = 0; i < distances.length; i++) {
for (int j = 0; j < distances.length; j++) {
System.out.println(distances[i][j]);
}
} graph.close();
} public static int[] findClosestVertexIds(Graph graph, LatLon... latLons) {
int[] vertexIds = new int[latLons.length];
for (int i = 0; i < latLons.length; i++) {
// if failed, return -1
vertexIds[i] = graph.findClosestVertexId(
(float) latLons[i].getLat(), (float) latLons[i].getLon());
}
return vertexIds;
}

算出来的结果21.01734公里,和高德地图完全吻合

公司项目第一个使用的地方是一个鸟不拉屎的非洲小国家,除了主干道基本都是人踩出来的小路,固定地点寻路成功率也达到了83%以上,失败的情况一般谷歌地图也没路。国内道路好太多,估计95%成功率是OK的。

实际测试1700个点,地图大小30M,生成有效数据240w条,堆内存使用6.5g,只用了60秒。
 
ps:距离相近的点,得到的地图块id可能相同,传入TspDefaultMatrix会error,要做一个去重的映射处理。

基于OpenStreetMap计算驾车距离(Java)的更多相关文章

  1. 【小o地图Excel插件版】计算两点间驾车路径,获取途径道路、驾车距离、耗时等信息

    小o地图Excel插件版:一款基于Excel软件开发的地图软件,提供基于Excel表格进行地理数据挖掘.地理数据分析.地图绘制.地图图表等功能的工具类软件.具有易用.高效.稳定的特点,能够满足地理数据 ...

  2. Spark Java API 计算 Levenshtein 距离

    Spark Java API 计算 Levenshtein 距离 在上一篇文章中,完成了Spark开发环境的搭建,最终的目标是对用户昵称信息做聚类分析,找出违规的昵称.聚类分析需要一个距离,用来衡量两 ...

  3. Spark 介绍(基于内存计算的大数据并行计算框架)

    Spark 介绍(基于内存计算的大数据并行计算框架)  Hadoop与Spark 行业广泛使用Hadoop来分析他们的数据集.原因是Hadoop框架基于一个简单的编程模型(MapReduce),它支持 ...

  4. SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

    熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...

  5. android中使用百度定位sdk实时的计算移动距离

    ;   //5秒刷新一次 private Handler refreshHandler = new Handler(){ //刷新界面的Handler public void handleMessag ...

  6. 一元建站-基于函数计算 + wordpress 构建 serverless 网站

    前言 本文旨在通过 快速部署一个 wordpress 网站到阿里云函数计算平台 这个示例来展示 serverless web 新的开发模式, 包括 FUN 工具一键初始化 NAS, 同步网站到 NAS ...

  7. PyTorch 实战:计算 Wasserstein 距离

    PyTorch 实战:计算 Wasserstein 距离 2019-09-23 18:42:56 This blog is copied from: https://mp.weixin.qq.com/ ...

  8. geolocation获取当前位置显示及计算两地距离

    获取当前经纬度 利用HTML5(以及基于JavaScript的地理定位API),可以很容易地在页面中访问位置信息,下面代码,就可以简单的获取当前位置信息: <!DOCTYPE html> ...

  9. 百度地图 获取两点坐标之间的驾车距离(非直线距离) c#

    百度接口了解: http://lbsyun.baidu.com/index.php?title=webapi/route-matrix-api-v2 起点与终点为多对多关系,如果你只想取两个坐标,那就 ...

随机推荐

  1. Python_正则表达式样例

    ''' 正则表达式是字符串处理的有力工具和技术,正则表达式使用预定义的特定模式去匹配一类具有共同特征的字符串, 主要用于字符串处理,可以快速.准确地完成复杂的查找.替换等处理要求. 正则表达式由元字符 ...

  2. debain 安装nodejs

    apt-get update -yapt-get install -y build-essential curl curl -sL https://deb.nodesource.com/setup_8 ...

  3. 通过VirtualBox安装Linux系统(CentOS7)

    本文目的:创建虚拟系统.在windows系统中通过虚拟工具VirtualBox创建一个虚拟系统CentOS. 备注:(1)版本如下:VirtualBox-5.2.12-122591-Win 和Cent ...

  4. 在JavaWeb项目中URL中字符串加密解密方案

    URL由来: 一般来说,URL只能使用英文字母.阿拉伯数字和某些标点符号,不能使用其他文字和符号.比如,世界上有英文字母的网址 “http://www.abc.com”,但是没有希腊字母的网址“htt ...

  5. tkinter中树状结构的建立(十四)

    树状结构的建立 import tkinter from tkinter import ttk wuya = tkinter.Tk() wuya.title("wuya") wuya ...

  6. 浅谈MySQL存储引擎-InnoDB&MyISAM

    存储引擎在MySQL的逻辑架构中位于第三层,负责MySQL中的数据的存储和提取.MySQL存储引擎有很多,不同的存储引擎保存数据和索引的方式是不同的.每一种存储引擎都有它的优势和劣势,本文只讨论最常见 ...

  7. JVM学习记录-垃圾收集器

    先回顾一下上一篇介绍的JVM中常见几种垃圾收集算法: 标记-清除算法(Mark-Sweep). 复制算法(Copying). 标记整理算法(Mark-Compact). 分代收集算法(Generati ...

  8. mac上如何解压和压缩rar文件

    许多喜欢mac的人都知道,这个os没有像win上winRAR或者hao123解压等类似软件,对于文件的压缩和解压很不方便,在下载rar的文件包之后就会束手无策,很是尴尬至极,为了避免这种情况,自己动手 ...

  9. ranker_worker.go

    package         outputDocs, numDocs := engine.rankers[shard].Rank(request.docs, request.options, req ...

  10. .net core使用Ocelot+Identity Server统一网关验证

    源码下载地址:下载 项目结构如下图: 在Identity Server授权中,实现IResourceOwnerPasswordValidator接口: public class IdentityVal ...