Skip to content

Commit

Permalink
Merge pull request #115 from nmpeterson/master
Browse files Browse the repository at this point in the history
Fix busway handling for base year transit network generation
  • Loading branch information
nmpeterson authored Apr 20, 2018
2 parents bcc8c74 + 859bd4a commit 82df514
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 66 deletions.
13 changes: 12 additions & 1 deletion MHN.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
'''
MHN.py
Author: npeterson
Revised: 4/6/18
Revised: 4/19/18
---------------------------------------------------------------------------
A class for importing into MHN processing scripts, containing frequently
used methods and variables.
Expand Down Expand Up @@ -407,6 +407,17 @@ def calculate_itin_measures(self, itin_table):
return itin_table


@staticmethod
def check_selection(lyr):
''' Check whether specified layer has a selection. '''
desc = arcpy.Describe(lyr)
selected = desc.FIDSet
if len(selected) == 0:
return False
else:
return True


@staticmethod
def delete_if_exists(filepath):
''' Check if a file exists, and delete it if so. '''
Expand Down
116 changes: 60 additions & 56 deletions generate_transit_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
'''
generate_transit_files.py
Author: npeterson
Revised: 4/6/18
Revised: 4/19/18
---------------------------------------------------------------------------
This program creates the Emme transit batchin files needed to model a
scenario network. The scenario, output path and CT-RAMP flag are passed to
Expand Down Expand Up @@ -476,44 +476,47 @@
pnr_csv = pnr_fixed_csv

# Identify NEW_MODES=4 links in base network and among highway projects completed by scenario year.
hwyproj_id_field = MHN.route_systems[MHN.hwyproj][1]
hwy_year_attr = [hwyproj_id_field, 'COMPLETION_YEAR']
hwy_year_query = '"COMPLETION_YEAR" <= {0}'.format(scen_year)
hwy_year_view = MHN.make_skinny_table_view(MHN.hwyproj, 'hwy_year_view', hwy_year_attr, hwy_year_query)
hwyproj_years = {r[0]: r[1] for r in arcpy.da.SearchCursor(hwy_year_view, hwy_year_attr)}
arcpy.Delete_management(hwy_year_view)

busway_coding_attr = [
hwyproj_id_field, 'ABB', 'NEW_MODES', 'NEW_DIRECTIONS',
'NEW_THRULANES1', 'NEW_THRULANES2', 'NEW_TYPE1', 'NEW_TYPE2',
'NEW_AMPM1', 'NEW_AMPM2', 'TOD'
]
busway_coding_query = ''' "NEW_MODES" = '4' AND "{0}" IN ('{1}') '''.format(
hwyproj_id_field, "','".join(hwyproj_id for hwyproj_id in hwyproj_years.keys())
)
busway_coding_view = MHN.make_skinny_table_view(
MHN.route_systems[MHN.hwyproj][0], 'busway_coding_view', busway_coding_attr, busway_coding_query
)
busway_coding_abb = [r[0] for r in arcpy.da.SearchCursor(busway_coding_view, ['ABB'])]
busway_coding_dict = {abb: dict() for abb in busway_coding_abb}
with arcpy.da.SearchCursor(busway_coding_view, busway_coding_attr) as c:
for r in c:
tipid = r[0]
abb = r[1]
attr = list(r[2:])
for i in range(len(attr)):
attr[i] = str(attr[i]) if str(attr[i]) != '0' else None # Set 0s to null, stringify rest
attr_dict = dict(zip(busway_coding_attr[2:], attr))
busway_coding_dict[abb][tipid] = attr_dict
arcpy.Delete_management(busway_coding_view)
if scen_year > MHN.base_year:
hwyproj_id_field = MHN.route_systems[MHN.hwyproj][1]
hwy_year_attr = [hwyproj_id_field, 'COMPLETION_YEAR']
hwy_year_query = '"COMPLETION_YEAR" <= {0}'.format(scen_year)
hwy_year_view = MHN.make_skinny_table_view(MHN.hwyproj, 'hwy_year_view', hwy_year_attr, hwy_year_query)
hwyproj_years = {r[0]: r[1] for r in arcpy.da.SearchCursor(hwy_year_view, hwy_year_attr)}
arcpy.Delete_management(hwy_year_view)

