基于路网的两点距离Matlab计算需求(不调用谷歌API)
无谷歌API的Matlab路网距离计算方案
要在Matlab中计算两点的路网距离且不依赖谷歌API,核心思路是使用开源路网数据构建图结构,再通过路径规划算法求解最短路径距离,具体步骤如下:
1. 获取目标区域的开源路网数据
使用OpenStreetMap(OSM)的开源路网数据,可通过两种方式获取:
- 手动下载:访问OpenStreetMap官网,框选目标区域(你的坐标位于巴西圣保罗附近),导出OSM格式文件;
- 代码调用Overpass API:编写简单脚本批量下载指定区域数据(非谷歌API,符合要求)。
2. 预处理路网为Matlab可识别的图结构
将OSM数据解析为节点(经纬度)和边(连接关系、长度),构建加权图:
2.1 自定义球面距离计算函数(替代Mapping Toolbox)
如果没有Matlab Mapping Toolbox,用Haversine公式实现经纬度距离计算:
function dist = haversine(lat1, lon1, lat2, lon2) % 转换为弧度 lat1 = deg2rad(lat1); lon1 = deg2rad(lon1); lat2 = deg2rad(lat2); lon2 = deg2rad(lon2); R = 6371000; % 地球平均半径(米) dlat = lat2 - lat1; dlon = lon2 - lon1; a = sin(dlat/2).^2 + cos(lat1).*cos(lat2).*sin(dlon/2).^2; c = 2*atan2(sqrt(a), sqrt(1-a)); dist = R*c; % 返回距离(米) end
2.2 解析OSM数据并构建图
% 读取下载好的OSM文件(示例:sao_paulo.osm) osmData = osmread('sao_paulo.osm'); % 提取路网节点与道路信息 nodes = osmData.Nodes; ways = osmData.Ways; % 筛选有效道路类型(可根据需求调整) validRoads = {'motorway', 'primary', 'secondary', 'tertiary', 'residential'}; roadWays = ways(ismember({ways.tags.highway}, validRoads)); % 建立节点ID到索引的映射 nodeIDs = [nodes.id]; nodeLats = [nodes.lat]; nodeLons = [nodes.lon]; nodeMap = containers.Map(nodeIDs, 1:length(nodeIDs)); % 构建图的边与权重(道路长度) edges = []; weights = []; for way = roadWays wayNodes = way.nodeIDs; % 遍历道路的节点对,添加双向边(路网为双向通行) for i = 1:length(wayNodes)-1 u = nodeMap(wayNodes(i)); v = nodeMap(wayNodes(i+1)); % 计算当前路段的长度 segLen = haversine(nodeLats(u), nodeLons(u), nodeLats(v), nodeLons(v)); edges = [edges; u v]; weights = [weights; segLen]; edges = [edges; v u]; weights = [weights; segLen]; end end % 创建Matlab加权图对象 G = graph(edges(:,1), edges(:,2), weights);
3. 匹配目标坐标到路网节点
将你提供的经纬度坐标匹配到最近的路网节点:
% 用户给定的目标坐标 lat1 = -22.8851078223344; lon1 = -48.4939312250395; lat2 = -22.8315940282463; lon2 = -48.4298167144681; % 找到离起点最近的路网节点 distToStart = haversine(lat1, lon1, nodeLats, nodeLons); [~, startNodeIdx] = min(distToStart); % 找到离终点最近的路网节点 distToEnd = haversine(lat2, lon2, nodeLats, nodeLons); [~, endNodeIdx] = min(distToEnd);
4. 计算路网最短路径距离
使用Matlab内置的Dijkstra算法求解最短路径及总距离:
% 计算最短路径与总距离 [~, totalDist] = shortestpath(G, startNodeIdx, endNodeIdx); % 输出结果(转换为公里) fprintf('路网最短距离:%.2f 公里\n', totalDist / 1000);
关键注意事项
- 确保OSM数据覆盖目标坐标区域,否则节点匹配会出现较大误差;
- 可根据需求调整
validRoads的道路类型,比如添加footway计算步行路网距离; - 如果坐标离路网过远,建议先通过插值或扩展路网覆盖范围优化结果。
内容的提问来源于stack exchange,提问作者Carlo Soares
相关产品推荐
相关产品推荐

