def add_minimum_height_above_drainage(lc_ws, lc_input_features,
                                      lc_input_surface, lc_had_field,
                                      lc_memory_switch):

    try:
        if arcpy.Exists(lc_input_features):
            # find minimum value in input surface
            # run zonal stats and get minimum DEM elevation for each polygon

            heightsTable = os.path.join(lc_ws, "heightsTable")

            if arcpy.Exists(heightsTable):
                arcpy.Delete_management(heightsTable)

            stat_type = "MINIMUM"

            arcpy.sa.ZonalStatisticsAsTable(lc_input_features, esri_featureID,
                                            lc_input_surface, heightsTable,
                                            "DATA", stat_type)

            common_lib.delete_fields(lc_input_features, [min_field])
            arcpy.JoinField_management(lc_input_features, esri_featureID,
                                       heightsTable, esri_featureID, min_field)

            # add minimum Z information for input feature
            common_lib.delete_fields(lc_input_features, zmin_field)
            arcpy.AddZInformation_3d(lc_input_features, zmin_field, None)

            # calculate height above drainage surface
            common_lib.add_field(lc_input_features, lc_had_field, "DOUBLE", 5)

            expression = "round(float(!" + zmin_field + "! - !" + min_field + "!), 2)"
            arcpy.CalculateField_management(lc_input_features, lc_had_field,
                                            expression, "PYTHON3", None)

            common_lib.delete_fields(lc_input_features, [min_field])
        else:
            msg_body = create_msg_body(
                "Couldn't find input feature class: " + str(lc_input_features),
                0, 0)
            msg(msg_body, WARNING)

    except arcpy.ExecuteError:
        msgs = arcpy.GetMessages(2)  # Get the tool error messages

        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def template_function(local_var1, local_var2, local_verbose):

    if local_verbose == 1:
        msg("--------------------------")
        msg("Executing template_function...")

    start_time = time.clock()

    try:
        i = 0
        msg_prefix = ""
        failed = True

        # your function code

        msg_prefix = "Function create_3Dflood_level_tbx completed successfully."
        failed = False
        return 0

    except:
        line, filename, synerror = trace()
        failed = True
        msg_prefix = ""
        raise FunctionError(
            {
                "function": "create_3Dflood_level_tbx",
                "line": line,
                "filename": filename,
                "synerror": synerror,
                "arc": str(arcpy.GetMessages(2))
            }
        )

    finally:
        end_time = time.clock()
        msg_body = create_msg_body(msg_prefix, start_time, end_time)
        if failed:
            msg(msg_body, ERROR)
        else:
            if local_verbose == 1:
                msg(msg_body)
            pass
Esempio n. 3
0
def main():
    try:
        # Get Attributes from User
        if debugging == 0:
            ## User input
            input_source = arcpy.GetParameter(0)
            flood_elevation_attribute = arcpy.GetParameter(1)
            default_flood_elevation_value = arcpy.GetParameterAsText(2)

            # script variables
            aprx = arcpy.mp.ArcGISProject("CURRENT")
            home_directory = aprx.homeFolder
            layer_directory = home_directory + "\\layer_files"
            rule_directory = aprx.homeFolder + "\\rule_packages"
            log_directory = aprx.homeFolder + "\\Logs"
            project_ws = aprx.defaultGeodatabase

        else:
            # debug
            input_source = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact\Baltimore.gdb\test_area1_slr6ft_pol'
            flood_elevation_attribute = FLOODELEV
            default_flood_elevation_value = 6

            home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact'
            layer_directory = home_directory + "\\layer_files"
            rule_directory = home_directory + "\\rule_packages"
            log_directory = home_directory + "\\Logs"
            project_ws = home_directory + "\\3DFloodImpact.gdb"

        scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb")
        arcpy.env.workspace = scratch_ws
        arcpy.env.overwriteOutput = True

        start_time = time.clock()

        # check if input exists
        if arcpy.Exists(input_source):
            full_path_source = common_lib.get_full_path_from_layer(
                input_source)
        else:
            raise NoPolygonLayer

        desc = arcpy.Describe(input_source)

        success = set_flood_elevation_value_polygon.set_value(
            input_source=full_path_source,
            flood_elevation_attribute=flood_elevation_attribute,
            esri_flood_elevation_attribute=FLOODELEV,
            default_flood_elevation_value=default_flood_elevation_value,
            debug=0)

        end_time = time.clock()

        if success:
            msg_body = create_msg_body(
                "set_flood_elevation_value_tbx_polygon completed successfully.",
                start_time, end_time)
        else:
            msg_body = create_msg_body(
                "error in set_flood_elevation_value_tbx_polygon.", start_time,
                end_time)

        arcpy.ClearWorkspaceCache_management()

        # end main code

        msg(msg_body)

    except LicenseError3D:
        print("3D Analyst license is unavailable")
        arcpy.AddError("3D Analyst license is unavailable")

    except NoPolygonLayer:
        print("Can't find Raster layer. Exiting...")
        arcpy.AddError("Can't find Raster layer. Exiting...")

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

    except arcpy.ExecuteError:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("With error message:  %s" % synerror, ERROR)
        msg("ArcPy Error Message:  %s" % arcpy.GetMessages(2), ERROR)

    except FunctionError as f_e:
        messages = f_e.args[0]
        msg("Error in function:  %s" % messages["function"], ERROR)
        msg("Error on %s" % messages["line"], ERROR)
        msg("Error in file name:  %s" % messages["filename"], ERROR)
        msg("With error message:  %s" % messages["synerror"], ERROR)
        msg("ArcPy Error Message:  %s" % messages["arc"], ERROR)

    except:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("with error message:  %s" % synerror, ERROR)

    finally:
        arcpy.CheckInExtension("3D")
Esempio n. 4
0
def main():
    try:
        # Get Attributes from User
        if debugging == 0:
            ## User input

            depth_raster = arcpy.GetParameterAsText(0)
            dtm = arcpy.GetParameterAsText(1)
            smooth_factor = arcpy.GetParameter(2)
            output_raster = arcpy.GetParameterAsText(3)

            # script variables
            aprx = arcpy.mp.ArcGISProject("CURRENT")
            home_directory = aprx.homeFolder
            layer_directory = home_directory + "\\layer_files"
            rule_directory = aprx.homeFolder + "\\rule_packages"
            log_directory = aprx.homeFolder + "\\Logs"
            project_ws = aprx.defaultGeodatabase

        else:
            # debug
            depth_raster = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\data\Vancouver\3DFloodImpact\depth_rasters.gdb\I_0_5pct_nodata_clip_utm'
            dtm = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\data\Vancouver\3DFloodImpact\Surrey_Buildings.gdb\DEM'
            smooth_factor = 30
            output_raster = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.2.3\3DFloodImpact\Testing.gdb\FloodElevationRaster'

            home_directory = r'D:\\Gert\Work\\Esri\\Solutions\\3DFloodImpact\\work2.2.3\\3DFloodImpact'
            layer_directory = home_directory + "\\layer_files"
            rule_directory = home_directory + "\\rule_packages"
            log_directory = home_directory + "\\Logs"
            project_ws = home_directory + "\\3DFloodImpact.gdb"

        start_time = time.clock()

        # check if input exists
        if arcpy.Exists(depth_raster):
            full_path_source = common_lib.get_full_path_from_layer(
                depth_raster)

            flood_elevation_raster = create_flood_elevation_from_depth_raster.create_raster(
                depth_raster=depth_raster,
                dtm=dtm,
                smoothing=smooth_factor,
                output_raster=output_raster,
                use_in_memory=in_memory_switch,
                debug=debugging)

            if arcpy.Exists(output_raster):
                # output_layer = common_lib.get_name_from_feature_class(flood_elevation_raster)
                # arcpy.MakeRasterLayer_management(flood_elevation_raster, output_layer)
                #
                # arcpy.SetParameter(3, output_layer)

                end_time = time.clock()
                msg_body = create_msg_body(
                    "create_flood_elevation_from_depth_raster completed successfully.",
                    start_time, end_time)
            else:
                raise NoRasterLayer

        else:
            raise NoRasterLayer

        arcpy.ClearWorkspaceCache_management()

        # end main code

        msg(msg_body)

    except LicenseError3D:
        print("3D Analyst license is unavailable")
        arcpy.AddError("3D Analyst license is unavailable")

    except NoRasterLayer:
        print("Can't find Raster layer. Exiting...")
        arcpy.AddError("Can't find Raster layer. Exiting...")

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

    except arcpy.ExecuteError:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("With error message:  %s" % synerror, ERROR)
        msg("ArcPy Error Message:  %s" % arcpy.GetMessages(2), ERROR)

    except FunctionError as f_e:
        messages = f_e.args[0]
        msg("Error in function:  %s" % messages["function"], ERROR)
        msg("Error on %s" % messages["line"], ERROR)
        msg("Error in file name:  %s" % messages["filename"], ERROR)
        msg("With error message:  %s" % messages["synerror"], ERROR)
        msg("ArcPy Error Message:  %s" % messages["arc"], ERROR)

    except:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("with error message:  %s" % synerror, ERROR)

    finally:
        arcpy.CheckInExtension("3D")
Esempio n. 5
0
def main():
    try:
        # Get Attributes from User
        if debugging == 0:
            ## User input
            input_source = arcpy.GetParameterAsText(0)

            # script variables
            aprx = arcpy.mp.ArcGISProject("CURRENT")
            home_directory = aprx.homeFolder
            log_directory = aprx.homeFolder + "\\Logs"

        else:
            # debug
            input_source = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact\3DFloodImpact.gdb\WSE_01pct_testarea2'
            home_directory = r'D:\Gert\Work\Esri\Solutions\LocalGovernment\DevelopmentCapacity\work1.4\DevelopmentCapacity'
            log_directory = home_directory + "\\Logs"

        scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb")
        arcpy.env.workspace = scratch_ws
        arcpy.env.overwriteOutput = True

        common_lib.set_up_logging(log_directory, TOOLNAME)
        start_time = time.clock()

        if arcpy.CheckExtension("3D") == "Available":
            arcpy.CheckOutExtension("3D")
            """The source code of the tool."""
            arcpy.AddMessage("Input layer: " + input_source)

            # check if input exists
            if arcpy.Exists(input_source):
                full_path_source = common_lib.get_full_path_from_layer(
                    input_source)
                data_type, shape_type = common_lib.get_raster_featuretype_from_layer(
                    full_path_source)

                if data_type == "FeatureClass":
                    if shape_type == "Polygon":
                        arcpy.AddMessage("!!!")
                        arcpy.AddWarning(
                            "Please use the 'Convert flooding polygon to raster' task to convert polygons to raster."
                        )
                        arcpy.AddMessage("!!!")
                    else:
                        arcpy.AddWarning(
                            "Only polygon feature classes are supported.")

                cs_name, cs_vcs_name, projected = common_lib.get_cs_info(
                    full_path_source, 0)

                if not projected:
                    arcpy.AddWarning(
                        "Please re-project your input layer to a projected coordinate system."
                    )

                if not cs_vcs_name:
                    arcpy.AddWarning(
                        "Please define a vertical coordinate system.")
            else:
                raise NoInputLayer
        else:
            raise LicenseError3D

        arcpy.ClearWorkspaceCache_management()

        end_time = time.clock()
        msg_body = create_msg_body(
            "check_flooding_data_tbx completed successfully.", start_time,
            end_time)
        msg(msg_body)

        # end main code

    except NoInputLayer:
        print("Can't find Input layer. Exiting...")
        arcpy.AddError("Can't find Input layer. Exiting...")

    except NotProjected:
        print(
            "Input layer does not have a projected coordinate system. Exiting..."
        )
        arcpy.AddWarning(
            "Input layer does not have a projected coordinate system. Exiting..."
        )

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

    except LicenseError3D:
        print("3D Analyst license is unavailable")
        arcpy.AddError("3D Analyst license is unavailable")

    except arcpy.ExecuteError:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("With error message:  %s" % synerror, ERROR)
        msg("ArcPy Error Message:  %s" % arcpy.GetMessages(2), ERROR)

    except FunctionError as f_e:
        messages = f_e.args[0]
        msg("Error in function:  %s" % messages["function"], ERROR)
        msg("Error on %s" % messages["line"], ERROR)
        msg("Error in file name:  %s" % messages["filename"], ERROR)
        msg("With error message:  %s" % messages["synerror"], ERROR)
        msg("ArcPy Error Message:  %s" % messages["arc"], ERROR)

    except:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("with error message:  %s" % synerror, ERROR)

    finally:
        arcpy.CheckInExtension("3D")
