(三)关于osm格式文件与sumo中的net文件对比解读

之前我们说过osm格式文件拥有四个主要元素:其中包括node、way、relation和tag。

那么从osm格式文件映射到net文件中,必然会存在一些对应关系。

1.首先我们来看一下关于节点node上的对应关系。在sumo的net文件中,并不存在node元素,其对应存在的是junction(路口)。

从一个实际例子入手:

.osm格式文件:

 <node id="2473907617" visible="true" version="2" changeset="81818043" timestamp="2020-03-05T10:35:01Z" user="XD346" uid="4892967" lat="22.7947984" lon="113.9483788"/>

.net.xml文件:

<junction id="2473907617" type="priority" x="896.06" y="1728.27" incLanes="239609617#3_0 -239609617#4_0 778519562#1_0" intLanes="……" shape="……"> <……>

我们可以发现:

1.节点编号没变,这说明原本的node元素映射到net文件中时,变为了junction元素。

2.但是原本在.osm格式文件中的经纬度坐标在.net.xml文件中变成了XY坐标

查询之后了解到了原因:SUMO中采用的是笛卡尔坐标,如果原始路网未使用笛卡尔坐标和/或度量坐标,则在导入时,netconvert会投影网络,而在上一节我们了解过,osm路网中采用的是大地地理坐标。

2.其次再来看一下osm格式文件中的way元素对应成了什么。

答案是edge。

从一个实际例子入手:

.osm格式文件:

<way id="778519562" visible="true" version="4" changeset="142277965" timestamp="2023-10-07T17:20:37Z" user="Obanazawa Kuri" uid="17453820">   <nd ref="7266018619"/>   <……>  <tag k="highway" v="secondary"/>   <tag k="name" v="圳美一路"/>   <tag k="oneway" v="yes"/>  </way>

.net.xml文件:

<edge id="778519562#0" from="7266018619" to="10995087876" priority="11" type="highway.secondary" spreadType="center"> <lane id="778519562#0_0" index="0" disallow="tram rail_urban rail rail_electric rail_fast ship" speed="27.78" length="119.47" shape="833.29,1966.82 863.70,1851.28"/> </edge>

我们可以发现:

1.映射到net文件中时,way与edge的ID几乎是一样的,但是#后面出现的数字代表了什么?

这是由于sumo生成net文件时,会自动将路段进行打断,分成第0段,第1段,第2段……

而osm格式文件本身的道路是没有打断过,这也解释了为什么从openstreetmap中一开始得到的路网,会超出用户想要的边界之外了。因为没有打断,所以你明明只截了一部分,但它就是会把这条路都下载给你……

‘#0’:路网文件通过节点将道路打断后,对该道路上的各条路段进行编号

3.接着看relation:

我反反复复看net文件也没找到一个完全对的上的元素,只有connection(道路转向设置)从定义上来说在一定程度上也展现了路段之间的关系,然而真的对比起来又会发现毫无关系……(如果对这点有研究的小伙伴欢迎和我讨论~)

从一个实际例子入手:

.osm格式文件:

<relation id="14960658" visible="true" version="1" changeset="129642624" timestamp="2022-12-02T12:22:24Z" user="Claudius Henrichs" uid="18069">   <member type="node" ref="10228156815" role=""/>   <……>   <tag k="name" v="圳美"/>   <tag k="name:en" v="Zhenmei"/>   <tag k="public_transport" v="stop_area"/>   <tag k="type" v="public_transport"/>  </relation>

.net.xml文件:

<connection from="1024772868#1" to="1024772868#2" fromLane="0" toLane="0" via=":9449350154_5_0" dir="s" state="="/>

从关系上看两种格式文件:两者描述的关系并不一致!

考虑原因:.osm文件描述地图中路段、节点等元素的关系,从而反映地理信息相关关系。 .net.xml文件映射到SUMO当中时,地理信息全部消失,因此其只展现道路转向,车道连接的关系信息。