busway_coding_attr = [
hwyproj_id_field, 'ABB', 'NEW_MODES', 'NEW_DIRECTIONS',
'NEW_THRULANES1', 'NEW_THRULANES2', 'NEW_TYPE1', 'NEW_TYPE2',
'NEW_AMPM1', 'NEW_AMPM2', 'TOD'
]
busway_coding_query = ''' "NEW_MODES" = '4' AND "{0}" IN ('{1}') '''.format(
hwyproj_id_field, "','".join(hwyproj_id for hwyproj_id in hwyproj_years.keys())
)
busway_coding_view = MHN.make_skinny_table_view(
MHN.route_systems[MHN.hwyproj][0], 'busway_coding_view', busway_coding_attr, busway_coding_query
)
busway_coding_abb = [r[0] for r in arcpy.da.SearchCursor(busway_coding_view, ['ABB'])]
busway_coding_dict = {abb: dict() for abb in busway_coding_abb}
with arcpy.da.SearchCursor(busway_coding_view, busway_coding_attr) as c:
for r in c:
tipid = r[0]
abb = r[1]
attr = list(r[2:])
for i in range(len(attr)):
attr[i] = str(attr[i]) if str(attr[i]) != '0' else None # Set 0s to null, stringify rest
attr_dict = dict(zip(busway_coding_attr[2:], attr))
busway_coding_dict[abb][tipid] = attr_dict
arcpy.Delete_management(busway_coding_view)

busway_link_attr = [
'ABB', 'MILES', 'DIRECTIONS', 'THRULANES1', 'THRULANES2', 'TYPE1', 'TYPE2',
'AMPM1', 'AMPM2'
]
busway_link_query = ''' "MODES" = '4' OR "ABB" IN ('{0}') '''.format(
"','".join((abb for abb in busway_coding_abb if abb[-1] != '1'))
)
busway_link_query = ''' ("MODES" = '4' AND ABB NOT LIKE '%-1') '''
if scen_year > MHN.base_year:
busway_link_query += ''' OR "ABB" IN ('{0}') '''.format(
"','".join((abb for abb in busway_coding_abb if abb[-1] != '1'))
)
busway_link_view = MHN.make_skinny_table_view(MHN.arc, 'busway_link_view', busway_link_attr, busway_link_query)
busway_link_abb = [r[0] for r in arcpy.da.SearchCursor(busway_link_view, ['ABB'])]
busway_baseyear_csv = os.path.join(MHN.temp_dir, 'busway_links_baseyear.csv')
Expand Down Expand Up @@ -553,26 +556,27 @@
ampm2 = attr[8] if attr[8] != '0' else None