Esempio n. 6
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")
Esempio n. 7
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 calculate_height(lc_input_features, lc_ws, lc_tin_dir, lc_input_surface,
                     lc_output_features, lc_log_dir, lc_debug,
                     lc_memory_switch):

    try:
        # create dem
        desc = arcpy.Describe(lc_input_features)
        if desc.spatialReference.linearUnitName in ['Foot_US', 'Foot']:
            unit = 'Feet'
        else:
            unit = 'Meters'

        # Generate raster from lasd
        if arcpy.Exists(lc_input_features):
            if arcpy.Exists(lc_output_features):
                arcpy.Delete_management(lc_output_features)

            # make a copy
            bridge_polys = lc_output_features + "_height"

            if arcpy.Exists(bridge_polys):
                arcpy.Delete_management(bridge_polys)

            arcpy.CopyFeatures_management(lc_input_features, bridge_polys)

            # create string field for featureFID
            oidFieldName = arcpy.Describe(bridge_polys).oidFieldName
            common_lib.delete_add_field(bridge_polys, esri_featureID, "TEXT")
            arcpy.CalculateField_management(bridge_polys, esri_featureID,
                                            "!" + oidFieldName + "!",
                                            "PYTHON_9.3")

            msg_body = create_msg_body(
                "Calculating height above surface for: " +
                common_lib.get_name_from_feature_class(lc_input_features), 0,
                0)
            msg(msg_body)

            # create bridge tin
            out_tin = os.path.join(lc_tin_dir, "bridge_tin")
            if arcpy.Exists(out_tin):
                arcpy.Delete_management(out_tin)

            msg_body = create_msg_body(
                "Creating raster for: " +
                common_lib.get_name_from_feature_class(lc_input_features), 0,
                0)
            msg(msg_body)

            arcpy.CreateTin_3d(
                out_tin,
                arcpy.Describe(bridge_polys).spatialReference,
                "{} Shape.Z Hard_Clip <None>".format(bridge_polys), "DELAUNAY")

            # turn to raster
            if 0:
                bridge_raster = "in_memory/bridge_raster"
            else:
                bridge_raster = os.path.join(lc_ws, "bridge_raster")
                if arcpy.Exists(bridge_raster):
                    arcpy.Delete_management(bridge_raster)

            # use same cell size as input surface
            cell_size = arcpy.GetRasterProperties_management(
                lc_input_surface, "CELLSIZEX")[0]

            dataType = "FLOAT"
            method = "LINEAR"
            sampling = "CELLSIZE " + str(cell_size)
            zfactor = "1"

            arcpy.TinRaster_3d(out_tin, bridge_raster, dataType, method,
                               sampling, zfactor)

            add_minimum_height_above_water_surface(lc_ws, bridge_polys,
                                                   bridge_raster,
                                                   lc_input_surface,
                                                   lc_memory_switch)

            # create point file for labeling
            if lc_memory_switch:
                bridge_points = "in_memory/bridge_points"
            else:
                bridge_points = os.path.join(lc_ws, "bridge_points")
                if arcpy.Exists(bridge_points):
                    arcpy.Delete_management(bridge_points)

            arcpy.FeatureToPoint_management(bridge_polys, bridge_points,
                                            "INSIDE")

            bridge_points3D = lc_output_features + "_points_3D"
            if arcpy.Exists(bridge_points3D):
                arcpy.Delete_management(bridge_points3D)

            # create 3D point
            arcpy.FeatureTo3DByAttribute_3d(bridge_points, bridge_points3D,
                                            zmin_field)

            # add unit field
            common_lib.delete_add_field(bridge_points3D, esri_unit, "TEXT")

            expression = """{} IS NOT NULL""".format(
                arcpy.AddFieldDelimiters(bridge_points3D, has_field))

            # select all points with good elevation values
            local_layer = common_lib.get_name_from_feature_class(
                bridge_points3D) + "_lyr"
            select_lyr = arcpy.MakeFeatureLayer_management(
                bridge_points3D, local_layer).getOutput(0)
            arcpy.SelectLayerByAttribute_management(select_lyr,
                                                    "NEW_SELECTION",
                                                    expression, None)

            z_unit = common_lib.get_z_unit(bridge_points3D, lc_debug)

            if z_unit == "Meters":
                expression = "'m'"
            else:
                expression = "'ft'"

            arcpy.CalculateField_management(select_lyr, esri_unit, expression,
                                            "PYTHON_9.3")
            arcpy.SelectLayerByAttribute_management(select_lyr,
                                                    "CLEAR_SELECTION")

            common_lib.delete_fields(bridge_polys, [min_field, zmin_field])
            common_lib.delete_fields(bridge_points3D, [min_field, zmin_field])

            return bridge_polys, bridge_points3D
        else:
            msg_body = create_msg_body(
                "Couldn't find input feature class: " + str(lc_input_features),
                0, 0)
            msg(msg_body, WARNING)

            return None

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def makeTowersAndJunctions(lc_scratch_ws, lc_rule_dir, lc_input_features, lc_testLineWeight, lc_sag_to_span_ratio, lc_horizontal_tension,
                                    lc_tower_configuration, lc_ends, lc_output_features,
                                    lc_debug, lc_use_in_memory):

    try:
        # Making Tower configuration object to hold fields for TowerBasePoints layer.
        towerConfiguration = lc_tower_configuration

        geometry_type = "POINT"
        has_m = "DISABLED"
        has_z = "ENABLED"

        in_memory = "in_memory"
        tower_placement_points_name = "TowerLocations"
        out_tower_models_name = "TowerModels"
        junction_intoFFCER = "JunctionPoints"
        junction_points_name = "JunctionPoints"
        CE_additionP = "_Points"
        CE_additionMP = "_MPoints"
        CE_additionL = "_Lines"
        spans_name = "Spans"

        exportPointsRPK = lc_rule_dir + "\\" + "TransmissionTower_ExportPoints.rpk"
        exportModelsRPK = lc_rule_dir + "\\" + "TransmissionTower_ExportModel.rpk"

        spatial_reference = arcpy.Describe(lc_input_features).spatialReference

        # create empty feature class with required fields
        msg_body = create_msg_body("Preparing output feature classes...", 0, 0)
        msg(msg_body)

        # create / check out features classes
        # tower placement points
        outTowerPlacementPoints = lc_output_features + "_" + tower_placement_points_name

        if arcpy.Exists(outTowerPlacementPoints):
            arcpy.Delete_management(outTowerPlacementPoints)

        # tower models: multipatches generated from tower placement points
        outTowerModels = lc_output_features + "_" + out_tower_models_name

        if arcpy.Exists(outTowerModels):
            arcpy.Delete_management(outTowerModels)

        outJunctionPointsFromFFCER = lc_output_features + "_" + junction_points_name

        if arcpy.Exists(outJunctionPointsFromFFCER):
            arcpy.Delete_management(outJunctionPointsFromFFCER)

        # output spans
        outSpansIntoScript = lc_output_features + "_" + spans_name

        if arcpy.Exists(outSpansIntoScript):
            arcpy.Delete_management(outSpansIntoScript)

        # NOTE: these items are used to create attributes and values must correspond to
        # TowerConfiguration attributes. If this list changes you must update TowerConfiguration object class

        # Tower RPK Fields, in TowerBasePoints layer.
        tower_number_field = "TowerNumber"
        units_field = "Units"
        cardinal_direction_field = "Cardinal_Direction"
        line_type_field = "Line_Type"
        structure_type_field = "Structure_Type"
        voltage_field = "Voltage"
        circuits_field = "Circuits"
        alignment_field = "Alignment"
        conductor_vertical_clearance_field = "Conductor_Vertical_Clearance"
        conductor_horizontal_clearance_field = "Conductor_Horizontal_Clearance"
        minimum_ground_clearance_field = "Minimum_Ground_Clearance"
        maximum_sag_allowance_field = "Maximum_Sag_Allowance"
        shield_wires_field = "Shield_Wires"
        insulator_hang_type_field = "Insulator_Hang_Type"
        beam_color_field = "Beam_Color"
        tower_material = "DistPole_Material"

        tower_base_point_field_dict = {cardinal_direction_field:"DOUBLE",
                                            tower_number_field:"LONG",
                                            line_type_field:"TEXT",
                                            structure_type_field:"TEXT",
                                            voltage_field:"TEXT",
                                            circuits_field:"LONG",
                                            alignment_field:"TEXT",
                                            conductor_vertical_clearance_field:"FLOAT",
                                            conductor_horizontal_clearance_field:"FLOAT",
                                            minimum_ground_clearance_field:"FLOAT",
                                            maximum_sag_allowance_field:"FLOAT",
                                            shield_wires_field:"LONG",
                                            insulator_hang_type_field:"TEXT",
                                            beam_color_field:"TEXT",
                                            units_field:"TEXT",
                                            tower_material: "TEXT"
                                       }

        catenary = None
        fieldList = ["SHAPE@"]
        fieldAccess = utils.FieldAccess(fieldList)

        num_features = int(arcpy.GetCount_management(lc_input_features).getOutput(0))

        lineCursor = arcpy.da.SearchCursor(lc_input_features, fieldList)
        i = 1

        for row in lineCursor:
            if lc_use_in_memory:
                arcpy.AddMessage("Using in memory for processing")

                # junctions points needed for FFCER
                outJunctionPointsIntoFFCER = in_memory + "/" + junction_intoFFCER

            else:
                # junctions points needed for makeSpans: FFCER generates 3D points with _Points in name
                outJunctionPointsIntoFFCER = os.path.join(lc_scratch_ws, junction_intoFFCER)

            if arcpy.Exists(outJunctionPointsIntoFFCER):
                arcpy.Delete_management(outJunctionPointsIntoFFCER)

            # delete additional CE output
            if arcpy.Exists(outJunctionPointsIntoFFCER + CE_additionP):
                arcpy.Delete_management(outJunctionPointsIntoFFCER + CE_additionP)

            if arcpy.Exists(outJunctionPointsIntoFFCER + CE_additionMP):
                arcpy.Delete_management(outJunctionPointsIntoFFCER + CE_additionMP)

            if arcpy.Exists(outJunctionPointsIntoFFCER + CE_additionL):
                arcpy.Delete_management(outJunctionPointsIntoFFCER + CE_additionL)

                # create temporary per line feature classes
                # temp tower placement points
            if lc_use_in_memory:
                arcpy.AddMessage("Using in memory for processing")

                temp_outTowerPlacementPoints = in_memory + "/" + tower_placement_points_name + "_temp"

            else:
                temp_outTowerPlacementPoints = os.path.join(lc_scratch_ws, tower_placement_points_name + "_temp")

            # first time delete just to be sure
            if i == 1 and arcpy.Exists(temp_outTowerPlacementPoints):
                arcpy.Delete_management(temp_outTowerPlacementPoints)

            if arcpy.Exists(temp_outTowerPlacementPoints):
                arcpy.TruncateTable_management(temp_outTowerPlacementPoints)
            else:
                temp_outtowerPlacementPoints_dirname = os.path.dirname(temp_outTowerPlacementPoints)
                temp_outtowerPlacementPoints_basename = os.path.basename(temp_outTowerPlacementPoints)

                arcpy.CreateFeatureclass_management(temp_outtowerPlacementPoints_dirname,
                                                    temp_outtowerPlacementPoints_basename,
                                                    geometry_type, "", has_m, has_z,
                                                    spatial_reference)
                # add required fields for towerPlacementPoints
                arcpy.AddMessage("Adding required fields to tower placement points...")

                start_time = time.clock()

#                for k, v in tower_base_point_field_dict.items():
#                    common_lib.delete_add_field(temp_outTowerPlacementPoints, k, v)

                listoffields = []
                for k, v in tower_base_point_field_dict.items():
                    field = []
                    field.append(k)
                    field.append(v)
                    listoffields.append(field)

                arcpy.management.AddFields(temp_outTowerPlacementPoints, listoffields)

                end_time = time.clock()
                msg_body = create_msg_body("Time to create fields...", start_time,
                                           end_time)
                msg(msg_body)

            # temp tower models: multipatches generated from tower placement points
            if lc_use_in_memory:
                arcpy.AddMessage("Using in memory for processing")

                temp_outTowerModels = in_memory + "/" + out_tower_models_name + "_temp"
            else:
                temp_outTowerModels = os.path.join(lc_scratch_ws, out_tower_models_name + "_temp")

            if arcpy.Exists(temp_outTowerModels):
                arcpy.Delete_management(temp_outTowerModels)

            if lc_use_in_memory:
                arcpy.AddMessage("Using in memory for processing")

                temp_outJunctionPointsFromFFCER = in_memory + "/" + out_tower_models_name + "_temp"

            else:
                temp_outJunctionPointsFromFFCER = os.path.join(lc_scratch_ws, junction_points_name + "_temp")

            if arcpy.Exists(temp_outJunctionPointsFromFFCER):
                arcpy.Delete_management(temp_outJunctionPointsFromFFCER)

            # output temp spans
            if lc_use_in_memory:
                arcpy.AddMessage("Using in memory for processing")

                temp_outSpansIntoScript = in_memory + "/" + spans_name + "_temp"

            else:
                temp_outSpansIntoScript = os.path.join(lc_scratch_ws, spans_name + "_temp")

            if arcpy.Exists(temp_outSpansIntoScript):
                arcpy.Delete_management(temp_outSpansIntoScript)

            # multiple lines are now supported...
            if i >= 0:
                fieldAccess.setRow(row)

                arcpyPolyline = fieldAccess.getValue("SHAPE@")

                # read the line
                vgPolyline = vg.arcpyPolylineToVGPolyline(arcpyPolyline)
                if vgPolyline:
                    # get tower point objects here. Initializing TowerPlacementLine builds the TowerBasePoints.
                    # from towerConfiguration
                    pint("Preparing tower base points for feature: " + str(i) + " out of " + str(num_features) + ".")

                    towerPlacementLine = TowerPlacementLine(vgPolyline, towerConfiguration, lc_sag_to_span_ratio, lc_horizontal_tension, lc_testLineWeight, lc_ends)
                    towerBasePoints = towerPlacementLine.towerBasePoints
                    # put the tower base points into the scene.
                    InsertTowerBasePoints(towerBasePoints, towerConfiguration, temp_outTowerPlacementPoints, list(tower_base_point_field_dict.keys()))
                    arcpy.ddd.FeaturesFromCityEngineRules(temp_outTowerPlacementPoints, exportPointsRPK,
                                                          outJunctionPointsIntoFFCER, "DROP_EXISTING_FIELDS",
                                                          "INCLUDE_REPORTS", "FEATURE_PER_LEAF_SHAPE")

                    # TODO built in check when FFCER fails XX Gert

                    # copy _Points fc to input gdb
                    arcpy.CopyFeatures_management(outJunctionPointsIntoFFCER + CE_additionP, temp_outJunctionPointsFromFFCER)

                    arcpy.ddd.FeaturesFromCityEngineRules(temp_outTowerPlacementPoints, exportModelsRPK,
                                                          temp_outTowerModels, "INCLUDE_EXISTING_FIELDS",
                                                          "EXCLUDE_REPORTS", "FEATURE_PER_SHAPE")

                    pint("Making spans for feature: " + str(i) + " out of " + str(num_features) + ".")

                    catenary, guide_lines = create_3D_catenary.makeSpans(lc_scratch_ws=lc_scratch_ws,
                                                        lc_inPoints=temp_outJunctionPointsFromFFCER,
                                                        lc_testLineWeight=lc_testLineWeight,
                                                        lc_sag_to_span_ratio=lc_sag_to_span_ratio,
                                                        lc_horizontal_tension=lc_horizontal_tension,
                                                        lc_output_features=temp_outSpansIntoScript,
                                                        lc_debug=lc_debug,
                                                        lc_use_in_memory=False,
                                                        lc_cleanup=False,
                                                        lc_caller=TOOLNAME)

                    # append features to output feature classes

                    # catenary, outTowerModels, outJunctionPointsFromFFCER, outTowerPlacementPoints
                    schemaType = "NO_TEST"
                    if arcpy.Exists(outSpansIntoScript):
                        arcpy.Append_management(catenary, outSpansIntoScript, schemaType)
                    else:
                        arcpy.Copy_management(catenary, outSpansIntoScript)

                    pint("Made spans for feature: " + str(i) + " out of " + str(num_features) + ".")

                    if arcpy.Exists(outTowerModels):
                        arcpy.Append_management(temp_outTowerModels, outTowerModels, schemaType)
                    else:
                        arcpy.Copy_management(temp_outTowerModels, outTowerModels)

                    pint("Made towers for feature: " + str(i) + " out of " + str(num_features) + ".")

                    if arcpy.Exists(outJunctionPointsFromFFCER):
                        arcpy.Append_management(temp_outJunctionPointsFromFFCER, outJunctionPointsFromFFCER, schemaType)
                    else:
                        arcpy.Copy_management(temp_outJunctionPointsFromFFCER, outJunctionPointsFromFFCER)

                    pint("Made junctions for feature: " + str(i) + " out of " + str(num_features) + ".")

                    if arcpy.Exists(outTowerPlacementPoints):
                        arcpy.Append_management(temp_outTowerPlacementPoints, outTowerPlacementPoints, schemaType)
                    else:
                        arcpy.Copy_management(temp_outTowerPlacementPoints, outTowerPlacementPoints)
                else:
                    raise MultipartInputNotSupported

            i += 1

        return outSpansIntoScript, outTowerModels, outJunctionPointsFromFFCER, outTowerPlacementPoints

    except MultipartInputNotSupported:
        print("Multipart features are not supported. Exiting...")
        arcpy.AddError("Multipart features are not supported. Exiting...")

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
    pass
