Exemple #1
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_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 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")
Exemple #4
0
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 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 main():
    try:
        # Get Attributes from User
        if debugging == 0:
            # script variables
            riskType = arcpy.GetParameterAsText(0)
            isPercentFlood = arcpy.GetParameter(1)
            inWaterSurfaceType = arcpy.GetParameterAsText(2)
            inSurfaceGDB = arcpy.GetParameterAsText(3)
            inDepthGDB = arcpy.GetParameterAsText(4)
            inFeature = arcpy.GetParameterAsText(5)
            featureFID = arcpy.GetParameterAsText(6)
            bufferDistance = arcpy.GetParameterAsText(7)
            tolerance = arcpy.GetParameter(8)
            inDEM = arcpy.GetParameterAsText(9)
            inLossTable = arcpy.GetParameterAsText(10)
            outTable = arcpy.GetParameterAsText(11)

            minField = arcpy.GetParameter(12)
            maxField = arcpy.GetParameter(13)
            rangeField = arcpy.GetParameter(14)
            meanField = arcpy.GetParameter(15)
            stdField = arcpy.GetParameter(16)
            areaField = arcpy.GetParameter(17)
            shapeAreaField = arcpy.GetParameter(18)
            exposureField = arcpy.GetParameter(19)
            volumeField = arcpy.GetParameter(20)

            WaterSurfaceElevationLevel = arcpy.GetParameter(21)
            GroundMinField = arcpy.GetParameter(22)
            GroundMaxField = arcpy.GetParameter(23)
            GroundRangeField = arcpy.GetParameter(24)
            GroundMeanField = arcpy.GetParameter(25)
            GroundSTDField = arcpy.GetParameter(26)
            lossField = arcpy.GetParameter(27)
        else:
            # debug
            riskType = "NOAA Sea Level Rise"  # "NOAA Sea Level Rise", "FEMA Flood Percent", "FEMA Flood Annual", "Tidal Flood", "Storm Surge", "Riverine Flood"
            #            inSurfaceGDB = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\SampleFloodData\Results_NOAA_SeaLevelRise_3D.gdb'
            inSurfaceGDB = r''
            inDepthGDB = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\SampleFloodData\NOAA_SeaLevelRise_Depth_Prj.gdb'
            inFeature = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\SampleFloodData\Baltimore.gdb\Buildings_3D'

            featureFID = "OBJECTID"
            #featureFID = "BuildingFID"

            bufferDistance = "0"
            tolerance = 1
            #            inDEM = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact\Baltimore.gdb\Sandy_Baltimore_dtm_2m_test_area1_1900'
            inDEM = ""
            inLossTable = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\tables\fema_loss_potential_feet.xls\fema_loss_potential$'
            outTable = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\Testing.gdb\flood_exposure_test'

            areaField = True
            minField = True
            maxField = True
            rangeField = False
            meanField = False
            stdField = False
            volumeField = True  # Stable
            shapeAreaField = True
            exposureField = True
            WaterSurfaceElevationLevel = True
            GroundMinField = True
            GroundMaxField = True
            GroundRangeField = False
            GroundMeanField = False
            GroundSTDField = False
            lossField = True

        # fail safe for Europese's comma's
        if bufferDistance:
            bufferDistance = float(re.sub("[,.]", ".", bufferDistance))
        else:
            bufferDistance = 0

        start_time = time.clock()

        esri_featureID = "copy_featureID"

        # check if input exists
        if arcpy.Exists(inDepthGDB):
            if arcpy.Exists(inFeature):
                success, copy_inFeature, stats_table = attribute_exposure.attribute_feature(
                    riskType=riskType,
                    inWaterSurfaceType="",
                    inSurfaceGDB=inSurfaceGDB,
                    inDepthGDB=inDepthGDB,
                    inFeature=inFeature,
                    featureFID=featureFID,
                    esri_featureID=esri_featureID,
                    bufferDistance=bufferDistance,
                    tolerance=1,
                    inDEM=inDEM,
                    lossTable=inLossTable,
                    outTable=outTable,
                    areaField=areaField,
                    minField=minField,
                    maxField=maxField,
                    rangeField=rangeField,
                    meanField=meanField,
                    stdField=stdField,
                    volumeField=volumeField,
                    shapeAreaField=shapeAreaField,
                    exposureField=exposureField,
                    WaterSurfaceElevationLevel=WaterSurfaceElevationLevel,
                    GroundMinField=GroundMinField,
                    GroundMaxField=GroundMaxField,
                    GroundRangeField=GroundRangeField,
                    GroundMeanField=GroundMeanField,
                    GroundSTDField=GroundSTDField,
                    lossField=lossField,
                    debug=debugging,
                    lc_use_in_memory=in_memory_switch)
                end_time = time.clock()

                if success:
                    if arcpy.Exists(outTable) and arcpy.Exists(
                            copy_inFeature) and arcpy.Exists(stats_table):
                        # join risk table to input feature class
                        arcpy.AddMessage(
                            "Joining " + outTable + " to " +
                            common_lib.get_name_from_feature_class(inFeature) +
                            ".")

                        join_layer = common_lib.get_name_from_feature_class(
                            copy_inFeature) + "_temp"
                        arcpy.MakeFeatureLayer_management(
                            copy_inFeature, join_layer)

                        arcpy.AddJoin_management(join_layer, esri_featureID,
                                                 outTable, esri_featureID)

                        table_gdb = common_lib.get_work_space_from_feature_class(
                            outTable, "yes")

                        join_copy = os.path.join(
                            table_gdb,
                            common_lib.get_name_from_feature_class(inFeature) +
                            "_" +
                            common_lib.get_name_from_feature_class(outTable))
                        if arcpy.Exists(join_copy):
                            arcpy.Delete_management(join_copy)

                        msg_body = create_msg_body(
                            "Creating new copy of " +
                            common_lib.get_name_from_feature_class(inFeature) +
                            " in " + table_gdb, 0, 0)
                        msg(msg_body)

                        arcpy.CopyFeatures_management(join_layer, join_copy)

                        # delete OBJECTID, esri_featureID field for table
                        common_lib.delete_fields(join_copy, [
                            common_lib.get_name_from_feature_class(outTable) +
                            "_OBJECTID"
                        ])
                        common_lib.delete_fields(join_copy, [
                            common_lib.get_name_from_feature_class(outTable) +
                            "_" + esri_featureID
                        ])
                        common_lib.delete_fields(join_copy, [
                            common_lib.get_name_from_feature_class(inFeature) +
                            "_" + esri_featureID
                        ])

                        common_lib.delete_fields(inFeature, [esri_featureID])

                        output_layer = common_lib.get_name_from_feature_class(
                            join_copy)
                        arcpy.MakeFeatureLayer_management(
                            join_copy, output_layer)

                        output_layer2 = common_lib.get_name_from_feature_class(
                            stats_table)
                        arcpy.MakeFeatureLayer_management(
                            stats_table, output_layer2)

                        if output_layer and output_layer2:
                            arcpy.SetParameter(28, output_layer)
                            arcpy.SetParameter(29, output_layer2)
                        else:
                            raise NoOutput

                        end_time = time.clock()
                        msg_body = create_msg_body(
                            "attribute_exposure_tbx completed successfully.",
                            start_time, end_time)
                        msg(msg_body)
                    else:
                        end_time = time.clock()
                        msg_body = create_msg_body(
                            "No risk table created. Exiting...", start_time,
                            end_time)
                        msg(msg_body, WARNING)
                else:
                    end_time = time.clock()
                    msg_body = create_msg_body(
                        "No risk table created. Exiting...", start_time,
                        end_time)
                    msg(msg_body, WARNING)

                arcpy.ClearWorkspaceCache_management()

                # end main code

                msg(msg_body)

            else:
                raise NoFeatureLayer
        else:
            raise NoDepthGBD

    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 NoFeatureLayer:
        print("Can't find feature layer. Exiting...")
        arcpy.AddError("Can't find feature layer. Exiting...")

    except NoDepthGBD:
        print("Can't find Depth GDB. Exiting...")
        arcpy.AddError("Can't find Depth GDB. Exiting...")

    except NoOutput:
        print("Can't create output joined with risk table. Exiting...")
        arcpy.AddError(
            "Can't create output joined with risk table. Exiting...")

    except NoGuideLinesLayer:
        print("Can't find GuideLines output. Exiting...")
        arcpy.AddError("Can't find GuideLines. 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")
        arcpy.CheckInExtension("Spatial")
