def add_minimum_height_above_drainage(lc_ws, lc_input_features, lc_input_surface, lc_had_field, lc_memory_switch): try: if arcpy.Exists(lc_input_features): # find minimum value in input surface # run zonal stats and get minimum DEM elevation for each polygon heightsTable = os.path.join(lc_ws, "heightsTable") if arcpy.Exists(heightsTable): arcpy.Delete_management(heightsTable) stat_type = "MINIMUM" arcpy.sa.ZonalStatisticsAsTable(lc_input_features, esri_featureID, lc_input_surface, heightsTable, "DATA", stat_type) common_lib.delete_fields(lc_input_features, [min_field]) arcpy.JoinField_management(lc_input_features, esri_featureID, heightsTable, esri_featureID, min_field) # add minimum Z information for input feature common_lib.delete_fields(lc_input_features, zmin_field) arcpy.AddZInformation_3d(lc_input_features, zmin_field, None) # calculate height above drainage surface common_lib.add_field(lc_input_features, lc_had_field, "DOUBLE", 5) expression = "round(float(!" + zmin_field + "! - !" + min_field + "!), 2)" arcpy.CalculateField_management(lc_input_features, lc_had_field, expression, "PYTHON3", None) common_lib.delete_fields(lc_input_features, [min_field]) else: msg_body = create_msg_body( "Couldn't find input feature class: " + str(lc_input_features), 0, 0) msg(msg_body, WARNING) except arcpy.ExecuteError: msgs = arcpy.GetMessages(2) # Get the tool error messages arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def template_function(local_var1, local_var2, local_verbose): if local_verbose == 1: msg("--------------------------") msg("Executing template_function...") start_time = time.clock() try: i = 0 msg_prefix = "" failed = True # your function code msg_prefix = "Function create_3Dflood_level_tbx completed successfully." failed = False return 0 except: line, filename, synerror = trace() failed = True msg_prefix = "" raise FunctionError( { "function": "create_3Dflood_level_tbx", "line": line, "filename": filename, "synerror": synerror, "arc": str(arcpy.GetMessages(2)) } ) finally: end_time = time.clock() msg_body = create_msg_body(msg_prefix, start_time, end_time) if failed: msg(msg_body, ERROR) else: if local_verbose == 1: msg(msg_body) pass
def main(): try: # Get Attributes from User if debugging == 0: ## User input input_source = arcpy.GetParameter(0) flood_elevation_attribute = arcpy.GetParameter(1) default_flood_elevation_value = arcpy.GetParameterAsText(2) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder layer_directory = home_directory + "\\layer_files" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" project_ws = aprx.defaultGeodatabase else: # debug input_source = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact\Baltimore.gdb\test_area1_slr6ft_pol' flood_elevation_attribute = FLOODELEV default_flood_elevation_value = 6 home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact' layer_directory = home_directory + "\\layer_files" rule_directory = home_directory + "\\rule_packages" log_directory = home_directory + "\\Logs" project_ws = home_directory + "\\3DFloodImpact.gdb" scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True start_time = time.clock() # check if input exists if arcpy.Exists(input_source): full_path_source = common_lib.get_full_path_from_layer( input_source) else: raise NoPolygonLayer desc = arcpy.Describe(input_source) success = set_flood_elevation_value_polygon.set_value( input_source=full_path_source, flood_elevation_attribute=flood_elevation_attribute, esri_flood_elevation_attribute=FLOODELEV, default_flood_elevation_value=default_flood_elevation_value, debug=0) end_time = time.clock() if success: msg_body = create_msg_body( "set_flood_elevation_value_tbx_polygon completed successfully.", start_time, end_time) else: msg_body = create_msg_body( "error in set_flood_elevation_value_tbx_polygon.", start_time, end_time) arcpy.ClearWorkspaceCache_management() # end main code msg(msg_body) except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoPolygonLayer: print("Can't find Raster layer. Exiting...") arcpy.AddError("Can't find Raster layer. Exiting...") except NoOutput: print("Can't create output. Exiting...") arcpy.AddError("Can't create output. Exiting...") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def main(): try: # Get Attributes from User if debugging == 0: ## User input depth_raster = arcpy.GetParameterAsText(0) dtm = arcpy.GetParameterAsText(1) smooth_factor = arcpy.GetParameter(2) output_raster = arcpy.GetParameterAsText(3) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder layer_directory = home_directory + "\\layer_files" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" project_ws = aprx.defaultGeodatabase else: # debug depth_raster = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\data\Vancouver\3DFloodImpact\depth_rasters.gdb\I_0_5pct_nodata_clip_utm' dtm = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\data\Vancouver\3DFloodImpact\Surrey_Buildings.gdb\DEM' smooth_factor = 30 output_raster = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.2.3\3DFloodImpact\Testing.gdb\FloodElevationRaster' home_directory = r'D:\\Gert\Work\\Esri\\Solutions\\3DFloodImpact\\work2.2.3\\3DFloodImpact' layer_directory = home_directory + "\\layer_files" rule_directory = home_directory + "\\rule_packages" log_directory = home_directory + "\\Logs" project_ws = home_directory + "\\3DFloodImpact.gdb" start_time = time.clock() # check if input exists if arcpy.Exists(depth_raster): full_path_source = common_lib.get_full_path_from_layer( depth_raster) flood_elevation_raster = create_flood_elevation_from_depth_raster.create_raster( depth_raster=depth_raster, dtm=dtm, smoothing=smooth_factor, output_raster=output_raster, use_in_memory=in_memory_switch, debug=debugging) if arcpy.Exists(output_raster): # output_layer = common_lib.get_name_from_feature_class(flood_elevation_raster) # arcpy.MakeRasterLayer_management(flood_elevation_raster, output_layer) # # arcpy.SetParameter(3, output_layer) end_time = time.clock() msg_body = create_msg_body( "create_flood_elevation_from_depth_raster completed successfully.", start_time, end_time) else: raise NoRasterLayer else: raise NoRasterLayer arcpy.ClearWorkspaceCache_management() # end main code msg(msg_body) except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoRasterLayer: print("Can't find Raster layer. Exiting...") arcpy.AddError("Can't find Raster layer. Exiting...") except NoOutput: print("Can't create output. Exiting...") arcpy.AddError("Can't create output. Exiting...") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def main(): try: # Get Attributes from User if debugging == 0: ## User input input_source = arcpy.GetParameterAsText(0) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder log_directory = aprx.homeFolder + "\\Logs" else: # debug input_source = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact\3DFloodImpact.gdb\WSE_01pct_testarea2' home_directory = r'D:\Gert\Work\Esri\Solutions\LocalGovernment\DevelopmentCapacity\work1.4\DevelopmentCapacity' log_directory = home_directory + "\\Logs" scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True common_lib.set_up_logging(log_directory, TOOLNAME) start_time = time.clock() if arcpy.CheckExtension("3D") == "Available": arcpy.CheckOutExtension("3D") """The source code of the tool.""" arcpy.AddMessage("Input layer: " + input_source) # check if input exists if arcpy.Exists(input_source): full_path_source = common_lib.get_full_path_from_layer( input_source) data_type, shape_type = common_lib.get_raster_featuretype_from_layer( full_path_source) if data_type == "FeatureClass": if shape_type == "Polygon": arcpy.AddMessage("!!!") arcpy.AddWarning( "Please use the 'Convert flooding polygon to raster' task to convert polygons to raster." ) arcpy.AddMessage("!!!") else: arcpy.AddWarning( "Only polygon feature classes are supported.") cs_name, cs_vcs_name, projected = common_lib.get_cs_info( full_path_source, 0) if not projected: arcpy.AddWarning( "Please re-project your input layer to a projected coordinate system." ) if not cs_vcs_name: arcpy.AddWarning( "Please define a vertical coordinate system.") else: raise NoInputLayer else: raise LicenseError3D arcpy.ClearWorkspaceCache_management() end_time = time.clock() msg_body = create_msg_body( "check_flooding_data_tbx completed successfully.", start_time, end_time) msg(msg_body) # end main code except NoInputLayer: print("Can't find Input layer. Exiting...") arcpy.AddError("Can't find Input layer. Exiting...") except NotProjected: print( "Input layer does not have a projected coordinate system. Exiting..." ) arcpy.AddWarning( "Input layer does not have a projected coordinate system. Exiting..." ) except NoOutput: print("Can't create output. Exiting...") arcpy.AddError("Can't create output. Exiting...") except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def main(): try: # Get Attributes from User if debugging == 0: # User input input_features = arcpy.GetParameterAsText(0) input_surface = arcpy.GetParameter(1) output_features = arcpy.GetParameterAsText(2) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder project_ws = aprx.defaultGeodatabase tin_directory = home_directory + "\TINs" else: input_features = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\Testing.gdb\bridges_test_surfaces' input_surface = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\ArcHydro\TSDepth\wse_28' output_features = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\Testing.gdb\bridges_HAS' home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact' project_ws = home_directory + "\\3DFloodImpact.gdb" tin_directory = home_directory + "\TINs" if os.path.exists(home_directory + "\\p20"): # it is a package home_directory = home_directory + "\\p20" if not os.path.exists(tin_directory): os.makedirs(tin_directory) arcpy.AddMessage("Project Home Directory is: " + home_directory) # set directories layer_directory = home_directory + "\\layer_files" log_directory = home_directory + "\\Logs" if not os.path.exists(log_directory): os.makedirs(log_directory) # rename layer files (for packaging) if os.path.exists(layer_directory): common_lib.rename_file_extension(layer_directory, ".txt", ".lyrx") # Create folders and intermediate gdb, if needed scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True start_time = time.clock() # check if input exists if arcpy.Exists(input_features): if arcpy.Exists(input_surface): z_values = arcpy.Describe(input_features).hasZ if z_values: # extract the elevation layers bridges, bridge_points = calculate_height_above_water_surface.calculate_height( lc_input_features=input_features, lc_ws=scratch_ws, lc_tin_dir=tin_directory, lc_input_surface=input_surface, lc_output_features=output_features, lc_log_dir=log_directory, lc_debug=verbose, lc_memory_switch=in_memory_switch) if bridges and bridge_points: # add symbology to points and add layer output_layer1 = common_lib.get_name_from_feature_class( bridges) arcpy.MakeFeatureLayer_management( bridges, output_layer1) output_layer2 = common_lib.get_name_from_feature_class( bridge_points) arcpy.MakeFeatureLayer_management( bridge_points, output_layer2) symbology_layer = layer_directory + "\\has_labels.lyrx" if arcpy.Exists(symbology_layer): arcpy.ApplySymbologyFromLayer_management( output_layer2, symbology_layer) else: msg_body = create_msg_body( "Can't find" + symbology_layer + " in " + layer_directory, 0, 0) msg(msg_body, WARNING) arcpy.SetParameter(3, output_layer1) arcpy.SetParameter(4, output_layer2) end_time = time.clock() msg_body = create_msg_body( "calculate_height_above_water_surface completed successfully.", start_time, end_time) msg(msg_body) else: end_time = time.clock() msg_body = create_msg_body( "No bridge surfaces and points created. Exiting...", start_time, end_time) msg(msg_body, WARNING) arcpy.ClearWorkspaceCache_management() if DeleteIntermediateData: fcs = common_lib.listFcsInGDB(scratch_ws) rs = common_lib.list_rasters_in_gdb( scratch_ws, verbose) msg_prefix = "Deleting intermediate data..." msg_body = common_lib.create_msg_body(msg_prefix, 0, 0) common_lib.msg(msg_body) for fc in fcs: arcpy.Delete_management(fc) for r in rs: arcpy.Delete_management(r) else: raise NoRaster else: raise No3DFeatures # end main code except No3DFeatures: # The input has no 3D features # print( '2D features are not supported. Make sure the input layer is a PolygonZ feature class.' ) arcpy.AddError( '2D features are not supported. Make sure the input layer is a PolygonZ feature class.' ) except NoRaster: # Can't find input raster # print("Can't find input raster.") arcpy.AddError("Can't find input raster.") except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoPointLayer: print("Can't find attachment points layer. Exiting...") arcpy.AddError("Can't find attachment points layer. Exiting...") except MoreThan1Selected: print( "More than 1 line selected. Please select 1 guide line only. Exiting..." ) arcpy.AddError( "More than 1 line selected. Please select 1 guide line only. Exiting..." ) except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def create_raster(input_source, depth_raster, depth_value, boundary_size, boundary_offset, output_raster, debug): try: # Get Attributes from User if debug == 0: # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder tiff_directory = home_directory + "\\Tiffs" tin_directory = home_directory + "\\Tins" scripts_directory = aprx.homeFolder + "\\Scripts" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" layer_directory = home_directory + "\\layer_files" project_ws = aprx.defaultGeodatabase enableLogging = True DeleteIntermediateData = True verbose = 0 in_memory_switch = True else: # debug home_directory = r'D:\Temporary\Flood\3DFloodImpact' tiff_directory = home_directory + "\\Tiffs" log_directory = home_directory + "\\Logs" layer_directory = home_directory + "\\LayerFiles" project_ws = home_directory + "\\Testing.gdb" enableLogging = False DeleteIntermediateData = True verbose = 1 in_memory_switch = False scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True # fail safe for Eurpose's comma's depth_value = float(re.sub("[,.]", ".", depth_value)) boundary_size = float(re.sub("[,.]", ".", boundary_size)) boundary_offset = float(re.sub("[,.]", ".", boundary_offset)) bail = 0 if debug == 1: use_in_memory = False else: use_in_memory = True common_lib.set_up_logging(log_directory, TOOLNAME) start_time = time.clock() if arcpy.CheckExtension("3D") == "Available": arcpy.CheckOutExtension("3D") if arcpy.CheckExtension("Spatial") == "Available": arcpy.CheckOutExtension("Spatial") # check if input exists if arcpy.Exists(input_source): arcpy.AddMessage( "Processing input source: " + common_lib.get_name_from_feature_class(input_source)) no_initial_depth_raster = False # create isnull from input source if use_in_memory: is_null = "in_memory/isnull_copy" else: is_null = os.path.join(scratch_ws, "isnull_copy") if arcpy.Exists(is_null): arcpy.Delete_management(is_null) # check where we have NULL values is_Null_raster = arcpy.sa.IsNull(input_source) is_Null_raster.save(is_null) # if we have a depth raster as input: make sure it overlaps with input_source if depth_raster: if arcpy.Exists(depth_raster): # Check if same spatial reference!!! if common_lib.check_same_spatial_reference( [input_source], [depth_raster]) == 1: depth_raster = None raise MixOfSR else: if use_in_memory: clip_raster = "in_memory/clip_copy" else: clip_raster = os.path.join( scratch_ws, "clip_copy") if arcpy.Exists(clip_raster): arcpy.Delete_management(clip_raster) # check extents # clip terrain to extent msg_body = create_msg_body( "Clipping depth raster to input flooding layer extent", 0, 0) msg(msg_body) arcpy.Clip_management(depth_raster, "#", clip_raster, input_source, "#", "#", "MAINTAIN_EXTENT") # TODO double check below # create IsNull to be used to check for NoData. if use_in_memory: is_null0 = "in_memory/is_null0" else: is_null0 = os.path.join( scratch_ws, "is_null0") if arcpy.Exists(is_null0): arcpy.Delete_management(is_null0) is_null_raster = arcpy.sa.IsNull(clip_raster) is_null_raster.save(is_null0) min_value = arcpy.GetRasterProperties_management( is_null0, "MINIMUM")[0] # all_nodata = arcpy.GetRasterProperties_management(clip_raster, "ALLNODATA")[0] if int(min_value) == 1: msg_body = create_msg_body( "Input rasters do not overlap.", 0, 0) msg(msg_body, WARNING) depth_raster = None else: org_depth_raster = depth_raster depth_raster = clip_raster no_initial_depth_raster = False # if depth_value > 0: # # grab set all values > 2 to default depth value # if use_in_memory: # depth_push = "in_memory/depth_push" # else: # depth_push = os.path.join(scratch_ws, "depth_push") # # if arcpy.Exists(depth_push): # arcpy.Delete_management(depth_push) # # msg_body = create_msg_body("Pushing depth > 2 to: " + str(depth_value), 0, 0) # msg(msg_body) # # depth_pushRaster = arcpy.sa.Con(clip_raster, depth_value, clip_raster, "VALUE > 2") # depth_pushRaster.save(depth_push) # # depth_raster = depth_push # else: # depth_raster = clip_raster else: depth_raster = None raise NoDepthRaster # if we don't have a depth raster: crate one based on the depth value if not depth_raster: if depth_value != 0: no_initial_depth_raster = True arcpy.AddMessage("Using default depth value of: " + str(depth_value)) # create raster from default depth value if use_in_memory: depth_raster = "in_memory/depth_value_raster" else: depth_raster = os.path.join( scratch_ws, "depth_value_raster") if arcpy.Exists(depth_raster): arcpy.Delete_management(depth_raster) # create raster from default depth value msg_body = create_msg_body( "Create depth raster from default depth value.", 0, 0) msg(msg_body) outConRaster = arcpy.sa.Con( is_null, depth_value, depth_value) outConRaster.save(depth_raster) else: bail = 1 msg_body = create_msg_body( "No depth raster and default depth value is 0. No point continuing.", 0, 0) msg(msg_body, WARNING) if bail == 0: # subtract depth raster from flood elevation raster cell_size_source = arcpy.GetRasterProperties_management( input_source, "CELLSIZEX") cell_size_depth = arcpy.GetRasterProperties_management( depth_raster, "CELLSIZEX") if cell_size_source.getOutput( 0) == cell_size_depth.getOutput(0): if arcpy.Exists(output_raster): arcpy.Delete_management(output_raster) # create raster from depth values # adjust values that are less than 0.2 if use_in_memory: depth_push = "in_memory/depth_boundary_push" depth_temp = "in_memory/depth_temp" else: depth_push = os.path.join( scratch_ws, "depth_boundary_push") if arcpy.Exists(depth_push): arcpy.Delete_management(depth_push) depth_temp = os.path.join( scratch_ws, "depth_temp") if arcpy.Exists(depth_temp): arcpy.Delete_management(depth_temp) msg_body = create_msg_body( "Adjusting boundary values by: " + str(boundary_offset), 0, 0) msg(msg_body) # add boundary offset to depth raster arcpy.Plus_3d(depth_raster, boundary_offset, depth_temp) depth_raster_object = arcpy.sa.Raster(depth_raster) # for values less than 0.2 -> grab adjusted depth raster. depth_push_Boundary_Raster = arcpy.sa.Con( depth_raster_object < 0.2, depth_temp, depth_raster) depth_push_Boundary_Raster.save(depth_push) depth_raster = depth_push if use_in_memory: clip_depth = "in_memory/clip_depth" else: clip_depth = os.path.join( scratch_ws, "clip_depth") if arcpy.Exists(clip_depth): arcpy.Delete_management(clip_depth) # create raster from default depth value msg_body = create_msg_body( "Create clip depth raster...", 0, 0) msg(msg_body) # grab depth elevation values where not null and null where is null (clip using flooding raster) outConRaster = arcpy.sa.Con( is_null, input_source, depth_raster) outConRaster.save(clip_depth) msg_body = create_msg_body( "Subtracting depth raster from input flooding raster.", 0, 0) msg(msg_body) if use_in_memory: minus_raster = "in_memory/minus_3D" else: minus_raster = os.path.join( scratch_ws, "minus_3D") if arcpy.Exists(minus_raster): arcpy.Delete_management(minus_raster) # actual subtract arcpy.Minus_3d(input_source, clip_depth, minus_raster) # now we want just the outside cells (1x cellsize) if use_in_memory: raster_polygons = "in_memory/raster_polygons" else: raster_polygons = os.path.join( scratch_ws, "raster_polygons") if arcpy.Exists(raster_polygons): arcpy.Delete_management(raster_polygons) out_geom = "POLYGON" # output geometry type arcpy.RasterDomain_3d(minus_raster, raster_polygons, out_geom) # buffer it outwards first if use_in_memory: polygons_outward = "in_memory/outward_buffer" else: polygons_outward = os.path.join( scratch_ws, "outward_buffer") if arcpy.Exists(polygons_outward): arcpy.Delete_management(polygons_outward) # x = cell_size_source.getOutput(0) x = float( re.sub("[,.]", ".", str(cell_size_source.getOutput(0)))) # x = float(str(cell_size_source.getOutput(0))) buffer_out = int(x) xy_unit = common_lib.get_xy_unit(minus_raster, 0) if xy_unit == "Feet": buffer_text = str(buffer_out) + " Feet" else: buffer_text = str(buffer_out) + " Meters" sideType = "FULL" arcpy.Buffer_analysis(raster_polygons, polygons_outward, buffer_text, sideType) # buffer it inwards so that we have a polygon only of the perimeter plus a 2 cells inward. if use_in_memory: polygons_inward = "in_memory/inward_buffer" else: polygons_inward = os.path.join( scratch_ws, "inward_buffer") if arcpy.Exists(polygons_inward): arcpy.Delete_management(polygons_inward) # x = cell_size_source.getOutput(0) x = float( re.sub("[,.]", ".", str(cell_size_source.getOutput(0)))) # x = float(str(cell_size_source.getOutput(0))) buffer_in = (boundary_size - 1) + int( 2 * x ) # boundary is always 2 cellsizes / user can't go lower than 2. xy_unit = common_lib.get_xy_unit(minus_raster, 0) if xy_unit == "Feet": buffer_text = "-" + str(buffer_in) + " Feet" else: buffer_text = "-" + str(buffer_in) + " Meters" sideType = "FULL" arcpy.Buffer_analysis(polygons_outward, polygons_inward, buffer_text, sideType) if use_in_memory: erase_polygons = "in_memory/erase" else: erase_polygons = os.path.join( scratch_ws, "erase") if arcpy.Exists(erase_polygons): arcpy.Delete_management(erase_polygons) xyTol = "1 Meters" arcpy.Erase_analysis(polygons_outward, polygons_inward, erase_polygons) msg_body = create_msg_body( "Buffering depth edges...", 0, 0) msg(msg_body) if use_in_memory: extract_mask_raster = "in_memory/extract_mask" else: extract_mask_raster = os.path.join( scratch_ws, "extract_mask") if arcpy.Exists(extract_mask_raster): arcpy.Delete_management( extract_mask_raster) extract_temp_raster = arcpy.sa.ExtractByMask( minus_raster, erase_polygons) extract_temp_raster.save(extract_mask_raster) if no_initial_depth_raster == True: if use_in_memory: plus_mask = "in_memory/plus_mask" else: plus_mask = os.path.join( scratch_ws, "plus_mask") if arcpy.Exists(plus_mask): arcpy.Delete_management(plus_mask) arcpy.Plus_3d(extract_mask_raster, (depth_value - 1), plus_mask) extract_mask_raster = plus_mask if use_in_memory: minus_raster2 = "in_memory/minus_3D2" else: minus_raster2 = os.path.join( scratch_ws, "minus_3D2") if arcpy.Exists(minus_raster2): arcpy.Delete_management(minus_raster2) # push depth elevation raster down by default depth value if depth_value > 0 and no_initial_depth_raster == False: msg_body = create_msg_body( "Pushing inner depth down by: " + str(depth_value) + " to prevent z-fighting.", 0, 0) msg(msg_body) arcpy.Minus_3d(minus_raster, depth_value, minus_raster2) else: minus_raster2 = minus_raster if 0: #use_in_memory: mosaic_raster = "in_memory/mosaic" else: mosaic_raster = os.path.join( scratch_ws, "mosaic") if arcpy.Exists(mosaic_raster): arcpy.Delete_management(mosaic_raster) listRasters = [] listRasters.append(extract_mask_raster) listRasters.append(minus_raster2) desc = arcpy.Describe(listRasters[0]) # grab the original outside cells and the pushed down depth elevation raster arcpy.MosaicToNewRaster_management( listRasters, os.path.dirname(mosaic_raster), os.path.basename(mosaic_raster), desc.spatialReference, "32_BIT_FLOAT", x, 1, "FIRST", "") # now we do an isnull on raster domain poly assignmentType = "CELL_CENTER" priorityField = "#" # Execute PolygonToRaster calc_field = "value_field" common_lib.delete_add_field( raster_polygons, calc_field, "DOUBLE") arcpy.CalculateField_management( raster_polygons, calc_field, 1, "PYTHON_9.3") if use_in_memory: poly_raster = "in_memory/poly_raster" else: poly_raster = os.path.join( scratch_ws, "poly_raster") if arcpy.Exists(poly_raster): arcpy.Delete_management(poly_raster) arcpy.PolygonToRaster_conversion( raster_polygons, calc_field, poly_raster, assignmentType, priorityField, x) # create isnull if use_in_memory: is_null2 = "in_memory/isnull_copy2" else: is_null2 = os.path.join( scratch_ws, "isnull_copy2") if arcpy.Exists(is_null2): arcpy.Delete_management(is_null2) is_Null_raster2 = arcpy.sa.IsNull(poly_raster) is_Null_raster2.save(is_null2) # con on mosaic finalRaster = arcpy.sa.Con(is_null2, poly_raster, mosaic_raster) finalRaster.save(output_raster) else: arcpy.AddWarning( "Cell size of " + common_lib.get_name_from_feature_class( input_source) + " is different than " + org_depth_raster + ". Exiting...") output_raster = None if use_in_memory: arcpy.Delete_management("in_memory") else: # use default depth value raise NoInputLayer end_time = time.clock() msg_body = create_msg_body( "Set Flood Elevation Value for Raster completed successfully.", start_time, end_time) msg(msg_body) arcpy.ClearWorkspaceCache_management() return output_raster else: raise LicenseErrorSpatial else: raise LicenseError3D arcpy.ClearWorkspaceCache_management() except MixOfSR: # The input has mixed SR # print(( 'Input data has mixed spatial references. Ensure all input is in the same spatial reference, including the same vertical units.' )) arcpy.AddError( 'Input data has mixed spatial references. Ensure all input is in the same spatial reference, including the same vertical units.' ) except NoInputLayer: print("Can't find Input layer. Exiting...") arcpy.AddError("Can't find Input layer. Exiting...") except NoDepthRaster: print("Can't find Depth raster. Exiting...") arcpy.AddError("Can't find depth raster. Exiting...") except NotProjected: print( "Input data needs to be in a projected coordinate system. Exiting..." ) arcpy.AddError( "Input data needs to be in a projected coordinate system. Exiting..." ) except NoLayerFile: print("Can't find Layer file. Exiting...") arcpy.AddError("Can't find Layer file. Exiting...") except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except LicenseErrorSpatial: print("Spatial Analyst license is unavailable") arcpy.AddError("Spatial Analyst license is unavailable") except NoNoDataError: print("Input raster does not have NODATA values") arcpy.AddError("Input raster does not have NODATA values") except NoUnits: print("No units detected on input data") arcpy.AddError("No units detected on input data") except NoPolygons: print("Input data can only be polygon features or raster datasets.") arcpy.AddError( "Input data can only be polygon features or raster datasets.") except ValueError: print("Input no flood value is not a number.") arcpy.AddError("Input no flood value is not a number.") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D") arcpy.CheckInExtension("Spatial")
def calculate_height(lc_input_features, lc_ws, lc_tin_dir, lc_input_surface, lc_output_features, lc_log_dir, lc_debug, lc_memory_switch): try: # create dem desc = arcpy.Describe(lc_input_features) if desc.spatialReference.linearUnitName in ['Foot_US', 'Foot']: unit = 'Feet' else: unit = 'Meters' # Generate raster from lasd if arcpy.Exists(lc_input_features): if arcpy.Exists(lc_output_features): arcpy.Delete_management(lc_output_features) # make a copy bridge_polys = lc_output_features + "_height" if arcpy.Exists(bridge_polys): arcpy.Delete_management(bridge_polys) arcpy.CopyFeatures_management(lc_input_features, bridge_polys) # create string field for featureFID oidFieldName = arcpy.Describe(bridge_polys).oidFieldName common_lib.delete_add_field(bridge_polys, esri_featureID, "TEXT") arcpy.CalculateField_management(bridge_polys, esri_featureID, "!" + oidFieldName + "!", "PYTHON_9.3") msg_body = create_msg_body( "Calculating height above surface for: " + common_lib.get_name_from_feature_class(lc_input_features), 0, 0) msg(msg_body) # create bridge tin out_tin = os.path.join(lc_tin_dir, "bridge_tin") if arcpy.Exists(out_tin): arcpy.Delete_management(out_tin) msg_body = create_msg_body( "Creating raster for: " + common_lib.get_name_from_feature_class(lc_input_features), 0, 0) msg(msg_body) arcpy.CreateTin_3d( out_tin, arcpy.Describe(bridge_polys).spatialReference, "{} Shape.Z Hard_Clip <None>".format(bridge_polys), "DELAUNAY") # turn to raster if 0: bridge_raster = "in_memory/bridge_raster" else: bridge_raster = os.path.join(lc_ws, "bridge_raster") if arcpy.Exists(bridge_raster): arcpy.Delete_management(bridge_raster) # use same cell size as input surface cell_size = arcpy.GetRasterProperties_management( lc_input_surface, "CELLSIZEX")[0] dataType = "FLOAT" method = "LINEAR" sampling = "CELLSIZE " + str(cell_size) zfactor = "1" arcpy.TinRaster_3d(out_tin, bridge_raster, dataType, method, sampling, zfactor) add_minimum_height_above_water_surface(lc_ws, bridge_polys, bridge_raster, lc_input_surface, lc_memory_switch) # create point file for labeling if lc_memory_switch: bridge_points = "in_memory/bridge_points" else: bridge_points = os.path.join(lc_ws, "bridge_points") if arcpy.Exists(bridge_points): arcpy.Delete_management(bridge_points) arcpy.FeatureToPoint_management(bridge_polys, bridge_points, "INSIDE") bridge_points3D = lc_output_features + "_points_3D" if arcpy.Exists(bridge_points3D): arcpy.Delete_management(bridge_points3D) # create 3D point arcpy.FeatureTo3DByAttribute_3d(bridge_points, bridge_points3D, zmin_field) # add unit field common_lib.delete_add_field(bridge_points3D, esri_unit, "TEXT") expression = """{} IS NOT NULL""".format( arcpy.AddFieldDelimiters(bridge_points3D, has_field)) # select all points with good elevation values local_layer = common_lib.get_name_from_feature_class( bridge_points3D) + "_lyr" select_lyr = arcpy.MakeFeatureLayer_management( bridge_points3D, local_layer).getOutput(0) arcpy.SelectLayerByAttribute_management(select_lyr, "NEW_SELECTION", expression, None) z_unit = common_lib.get_z_unit(bridge_points3D, lc_debug) if z_unit == "Meters": expression = "'m'" else: expression = "'ft'" arcpy.CalculateField_management(select_lyr, esri_unit, expression, "PYTHON_9.3") arcpy.SelectLayerByAttribute_management(select_lyr, "CLEAR_SELECTION") common_lib.delete_fields(bridge_polys, [min_field, zmin_field]) common_lib.delete_fields(bridge_points3D, [min_field, zmin_field]) return bridge_polys, bridge_points3D else: msg_body = create_msg_body( "Couldn't find input feature class: " + str(lc_input_features), 0, 0) msg(msg_body, WARNING) return None except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def makeTowersAndJunctions(lc_scratch_ws, lc_rule_dir, lc_input_features, lc_testLineWeight, lc_sag_to_span_ratio, lc_horizontal_tension, lc_tower_configuration, lc_ends, lc_output_features, lc_debug, lc_use_in_memory): try: # Making Tower configuration object to hold fields for TowerBasePoints layer. towerConfiguration = lc_tower_configuration geometry_type = "POINT" has_m = "DISABLED" has_z = "ENABLED" in_memory = "in_memory" tower_placement_points_name = "TowerLocations" out_tower_models_name = "TowerModels" junction_intoFFCER = "JunctionPoints" junction_points_name = "JunctionPoints" CE_additionP = "_Points" CE_additionMP = "_MPoints" CE_additionL = "_Lines" spans_name = "Spans" exportPointsRPK = lc_rule_dir + "\\" + "TransmissionTower_ExportPoints.rpk" exportModelsRPK = lc_rule_dir + "\\" + "TransmissionTower_ExportModel.rpk" spatial_reference = arcpy.Describe(lc_input_features).spatialReference # create empty feature class with required fields msg_body = create_msg_body("Preparing output feature classes...", 0, 0) msg(msg_body) # create / check out features classes # tower placement points outTowerPlacementPoints = lc_output_features + "_" + tower_placement_points_name if arcpy.Exists(outTowerPlacementPoints): arcpy.Delete_management(outTowerPlacementPoints) # tower models: multipatches generated from tower placement points outTowerModels = lc_output_features + "_" + out_tower_models_name if arcpy.Exists(outTowerModels): arcpy.Delete_management(outTowerModels) outJunctionPointsFromFFCER = lc_output_features + "_" + junction_points_name if arcpy.Exists(outJunctionPointsFromFFCER): arcpy.Delete_management(outJunctionPointsFromFFCER) # output spans outSpansIntoScript = lc_output_features + "_" + spans_name if arcpy.Exists(outSpansIntoScript): arcpy.Delete_management(outSpansIntoScript) # NOTE: these items are used to create attributes and values must correspond to # TowerConfiguration attributes. If this list changes you must update TowerConfiguration object class # Tower RPK Fields, in TowerBasePoints layer. tower_number_field = "TowerNumber" units_field = "Units" cardinal_direction_field = "Cardinal_Direction" line_type_field = "Line_Type" structure_type_field = "Structure_Type" voltage_field = "Voltage" circuits_field = "Circuits" alignment_field = "Alignment" conductor_vertical_clearance_field = "Conductor_Vertical_Clearance" conductor_horizontal_clearance_field = "Conductor_Horizontal_Clearance" minimum_ground_clearance_field = "Minimum_Ground_Clearance" maximum_sag_allowance_field = "Maximum_Sag_Allowance" shield_wires_field = "Shield_Wires" insulator_hang_type_field = "Insulator_Hang_Type" beam_color_field = "Beam_Color" tower_material = "DistPole_Material" tower_base_point_field_dict = {cardinal_direction_field:"DOUBLE", tower_number_field:"LONG", line_type_field:"TEXT", structure_type_field:"TEXT", voltage_field:"TEXT", circuits_field:"LONG", alignment_field:"TEXT", conductor_vertical_clearance_field:"FLOAT", conductor_horizontal_clearance_field:"FLOAT", minimum_ground_clearance_field:"FLOAT", maximum_sag_allowance_field:"FLOAT", shield_wires_field:"LONG", insulator_hang_type_field:"TEXT", beam_color_field:"TEXT", units_field:"TEXT", tower_material: "TEXT" } catenary = None fieldList = ["SHAPE@"] fieldAccess = utils.FieldAccess(fieldList) num_features = int(arcpy.GetCount_management(lc_input_features).getOutput(0)) lineCursor = arcpy.da.SearchCursor(lc_input_features, fieldList) i = 1 for row in lineCursor: if lc_use_in_memory: arcpy.AddMessage("Using in memory for processing") # junctions points needed for FFCER outJunctionPointsIntoFFCER = in_memory + "/" + junction_intoFFCER else: # junctions points needed for makeSpans: FFCER generates 3D points with _Points in name outJunctionPointsIntoFFCER = os.path.join(lc_scratch_ws, junction_intoFFCER) if arcpy.Exists(outJunctionPointsIntoFFCER): arcpy.Delete_management(outJunctionPointsIntoFFCER) # delete additional CE output if arcpy.Exists(outJunctionPointsIntoFFCER + CE_additionP): arcpy.Delete_management(outJunctionPointsIntoFFCER + CE_additionP) if arcpy.Exists(outJunctionPointsIntoFFCER + CE_additionMP): arcpy.Delete_management(outJunctionPointsIntoFFCER + CE_additionMP) if arcpy.Exists(outJunctionPointsIntoFFCER + CE_additionL): arcpy.Delete_management(outJunctionPointsIntoFFCER + CE_additionL) # create temporary per line feature classes # temp tower placement points if lc_use_in_memory: arcpy.AddMessage("Using in memory for processing") temp_outTowerPlacementPoints = in_memory + "/" + tower_placement_points_name + "_temp" else: temp_outTowerPlacementPoints = os.path.join(lc_scratch_ws, tower_placement_points_name + "_temp") # first time delete just to be sure if i == 1 and arcpy.Exists(temp_outTowerPlacementPoints): arcpy.Delete_management(temp_outTowerPlacementPoints) if arcpy.Exists(temp_outTowerPlacementPoints): arcpy.TruncateTable_management(temp_outTowerPlacementPoints) else: temp_outtowerPlacementPoints_dirname = os.path.dirname(temp_outTowerPlacementPoints) temp_outtowerPlacementPoints_basename = os.path.basename(temp_outTowerPlacementPoints) arcpy.CreateFeatureclass_management(temp_outtowerPlacementPoints_dirname, temp_outtowerPlacementPoints_basename, geometry_type, "", has_m, has_z, spatial_reference) # add required fields for towerPlacementPoints arcpy.AddMessage("Adding required fields to tower placement points...") start_time = time.clock() # for k, v in tower_base_point_field_dict.items(): # common_lib.delete_add_field(temp_outTowerPlacementPoints, k, v) listoffields = [] for k, v in tower_base_point_field_dict.items(): field = [] field.append(k) field.append(v) listoffields.append(field) arcpy.management.AddFields(temp_outTowerPlacementPoints, listoffields) end_time = time.clock() msg_body = create_msg_body("Time to create fields...", start_time, end_time) msg(msg_body) # temp tower models: multipatches generated from tower placement points if lc_use_in_memory: arcpy.AddMessage("Using in memory for processing") temp_outTowerModels = in_memory + "/" + out_tower_models_name + "_temp" else: temp_outTowerModels = os.path.join(lc_scratch_ws, out_tower_models_name + "_temp") if arcpy.Exists(temp_outTowerModels): arcpy.Delete_management(temp_outTowerModels) if lc_use_in_memory: arcpy.AddMessage("Using in memory for processing") temp_outJunctionPointsFromFFCER = in_memory + "/" + out_tower_models_name + "_temp" else: temp_outJunctionPointsFromFFCER = os.path.join(lc_scratch_ws, junction_points_name + "_temp") if arcpy.Exists(temp_outJunctionPointsFromFFCER): arcpy.Delete_management(temp_outJunctionPointsFromFFCER) # output temp spans if lc_use_in_memory: arcpy.AddMessage("Using in memory for processing") temp_outSpansIntoScript = in_memory + "/" + spans_name + "_temp" else: temp_outSpansIntoScript = os.path.join(lc_scratch_ws, spans_name + "_temp") if arcpy.Exists(temp_outSpansIntoScript): arcpy.Delete_management(temp_outSpansIntoScript) # multiple lines are now supported... if i >= 0: fieldAccess.setRow(row) arcpyPolyline = fieldAccess.getValue("SHAPE@") # read the line vgPolyline = vg.arcpyPolylineToVGPolyline(arcpyPolyline) if vgPolyline: # get tower point objects here. Initializing TowerPlacementLine builds the TowerBasePoints. # from towerConfiguration pint("Preparing tower base points for feature: " + str(i) + " out of " + str(num_features) + ".") towerPlacementLine = TowerPlacementLine(vgPolyline, towerConfiguration, lc_sag_to_span_ratio, lc_horizontal_tension, lc_testLineWeight, lc_ends) towerBasePoints = towerPlacementLine.towerBasePoints # put the tower base points into the scene. InsertTowerBasePoints(towerBasePoints, towerConfiguration, temp_outTowerPlacementPoints, list(tower_base_point_field_dict.keys())) arcpy.ddd.FeaturesFromCityEngineRules(temp_outTowerPlacementPoints, exportPointsRPK, outJunctionPointsIntoFFCER, "DROP_EXISTING_FIELDS", "INCLUDE_REPORTS", "FEATURE_PER_LEAF_SHAPE") # TODO built in check when FFCER fails XX Gert # copy _Points fc to input gdb arcpy.CopyFeatures_management(outJunctionPointsIntoFFCER + CE_additionP, temp_outJunctionPointsFromFFCER) arcpy.ddd.FeaturesFromCityEngineRules(temp_outTowerPlacementPoints, exportModelsRPK, temp_outTowerModels, "INCLUDE_EXISTING_FIELDS", "EXCLUDE_REPORTS", "FEATURE_PER_SHAPE") pint("Making spans for feature: " + str(i) + " out of " + str(num_features) + ".") catenary, guide_lines = create_3D_catenary.makeSpans(lc_scratch_ws=lc_scratch_ws, lc_inPoints=temp_outJunctionPointsFromFFCER, lc_testLineWeight=lc_testLineWeight, lc_sag_to_span_ratio=lc_sag_to_span_ratio, lc_horizontal_tension=lc_horizontal_tension, lc_output_features=temp_outSpansIntoScript, lc_debug=lc_debug, lc_use_in_memory=False, lc_cleanup=False, lc_caller=TOOLNAME) # append features to output feature classes # catenary, outTowerModels, outJunctionPointsFromFFCER, outTowerPlacementPoints schemaType = "NO_TEST" if arcpy.Exists(outSpansIntoScript): arcpy.Append_management(catenary, outSpansIntoScript, schemaType) else: arcpy.Copy_management(catenary, outSpansIntoScript) pint("Made spans for feature: " + str(i) + " out of " + str(num_features) + ".") if arcpy.Exists(outTowerModels): arcpy.Append_management(temp_outTowerModels, outTowerModels, schemaType) else: arcpy.Copy_management(temp_outTowerModels, outTowerModels) pint("Made towers for feature: " + str(i) + " out of " + str(num_features) + ".") if arcpy.Exists(outJunctionPointsFromFFCER): arcpy.Append_management(temp_outJunctionPointsFromFFCER, outJunctionPointsFromFFCER, schemaType) else: arcpy.Copy_management(temp_outJunctionPointsFromFFCER, outJunctionPointsFromFFCER) pint("Made junctions for feature: " + str(i) + " out of " + str(num_features) + ".") if arcpy.Exists(outTowerPlacementPoints): arcpy.Append_management(temp_outTowerPlacementPoints, outTowerPlacementPoints, schemaType) else: arcpy.Copy_management(temp_outTowerPlacementPoints, outTowerPlacementPoints) else: raise MultipartInputNotSupported i += 1 return outSpansIntoScript, outTowerModels, outJunctionPointsFromFFCER, outTowerPlacementPoints except MultipartInputNotSupported: print("Multipart features are not supported. Exiting...") arcpy.AddError("Multipart features are not supported. Exiting...") except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0])) pass
def main(): try: # Get Attributes from User if debugging == 0: ## User input input_source = arcpy.GetParameter(0) no_flood_value = arcpy.GetParameterAsText(1) flood_elevation_value = arcpy.GetParameterAsText(2) output_features = arcpy.GetParameterAsText(3) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder layer_directory = home_directory + "\\layer_files" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" project_ws = aprx.defaultGeodatabase else: # debug input_source = r'D:\\Gert\\Work\\Esri\\Solutions\\3DFloodImpact\\work2.1\\3DFloodImpact\\3DFloodImpact.gdb\\WSE_01pct_testarea2' flood_elevation_value = "5" no_flood_value = "NoData" output_features = r'D:\\Gert\\Work\\Esri\\Solutions\\3DFloodImpact\\work2.1\\3DFloodImpact\\Testing.gdb\\FloodElevationRaster' home_directory = r'D:\\Gert\Work\\Esri\\Solutions\\3DFloodImpact\\work2.1\\3DFloodImpact' layer_directory = home_directory + "\\layer_files" rule_directory = home_directory + "\\rule_packages" log_directory = home_directory + "\\Logs" project_ws = home_directory + "\\3DFloodImpact.gdb" scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True start_time = time.clock() # check if input exists if arcpy.Exists(input_source): full_path_source = common_lib.get_full_path_from_layer(input_source) else: raise NoRasterLayer desc = arcpy.Describe(input_source) flood_raster = set_flood_elevation_value_raster.set_value(input_source=full_path_source, no_flood_value=no_flood_value, flood_elevation_value=flood_elevation_value, output_raster=output_features, debug=0) if arcpy.Exists(flood_raster): output_layer = common_lib.get_name_from_feature_class(flood_raster) arcpy.MakeRasterLayer_management(flood_raster, output_layer) arcpy.SetParameter(4, output_layer) end_time = time.clock() msg_body = create_msg_body("set_flood_elevation_value_raster_tbx completed successfully.", start_time, end_time) else: raise NoRasterLayer arcpy.ClearWorkspaceCache_management() # end main code msg(msg_body) except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoRasterLayer: print("Can't find Raster layer. Exiting...") arcpy.AddError("Can't find Raster layer. Exiting...") except NoOutput: print("Can't create output. Exiting...") arcpy.AddError("Can't create output. Exiting...") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def main(): try: # Get Attributes from User if debugging == 0: ## User input input_source = arcpy.GetParameter(0) line_weight = arcpy.GetParameterAsText(1) horizontal_tension = arcpy.GetParameterAsText(2) output_features = arcpy.GetParameterAsText(3) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder layer_directory = home_directory + "\\layer_files" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" project_ws = aprx.defaultGeodatabase else: # debug input_source = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2.3\Transmission_Lines\Seattle_Utility_Sample.gdb\Attachment_Points' line_weight = 1.096 horizontal_tension = 4500 output_features = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2.3\Transmission_Lines\Testing.gdb\catenary3D' home_directory = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2.3\Transmission_Lines' layer_directory = home_directory + "\\layer_files" rule_directory = home_directory + "\\rule_packages" log_directory = home_directory + "\\Logs" project_ws = home_directory + "\\\Transmission_Lines.gdb" scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True start_time = time.clock() default_SagToSpanRatio = 0.035 # This number is used in the book. TODO make this user variable sag_to_span_ratio = default_SagToSpanRatio # check if input exists if arcpy.Exists(input_source): # make a copy to grab the selection # make new feature classes of observer and target input fcs. This is because FFCER doesn't work with selections arcpy.AddMessage( "Processing input source: " + common_lib.get_name_from_feature_class(input_source)) input_source_copy = os.path.join(scratch_ws, "attachment_points_copy") if arcpy.Exists(input_source_copy): arcpy.Delete_management(input_source_copy) msg_body = create_msg_body( "Making copy of " + common_lib.get_name_from_feature_class(input_source) + " in " + scratch_ws, 0, 0) msg(msg_body) arcpy.CopyFeatures_management(input_source, input_source_copy) else: raise NoPointLayer desc = arcpy.Describe(input_source) catenary, guide_lines = create_3D_catenary.makeSpans( lc_scratch_ws=scratch_ws, lc_inPoints=input_source_copy, lc_testLineWeight=float(line_weight), lc_sag_to_span_ratio=sag_to_span_ratio, lc_horizontal_tension=float(horizontal_tension), lc_output_features=output_features, lc_debug=verbose, lc_use_in_memory=False, lc_cleanup=True, lc_caller=TOOLNAME) end_time = time.clock() if catenary and guide_lines: if arcpy.Exists(catenary) and arcpy.Exists(guide_lines): # create layer, set layer file # apply transparency here // checking if symbology layer is present z_unit = common_lib.get_z_unit(catenary, verbose) if z_unit == "Feet": catenarySymbologyLayer = layer_directory + "\\catenary3Dfeet.lyrx" else: catenarySymbologyLayer = layer_directory + "\\catenary3Dmeter.lyrx" output_layer1 = common_lib.get_name_from_feature_class( catenary) arcpy.MakeFeatureLayer_management(catenary, output_layer1) if arcpy.Exists(catenarySymbologyLayer): arcpy.ApplySymbologyFromLayer_management( output_layer1, catenarySymbologyLayer) else: msg_body = create_msg_body( "Can't find" + catenarySymbologyLayer + " in " + layer_directory, 0, 0) msg(msg_body, WARNING) if z_unit == "Feet": guidelinesSymbologyLayer = layer_directory + "\\guidelines3Dfeet.lyrx" else: guidelinesSymbologyLayer = layer_directory + "\\guidelines3Dmeter.lyrx" output_layer2 = common_lib.get_name_from_feature_class( guide_lines) arcpy.MakeFeatureLayer_management(guide_lines, output_layer2) if arcpy.Exists(guidelinesSymbologyLayer): arcpy.ApplySymbologyFromLayer_management( output_layer2, guidelinesSymbologyLayer) else: msg_body = create_msg_body( "Can't find" + guidelinesSymbologyLayer + " in " + layer_directory, 0, 0) msg(msg_body, WARNING) if output_layer1: if z_unit == "Feet": arcpy.SetParameter(4, output_layer1) else: arcpy.SetParameter(5, output_layer1) else: raise NoCatenaryOutput if output_layer2: if z_unit == "Feet": arcpy.SetParameter(6, output_layer2) else: arcpy.SetParameter(7, output_layer2) else: raise NoGuideLinesOutput end_time = time.clock() msg_body = create_msg_body( "create_3D_catenary_tbx completed successfully.", start_time, end_time) msg(msg_body) else: end_time = time.clock() msg_body = create_msg_body( "No catenary or guide_lines created. Exiting...", start_time, end_time) msg(msg_body, WARNING) else: end_time = time.clock() msg_body = create_msg_body( "No catenary or guide_lines created. Exiting...", start_time, end_time) msg(msg_body, WARNING) arcpy.ClearWorkspaceCache_management() # end main code msg(msg_body) except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoPointLayer: print("Can't find attachment points layer. Exiting...") arcpy.AddError("Can't find attachment points layer. Exiting...") except NoCatenaryOutput: print("Can't create Catenary output. Exiting...") arcpy.AddError("Can't Catenary output. Exiting...") except NoGuideLinesOutput: print("Can't create GuideLines output. Exiting...") arcpy.AddError("Can't create GuideLines. Exiting...") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def main(): try: # Get Attributes from User if debugging == 0: ## User input input_source = arcpy.GetParameter(0) no_flood_value = arcpy.GetParameterAsText(1) baseline_elevation_raster = arcpy.GetParameter(2) baseline_elevation_value = arcpy.GetParameterAsText(3) smooth_factor = arcpy.GetParameter(4) output_features = arcpy.GetParameterAsText(5) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder layer_directory = home_directory + "\\layer_files" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" project_ws = aprx.defaultGeodatabase else: # debug input_source = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\3DFloodImpact.gdb\slr_6_ProjectRaster' no_flood_value = "NoData" baseline_elevation_raster = r'' baseline_elevation_value = "0" smooth_factor = 0 output_features = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\3DFloodImpact.gdb\FloodPolys' home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact' layer_directory = home_directory + "\\layer_files" rule_directory = home_directory + "\\rule_packages" log_directory = home_directory + "\\Logs" project_ws = home_directory + "\\3DFloodImpact.gdb" scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True start_time = time.clock() if arcpy.CheckExtension("3D") == "Available": arcpy.CheckOutExtension("3D") # check if input exists if arcpy.Exists(input_source): full_path_source = common_lib.get_full_path_from_layer(input_source) else: raise NoRasterLayer # check if input exists if arcpy.Exists(baseline_elevation_raster): full_path_baseline_raster = common_lib.get_full_path_from_layer(baseline_elevation_raster) else: full_path_baseline_raster = None desc = arcpy.Describe(input_source) flood_polygons = create_3Dflood_level.flood_from_raster(input_source=full_path_source, input_type=desc.dataType, no_flood_value=no_flood_value, baseline_elevation_raster=full_path_baseline_raster, baseline_elevation_value=baseline_elevation_value, outward_buffer=0, output_polygons=output_features, smoothing=smooth_factor, debug=debugging) # create layer, set layer file # apply transparency here // checking if symbology layer is present z_unit = common_lib.get_z_unit(flood_polygons, verbose) if z_unit == "Feet": floodSymbologyLayer = layer_directory + "\\flood3Dfeet.lyrx" else: floodSymbologyLayer = layer_directory + "\\flood3Dmeter.lyrx" output_layer = common_lib.get_name_from_feature_class(flood_polygons) arcpy.MakeFeatureLayer_management(flood_polygons, output_layer) if arcpy.Exists(floodSymbologyLayer): arcpy.ApplySymbologyFromLayer_management(output_layer, floodSymbologyLayer) else: msg_body = create_msg_body("Can't find" + floodSymbologyLayer + " in " + layer_directory, 0, 0) msg(msg_body, WARNING) if output_layer: if z_unit == "Feet": arcpy.SetParameter(6, output_layer) else: arcpy.SetParameter(7, output_layer) else: raise NoOutput end_time = time.clock() msg_body = create_msg_body("create_3Dflood_level_tbx completed successfully.", start_time, end_time) else: raise LicenseError3D arcpy.ClearWorkspaceCache_management() # end main code msg(msg_body) except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoRasterLayer: print("Can't find Raster layer. Exiting...") arcpy.AddError("Can't find Raster layer. Exiting...") except NoOutput: print("Can't create output. Exiting...") arcpy.AddError("Can't create output. Exiting...") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def makeSpan(fromPoint, toPoint, lc_includedTransmissionLineGuides, lc_testLineWeight, sagToSpanRatio, sagDistance, horizontalTension): try: span = Span(fromPoint, toPoint) # Define span shape here, then set polyline on Span object. spanVector3D = vg.getVectorFromTwoPoints(fromPoint, toPoint) spanLength3D = vg.magnitude(spanVector3D) spanVector2DNoZ = vg.Vector(spanVector3D.x, spanVector3D.y, 0) spanLength2D = vg.magnitude(spanVector2DNoZ) fromTower = fromPoint.towerNumber toTower = toPoint.towerNumber lineNumber = fromPoint.lineNumber attachmentPointHeightDifference = abs(toPoint.z - fromPoint.z) lineWeightPerUnitLength = lc_testLineWeight # NOTE: The logic below depends on which script calls the function. # When called from create_3D_catenary(this script), inside makeSpans() function, # new spans are created based on horizontal tension, and sagDistance is calculated. # When called from adjust_3D: # It is called once with sagDistance of None which triggers use of line guide. # Once sagDistance is known, if "adjust all" tool option is used, then sagDistance is used to # make the matching spans, so sagDistance is not None. w = lineWeightPerUnitLength H = None # When called from create_3D_catenary_from_line, GP tool might send sagToSpanRatio: if sagToSpanRatio is not None: D = sagToSpanRatio * spanLength2D # When called from create_3D_catenary_from_line, GP tool might send horizontal tension: elif horizontalTension is not None: # Using sag approximation until I find better formula. # XX This method doesn't work with the degree of accuracy needed, but is close enough and will be visually corrected. H = horizontalTension catenaryConstant = H/w sOver2 = spanLength3D/2 inverseCatenaryConstant = w/H coshValue = math.cosh(sOver2 * inverseCatenaryConstant) coshValueMinusOne = coshValue - 1 sagApproximation = catenaryConstant * coshValueMinusOne D = sagApproximation # When called from adjust_3D_catenary the first time sagDistance is None: elif sagDistance is None and lc_includedTransmissionLineGuides is not None: # Query LineGuides for line with matching from, to, and line. fieldListLineGuides = ["SHAPE@", "FromTower", "ToTower", "LineNumber"] fieldAccessLineGuides = utils.FieldAccess(fieldListLineGuides) whereClauseLineGuides = "FromTower = " + str(fromTower) + " and ToTower = " + str( toTower) + " and LineNumber = " + str(lineNumber) cursor = arcpy.da.SearchCursor(lc_includedTransmissionLineGuides, fieldListLineGuides, whereClauseLineGuides) msg_body = create_msg_body("Creating span for line number " + str(lineNumber) + " from tower " + str( fromTower) + " to tower " + str(toTower) + ".", 0, 0) msg(msg_body) # default lineGuideZ for when none exists. This ensures no square root of zero causes error. # XX In what part? The calculation of D, I guess. # XX This brings up a question... Will this entire function work if both points are at same z? That would be very unlikely. lineGuideZ = None if fromPoint.z > toPoint.z: defaultLineGuideZ = toPoint.z - 10 else: defaultLineGuideZ = fromPoint.z - 10 for row in cursor: fieldAccessLineGuides.setRow(row) lineGuideShape = fieldAccessLineGuides.getValue("SHAPE@") lineGuide = vg.arcpyPolylineToVGPolyline(lineGuideShape) lineGuideZ = lineGuide.nodes[0].z if cursor: del cursor # If no user line exists, this span has not been run yet, so use default. # Only issue warning if user-adjusted line is above either attachment point. if lineGuideZ is None: lineGuideZ = defaultLineGuideZ elif lineGuideZ > fromPoint.z or lineGuideZ > toPoint.z: arcpy.AddWarning("Warning: Match line placed above lowest point.") lineGuideZ = defaultLineGuideZ # Redundant with Tension case above: if fromPoint.z > toPoint.z: dLow = toPoint.z - lineGuideZ hSign = 1 else: dLow = fromPoint.z - lineGuideZ hSign = -1 h = attachmentPointHeightDifference dHigh = dLow + h h_over4 = (h / 4) * hSign sqrtDLow = math.sqrt(dLow) sqrtDHigh = math.sqrt(dHigh) lowPlusHigh = sqrtDLow + sqrtDHigh lowMinusHigh = sqrtDLow - sqrtDHigh lowPlusHigh_over_lowMinusHigh = lowPlusHigh / lowMinusHigh D = h_over4 * lowPlusHigh_over_lowMinusHigh else: # When called from adjust_3D_catenary the second time, sagDistance is supplied: D = sagDistance ############################################################# ############################################################# # Sag is determined now. # The next part creates a function to calculate the catenary height (z-value) along a 2D line from tower to tower. # variables from the diagram: S = spanLength2D h = attachmentPointHeightDifference w = lineWeightPerUnitLength # lb/ft xHigh = (S / 2) * (1 + (h / (4 * D))) xLow = (S / 2) * (1 - (h / (4 * D))) dHigh = D * pow((1 + (h / (4 * D))), 2) # D sub L in book. dLow = D * pow((1 - (h / (4 * D))), 2) # D sub R in book. # XX This is reversed, because the book chose left and right, rather than high and low. if H is None: # else horizontal tension was supplied. hLow = (w * pow(xLow, 2)) / (2 * dLow) #hHigh = (w * pow(xHigh, 2)) / (2 * dHigh) H = hLow # or hHigh, because they must be equal. # Use external function for 3D polyline (below). makeSpanPolylineShapeAndLineGuide(span, xHigh, xLow, dHigh, dLow, H, w) # LineLength (uses these values from above calculations): # S = spanLength2D # xLow, xHigh # w = lineWeightPerUnitLength # H = Horizontal tension xRcubed_plus_xLcubed = pow(abs(xLow), 3) + pow(xHigh, 3) #XX note the abs! wSquared_over_6HSquared = pow(w, 2) / (6 * pow(H, 2)) L = S + (xRcubed_plus_xLcubed * wSquared_over_6HSquared) # Save span data for span feature class. span.sagDistance = D span.horizontalTension = H span.lineLength = L span.weightPerUnitLength = w return span except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0])) pass
def makeSpans(lc_scratch_ws, lc_inPoints, lc_testLineWeight, lc_sag_to_span_ratio, lc_horizontal_tension, lc_output_features, lc_debug, lc_use_in_memory, lc_cleanup, lc_caller): try: geometry_type = "POLYLINE" has_m = "DISABLED" has_z = "ENABLED" from_tower_field = "FromTower" to_tower_field = "ToTower" line_number_field = "LineNumber" count_field = "COUNT" from_X_field = "FromX" from_Y_field = "FromY" from_Z_field = "FromZ" To_X_field = "ToX" To_Y_field = "ToY" To_Z_field = "ToZ" sag_distance = "SagDistance" horizontal_tension = "HorizontalTension" line_lenght = "LineLength" weight_per_unit_length = "WeightPerUnitLength" transmission_line_name = "TransmissionLines3D" transmission_guide_name = "TransmissionLineGuide" in_memory = "in_memory" spatial_reference = arcpy.Describe(lc_inPoints).spatialReference # create empty feature class with required fields # msg_body = create_msg_body("Preparing output feature classes...", 0, 0) # msg(msg_body) if lc_use_in_memory: arcpy.AddMessage("Using in memory for processing") includedTransmissionLinesFC = in_memory + "/" + transmission_line_name arcpy.CreateFeatureclass_management(in_memory, transmission_line_name, geometry_type, "", has_m, has_z, spatial_reference) else: includedTransmissionLinesFC = lc_output_features + "_3D" includedTransmissionLinesFC_dirname = os.path.dirname(includedTransmissionLinesFC) includedTransmissionLinesFC_basename = os.path.basename(includedTransmissionLinesFC) if arcpy.Exists(includedTransmissionLinesFC): arcpy.Delete_management(includedTransmissionLinesFC) arcpy.CreateFeatureclass_management(includedTransmissionLinesFC_dirname, includedTransmissionLinesFC_basename, geometry_type, "", has_m, has_z, spatial_reference) fields1_dict = {from_tower_field:"LONG", to_tower_field:"LONG", line_number_field:"LONG", count_field:"LONG", sag_distance:"DOUBLE", horizontal_tension:"DOUBLE", line_lenght:"DOUBLE", weight_per_unit_length:"DOUBLE" } listoffields1 = [] for k, v in fields1_dict.items(): field = [] field.append(k) field.append(v) listoffields1.append(field) arcpy.management.AddFields(includedTransmissionLinesFC, listoffields1) # common_lib.delete_add_field(includedTransmissionLinesFC, from_tower_field, "LONG") # common_lib.delete_add_field(includedTransmissionLinesFC, to_tower_field, "LONG") # common_lib.delete_add_field(includedTransmissionLinesFC, line_number_field, "LONG") # common_lib.delete_add_field(includedTransmissionLinesFC, count_field, "LONG") # common_lib.delete_add_field(includedTransmissionLinesFC, sag_distance, "DOUBLE") # common_lib.delete_add_field(includedTransmissionLinesFC, horizontal_tension, "DOUBLE") # common_lib.delete_add_field(includedTransmissionLinesFC, line_lenght, "DOUBLE") # common_lib.delete_add_field(includedTransmissionLinesFC, weight_per_unit_length, "DOUBLE") if lc_caller == "Create3Dcatenaryfromline": create_guidelines = False else: create_guidelines = True if create_guidelines: if lc_use_in_memory: includedTransmissionLineGuides = in_memory + "/" + transmission_guide_name arcpy.CreateFeatureclass_management(in_memory, transmission_guide_name, geometry_type, "", has_m, has_z, spatial_reference) else: includedTransmissionLineGuides = lc_output_features + "_LineGuides_3D" includedTransmissionLinesGuides_dirname = os.path.dirname(includedTransmissionLineGuides) includedTransmissionLinesGuides_basename = os.path.basename(includedTransmissionLineGuides) if arcpy.Exists(includedTransmissionLineGuides): arcpy.Delete_management(includedTransmissionLineGuides) arcpy.CreateFeatureclass_management(includedTransmissionLinesGuides_dirname, includedTransmissionLinesGuides_basename, geometry_type, "", has_m, has_z, spatial_reference) fields2_dict = {from_tower_field: "LONG", to_tower_field: "LONG", line_number_field: "LONG", from_X_field: "DOUBLE", from_Y_field: "DOUBLE", from_Z_field: "DOUBLE", To_X_field: "DOUBLE", To_Y_field: "DOUBLE", To_Z_field: "DOUBLE", count_field: "LONG", sag_distance: "DOUBLE", weight_per_unit_length: "DOUBLE" } listoffields2 = [] for k, v in fields2_dict.items(): field = [] field.append(k) field.append(v) listoffields2.append(field) arcpy.management.AddFields(includedTransmissionLineGuides, listoffields2) # common_lib.delete_add_field(includedTransmissionLineGuides, from_tower_field, "LONG") # common_lib.delete_add_field(includedTransmissionLineGuides, to_tower_field, "LONG") # common_lib.delete_add_field(includedTransmissionLineGuides, line_number_field, "LONG") # common_lib.delete_add_field(includedTransmissionLineGuides, from_X_field, "DOUBLE") # common_lib.delete_add_field(includedTransmissionLineGuides, from_Y_field, "DOUBLE") # common_lib.delete_add_field(includedTransmissionLineGuides, from_Z_field, "DOUBLE") # common_lib.delete_add_field(includedTransmissionLineGuides, To_X_field, "DOUBLE") # common_lib.delete_add_field(includedTransmissionLineGuides, To_Y_field, "DOUBLE") # common_lib.delete_add_field(includedTransmissionLineGuides, To_Z_field, "DOUBLE") # common_lib.delete_add_field(includedTransmissionLineGuides, sag_distance, "DOUBLE") # common_lib.delete_add_field(includedTransmissionLineGuides, weight_per_unit_length, "DOUBLE") else: includedTransmissionLineGuides = None ############################################################################################### Chris continues................... attachmentPointList = [] fieldList = ["SHAPE@X", "SHAPE@Y", "SHAPE@Z", "Line", "Tower"] fieldAccess = utils.FieldAccess(fieldList) cursor = arcpy.da.SearchCursor(lc_inPoints, fieldList) for row in cursor: fieldAccess.setRow(row) x = fieldAccess.getValue("SHAPE@X") y = fieldAccess.getValue("SHAPE@Y") z = fieldAccess.getValue("SHAPE@Z") lineNumber = fieldAccess.getValue("Line") towerNumber = fieldAccess.getValue("Tower") point = vg.Point(x, y, z) attachmentPoint = AttachmentPoint(point, lineNumber, towerNumber) attachmentPointList.append(attachmentPoint) if cursor: del cursor # Organize points into lists per line. dictionaryOfListsOfAttachmentPointsPerLine = {} for attachmentPoint in attachmentPointList: lineNumber = attachmentPoint.lineNumber if lineNumber in dictionaryOfListsOfAttachmentPointsPerLine.keys(): listOfAttachmentPointsPerLine = dictionaryOfListsOfAttachmentPointsPerLine[lineNumber] else: listOfAttachmentPointsPerLine = [] dictionaryOfListsOfAttachmentPointsPerLine[lineNumber] = listOfAttachmentPointsPerLine listOfAttachmentPointsPerLine.append(attachmentPoint) # Sort attachment points in each line list. # And make a list of line numbers for use in another dictionary. dictionaryOfSpanListsPerLine = {} lineNumberList = [] for lineNumber in dictionaryOfListsOfAttachmentPointsPerLine.keys(): lineNumberList.append(lineNumber) listOfAttachmentPointsPerLine = dictionaryOfListsOfAttachmentPointsPerLine[lineNumber] listOfAttachmentPointsPerLineSorted = sorted(listOfAttachmentPointsPerLine, key=lambda attachmentPoint: attachmentPoint.towerNumber) spanListPerThisLine = [] for index in range(0, len(listOfAttachmentPointsPerLineSorted) - 1): fromPoint = listOfAttachmentPointsPerLineSorted[index] toPoint = listOfAttachmentPointsPerLineSorted[index + 1] # This is to give shield wires less sag, but only works when using the Easy Way. sagToSpanRatioForMakeSpan = None if lc_sag_to_span_ratio is not None: sagToSpanRatioForMakeSpan = lc_sag_to_span_ratio if lineNumber < 0: sagToSpanRatioForMakeSpan = sagToSpanRatioForMakeSpan * 0.5 span = makeSpan(fromPoint, toPoint, includedTransmissionLineGuides, lc_testLineWeight, sagToSpanRatio=sagToSpanRatioForMakeSpan,sagDistance=None, horizontalTension=lc_horizontal_tension) spanListPerThisLine.append(span) dictionaryOfSpanListsPerLine[lineNumber] = spanListPerThisLine # msg_body = create_msg_body("Writing all span lines to " + includedTransmissionLinesFC_basename + ".", 0, 0) # msg(msg_body) for index in range(0,len(lineNumberList)): lineNumber = lineNumberList[index] spanListPerThisLine = dictionaryOfSpanListsPerLine[lineNumber] # not TODO: CW, yes is has to run: switch is driven by includedTransmissionLineGuides inside the function. doInsertSpanAndGuideLine(includedTransmissionLinesFC, includedTransmissionLineGuides, spanListPerThisLine) if includedTransmissionLineGuides is not None: # not TODO: CW, nope: see inside doInsertSpanAndGuideLine but could be coded more elegantly msg_body = create_msg_body( "Created helper Guide Lines feature class " + common_lib.get_name_from_feature_class(includedTransmissionLineGuides) + ".", 0, 0) msg(msg_body) # TODO check when necessary. When called from create_3D_catenary_from_line, this should not be called. if lc_cleanup: if lc_use_in_memory: arcpy.Delete_management("in_memory") if lc_debug == 0: fcs = common_lib.listFcsInGDB(lc_scratch_ws) msg_prefix = "Deleting intermediate data..." msg_body = common_lib.create_msg_body(msg_prefix, 0, 0) common_lib.msg(msg_body) for fc in fcs: arcpy.Delete_management(fc) arcpy.ClearWorkspaceCache_management() return includedTransmissionLinesFC, includedTransmissionLineGuides except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0])) pass
"Processing input source: " + common_lib.get_name_from_feature_class(input_raster)) if replace_value != "NoData": if not common_lib.is_number(replace_value): raise ValueError else: txt_replace_value = str(replace_value) else: txt_replace_value = "NoData" replace_value = "" msg_body = create_msg_body( "Setting replacement value for negative raster values to: " + txt_replace_value + " in " + output_raster + "...", 0, 0) msg(msg_body) # con on mosaic myConRaster = arcpy.sa.Con(input_raster, input_raster, replace_value, "VALUE >= 0") myConRaster.save(output_raster) if arcpy.Exists(output_raster): # output_layer = common_lib.get_name_from_feature_class(output_raster) + "no_negative" # arcpy.MakeRasterLayer_management(output_raster, output_layer) # arcpy.SetParameter(3, output_layer) end_time = time.clock() msg_body = create_msg_body( "Remove negative values from raster completed successfully.",
def flood_from_raster(input_source, input_type, no_flood_value, baseline_elevation_raster, baseline_elevation_value, outward_buffer, output_polygons, smoothing, debug): try: # Get Attributes from User if debug == 0: # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder tiff_directory = home_directory + "\\Tiffs" tin_directory = home_directory + "\\Tins" scripts_directory = aprx.homeFolder + "\\Scripts" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" layer_directory = home_directory + "\\layer_files" project_ws = aprx.defaultGeodatabase enableLogging = True DeleteIntermediateData = True verbose = 0 use_in_memory = True else: # debug home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact' tiff_directory = home_directory + "\\Tiffs" tin_directory = home_directory + "\\Tins" scripts_directory = home_directory + "\\Scripts" rule_directory = home_directory + "\\rule_packages" log_directory = home_directory + "\\Logs" layer_directory = home_directory + "\\layer_files" project_ws = home_directory + "\\Results.gdb" enableLogging = False DeleteIntermediateData = True verbose = 1 use_in_memory = False scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True # fail safe for Europese's comma's baseline_elevation_value = float( re.sub("[,.]", ".", baseline_elevation_value)) if not os.path.exists(tiff_directory): os.makedirs(tiff_directory) if not os.path.exists(tin_directory): os.makedirs(tin_directory) common_lib.set_up_logging(log_directory, TOOLNAME) start_time = time.clock() if arcpy.CheckExtension("3D") == "Available": arcpy.CheckOutExtension("3D") if arcpy.CheckExtension("Spatial") == "Available": arcpy.CheckOutExtension("Spatial") flood_level_layer_mp = None desc = arcpy.Describe(input_source) arcpy.AddMessage( "Processing input source: " + common_lib.get_name_from_feature_class(input_source)) spatial_ref = desc.spatialReference # create IsNull to be used to clip and check for NoData. if use_in_memory: is_null0 = "in_memory/is_null0" else: is_null0 = os.path.join(scratch_ws, "is_null0") if arcpy.Exists(is_null0): arcpy.Delete_management(is_null0) is_null_raster = arcpy.sa.IsNull(input_source) is_null_raster.save(is_null0) if spatial_ref.type == 'PROJECTED' or spatial_ref.type == 'Projected': # check input source type: projected rasters ONLY!!!! # check type, if polygon -> convert to raster if input_type == "RasterLayer" or input_type == "RasterDataset" or input_type == "raster": # prep raster # smooth result using focal stats if smoothing > 0: if use_in_memory: focal_raster = "in_memory/focal_raster" else: focal_raster = os.path.join( scratch_ws, "focal_raster") if arcpy.Exists(focal_raster): arcpy.Delete_management(focal_raster) if not (1 <= smoothing <= 100): smoothing = 30 neighborhood = arcpy.sa.NbrRectangle( smoothing, smoothing, "CELL") flood_elev_raster = arcpy.sa.FocalStatistics( input_source, neighborhood, "MEAN", "true") flood_elev_raster.save(focal_raster) # con if use_in_memory: smooth_input = "in_memory/smooth_input" else: smooth_input = os.path.join( scratch_ws, "smooth_input") if arcpy.Exists(smooth_input): arcpy.Delete_management(smooth_input) output = arcpy.sa.Con(is_null0, input_source, flood_elev_raster) output.save(smooth_input) input_raster = smooth_input else: input_raster = input_source else: raise NotSupported # use numeric value for determining non flooded areas: set these values to NoData. We need NoData for clippng later on if no_flood_value != "NoData": if common_lib.is_number(no_flood_value): msg_body = create_msg_body( "Setting no flood value: " + no_flood_value + " to NoData in copy of " + common_lib.get_name_from_feature_class( input_raster) + "...", 0, 0) msg(msg_body) if use_in_memory: null_for_no_flooded_areas_raster = "in_memory/null_for_flooded" else: null_for_no_flooded_areas_raster = os.path.join( scratch_ws, "null_for_flooded") if arcpy.Exists( null_for_no_flooded_areas_raster): arcpy.Delete_management( null_for_no_flooded_areas_raster) whereClause = "VALUE = " + no_flood_value # Execute SetNull outSetNull_temp = arcpy.sa.SetNull( input_raster, input_raster, whereClause) outSetNull_temp.save( null_for_no_flooded_areas_raster) input_raster = null_for_no_flooded_areas_raster else: raise ValueError else: pass msg_body = create_msg_body( "Checking for NoData values in raster: " + common_lib.get_name_from_feature_class(input_raster) + ". NoData values are considered to be non-flooded areas!", 0, 0) msg(msg_body) max_value = arcpy.GetRasterProperties_management( is_null0, "MAXIMUM")[0] # has_nodata = arcpy.GetRasterProperties_management(input_raster, "ANYNODATA")[0] ## fails on some rasters if int(max_value) == 1: # 1. get the outline of the raster as polygon via RasterDomain xy_unit = common_lib.get_xy_unit(input_raster, 0) if xy_unit: cell_size = arcpy.GetRasterProperties_management( input_raster, "CELLSIZEX") if baseline_elevation_raster: # check celll size cell_size_base = arcpy.GetRasterProperties_management( baseline_elevation_raster, "CELLSIZEX") if cell_size_base.getOutput( 0) == cell_size.getOutput(0): # Execute Plus if use_in_memory: flood_plus_base_raster = "in_memory/flooding_plus_base" else: flood_plus_base_raster = os.path.join( scratch_ws, "flooding_plus_base") if arcpy.Exists( flood_plus_base_raster): arcpy.Delete_management( flood_plus_base_raster) listRasters = [] listRasters.append(input_raster) listRasters.append( baseline_elevation_raster) desc = arcpy.Describe(listRasters[0]) arcpy.MosaicToNewRaster_management( listRasters, scratch_ws, "flooding_plus_base", desc.spatialReference, "32_BIT_FLOAT", cell_size, 1, "SUM", "") # check where there is IsNull and set the con values if use_in_memory: is_Null = "in_memory/is_Null" else: is_Null = os.path.join( scratch_ws, "is_Null") if arcpy.Exists(is_Null): arcpy.Delete_management(is_Null) is_Null_raster = arcpy.sa.IsNull( input_raster) is_Null_raster.save(is_Null) # Con if use_in_memory: flood_plus_base_raster_null = "in_memory/flooding_plus_base_null" else: flood_plus_base_raster_null = os.path.join( scratch_ws, "flooding_plus_base_null") if arcpy.Exists( flood_plus_base_raster_null): arcpy.Delete_management( flood_plus_base_raster_null) msg_body = create_msg_body( "Adding baseline elevation raster to input flood layer...", 0, 0) msg(msg_body) fpbrn = arcpy.sa.Con( is_Null, input_raster, flood_plus_base_raster) fpbrn.save(flood_plus_base_raster_null) input_raster = flood_plus_base_raster_null else: arcpy.AddWarning( "Cell size of " + input_raster + " is different than " + baseline_elevation_raster + ". Ignoring Base Elevation Raster.") else: if baseline_elevation_value > 0: if use_in_memory: flood_plus_base_raster = "in_memory/flood_plus_base" else: flood_plus_base_raster = os.path.join( scratch_ws, "flooding_plus_base") if arcpy.Exists( flood_plus_base_raster): arcpy.Delete_management( flood_plus_base_raster) arcpy.Plus_3d(input_raster, baseline_elevation_value, flood_plus_base_raster) input_raster = flood_plus_base_raster msg_body = create_msg_body( "Creating 3D polygons...", 0, 0) msg(msg_body) if use_in_memory: raster_polygons = "in_memory/raster_polygons" else: raster_polygons = os.path.join( scratch_ws, "raster_polygons") if arcpy.Exists(raster_polygons): arcpy.Delete_management(raster_polygons) out_geom = "POLYGON" # output geometry type arcpy.RasterDomain_3d(input_raster, raster_polygons, out_geom) # 2. buffer it inwards so that we have a polygon only of the perimeter plus a few ???????cells inward???????. if use_in_memory: polygons_inward = "in_memory/inward_buffer" else: polygons_inward = os.path.join( scratch_ws, "inward_buffer") if arcpy.Exists(polygons_inward): arcpy.Delete_management(polygons_inward) x = float( re.sub("[,.]", ".", str(cell_size.getOutput(0)))) # x = float(str(cell_size.getOutput(0))) if x < 0.1: arcpy.AddError( "Raster cell size is 0. Can't continue. Please check the raster properties." ) raise ValueError else: buffer_in = 3 * int(x) if xy_unit == "Feet": buffer_text = "-" + str( buffer_in) + " Feet" else: buffer_text = "-" + str( buffer_in) + " Meters" sideType = "OUTSIDE_ONLY" arcpy.Buffer_analysis(raster_polygons, polygons_inward, buffer_text, sideType) msg_body = create_msg_body( "Buffering flood edges...", 0, 0) msg(msg_body) # 3. mask in ExtractByMask: gives just boundary raster with a few cells inwards if use_in_memory: extract_mask_raster = "in_memory/extract_mask" else: extract_mask_raster = os.path.join( scratch_ws, "extract_mask") if arcpy.Exists(extract_mask_raster): arcpy.Delete_management( extract_mask_raster) extract_temp_raster = arcpy.sa.ExtractByMask( input_raster, polygons_inward) extract_temp_raster.save(extract_mask_raster) # 4. convert the output to points if use_in_memory: extract_mask_points = "in_memory/extract_points" else: extract_mask_points = os.path.join( scratch_ws, "extract_points") if arcpy.Exists(extract_mask_points): arcpy.Delete_management( extract_mask_points) arcpy.RasterToPoint_conversion( extract_mask_raster, extract_mask_points, "VALUE") msg_body = create_msg_body( "Create flood points...", 0, 0) msg(msg_body) # 5. Interpolate: this will also interpolate outside the flood boundary which is # what we need so we get a nice 3D poly that extends into the surrounding DEM if use_in_memory: interpolated_raster = "in_memory/interpolate_raster" else: interpolated_raster = os.path.join( scratch_ws, "interpolate_raster") if arcpy.Exists(interpolated_raster): arcpy.Delete_management( interpolated_raster) zField = "grid_code" power = 2 searchRadius = arcpy.sa.RadiusVariable( 12, 150000) msg_body = create_msg_body( "Interpolating flood points...", 0, 0) msg(msg_body) # Execute IDW out_IDW = arcpy.sa.Idw(extract_mask_points, zField, cell_size, power) # Save the output out_IDW.save(interpolated_raster) extent_poly = common_lib.get_extent_feature( scratch_ws, polygons_inward) msg_body = create_msg_body( "Clipping terrain...", 0, 0) msg(msg_body) # clip the input surface if use_in_memory: extent_clip_idwraster = "in_memory/extent_clip_idw" else: extent_clip_idwraster = os.path.join( scratch_ws, "extent_clip_idw") if arcpy.Exists(extent_clip_idwraster): arcpy.Delete_management( extent_clip_idwraster) # clip terrain to extent arcpy.Clip_management(interpolated_raster, "#", extent_clip_idwraster, extent_poly) # 6. clip the interpolated raster by (outward buffered) outline polygon if use_in_memory: polygons_outward = "in_memory/outward_buffer" else: polygons_outward = os.path.join( scratch_ws, "outward_buffer") if arcpy.Exists(polygons_outward): arcpy.Delete_management( polygons_outward) outward_buffer += 0.5 * int( x ) # we buffer out by half the raster cellsize if outward_buffer > 0: if xy_unit == "Feet": buffer_text = str( outward_buffer) + " Feet" else: buffer_text = str( outward_buffer) + " Meters" sideType = "FULL" arcpy.Buffer_analysis( raster_polygons, polygons_outward, buffer_text, sideType) raster_polygons = polygons_outward # clip the input surface if use_in_memory: flood_clip_raster = "in_memory/flood_clip_raster" else: flood_clip_raster = os.path.join( scratch_ws, "flood_clip_raster") if arcpy.Exists(flood_clip_raster): arcpy.Delete_management( flood_clip_raster) msg_body = create_msg_body( "Clipping flood raster...", 0, 0) msg(msg_body) # clip terrain to extent # arcpy.Clip_management(interpolated_raster, "#", flood_clip_raster, raster_polygons) Check again arcpy.Clip_management(interpolated_raster, "#", flood_clip_raster, raster_polygons) # 7. Isnull, and Con to grab values from flood_clip_raster for # create NUll mask if use_in_memory: is_Null = "in_memory/is_Null" else: is_Null = os.path.join( scratch_ws, "is_Null") if arcpy.Exists(is_Null): arcpy.Delete_management(is_Null) is_Null_raster = arcpy.sa.IsNull(input_raster) is_Null_raster.save(is_Null) # Con if use_in_memory: con_raster = "in_memory/con_raster" else: con_raster = os.path.join( scratch_ws, "con_raster") if arcpy.Exists(con_raster): arcpy.Delete_management(con_raster) temp_con_raster = arcpy.sa.Con( is_Null, interpolated_raster, input_raster) temp_con_raster.save(con_raster) msg_body = create_msg_body( "Merging rasters...", 0, 0) msg(msg_body) # 8. focal stats on raster to smooth? # 9. copy raster to geotiff if use_in_memory: con_raster_tif = "in_memory/con_raster_tif" else: con_raster_tif = os.path.join( tiff_directory, "con_raster.tif") if arcpy.Exists(con_raster_tif): arcpy.Delete_management(con_raster_tif) arcpy.CopyRaster_management( con_raster, con_raster_tif, "#", "#", "#", "#", "#", "32_BIT_FLOAT") msg_body = create_msg_body( "Copying to tiff...", 0, 0) msg(msg_body) # 10. raster to TIN zTol = 0.1 maxPts = 1500000 zFactor = 1 con_tin = os.path.join(tin_directory, "con_tin") if arcpy.Exists(con_tin): arcpy.Delete_management(con_tin) # Execute RasterTin arcpy.RasterTin_3d(con_raster_tif, con_tin, zTol, maxPts, zFactor) msg_body = create_msg_body( "Creating TIN...", 0, 0) msg(msg_body) # 11. TIN triangles if use_in_memory: con_triangles = "in_memory/con_triangles" else: con_triangles = os.path.join( scratch_ws, "con_triangles") if arcpy.Exists(con_triangles): arcpy.Delete_management(con_triangles) arcpy.TinTriangle_3d(con_tin, con_triangles) msg_body = create_msg_body( "Creating polygons...", 0, 0) msg(msg_body) # 12. make 2D polygons feature to feature class arcpy.FeatureClassToFeatureClass_conversion( con_triangles, scratch_ws, "con_triangles_2D") # 12. clip with smooth polygon smooth_polygons = os.path.join( scratch_ws, "smooth_raster_polygons") if arcpy.Exists(smooth_polygons): arcpy.Delete_management(smooth_polygons) msg_body = create_msg_body( "Smoothing edges...", 0, 0) msg(msg_body) CA.SmoothPolygon(os.path.join(raster_polygons), smooth_polygons, "PAEK", x, "", "FLAG_ERRORS") if use_in_memory: clip_smooth_triangles = "in_memory/clip_smooth_triangles" else: clip_smooth_triangles = os.path.join( scratch_ws, "clip_smooth_triangles") if arcpy.Exists(clip_smooth_triangles): arcpy.Delete_management( clip_smooth_triangles) msg_body = create_msg_body( "Clipping smooth edges...", 0, 0) msg(msg_body) # clip terrain to extent arcpy.Clip_analysis(con_triangles, smooth_polygons, clip_smooth_triangles) # clip to slightly lesser extent because of InterpolateShape fail. area_extent = common_lib.get_extent_feature( scratch_ws, clip_smooth_triangles) if use_in_memory: extent_inward = "in_memory/inward_extent_buffer" else: extent_inward = os.path.join( scratch_ws, "inward_extent_buffer") if arcpy.Exists(extent_inward): arcpy.Delete_management(extent_inward) buffer_in = 3 if xy_unit == "Feet": buffer_text = "-" + str( buffer_in) + " Feet" else: buffer_text = "-" + str( buffer_in) + " Meters" sideType = "FULL" arcpy.Buffer_analysis(area_extent, extent_inward, buffer_text, sideType) if use_in_memory: clip2_smooth_triangles = "in_memory/clip2_smooth_triangles" else: clip2_smooth_triangles = os.path.join( scratch_ws, "clip2_smooth_triangles") if arcpy.Exists(clip2_smooth_triangles): arcpy.Delete_management( clip2_smooth_triangles) msg_body = create_msg_body( "Clipping smooth edges a second time...", 0, 0) msg(msg_body) # clip terrain to extent arcpy.Clip_analysis(clip_smooth_triangles, extent_inward, clip2_smooth_triangles) # 13. interpolate on TIN if use_in_memory: clip_smooth_triangles3D = "in_memory/clip_smooth_traingles3D" else: clip_smooth_triangles3D = os.path.join( scratch_ws, "clip_smooth_triangles3D") if arcpy.Exists(clip_smooth_triangles3D): arcpy.Delete_management( clip_smooth_triangles3D) msg_body = create_msg_body( "Interpolating polygons on TIN", 0, 0) msg(msg_body) arcpy.InterpolateShape_3d( con_tin, clip2_smooth_triangles, clip_smooth_triangles3D, "#", 1, "LINEAR", "VERTICES_ONLY") # 13. to multipatch z_unit = common_lib.get_z_unit( clip_smooth_triangles3D, verbose) # temp layer flood_level_layer = "flood_level_layer" arcpy.MakeFeatureLayer_management( clip_smooth_triangles3D, flood_level_layer) # flood_level_mp = os.path.join(project_ws, common_lib.get_name_from_feature_class(input_raster) + "_3D") flood_level_mp = output_polygons + "_3D" if arcpy.Exists(flood_level_mp): arcpy.Delete_management(flood_level_mp) arcpy.Layer3DToFeatureClass_3d( flood_level_layer, flood_level_mp) # layer to be added to TOC flood_level_layer_mp = common_lib.get_name_from_feature_class( flood_level_mp) arcpy.MakeFeatureLayer_management( flood_level_mp, flood_level_layer_mp) # apply transparency here // checking if symbology layer is present if z_unit == "Feet": floodSymbologyLayer = layer_directory + "\\flood3Dfeet.lyrx" else: floodSymbologyLayer = layer_directory + "\\flood3Dmeter.lyrx" if not arcpy.Exists(floodSymbologyLayer): arcpy.AddWarning( "Can't find: " + floodSymbologyLayer + ". Symbolize features by error attribute to see data errors." ) arcpy.AddMessage("Results written to: " + output_polygons) if use_in_memory: arcpy.Delete_management("in_memory") if DeleteIntermediateData: fcs = common_lib.listFcsInGDB(scratch_ws) msg_prefix = "Deleting intermediate data..." msg_body = common_lib.create_msg_body( msg_prefix, 0, 0) common_lib.msg(msg_body) for fc in fcs: arcpy.Delete_management(fc) return flood_level_layer_mp # 14. adjust 3D Z feet to meters??? else: raise NoUnits else: raise NoNoDataError end_time = time.clock() msg_body = create_msg_body( "Create 3D Flood Leveles completed successfully.", start_time, end_time) else: raise NotProjected else: raise LicenseErrorSpatial else: raise LicenseError3D arcpy.ClearWorkspaceCache_management() msg(msg_body) except NotProjected: print( "Input data needs to be in a projected coordinate system. Exiting..." ) arcpy.AddError( "Input data needs to be in a projected coordinate system. Exiting..." ) except NoLayerFile: print("Can't find Layer file. Exiting...") arcpy.AddError("Can't find Layer file. Exiting...") except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except LicenseErrorSpatial: print("Spatial Analyst license is unavailable") arcpy.AddError("Spatial Analyst license is unavailable") except NoNoDataError: print("Input raster does not have NODATA values") arcpy.AddError("Input raster does not have NODATA values") except NoUnits: print("No units detected on input data") arcpy.AddError("No units detected on input data") except NoPolygons: print("Input data can only be polygon features or raster datasets.") arcpy.AddError( "Input data can only be polygon features or raster datasets.") except ValueError: print("Input no flood value is not a number.") arcpy.AddError("Input no flood value is not a number.") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D") arcpy.CheckInExtension("Spatial")
def calculate_height(lc_input_features, lc_ws, lc_input_surface, lc_output_features, lc_log_dir, lc_debug, lc_memory_switch): try: # create dem desc = arcpy.Describe(lc_input_features) if desc.spatialReference.linearUnitName in ['Foot_US', 'Foot']: unit = 'Feet' else: unit = 'Meters' # Generate raster from lasd if arcpy.Exists(lc_input_features): if arcpy.Exists(lc_output_features): arcpy.Delete_management(lc_output_features) esri_featureID = "copy_featureID" # create string field for featureFID oidFieldName = arcpy.Describe(lc_input_features).oidFieldName common_lib.delete_add_field(lc_input_features, esri_featureID, "TEXT") arcpy.CalculateField_management(lc_input_features, esri_featureID, "!" + oidFieldName + "!", "PYTHON_9.3") msg_body = create_msg_body("Calculating height above surface for; " + common_lib.get_name_from_feature_class(lc_input_features), 0, 0) msg(msg_body) # run zonal stats and get maximum elevation for each polygon WSE_max = os.path.join(lc_ws, "SurfaceMaximum") if arcpy.Exists(WSE_max): arcpy.Delete_management(WSE_max) heightsTable = os.path.join(lc_ws, "heightsTable") if arcpy.Exists(heightsTable): arcpy.Delete_management(heightsTable) stat_type = "MAXIMUM" max_field = "MAX" zmin_field = "Z_MIN" arcpy.AddMessage("Calculating Height Statistics Information for " + common_lib.get_name_from_feature_class( lc_input_features) + ".") arcpy.sa.ZonalStatisticsAsTable(lc_input_features, esri_featureID, lc_input_surface, heightsTable, "DATA", stat_type) common_lib.delete_fields(lc_input_features, [max_field]) arcpy.JoinField_management(lc_input_features, esri_featureID, heightsTable, esri_featureID, max_field) # DISREGARD for now # select features with MAXIMUM not NULL # select all points with good elevation values # expression = """{} IS NOT NULL""".format(arcpy.AddFieldDelimiters(lc_input_features, max_field)) # # msg_body = create_msg_body("Removing polygons with NULL values for MAXIMUM height", 0, 0) # msg(msg_body) # # select_name = arcpy.CreateUniqueName('bridge_height_select_lyr') # select_lyr = arcpy.MakeFeatureLayer_management(lc_input_features, select_name).getOutput(0) # arcpy.SelectLayerByAttribute_management(select_lyr, "NEW_SELECTION", expression) bridge_polys = lc_output_features + "_height" if arcpy.Exists(bridge_polys): arcpy.Delete_management(bridge_polys) # arcpy.CopyFeatures_management(select_lyr, bridge_polys) arcpy.CopyFeatures_management(lc_input_features, bridge_polys) # add Z information arcpy.ddd.AddZInformation(bridge_polys, zmin_field, None) # calculate height above surface has_field = "HAS_height" common_lib.add_field(bridge_polys, has_field, "DOUBLE", 20) arcpy.CalculateField_management(bridge_polys, has_field, "!" + zmin_field + "! - !" + max_field + "!", "PYTHON3", None) # create point file for labeling return bridge_polys #, bridge_points else: msg_body = create_msg_body("Couldn't find input feature class: " + str(lc_input_features), 0, 0) msg(msg_body, WARNING) return None except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def calculate_height(lc_input_features, lc_ws, lc_tin_dir, lc_input_surface, lc_is_hand, lc_dem, lc_output_features, lc_log_dir, lc_debug, lc_memory_switch): try: if arcpy.Exists(lc_input_features): if arcpy.Exists(lc_output_features): arcpy.Delete_management(lc_output_features) # make a copy bridge_polys = lc_output_features + "_height" if arcpy.Exists(bridge_polys): arcpy.Delete_management(bridge_polys) arcpy.CopyFeatures_management(lc_input_features, bridge_polys) # create string field for featureFID oidFieldName = arcpy.Describe(bridge_polys).oidFieldName common_lib.delete_add_field(bridge_polys, esri_featureID, "TEXT") arcpy.CalculateField_management(bridge_polys, esri_featureID, "!" + oidFieldName + "!", "PYTHON_9.3") msg_body = create_msg_body( "Calculating height above surface for: " + common_lib.get_name_from_feature_class(lc_input_features), 0, 0) msg(msg_body) had_field = "height_dem" # if HAND raster if lc_is_hand: arcpy.AddMessage( "Assuming input surface " + common_lib.get_name_from_feature_class(lc_input_surface) + " is a HAND raster.") arcpy.AddMessage( "First adding height above DEM to " + common_lib.get_name_from_feature_class(lc_input_features) + ".") add_minimum_height_above_drainage(lc_ws, bridge_polys, lc_dem, had_field, lc_memory_switch) arcpy.AddMessage( "Now adding height above HAND raster " + common_lib.get_name_from_feature_class(lc_input_features) + ".") add_minimum_height_above_HAND(lc_ws, bridge_polys, lc_input_surface, had_field, lc_memory_switch) else: # if just DEM arcpy.AddMessage( "Assuming input surface " + common_lib.get_name_from_feature_class(lc_input_surface) + " is a digital elevation model.") arcpy.AddMessage( "Adding height above input surface to " + common_lib.get_name_from_feature_class(lc_input_features) + ".") add_minimum_height_above_drainage(lc_ws, bridge_polys, lc_input_surface, had_field, lc_memory_switch) # create point file for labeling if lc_memory_switch: bridge_points = "in_memory/bridge_points" else: bridge_points = os.path.join(lc_ws, "bridge_points") if arcpy.Exists(bridge_points): arcpy.Delete_management(bridge_points) arcpy.FeatureToPoint_management(bridge_polys, bridge_points, "INSIDE") bridge_points3D = lc_output_features + "_points_3D" if arcpy.Exists(bridge_points3D): arcpy.Delete_management(bridge_points3D) # create 3D point arcpy.FeatureTo3DByAttribute_3d(bridge_points, bridge_points3D, zmin_field) # add unit field z_unit = common_lib.get_z_unit(bridge_points3D, lc_debug) if z_unit == "Meters": expression = "'m'" else: expression = "'ft'" common_lib.delete_add_field(bridge_points3D, esri_unit, "TEXT") arcpy.CalculateField_management(bridge_points3D, esri_unit, expression, "PYTHON_9.3") return bridge_polys, bridge_points3D else: msg_body = create_msg_body( "Couldn't find input feature class: " + str(lc_input_features), 0, 0) msg(msg_body, WARNING) return None except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def convert(input_source, flood_elevation_attribute, esri_flood_elevation_attribute, default_flood_elevation_value, output_raster, cell_size, debug): try: # Get Attributes from User if debug == 0: # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder tiff_directory = home_directory + "\\Tiffs" tin_directory = home_directory + "\\Tins" scripts_directory = aprx.homeFolder + "\\Scripts" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" layer_directory = home_directory + "\\layer_files" project_ws = aprx.defaultGeodatabase enableLogging = True DeleteIntermediateData = True verbose = 0 in_memory_switch = True else: # debug input_source = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact\Baltimore.gdb\test_area1_slr6ft_pol' flood_elevation_attribute = "my_elev" esri_flood_elevation_attribute = "flood_elevation" default_flood_elevation_value = 6 output_raster = r'D:\\Gert\\Work\\Esri\\Solutions\\3DFloodImpact\\work2.1\\3DFloodImpact\\Testing.gdb\\PolygonRaster' cell_size = 10 home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact' tiff_directory = home_directory + "\\Tiffs" tin_directory = home_directory + "\\Tins" scripts_directory = home_directory + "\\Scripts" rule_directory = home_directory + "\\rule_packages" log_directory = home_directory + "\\Logs" layer_directory = home_directory + "\\layer_files" project_ws = home_directory + "\\Results.gdb" enableLogging = False DeleteIntermediateData = True verbose = 1 in_memory_switch = False return_code = 0 scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True # fail safe for Europese's comma's if default_flood_elevation_value: default_flood_elevation_value = float( re.sub("[,.]", ".", default_flood_elevation_value)) else: default_flood_elevation_value = 1 if cell_size: cell_size = float(re.sub("[,.]", ".", cell_size)) else: cell_size = 1 if not os.path.exists(tiff_directory): os.makedirs(tiff_directory) if not os.path.exists(tin_directory): os.makedirs(tin_directory) common_lib.set_up_logging(log_directory, TOOLNAME) start_time = time.clock() if arcpy.CheckExtension("3D") == "Available": arcpy.CheckOutExtension("3D") if arcpy.CheckExtension("Spatial") == "Available": arcpy.CheckOutExtension("Spatial") arcpy.AddMessage( "Processing input source: " + common_lib.get_name_from_feature_class(input_source)) common_lib.delete_add_field(input_source, esri_flood_elevation_attribute, "DOUBLE") # check attribute if flood_elevation_attribute: if common_lib.check_fields(input_source, [flood_elevation_attribute], False, verbose) == 0: arcpy.CalculateField_management( input_source, esri_flood_elevation_attribute, "!" + flood_elevation_attribute + "!", "PYTHON_9.3") common_lib.set_null_or_negative_to_value_in_fields( input_source, [esri_flood_elevation_attribute], [default_flood_elevation_value], True, verbose) return_code = 1 else: # create a default attribute arcpy.CalculateField_management( input_source, esri_flood_elevation_attribute, default_flood_elevation_value, "PYTHON_9.3") return_code = 1 else: arcpy.CalculateField_management( input_source, esri_flood_elevation_attribute, default_flood_elevation_value, "PYTHON_9.3") return_code = 1 # convert here assignmentType = "CELL_CENTER" priorityField = "#" # Execute PolygonToRaster arcpy.PolygonToRaster_conversion( input_source, esri_flood_elevation_attribute, output_raster, assignmentType, priorityField, cell_size) return output_raster end_time = time.clock() msg_body = create_msg_body( "set Flood Elevation Value For Polygon completed successfully.", start_time, end_time) else: raise LicenseErrorSpatial else: raise LicenseError3D arcpy.ClearWorkspaceCache_management() msg(msg_body) except NotProjected: print( "Input data needs to be in a projected coordinate system. Exiting..." ) arcpy.AddError( "Input data needs to be in a projected coordinate system. Exiting..." ) except NoLayerFile: print("Can't find Layer file. Exiting...") arcpy.AddError("Can't find Layer file. Exiting...") except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except LicenseErrorSpatial: print("Spatial Analyst license is unavailable") arcpy.AddError("Spatial Analyst license is unavailable") except NoNoDataError: print("Input raster does not have NODATA values") arcpy.AddError("Input raster does not have NODATA values") except NoUnits: print("No units detected on input data") arcpy.AddError("No units detected on input data") except NoPolygons: print("Input data can only be polygon features or raster datasets.") arcpy.AddError( "Input data can only be polygon features or raster datasets.") except ValueError: print("Input no flood value is not a number.") arcpy.AddError("Input no flood value is not a number.") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D") arcpy.CheckInExtension("Spatial")
def add_minimum_height_above_HAND(lc_ws, lc_input_features, lc_input_surface, lc_had_field, lc_memory_switch): try: if arcpy.Exists(lc_input_features): if arcpy.Exists(lc_input_surface): # find minimum HAND value for each input features heightsTable = os.path.join(lc_ws, "heightsTable") if arcpy.Exists(heightsTable): arcpy.Delete_management(heightsTable) stat_type = "MINIMUM" arcpy.AddMessage( "Calculating minimum HAND height for " + common_lib.get_name_from_feature_class(lc_input_features) + ".") arcpy.sa.ZonalStatisticsAsTable(lc_input_features, esri_featureID, lc_input_surface, heightsTable, "DATA", stat_type) common_lib.delete_fields(lc_input_features, [min_field]) arcpy.JoinField_management(lc_input_features, esri_featureID, heightsTable, esri_featureID, min_field) # add minimum HAND height to height_dem which was previously calculated hand_field = "HAND" common_lib.add_field(lc_input_features, hand_field, "DOUBLE", 5) expression = "round(float(!" + lc_had_field + "! + !" + min_field + "!), 2)" arcpy.CalculateField_management(lc_input_features, hand_field, expression, "PYTHON3", None) common_lib.delete_fields(lc_input_features, [lc_had_field, min_field]) # alternative way -> # bridge surface to points # bridge polygons to raster # add Z values # find point with minimum Z value # get HAND value point # get DEM value for point # subtract DEM value from minimum Z -> Height above DEM # add this value to HAND for location else: msg_body = create_msg_body( "Couldn't find input surface: " + str(lc_input_surface), 0, 0) msg(msg_body, WARNING) else: msg_body = create_msg_body( "Couldn't find input feature class: " + str(lc_input_features), 0, 0) msg(msg_body, WARNING) return None except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def add_minimum_height_above_water_surface(lc_ws, lc_input_features, lc_bridge_raster, lc_input_surface, lc_memory_switch): try: if arcpy.Exists(lc_input_features): # subtract input surface from bridge raster to obtain heights above surface if lc_memory_switch: minus_raster = "in_memory/minus_3D" else: minus_raster = os.path.join(lc_ws, "minus_3D") if arcpy.Exists(minus_raster): arcpy.Delete_management(minus_raster) # actual subtract msg_body = create_msg_body( "Finding minimum distance between surfaces for each input feature...", 0, 0) msg(msg_body) arcpy.Minus_3d(lc_bridge_raster, lc_input_surface, minus_raster) # zonal stats to find minimum height above surface heights_table = os.path.join(lc_ws, "heightsTable") if arcpy.Exists(heights_table): arcpy.Delete_management(heights_table) stat_type = "MINIMUM" arcpy.AddMessage( "Calculating Height Statistics Information for " + common_lib.get_name_from_feature_class(lc_input_features) + ".") arcpy.sa.ZonalStatisticsAsTable(lc_input_features, esri_featureID, minus_raster, heights_table, "DATA", stat_type) # join back to bridge object common_lib.delete_fields(lc_input_features, [min_field]) arcpy.JoinField_management(lc_input_features, esri_featureID, heights_table, esri_featureID, min_field) # add Z information arcpy.AddZInformation_3d(lc_input_features, zmin_field, None) # calculate height above surface common_lib.add_field(lc_input_features, has_field, "DOUBLE", 5) expression = "round(float(!" + min_field + "!), 2)" arcpy.CalculateField_management(lc_input_features, has_field, expression, "PYTHON3", None) else: msg_body = create_msg_body( "Couldn't find input feature class: " + str(lc_input_features), 0, 0) msg(msg_body, WARNING) except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def main(): try: # Get Attributes from User if debugging == 0: ## User input input_source = arcpy.GetParameter(0) depth_raster = arcpy.GetParameterAsText(1) depth_value = arcpy.GetParameterAsText(2) boundary_size = arcpy.GetParameterAsText(3) boundary_offset = arcpy.GetParameterAsText(4) output_raster = arcpy.GetParameterAsText(5) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder layer_directory = home_directory + "\\layer_files" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" project_ws = aprx.defaultGeodatabase else: # debug input_source = r'D:\Temporary\Flood\3DFloodImpact\3DFloodImpact.gdb\slr_3ft_ProjectRaster' depth_raster = r'D:\Temporary\Flood\3DFloodImpact\3DFloodImpact.gdb\MD_LWX_slr_depth_3ft_Project' depth_value = 0 boundary_size = 1 boundary_offset = 0.2 output_raster = r'D:\Temporary\Flood\3DFloodImpact\3DFloodImpact.gdb\DepthElevationRaster_debug' home_directory = r'D:\Temporary\Flood\3DFloodImpact' layer_directory = home_directory + "\\layer_files" rule_directory = home_directory + "\\rule_packages" log_directory = home_directory + "\\Logs" project_ws = home_directory + "\\3DFloodImpact.gdb" scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True start_time = time.clock() # check if input exists if arcpy.Exists(input_source): full_path_source = common_lib.get_full_path_from_layer(input_source) else: raise NoRasterLayer desc = arcpy.Describe(input_source) depth_elevation_raster = create_depth_raster.create_raster(input_source=full_path_source, depth_raster=depth_raster, depth_value=depth_value, boundary_size=boundary_size, boundary_offset=boundary_offset, output_raster=output_raster, debug=debugging) if depth_elevation_raster: if arcpy.Exists(depth_elevation_raster): end_time = time.clock() msg_body = create_msg_body("create_depth_raster_tbx completed successfully.", start_time, end_time) msg(msg_body) else: end_time = time.clock() msg_body = create_msg_body("No output raster layer. Exiting...", start_time, end_time) msg(msg_body, WARNING) else: end_time = time.clock() msg_body = create_msg_body("No output raster layer. Exiting...", start_time, end_time) msg(msg_body, WARNING) arcpy.ClearWorkspaceCache_management() # end main code except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoRasterLayer: print("No output Raster layer. Exiting...") arcpy.AddError("No output raster layer. Exiting...") except NoOutput: print("Can't create output. Exiting...") arcpy.AddError("Can't create output. Exiting...") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def create_raster(depth_raster, dtm, smoothing, output_raster, use_in_memory, debug): try: # Get Attributes from User if debug == 0: # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder tiff_directory = home_directory + "\\Tiffs" tin_directory = home_directory + "\\Tins" scripts_directory = aprx.homeFolder + "\\Scripts" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" layer_directory = home_directory + "\\layer_files" project_ws = aprx.defaultGeodatabase enableLogging = True DeleteIntermediateData = True verbose = 0 in_memory_switch = True else: # debug home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.2.3\3DFloodImpact' log_directory = home_directory + "\\Logs" layer_directory = home_directory + "\\LayerFiles" project_ws = home_directory + "\\Testing.gdb" enableLogging = False DeleteIntermediateData = True verbose = 1 in_memory_switch = False scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True common_lib.set_up_logging(log_directory, TOOLNAME) start_time = time.clock() if arcpy.CheckExtension("3D") == "Available": arcpy.CheckOutExtension("3D") if arcpy.CheckExtension("Spatial") == "Available": arcpy.CheckOutExtension("Spatial") arcpy.AddMessage( "Processing input source: " + common_lib.get_name_from_feature_class(depth_raster)) arcpy.AddMessage("Processing input source: " + common_lib.get_name_from_feature_class(dtm)) # add depth raster and DTM together if use_in_memory: plus_raster = "in_memory/depth_plus_dtm" else: plus_raster = os.path.join(scratch_ws, "depth_plus_dtm") if arcpy.Exists(plus_raster): arcpy.Delete_management(plus_raster) arcpy.Plus_3d(depth_raster, dtm, plus_raster) # smooth result using focal stats if use_in_memory: focal_raster = "in_memory/focal_raster" else: focal_raster = os.path.join(scratch_ws, "focal_raster") if arcpy.Exists(focal_raster): arcpy.Delete_management(focal_raster) if not (1 <= smoothing <= 100): smoothing = 30 neighborhood = arcpy.sa.NbrRectangle(smoothing, smoothing, "CELL") flood_elev_raster = arcpy.sa.FocalStatistics( plus_raster, neighborhood, "MEAN", "true") flood_elev_raster.save(focal_raster) # clip with IsNull from depth because we don't want DEM values where there is no depth. if use_in_memory: is_null = "in_memory/is_null" else: is_null = os.path.join(scratch_ws, "is_null") if arcpy.Exists(is_null): arcpy.Delete_management(is_null) is_null_raster = arcpy.sa.IsNull(depth_raster) is_null_raster.save(is_null) # con output = arcpy.sa.Con(is_null, depth_raster, flood_elev_raster) output.save(output_raster) end_time = time.clock() msg_body = create_msg_body( "Create Flood Elevation Raster From Depth Raster completed successfully.", start_time, end_time) if use_in_memory: arcpy.Delete_management("in_memory") arcpy.ClearWorkspaceCache_management() # return output_raster else: raise LicenseErrorSpatial else: raise LicenseError3D arcpy.ClearWorkspaceCache_management() msg(msg_body) except NotProjected: print( "Input data needs to be in a projected coordinate system. Exiting..." ) arcpy.AddError( "Input data needs to be in a projected coordinate system. Exiting..." ) except NoLayerFile: print("Can't find Layer file. Exiting...") arcpy.AddError("Can't find Layer file. Exiting...") except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except LicenseErrorSpatial: print("Spatial Analyst license is unavailable") arcpy.AddError("Spatial Analyst license is unavailable") except NoNoDataError: print("Input raster does not have NODATA values") arcpy.AddError("Input raster does not have NODATA values") except NoUnits: print("No units detected on input data") arcpy.AddError("No units detected on input data") except NoPolygons: print("Input data can only be polygon features or raster datasets.") arcpy.AddError( "Input data can only be polygon features or raster datasets.") except ValueError: print("Input no flood value is not a number.") arcpy.AddError("Input no flood value is not a number.") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D") arcpy.CheckInExtension("Spatial")
def main(): try: # Get Attributes from User if debugging == 0: ## User input input_source = arcpy.GetParameter(0) angle = arcpy.GetParameterAsText(1) output_features = arcpy.GetParameterAsText(2) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder layer_directory = home_directory + "\\layer_files" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" project_ws = aprx.defaultGeodatabase else: # debug input_source = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2.3\Transmission_Lines\Testing.gdb\Cat_test_LineGuides_3D' angle = 45 output_features = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2.3\Transmission_Lines\Testing.gdb\sway_surfaces' home_directory = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2.3\Transmission_Lines' layer_directory = home_directory + "\\layer_files" rule_directory = home_directory + "\\rule_packages" log_directory = home_directory + "\\Logs" project_ws = home_directory + "\\\Transmission_Lines.gdb" scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True start_time = time.clock() # check if input exists if arcpy.Exists(input_source): # make a copy to grab the selection input_source_copy = os.path.join(scratch_ws, "catenary_copy") if arcpy.Exists(input_source_copy): arcpy.Delete_management(input_source_copy) arcpy.CopyFeatures_management(input_source, input_source_copy) # check number of selected features num_features = int( arcpy.GetCount_management(input_source_copy).getOutput(0)) if num_features == 1: arcpy.AddMessage( "Creating sway surface for selected catenary: " + common_lib.get_name_from_feature_class(input_source)) else: arcpy.AddMessage( "Creating multiple sway surfaces for catenaries: " + common_lib.get_name_from_feature_class(input_source)) sway_lines, sway_surfaces = create_3D_swaysurface.makeSwayLinesAndSurfaces( lc_scratch_ws=scratch_ws, lc_catenary=input_source_copy, lc_angle=int(angle), lc_output_features=output_features, lc_debug=verbose, lc_use_in_memory=False) end_time = time.clock() if sway_lines and sway_surfaces: if arcpy.Exists(sway_lines) and arcpy.Exists(sway_surfaces): # create layer, set layer file # apply transparency here // checking if symbology layer is present z_unit = common_lib.get_z_unit(sway_surfaces, verbose) if z_unit == "Feet": swaysurfaceSymbologyLayer = layer_directory + "\\swaysurface3Dfeet_mp.lyrx" else: swaysurfaceSymbologyLayer = layer_directory + "\\swaysurface3Dmeter_mp.lyrx" sway_layer = common_lib.get_name_from_feature_class( sway_surfaces) arcpy.MakeFeatureLayer_management(sway_surfaces, sway_layer) sway_surfaces_mp = output_features + "_3D" if arcpy.Exists(sway_surfaces_mp): arcpy.Delete_management(sway_surfaces_mp) arcpy.Layer3DToFeatureClass_3d(sway_layer, sway_surfaces_mp, "LineNumber") output_layer3 = common_lib.get_name_from_feature_class( sway_surfaces_mp) arcpy.MakeFeatureLayer_management(sway_surfaces_mp, output_layer3) if arcpy.Exists(swaysurfaceSymbologyLayer): arcpy.ApplySymbologyFromLayer_management( output_layer3, swaysurfaceSymbologyLayer) else: msg_body = create_msg_body( "Can't find" + swaysurfaceSymbologyLayer + " in " + layer_directory, 0, 0) msg(msg_body, WARNING) if output_layer3: if z_unit == "Feet": arcpy.SetParameter(3, output_layer3) else: arcpy.SetParameter(4, output_layer3) else: raise NoSwaySurfaceOutput else: end_time = time.clock() msg_body = create_msg_body( "No sway lines or surfaces created. Exiting...", start_time, end_time) msg(msg_body, WARNING) else: end_time = time.clock() msg_body = create_msg_body( "No sway lines or surfaces created. Exiting...", start_time, end_time) msg(msg_body, WARNING) arcpy.ClearWorkspaceCache_management() if DeleteIntermediateData: fcs = common_lib.listFcsInGDB(scratch_ws) msg_prefix = "Deleting intermediate data..." msg_body = common_lib.create_msg_body(msg_prefix, 0, 0) common_lib.msg(msg_body) for fc in fcs: arcpy.Delete_management(fc) # end main code except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoPointLayer: print("Can't find attachment points layer. Exiting...") arcpy.AddError("Can't find attachment points layer. Exiting...") except NoPointLayer: print( "None or more than 1 guide line selected. Please select only 1 guide line. Exiting..." ) arcpy.AddError( "None or more than 1 guide line selected. Please select only 1 guide line. Exiting..." ) except NoCatenaryLayer: print("Can't find Catenary layer. Exiting...") arcpy.AddError("Can't find Catenary layer. Exiting...") except NoCatenaryOutput: print("Can't create Catenary output. Exiting...") arcpy.AddError("Can't create Catenary output. Exiting...") except NoSwaySurfaceOutput: print("Can't find SwaySurface output. Exiting...") arcpy.AddError("Can't find SwaySurface. Exiting...") except NoGuideLinesLayer: print("Can't find GuideLines output. Exiting...") arcpy.AddError("Can't find GuideLines. Exiting...") except MoreThan1Selected: print( "More than 1 line selected. Please select 1 guide line only. Exiting..." ) arcpy.AddError( "More than 1 line selected. Please select 1 guide line only. Exiting..." ) except NoGuideLinesOutput: print("Can't create GuideLines output. Exiting...") arcpy.AddError("Can't create GuideLines. Exiting...") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def adjustSpans(lc_scratch_ws, lc_catenary, lc_guide_lines, lc_adjust_all, lc_debug, lc_use_in_memory): try: # First, find the from and to points, and line number for this guide line. fieldList = ["FromTower", "ToTower", "LineNumber", "FromX", "FromY", "FromZ", "ToX", "ToY", "ToZ", "SagDistance", "WeightPerUnitLength"] fieldAccess = utils.FieldAccess(fieldList) # lc_guide_lines can be a layer. There is only 1 feature (selected) cursor = arcpy.da.SearchCursor(lc_guide_lines, fieldList) # Process selected guidelines. # XX Pretend for now that only one guideline is selected. index = 0 for row in cursor: # only one guideline is selected. if index == 0: fieldAccess.setRow(row) lineNumber = fieldAccess.getValue("LineNumber") fromTower = fieldAccess.getValue("FromTower") toTower = fieldAccess.getValue("ToTower") fromX = fieldAccess.getValue("FromX") fromY = fieldAccess.getValue("FromY") fromZ = fieldAccess.getValue("FromZ") toX = fieldAccess.getValue("ToX") toY = fieldAccess.getValue("ToY") toZ = fieldAccess.getValue("ToZ") sagDistance = fieldAccess.getValue("SagDistance") weightPerUnitLength = fieldAccess.getValue("WeightPerUnitLength") fromPointXYZ = vg.Point(fromX, fromY, fromZ) toPointXYZ = vg.Point(toX, toY, toZ) # Change to attachment point objects. fromPoint = create_3D_catenary.AttachmentPoint(fromPointXYZ, lineNumber, fromTower) toPoint = create_3D_catenary.AttachmentPoint(toPointXYZ, lineNumber, toTower) p("Initial sagDistance on feature:", sagDistance) # sag distance is None because we need to calculate it from the lineGuide # horizontal tension is not supplied. adjustedSpan = create_3D_catenary.makeSpan(fromPoint, toPoint, lc_guide_lines, weightPerUnitLength, None, None, None) newSpanDistance = adjustedSpan.sagDistance p("new sagDistance on feature:", newSpanDistance) if cursor: del cursor if lc_adjust_all: # We have already created the span with a sag distance. # For simplicity, we'll throw out that span object and make all six using that sag. adjustedSpans = [] fieldList = ["FromTower", "ToTower", "LineNumber", "FromX", "FromY", "FromZ", "ToX", "ToY", "ToZ"] fieldAccess = utils.FieldAccess(fieldList) whereClause = "FromTower = " + str(fromTower) + " and ToTower = " + str(toTower) p("sagDistance for all lines", newSpanDistance) # search in full feature class, not just selection i = 0 cursor = arcpy.da.SearchCursor(common_lib.get_full_path_from_layer(lc_guide_lines), fieldList, whereClause) for row in cursor: fieldAccess.setRow(row) lineNumber = fieldAccess.getValue("LineNumber") fromTower = fieldAccess.getValue("FromTower") toTower = fieldAccess.getValue("ToTower") fromX = fieldAccess.getValue("FromX") fromY = fieldAccess.getValue("FromY") fromZ = fieldAccess.getValue("FromZ") toX = fieldAccess.getValue("ToX") toY = fieldAccess.getValue("ToY") toZ = fieldAccess.getValue("ToZ") fromPointXYZ = vg.Point(fromX, fromY, fromZ) toPointXYZ = vg.Point(toX, toY, toZ) # Change to attachment point objects. fromPoint = create_3D_catenary.AttachmentPoint(fromPointXYZ, lineNumber, fromTower) toPoint = create_3D_catenary.AttachmentPoint(toPointXYZ, lineNumber, toTower) p("newSpanDistance in loop", newSpanDistance) adjustedSpan = create_3D_catenary.makeSpan(fromPoint, toPoint, common_lib.get_full_path_from_layer(lc_guide_lines), weightPerUnitLength, newSpanDistance, None) adjustedSpans.append(adjustedSpan) i+=1 # arcpy.AddMessage(str(i)) doSpanRemoveAndInsert(lc_catenary, common_lib.get_full_path_from_layer(lc_guide_lines), adjustedSpans) else: doSpanRemoveAndInsert(lc_catenary, common_lib.get_full_path_from_layer(lc_guide_lines), [adjustedSpan]) if lc_use_in_memory: arcpy.Delete_management("in_memory") if lc_debug == 0: fcs = common_lib.listFcsInGDB(lc_scratch_ws) msg_prefix = "Deleting intermediate data..." msg_body = common_lib.create_msg_body(msg_prefix, 0, 0) common_lib.msg(msg_body) for fc in fcs: arcpy.Delete_management(fc) arcpy.ClearWorkspaceCache_management() return lc_catenary, common_lib.get_full_path_from_layer(lc_guide_lines) except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0])) pass
def extract(lc_lasd, lc_ws, lc_class_code, lc_cell_size, lc_min_bridge_area, lc_extrapolate, lc_output_features, lc_log_dir, lc_debug, lc_memory_switch): try: # create dem desc = arcpy.Describe(lc_lasd) if desc.spatialReference.linearUnitName in ['Foot_US', 'Foot']: unit = 'Feet' else: unit = 'Meters' ground_code = 2 # get class codes class_code_string = desc.classCodes # get point spacing point_spacing = desc.pointSpacing # get lidar class code msg_body = create_msg_body( "Looking for class code: " + str(lc_class_code), 0, 0) msg(msg_body) class_code_list = class_code_string.split(";") # old way # class_code_list = common_lib.get_las_class_codes(lc_lasd, lc_log_dir) # Generate raster from lasd if str(lc_class_code) in class_code_list: if arcpy.Exists(lc_output_features): arcpy.Delete_management(lc_output_features) msg_body = create_msg_body( "Creating bridge surfaces using the following class codes: " + str(lc_class_code), 0, 0) msg(msg_body) bridge_ld_layer = arcpy.CreateUniqueName('bridge_ld_lyr') # Filter for bridge points arcpy.MakeLasDatasetLayer_management(lc_lasd, bridge_ld_layer, class_code=str(lc_class_code)) # create dsm from las with just bridge codes if lc_memory_switch: dsm = "in_memory/dsm" else: dsm = os.path.join(lc_ws, "dsm") if arcpy.Exists(dsm): arcpy.Delete_management(dsm) if arcpy.Exists(dsm): arcpy.Delete_management(dsm) arcpy.conversion.LasDatasetToRaster(bridge_ld_layer, dsm, 'ELEVATION', 'BINNING MAXIMUM LINEAR', sampling_type='CELLSIZE', sampling_value=lc_cell_size) arcpy.ResetEnvironments() arcpy.env.workspace = lc_ws arcpy.env.overwriteOutput = True # extrapolate dsm for better interpolation if lc_extrapolate: dsm_outer = extrapolate_raster(lc_ws, dsm, lc_cell_size, lc_log_dir, lc_debug, lc_memory_switch) # merge rasters listRasters = [] listRasters.append(dsm) listRasters.append(dsm_outer) outer_dsm_name = "dms_plus_outer" desc = arcpy.Describe(listRasters[0]) arcpy.MosaicToNewRaster_management(listRasters, lc_ws, outer_dsm_name, desc.spatialReference, "32_BIT_FLOAT", lc_cell_size, 1, "MEAN", "") dsm = os.path.join(lc_ws, outer_dsm_name) # create raster using LASPointStatisticsAsRaster if lc_memory_switch: las_point_stats = "in_memory/las_point_stats" else: las_point_stats = os.path.join(lc_ws, "las_point_stats") if arcpy.Exists(las_point_stats): arcpy.Delete_management(las_point_stats) if arcpy.Exists(las_point_stats): arcpy.Delete_management(las_point_stats) msg_body = create_msg_body( "Creating points statistics raster using the following class codes: " + str(lc_class_code), 0, 0) msg(msg_body) arcpy.management.LasPointStatsAsRaster(bridge_ld_layer, las_point_stats, "PREDOMINANT_CLASS", "CELLSIZE", 2 * lc_cell_size) lc_memory_switch = False # convert to polygon if lc_memory_switch: bridge_polys = "in_memory/bridge_polys" else: bridge_polys = os.path.join(lc_ws, "bridge_polys") if arcpy.Exists(bridge_polys): arcpy.Delete_management(bridge_polys) msg_body = create_msg_body("Creating polygons from raster", 0, 0) msg(msg_body) arcpy.conversion.RasterToPolygon(las_point_stats, bridge_polys, "SIMPLIFY", "Value", "SINGLE_OUTER_PART", None) # eliminate holes if lc_memory_switch: bridge_polys2 = "memory/bridge_polys2" else: bridge_polys2 = os.path.join(lc_ws, "bridge_polys2") if arcpy.Exists(bridge_polys2): arcpy.Delete_management(bridge_polys2) msg_body = create_msg_body("Eliminating holes from polygons", 0, 0) msg(msg_body) arcpy.management.EliminatePolygonPart(bridge_polys, bridge_polys2, "AREA", "20 SquareMeters", 0, "ANY") # regularize footprints if lc_memory_switch: bridge_polys3 = "memory/bridge_polys3" else: bridge_polys3 = os.path.join(lc_ws, "bridge_polys3") if arcpy.Exists(bridge_polys3): arcpy.Delete_management(bridge_polys3) msg_body = create_msg_body("Regularizing polygons...", 0, 0) msg(msg_body) arcpy.ddd.RegularizeBuildingFootprint(bridge_polys2, bridge_polys3, "ANY_ANGLE", 2 * lc_cell_size, 2 * lc_cell_size, 0.25, 1.5, 0.1, 1000000) # interpolate shape on the dsm if lc_memory_switch: bridge_polys5 = "memory/bridge_polys5" else: bridge_polys5 = os.path.join(lc_ws, "bridge_polys5") if arcpy.Exists(bridge_polys5): arcpy.Delete_management(bridge_polys5) msg_body = create_msg_body("Interpolating polygons...", 0, 0) msg(msg_body) if not lc_extrapolate: if lc_memory_switch: bridge_polys4 = "memory/bridge_polys4" else: bridge_polys4 = os.path.join(lc_ws, "bridge_polys4") if arcpy.Exists(bridge_polys4): arcpy.Delete_management(bridge_polys4) if common_lib.get_xy_unit(bridge_polys3, 0) == "Feet": buffer_text = "-" + str(lc_cell_size * 2) + " Feet" else: buffer_text = "-" + str(lc_cell_size * 2) + " Meters" arcpy.analysis.Buffer(bridge_polys3, bridge_polys4, buffer_text, "FULL", "ROUND", "NONE", None, "PLANAR") # densify buffer so the bridge surface will follow the dsm arcpy.edit.Densify(bridge_polys4, "DISTANCE", "10 Meters", "0.1 Meters", 10) arcpy.ddd.InterpolateShape(dsm, bridge_polys4, bridge_polys5, None, 1, "BILINEAR", "VERTICES_ONLY", 0, "EXCLUDE") else: # densify buffer so the bridge surface will follow the dsm arcpy.edit.Densify(bridge_polys3, "DISTANCE", "10 Meters", "0.1 Meters", 10) arcpy.ddd.InterpolateShape(dsm, bridge_polys3, bridge_polys5, None, 1, "BILINEAR", "VERTICES_ONLY", 0, "EXCLUDE") valueAttribute = "Shape_Area" expression = """{} > {}""".format( arcpy.AddFieldDelimiters(bridge_polys5, valueAttribute), lc_min_bridge_area) msg_body = create_msg_body( "Removing polygons with area smaller than " + str(lc_min_bridge_area) + ".", 0, 0) msg(msg_body) # select all points with good elevation values select_name = arcpy.CreateUniqueName('bridge_select_lyr') select_lyr = arcpy.MakeFeatureLayer_management( bridge_polys5, select_name).getOutput(0) arcpy.SelectLayerByAttribute_management(select_lyr, "NEW_SELECTION", expression) bridge_polys6 = lc_output_features + "_surfaces" if arcpy.Exists(bridge_polys6): arcpy.Delete_management(bridge_polys6) arcpy.CopyFeatures_management(select_lyr, bridge_polys6) return bridge_polys6 else: msg_body = create_msg_body( "Couldn't detect class code " + str(lc_class_code) + " in las dataset. Exiting...", 0, 0) msg(msg_body, WARNING) return None except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def main(): try: # Get Attributes from User if debugging == 0: # User input input_las_dataset = arcpy.GetParameterAsText(0) class_code = arcpy.GetParameter(1) cell_size = arcpy.GetParameterAsText(2) minimum_bridge_area = arcpy.GetParameterAsText(3) extrapolate_surface = arcpy.GetParameter(4) output_features = arcpy.GetParameterAsText(5) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder project_ws = aprx.defaultGeodatabase else: input_las_dataset = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\testing.lasd' class_code = 13 cell_size = str(0.5) minimum_bridge_area = str(20) extrapolate_surface = False output_features = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\Testing.gdb\bridges' home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact' project_ws = home_directory + "\\3DFloodImpact.gdb" if os.path.exists(home_directory + "\\p20"): # it is a package home_directory = home_directory + "\\p20" arcpy.AddMessage("Project Home Directory is: " + home_directory) # set directories layer_directory = home_directory + "\\layer_files" log_directory = home_directory + "\\Logs" if not os.path.exists(log_directory): os.makedirs(log_directory) # ensure numerical input is correct # fail safe for Europe's comma's cell_size = float(re.sub("[,.]", ".", cell_size)) minimum_bridge_area = float(re.sub("[,.]", ".", minimum_bridge_area)) # rename layer files (for packaging) if os.path.exists(layer_directory): common_lib.rename_file_extension(layer_directory, ".txt", ".lyrx") # Create folders and intermediate gdb, if needed scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True start_time = time.clock() # check if input exists if arcpy.Exists(input_las_dataset): # extract the elevation layers bridges = extract_bridges_from_las.extract( lc_lasd=input_las_dataset, lc_ws=scratch_ws, lc_class_code=class_code, lc_cell_size=float(cell_size), lc_min_bridge_area=float(minimum_bridge_area), lc_extrapolate=extrapolate_surface, lc_output_features=output_features, lc_log_dir=log_directory, lc_debug=verbose, lc_memory_switch=in_memory_switch) if bridges: if arcpy.Exists(bridges): arcpy.AddMessage("Adding Bridges") output_layer1 = common_lib.get_name_from_feature_class( bridges) arcpy.MakeFeatureLayer_management(bridges, output_layer1) arcpy.SetParameter(6, output_layer1) end_time = time.clock() msg_body = create_msg_body( "extract_bridges_from_las completed successfully.", start_time, end_time) msg(msg_body) else: end_time = time.clock() msg_body = create_msg_body( "No bridge surfaces created. Exiting...", start_time, end_time) msg(msg_body, WARNING) else: end_time = time.clock() msg_body = create_msg_body( "No bridge surfaces created. Exiting...", start_time, end_time) msg(msg_body, WARNING) arcpy.ClearWorkspaceCache_management() if DeleteIntermediateData: fcs = common_lib.listFcsInGDB(scratch_ws) rs = common_lib.list_rasters_in_gdb(scratch_ws, verbose) msg_prefix = "Deleting intermediate data..." msg_body = common_lib.create_msg_body(msg_prefix, 0, 0) common_lib.msg(msg_body) for fc in fcs: arcpy.Delete_management(fc) for r in rs: arcpy.Delete_management(r) # end main code except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoPointLayer: print("Can't find attachment points layer. Exiting...") arcpy.AddError("Can't find attachment points layer. Exiting...") except NoCatenaryLayer: print("Can't find Catenary layer. Exiting...") arcpy.AddError("Can't find Catenary layer. Exiting...") except NoCatenaryOutput: print("Can't create Catenary output. Exiting...") arcpy.AddError("Can't create Catenary output. Exiting...") except NoSwaySurfaceOutput: print("Can't find SwaySurface output. Exiting...") arcpy.AddError("Can't find SwaySurface. Exiting...") except NoGuideLinesLayer: print("Can't find GuideLines output. Exiting...") arcpy.AddError("Can't find GuideLines. Exiting...") except MoreThan1Selected: print( "More than 1 line selected. Please select 1 guide line only. Exiting..." ) arcpy.AddError( "More than 1 line selected. Please select 1 guide line only. Exiting..." ) except NoGuideLinesOutput: print("Can't create GuideLines output. Exiting...") arcpy.AddError("Can't create GuideLines. Exiting...") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def extrapolate_raster(lc_ws, lc_dsm, lc_cell_size, lc_log_dir, lc_debug, lc_memory_switch): try: if lc_memory_switch: raster_polygons = "memory/raster_polygons" else: raster_polygons = os.path.join(lc_ws, "raster_polygons") if arcpy.Exists(raster_polygons): arcpy.Delete_management(raster_polygons) out_geom = "POLYGON" # output geometry type arcpy.RasterDomain_3d(lc_dsm, raster_polygons, out_geom) # 2. buffer it inwards so that we have a polygon only of the perimeter plus a few cells inward?. if lc_memory_switch: polygons_inward = "memory/inward_buffer" else: polygons_inward = os.path.join(lc_ws, "inward_buffer") if arcpy.Exists(polygons_inward): arcpy.Delete_management(polygons_inward) if lc_memory_switch: polygons_outward = "memory/outward_buffer" else: polygons_outward = os.path.join(lc_ws, "outward_buffer") if arcpy.Exists(polygons_outward): arcpy.Delete_management(polygons_outward) x = float(lc_cell_size) if x < 0.1: arcpy.AddError( "Raster cell size is 0. Can't continue. Please check the raster properties." ) raise ValueError return None else: buffer_in = 6 * x xy_unit = common_lib.get_xy_unit(lc_dsm, 0) if xy_unit == "Feet": buffer_text = "-" + str(buffer_in) + " Feet" else: buffer_text = "-" + str(buffer_in) + " Meters" sideType = "OUTSIDE_ONLY" arcpy.Buffer_analysis(raster_polygons, polygons_inward, buffer_text, sideType) # create outside buffer for extent only. if xy_unit == "Feet": buffer_text = str(buffer_in) + " Feet" else: buffer_text = str(buffer_in) + " Meters" arcpy.Buffer_analysis(raster_polygons, polygons_outward, buffer_text, sideType) msg_body = create_msg_body("Buffering flood edges...", 0, 0) msg(msg_body) # 3. mask in ExtractByMask: gives just boundary raster with a few cells inwards if lc_memory_switch: extract_mask_raster = "in_memory/extract_mask" else: extract_mask_raster = os.path.join(lc_ws, "extract_mask") if arcpy.Exists(extract_mask_raster): arcpy.Delete_management(extract_mask_raster) extract_temp_raster = arcpy.sa.ExtractByMask( lc_dsm, polygons_inward) extract_temp_raster.save(extract_mask_raster) # 4. convert the output to points if lc_memory_switch: extract_mask_points = "in_memory/extract_points" else: extract_mask_points = os.path.join(lc_ws, "extract_points") if arcpy.Exists(extract_mask_points): arcpy.Delete_management(extract_mask_points) arcpy.RasterToPoint_conversion(extract_mask_raster, extract_mask_points, "VALUE") msg_body = create_msg_body("Create flood points...", 0, 0) msg(msg_body) # 5. Interpolate: this will also interpolate outside the bridge extent if lc_memory_switch: interpolated_raster = "in_memory/interpolate_raster" else: interpolated_raster = os.path.join(lc_ws, "interpolate_raster") if arcpy.Exists(interpolated_raster): arcpy.Delete_management(interpolated_raster) zField = "grid_code" power = 2 msg_body = create_msg_body("Interpolating bridge raster points...", 0, 0) msg(msg_body) arcpy.env.extent = polygons_outward # Execute IDW out_IDW = arcpy.sa.Idw(extract_mask_points, zField, lc_cell_size, power) # Save the output out_IDW.save(interpolated_raster) arcpy.ResetEnvironments() arcpy.env.workspace = lc_ws arcpy.env.overwriteOutput = True # extract the outer rim only extract_mask_raster2 = os.path.join(lc_ws, "extract_mask2") if arcpy.Exists(extract_mask_raster2): arcpy.Delete_management(extract_mask_raster2) extract_temp_raster = arcpy.sa.ExtractByMask( interpolated_raster, polygons_outward) extract_temp_raster.save(extract_mask_raster2) return extract_mask_raster2 except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) arcpy.AddError(msgs) except Exception: e = sys.exc_info()[1] arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def main(): try: # Get Attributes from User if debugging == 0: ## User input input_source2 = arcpy.GetParameter(0) adjust_all = arcpy.GetParameter(1) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder layer_directory = home_directory + "\\layer_files" rule_directory = aprx.homeFolder + "\\rule_packages" log_directory = aprx.homeFolder + "\\Logs" project_ws = aprx.defaultGeodatabase else: # debug input_source2 = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2.3\Transmission_Lines\Testing.gdb\test_adjust_line_feet1' adjust_all = False home_directory = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2\Transmission_Lines' layer_directory = home_directory + "\\layer_files" rule_directory = home_directory + "\\rule_packages" log_directory = home_directory + "\\Logs" project_ws = home_directory + "\\\Transmission_Lines.gdb" scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True start_time = time.clock() # check if input exists if arcpy.Exists(input_source2): # find associated catenary catenary_full_path = common_lib.get_full_path_from_layer( input_source2) catenary_full_path = catenary_full_path.replace( "_LineGuides_", "_") if arcpy.Exists(catenary_full_path): # make a copy to grab the selection arcpy.AddMessage("Adjusting catenary: " + catenary_full_path) arcpy.AddMessage( "Adjusting with selection of guide lines: " + common_lib.get_name_from_feature_class(input_source2)) input_source2_copy = os.path.join(scratch_ws, "guide_lines_copy") if arcpy.Exists(input_source2_copy): arcpy.Delete_management(input_source2_copy) msg_body = create_msg_body( "Making copy of " + common_lib.get_name_from_feature_class(input_source2) + " in " + scratch_ws, 0, 0) msg(msg_body) arcpy.CopyFeatures_management(input_source2, input_source2_copy) # check number of selected features num_features = int( arcpy.GetCount_management(input_source2_copy).getOutput(0)) if num_features != 1: raise MoreThan1Selected else: catenary, guide_lines = adjust_3D_catenary.adjustSpans( lc_scratch_ws=scratch_ws, lc_catenary=catenary_full_path, lc_guide_lines=input_source2, lc_adjust_all=adjust_all, lc_debug=verbose, lc_use_in_memory=False) end_time = time.clock() if catenary and guide_lines: if arcpy.Exists(catenary) and arcpy.Exists( guide_lines): # create layer, set layer file # apply transparency here // checking if symbology layer is present z_unit = common_lib.get_z_unit(catenary, verbose) if z_unit == "Feet": catenarySymbologyLayer = layer_directory + "\\catenary3Dfeet.lyrx" else: catenarySymbologyLayer = layer_directory + "\\catenary3Dmeter.lyrx" output_layer1 = common_lib.get_name_from_feature_class( catenary) arcpy.MakeFeatureLayer_management( catenary, output_layer1) if arcpy.Exists(catenarySymbologyLayer): arcpy.ApplySymbologyFromLayer_management( output_layer1, catenarySymbologyLayer) else: msg_body = create_msg_body( "Can't find" + catenarySymbologyLayer + " in " + layer_directory, 0, 0) msg(msg_body, WARNING) if z_unit == "Feet": guidelinesSymbologyLayer = layer_directory + "\\guidelines3Dfeet.lyrx" else: guidelinesSymbologyLayer = layer_directory + "\\guidelines3Dmeter.lyrx" output_layer2 = common_lib.get_name_from_feature_class( guide_lines) arcpy.MakeFeatureLayer_management( guide_lines, output_layer2) if arcpy.Exists(guidelinesSymbologyLayer): arcpy.ApplySymbologyFromLayer_management( output_layer2, guidelinesSymbologyLayer) else: msg_body = create_msg_body( "Can't find" + guidelinesSymbologyLayer + " in " + layer_directory, 0, 0) msg(msg_body, WARNING) if output_layer1: if z_unit == "Feet": arcpy.SetParameter(2, output_layer1) else: arcpy.SetParameter(3, output_layer1) else: raise NoCatenaryOutput if output_layer2: if z_unit == "Feet": arcpy.SetParameter( 4, common_lib.get_full_path_from_layer( output_layer2)) else: arcpy.SetParameter(5, output_layer2) else: raise NoGuideLinesOutput end_time = time.clock() msg_body = create_msg_body( "create_3D_catenary_tbx completed successfully.", start_time, end_time) msg(msg_body) else: end_time = time.clock() msg_body = create_msg_body( "No catenary or guide_lines created. Exiting...", start_time, end_time) msg(msg_body, WARNING) else: end_time = time.clock() msg_body = create_msg_body( "No catenary or guide_lines created. Exiting...", start_time, end_time) msg(msg_body, WARNING) arcpy.ClearWorkspaceCache_management() # end main code msg(msg_body) else: NoCatenaryLayer else: raise NoGuideLinesLayer except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoPointLayer: print("Can't find attachment points layer. Exiting...") arcpy.AddError("Can't find attachment points layer. Exiting...") except NoPointLayer: print( "None or more than 1 guide line selected. Please select only 1 guide line. Exiting..." ) arcpy.AddError( "None or more than 1 guide line selected. Please select only 1 guide line. Exiting..." ) except NoCatenaryLayer: print("Can't find Catenary layer. Exiting...") arcpy.AddError("Can't find Catenary layer. Exiting...") except NoCatenaryOutput: print("Can't create Catenary output. Exiting...") arcpy.AddError("Can't create Catenary output. Exiting...") except NoSwaySurfaceOutput: print("Can't find SwaySurface output. Exiting...") arcpy.AddError("Can't find SwaySurface. Exiting...") except NoGuideLinesLayer: print("Can't find GuideLines output. Exiting...") arcpy.AddError("Can't find GuideLines. Exiting...") except MoreThan1Selected: print( "More than 1 line selected. Please select 1 guide line only. Exiting..." ) arcpy.AddError( "More than 1 line selected. Please select 1 guide line only. Exiting..." ) except NoGuideLinesOutput: print("Can't create GuideLines output. Exiting...") arcpy.AddError("Can't create GuideLines. Exiting...") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")
def main(): try: # Get Attributes from User if debugging == 0: ## User input input_features = arcpy.GetParameterAsText(0) tower_height = arcpy.GetParameterAsText(1) voltage = arcpy.GetParameterAsText(2) do_sag_to_span = arcpy.GetParameter(3) conductor_name = arcpy.GetParameterAsText(4) horizontal_tension = arcpy.GetParameter(7) output_features = arcpy.GetParameterAsText(8) structure_type = arcpy.GetParameterAsText(13) circuits = arcpy.GetParameterAsText(14) alignment = arcpy.GetParameterAsText(15) insulator_hang_type = arcpy.GetParameterAsText(16) shield_wires = arcpy.GetParameterAsText(17) line_type = arcpy.GetParameterAsText(19) tower_material = arcpy.GetParameterAsText(20) endPoints = arcpy.GetParameterAsText(21) # script variables aprx = arcpy.mp.ArcGISProject("CURRENT") home_directory = aprx.homeFolder layer_directory = home_directory + "\\layer_files" rule_directory = aprx.homeFolder + "\\rule_packages" table_directory = home_directory + "\\tables" log_directory = aprx.homeFolder + "\\Logs" project_ws = aprx.defaultGeodatabase else: # debug input_features = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.3\3DToolsForPowerLines\Testing.gdb\testing_riverside' tower_height = "height" voltage = "400kV" do_sag_to_span = True conductor_name = "Sample Conductor 400" line_type = "Transmission" horizontal_tension = 4500 output_features = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.3\3DToolsForPowerLines\Testing.gdb\testing_riverside_3D' structure_type = "Lattice" circuits = 2 alignment = "Horizontal" insulator_hang_type = "Single" shield_wires = 0 tower_material = "Steel" endPoints = "None" #Both, Start, End, None home_directory = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.3\3DToolsForPowerLines' layer_directory = home_directory + "\\layer_files" rule_directory = home_directory + "\\rule_packages" table_directory = home_directory + "\\tables" log_directory = home_directory + "\\Logs" project_ws = home_directory + "\\Testing.gdb" scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb") arcpy.env.workspace = scratch_ws arcpy.env.overwriteOutput = True default_SagToSpanRatio = 0.035 # This number is used in the book. TODO make this user variable start_time = time.clock() in_memory = "in_memory" # check if input exists if arcpy.Exists(input_features): # test input type # current support 3D line only. TODO 2D line, 2D/3D points # set units input_z_unit = common_lib.get_z_unit(input_features, verbose) desc = arcpy.Describe(input_features) if desc.shapeType in ["Polyline", "Line", "Point"]: zValues = desc.hasZ if zValues: if desc.shapeType == "Point": # check for Line and Tower attribute line_attribute = "Line" tower_attribute = "Tower" if common_lib.check_fields( input_features, [line_attribute, tower_attribute], False, verbose) == 0: # process points lines_name = "lines_from_points" if in_memory_switch: arcpy.AddMessage( "Using in memory for processing") # junctions points needed for FFCER pointToLines = in_memory + "/" + lines_name else: # junctions points needed for makeSpans: FFCER generates 3D points with _Points in name pointToLines = os.path.join( scratch_ws, lines_name) arcpy.PointsToLine_management( input_features, pointToLines, line_attribute, tower_attribute) input_features = pointToLines else: arcpy.AddError("Input feature class requires a '" + line_attribute + "' and '" + tower_attribute + "' attribute. Exiting...") input_features = None if len(tower_height) > 0: if common_lib.check_fields(input_features, [tower_height], False, verbose) == 0: tower_attribute = "esri_tower_height" # create internal tower_height attribute if input_features: # make a copy to grab the selection input_source_copy = os.path.join( scratch_ws, "line_copy") if arcpy.Exists(input_source_copy): arcpy.Delete_management(input_source_copy) arcpy.CopyFeatures_management(input_features, input_source_copy) # create tower height attribute. set to zero for non tower height workflow # tower_attribute = "esri_tower_height" # common_lib.delete_add_field(input_source_copy, tower_attribute, "TEXT") # arcpy.CalculateField_management(input_source_copy, tower_attribute, 0, "PYTHON_9.3", None) # # # if user chooses an attribute, copy over. # if len(tower_height) > 0: # if common_lib.check_fields(input_source_copy, [tower_height], False, verbose) == 0: # # create internal tower_height attribute # common_lib.calculate_field_from_other_field(None, input_source_copy, tower_height, tower_attribute, "plus", 0, False, verbose) # check number of selected features num_features = int( arcpy.GetCount_management( input_source_copy).getOutput(0)) if num_features == 0: raise NoneSelected else: # check if conductor table exists... haveTables = False haveTower = False haveConductor = False inTowerTable = os.path.join( table_directory, TOWERTABLENAME) inConductorTable = os.path.join( table_directory, CONDUCTORTABLENAME) if arcpy.Exists(inTowerTable) and arcpy.Exists( inConductorTable): arcpy.AddMessage( "Reading tower and conductor tables: " + inTowerTable + ", " + inConductorTable + ".") inTowerSpreadsheet = inTowerTable + "\\" + TOWERINSHEET inConductorSpreadsheet = inConductorTable + "\\" + CONDUCTORINSHEET # table fields for Tower LU table. voltageField = "Voltage" minVField = "MinVSeparation" minHField = "MinHSeparation" minimumGroundClearanceField = "MinimumGroundClearance" beamColorField = "BeamColor" tableUnitsField = "Units" tower_field_list = [ voltageField, minVField, minHField, minimumGroundClearanceField, beamColorField, tableUnitsField ] # table fields for Conductor LU table. nameField = "ConductorName" weightField = "WeightPerUnitLength" rbsField = "RBS" conductor_field_list = [ nameField, weightField, rbsField, voltageField ] # read tower table code, tower_gdb_table = common_lib.import_table_with_required_fields( inTowerSpreadsheet, project_ws, TOWERTABLE, tower_field_list, verbose) if code == 0: haveTower = True else: msg_body = create_msg_body( "Failed to import " + inTowerSpreadsheet + "!", 0, 0) msg(msg_body, WARNING) haveTables = False # import conductor table code, conductor_gdb_table = common_lib.import_table_with_required_fields( inConductorSpreadsheet, project_ws, CONDUCTORTABLE, conductor_field_list, verbose) if code == 0: haveConductor = True else: msg_body = create_msg_body( "Failed to import " + inConductorSpreadsheet + "!", 0, 0) msg(msg_body, WARNING) haveTables = False if haveTower and haveConductor: haveTables = True pass else: msg_body = create_msg_body( "Failed to import necessary LUT tables!", 0, 0) msg(msg_body, ERROR) haveTables = False else: msg_body = create_msg_body( "Can't find: " + inTowerTable + " and/or " + inConductorTable + "!", 0, 0) msg(msg_body, WARNING) haveTables = False if haveTables: tower_configuration = create_3D_catenary_from_line.TowerConfiguration( ) # set parameters from UI tower_configuration.line_type = line_type tower_configuration.structure_type = structure_type tower_configuration.circuits = int(circuits) tower_configuration.alignment = alignment tower_configuration.shield_wires = int( shield_wires) tower_configuration.insulator_hang_type = insulator_hang_type tower_configuration.tower_material = tower_material msg_body = ("Retrieving values for " + voltage + " in " + TOWERTABLENAME) msg(msg_body) if do_sag_to_span == False: msg_body = ("Retrieving values for " + conductor_name + " in " + CONDUCTORTABLENAME) msg(msg_body) expression = """{} = '{}'""".format( arcpy.AddFieldDelimiters( tower_gdb_table, tower_field_list[0]), voltage) # read additional parameters from tower table with arcpy.da.SearchCursor( tower_gdb_table, tower_field_list, expression) as s_cursor: count = 0 for s_row in s_cursor: # read clearances and attachment height etc from TOWER table tower_configuration.voltage = "{0}".format( s_row[0]) tower_configuration.conductor_vertical_clearance = float( "{:.2f}".format(s_row[1])) tower_configuration.conductor_horizontal_clearance = float( "{:.2f}".format(s_row[2])) tower_configuration.minimum_ground_clearance = float( "{:.2f}".format(s_row[3])) tower_configuration.beam_color = "{0}".format( s_row[4]) tower_configuration.units = "{0}".format( s_row[5]) if do_sag_to_span is False and len( conductor_name) > 0: # read additional parameters from conductor table expression = """{} = '{}'""".format( arcpy.AddFieldDelimiters( conductor_gdb_table, conductor_field_list[0]), conductor_name) with arcpy.da.SearchCursor( conductor_gdb_table, conductor_field_list, expression) as s_cursor: count = 0 for s_row in s_cursor: # read clearances and attachment height etc from CONDUCTOR table line_weight = "{:.4f}".format( s_row[1]) sag_to_span_ratio = None arcpy.AddMessage( "Creating catenaries with a horizontal tension of: " + str(horizontal_tension) + " pounds and " + str(line_weight) + " pound weight per unit length.") else: if line_type == "Transmission": line_weight = 1.096 else: line_weight = 0.5 horizontal_tension = None sag_to_span_ratio = default_SagToSpanRatio arcpy.AddMessage( "Creating catenaries with a sagToSpan ratio of: " + str(sag_to_span_ratio) + " and " + str(line_weight) + " pound weight per unit length.") catenary, TowerModels, JunctionPoints, TowerPlacementPoints = create_3D_catenary_from_line.makeTowersAndJunctions( lc_scratch_ws=scratch_ws, lc_rule_dir=rule_directory, lc_input_features=input_features, lc_testLineWeight=float(line_weight), lc_sag_to_span_ratio=sag_to_span_ratio, lc_horizontal_tension=horizontal_tension, lc_tower_configuration=tower_configuration, lc_ends=endPoints, lc_output_features=output_features, lc_debug=verbose, lc_use_in_memory=in_memory_switch) if catenary and TowerModels and JunctionPoints and TowerPlacementPoints: if arcpy.Exists(catenary) and arcpy.Exists(TowerModels) and\ arcpy.Exists(TowerPlacementPoints) and arcpy.Exists(JunctionPoints): arcpy.SetParameter( 9, TowerPlacementPoints) arcpy.SetParameter(10, JunctionPoints) arcpy.SetParameter( 11, TowerModels ) # reordered these lines just for good chi. # create layer, set layer file # apply transparency here // checking if symbology layer is present z_unit = common_lib.get_z_unit( catenary, verbose) if z_unit == "Feet": if line_type == "Transmission": catenarySymbologyLayer = layer_directory + "\\transmission3Dfeet.lyrx" else: catenarySymbologyLayer = layer_directory + "\\distribution3Dfeet.lyrx" else: if line_type == "Transmission": catenarySymbologyLayer = layer_directory + "\\transmission3Dmeter.lyrx" else: catenarySymbologyLayer = layer_directory + "\\distribution3Dmeter.lyrx" output_layer4 = common_lib.get_name_from_feature_class( catenary) arcpy.MakeFeatureLayer_management( catenary, output_layer4) if arcpy.Exists( catenarySymbologyLayer): arcpy.ApplySymbologyFromLayer_management( output_layer4, catenarySymbologyLayer) else: msg_body = create_msg_body( "Can't find" + catenarySymbologyLayer + " in " + layer_directory, 0, 0) msg(msg_body, WARNING) if output_layer4: arcpy.SetParameter( 12, output_layer4) else: raise NoCatenaryOutput else: end_time = time.clock() msg_body = create_msg_body( "Can't find 3D catenaries or towers. Exiting...", start_time, end_time) msg(msg_body, WARNING) else: end_time = time.clock() msg_body = create_msg_body( "No 3D catenaries or towers created. Exiting...", start_time, end_time) msg(msg_body, WARNING) else: msg_body = create_msg_body( "Can't find necessary tables!", 0, 0) msg(msg_body, WARNING) else: msg_body = create_msg_body( "Error processing input features.", 0, 0) msg(msg_body, WARNING) else: end_time = time.clock() msg_body = create_msg_body( "Input feature class: " + input_features + " does not have Z values. Exiting...", start_time, end_time) msg(msg_body, WARNING) else: end_time = time.clock() msg_body = create_msg_body( "Only input feature type: Point, PolyLine supported currently. Exiting...", start_time, end_time) msg(msg_body, WARNING) arcpy.ClearWorkspaceCache_management() if DeleteIntermediateData: fcs = common_lib.listFcsInGDB(scratch_ws) msg_prefix = "Deleting intermediate data..." msg_body = common_lib.create_msg_body(msg_prefix, 0, 0) common_lib.msg(msg_body) for fc in fcs: arcpy.Delete_management(fc) else: end_time = time.clock() msg_body = create_msg_body( "Input: " + input_features + " not found. Exiting...", start_time, end_time) msg(msg_body, WARNING) # end main code except LicenseError3D: print("3D Analyst license is unavailable") arcpy.AddError("3D Analyst license is unavailable") except NoPointLayer: print("Can't find attachment points layer. Exiting...") arcpy.AddError("Can't find attachment points layer. Exiting...") except NoPointLayer: print( "None or more than 1 guide line selected. Please select only 1 guide line. Exiting..." ) arcpy.AddError( "None or more than 1 guide line selected. Please select only 1 guide line. Exiting..." ) except NoCatenaryLayer: print("Can't find Catenary layer. Exiting...") arcpy.AddError("Can't find Catenary layer. Exiting...") except NoCatenaryOutput: print("Can't create Catenary output. Exiting...") arcpy.AddError("Can't create Catenary output. Exiting...") except NoSwaySurfaceOutput: print("Can't find SwaySurface output. Exiting...") arcpy.AddError("Can't find SwaySurface. Exiting...") except NoGuideLinesLayer: print("Can't find GuideLines output. Exiting...") arcpy.AddError("Can't find GuideLines. Exiting...") except MoreThan1Selected: print( "More than 1 line selected. Please select 1 guide line only. Exiting..." ) arcpy.AddError( "More than 1 line selected. Please select 1 guide line only. Exiting..." ) except NoneSelected: print("No features found. Exiting...") arcpy.AddError("No features found. Exiting...") except NoGuideLinesOutput: print("Can't create GuideLines output. Exiting...") arcpy.AddError("Can't create GuideLines. Exiting...") except arcpy.ExecuteError: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("With error message: %s" % synerror, ERROR) msg("ArcPy Error Message: %s" % arcpy.GetMessages(2), ERROR) except FunctionError as f_e: messages = f_e.args[0] msg("Error in function: %s" % messages["function"], ERROR) msg("Error on %s" % messages["line"], ERROR) msg("Error in file name: %s" % messages["filename"], ERROR) msg("With error message: %s" % messages["synerror"], ERROR) msg("ArcPy Error Message: %s" % messages["arc"], ERROR) except: line, filename, synerror = trace() msg("Error on %s" % line, ERROR) msg("Error in file name: %s" % filename, ERROR) msg("with error message: %s" % synerror, ERROR) finally: arcpy.CheckInExtension("3D")