Esempio n. 10
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")
def main():
    try:
        # Get Attributes from User
        if debugging == 0:
            ## User input
            input_source = arcpy.GetParameter(0)
            line_weight = arcpy.GetParameterAsText(1)
            horizontal_tension = arcpy.GetParameterAsText(2)
            output_features = arcpy.GetParameterAsText(3)

            # script variables
            aprx = arcpy.mp.ArcGISProject("CURRENT")
            home_directory = aprx.homeFolder
            layer_directory = home_directory + "\\layer_files"
            rule_directory = aprx.homeFolder + "\\rule_packages"
            log_directory = aprx.homeFolder + "\\Logs"
            project_ws = aprx.defaultGeodatabase

        else:
            # debug
            input_source = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2.3\Transmission_Lines\Seattle_Utility_Sample.gdb\Attachment_Points'
            line_weight = 1.096
            horizontal_tension = 4500
            output_features = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2.3\Transmission_Lines\Testing.gdb\catenary3D'

            home_directory = r'D:\Gert\Work\Esri\Solutions\Utilities\Electric\work2.2.3\Transmission_Lines'
            layer_directory = home_directory + "\\layer_files"
            rule_directory = home_directory + "\\rule_packages"
            log_directory = home_directory + "\\Logs"
            project_ws = home_directory + "\\\Transmission_Lines.gdb"

        scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb")
        arcpy.env.workspace = scratch_ws
        arcpy.env.overwriteOutput = True

        start_time = time.clock()

        default_SagToSpanRatio = 0.035  # This number is used in the book. TODO make this user variable
        sag_to_span_ratio = default_SagToSpanRatio

        # check if input exists
        if arcpy.Exists(input_source):
            # make a copy to grab the selection
            # make new feature classes of observer and target input fcs. This is because FFCER doesn't work with selections

            arcpy.AddMessage(
                "Processing input source: " +
                common_lib.get_name_from_feature_class(input_source))

            input_source_copy = os.path.join(scratch_ws,
                                             "attachment_points_copy")
            if arcpy.Exists(input_source_copy):
                arcpy.Delete_management(input_source_copy)

            msg_body = create_msg_body(
                "Making copy of " +
                common_lib.get_name_from_feature_class(input_source) + " in " +
                scratch_ws, 0, 0)
            msg(msg_body)

            arcpy.CopyFeatures_management(input_source, input_source_copy)
        else:
            raise NoPointLayer

        desc = arcpy.Describe(input_source)

        catenary, guide_lines = create_3D_catenary.makeSpans(
            lc_scratch_ws=scratch_ws,
            lc_inPoints=input_source_copy,
            lc_testLineWeight=float(line_weight),
            lc_sag_to_span_ratio=sag_to_span_ratio,
            lc_horizontal_tension=float(horizontal_tension),
            lc_output_features=output_features,
            lc_debug=verbose,
            lc_use_in_memory=False,
            lc_cleanup=True,
            lc_caller=TOOLNAME)

        end_time = time.clock()

        if catenary and guide_lines:
            if arcpy.Exists(catenary) and arcpy.Exists(guide_lines):

                # create layer, set layer file
                # apply transparency here // checking if symbology layer is present
                z_unit = common_lib.get_z_unit(catenary, verbose)

                if z_unit == "Feet":
                    catenarySymbologyLayer = layer_directory + "\\catenary3Dfeet.lyrx"
                else:
                    catenarySymbologyLayer = layer_directory + "\\catenary3Dmeter.lyrx"

                output_layer1 = common_lib.get_name_from_feature_class(
                    catenary)
                arcpy.MakeFeatureLayer_management(catenary, output_layer1)

                if arcpy.Exists(catenarySymbologyLayer):
                    arcpy.ApplySymbologyFromLayer_management(
                        output_layer1, catenarySymbologyLayer)
                else:
                    msg_body = create_msg_body(
                        "Can't find" + catenarySymbologyLayer + " in " +
                        layer_directory, 0, 0)
                    msg(msg_body, WARNING)

                if z_unit == "Feet":
                    guidelinesSymbologyLayer = layer_directory + "\\guidelines3Dfeet.lyrx"
                else:
                    guidelinesSymbologyLayer = layer_directory + "\\guidelines3Dmeter.lyrx"

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

                if arcpy.Exists(guidelinesSymbologyLayer):
                    arcpy.ApplySymbologyFromLayer_management(
                        output_layer2, guidelinesSymbologyLayer)
                else:
                    msg_body = create_msg_body(
                        "Can't find" + guidelinesSymbologyLayer + " in " +
                        layer_directory, 0, 0)
                    msg(msg_body, WARNING)

                if output_layer1:
                    if z_unit == "Feet":
                        arcpy.SetParameter(4, output_layer1)
                    else:
                        arcpy.SetParameter(5, output_layer1)
                else:
                    raise NoCatenaryOutput

                if output_layer2:
                    if z_unit == "Feet":
                        arcpy.SetParameter(6, output_layer2)
                    else:
                        arcpy.SetParameter(7, output_layer2)
                else:
                    raise NoGuideLinesOutput

                end_time = time.clock()
                msg_body = create_msg_body(
                    "create_3D_catenary_tbx completed successfully.",
                    start_time, end_time)
                msg(msg_body)
            else:
                end_time = time.clock()
                msg_body = create_msg_body(
                    "No catenary or guide_lines created. Exiting...",
                    start_time, end_time)
                msg(msg_body, WARNING)
        else:
            end_time = time.clock()
            msg_body = create_msg_body(
                "No catenary or guide_lines created. Exiting...", start_time,
                end_time)
            msg(msg_body, WARNING)

        arcpy.ClearWorkspaceCache_management()

        # end main code

        msg(msg_body)

    except LicenseError3D:
        print("3D Analyst license is unavailable")
        arcpy.AddError("3D Analyst license is unavailable")

    except NoPointLayer:
        print("Can't find attachment points layer. Exiting...")
        arcpy.AddError("Can't find attachment points layer. Exiting...")

    except NoCatenaryOutput:
        print("Can't create Catenary output. Exiting...")
        arcpy.AddError("Can't Catenary output. Exiting...")

    except NoGuideLinesOutput:
        print("Can't create GuideLines output. Exiting...")
        arcpy.AddError("Can't create GuideLines. Exiting...")

    except arcpy.ExecuteError:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("With error message:  %s" % synerror, ERROR)
        msg("ArcPy Error Message:  %s" % arcpy.GetMessages(2), ERROR)

    except FunctionError as f_e:
        messages = f_e.args[0]
        msg("Error in function:  %s" % messages["function"], ERROR)
        msg("Error on %s" % messages["line"], ERROR)
        msg("Error in file name:  %s" % messages["filename"], ERROR)
        msg("With error message:  %s" % messages["synerror"], ERROR)
        msg("ArcPy Error Message:  %s" % messages["arc"], ERROR)

    except:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("with error message:  %s" % synerror, ERROR)

    finally:
        arcpy.CheckInExtension("3D")
def main():
    try:
        # Get Attributes from User
        if debugging == 0:
            ## User input
            input_source = arcpy.GetParameter(0)
            no_flood_value = arcpy.GetParameterAsText(1)
            baseline_elevation_raster = arcpy.GetParameter(2)
            baseline_elevation_value = arcpy.GetParameterAsText(3)
            smooth_factor = arcpy.GetParameter(4)
            output_features = arcpy.GetParameterAsText(5)

            # script variables
            aprx = arcpy.mp.ArcGISProject("CURRENT")
            home_directory = aprx.homeFolder
            layer_directory = home_directory + "\\layer_files"
            rule_directory = aprx.homeFolder + "\\rule_packages"
            log_directory = aprx.homeFolder + "\\Logs"
            project_ws = aprx.defaultGeodatabase
        else:
            # debug
            input_source = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\3DFloodImpact.gdb\slr_6_ProjectRaster'
            no_flood_value = "NoData"
            baseline_elevation_raster = r''
            baseline_elevation_value = "0"
            smooth_factor = 0
            output_features = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\3DFloodImpact.gdb\FloodPolys'

            home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact'
            layer_directory = home_directory + "\\layer_files"
            rule_directory = home_directory + "\\rule_packages"
            log_directory = home_directory + "\\Logs"
            project_ws = home_directory + "\\3DFloodImpact.gdb"

        scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb")
        arcpy.env.workspace = scratch_ws
        arcpy.env.overwriteOutput = True

        start_time = time.clock()

        if arcpy.CheckExtension("3D") == "Available":
            arcpy.CheckOutExtension("3D")

            # check if input exists
            if arcpy.Exists(input_source):
                full_path_source = common_lib.get_full_path_from_layer(input_source)
            else:
                raise NoRasterLayer

            # check if input exists
            if arcpy.Exists(baseline_elevation_raster):
                full_path_baseline_raster = common_lib.get_full_path_from_layer(baseline_elevation_raster)
            else:
                full_path_baseline_raster = None

            desc = arcpy.Describe(input_source)

            flood_polygons = create_3Dflood_level.flood_from_raster(input_source=full_path_source,
                                        input_type=desc.dataType,
                                        no_flood_value=no_flood_value,
                                        baseline_elevation_raster=full_path_baseline_raster,
                                        baseline_elevation_value=baseline_elevation_value,
                                        outward_buffer=0,
                                        output_polygons=output_features,
                                        smoothing=smooth_factor,
                                        debug=debugging)

            # create layer, set layer file
            # apply transparency here // checking if symbology layer is present
            z_unit = common_lib.get_z_unit(flood_polygons, verbose)

            if z_unit == "Feet":
                floodSymbologyLayer = layer_directory + "\\flood3Dfeet.lyrx"
            else:
                floodSymbologyLayer = layer_directory + "\\flood3Dmeter.lyrx"

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

            if arcpy.Exists(floodSymbologyLayer):
                arcpy.ApplySymbologyFromLayer_management(output_layer, floodSymbologyLayer)
            else:
                msg_body = create_msg_body("Can't find" + floodSymbologyLayer + " in " + layer_directory, 0, 0)
                msg(msg_body, WARNING)

            if output_layer:
                if z_unit == "Feet":
                    arcpy.SetParameter(6, output_layer)
                else:
                    arcpy.SetParameter(7, output_layer)
            else:
                raise NoOutput

            end_time = time.clock()
            msg_body = create_msg_body("create_3Dflood_level_tbx completed successfully.", start_time, end_time)

        else:
            raise LicenseError3D

        arcpy.ClearWorkspaceCache_management()

        # end main code

        msg(msg_body)

    except LicenseError3D:
        print("3D Analyst license is unavailable")
        arcpy.AddError("3D Analyst license is unavailable")

    except NoRasterLayer:
        print("Can't find Raster layer. Exiting...")
        arcpy.AddError("Can't find Raster layer. Exiting...")

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

    except arcpy.ExecuteError:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("With error message:  %s" % synerror, ERROR)
        msg("ArcPy Error Message:  %s" % arcpy.GetMessages(2), ERROR)

    except FunctionError as f_e:
        messages = f_e.args[0]
        msg("Error in function:  %s" % messages["function"], ERROR)
        msg("Error on %s" % messages["line"], ERROR)
        msg("Error in file name:  %s" % messages["filename"], ERROR)
        msg("With error message:  %s" % messages["synerror"], ERROR)
        msg("ArcPy Error Message:  %s" % messages["arc"], ERROR)

    except:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("with error message:  %s" % synerror, ERROR)

    finally:
        arcpy.CheckInExtension("3D")