# Update chronologically with highway coding
link_hwyproj = {tipid: hwyproj_years[tipid] for tipid in busway_coding_dict[abb].keys()}
link_hwyproj_chrono = sorted(link_hwyproj.items(), key=operator.itemgetter(1))
for tipid, year in link_hwyproj_chrono:
attr2 = busway_coding_dict[abb][tipid]
if attr2['TOD'] and tod not in attr2['TOD']:
continue # Ignore if coding doesn't apply to current TOD
dirs = attr2['NEW_DIRECTIONS'] if attr2['NEW_DIRECTIONS'] else dirs
lanes1 = attr2['NEW_THRULANES1'] if attr2['NEW_THRULANES1'] else lanes1
vdf1 = attr2['NEW_TYPE1'] if attr2['NEW_TYPE1'] else vdf1
ampm1 = attr2['NEW_AMPM1'] if attr2['NEW_AMPM1'] else ampm1
if dirs == '1':
lanes2 = vdf2 = ampm2 = None
elif dirs == '2':
lanes2 = lanes1
vdf2 = vdf1
ampm2 = ampm1
else:
lanes2 = attr2['NEW_THRULANES2'] if attr2['NEW_THRULANES2'] else lanes2
vdf2 = attr2['NEW_TYPE2'] if attr2['NEW_TYPE2'] else vdf2
ampm2 = attr2['NEW_AMPM2'] if attr2['NEW_AMPM2'] else ampm2
if scen_year > MHN.base_year:
link_hwyproj = {tipid: hwyproj_years[tipid] for tipid in busway_coding_dict[abb].keys()}
link_hwyproj_chrono = sorted(link_hwyproj.items(), key=operator.itemgetter(1))
for tipid, year in link_hwyproj_chrono:
attr2 = busway_coding_dict[abb][tipid]
if attr2['TOD'] and tod not in attr2['TOD']:
continue # Ignore if coding doesn't apply to current TOD
dirs = attr2['NEW_DIRECTIONS'] if attr2['NEW_DIRECTIONS'] else dirs
lanes1 = attr2['NEW_THRULANES1'] if attr2['NEW_THRULANES1'] else lanes1
vdf1 = attr2['NEW_TYPE1'] if attr2['NEW_TYPE1'] else vdf1
ampm1 = attr2['NEW_AMPM1'] if attr2['NEW_AMPM1'] else ampm1
if dirs == '1':
lanes2 = vdf2 = ampm2 = None
elif dirs == '2':
lanes2 = lanes1
vdf2 = vdf1
ampm2 = ampm1
else:
lanes2 = attr2['NEW_THRULANES2'] if attr2['NEW_THRULANES2'] else lanes2
vdf2 = attr2['NEW_TYPE2'] if attr2['NEW_TYPE2'] else vdf2
ampm2 = attr2['NEW_AMPM2'] if attr2['NEW_AMPM2'] else ampm2

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

os.remove(busway_baseyear_csv)
MHN.delete_if_exists(busway_baseyear_csv)

# Identify end nodes of MODES=4 links
busway_nodes_list = list(busway_nodes)
busway_nodes_list = list(busway_nodes) if busway_nodes else ['-1']
busway_nodes_attr = ['NODE', 'POINT_X', 'POINT_Y', MHN.zone_attr, MHN.capzone_attr]
busway_nodes_query = '"NODE" IN ({0})'.format(','.join(busway_nodes_list))
busway_nodes_view = MHN.make_skinny_table_view(MHN.node, 'busway_nodes_view', busway_nodes_attr, busway_nodes_query)
Expand Down
16 changes: 8 additions & 8 deletions generate_transit_files_2.sas
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
generate_transit_files_2.sas
authors: cheither & npeterson
revised: 4/6/18
revised: 4/19/18
----------------------------------------------------------------------------
Program creates bus transit network batchin files. Bus transit network is
built using a modified version of MHN processing procedures.
Expand Down Expand Up @@ -218,10 +218,10 @@ data nodes(drop=flag); infile innd missover;
proc sort; by itina;

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

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

*** Get and append busway (MODES=4) links ***;
proc import datafile=bwylk out=buswaylk dbms=csv replace; getnames=yes;
data buswaylk; set buswaylk;
rename anode=itina bnode=itinb;
data buswaylk;
infile bwylk delimiter=',' dsd missover firstobs=2;
input itina: 5. itinb: 5. miles: 20. thruln: 2. vdf: 1.; run;
proc sort; by itina itinb; run;
data links; merge links buswaylk; by itina itinb;
proc sort; by itina itinb; run;
Expand Down
2 changes: 1 addition & 1 deletion import_future_bus_routes_2.sas
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ data rte; set rte(where=(tr_line is not null));
if notes='' then notes='X';
description=upcase(description);
d=compress(description,"'");
d=substr(d,1,20); ** Can this be expanded to accommodate longer names? **;
d=substr(d,1,20); ** 20-char limit imposed by Emme **;
des=trim(d);
nt=trim(notes);

Expand Down

0 comments on commit 82df514

Please sign in to comment.