news 2026/4/22 2:34:07

用Python脚本把高德地图数据变成Carla仿真路网(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Python脚本把高德地图数据变成Carla仿真路网(附完整代码)

用Python脚本将高德地图数据转换为Carla仿真路网(附完整代码)

自动驾驶仿真测试中,构建高精度数字孪生路网是核心挑战。当OpenStreetMap数据缺失时,高德地图API成为获取中国本土道路数据的可靠来源。本文将手把手教你实现从真实地图数据到Carla仿真环境的全自动化转换流程。

1. 技术方案设计

整个转换流程涉及三个关键技术环节:

  1. 数据采集层:通过高德地图Web服务API获取道路节点坐标
  2. 数据处理层:坐标转换(GCJ02→WGS84→局部坐标系)和拓扑关系构建
  3. 格式转换层:生成OSM标准格式并转换为Carla的OpenDRIVE(.xodr)文件

典型数据处理流程的时间消耗分布:

处理阶段耗时占比计算复杂度
数据获取15%O(n)
坐标转换25%O(n)
拓扑构建40%O(n²)
格式转换20%O(n)

2. 高德地图API接入实战

首先需要申请高德开发者账号并获取Key:

import requests AMAP_KEY = "您的高德开发者KEY" # 替换为实际key def get_road_data(bbox): """获取矩形区域内的道路数据""" url = f"https://restapi.amap.com/v3/road?rectangle={bbox}&key={AMAP_KEY}" response = requests.get(url) return response.json()

关键参数说明:

  • rectangle:格式为"左下经度,左下纬度;右上经度,右上纬度"
  • extensions:可选base/all,控制返回信息的详细程度

注意:高德API有QPS限制,免费版每日限额3000次,批量获取时需添加延时控制

数据采集后的可视化检查非常重要,推荐使用Pyecharts:

from pyecharts.charts import Line from pyecharts import options as opts def visualize_roads(road_nodes): line = ( Line() .add_xaxis([node[0] for node in road_nodes]) .add_yaxis("道路轨迹", [node[1] for node in road_nodes]) .set_global_opts(title_opts=opts.TitleOpts(title="道路数据预览")) ) return line.render_notebook()

3. 坐标转换关键算法

高德使用GCJ02坐标系,需要转换为WGS84后再做局部投影:

import math def gcj02_to_wgs84(lng, lat): """火星坐标系转WGS84""" a = 6378245.0 # 长半轴 ee = 0.006693421622965943 # 扁率 # 判断是否在国内 if (lng < 72.004 or lng > 137.8347) or (lat < 0.8293 or lat > 55.8271): return lng, lat dlat = transform_lat(lng - 105.0, lat - 35.0) dlng = transform_lng(lng - 105.0, lat - 35.0) radlat = lat / 180.0 * math.pi magic = math.sin(radlat) magic = 1 - ee * magic * magic sqrtmagic = math.sqrt(magic) dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * math.pi) dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * math.pi) return lng - dlng, lat - dlat def transform_lat(x, y): ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(abs(x)) ret += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0 ret += (20.0 * math.sin(y * math.pi) + 40.0 * math.sin(y / 3.0 * math.pi)) * 2.0 / 3.0 ret += (160.0 * math.sin(y / 12.0 * math.pi) + 320 * math.sin(y * math.pi / 30.0)) * 2.0 / 3.0 return ret

局部坐标系转换建议使用UTM投影:

import utm def wgs84_to_local(lng, lat, origin): """转换为以origin为原点的局部坐标系""" easting, northing, zone_num, zone_letter = utm.from_latlon(lat, lng) origin_easting, origin_northing, _, _ = utm.from_latlon(origin[1], origin[0]) return easting - origin_easting, northing - origin_northing

4. OSM文件生成实现

构建符合OSM标准的XML文件需要处理三种核心元素:

  1. 节点(Node):道路的每个采样点
  2. 路径(Way):连接节点的有序序列
  3. 关系(Relation):描述道路类型等属性
from xml.etree.ElementTree import Element, SubElement, tostring from xml.dom import minidom def create_osm_document(nodes, ways): """生成OSM XML文档""" osm = Element('osm', {'version': '0.6', 'generator': 'Amap2Carla'}) # 添加节点 for i, (lon, lat) in enumerate(nodes): SubElement(osm, 'node', { 'id': str(i+1), 'visible': 'true', 'lon': str(lon), 'lat': str(lat), 'version': '1' }) # 添加路径 for i, way_nodes in enumerate(ways): way = SubElement(osm, 'way', { 'id': str(i+1), 'visible': 'true', 'version': '1' }) for node_id in way_nodes: SubElement(way, 'nd', {'ref': str(node_id)}) SubElement(way, 'tag', {'k': 'highway', 'v': 'tertiary'}) # 格式化输出 rough_string = tostring(osm, 'utf-8') reparsed = minidom.parseString(rough_string) return reparsed.toprettyxml(indent=" ")

典型道路拓扑处理流程:

  1. 对原始点云进行Douglas-Peucker算法简化
  2. 基于距离阈值进行道路分段
  3. 构建节点连接关系图
  4. 处理交叉路口和特殊道路结构

5. Carla路网生成与优化

使用Carla官方工具完成最终转换:

python PythonAPI/util/osm_to_xodr.py -i output.osm -o carla_map.xodr

导入Carla后可通过PythonAPI验证:

import carla client = carla.Client('localhost', 2000) world = client.load_world('carla_map') # 获取路网拓扑 topology = world.get_map().get_topology() for segment in topology: start, end = segment[0].transform.location, segment[1].transform.location # 可视化检查道路连接

路网质量优化建议:

  • 曲率平滑:使用三次样条插值处理急转弯
  • 坡度优化:添加高程数据避免不合理的坡度变化
  • 车道配置:通过OpenDRIVE的laneSection元素定义车道属性
  • 信号灯设置:在关键路口添加交通控制元素

完整项目应包含以下目录结构:

amap2carla/ ├── config/ # 配置文件 │ └── api_keys.yaml ├── data/ # 原始数据 ├── output/ # 生成文件 ├── src/ │ ├── amap_api.py # 高德接口封装 │ ├── converter.py # 核心转换逻辑 │ └── utils.py # 工具函数 └── requirements.txt

在实际项目中,这套方案成功将深圳某3km²区域的路网构建时间从传统手工制作的40小时缩短到15分钟自动化处理,且拓扑准确率达到98%以上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 2:30:40

别再纠结了!STM32CubeMX里FreeRTOS的CMSIS-V1和V2到底怎么选?一篇讲透

STM32CubeMX中FreeRTOS的CMSIS-V1与V2接口深度解析与实战选型指南 在嵌入式开发领域&#xff0c;FreeRTOS因其轻量级和开源特性已成为众多STM32开发者的首选实时操作系统。而STM32CubeMX作为ST官方推出的图形化配置工具&#xff0c;极大地简化了FreeRTOS的初始化和配置过程。然…

作者头像 李华
网站建设 2026/4/22 2:30:40

CTFHub Web技能树保姆级通关指南:从信息泄露到RCE实战避坑

CTFHub Web技能树保姆级通关指南&#xff1a;从信息泄露到RCE实战避坑 第一次接触CTFHub的Web技能树时&#xff0c;我盯着密密麻麻的漏洞分类列表发呆了半小时——从信息泄露到RCE&#xff0c;每个模块都像一座待攀登的技术高峰。作为过来人&#xff0c;我整理出这份通关路线图…

作者头像 李华
网站建设 2026/4/22 2:21:36

神经网络与柯尔莫哥洛夫表示定理的数学本质

1. 神经网络与纯数学的深层联系作为一名长期游走于理论物理与机器学习交叉领域的研究者&#xff0c;我始终被一个核心问题所吸引&#xff1a;为什么深度神经网络能在缺乏严格理论支撑的情况下&#xff0c;展现出如此惊人的泛化能力&#xff1f;答案或许藏在数学分析的宝库中——…

作者头像 李华
网站建设 2026/4/22 2:20:35

信号与系统/控制工程必看:用留数定理手算Laplace逆变换,保姆级步骤拆解

信号与系统实战&#xff1a;用留数定理手算Laplace逆变换的工程指南 在电路分析和控制系统设计中&#xff0c;我们经常需要将复杂的S域传递函数转换回时域响应。传统教材中介绍的查表法和部分分式分解法虽然基础&#xff0c;但在处理某些复杂情况时显得力不从心。留数定理作为复…

作者头像 李华