Esempio n. 13
0
def makeSpan(fromPoint, toPoint, lc_includedTransmissionLineGuides, lc_testLineWeight, sagToSpanRatio, sagDistance, horizontalTension):
    try:
        span = Span(fromPoint, toPoint)
        # Define span shape here, then set polyline on Span object.
        spanVector3D = vg.getVectorFromTwoPoints(fromPoint, toPoint)
        spanLength3D = vg.magnitude(spanVector3D)
        spanVector2DNoZ = vg.Vector(spanVector3D.x, spanVector3D.y, 0)
        spanLength2D = vg.magnitude(spanVector2DNoZ)
        fromTower = fromPoint.towerNumber
        toTower = toPoint.towerNumber
        lineNumber = fromPoint.lineNumber
        attachmentPointHeightDifference = abs(toPoint.z - fromPoint.z)
        lineWeightPerUnitLength = lc_testLineWeight

        # NOTE: The logic below depends on which script calls the function.
        # When called from create_3D_catenary(this script), inside makeSpans() function,
        # new spans are created based on horizontal tension, and sagDistance is calculated.

        # When called from adjust_3D:
        # It is called once with sagDistance of None which triggers use of line guide.
        # Once sagDistance is known, if "adjust all" tool option is used, then sagDistance is used to
        # make the matching spans, so sagDistance is not None.

        w = lineWeightPerUnitLength
        H = None
        # When called from create_3D_catenary_from_line, GP tool might send sagToSpanRatio:
        if sagToSpanRatio is not None:
            D = sagToSpanRatio * spanLength2D

        # When called from create_3D_catenary_from_line, GP tool might send horizontal tension:
        elif horizontalTension is not None:
            # Using sag approximation until I find better formula.
            # XX This method doesn't work with the degree of accuracy needed, but is close enough and will be visually corrected.
            H = horizontalTension
            catenaryConstant = H/w
            sOver2 = spanLength3D/2
            inverseCatenaryConstant = w/H
            coshValue = math.cosh(sOver2 * inverseCatenaryConstant)
            coshValueMinusOne = coshValue - 1
            sagApproximation = catenaryConstant * coshValueMinusOne
            D = sagApproximation

        # When called from adjust_3D_catenary the first time sagDistance is None:
        elif sagDistance is None and lc_includedTransmissionLineGuides is not None:

            # Query LineGuides for line with matching from, to, and line.
            fieldListLineGuides = ["SHAPE@", "FromTower", "ToTower", "LineNumber"]
            fieldAccessLineGuides = utils.FieldAccess(fieldListLineGuides)
            whereClauseLineGuides = "FromTower = " + str(fromTower) + " and ToTower = " + str(
                toTower) + " and LineNumber = " + str(lineNumber)
            cursor = arcpy.da.SearchCursor(lc_includedTransmissionLineGuides, fieldListLineGuides, whereClauseLineGuides)

            msg_body = create_msg_body("Creating span for line number " + str(lineNumber) + " from tower " + str(
                                                                    fromTower) + " to tower " + str(toTower) + ".", 0, 0)
            msg(msg_body)

            # default lineGuideZ for when none exists. This ensures no square root of zero causes error.
            #  XX In what part? The calculation of D, I guess.
            #  XX This brings up a question... Will this entire function work if both points are at same z? That would be very unlikely.
            lineGuideZ = None
            if fromPoint.z > toPoint.z:
                defaultLineGuideZ = toPoint.z - 10
            else:
                defaultLineGuideZ = fromPoint.z - 10

            for row in cursor:
                fieldAccessLineGuides.setRow(row)
                lineGuideShape = fieldAccessLineGuides.getValue("SHAPE@")
                lineGuide = vg.arcpyPolylineToVGPolyline(lineGuideShape)
                lineGuideZ = lineGuide.nodes[0].z
            if cursor:
                del cursor

            # If no user line exists, this span has not been run yet, so use default.
            # Only issue warning if user-adjusted line is above either attachment point.
            if lineGuideZ is None:
                lineGuideZ = defaultLineGuideZ
            elif lineGuideZ > fromPoint.z or lineGuideZ > toPoint.z:
                arcpy.AddWarning("Warning: Match line placed above lowest point.")
                lineGuideZ = defaultLineGuideZ

            # Redundant with Tension case above:
            if fromPoint.z > toPoint.z:
                dLow = toPoint.z - lineGuideZ
                hSign = 1
            else:
                dLow = fromPoint.z - lineGuideZ
                hSign = -1

            h = attachmentPointHeightDifference
            dHigh = dLow + h

            h_over4 = (h / 4) * hSign
            sqrtDLow = math.sqrt(dLow)
            sqrtDHigh = math.sqrt(dHigh)
            lowPlusHigh = sqrtDLow + sqrtDHigh
            lowMinusHigh = sqrtDLow - sqrtDHigh
            lowPlusHigh_over_lowMinusHigh = lowPlusHigh / lowMinusHigh
            D = h_over4 * lowPlusHigh_over_lowMinusHigh

        else:
            # When called from adjust_3D_catenary the second time, sagDistance is supplied:
            D = sagDistance


        #############################################################
        #############################################################
        # Sag is determined now.
        # The next part creates a function to calculate the catenary height (z-value) along a 2D line from tower to tower.

        # variables from the diagram:
        S = spanLength2D
        h = attachmentPointHeightDifference
        w = lineWeightPerUnitLength  # lb/ft

        xHigh = (S / 2) * (1 + (h / (4 * D)))
        xLow = (S / 2) * (1 - (h / (4 * D)))


        dHigh = D * pow((1 + (h / (4 * D))), 2) # D sub L in book.
        dLow = D * pow((1 - (h / (4 * D))), 2)  # D sub R in book. # XX This is reversed, because the book chose left and right, rather than high and low.

        if H is None: # else horizontal tension was supplied.
            hLow = (w * pow(xLow, 2)) / (2 * dLow)
            #hHigh = (w * pow(xHigh, 2)) / (2 * dHigh)
            H = hLow  # or hHigh, because they must be equal.


        # Use external function for 3D polyline (below).
        makeSpanPolylineShapeAndLineGuide(span, xHigh, xLow, dHigh, dLow, H, w)


        # LineLength (uses these values from above calculations):
        # S = spanLength2D
        # xLow, xHigh
        # w = lineWeightPerUnitLength
        # H = Horizontal tension
        xRcubed_plus_xLcubed = pow(abs(xLow), 3) + pow(xHigh, 3) #XX note the abs!
        wSquared_over_6HSquared = pow(w, 2) / (6 * pow(H, 2))
        L = S + (xRcubed_plus_xLcubed * wSquared_over_6HSquared)

        # Save span data for span feature class.
        span.sagDistance = D
        span.horizontalTension = H
        span.lineLength = L
        span.weightPerUnitLength = w

        return span

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
    pass
