From 492bc204053d5b162d72ba79ba9cb6abbf75adc1 Mon Sep 17 00:00:00 2001 From: Tyler Hatch Date: Tue, 16 Mar 2021 13:09:47 -0500 Subject: [PATCH 1/6] Fixed Bug when using different network type --- BRAT_table.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/BRAT_table.py b/BRAT_table.py index a97e37c6..741c6389 100644 --- a/BRAT_table.py +++ b/BRAT_table.py @@ -546,7 +546,10 @@ def zSeg(vertex_type, out_field): if is_verbose: arcpy.AddMessage("Calculating iGeo_Slope...") for row in cursor: - row[3] = (abs(row[0] - row[1]))/row[2] + if row[2] == 0: + row[3] = 0.0001 + else: + row[3] = (abs(row[0] - row[1]))/row[2] if row[3] == 0.0: row[3] = 0.0001 cursor.updateRow(row) From 5db4a5e6443eb520b5a2012cf225838b50e31572 Mon Sep 17 00:00:00 2001 From: Tyler Hatch Date: Tue, 16 Mar 2021 17:16:46 -0500 Subject: [PATCH 2/6] Changes to account for slightly different networks --- Capacity_Validation.py | 6 +++++- Constraints_Opportunities.py | 4 ++++ FindBraidedNetwork.py | 18 +++++++++++++----- iHyd.py | 2 ++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Capacity_Validation.py b/Capacity_Validation.py index ef1f84fc..258f5ddd 100644 --- a/Capacity_Validation.py +++ b/Capacity_Validation.py @@ -31,6 +31,8 @@ def main(in_network, output_name, dams=None, da_threshold=None): :param da_threshold: Drainage area at which stream is presumably too large for dam building :return: """ + + if da_threshold == "None": da_threshold = None @@ -41,6 +43,8 @@ def main(in_network, output_name, dams=None, da_threshold=None): if dams: dams = copy_dams_to_inputs(proj_path, dams, in_network) + + if output_name.endswith('.shp'): output_network = os.path.join(os.path.dirname(in_network), output_name) else: @@ -101,7 +105,7 @@ def copy_dams_to_inputs(proj_path, dams, in_network): """ if proj_path in dams: # The dams input is already in our project folder, so we don't need to copy it over - return + return dams inputs_folder = find_folder(proj_path, "Inputs") beaver_dams_folder = find_folder(inputs_folder, "*[0-9]*_BeaverDams") diff --git a/Constraints_Opportunities.py b/Constraints_Opportunities.py index 80ca2b39..d3226b75 100644 --- a/Constraints_Opportunities.py +++ b/Constraints_Opportunities.py @@ -66,6 +66,10 @@ def main(proj_path, in_network, out_name, surveyed_dams=None, conservation_areas 'iPC_VLowLU', 'iPC_HighLU', 'oPC_Dist', 'iPC_LU', 'iHyd_SPLow', 'iHyd_SP2', 'DamStrat', 'iPC_RoadX', 'iPC_Canal', 'ObsDam', 'ConsArea', 'ConsEase'] + for field in fields: + if field not in [f.name for f in arcpy.ListFields(out_network)]: + arcpy.AddWarning('Missing {} Field!'.format(field)) + # add arbitrarily large value to avoid error if 'iPC_Canal' not in old_fields: arcpy.AddField_management(out_network, "iPC_Canal", "DOUBLE") diff --git a/FindBraidedNetwork.py b/FindBraidedNetwork.py index b3ca61eb..03364f1f 100644 --- a/FindBraidedNetwork.py +++ b/FindBraidedNetwork.py @@ -47,11 +47,19 @@ def main(fcStreamNetwork, canal, tempDir, perennial_network, is_verbose): def use_stream_names(stream_network): - with arcpy.da.UpdateCursor(stream_network, ["IsMultiCh", "IsMainCh", "StreamName"]) as cursor: - for row in cursor: - if row[0] == 1 and row[2] != ' ': - row[1] = 1 - cursor.updateRow(row) + fields = arcpy.ListFields(stream_network) + if "StreamName" in fields: + new_name = "StreamName" + elif "GNIS_Name" in fields: + new_name = "GNIS_Name" + else: + new_name = False + if new_name: + with arcpy.da.UpdateCursor(stream_network, ["IsMultiCh", "IsMainCh", new_name]) as cursor: + for row in cursor: + if row[0] == 1 and row[2] != ' ': + row[1] = 1 + cursor.updateRow(row) def handleCanals(stream_network, canal, perennial_network, temp_folder, is_verbose): diff --git a/iHyd.py b/iHyd.py index 8ef4a25c..f4136584 100644 --- a/iHyd.py +++ b/iHyd.py @@ -65,6 +65,7 @@ def main(in_network, region, q_low_eqtn, q2_eqtn): # --regional curve equations for Qlow (baseflow) and Q2 (annual peak streamflow)-- # # # Add in regional curve equations here # # # if q_low_eqtn is not None: + arcpy.AddMessage("Evaluating qlow...") q_low = eval(q_low_eqtn) elif region == 101: # example 1 (box elder county) q_low = 0.019875 * (DAsqm ** 0.6634) * (10 ** (0.6068 * 2.04)) @@ -76,6 +77,7 @@ def main(in_network, region, q_low_eqtn, q2_eqtn): q_low = (DAsqm ** 0.2098) + 1 if q2_eqtn is not None: + arcpy.AddMessage("Evaluating q2...") q2 = eval(q2_eqtn) elif region == 101: # example 1 (box elder county) q2 = 14.5 * DAsqm ** 0.328 From 6c80617ee2557a0fdb74675aa3460c476bc3ffb5 Mon Sep 17 00:00:00 2001 From: Tyler Hatch Date: Fri, 19 Mar 2021 15:58:45 -0500 Subject: [PATCH 3/6] Fixed a bug that caused oPBRC_CR to sometimes calculate incorrectly --- Constraints_Opportunities.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Constraints_Opportunities.py b/Constraints_Opportunities.py index 80ca2b39..81d8f550 100644 --- a/Constraints_Opportunities.py +++ b/Constraints_Opportunities.py @@ -177,7 +177,7 @@ def main(proj_path, in_network, out_name, surveyed_dams=None, conservation_areas # 'oCC_HPE' Frequent or Pervasive # 'ipc_vlow_lu'(i.e., Natural) > 75 # 'ipc_high_lu' (i.e., Developed) < 10 - elif occ_hpe >= 5 > occ_ex > 0 and ipc_vlow_lu > 75 and ipc_high_lu < 10: + elif occ_hpe >= 5 and occ_ex > 0 and ipc_vlow_lu > 75 and ipc_high_lu < 10: row[2] = 'Strategic - Long-Term Investment' else: row[2] = 'NA' From 5d1670f9c66a258f9bf9d69e7b068463fe1da410 Mon Sep 17 00:00:00 2001 From: Tyler Hatch Date: Fri, 19 Mar 2021 16:29:20 -0500 Subject: [PATCH 4/6] Update Collect_Summary_Products.py --- Collect_Summary_Products.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Collect_Summary_Products.py b/Collect_Summary_Products.py index 6e46e8d2..89708af2 100644 --- a/Collect_Summary_Products.py +++ b/Collect_Summary_Products.py @@ -570,7 +570,8 @@ def write_summary_worksheet(worksheet, stream_network, watershed_name, workbook, for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for length, in cursor: - total_stream_length_km += length + if length is not None: + total_stream_length_km += length total_stream_length_km /= 1000 total_stream_length_mi = total_stream_length_km / 1.609344 From 9ce5b78a91ca301f7a1f72c567561a617fd5133b Mon Sep 17 00:00:00 2001 From: Tyler Hatch Date: Fri, 19 Mar 2021 16:57:36 -0500 Subject: [PATCH 5/6] Now checks for Null length --- Collect_Summary_Products.py | 313 +++++++++++++++++++----------------- 1 file changed, 167 insertions(+), 146 deletions(-) diff --git a/Collect_Summary_Products.py b/Collect_Summary_Products.py index 89708af2..59385e6a 100644 --- a/Collect_Summary_Products.py +++ b/Collect_Summary_Products.py @@ -427,50 +427,53 @@ def search_cursor(fields, data, total, stream_network, is_complex, is_capacity_t for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for capacity, dam_complex_size, length in cursor: - if capacity == 0: - data[0] += capacity * (length/1000) - elif capacity <= 1: - data[1] += capacity * (length/1000) - elif capacity <= 5: - data[2] += capacity * (length/1000) - elif capacity <= 15: - data[3] += capacity * (length/1000) - else: - data[4] += capacity * (length/1000) + if length is not None: + if capacity == 0: + data[0] += capacity * (length/1000) + elif capacity <= 1: + data[1] += capacity * (length/1000) + elif capacity <= 5: + data[2] += capacity * (length/1000) + elif capacity <= 15: + data[3] += capacity * (length/1000) + else: + data[4] += capacity * (length/1000) return data elif is_complex: for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for length, dam_complex_size in cursor: - total += length - if dam_complex_size == 0: - data[0] += length - elif dam_complex_size <= 1: - data[1] += length - elif dam_complex_size <= 3: - data[2] += length - elif dam_complex_size <= 5: - data[3] += length - else: - data[4] += length + if length is not None: + total += length + if dam_complex_size == 0: + data[0] += length + elif dam_complex_size <= 1: + data[1] += length + elif dam_complex_size <= 3: + data[2] += length + elif dam_complex_size <= 5: + data[3] += length + else: + data[4] += length total = total / 1000 write_data(data[0], data[1], data[2], data[3], data[4], total, worksheet, workbook) else: for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for length, capacity in cursor: - total += length - if capacity == 0: - data[0] += length/1000 - elif capacity <= 1: - data[1] += length/1000 - elif capacity <= 5: - data[2] += length/1000 - elif capacity <= 15: - data[3] += length/1000 - else: - data[4] += length/1000 + if length is not None: + total += length + if capacity == 0: + data[0] += length/1000 + elif capacity <= 1: + data[1] += length/1000 + elif capacity <= 5: + data[2] += length/1000 + elif capacity <= 15: + data[3] += length/1000 + else: + data[4] += length/1000 return data @@ -608,7 +611,8 @@ def write_summary_worksheet(worksheet, stream_network, watershed_name, workbook, for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for length, density in cursor: - total_existing_veg += ((length / 1000) * density) + if length is not None: + total_existing_veg += ((length / 1000) * density) else: arcpy.AddWarning("Could not complete summary worksheet: {0} not in fields.".format(fields[1])) total_existing_veg = "N/A" @@ -619,7 +623,8 @@ def write_summary_worksheet(worksheet, stream_network, watershed_name, workbook, for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for length, density in cursor: - total_historic_veg += ((length / 1000) * density) + if length is not None: + total_historic_veg += ((length / 1000) * density) else: arcpy.AddWarning("Could not complete summary worksheet: {0} not in fields.".format(fields[1])) total_historic_veg = "N/A" @@ -632,7 +637,8 @@ def write_summary_worksheet(worksheet, stream_network, watershed_name, workbook, for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for length, density in cursor: - total_existing_capacity += ((length / 1000) * density) + if length is not None: + total_existing_capacity += ((length / 1000) * density) else: arcpy.AddWarning("Could not complete summary worksheet: {0} not in fields.".format(fields[1])) @@ -646,7 +652,8 @@ def write_summary_worksheet(worksheet, stream_network, watershed_name, workbook, for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for length, density in cursor: - total_historic_capacity += ((length / 1000) * density) + if length is not None: + total_historic_capacity += ((length / 1000) * density) else: arcpy.AddWarning("Could not complete summary worksheet: {0} not in fields.".format(fields[1])) total_historic_capacity = "N/A" @@ -663,8 +670,9 @@ def write_summary_worksheet(worksheet, stream_network, watershed_name, workbook, for length, surveyed, predicted in cursor: reach_count += 1 if surveyed > (predicted * .8): - total_surveyed_greater_length += (length / 1000) - total_surveyed_greater_count += 1 + if length is not None: + total_surveyed_greater_length += (length / 1000) + total_surveyed_greater_count += 1 else: pass # total_surveyed_greater_percent = float(total_surveyed_greater_count) / float(reach_count) @@ -736,8 +744,9 @@ def write_summary_worksheet(worksheet, stream_network, watershed_name, workbook, # estimate_right += 1 else: estimate_wrong += 1 - if length < 150: - estimate_wrong_short += 1 + if length is not None: + if length < 150: + estimate_wrong_short += 1 if float(estimate_wrong)+float(estimate_right) == 0: percent_correct_estimate = "N/A" else: @@ -760,8 +769,9 @@ def write_summary_worksheet(worksheet, stream_network, watershed_name, workbook, for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for length, category in cursor: - if category == "Easiest - Low-Hanging Fruit": - easiest_length += length + if length is not None: + if category == "Easiest - Low-Hanging Fruit": + easiest_length += length else: pass percent_easiest = easiest_length / (total_stream_length_km * 1000) @@ -777,8 +787,9 @@ def write_summary_worksheet(worksheet, stream_network, watershed_name, workbook, for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for length, category in cursor: - if category == "Dam Building Possible": - possible_length += length + if length is not None: + if category == "Dam Building Possible": + possible_length += length else: pass percent_possible = possible_length / (total_stream_length_km * 1000) @@ -794,8 +805,9 @@ def write_summary_worksheet(worksheet, stream_network, watershed_name, workbook, for streams in split_input: with arcpy.da.SearchCursor(streams, fields) as cursor: for length, category in cursor: - if category == "Negligible Risk": - negligibleLength += length + if length is not None: + if category == "Negligible Risk": + negligibleLength += length else: pass @@ -911,10 +923,11 @@ def write_strategy_map_worksheet(worksheet, stream_network, watershed_name, work for streams in split_input: with arcpy.da.SearchCursor(streams, ['SHAPE@Length', 'DamStrat']) as cursor: for length, category in cursor: - total += length - for counter, match in enumerate(category_list): - if category == match: - count_list[counter] += (length/1000) + if length is not None: + total += length + for counter, match in enumerate(category_list): + if category == match: + count_list[counter] += (length/1000) row = 2 col = 0 @@ -1491,15 +1504,16 @@ def write_conservation_restoration(worksheet, stream_network, watershed_name, wo for streams in split_input: with arcpy.da.SearchCursor(streams, ['SHAPE@Length', 'oPBRC_CR']) as cursor: for length, category in cursor: - total += length - if category == "Easiest - Low-Hanging Fruit": - easy += length - elif category == "Straight Forward - Quick Return": - mod += length - elif category == "Strategic - Long-Term Investment": - strateg += length - else: - other += length + if length is not None: + total += length + if category == "Easiest - Low-Hanging Fruit": + easy += length + elif category == "Straight Forward - Quick Return": + mod += length + elif category == "Strategic - Long-Term Investment": + strateg += length + else: + other += length # convert from m to km easy /= 1000 mod /= 1000 @@ -1617,23 +1631,24 @@ def write_unsuitable_worksheet(worksheet, stream_network, watershed_name, workbo for streams in split_input: with arcpy.da.SearchCursor(streams, ['SHAPE@Length', 'oPBRC_UD']) as cursor: for length, category in cursor: - total += length - if category == "Anthropogenically Limited": - anth += length - elif category == "Naturally Vegetation Limited": - veg += length - elif category == "Slope Limited": - slope += length - elif category == "Stream Power Limited": - stream += length - elif category == "Potential Reservoir or Landuse": - reservoir += length - elif category == "Dam Building Possible": - dams += length - elif category == "Stream Size Limited": - tbd += length - else: - pass + if length is not None: + total += length + if category == "Anthropogenically Limited": + anth += length + elif category == "Naturally Vegetation Limited": + veg += length + elif category == "Slope Limited": + slope += length + elif category == "Stream Power Limited": + stream += length + elif category == "Potential Reservoir or Landuse": + reservoir += length + elif category == "Dam Building Possible": + dams += length + elif category == "Stream Size Limited": + tbd += length + else: + pass # convert m to km anth /= 1000 veg /= 1000 @@ -1762,17 +1777,18 @@ def write_risk_worksheet(worksheet, stream_network, watershed_name, workbook): for streams in split_input: with arcpy.da.SearchCursor(streams, ['SHAPE@Length', 'oPBRC_UI']) as cursor: for length, category in cursor: - total += length - if category == "Major Risk": - cons += length - elif category == "Considerable Risk": - some += length - elif category == "Minor Risk": - minr += length - elif category == "Negligible Risk": - negl += length - else: - pass + if length is not None: + total += length + if category == "Major Risk": + cons += length + elif category == "Considerable Risk": + some += length + elif category == "Minor Risk": + minr += length + elif category == "Negligible Risk": + negl += length + else: + pass # convert m to km cons /= 1000 some /= 1000 @@ -1884,19 +1900,20 @@ def write_strategies_worksheet(worksheet, stream_network, watershed_name, workbo for streams in split_input: with arcpy.da.SearchCursor(streams, ['SHAPE@Length', 'ConsVRest']) as cursor: for length, category in cursor: - total += length - if category == "Immediate - Beaver Conservation": - cons += length - elif category == "Immediate - Potential Beaver Translocation": - trns += length - elif category == "Mid Term - Process-based Riparian Vegetation Resto": - rest += length - elif category == "Long Term: Riparian Vegetation Reestablishment": - veg += length - elif category == "Low Capacity Habitat": - low += length - else: - pass + if length is not None: + total += length + if category == "Immediate - Beaver Conservation": + cons += length + elif category == "Immediate - Potential Beaver Translocation": + trns += length + elif category == "Mid Term - Process-based Riparian Vegetation Resto": + rest += length + elif category == "Long Term: Riparian Vegetation Reestablishment": + veg += length + elif category == "Low Capacity Habitat": + low += length + else: + pass # convert m to km cons /= 1000 trns /= 1000 @@ -2064,20 +2081,21 @@ def write_validation_worksheet(worksheet, stream_network, watershed_name, workbo if category == "Urban": with arcpy.da.SearchCursor(streams, ['SHAPE@Length', 'BRATvSurv', 'iPC_HighLU', 'e_DamCt']) as cursor: for length, valid, land, damCount in cursor: - if land > 20: - if valid == -1: - none_km += length - none += 1 - elif valid >= 1 and damCount > 0: - few_km += length - few += 1 - elif damCount > 0: - more_km += length - more += 1 + if length is not None: + if land > 20: + if valid == -1: + none_km += length + none += 1 + elif valid >= 1 and damCount > 0: + few_km += length + few += 1 + elif damCount > 0: + more_km += length + more += 1 + else: + pass else: pass - else: - pass elif category == "Undeveloped": with arcpy.da.SearchCursor(streams, ['SHAPE@Length', @@ -2086,20 +2104,21 @@ def write_validation_worksheet(worksheet, stream_network, watershed_name, workbo 'iPC_VLowLU', 'e_DamCt']) as cursor: for length, valid, landHigh, landLow, damCount in cursor: - if (not landHigh > 20) and (landLow > 90): - if valid == -1: - none_km += length - none += 1 - elif valid >= 1 and damCount > 0: - few_km += length - few += 1 - elif damCount > 0: - more_km += length - more += 1 + if length is not None: + if (not landHigh > 20) and (landLow > 90): + if valid == -1: + none_km += length + none += 1 + elif valid >= 1 and damCount > 0: + few_km += length + few += 1 + elif damCount > 0: + more_km += length + more += 1 + else: + pass else: pass - else: - pass else: with arcpy.da.SearchCursor(streams, ['SHAPE@Length', @@ -2108,20 +2127,21 @@ def write_validation_worksheet(worksheet, stream_network, watershed_name, workbo 'iPC_VLowLU', 'e_DamCt']) as cursor: for length, valid, landHigh, landLow, damCount in cursor: - if (not landHigh > 20) and (not landLow > 90): - if valid == -1: - none_km += length - none += 1 - elif valid >= 1 and damCount > 0: - few_km += length - few += 1 - elif damCount > 0: - more_km += length - more += 1 + if length is not None: + if (not landHigh > 20) and (not landLow > 90): + if valid == -1: + none_km += length + none += 1 + elif valid >= 1 and damCount > 0: + few_km += length + few += 1 + elif damCount > 0: + more_km += length + more += 1 + else: + pass else: pass - else: - pass few_km /= 1000 more_km /= 1000 none_km /= 1000 @@ -2257,16 +2277,17 @@ def write_historic_remaining_worksheet(worksheet, stream_network, watershed_name for streams in split_input: with arcpy.da.SearchCursor(streams, ['SHAPE@Length', 'mCC_EXvHPE']) as cursor: for length, percent in cursor: - if percent <= 0.25: - zero_25 += length - elif percent <= 0.50: - twentyfive_50 += length - elif percent <= 0.75: - fifty_75 += length - elif percent <= 1.0: - seventyfive_100 += length - else: - hundred_plus += length + if length is not None: + if percent <= 0.25: + zero_25 += length + elif percent <= 0.50: + twentyfive_50 += length + elif percent <= 0.75: + fifty_75 += length + elif percent <= 1.0: + seventyfive_100 += length + else: + hundred_plus += length zero_25 /= 1000 twentyfive_50 /= 1000 From 5dee6dbd4c32ba66b4d883b6e1371cde51a4d869 Mon Sep 17 00:00:00 2001 From: Tyler Hatch Date: Fri, 26 Mar 2021 15:10:30 -0500 Subject: [PATCH 6/6] Projections are now consistent --- BRATProject.py | 3 ++- BRAT_table.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/BRATProject.py b/BRATProject.py index 3a86a815..f10f92b8 100644 --- a/BRATProject.py +++ b/BRATProject.py @@ -15,9 +15,10 @@ import os import arcpy import sys -from SupportingFunctions import make_folder, make_layer, get_execute_error_code, write_xml_element_with_path, find_available_num_prefix import XMLBuilder reload(XMLBuilder) +from SupportingFunctions import make_folder, make_layer, get_execute_error_code, write_xml_element_with_path, find_available_num_prefix + XMLBuilder = XMLBuilder.XMLBuilder diff --git a/BRAT_table.py b/BRAT_table.py index 741c6389..0318a99a 100644 --- a/BRAT_table.py +++ b/BRAT_table.py @@ -90,9 +90,12 @@ def main( arcpy.env.outputMFlag = "Disabled" arcpy.CheckOutExtension("Spatial") + # --check input projections-- validate_inputs(seg_network, road, railroad, canal, is_verbose) + arcpy.env.outputCoordinateSystem = seg_network + # name and create output folder new_output_folder, intermediate_folder, seg_network_copy = build_output_folder(proj_path, out_name, seg_network, road, should_segment_network, ownership, segment_by_ownership, @@ -957,6 +960,8 @@ def find_distance_from_feature(out_network, feature, valley_bottom, temp_dir, bu ct = int(count.getOutput(0)) # if there are features, then set the distance from to high value (10000 m) if ct < 1: + if is_verbose: + arcpy.AddMessage('No Data found for ' + new_field_name) with arcpy.da.UpdateCursor(out_network, new_field_name) as cursor: for row in cursor: row[0] = 10000.0 @@ -966,6 +971,11 @@ def find_distance_from_feature(out_network, feature, valley_bottom, temp_dir, bu # set extent to the stream network arcpy.env.extent = out_network # calculate euclidean distance from input features + + sr = arcpy.Describe(feature_subset).spatialReference + unit = sr.linearUnitName + arcpy.AddMessage('Raster units are ' + unit) + ed_feature = EucDistance(feature_subset, cell_size = 5) # cell size of 5 m # get min distance from feature in the within 30 m buffer of each network segment if new_field_name == 'iPC_RoadX':