tag(标签)信息在.net.xml文件也随之消失,所以后面我就不介绍tag了。

4.那么我们用openstreetmap和sumo里的图进行对比看看:

从节点上看:节点已被全部打断,并用红色点进行表示

从路段上看:

1.建筑物的边界线消失(但这只是在路网文件中没有,因为我之前导入过地形文件,所以在仿真文件中存在)

2.路段上的车道已区分好

3.中央分隔带的道路在路网中被隔开

4.根据路网中道路的不同服务类型,通过形状、灰度进行划分

<think>好的,我现在要帮用户完成基于决策树的交通信号灯优化模型的毕业设计。用户需要利用SUMO仿真软件生成数据,并编写TraCI接口的代码来收集所需数据。首先,我需要理解用户的需求。 用户提供的路网文件看起来是标准的SUMOnet.xml文件,但具体结构没有详细给出。不过,不管路网的具体结构如何,TraCI接口的代码结构应该是类似的。用户需要的数据可能包括交通流量、车辆等待时间、信号灯状态等,这些数据将用于训练决策树模型。 接下来,我需要考虑如何通过TraCI获取这些数据。通常,在SUMO仿真中,每个交通信号灯(junction)都有其状态,比如红灯、绿灯等。车辆的等待时间可以通过检测车辆在接近路口时的速度或停止时间来计算。此外,车流量可以通过统计每个车道上的车辆数来获得。 首先,用户需要安装SUMO并确保TraCI库可用。然后,编写Python脚本,连接到SUMO的仿真进程,并在每个仿真步骤中收集数据。可能需要的数据包括: 1.当前信号灯的状态和相位持续时间。2. 各车道的车辆数量。 3.车辆的等待时间(例如,车辆速度低于某个阈值的时间)。 4.车辆排队长度(即停止的车辆数)。 数据收集后,可以保存为CSV文件,方便后续处理和分析。 在代码实现上,需要启动SUMO仿真,连接到TraCI,然后在每一步循环中提取所需信息。例如,使用traci.trafficlight.getPhase()获取当前相位,traci.lane.getLastStepVehicleNumber()获取车道车辆数,traci.vehicle.getSpeed()来检测车辆是否在等待。 需要注意的是,用户可能需要根据实际路网的结构调整车道ID和信号灯ID。例如,用户的路网可能有不同的junction ID,需要正确指定这些ID才能获取正确的数据。 另外,数据收集的频率(每个仿真步骤)可能会影响数据量和处理速度,需要根据仿真时间步长和需求来调整。数据的存储结构也需要合理设计,确保每个时间步的数据能够正确关联。 可能遇到的问题包括TraCI连接失败、错误的ID导致数据获取失败,或者数据收集不全面。因此,代码中需要加入异常处理,或者在运行前检查路网中的元素ID是否正确。最后,用户可能需要运行多次仿真,调整交通流量或信号灯参数,以生成足够多样化的数据供模型训练。因此,代码可能需要支持不同的仿真配置或场景。</think>是通过TraCI接口获取交通信号灯优化所需数据的完整Python代码实现: ```python import traci import csv import os import time from datetime import datetime # SUMO环境配置 sumo_binary = "sumo-gui" # 或使用"sumo"进行无界面运行 sumocfg_file = "your_config.sumocfg" port = 8873 # 数据存储配置 output_dir = "simulation_data" os.makedirs(output_dir, exist_ok=True) filename = f"tl_data_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv" # 初始化数据采集参数 simulation_steps = 3600 # 仿真时长(秒) data_interval = 30 # 数据采集间隔(秒) current_interval = 0 # 交通灯信息(需要根据实际路网修改) tl_ids = ["J0", "J1"] # 信号灯ID列表 lane_mapping = { # 各方向车道映射 "J0": {"north": ["lane0_0", "lane1_0"], "south": ["lane2_0", "lane3_0"], "east": ["lane4_0", "lane5_0"], "west": ["lane6_0", "lane7_0"]}, "J1": {...} } # 创建CSV文件并写入表头 with open(os.path.join(output_dir, filename), 'w', newline='') as f: writer = csv.writer(f) header = [ 'timestamp', 'tl_id', 'phase', 'phase_duration', 'north_flow', 'south_flow', 'east_flow', 'west_flow', 'north_queue', 'south_queue', 'east_queue', 'west_queue', 'avg_wait_time' ] writer.writerow(header) def get_queue_length(lanes): """计算指定车道的排队长度""" queue_count = 0 for lane in lanes: vehicles = traci.lane.getLastStepVehicleIDs(lane) for veh in vehicles: if traci.vehicle.getSpeed(veh) < 0.1: # 速度低于0.1m/s视为排队 queue_count += 1 return queue_count def get_wait_time(lanes): """计算平均等待时间""" total_wait = 0 count = 0 for lane in lanes: vehicles = traci.lane.getLastStepVehicleIDs(lane) for veh in vehicles: total_wait += traci.vehicle.getAccumulatedWaitingTime(veh) count += 1 return total_wait / count if count > 0 else 0 def collect_tl_data(tl_id): """采集单个交通灯的数据""" data = {} # 基础信息 data['timestamp'] = traci.simulation.getTime() data['tl_id'] = tl_id data['phase'] = traci.trafficlight.getPhase(tl_id) data['phase_duration'] = traci.trafficlight.getPhaseDuration(tl_id) # 车道流量数据 directions = ['north', 'south', 'east', 'west'] for direction in directions: lanes = lane_mapping[tl_id][direction] # 流量统计 data[f'{direction}_flow'] = sum( [traci.lane.getLastStepVehicleNumber(lane) for lane in lanes] ) # 排队长度 data[f'{direction}_queue'] = get_queue_length(lanes) # 平均等待时间 all_lanes = [l for d in lane_mapping[tl_id].values() for l in d] data['avg_wait_time'] = get_wait_time(all_lanes) return data # 启动SUMO仿真 traci.start([sumo_binary, '-c', sumocfg_file, '--remote-port', str(port)]) try: while traci.simulation.getTime() < simulation_steps: traci.simulationStep() current_time = traci.simulation.getTime() # 按间隔采集数据 if current_time >= current_interval: for tl_id in tl_ids: tl_data = collect_tl_data(tl_id) # 写入CSV文件 with open(os.path.join(output_dir, filename), 'a', newline='') as f: writer = csv.writer(f) writer.writerow([ tl_data['timestamp'], tl_data['tl_id'], tl_data['phase'], tl_data['phase_duration'], tl_data['north_flow'], tl_data['south_flow'], tl_data['east_flow'], tl_data['west_flow'], tl_data['north_queue'], tl_data['south_queue'], tl_data['east_queue'], tl_data['west_queue'], tl_data['avg_wait_time'] ]) current_interval += data_interval except Exception as e: print(f"仿真异常终止: {str(e)}") finally: traci.close() ``` 代码解释: 1. **初始化配置**:设置SUMO执行路径、配置文件和数据存储路径 2. **数据采集函数**: - `get_queue_length()`:通过检测车辆速度计算排队长度 - `get_wait_time()`:统计车辆累计等待时间 - `collect_tl_data()`:采集单个信号灯的完整数据 3. **主循环**: - 按设定时间步长推进仿真 - 定期采集各信号灯数据 - 将数据写入CSV文件 需要准备的工作: 1. 根据实际路网修改`tl_ids`和`lane_mapping` 2. 创建对应的sumocfg配置文件 3. 调整数据采集间隔和仿真时长 建议采集的数据维度: - 时间戳 - 信号灯当前相位 - 各方向车流量 - 排队长度 - 平均等待时间 - 相位持续时间
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值