Esempio n. 14
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
Esempio n. 15
0
                "Processing input source: " +
                common_lib.get_name_from_feature_class(input_raster))

            if replace_value != "NoData":
                if not common_lib.is_number(replace_value):
                    raise ValueError
                else:
                    txt_replace_value = str(replace_value)
            else:
                txt_replace_value = "NoData"
                replace_value = ""

            msg_body = create_msg_body(
                "Setting replacement value for negative raster values to: " +
                txt_replace_value + " in " + output_raster + "...", 0, 0)
            msg(msg_body)

            # con on mosaic
            myConRaster = arcpy.sa.Con(input_raster, input_raster,
                                       replace_value, "VALUE >= 0")
            myConRaster.save(output_raster)

            if arcpy.Exists(output_raster):
                #                output_layer = common_lib.get_name_from_feature_class(output_raster) + "no_negative"
                #                arcpy.MakeRasterLayer_management(output_raster, output_layer)

                #                arcpy.SetParameter(3, output_layer)

                end_time = time.clock()
                msg_body = create_msg_body(
                    "Remove negative values from raster completed successfully.",
def flood_from_raster(input_source, input_type, no_flood_value,
                      baseline_elevation_raster, baseline_elevation_value,
                      outward_buffer, output_polygons, smoothing, debug):
    try:
        # Get Attributes from User
        if debug == 0:
            # script variables
            aprx = arcpy.mp.ArcGISProject("CURRENT")
            home_directory = aprx.homeFolder
            tiff_directory = home_directory + "\\Tiffs"
            tin_directory = home_directory + "\\Tins"
            scripts_directory = aprx.homeFolder + "\\Scripts"
            rule_directory = aprx.homeFolder + "\\rule_packages"
            log_directory = aprx.homeFolder + "\\Logs"
            layer_directory = home_directory + "\\layer_files"
            project_ws = aprx.defaultGeodatabase

            enableLogging = True
            DeleteIntermediateData = True
            verbose = 0
            use_in_memory = True
        else:
            # debug
            home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact'
            tiff_directory = home_directory + "\\Tiffs"
            tin_directory = home_directory + "\\Tins"
            scripts_directory = home_directory + "\\Scripts"
            rule_directory = home_directory + "\\rule_packages"
            log_directory = home_directory + "\\Logs"
            layer_directory = home_directory + "\\layer_files"
            project_ws = home_directory + "\\Results.gdb"

            enableLogging = False
            DeleteIntermediateData = True
            verbose = 1
            use_in_memory = False

        scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb")
        arcpy.env.workspace = scratch_ws
        arcpy.env.overwriteOutput = True

        # fail safe for Europese's comma's
        baseline_elevation_value = float(
            re.sub("[,.]", ".", baseline_elevation_value))

        if not os.path.exists(tiff_directory):
            os.makedirs(tiff_directory)

        if not os.path.exists(tin_directory):
            os.makedirs(tin_directory)

        common_lib.set_up_logging(log_directory, TOOLNAME)
        start_time = time.clock()

        if arcpy.CheckExtension("3D") == "Available":
            arcpy.CheckOutExtension("3D")

            if arcpy.CheckExtension("Spatial") == "Available":
                arcpy.CheckOutExtension("Spatial")

                flood_level_layer_mp = None

                desc = arcpy.Describe(input_source)

                arcpy.AddMessage(
                    "Processing input source: " +
                    common_lib.get_name_from_feature_class(input_source))

                spatial_ref = desc.spatialReference

                # create IsNull to be used to clip and check for NoData.
                if use_in_memory:
                    is_null0 = "in_memory/is_null0"
                else:
                    is_null0 = os.path.join(scratch_ws, "is_null0")
                    if arcpy.Exists(is_null0):
                        arcpy.Delete_management(is_null0)

                is_null_raster = arcpy.sa.IsNull(input_source)
                is_null_raster.save(is_null0)

                if spatial_ref.type == 'PROJECTED' or spatial_ref.type == 'Projected':
                    # check input source type: projected rasters ONLY!!!!
                    # check type, if polygon -> convert to raster
                    if input_type == "RasterLayer" or input_type == "RasterDataset" or input_type == "raster":
                        # prep raster
                        # smooth result using focal stats
                        if smoothing > 0:
                            if use_in_memory:
                                focal_raster = "in_memory/focal_raster"
                            else:
                                focal_raster = os.path.join(
                                    scratch_ws, "focal_raster")
                                if arcpy.Exists(focal_raster):
                                    arcpy.Delete_management(focal_raster)

                            if not (1 <= smoothing <= 100):
                                smoothing = 30

                            neighborhood = arcpy.sa.NbrRectangle(
                                smoothing, smoothing, "CELL")

                            flood_elev_raster = arcpy.sa.FocalStatistics(
                                input_source, neighborhood, "MEAN", "true")
                            flood_elev_raster.save(focal_raster)

                            # con
                            if use_in_memory:
                                smooth_input = "in_memory/smooth_input"
                            else:
                                smooth_input = os.path.join(
                                    scratch_ws, "smooth_input")
                                if arcpy.Exists(smooth_input):
                                    arcpy.Delete_management(smooth_input)

                            output = arcpy.sa.Con(is_null0, input_source,
                                                  flood_elev_raster)
                            output.save(smooth_input)

                            input_raster = smooth_input
                        else:
                            input_raster = input_source
                    else:
                        raise NotSupported

                    # use numeric value for determining non flooded areas: set these values to NoData. We need NoData for clippng later on
                    if no_flood_value != "NoData":
                        if common_lib.is_number(no_flood_value):
                            msg_body = create_msg_body(
                                "Setting no flood value: " + no_flood_value +
                                " to NoData in copy of " +
                                common_lib.get_name_from_feature_class(
                                    input_raster) + "...", 0, 0)
                            msg(msg_body)

                            if use_in_memory:
                                null_for_no_flooded_areas_raster = "in_memory/null_for_flooded"
                            else:
                                null_for_no_flooded_areas_raster = os.path.join(
                                    scratch_ws, "null_for_flooded")
                                if arcpy.Exists(
                                        null_for_no_flooded_areas_raster):
                                    arcpy.Delete_management(
                                        null_for_no_flooded_areas_raster)

                            whereClause = "VALUE = " + no_flood_value

                            # Execute SetNull
                            outSetNull_temp = arcpy.sa.SetNull(
                                input_raster, input_raster, whereClause)
                            outSetNull_temp.save(
                                null_for_no_flooded_areas_raster)

                            input_raster = null_for_no_flooded_areas_raster
                        else:
                            raise ValueError
                    else:
                        pass

                    msg_body = create_msg_body(
                        "Checking for NoData values in raster: " +
                        common_lib.get_name_from_feature_class(input_raster) +
                        ". NoData values are considered to be non-flooded areas!",
                        0, 0)
                    msg(msg_body)

                    max_value = arcpy.GetRasterProperties_management(
                        is_null0, "MAXIMUM")[0]
                    #                    has_nodata = arcpy.GetRasterProperties_management(input_raster, "ANYNODATA")[0] ## fails on some rasters

                    if int(max_value) == 1:
                        # 1. get the outline of the raster as polygon via RasterDomain
                        xy_unit = common_lib.get_xy_unit(input_raster, 0)

                        if xy_unit:
                            cell_size = arcpy.GetRasterProperties_management(
                                input_raster, "CELLSIZEX")

                            if baseline_elevation_raster:
                                # check celll size
                                cell_size_base = arcpy.GetRasterProperties_management(
                                    baseline_elevation_raster, "CELLSIZEX")

                                if cell_size_base.getOutput(
                                        0) == cell_size.getOutput(0):
                                    # Execute Plus
                                    if use_in_memory:
                                        flood_plus_base_raster = "in_memory/flooding_plus_base"
                                    else:
                                        flood_plus_base_raster = os.path.join(
                                            scratch_ws, "flooding_plus_base")
                                        if arcpy.Exists(
                                                flood_plus_base_raster):
                                            arcpy.Delete_management(
                                                flood_plus_base_raster)

                                    listRasters = []
                                    listRasters.append(input_raster)
                                    listRasters.append(
                                        baseline_elevation_raster)

                                    desc = arcpy.Describe(listRasters[0])
                                    arcpy.MosaicToNewRaster_management(
                                        listRasters, scratch_ws,
                                        "flooding_plus_base",
                                        desc.spatialReference, "32_BIT_FLOAT",
                                        cell_size, 1, "SUM", "")

                                    # check where there is IsNull and set the con values
                                    if use_in_memory:
                                        is_Null = "in_memory/is_Null"
                                    else:
                                        is_Null = os.path.join(
                                            scratch_ws, "is_Null")
                                        if arcpy.Exists(is_Null):
                                            arcpy.Delete_management(is_Null)

                                    is_Null_raster = arcpy.sa.IsNull(
                                        input_raster)
                                    is_Null_raster.save(is_Null)

                                    # Con
                                    if use_in_memory:
                                        flood_plus_base_raster_null = "in_memory/flooding_plus_base_null"
                                    else:
                                        flood_plus_base_raster_null = os.path.join(
                                            scratch_ws,
                                            "flooding_plus_base_null")
                                        if arcpy.Exists(
                                                flood_plus_base_raster_null):
                                            arcpy.Delete_management(
                                                flood_plus_base_raster_null)

                                    msg_body = create_msg_body(
                                        "Adding baseline elevation raster to input flood layer...",
                                        0, 0)
                                    msg(msg_body)

                                    fpbrn = arcpy.sa.Con(
                                        is_Null, input_raster,
                                        flood_plus_base_raster)
                                    fpbrn.save(flood_plus_base_raster_null)

                                    input_raster = flood_plus_base_raster_null
                                else:
                                    arcpy.AddWarning(
                                        "Cell size of " + input_raster +
                                        " is different than " +
                                        baseline_elevation_raster +
                                        ". Ignoring Base Elevation Raster.")
                            else:
                                if baseline_elevation_value > 0:
                                    if use_in_memory:
                                        flood_plus_base_raster = "in_memory/flood_plus_base"
                                    else:
                                        flood_plus_base_raster = os.path.join(
                                            scratch_ws, "flooding_plus_base")
                                        if arcpy.Exists(
                                                flood_plus_base_raster):
                                            arcpy.Delete_management(
                                                flood_plus_base_raster)
                                    arcpy.Plus_3d(input_raster,
                                                  baseline_elevation_value,
                                                  flood_plus_base_raster)

                                    input_raster = flood_plus_base_raster

                            msg_body = create_msg_body(
                                "Creating 3D polygons...", 0, 0)
                            msg(msg_body)

                            if use_in_memory:
                                raster_polygons = "in_memory/raster_polygons"
                            else:
                                raster_polygons = os.path.join(
                                    scratch_ws, "raster_polygons")
                                if arcpy.Exists(raster_polygons):
                                    arcpy.Delete_management(raster_polygons)

                            out_geom = "POLYGON"  # output geometry type
                            arcpy.RasterDomain_3d(input_raster,
                                                  raster_polygons, out_geom)

                            # 2. buffer it inwards so that we have a polygon only of the perimeter plus a few ???????cells inward???????.
                            if use_in_memory:
                                polygons_inward = "in_memory/inward_buffer"
                            else:
                                polygons_inward = os.path.join(
                                    scratch_ws, "inward_buffer")
                                if arcpy.Exists(polygons_inward):
                                    arcpy.Delete_management(polygons_inward)

                            x = float(
                                re.sub("[,.]", ".",
                                       str(cell_size.getOutput(0))))
                            #                            x = float(str(cell_size.getOutput(0)))

                            if x < 0.1:
                                arcpy.AddError(
                                    "Raster cell size is 0. Can't continue. Please check the raster properties."
                                )
                                raise ValueError
                            else:
                                buffer_in = 3 * int(x)

                                if xy_unit == "Feet":
                                    buffer_text = "-" + str(
                                        buffer_in) + " Feet"
                                else:
                                    buffer_text = "-" + str(
                                        buffer_in) + " Meters"

                                sideType = "OUTSIDE_ONLY"
                                arcpy.Buffer_analysis(raster_polygons,
                                                      polygons_inward,
                                                      buffer_text, sideType)

                                msg_body = create_msg_body(
                                    "Buffering flood edges...", 0, 0)
                                msg(msg_body)

                                # 3. mask in ExtractByMask: gives just boundary raster with a few cells inwards
                                if use_in_memory:
                                    extract_mask_raster = "in_memory/extract_mask"
                                else:
                                    extract_mask_raster = os.path.join(
                                        scratch_ws, "extract_mask")
                                    if arcpy.Exists(extract_mask_raster):
                                        arcpy.Delete_management(
                                            extract_mask_raster)

                                extract_temp_raster = arcpy.sa.ExtractByMask(
                                    input_raster, polygons_inward)
                                extract_temp_raster.save(extract_mask_raster)

                                # 4. convert the output to points
                                if use_in_memory:
                                    extract_mask_points = "in_memory/extract_points"
                                else:
                                    extract_mask_points = os.path.join(
                                        scratch_ws, "extract_points")
                                    if arcpy.Exists(extract_mask_points):
                                        arcpy.Delete_management(
                                            extract_mask_points)

                                arcpy.RasterToPoint_conversion(
                                    extract_mask_raster, extract_mask_points,
                                    "VALUE")

                                msg_body = create_msg_body(
                                    "Create flood points...", 0, 0)
                                msg(msg_body)

                                # 5. Interpolate: this will also interpolate outside the flood boundary which is
                                # what we need so we get a nice 3D poly that extends into the surrounding DEM
                                if use_in_memory:
                                    interpolated_raster = "in_memory/interpolate_raster"
                                else:
                                    interpolated_raster = os.path.join(
                                        scratch_ws, "interpolate_raster")
                                    if arcpy.Exists(interpolated_raster):
                                        arcpy.Delete_management(
                                            interpolated_raster)

                                zField = "grid_code"
                                power = 2
                                searchRadius = arcpy.sa.RadiusVariable(
                                    12, 150000)

                                msg_body = create_msg_body(
                                    "Interpolating flood points...", 0, 0)
                                msg(msg_body)

                                # Execute IDW
                                out_IDW = arcpy.sa.Idw(extract_mask_points,
                                                       zField, cell_size,
                                                       power)

                                # Save the output
                                out_IDW.save(interpolated_raster)

                                extent_poly = common_lib.get_extent_feature(
                                    scratch_ws, polygons_inward)

                                msg_body = create_msg_body(
                                    "Clipping terrain...", 0, 0)
                                msg(msg_body)

                                # clip the input surface
                                if use_in_memory:
                                    extent_clip_idwraster = "in_memory/extent_clip_idw"
                                else:
                                    extent_clip_idwraster = os.path.join(
                                        scratch_ws, "extent_clip_idw")
                                    if arcpy.Exists(extent_clip_idwraster):
                                        arcpy.Delete_management(
                                            extent_clip_idwraster)

                                # clip terrain to extent
                                arcpy.Clip_management(interpolated_raster, "#",
                                                      extent_clip_idwraster,
                                                      extent_poly)

                                # 6. clip the interpolated raster by (outward buffered) outline polygon
                                if use_in_memory:
                                    polygons_outward = "in_memory/outward_buffer"
                                else:
                                    polygons_outward = os.path.join(
                                        scratch_ws, "outward_buffer")
                                    if arcpy.Exists(polygons_outward):
                                        arcpy.Delete_management(
                                            polygons_outward)

                                outward_buffer += 0.5 * int(
                                    x
                                )  # we buffer out by half the raster cellsize

                                if outward_buffer > 0:
                                    if xy_unit == "Feet":
                                        buffer_text = str(
                                            outward_buffer) + " Feet"
                                    else:
                                        buffer_text = str(
                                            outward_buffer) + " Meters"

                                    sideType = "FULL"
                                    arcpy.Buffer_analysis(
                                        raster_polygons, polygons_outward,
                                        buffer_text, sideType)

                                    raster_polygons = polygons_outward

                                # clip the input surface
                                if use_in_memory:
                                    flood_clip_raster = "in_memory/flood_clip_raster"
                                else:
                                    flood_clip_raster = os.path.join(
                                        scratch_ws, "flood_clip_raster")
                                    if arcpy.Exists(flood_clip_raster):
                                        arcpy.Delete_management(
                                            flood_clip_raster)

                                msg_body = create_msg_body(
                                    "Clipping flood raster...", 0, 0)
                                msg(msg_body)

                                # clip terrain to extent
                                #                            arcpy.Clip_management(interpolated_raster, "#", flood_clip_raster, raster_polygons)    Check again
                                arcpy.Clip_management(interpolated_raster, "#",
                                                      flood_clip_raster,
                                                      raster_polygons)

                                # 7. Isnull, and Con to grab values from flood_clip_raster for
                                # create NUll mask
                                if use_in_memory:
                                    is_Null = "in_memory/is_Null"
                                else:
                                    is_Null = os.path.join(
                                        scratch_ws, "is_Null")
                                    if arcpy.Exists(is_Null):
                                        arcpy.Delete_management(is_Null)

                                is_Null_raster = arcpy.sa.IsNull(input_raster)
                                is_Null_raster.save(is_Null)

                                # Con
                                if use_in_memory:
                                    con_raster = "in_memory/con_raster"
                                else:
                                    con_raster = os.path.join(
                                        scratch_ws, "con_raster")
                                    if arcpy.Exists(con_raster):
                                        arcpy.Delete_management(con_raster)
                                temp_con_raster = arcpy.sa.Con(
                                    is_Null, interpolated_raster, input_raster)
                                temp_con_raster.save(con_raster)

                                msg_body = create_msg_body(
                                    "Merging rasters...", 0, 0)
                                msg(msg_body)

                                # 8. focal stats on raster to smooth?

                                # 9. copy raster to geotiff
                                if use_in_memory:
                                    con_raster_tif = "in_memory/con_raster_tif"
                                else:
                                    con_raster_tif = os.path.join(
                                        tiff_directory, "con_raster.tif")
                                    if arcpy.Exists(con_raster_tif):
                                        arcpy.Delete_management(con_raster_tif)

                                arcpy.CopyRaster_management(
                                    con_raster, con_raster_tif, "#", "#", "#",
                                    "#", "#", "32_BIT_FLOAT")

                                msg_body = create_msg_body(
                                    "Copying to tiff...", 0, 0)
                                msg(msg_body)

                                # 10. raster to TIN
                                zTol = 0.1
                                maxPts = 1500000
                                zFactor = 1
                                con_tin = os.path.join(tin_directory,
                                                       "con_tin")
                                if arcpy.Exists(con_tin):
                                    arcpy.Delete_management(con_tin)

                                # Execute RasterTin
                                arcpy.RasterTin_3d(con_raster_tif, con_tin,
                                                   zTol, maxPts, zFactor)

                                msg_body = create_msg_body(
                                    "Creating TIN...", 0, 0)
                                msg(msg_body)

                                # 11. TIN triangles
                                if use_in_memory:
                                    con_triangles = "in_memory/con_triangles"
                                else:
                                    con_triangles = os.path.join(
                                        scratch_ws, "con_triangles")
                                    if arcpy.Exists(con_triangles):
                                        arcpy.Delete_management(con_triangles)

                                arcpy.TinTriangle_3d(con_tin, con_triangles)

                                msg_body = create_msg_body(
                                    "Creating polygons...", 0, 0)
                                msg(msg_body)

                                # 12. make 2D polygons feature to feature class
                                arcpy.FeatureClassToFeatureClass_conversion(
                                    con_triangles, scratch_ws,
                                    "con_triangles_2D")

                                # 12. clip with smooth polygon
                                smooth_polygons = os.path.join(
                                    scratch_ws, "smooth_raster_polygons")
                                if arcpy.Exists(smooth_polygons):
                                    arcpy.Delete_management(smooth_polygons)

                                msg_body = create_msg_body(
                                    "Smoothing edges...", 0, 0)
                                msg(msg_body)

                                CA.SmoothPolygon(os.path.join(raster_polygons),
                                                 smooth_polygons, "PAEK", x,
                                                 "", "FLAG_ERRORS")

                                if use_in_memory:
                                    clip_smooth_triangles = "in_memory/clip_smooth_triangles"
                                else:
                                    clip_smooth_triangles = os.path.join(
                                        scratch_ws, "clip_smooth_triangles")
                                    if arcpy.Exists(clip_smooth_triangles):
                                        arcpy.Delete_management(
                                            clip_smooth_triangles)

                                msg_body = create_msg_body(
                                    "Clipping smooth edges...", 0, 0)
                                msg(msg_body)

                                # clip terrain to extent
                                arcpy.Clip_analysis(con_triangles,
                                                    smooth_polygons,
                                                    clip_smooth_triangles)

                                # clip to slightly lesser extent because of InterpolateShape fail.
                                area_extent = common_lib.get_extent_feature(
                                    scratch_ws, clip_smooth_triangles)

                                if use_in_memory:
                                    extent_inward = "in_memory/inward_extent_buffer"
                                else:
                                    extent_inward = os.path.join(
                                        scratch_ws, "inward_extent_buffer")
                                    if arcpy.Exists(extent_inward):
                                        arcpy.Delete_management(extent_inward)

                                buffer_in = 3

                                if xy_unit == "Feet":
                                    buffer_text = "-" + str(
                                        buffer_in) + " Feet"
                                else:
                                    buffer_text = "-" + str(
                                        buffer_in) + " Meters"

                                sideType = "FULL"
                                arcpy.Buffer_analysis(area_extent,
                                                      extent_inward,
                                                      buffer_text, sideType)

                                if use_in_memory:
                                    clip2_smooth_triangles = "in_memory/clip2_smooth_triangles"
                                else:
                                    clip2_smooth_triangles = os.path.join(
                                        scratch_ws, "clip2_smooth_triangles")
                                    if arcpy.Exists(clip2_smooth_triangles):
                                        arcpy.Delete_management(
                                            clip2_smooth_triangles)

                                msg_body = create_msg_body(
                                    "Clipping smooth edges a second time...",
                                    0, 0)
                                msg(msg_body)

                                # clip terrain to extent
                                arcpy.Clip_analysis(clip_smooth_triangles,
                                                    extent_inward,
                                                    clip2_smooth_triangles)

                                # 13. interpolate on TIN
                                if use_in_memory:
                                    clip_smooth_triangles3D = "in_memory/clip_smooth_traingles3D"
                                else:
                                    clip_smooth_triangles3D = os.path.join(
                                        scratch_ws, "clip_smooth_triangles3D")
                                    if arcpy.Exists(clip_smooth_triangles3D):
                                        arcpy.Delete_management(
                                            clip_smooth_triangles3D)

                                msg_body = create_msg_body(
                                    "Interpolating polygons on TIN", 0, 0)
                                msg(msg_body)
                                arcpy.InterpolateShape_3d(
                                    con_tin, clip2_smooth_triangles,
                                    clip_smooth_triangles3D, "#", 1, "LINEAR",
                                    "VERTICES_ONLY")

                                # 13. to multipatch
                                z_unit = common_lib.get_z_unit(
                                    clip_smooth_triangles3D, verbose)

                                # temp layer
                                flood_level_layer = "flood_level_layer"
                                arcpy.MakeFeatureLayer_management(
                                    clip_smooth_triangles3D, flood_level_layer)

                                # flood_level_mp = os.path.join(project_ws, common_lib.get_name_from_feature_class(input_raster) + "_3D")
                                flood_level_mp = output_polygons + "_3D"

                                if arcpy.Exists(flood_level_mp):
                                    arcpy.Delete_management(flood_level_mp)

                                arcpy.Layer3DToFeatureClass_3d(
                                    flood_level_layer, flood_level_mp)

                                # layer to be added to TOC
                                flood_level_layer_mp = common_lib.get_name_from_feature_class(
                                    flood_level_mp)
                                arcpy.MakeFeatureLayer_management(
                                    flood_level_mp, flood_level_layer_mp)

                                # apply transparency here // checking if symbology layer is present
                                if z_unit == "Feet":
                                    floodSymbologyLayer = layer_directory + "\\flood3Dfeet.lyrx"
                                else:
                                    floodSymbologyLayer = layer_directory + "\\flood3Dmeter.lyrx"

                                if not arcpy.Exists(floodSymbologyLayer):
                                    arcpy.AddWarning(
                                        "Can't find: " + floodSymbologyLayer +
                                        ". Symbolize features by error attribute to see data errors."
                                    )

                                arcpy.AddMessage("Results written to: " +
                                                 output_polygons)

                                if use_in_memory:
                                    arcpy.Delete_management("in_memory")

                                if DeleteIntermediateData:
                                    fcs = common_lib.listFcsInGDB(scratch_ws)

                                    msg_prefix = "Deleting intermediate data..."

                                    msg_body = common_lib.create_msg_body(
                                        msg_prefix, 0, 0)
                                    common_lib.msg(msg_body)

                                    for fc in fcs:
                                        arcpy.Delete_management(fc)

                                return flood_level_layer_mp

                            # 14. adjust 3D Z feet to meters???
                        else:
                            raise NoUnits
                    else:
                        raise NoNoDataError

                    end_time = time.clock()
                    msg_body = create_msg_body(
                        "Create 3D Flood Leveles completed successfully.",
                        start_time, end_time)
                else:
                    raise NotProjected
            else:
                raise LicenseErrorSpatial
        else:
            raise LicenseError3D

        arcpy.ClearWorkspaceCache_management()

        msg(msg_body)

    except NotProjected:
        print(
            "Input data needs to be in a projected coordinate system. Exiting..."
        )
        arcpy.AddError(
            "Input data needs to be in a projected coordinate system. Exiting..."
        )

    except NoLayerFile:
        print("Can't find Layer file. Exiting...")
        arcpy.AddError("Can't find Layer file. Exiting...")

    except LicenseError3D:
        print("3D Analyst license is unavailable")
        arcpy.AddError("3D Analyst license is unavailable")

    except LicenseErrorSpatial:
        print("Spatial Analyst license is unavailable")
        arcpy.AddError("Spatial Analyst license is unavailable")

    except NoNoDataError:
        print("Input raster does not have NODATA values")
        arcpy.AddError("Input raster does not have NODATA values")

    except NoUnits:
        print("No units detected on input data")
        arcpy.AddError("No units detected on input data")

    except NoPolygons:
        print("Input data can only be polygon features or raster datasets.")
        arcpy.AddError(
            "Input data can only be polygon features or raster datasets.")

    except ValueError:
        print("Input no flood value is not a number.")
        arcpy.AddError("Input no flood value is not a number.")

    except arcpy.ExecuteError:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("With error message:  %s" % synerror, ERROR)
        msg("ArcPy Error Message:  %s" % arcpy.GetMessages(2), ERROR)

    except FunctionError as f_e:
        messages = f_e.args[0]
        msg("Error in function:  %s" % messages["function"], ERROR)
        msg("Error on %s" % messages["line"], ERROR)
        msg("Error in file name:  %s" % messages["filename"], ERROR)
        msg("With error message:  %s" % messages["synerror"], ERROR)
        msg("ArcPy Error Message:  %s" % messages["arc"], ERROR)

    except:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("with error message:  %s" % synerror, ERROR)

    finally:
        arcpy.CheckInExtension("3D")
        arcpy.CheckInExtension("Spatial")
Esempio n. 17
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 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]))
Esempio n. 19
0
def convert(input_source, flood_elevation_attribute,
            esri_flood_elevation_attribute, default_flood_elevation_value,
            output_raster, cell_size, debug):
    try:
        # Get Attributes from User
        if debug == 0:
            # script variables
            aprx = arcpy.mp.ArcGISProject("CURRENT")
            home_directory = aprx.homeFolder
            tiff_directory = home_directory + "\\Tiffs"
            tin_directory = home_directory + "\\Tins"
            scripts_directory = aprx.homeFolder + "\\Scripts"
            rule_directory = aprx.homeFolder + "\\rule_packages"
            log_directory = aprx.homeFolder + "\\Logs"
            layer_directory = home_directory + "\\layer_files"
            project_ws = aprx.defaultGeodatabase

            enableLogging = True
            DeleteIntermediateData = True
            verbose = 0
            in_memory_switch = True
        else:
            # debug
            input_source = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact\Baltimore.gdb\test_area1_slr6ft_pol'
            flood_elevation_attribute = "my_elev"
            esri_flood_elevation_attribute = "flood_elevation"
            default_flood_elevation_value = 6
            output_raster = r'D:\\Gert\\Work\\Esri\\Solutions\\3DFloodImpact\\work2.1\\3DFloodImpact\\Testing.gdb\\PolygonRaster'
            cell_size = 10
            home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.1\3DFloodImpact'
            tiff_directory = home_directory + "\\Tiffs"
            tin_directory = home_directory + "\\Tins"
            scripts_directory = home_directory + "\\Scripts"
            rule_directory = home_directory + "\\rule_packages"
            log_directory = home_directory + "\\Logs"
            layer_directory = home_directory + "\\layer_files"
            project_ws = home_directory + "\\Results.gdb"

            enableLogging = False
            DeleteIntermediateData = True
            verbose = 1
            in_memory_switch = False

        return_code = 0
        scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb")
        arcpy.env.workspace = scratch_ws
        arcpy.env.overwriteOutput = True

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

        if cell_size:
            cell_size = float(re.sub("[,.]", ".", cell_size))
        else:
            cell_size = 1

        if not os.path.exists(tiff_directory):
            os.makedirs(tiff_directory)

        if not os.path.exists(tin_directory):
            os.makedirs(tin_directory)

        common_lib.set_up_logging(log_directory, TOOLNAME)
        start_time = time.clock()

        if arcpy.CheckExtension("3D") == "Available":
            arcpy.CheckOutExtension("3D")

            if arcpy.CheckExtension("Spatial") == "Available":
                arcpy.CheckOutExtension("Spatial")

                arcpy.AddMessage(
                    "Processing input source: " +
                    common_lib.get_name_from_feature_class(input_source))

                common_lib.delete_add_field(input_source,
                                            esri_flood_elevation_attribute,
                                            "DOUBLE")

                # check attribute
                if flood_elevation_attribute:
                    if common_lib.check_fields(input_source,
                                               [flood_elevation_attribute],
                                               False, verbose) == 0:
                        arcpy.CalculateField_management(
                            input_source, esri_flood_elevation_attribute,
                            "!" + flood_elevation_attribute + "!",
                            "PYTHON_9.3")
                        common_lib.set_null_or_negative_to_value_in_fields(
                            input_source, [esri_flood_elevation_attribute],
                            [default_flood_elevation_value], True, verbose)
                        return_code = 1
                    else:  # create a default attribute
                        arcpy.CalculateField_management(
                            input_source, esri_flood_elevation_attribute,
                            default_flood_elevation_value, "PYTHON_9.3")
                        return_code = 1
                else:
                    arcpy.CalculateField_management(
                        input_source, esri_flood_elevation_attribute,
                        default_flood_elevation_value, "PYTHON_9.3")
                    return_code = 1

                # convert here
                assignmentType = "CELL_CENTER"
                priorityField = "#"

                # Execute PolygonToRaster
                arcpy.PolygonToRaster_conversion(
                    input_source, esri_flood_elevation_attribute,
                    output_raster, assignmentType, priorityField, cell_size)

                return output_raster

                end_time = time.clock()
                msg_body = create_msg_body(
                    "set Flood Elevation Value For Polygon completed successfully.",
                    start_time, end_time)
            else:
                raise LicenseErrorSpatial
        else:
            raise LicenseError3D

        arcpy.ClearWorkspaceCache_management()

        msg(msg_body)

    except NotProjected:
        print(
            "Input data needs to be in a projected coordinate system. Exiting..."
        )
        arcpy.AddError(
            "Input data needs to be in a projected coordinate system. Exiting..."
        )

    except NoLayerFile:
        print("Can't find Layer file. Exiting...")
        arcpy.AddError("Can't find Layer file. Exiting...")

    except LicenseError3D:
        print("3D Analyst license is unavailable")
        arcpy.AddError("3D Analyst license is unavailable")

    except LicenseErrorSpatial:
        print("Spatial Analyst license is unavailable")
        arcpy.AddError("Spatial Analyst license is unavailable")

    except NoNoDataError:
        print("Input raster does not have NODATA values")
        arcpy.AddError("Input raster does not have NODATA values")

    except NoUnits:
        print("No units detected on input data")
        arcpy.AddError("No units detected on input data")

    except NoPolygons:
        print("Input data can only be polygon features or raster datasets.")
        arcpy.AddError(
            "Input data can only be polygon features or raster datasets.")

    except ValueError:
        print("Input no flood value is not a number.")
        arcpy.AddError("Input no flood value is not a number.")

    except arcpy.ExecuteError:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("With error message:  %s" % synerror, ERROR)
        msg("ArcPy Error Message:  %s" % arcpy.GetMessages(2), ERROR)

    except FunctionError as f_e:
        messages = f_e.args[0]
        msg("Error in function:  %s" % messages["function"], ERROR)
        msg("Error on %s" % messages["line"], ERROR)
        msg("Error in file name:  %s" % messages["filename"], ERROR)
        msg("With error message:  %s" % messages["synerror"], ERROR)
        msg("ArcPy Error Message:  %s" % messages["arc"], ERROR)

    except:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("with error message:  %s" % synerror, ERROR)

    finally:
        arcpy.CheckInExtension("3D")
        arcpy.CheckInExtension("Spatial")
