TransCAD公交线路与站点设置:路线系统与物理站点全解析
简介TransCAD是常用交通规划软件设置公交线路与站点是公交建模的核心操作。这份PDF教程面向交通规划师、交通管理研究者及高校学生系统讲解公交线路与站点设置全流程从创建路网与分区层开始逐步完成路线系统层的建立、道路网络的生成再利用最短路径法绘制公交线路最后分别设置路线站点和物理站点。内容特别对共用站点的自动识别、“Ignore”与确认操作、以及物理站点与路线站点的关联关系等易错细节也给出了说明。资源为1个PDF文档大小341KB文字简洁精炼配有对话框截图和参数解释适合边看边跟着操作。无论用于课程学习还是实际项目都可作为参考手册。目前已有411人学习对于正在使用TransCAD开展公交网络规划项目的读者可快速掌握关键设置方法减少上手与试错时间。1. 把公交线路和公交站点拆成“路线”与“物理位置”两层在 TransCAD 里做公交线路和公交站点设置最容易走偏的地方不是画线而是没理解路线系统Route System是一种容器它同时持有公交线路、路线站点、物理站点三层数据后两层之间还存在自动关联。一条线路上放置的路线站点会被系统自动登记到物理站点表中而单独放置的物理站点只登记在自己那张表里。这个设计直接影响共线识别、换乘统计和公交分配时站点匹配也是道路交通规划项目中反复核对数据的根源。本文按路网准备、网络创建、线路生成、站点放置、数据核对五个环节展开适合正在建公交线网模型、做公交分配与站点 OD 的工程师照着复现一遍。2. 路网、分区层与路线系统层的参数设计2.1 先落路网和分区层路网层必须是线层公交线路走向完全由它决定分区层通常为面层承载发生吸引量。原文把这两层放在第一步是因为后面的网络和线路都挂在路网层上分区层作为外部参照使用。实际项目中常见做法是File 菜单下新建 Geographic File 时选择线层类型导入道路中心线字段至少包含道路 ID、长度 Length分区层导入交通小区面字段至少包含 ZoneID 和面积属性。两层坐标系必须一致否则后续放置站点时会出现点位偏离道路的情况最短路径计算也会因为几何交叉错误而绕行。路网层和分区层建立后先不要急着做路线系统。打开路网层的 Dataview检查道路线段在交叉口处是否真正相交。很多人用 CAD 转来的路网两条道路在交叉口只是视觉上相交并没有生成节点这种情况下 TransCAD 无法把路径从一条路转到另一条路。常见做法是先用地理分析工具对路网做一次相交处理再进入下一步。分区层则要注意 ZoneID 不能重复公交分配时小区编号和站点编号会混在一起用重复会导致结果串位。2.2 New Route System 参数怎么填在新建文件时选择 Route System点 OK 后进入 New Route System 对话框。这里核心参数是 Based on 下拉列表它决定了路线系统挂在哪一层上。实际建模中很多人选错成面层或者节点层结果后面画线路时系统提示无法投影到路网。正确做法是选择已经建好的路网线层同时勾选 Route Stops 和 Physical Stops并分别填入这两层的名称。参数含义配置建议Layer Name路线系统名称用“Bus_路线_年份”命名如 Bus_Route_2024Based on路线系统基于的线层必须选路网线层不要选分区面层或节点层Route Stops是否创建路线站点层勾选命名如 RouteStopsPhysical Stops是否创建物理站点层勾选命名如 PhysStops为什么不省掉物理站点层公交分配时TransCAD 需要知道乘客在哪条道路上、哪个具体位置候车。物理站点提供绝对位置路线站点提供线路停靠关系。若只勾选 Route Stops路线站点表会自动生成但缺少独立的路网物理位置表遇到两条线路共用一个站台时系统无法判断是否为同一位置。勾选两层之后路线系统会自动维护两张点表的主从关系这就是后面讲共用站点和物理站点统计差异的基础。这里的两个层名建议用前缀区分比如 RouteStop 和 PhysStop避免在后续 Dataview 操作中混淆。2.3 建完路线系统后先做两件检查路线系统创建完成后第一件事是打开 Dataview确认路线系统基于的路网层是否正确。第二件事是确认两张站点表已经被创建为点层。TransCAD 工程内的数据表需要导出一份 Shapefile 后再用脚本读取检查这样能快速发现图层类型错误。下面这段 Python 代码可以同时检查两个站点层的几何类型和记录数import geopandas as gpd for name in [RouteStops, PhysicalStops]: gdf gpd.read_file(f{name}.shp) geo_type gdf.geom_type.iloc[0] if len(gdf) else None print(f{name}: {geo_type}, 记录数{len(gdf)})这段代码的逻辑是分别读取 RouteStops 和 PhysicalStops 两个 Shapefile取出第一条记录的几何类型并统计记录数。如果输出类型是 None 且记录数为 0说明空表创建成功还没有数据是正常的如果输出类型是 LineString说明创建路线系统时站点层选错了基础图层需要返回重新创建。参数说明里geom_type.iloc[0]取出第一条记录的几何类型len(gdf)返回要素总数。对于空表直接取第一条记录会报错所以先用if len(gdf)做判断输出 None 而不是中断脚本。3. 网络创建与线路走向阻抗字段决定公交线路怎么走3.1 建网前先检查路网连通性在路网层执行 Networks/Paths 下拉菜单中的 Create即可建立网络。但很多人第一步就报“Shortest Path 找不到路径”根源往往不是算法问题而是路网有断头或交叉口没打断。建网前建议先做四个检查路网是否有悬挂端点交叉口处线段是否真正相交单行线方向字段是否齐全是否有可用的阻抗字段。这四个检查里悬挂端点最容易被忽略。可以用一段 Python 脚本对路网做快速检查统计每条线段的首尾端点找出只出现一次的端点。这些就是悬挂点说明路网某处断开了。import geopandas as gpd from shapely.geometry import Point roads gpd.read_file(road.shp) counts {} for line in roads.geometry: for coord in [line.coords[0], line.coords[-1]]: pt Point(round(coord[0], 6), round(coord[1], 6)) counts[pt] counts.get(pt, 0) 1 dangling [pt for pt, c in counts.items() if c 1] print(悬空端点数:, len(dangling))这段代码把每条线段的起点和终点作为键存入字典值累加出现次数。某个端点只出现一次说明它只连接了一条线段路网在这里断开。round(coord[0], 6)是为了避免浮点精度导致同一个几何点被当成两个点统计。输出悬空端点数不为 0 时先在 TransCAD 里用选择工具高亮这些端点把断裂处连接起来再重新 Create 网络。常见做法是给路网做一次端点捕捉或拓扑处理然后再进入建网流程。3.2 创建网络时的方向与阻抗设置执行 Create 后TransCAD 会根据线层自动生成节点层。关键在阻抗字段的选择长度字段直接按几何长度累加适合简单校验如果线路运营时间则需要一个时间字段。没有现成时间字段时先在线层 Dataview 中新建字段 Time用公式Time Length / Speed * 60计算Length 单位为公里Speed 单位为公里/小时得到分钟数。方向字段用于设置单行限制指定单向道路的方向字段后反向阻抗填一个很大的值比如 9999代表该方向禁行。常见误用是只有长度没有方向字段。这样设置的结果是单行线被当成双向通行公交线路走向会绕到禁行方向上去后续做公交分配时线路经过某些路段的时间明显偏离实际。另一个常见问题是使用直线距离做阻抗这会让线路生成时完全脱离路网站点跑到路外。建网时选择基于路网线层而不是分区面层可以避免这类问题。3.3 Editing Toolbox 中 New Route 的参数在路线系统层执行 Route Systems 菜单下的 Editing Toolbox打开工具箱点击新建线路按钮会弹出一个对话框。该对话框用于确定公交线路的设置方法和建立何种站点以及公交线路以何值为标准生成。原文采用最短路径法Shortest Path以长度最小为标准同时勾选可设置路线站点。实际项目中除了长度还可以选择时间或广义费用作为阻抗标准。参数作用推荐选择线路生成方法自动拟合走向或手动逐段绘制首条线用 Shortest Path阻抗标准决定最短路径的目标函数Length 适合简单校验Time 适合运营方案Route Stops是否同步创建路线站点勾选Physical Stops是否同步创建物理站点建议勾选操作上点击新建线路按钮在路网层单击公交线路的起点然后沿线移动到终点位置双击。双击终点后系统弹出 New Route Name 对话框填入线路名称比如 1 号线点 OK 后系统生成一条黑色公交线路此时工具箱中所有按钮被激活。这一步需要特别注意双击这个动作单击是继续采集中间点双击表示路径终点。如果没有弹出线路命名对话框说明上一步的路径计算没有完成返回检查网络是否正常生成。长度最小并不等于实际走向合理。Shortest Path 只认阻抗字段如果只按长度结果会偏向短而窄的小路。现实中公交线路应优先走主干道常见做法是把道路等级写入阻抗公式比如Time Length / (Speed * ClassFactor)等级越高系数越大让高等级道路更容易被选中。这个调整在 Create 网络之前就要完成否则再次生成线路时需要重新建网。4. 路线站点、物理站点与共用站点的放置规则4.1 先激活线路再放置路线站点放置站点的前提是线路处于激活状态。在工具箱中先点击线路选择工具再点击刚生成的公交线路线路变为黑色即为激活。此时点击站点放置工具在公交线路的任意位置单击系统弹出 Confirm 对话框询问是否在该位置创建路线站点。点 Yes 后弹出 Edit Physical Stop 对话框填入站点名称点 OK再点击一次确认工具站点便显示在图上。这里有一个容易误解的细节Confirm 对话框确认的是“在线路上建立路线站点”Edit Physical Stop 对话框确认的是“该站点的物理名称”。如果点 Yes 后不改名直接 OK系统会生成一个默认编号。后续做客流分析时站点名称全是编号很难对应到实际地名。建议在建站阶段就把站名、线路名、站点序号三个字段一次性填清楚。原文中“桃子湖”“新一佳”“岳麓南”这些名称对应的是真实路网位置的物理站点名。4.2 共用站点的两种处理Ignore 与 Pick Route两条公交线路共用一处站点时TransCAD 会弹出对话框询问是否让新线路使用该站。以原文为例设置 2 号线时线路穿过 1 号线的“桃子湖”和“新一佳”两个站点系统自动搜索到这两个站并询问。点击 Ignore表示该站不被 2 号线使用2 号线只经过不停靠点击 OK该站同时属于两条线路成为共用站。另一种场景是在两条线路的两个站点之间新增一个共用站。比如在“岳麓南”和“桃子湖”之间设置一个 1 号线和 2 号线共用的“师大南”站。此时点击站点位置后系统弹出 Pick Route 对话框需要拖选该站点位于的公交线路名称点 OK 完成。这个对话框的本质是给物理位置绑定线路停靠关系。场景操作入口对话框是否共用新线穿过既有站点在新线上点击已有站点位置系统询问是否供新线使用OK 共用Ignore 不共用两线之间新增共用站在两条线路之间点击空白位置Pick Route选择线路后共用共用站的路线站点记录会重复出现。“师大南”在 1 号线的 Route Stops 表中有一条记录在 2 号线的 Route Stops 表中也有一条记录但 Physical Stops 表中只有一条记录。很多人在 Dataview 里看到路线站点数量大于物理站点数量就以为是数据错误其实这是共用站点的正常表现。记住这一点第 5 章的统计逻辑就不会乱。4.3 物理站点的编辑开关点击工具箱中的 Route System Edit Options 按钮弹出对话框Stop Edit Type 中勾选 Physical Stops点 OK 后物理站点放置工具被激活。此时在需要设置物理站点的位置点击并输入名称即可完成。原文中的“中南北”和“二里半”就是两个独立物理站点。需要强调的是编辑模式必须手动切换。处于 Physical Stops 模式下放置站点只写入物理站点表不再同时生成路线站点。这意味着该物理站点没有绑定任何线路停靠关系只代表路网上的一个实际位置。实际项目中这种站点通常用于校核公交站台位置或者作为未开通线路的预留站点。建议一个物理位置只点击一次。如果在同一个位置重复放置两个物理站点虽然地理坐标相同但系统会认为是两个独立站点公交分配时出现两个站都被匹配的情况客流量被拆成两半统计结果很难解释。遇到这种情况优先在 Dataview 中按坐标排序查找重复点删除后重新编辑。5. 用 Dataview 和脚本核验站点统计逻辑5.1 两个 Dataview 的计数差异分别打开路线站点和物理站点的 Dataview。路线站点表里一条线路停靠一次就有一条记录两条线路共用站会出现两次物理站点表里一个位置只有一条记录。这是两个表最核心的区别。用原文数据演算两条公交线路共有 8 个路线站点位置其中 3 个站点被两条线路共用所以独立路线站点数为 8 减去 3等于 5 个。系统还单独设置了 2 个物理站点物理站点总数为 5 加 2等于 7 个。统计口径计算方式本例数值路线站点记录数含共用重复每条线路停靠数相加8共用站点数至少两条线路停靠的位置3独立路线站点数8 - 35单独物理站点数手动放置且未绑定线路2物理站点总数5 27当 Dataview 中物理站点总数比路线站点记录数少这是正常的差值就是共用重复部分。反过来如果物理站点表里出现了路线站点表中不存在的记录说明这些站点是单独放置的物理站点没有绑定任何线路。5.2 用脚本核对两表差异当路线系统和站点数量达到几十条线路时靠肉眼比对 Dataview 不现实。可以导出两份站点表的 Shapefile用脚本快速核对。这里假设两张表都有 stop_id 字段实际项目中以导出后的字段名为准。import geopandas as gpd route_stops gpd.read_file(RouteStops.shp) phys_stops gpd.read_file(PhysicalStops.shp) route_ids route_stops[stop_id].tolist() phys_ids phys_stops[stop_id].tolist() print(路线站点记录数:, len(route_ids)) print(路线站点独立个数:, len(set(route_ids))) print(物理站点唯一数:, len(set(phys_ids)))这段代码先读取两个站点的 Shapefile再把 stop_id 字段转成列表。len(route_ids)得到路线站点的总记录数包含共用站点的重复记录len(set(route_ids))得到去掉重复后的独立路线站点数len(set(phys_ids))得到物理站点的唯一数量。如果物理站点唯一数大于路线站点独立个数多出来的数字就是手动放置的物理站点数量。如果发现物理站点的 stop_id 有重复说明同一位置被放置了多次需要回到属性表统一编号。5.3 实际项目里怎么用这个规则在公交分配之前建议按这个顺序做一遍核验打开 Route System 的属性表检查 Route Stops 与 Physical Stops 的 stop_id 字段是否有空值对共用站确认每条线路的 RouteID 都已填写完整对单独物理站点核对它是否确实有线路停靠。如果发现某个物理站点在路线站点表中找不到对应记录说明它没有被任何线路使用公交分配时该站不会产生客流。把 stop_id 统一编号后再回到 Route Systems 中重新生成线路站对线、线对路网分配结果里的站点匹配就不会莫名少几个物理站点。本文还有配套的精品资源点击获取