python生成matsim的plan文件

搞完network.xml文件,还有plan文件,config文件,做公共交通还有vehicle文件和schedule文件。今天来搞一下最简单的plan文件。
在这里插入图片描述



一、plan文件数据准备

每个agent都有自己的编号、起讫点、开始时间结束时间等,这些数据需要先生成出来。
由于路网中有的路线流量大,有的流量小,此处根据每个站点的连通情况不同,随机生成agent。
这里我用的是python+MATLAB。

  • 首先要有站点坐标文件,汽车站、火车站等:
    在这里插入图片描述
  • 利用python代码提取出文件中的站点编号、站点经纬度:
#将osm站点集合的文件,有用数据提取到txt中
import xml.etree.ElementTree as ET
tree = ET.parse('facilities.xml')#输入xml文档树
print(type(tree))#xml.etree.ElementTree.ElementTree
root = tree.getroot()#root是根元素
print(type(root))#xml.etree.ElementTree.ElementTree
print(root.tag) #notes
with open("facilities.txt","w")as f:
    for index,child,in enumerate(root):
        f.write('{0}'.format(child.attrib))
        f.write('\n')  
  • 去掉无用字符,保存成逗号分隔的txt文件格式:
    在这里插入图片描述
  • 将经纬度坐标转换成平面地理坐标系:(用matlab转换)
%% 转化坐标系,需要地理坐标矩阵xy,是上图的后两列,第一列要经度,第二列要纬度。
%MATLAB程序实现经纬度转换成平面尔坐标:
M_PI=3.14159265358979323846;
L = 6381372 * M_PI * 2; %地球周长  
W = L; % 平面展开后,x轴等于周长  
H = L / 2; % y轴约等于周长一半  
mill = 2.3; % 米勒投影中的一个常数,范围大约在正负2.3之间  
%xy
n=size(xy,1);
%lon=120.7015202;%经度
%lat=36.37423;%纬度
new_xy=[];
XY=[0,0];
for i =1:n
    lon=xy(i,1);
    lat=xy(i,2);
    x = lon * M_PI / 180; % 将经度从度数转换为弧度  
    y = lat * M_PI / 180; %将纬度从度数转换为弧度  
    y1 = 1.25 * log(tan(0.25 * M_PI + 0.4 * y)); % 米勒投影的转换  
    % 弧度转为实际距离  
    dikaerX = (W / 2) + (W / (2 * M_PI)) * x ; %笛卡尔坐标x
    dikaerY = (H / 2) - (H / (2 * mill)) * y1 ;%笛卡尔坐标y
    new_xy(i,1)=dikaerX;
    new_xy(i,2)=dikaerY;
    XY=[XY;new_xy(i,1),new_xy(i,2)];
end

生成的XY就是平面坐标系坐标。
至此,我们得到了站点的编号以及坐标。下一步需要根据站点坐标,对agent随机生成初始位置。

  • 生成每个agent的起讫点坐标
    需要的数据为站点的编号及平面坐标facilities,输出的数据为500个agent的起讫点坐标xy_agent。
%plan数据处理
%% 生成agent的起讫点编号
%思路:随机生成站点处的agent的od对,500个agent。
clear
load('plan_data.mat')
n=500;
[s,~]=size(facilities);
for i=1:n
    f=facilities(:,1)';
    prob(1:s)=(1/s);
    se(i,1)=randsrc(1,1,[f;prob]);
    f(find(f==se(i,1)))=[];
    prob(1:s-1)=(1/(s-1));prob(s)=[];
    se(i,2)=randsrc(1,1,[f;prob]);
end
save('plan_data.mat','facilities','se','n')%其中,n为agent的个数,facilities为站点的编号、横坐标、纵坐标,se为500个agent的起讫点编号。
%randsrc(m,n,[alphabet; prob]); %从alphabet集合中生成m行n列的数,prob是概率,注意是分号
%% 生成agent的起讫点坐标
clear
load('plan_data.mat')
[px,~]=size(se);
xy_agent=[0 0 0 0];
for i=1:px
    from=(find(facilities(:,1)==se(i,1)));
    to=(find(facilities(:,1)==se(i,2)));
    xy_agent=[xy_agent;facilities(from,2),facilities(from,3),facilities(to,2),facilities(to,3)];
end
xy_agent(1,:)=[];
save('plan_data.mat','facilities','se','n','xy_agent')%其中,xy_agent为500个agent的起点xy坐标、讫点xy坐标。

将数据xy_agent另存到新的plan_finish.csv文件就可以了。

  • 其他数据
    完整的plan文件还需要end_time,start_time等(如下图),我的项目end_time是统一的固定时刻,其他的数据也不重要,所以不需要专门处理这些数据。
    在这里插入图片描述

二、将数据转化为xml文件格式

就像搭积木一样,把数据搭建成xml格式。
python代码:

#将数据转化为xml文件中
#生成plan
import csv
with open('plan_finish.csv','r')as f:
    reader = csv.reader(f)
    line_count=0
    line_count=0
    #  rows=[row for row in  reader]
    #  print(rows[0])
    with open('plan_finish.txt','w')as f:
        for row in reader:
            f.write('   <person id="'+'{0}'.format(row[0])+'">'+'\n')
            f.write('       <plan selected="yes">'+'\n')
            f.write('           <act type="h" x="'+'{0}'.format(row[1])+'" y="'+'{0}.format(row[2])'+'" end_time="8:00:00"/>'+'\n')
            f.write('           <leg node="car" dep_time="8:02:00" trav_time="03:00:00" arr_time="11:00:00">'+'\n')
            f.write('           </leg>'+'\n')
            f.write('           <act type="w" x="'+'{0}.format(row[3])'+'" y="'+'{0}.format(row[4])'+'" start_time="11:00:00"/>'+'\n')
            f.write('       </plan>'+'\n')
            f.write('   </person>'+'\n')
            line_count += 1          

输出结果是这样的:
在这里插入图片描述
改一下头尾,就得到完整的plans啦!
在这里插入图片描述


又一个文件搞完了hooray!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值