def add_minimum_height_above_HAND(lc_ws, lc_input_features, lc_input_surface,
                                  lc_had_field, lc_memory_switch):
    try:
        if arcpy.Exists(lc_input_features):
            if arcpy.Exists(lc_input_surface):

                # find minimum HAND value for each input features
                heightsTable = os.path.join(lc_ws, "heightsTable")

                if arcpy.Exists(heightsTable):
                    arcpy.Delete_management(heightsTable)

                stat_type = "MINIMUM"

                arcpy.AddMessage(
                    "Calculating minimum HAND height for " +
                    common_lib.get_name_from_feature_class(lc_input_features) +
                    ".")
                arcpy.sa.ZonalStatisticsAsTable(lc_input_features,
                                                esri_featureID,
                                                lc_input_surface, heightsTable,
                                                "DATA", stat_type)

                common_lib.delete_fields(lc_input_features, [min_field])
                arcpy.JoinField_management(lc_input_features, esri_featureID,
                                           heightsTable, esri_featureID,
                                           min_field)

                # add minimum HAND height to height_dem which was previously calculated
                hand_field = "HAND"
                common_lib.add_field(lc_input_features, hand_field, "DOUBLE",
                                     5)

                expression = "round(float(!" + lc_had_field + "! + !" + min_field + "!), 2)"

                arcpy.CalculateField_management(lc_input_features, hand_field,
                                                expression, "PYTHON3", None)

                common_lib.delete_fields(lc_input_features,
                                         [lc_had_field, min_field])

                # alternative way ->

                # bridge surface to points

                # bridge polygons to raster

                # add Z values

                # find point with minimum Z value

                # get HAND value point

                # get DEM value for point

                # subtract DEM value from minimum Z -> Height above DEM

                # add this value to HAND for location

            else:
                msg_body = create_msg_body(
                    "Couldn't find input surface: " + str(lc_input_surface), 0,
                    0)
                msg(msg_body, WARNING)
        else:
            msg_body = create_msg_body(
                "Couldn't find input feature class: " + str(lc_input_features),
                0, 0)
            msg(msg_body, WARNING)

        return None

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def add_minimum_height_above_water_surface(lc_ws, lc_input_features,
                                           lc_bridge_raster, lc_input_surface,
                                           lc_memory_switch):

    try:
        if arcpy.Exists(lc_input_features):
            # subtract input surface from bridge raster to obtain heights above surface
            if lc_memory_switch:
                minus_raster = "in_memory/minus_3D"
            else:
                minus_raster = os.path.join(lc_ws, "minus_3D")
                if arcpy.Exists(minus_raster):
                    arcpy.Delete_management(minus_raster)

            # actual subtract
            msg_body = create_msg_body(
                "Finding minimum distance between surfaces for each input feature...",
                0, 0)
            msg(msg_body)
            arcpy.Minus_3d(lc_bridge_raster, lc_input_surface, minus_raster)

            # zonal stats to find minimum height above surface
            heights_table = os.path.join(lc_ws, "heightsTable")

            if arcpy.Exists(heights_table):
                arcpy.Delete_management(heights_table)

            stat_type = "MINIMUM"

            arcpy.AddMessage(
                "Calculating Height Statistics Information for " +
                common_lib.get_name_from_feature_class(lc_input_features) +
                ".")
            arcpy.sa.ZonalStatisticsAsTable(lc_input_features, esri_featureID,
                                            minus_raster, heights_table,
                                            "DATA", stat_type)

            # join back to bridge object
            common_lib.delete_fields(lc_input_features, [min_field])
            arcpy.JoinField_management(lc_input_features, esri_featureID,
                                       heights_table, esri_featureID,
                                       min_field)

            # add Z information
            arcpy.AddZInformation_3d(lc_input_features, zmin_field, None)

            # calculate height above surface
            common_lib.add_field(lc_input_features, has_field, "DOUBLE", 5)

            expression = "round(float(!" + min_field + "!), 2)"

            arcpy.CalculateField_management(lc_input_features, has_field,
                                            expression, "PYTHON3", None)
        else:
            msg_body = create_msg_body(
                "Couldn't find input feature class: " + str(lc_input_features),
                0, 0)
            msg(msg_body, WARNING)

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def main():
    try:
        # Get Attributes from User
        if debugging == 0:
            ## User input
            input_source = arcpy.GetParameter(0)
            depth_raster = arcpy.GetParameterAsText(1)
            depth_value = arcpy.GetParameterAsText(2)
            boundary_size = arcpy.GetParameterAsText(3)
            boundary_offset = arcpy.GetParameterAsText(4)
            output_raster = arcpy.GetParameterAsText(5)

            # script variables
            aprx = arcpy.mp.ArcGISProject("CURRENT")
            home_directory = aprx.homeFolder
            layer_directory = home_directory + "\\layer_files"
            rule_directory = aprx.homeFolder + "\\rule_packages"
            log_directory = aprx.homeFolder + "\\Logs"
            project_ws = aprx.defaultGeodatabase

        else:
            # debug
            input_source = r'D:\Temporary\Flood\3DFloodImpact\3DFloodImpact.gdb\slr_3ft_ProjectRaster'
            depth_raster = r'D:\Temporary\Flood\3DFloodImpact\3DFloodImpact.gdb\MD_LWX_slr_depth_3ft_Project'
            depth_value = 0
            boundary_size = 1
            boundary_offset = 0.2
            output_raster = r'D:\Temporary\Flood\3DFloodImpact\3DFloodImpact.gdb\DepthElevationRaster_debug'

            home_directory = r'D:\Temporary\Flood\3DFloodImpact'
            layer_directory = home_directory + "\\layer_files"
            rule_directory = home_directory + "\\rule_packages"
            log_directory = home_directory + "\\Logs"
            project_ws = home_directory + "\\3DFloodImpact.gdb"

        scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb")
        arcpy.env.workspace = scratch_ws
        arcpy.env.overwriteOutput = True

        start_time = time.clock()

        # check if input exists
        if arcpy.Exists(input_source):
            full_path_source = common_lib.get_full_path_from_layer(input_source)
        else:
            raise NoRasterLayer

        desc = arcpy.Describe(input_source)

        depth_elevation_raster = create_depth_raster.create_raster(input_source=full_path_source,
                                    depth_raster=depth_raster,
                                    depth_value=depth_value,
                                    boundary_size=boundary_size,
                                    boundary_offset=boundary_offset,
                                    output_raster=output_raster, debug=debugging)

        if depth_elevation_raster:
            if arcpy.Exists(depth_elevation_raster):
                end_time = time.clock()
                msg_body = create_msg_body("create_depth_raster_tbx completed successfully.", start_time, end_time)
                msg(msg_body)
            else:
                end_time = time.clock()
                msg_body = create_msg_body("No output raster layer. Exiting...", start_time, end_time)
                msg(msg_body, WARNING)
        else:
            end_time = time.clock()
            msg_body = create_msg_body("No output raster layer. Exiting...", start_time, end_time)
            msg(msg_body, WARNING)

        arcpy.ClearWorkspaceCache_management()

        # end main code

    except LicenseError3D:
        print("3D Analyst license is unavailable")
        arcpy.AddError("3D Analyst license is unavailable")

    except NoRasterLayer:
        print("No output Raster layer. Exiting...")
        arcpy.AddError("No output raster layer. Exiting...")

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

    except arcpy.ExecuteError:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("With error message:  %s" % synerror, ERROR)
        msg("ArcPy Error Message:  %s" % arcpy.GetMessages(2), ERROR)

    except FunctionError as f_e:
        messages = f_e.args[0]
        msg("Error in function:  %s" % messages["function"], ERROR)
        msg("Error on %s" % messages["line"], ERROR)
        msg("Error in file name:  %s" % messages["filename"], ERROR)
        msg("With error message:  %s" % messages["synerror"], ERROR)
        msg("ArcPy Error Message:  %s" % messages["arc"], ERROR)

    except:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("with error message:  %s" % synerror, ERROR)

    finally:
        arcpy.CheckInExtension("3D")
