From e8ed14e1ac05c8ff164f4acae1194f494819971b Mon Sep 17 00:00:00 2001 From: Noel Peterson Date: Fri, 20 Apr 2018 10:24:49 -0500 Subject: [PATCH 1/3] Added check_selection() static method for verifying that a feature layer or table view has an active selection --- MHN.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/MHN.py b/MHN.py index babb50d..72b9af1 100644 --- a/MHN.py +++ b/MHN.py @@ -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. @@ -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. ''' From d2e7c0990a6930aa8ff7236f3ba97c4f57f001b6 Mon Sep 17 00:00:00 2001 From: Noel Peterson Date: Fri, 20 Apr 2018 10:25:13 -0500 Subject: [PATCH 2/3] Added clarifying comment --- import_future_bus_routes_2.sas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import_future_bus_routes_2.sas b/import_future_bus_routes_2.sas index 31413ef..413a1ef 100644 --- a/import_future_bus_routes_2.sas +++ b/import_future_bus_routes_2.sas @@ -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); From 859bd4a1dc41f5275ce89522fe8157c1e88098ad Mon Sep 17 00:00:00 2001 From: Noel Peterson Date: Fri, 20 Apr 2018 10:25:51 -0500 Subject: [PATCH 3/3] Fixed busway handling for base year network generation --- generate_transit_files.py | 116 ++++++++++++++++++----------------- generate_transit_files_2.sas | 16 ++--- 2 files changed, 68 insertions(+), 64 deletions(-) diff --git a/generate_transit_files.py b/generate_transit_files.py index 254127e..2ec7468 100644 --- a/generate_transit_files.py +++ b/generate_transit_files.py @@ -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 @@ -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') @@ -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 @@ -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) diff --git a/generate_transit_files_2.sas b/generate_transit_files_2.sas index 3a20687..4b8200b 100644 --- a/generate_transit_files_2.sas +++ b/generate_transit_files_2.sas @@ -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. @@ -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; @@ -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;