Skip to content

Commit 82df514

Browse files
authored
Merge pull request #115 from nmpeterson/master
Fix busway handling for base year transit network generation
2 parents bcc8c74 + 859bd4a commit 82df514

4 files changed

Lines changed: 81 additions & 66 deletions

File tree

MHN.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
'''
33
MHN.py
44
Author: npeterson
5-
Revised: 4/6/18
5+
Revised: 4/19/18
66
---------------------------------------------------------------------------
77
A class for importing into MHN processing scripts, containing frequently
88
used methods and variables.
@@ -407,6 +407,17 @@ def calculate_itin_measures(self, itin_table):
407407
return itin_table
408408

409409

410+
@staticmethod
411+
def check_selection(lyr):
412+
''' Check whether specified layer has a selection. '''
413+
desc = arcpy.Describe(lyr)
414+
selected = desc.FIDSet
415+
if len(selected) == 0:
416+
return False
417+
else:
418+
return True
419+
420+
410421
@staticmethod
411422
def delete_if_exists(filepath):
412423
''' Check if a file exists, and delete it if so. '''

generate_transit_files.py

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
'''
33
generate_transit_files.py
44
Author: npeterson
5-
Revised: 4/6/18
5+
Revised: 4/19/18
66
---------------------------------------------------------------------------
77
This program creates the Emme transit batchin files needed to model a
88
scenario network. The scenario, output path and CT-RAMP flag are passed to
@@ -476,44 +476,47 @@
476476
pnr_csv = pnr_fixed_csv
477477

478478
# Identify NEW_MODES=4 links in base network and among highway projects completed by scenario year.
479-
hwyproj_id_field = MHN.route_systems[MHN.hwyproj][1]
480-
hwy_year_attr = [hwyproj_id_field, 'COMPLETION_YEAR']
481-
hwy_year_query = '"COMPLETION_YEAR" <= {0}'.format(scen_year)
482-
hwy_year_view = MHN.make_skinny_table_view(MHN.hwyproj, 'hwy_year_view', hwy_year_attr, hwy_year_query)
483-
hwyproj_years = {r[0]: r[1] for r in arcpy.da.SearchCursor(hwy_year_view, hwy_year_attr)}
484-
arcpy.Delete_management(hwy_year_view)
485-
486-
busway_coding_attr = [
487-
hwyproj_id_field, 'ABB', 'NEW_MODES', 'NEW_DIRECTIONS',
488-
'NEW_THRULANES1', 'NEW_THRULANES2', 'NEW_TYPE1', 'NEW_TYPE2',
489-
'NEW_AMPM1', 'NEW_AMPM2', 'TOD'
490-
]
491-
busway_coding_query = ''' "NEW_MODES" = '4' AND "{0}" IN ('{1}') '''.format(
492-
hwyproj_id_field, "','".join(hwyproj_id for hwyproj_id in hwyproj_years.keys())
493-
)
494-
busway_coding_view = MHN.make_skinny_table_view(
495-
MHN.route_systems[MHN.hwyproj][0], 'busway_coding_view', busway_coding_attr, busway_coding_query
496-
)
497-
busway_coding_abb = [r[0] for r in arcpy.da.SearchCursor(busway_coding_view, ['ABB'])]
498-
busway_coding_dict = {abb: dict() for abb in busway_coding_abb}
499-
with arcpy.da.SearchCursor(busway_coding_view, busway_coding_attr) as c:
500-
for r in c:
501-
tipid = r[0]
502-
abb = r[1]
503-
attr = list(r[2:])
504-
for i in range(len(attr)):
505-
attr[i] = str(attr[i]) if str(attr[i]) != '0' else None # Set 0s to null, stringify rest
506-
attr_dict = dict(zip(busway_coding_attr[2:], attr))
507-
busway_coding_dict[abb][tipid] = attr_dict
508-
arcpy.Delete_management(busway_coding_view)
479+
if scen_year > MHN.base_year:
480+
hwyproj_id_field = MHN.route_systems[MHN.hwyproj][1]
481+
hwy_year_attr = [hwyproj_id_field, 'COMPLETION_YEAR']
482+
hwy_year_query = '"COMPLETION_YEAR" <= {0}'.format(scen_year)
483+
hwy_year_view = MHN.make_skinny_table_view(MHN.hwyproj, 'hwy_year_view', hwy_year_attr, hwy_year_query)
484+
hwyproj_years = {r[0]: r[1] for r in arcpy.da.SearchCursor(hwy_year_view, hwy_year_attr)}
485+
arcpy.Delete_management(hwy_year_view)
486+
487+
busway_coding_attr = [
488+
hwyproj_id_field, 'ABB', 'NEW_MODES', 'NEW_DIRECTIONS',
489+
'NEW_THRULANES1', 'NEW_THRULANES2', 'NEW_TYPE1', 'NEW_TYPE2',
490+
'NEW_AMPM1', 'NEW_AMPM2', 'TOD'
491+
]
492+
busway_coding_query = ''' "NEW_MODES" = '4' AND "{0}" IN ('{1}') '''.format(
493+
hwyproj_id_field, "','".join(hwyproj_id for hwyproj_id in hwyproj_years.keys())
494+
)
495+
busway_coding_view = MHN.make_skinny_table_view(
496+
MHN.route_systems[MHN.hwyproj][0], 'busway_coding_view', busway_coding_attr, busway_coding_query
497+
)
498+
busway_coding_abb = [r[0] for r in arcpy.da.SearchCursor(busway_coding_view, ['ABB'])]
499+
busway_coding_dict = {abb: dict() for abb in busway_coding_abb}
500+
with arcpy.da.SearchCursor(busway_coding_view, busway_coding_attr) as c:
501+
for r in c:
502+
tipid = r[0]
503+
abb = r[1]
504+
attr = list(r[2:])
505+
for i in range(len(attr)):
506+
attr[i] = str(attr[i]) if str(attr[i]) != '0' else None # Set 0s to null, stringify rest
507+
attr_dict = dict(zip(busway_coding_attr[2:], attr))
508+
busway_coding_dict[abb][tipid] = attr_dict
509+
arcpy.Delete_management(busway_coding_view)
509510