Esempio n. 23
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")
Esempio n. 24
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")
Esempio n. 25
0
def adjustSpans(lc_scratch_ws, lc_catenary, lc_guide_lines, lc_adjust_all, lc_debug, lc_use_in_memory):
    try:
        # First, find the from and to points, and line number for this guide line.
        fieldList = ["FromTower", "ToTower", "LineNumber", "FromX", "FromY", "FromZ", "ToX", "ToY", "ToZ", "SagDistance", "WeightPerUnitLength"]
        fieldAccess = utils.FieldAccess(fieldList)

        # lc_guide_lines can be a layer. There is only 1 feature (selected)
        cursor = arcpy.da.SearchCursor(lc_guide_lines, fieldList)
        # Process selected guidelines.
        # XX Pretend for now that only one guideline is selected.
        index = 0
        for row in cursor:
            # only one guideline is selected.
            if index == 0:
                fieldAccess.setRow(row)
                lineNumber = fieldAccess.getValue("LineNumber")
                fromTower = fieldAccess.getValue("FromTower")
                toTower = fieldAccess.getValue("ToTower")
                fromX = fieldAccess.getValue("FromX")
                fromY = fieldAccess.getValue("FromY")
                fromZ = fieldAccess.getValue("FromZ")
                toX = fieldAccess.getValue("ToX")
                toY = fieldAccess.getValue("ToY")
                toZ = fieldAccess.getValue("ToZ")
                sagDistance = fieldAccess.getValue("SagDistance")
                weightPerUnitLength = fieldAccess.getValue("WeightPerUnitLength")
                fromPointXYZ = vg.Point(fromX, fromY, fromZ)
                toPointXYZ = vg.Point(toX, toY, toZ)
                # Change to attachment point objects.
                fromPoint = create_3D_catenary.AttachmentPoint(fromPointXYZ, lineNumber, fromTower)
                toPoint = create_3D_catenary.AttachmentPoint(toPointXYZ, lineNumber, toTower)

                p("Initial sagDistance on feature:", sagDistance)

                # sag distance is None because we need to calculate it from the lineGuide
                # horizontal tension is not supplied.
                adjustedSpan = create_3D_catenary.makeSpan(fromPoint, toPoint, lc_guide_lines, weightPerUnitLength, None, None, None)
                newSpanDistance = adjustedSpan.sagDistance
                p("new sagDistance on feature:", newSpanDistance)

        if cursor:
            del cursor

        if lc_adjust_all:
            # We have already created the span with a sag distance.
            # For simplicity, we'll throw out that span object and make all six using that sag.
            adjustedSpans = []
            fieldList = ["FromTower", "ToTower", "LineNumber", "FromX", "FromY", "FromZ", "ToX", "ToY", "ToZ"]
            fieldAccess = utils.FieldAccess(fieldList)
            whereClause = "FromTower = " + str(fromTower) + " and ToTower = " + str(toTower)

            p("sagDistance for all lines", newSpanDistance)

            # search in full feature class, not just selection
            i = 0
            cursor = arcpy.da.SearchCursor(common_lib.get_full_path_from_layer(lc_guide_lines), fieldList, whereClause)
            for row in cursor:
                fieldAccess.setRow(row)
                lineNumber = fieldAccess.getValue("LineNumber")
                fromTower = fieldAccess.getValue("FromTower")
                toTower = fieldAccess.getValue("ToTower")
                fromX = fieldAccess.getValue("FromX")
                fromY = fieldAccess.getValue("FromY")
                fromZ = fieldAccess.getValue("FromZ")
                toX = fieldAccess.getValue("ToX")
                toY = fieldAccess.getValue("ToY")
                toZ = fieldAccess.getValue("ToZ")
                fromPointXYZ = vg.Point(fromX, fromY, fromZ)
                toPointXYZ = vg.Point(toX, toY, toZ)
                # Change to attachment point objects.
                fromPoint = create_3D_catenary.AttachmentPoint(fromPointXYZ, lineNumber, fromTower)
                toPoint = create_3D_catenary.AttachmentPoint(toPointXYZ, lineNumber, toTower)

                p("newSpanDistance in loop", newSpanDistance)
                adjustedSpan = create_3D_catenary.makeSpan(fromPoint, toPoint, common_lib.get_full_path_from_layer(lc_guide_lines), weightPerUnitLength, newSpanDistance, None)
                adjustedSpans.append(adjustedSpan)

                i+=1
                # arcpy.AddMessage(str(i))

            doSpanRemoveAndInsert(lc_catenary, common_lib.get_full_path_from_layer(lc_guide_lines), adjustedSpans)
        else:
            doSpanRemoveAndInsert(lc_catenary, common_lib.get_full_path_from_layer(lc_guide_lines), [adjustedSpan])

        if lc_use_in_memory:
            arcpy.Delete_management("in_memory")

        if lc_debug == 0:
            fcs = common_lib.listFcsInGDB(lc_scratch_ws)

            msg_prefix = "Deleting intermediate data..."

            msg_body = common_lib.create_msg_body(msg_prefix, 0, 0)
            common_lib.msg(msg_body)

            for fc in fcs:
                arcpy.Delete_management(fc)

        arcpy.ClearWorkspaceCache_management()

        return lc_catenary, common_lib.get_full_path_from_layer(lc_guide_lines)

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
    pass
