def makeSwayLinesAndSurfaces(lc_scratch_ws, lc_catenary, lc_angle, lc_output_features, lc_debug, lc_use_in_memory): try: includedSwayLinesFC = None includedSwaySurfacesFC = None sr = arcpy.Describe(lc_catenary).spatialReference geometry_type = "POLYLINE" has_m = "DISABLED" has_z = "ENABLED" from_tower_field = "FromTower" to_tower_field = "ToTower" tower_field = "Tower" line_number_field = "LineNumber" count_field = "COUNT" swaylines = "SwayLines" swaysurfaces = "SwaySurfaces" in_memory = "in_memory" spatial_reference = arcpy.Describe(lc_catenary).spatialReference includedSwayLinesFC = lc_output_features + "_swaylines" includedSwayLinesFC_dirname = os.path.dirname(includedSwayLinesFC) includedSwayLinesFC_basename = os.path.basename(includedSwayLinesFC) if arcpy.Exists(includedSwayLinesFC): arcpy.Delete_management(includedSwayLinesFC) arcpy.CreateFeatureclass_management(includedSwayLinesFC_dirname, includedSwayLinesFC_basename, geometry_type, "", has_m, has_z, spatial_reference) common_lib.delete_add_field(includedSwayLinesFC, from_tower_field, "LONG") common_lib.delete_add_field(includedSwayLinesFC, to_tower_field, "LONG") common_lib.delete_add_field(includedSwayLinesFC, line_number_field, "LONG") common_lib.delete_add_field(includedSwayLinesFC, count_field, "LONG") geometry_type = "POLYGON" includedSwaySurfacesFC= os.path.join(lc_scratch_ws, "temp_sway_surfaces") includedSwaySurfacesFC_dirname = os.path.dirname(includedSwaySurfacesFC) includedSwaySurfacesFC_basename = os.path.basename(includedSwaySurfacesFC) if arcpy.Exists(includedSwaySurfacesFC): arcpy.Delete_management(includedSwaySurfacesFC) arcpy.CreateFeatureclass_management(includedSwaySurfacesFC_dirname, includedSwaySurfacesFC_basename, geometry_type, "", has_m, has_z, spatial_reference) common_lib.delete_add_field(includedSwaySurfacesFC, from_tower_field, "LONG") common_lib.delete_add_field(includedSwaySurfacesFC, to_tower_field, "LONG") common_lib.delete_add_field(includedSwaySurfacesFC, line_number_field, "LONG") common_lib.delete_add_field(includedSwaySurfacesFC, count_field, "LONG") arcpy.AddMessage("Creating sway surfaces...") # cycle through catenaries with arcpy.da.SearchCursor(lc_catenary, ['SHAPE@', 'FromTower', 'ToTower', 'LineNumber']) as cursor: for row in cursor: polyline = row[0] fromPoint = None toPoint = None # get start and end points from line, we assume 1 part for part in polyline: for pnt in part: if pnt: ptGeom = arcpy.PointGeometry(pnt, sr) line_length = polyline.length chainage = polyline.measureOnLine(ptGeom) if chainage == 0: # start point point = vg.Point(pnt.X, pnt.Y, pnt.Z) fromPoint = create_3D_catenary.AttachmentPoint(point, row[3], row[1]) elif chainage - line_length == 0: # end point point = vg.Point(pnt.X, pnt.Y, pnt.Z) toPoint = create_3D_catenary.AttachmentPoint(point, row[3], row[2]) else: # in between points continue # fill span object if fromPoint and toPoint: span = create_3D_catenary.Span(fromPoint, toPoint) catenary_line = vg.arcpyPolylineToVGPolyline(polyline) span.polyline = catenary_line makeSways(span, lc_angle) makeSurfacePanels(span) doInsert_SwayLinesSurfaces(includedSwayLinesFC, includedSwaySurfacesFC, [span]) else: arcpy.AddError("Error finding start and end points for catenary") if lc_use_in_memory: arcpy.Delete_management("in_memory") arcpy.ClearWorkspaceCache_management() return includedSwayLinesFC, includedSwaySurfacesFC 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 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 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 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]))