510511
busway_link_attr = [
511512
'ABB', 'MILES', 'DIRECTIONS', 'THRULANES1', 'THRULANES2', 'TYPE1', 'TYPE2',
512513
'AMPM1', 'AMPM2'
513514
]
514-
busway_link_query = ''' "MODES" = '4' OR "ABB" IN ('{0}') '''.format(
515-
"','".join((abb for abb in busway_coding_abb if abb[-1] != '1'))
516-
)
515+
busway_link_query = ''' ("MODES" = '4' AND ABB NOT LIKE '%-1') '''
516+
if scen_year > MHN.base_year:
517+
busway_link_query += ''' OR "ABB" IN ('{0}') '''.format(
518+
"','".join((abb for abb in busway_coding_abb if abb[-1] != '1'))
519+
)
517520
busway_link_view = MHN.make_skinny_table_view(MHN.arc, 'busway_link_view', busway_link_attr, busway_link_query)
518521
busway_link_abb = [r[0] for r in arcpy.da.SearchCursor(busway_link_view, ['ABB'])]
519522
busway_baseyear_csv = os.path.join(MHN.temp_dir, 'busway_links_baseyear.csv')
@@ -553,26 +556,27 @@
553556
ampm2 = attr[8] if attr[8] != '0' else None
554557

555558
# Update chronologically with highway coding
556-
link_hwyproj = {tipid: hwyproj_years[tipid] for tipid in busway_coding_dict[abb].keys()}
557-
link_hwyproj_chrono = sorted(link_hwyproj.items(), key=operator.itemgetter(1))
558-
for tipid, year in link_hwyproj_chrono:
559-
attr2 = busway_coding_dict[abb][tipid]
560-
if attr2['TOD'] and tod not in attr2['TOD']:
561-
continue # Ignore if coding doesn't apply to current TOD
562-
dirs = attr2['NEW_DIRECTIONS'] if attr2['NEW_DIRECTIONS'] else dirs
563-
lanes1 = attr2['NEW_THRULANES1'] if attr2['NEW_THRULANES1'] else lanes1
564-
vdf1 = attr2['NEW_TYPE1'] if attr2['NEW_TYPE1'] else vdf1
565-
ampm1 = attr2['NEW_AMPM1'] if attr2['NEW_AMPM1'] else ampm1
566-
if dirs == '1':
567-
lanes2 = vdf2 = ampm2 = None
568-
elif dirs == '2':
569-
lanes2 = lanes1
570-
vdf2 = vdf1
571-
ampm2 = ampm1
572-
else:
573-
lanes2 = attr2['NEW_THRULANES2'] if attr2['NEW_THRULANES2'] else lanes2
574-
vdf2 = attr2['NEW_TYPE2'] if attr2['NEW_TYPE2'] else vdf2
575-
ampm2 = attr2['NEW_AMPM2'] if attr2['NEW_AMPM2'] else ampm2
559+
if scen_year > MHN.base_year:
560+
link_hwyproj = {tipid: hwyproj_years[tipid] for tipid in busway_coding_dict[abb].keys()}
561+
link_hwyproj_chrono = sorted(link_hwyproj.items(), key=operator.itemgetter(1))
562+
for tipid, year in link_hwyproj_chrono:
563+
attr2 = busway_coding_dict[abb][tipid]
564+
if attr2['TOD'] and tod not in attr2['TOD']:
565+
continue # Ignore if coding doesn't apply to current TOD
566+
dirs = attr2['NEW_DIRECTIONS'] if attr2['NEW_DIRECTIONS'] else dirs
567+
lanes1 = attr2['NEW_THRULANES1'] if attr2['NEW_THRULANES1'] else lanes1
568+
vdf1 = attr2['NEW_TYPE1'] if attr2['NEW_TYPE1'] else vdf1
569+
ampm1 = attr2['NEW_AMPM1'] if attr2['NEW_AMPM1'] else ampm1
570+
if dirs == '1':
571+
lanes2 = vdf2 = ampm2 = None
572+
elif dirs == '2':
573+
lanes2 = lanes1
574+
vdf2 = vdf1
575+
ampm2 = ampm1
576+
else:
577+
lanes2 = attr2['NEW_THRULANES2'] if attr2['NEW_THRULANES2'] else lanes2
578+
vdf2 = attr2['NEW_TYPE2'] if attr2['NEW_TYPE2'] else vdf2
579+
ampm2 = attr2['NEW_AMPM2'] if attr2['NEW_AMPM2'] else ampm2
576580