def extract(lc_lasd, lc_ws, lc_class_code, lc_cell_size, lc_min_bridge_area,
            lc_extrapolate, lc_output_features, lc_log_dir, lc_debug,
            lc_memory_switch):

    try:
        # create dem
        desc = arcpy.Describe(lc_lasd)
        if desc.spatialReference.linearUnitName in ['Foot_US', 'Foot']:
            unit = 'Feet'
        else:
            unit = 'Meters'

        ground_code = 2
        # get class codes
        class_code_string = desc.classCodes

        # get point spacing
        point_spacing = desc.pointSpacing

        # get lidar class code
        msg_body = create_msg_body(
            "Looking for class code: " + str(lc_class_code), 0, 0)
        msg(msg_body)

        class_code_list = class_code_string.split(";")

        # old way
        # class_code_list = common_lib.get_las_class_codes(lc_lasd, lc_log_dir)

        # Generate raster from lasd
        if str(lc_class_code) in class_code_list:

            if arcpy.Exists(lc_output_features):
                arcpy.Delete_management(lc_output_features)

            msg_body = create_msg_body(
                "Creating bridge surfaces using the following class codes: " +
                str(lc_class_code), 0, 0)
            msg(msg_body)

            bridge_ld_layer = arcpy.CreateUniqueName('bridge_ld_lyr')

            # Filter for bridge points
            arcpy.MakeLasDatasetLayer_management(lc_lasd,
                                                 bridge_ld_layer,
                                                 class_code=str(lc_class_code))

            # create dsm from las with just bridge codes
            if lc_memory_switch:
                dsm = "in_memory/dsm"
            else:
                dsm = os.path.join(lc_ws, "dsm")
                if arcpy.Exists(dsm):
                    arcpy.Delete_management(dsm)

            if arcpy.Exists(dsm):
                arcpy.Delete_management(dsm)

            arcpy.conversion.LasDatasetToRaster(bridge_ld_layer,
                                                dsm,
                                                'ELEVATION',
                                                'BINNING MAXIMUM LINEAR',
                                                sampling_type='CELLSIZE',
                                                sampling_value=lc_cell_size)

            arcpy.ResetEnvironments()
            arcpy.env.workspace = lc_ws
            arcpy.env.overwriteOutput = True

            # extrapolate dsm for better interpolation
            if lc_extrapolate:
                dsm_outer = extrapolate_raster(lc_ws, dsm, lc_cell_size,
                                               lc_log_dir, lc_debug,
                                               lc_memory_switch)

                # merge rasters
                listRasters = []
                listRasters.append(dsm)
                listRasters.append(dsm_outer)
                outer_dsm_name = "dms_plus_outer"

                desc = arcpy.Describe(listRasters[0])
                arcpy.MosaicToNewRaster_management(listRasters, lc_ws,
                                                   outer_dsm_name,
                                                   desc.spatialReference,
                                                   "32_BIT_FLOAT",
                                                   lc_cell_size, 1, "MEAN", "")

                dsm = os.path.join(lc_ws, outer_dsm_name)

            # create raster using LASPointStatisticsAsRaster
            if lc_memory_switch:
                las_point_stats = "in_memory/las_point_stats"
            else:
                las_point_stats = os.path.join(lc_ws, "las_point_stats")
                if arcpy.Exists(las_point_stats):
                    arcpy.Delete_management(las_point_stats)

            if arcpy.Exists(las_point_stats):
                arcpy.Delete_management(las_point_stats)

            msg_body = create_msg_body(
                "Creating points statistics raster using the following class codes: "
                + str(lc_class_code), 0, 0)
            msg(msg_body)

            arcpy.management.LasPointStatsAsRaster(bridge_ld_layer,
                                                   las_point_stats,
                                                   "PREDOMINANT_CLASS",
                                                   "CELLSIZE",
                                                   2 * lc_cell_size)

            lc_memory_switch = False

            # convert to polygon
            if lc_memory_switch:
                bridge_polys = "in_memory/bridge_polys"
            else:
                bridge_polys = os.path.join(lc_ws, "bridge_polys")
                if arcpy.Exists(bridge_polys):
                    arcpy.Delete_management(bridge_polys)

            msg_body = create_msg_body("Creating polygons from raster", 0, 0)
            msg(msg_body)

            arcpy.conversion.RasterToPolygon(las_point_stats, bridge_polys,
                                             "SIMPLIFY", "Value",
                                             "SINGLE_OUTER_PART", None)

            # eliminate holes
            if lc_memory_switch:
                bridge_polys2 = "memory/bridge_polys2"
            else:
                bridge_polys2 = os.path.join(lc_ws, "bridge_polys2")
                if arcpy.Exists(bridge_polys2):
                    arcpy.Delete_management(bridge_polys2)

            msg_body = create_msg_body("Eliminating holes from polygons", 0, 0)
            msg(msg_body)

            arcpy.management.EliminatePolygonPart(bridge_polys, bridge_polys2,
                                                  "AREA", "20 SquareMeters", 0,
                                                  "ANY")
            # regularize footprints
            if lc_memory_switch:
                bridge_polys3 = "memory/bridge_polys3"
            else:
                bridge_polys3 = os.path.join(lc_ws, "bridge_polys3")
                if arcpy.Exists(bridge_polys3):
                    arcpy.Delete_management(bridge_polys3)

            msg_body = create_msg_body("Regularizing polygons...", 0, 0)
            msg(msg_body)

            arcpy.ddd.RegularizeBuildingFootprint(bridge_polys2, bridge_polys3,
                                                  "ANY_ANGLE",
                                                  2 * lc_cell_size,
                                                  2 * lc_cell_size, 0.25, 1.5,
                                                  0.1, 1000000)

            # interpolate shape on the dsm
            if lc_memory_switch:
                bridge_polys5 = "memory/bridge_polys5"
            else:
                bridge_polys5 = os.path.join(lc_ws, "bridge_polys5")
                if arcpy.Exists(bridge_polys5):
                    arcpy.Delete_management(bridge_polys5)

            msg_body = create_msg_body("Interpolating polygons...", 0, 0)
            msg(msg_body)

            if not lc_extrapolate:
                if lc_memory_switch:
                    bridge_polys4 = "memory/bridge_polys4"
                else:
                    bridge_polys4 = os.path.join(lc_ws, "bridge_polys4")
                    if arcpy.Exists(bridge_polys4):
                        arcpy.Delete_management(bridge_polys4)

                if common_lib.get_xy_unit(bridge_polys3, 0) == "Feet":
                    buffer_text = "-" + str(lc_cell_size * 2) + " Feet"
                else:
                    buffer_text = "-" + str(lc_cell_size * 2) + " Meters"

                arcpy.analysis.Buffer(bridge_polys3, bridge_polys4,
                                      buffer_text, "FULL", "ROUND", "NONE",
                                      None, "PLANAR")

                # densify buffer so the bridge surface will follow the dsm
                arcpy.edit.Densify(bridge_polys4, "DISTANCE", "10 Meters",
                                   "0.1 Meters", 10)

                arcpy.ddd.InterpolateShape(dsm, bridge_polys4, bridge_polys5,
                                           None, 1, "BILINEAR",
                                           "VERTICES_ONLY", 0, "EXCLUDE")
            else:
                # densify buffer so the bridge surface will follow the dsm
                arcpy.edit.Densify(bridge_polys3, "DISTANCE", "10 Meters",
                                   "0.1 Meters", 10)

                arcpy.ddd.InterpolateShape(dsm, bridge_polys3, bridge_polys5,
                                           None, 1, "BILINEAR",
                                           "VERTICES_ONLY", 0, "EXCLUDE")

            valueAttribute = "Shape_Area"
            expression = """{} > {}""".format(
                arcpy.AddFieldDelimiters(bridge_polys5, valueAttribute),
                lc_min_bridge_area)

            msg_body = create_msg_body(
                "Removing polygons with area smaller than " +
                str(lc_min_bridge_area) + ".", 0, 0)
            msg(msg_body)

            # select all points with good elevation values
            select_name = arcpy.CreateUniqueName('bridge_select_lyr')
            select_lyr = arcpy.MakeFeatureLayer_management(
                bridge_polys5, select_name).getOutput(0)
            arcpy.SelectLayerByAttribute_management(select_lyr,
                                                    "NEW_SELECTION",
                                                    expression)

            bridge_polys6 = lc_output_features + "_surfaces"

            if arcpy.Exists(bridge_polys6):
                arcpy.Delete_management(bridge_polys6)

            arcpy.CopyFeatures_management(select_lyr, bridge_polys6)

            return bridge_polys6
        else:
            msg_body = create_msg_body(
                "Couldn't detect class code " + str(lc_class_code) +
                " in las dataset. Exiting...", 0, 0)
            msg(msg_body, WARNING)

            return None

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
def main():
    try:
        # Get Attributes from User
        if debugging == 0:
            # User input
            input_las_dataset = arcpy.GetParameterAsText(0)
            class_code = arcpy.GetParameter(1)
            cell_size = arcpy.GetParameterAsText(2)
            minimum_bridge_area = arcpy.GetParameterAsText(3)
            extrapolate_surface = arcpy.GetParameter(4)
            output_features = arcpy.GetParameterAsText(5)

            # script variables
            aprx = arcpy.mp.ArcGISProject("CURRENT")
            home_directory = aprx.homeFolder
            project_ws = aprx.defaultGeodatabase
        else:
            input_las_dataset = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\testing.lasd'
            class_code = 13
            cell_size = str(0.5)
            minimum_bridge_area = str(20)
            extrapolate_surface = False
            output_features = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact\Testing.gdb\bridges'

            home_directory = r'D:\Gert\Work\Esri\Solutions\3DFloodImpact\work2.3\3DFloodImpact'
            project_ws = home_directory + "\\3DFloodImpact.gdb"

        if os.path.exists(home_directory + "\\p20"):  # it is a package
            home_directory = home_directory + "\\p20"

        arcpy.AddMessage("Project Home Directory is: " + home_directory)

        # set directories
        layer_directory = home_directory + "\\layer_files"
        log_directory = home_directory + "\\Logs"
        if not os.path.exists(log_directory):
            os.makedirs(log_directory)

        #  ensure numerical input is correct
        # fail safe for Europe's comma's
        cell_size = float(re.sub("[,.]", ".", cell_size))
        minimum_bridge_area = float(re.sub("[,.]", ".", minimum_bridge_area))

        # rename layer files (for packaging)
        if os.path.exists(layer_directory):
            common_lib.rename_file_extension(layer_directory, ".txt", ".lyrx")

        # Create folders and intermediate gdb, if needed
        scratch_ws = common_lib.create_gdb(home_directory, "Intermediate.gdb")
        arcpy.env.workspace = scratch_ws
        arcpy.env.overwriteOutput = True

        start_time = time.clock()

        # check if input exists
        if arcpy.Exists(input_las_dataset):

            # extract the elevation layers
            bridges = extract_bridges_from_las.extract(
                lc_lasd=input_las_dataset,
                lc_ws=scratch_ws,
                lc_class_code=class_code,
                lc_cell_size=float(cell_size),
                lc_min_bridge_area=float(minimum_bridge_area),
                lc_extrapolate=extrapolate_surface,
                lc_output_features=output_features,
                lc_log_dir=log_directory,
                lc_debug=verbose,
                lc_memory_switch=in_memory_switch)

            if bridges:
                if arcpy.Exists(bridges):
                    arcpy.AddMessage("Adding Bridges")

                    output_layer1 = common_lib.get_name_from_feature_class(
                        bridges)
                    arcpy.MakeFeatureLayer_management(bridges, output_layer1)

                    arcpy.SetParameter(6, output_layer1)

                    end_time = time.clock()
                    msg_body = create_msg_body(
                        "extract_bridges_from_las completed successfully.",
                        start_time, end_time)
                    msg(msg_body)
                else:
                    end_time = time.clock()
                    msg_body = create_msg_body(
                        "No bridge surfaces created. Exiting...", start_time,
                        end_time)
                    msg(msg_body, WARNING)
            else:
                end_time = time.clock()
                msg_body = create_msg_body(
                    "No bridge surfaces created. Exiting...", start_time,
                    end_time)
                msg(msg_body, WARNING)

            arcpy.ClearWorkspaceCache_management()

            if DeleteIntermediateData:
                fcs = common_lib.listFcsInGDB(scratch_ws)
                rs = common_lib.list_rasters_in_gdb(scratch_ws, verbose)

                msg_prefix = "Deleting intermediate data..."

                msg_body = common_lib.create_msg_body(msg_prefix, 0, 0)
                common_lib.msg(msg_body)

                for fc in fcs:
                    arcpy.Delete_management(fc)

                for r in rs:
                    arcpy.Delete_management(r)

            # end main code

    except LicenseError3D:
        print("3D Analyst license is unavailable")
        arcpy.AddError("3D Analyst license is unavailable")

    except NoPointLayer:
        print("Can't find attachment points layer. Exiting...")
        arcpy.AddError("Can't find attachment points layer. Exiting...")

    except NoCatenaryLayer:
        print("Can't find Catenary layer. Exiting...")
        arcpy.AddError("Can't find Catenary layer. Exiting...")

    except NoCatenaryOutput:
        print("Can't create Catenary output. Exiting...")
        arcpy.AddError("Can't create Catenary output. Exiting...")

    except NoSwaySurfaceOutput:
        print("Can't find SwaySurface output. Exiting...")
        arcpy.AddError("Can't find SwaySurface. Exiting...")

    except NoGuideLinesLayer:
        print("Can't find GuideLines output. Exiting...")
        arcpy.AddError("Can't find GuideLines. Exiting...")

    except MoreThan1Selected:
        print(
            "More than 1 line selected. Please select 1 guide line only. Exiting..."
        )
        arcpy.AddError(
            "More than 1 line selected. Please select 1 guide line only. Exiting..."
        )

    except NoGuideLinesOutput:
        print("Can't create GuideLines output. Exiting...")
        arcpy.AddError("Can't create GuideLines. Exiting...")

    except arcpy.ExecuteError:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("With error message:  %s" % synerror, ERROR)
        msg("ArcPy Error Message:  %s" % arcpy.GetMessages(2), ERROR)

    except FunctionError as f_e:
        messages = f_e.args[0]
        msg("Error in function:  %s" % messages["function"], ERROR)
        msg("Error on %s" % messages["line"], ERROR)
        msg("Error in file name:  %s" % messages["filename"], ERROR)
        msg("With error message:  %s" % messages["synerror"], ERROR)
        msg("ArcPy Error Message:  %s" % messages["arc"], ERROR)

    except:
        line, filename, synerror = trace()
        msg("Error on %s" % line, ERROR)
        msg("Error in file name:  %s" % filename, ERROR)
        msg("with error message:  %s" % synerror, ERROR)

    finally:
        arcpy.CheckInExtension("3D")
def extrapolate_raster(lc_ws, lc_dsm, lc_cell_size, lc_log_dir, lc_debug,
                       lc_memory_switch):

    try:
        if lc_memory_switch:
            raster_polygons = "memory/raster_polygons"
        else:
            raster_polygons = os.path.join(lc_ws, "raster_polygons")
            if arcpy.Exists(raster_polygons):
                arcpy.Delete_management(raster_polygons)

        out_geom = "POLYGON"  # output geometry type
        arcpy.RasterDomain_3d(lc_dsm, raster_polygons, out_geom)

        # 2. buffer it inwards so that we have a polygon only of the perimeter plus a few cells inward?.
        if lc_memory_switch:
            polygons_inward = "memory/inward_buffer"
        else:
            polygons_inward = os.path.join(lc_ws, "inward_buffer")
            if arcpy.Exists(polygons_inward):
                arcpy.Delete_management(polygons_inward)

        if lc_memory_switch:
            polygons_outward = "memory/outward_buffer"
        else:
            polygons_outward = os.path.join(lc_ws, "outward_buffer")
            if arcpy.Exists(polygons_outward):
                arcpy.Delete_management(polygons_outward)

        x = float(lc_cell_size)

        if x < 0.1:
            arcpy.AddError(
                "Raster cell size is 0. Can't continue. Please check the raster properties."
            )
            raise ValueError
            return None
        else:
            buffer_in = 6 * x

            xy_unit = common_lib.get_xy_unit(lc_dsm, 0)

            if xy_unit == "Feet":
                buffer_text = "-" + str(buffer_in) + " Feet"
            else:
                buffer_text = "-" + str(buffer_in) + " Meters"

            sideType = "OUTSIDE_ONLY"
            arcpy.Buffer_analysis(raster_polygons, polygons_inward,
                                  buffer_text, sideType)

            # create outside buffer for extent only.
            if xy_unit == "Feet":
                buffer_text = str(buffer_in) + " Feet"
            else:
                buffer_text = str(buffer_in) + " Meters"

            arcpy.Buffer_analysis(raster_polygons, polygons_outward,
                                  buffer_text, sideType)

            msg_body = create_msg_body("Buffering flood edges...", 0, 0)
            msg(msg_body)

            # 3. mask in ExtractByMask: gives just boundary raster with a few cells inwards
            if lc_memory_switch:
                extract_mask_raster = "in_memory/extract_mask"
            else:
                extract_mask_raster = os.path.join(lc_ws, "extract_mask")
                if arcpy.Exists(extract_mask_raster):
                    arcpy.Delete_management(extract_mask_raster)

            extract_temp_raster = arcpy.sa.ExtractByMask(
                lc_dsm, polygons_inward)
            extract_temp_raster.save(extract_mask_raster)

            # 4. convert the output to points
            if lc_memory_switch:
                extract_mask_points = "in_memory/extract_points"
            else:
                extract_mask_points = os.path.join(lc_ws, "extract_points")
                if arcpy.Exists(extract_mask_points):
                    arcpy.Delete_management(extract_mask_points)

            arcpy.RasterToPoint_conversion(extract_mask_raster,
                                           extract_mask_points, "VALUE")

            msg_body = create_msg_body("Create flood points...", 0, 0)
            msg(msg_body)

            # 5. Interpolate: this will also interpolate outside the bridge extent
            if lc_memory_switch:
                interpolated_raster = "in_memory/interpolate_raster"
            else:
                interpolated_raster = os.path.join(lc_ws, "interpolate_raster")
                if arcpy.Exists(interpolated_raster):
                    arcpy.Delete_management(interpolated_raster)

            zField = "grid_code"
            power = 2

            msg_body = create_msg_body("Interpolating bridge raster points...",
                                       0, 0)
            msg(msg_body)

            arcpy.env.extent = polygons_outward

            # Execute IDW
            out_IDW = arcpy.sa.Idw(extract_mask_points, zField, lc_cell_size,
                                   power)

            # Save the output
            out_IDW.save(interpolated_raster)

            arcpy.ResetEnvironments()
            arcpy.env.workspace = lc_ws
            arcpy.env.overwriteOutput = True

            # extract the outer rim only
            extract_mask_raster2 = os.path.join(lc_ws, "extract_mask2")
            if arcpy.Exists(extract_mask_raster2):
                arcpy.Delete_management(extract_mask_raster2)

            extract_temp_raster = arcpy.sa.ExtractByMask(
                interpolated_raster, polygons_outward)
            extract_temp_raster.save(extract_mask_raster2)

            return extract_mask_raster2

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
Esempio n. 29
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")
Esempio n. 30
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")