Exemple #7
0
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")
Exemple #8
0
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)
            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 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")
Exemple #11
0
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
Exemple #12
0
    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(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)
Exemple #13
0
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")
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 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]))
Exemple #16
0
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 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]))
Exemple #18
0
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")
Exemple #19
0
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")
Exemple #20
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")
Exemple #21
0
def set_value(input_source, no_flood_value, flood_elevation_value, 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
            input_source = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact\3DFloodImpact.gdb\c2ft_inundation_Clip'
            output_raster = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact\Testing.gdb\RasterValue'
            no_flood_value = "0"  # value or "NoData"
            flood_elevation_value = 8
            home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\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

        flood_elevation_value = float(re.sub("[,.]", ".", flood_elevation_value))

        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))

                # 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_source) + "...", 0, 0)
                        msg(msg_body)
                        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_source, input_source, whereClause)
                        outSetNull_temp.save(null_for_no_flooded_areas_raster)

                        input_source = null_for_no_flooded_areas_raster

                    else:
                        raise ValueError

                # check where there is IsNull and set the con values
                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_source)
                is_Null_raster.save(is_Null)

                # Con
                if arcpy.Exists(output_raster):
                    arcpy.Delete_management(output_raster)
                temp_con_raster = arcpy.sa.Con(is_Null, input_source, flood_elevation_value)
                temp_con_raster.save(output_raster)

                msg_body = create_msg_body(
                            "Setting flood elevation value to: " + str(flood_elevation_value) + " in " + common_lib.get_name_from_feature_class(output_raster) + "...", 0, 0)
                msg(msg_body)

                end_time = time.clock()
                msg_body = create_msg_body("Set Flood Elevation Value for Raster completed successfully.", start_time, end_time)

                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")