577581
# Determine whether to write A->B and B->A links
578582
write_ab = True if tod in MHN.ampm_tods[ampm1] else False
@@ -588,10 +592,10 @@
588592
w.write(out_ba)
589593
busway_nodes.update([anode, bnode])
590594

591-
os.remove(busway_baseyear_csv)
595+
MHN.delete_if_exists(busway_baseyear_csv)
592596

593597
# Identify end nodes of MODES=4 links
594-
busway_nodes_list = list(busway_nodes)
598+
busway_nodes_list = list(busway_nodes) if busway_nodes else ['-1']
595599
busway_nodes_attr = ['NODE', 'POINT_X', 'POINT_Y', MHN.zone_attr, MHN.capzone_attr]
596600
busway_nodes_query = '"NODE" IN ({0})'.format(','.join(busway_nodes_list))
597601
busway_nodes_view = MHN.make_skinny_table_view(MHN.node, 'busway_nodes_view', busway_nodes_attr, busway_nodes_query)

generate_transit_files_2.sas

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
generate_transit_files_2.sas
33
authors: cheither & npeterson
4-
revised: 4/6/18
4+
revised: 4/19/18
55
----------------------------------------------------------------------------
66
Program creates bus transit network batchin files. Bus transit network is
77
built using a modified version of MHN processing procedures.
@@ -218,10 +218,10 @@ data nodes(drop=flag); infile innd missover;
218218
proc sort; by itina;
219219

220220
*** Get and append busway (MODES=4) nodes ***;
221-
proc import datafile=bwynd out=buswaynd dbms=csv replace; getnames=yes;
222-
data buswaynd; set buswaynd;
223-
rename node=itina point_x=x_a point_y=y_a zone09=zone capacityzone09=atype;
224-
proc sort; by itina;
221+
data buswaynd;
222+
infile bwynd delimiter=',' dsd missover firstobs=2;
223+
input itina: 5. x_a: 20. y_a: 20. zone: 5. atype: 2.; run;
224+
proc sort; by itina; run;
225225
data nodes; merge nodes buswaynd; by itina;
226226
proc sort; by itina; run;
227227

@@ -309,9 +309,9 @@ data links(drop=flag j1-j2); infile inlk missover;
309309
proc sort; by itina itinb;
310310

311311
*** Get and append busway (MODES=4) links ***;
312-
proc import datafile=bwylk out=buswaylk dbms=csv replace; getnames=yes;
313-
data buswaylk; set buswaylk;
314-
rename anode=itina bnode=itinb;
312+
data buswaylk;
313+
infile bwylk delimiter=',' dsd missover firstobs=2;
314+
input itina: 5. itinb: 5. miles: 20. thruln: 2. vdf: 1.; run;
315315
proc sort; by itina itinb; run;
316316
data links; merge links buswaylk; by itina itinb;
317317
proc sort; by itina itinb; run;

import_future_bus_routes_2.sas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ data rte; set rte(where=(tr_line is not null));
6969
if notes='' then notes='X';
7070
description=upcase(description);
7171
d=compress(description,"'");
72-
d=substr(d,1,20); ** Can this be expanded to accommodate longer names? **;
72+
d=substr(d,1,20); ** 20-char limit imposed by Emme **;
7373
des=trim(d);
7474
nt=trim(notes);
7575

0 commit comments

Comments
 (0)