예제 #1
0
def createQARasterMosaics(isClassified, gdb_path, spatial_reference, target_folder, mxd, footprint_path=None, lasd_boundary_path=None):
    mosaics = []
    simple_footprint_path = None
    simple_lasd_boundary_path = None

    stats_methods = STATS_METHODS
    for method in stats_methods:
        arcpy.AddMessage("Creating {} MDS".format(method))
        for dataset_name in DATASET_NAMES:
            name = dataset_name

            if not isClassified:
                # Using a generic name for non-classified data
                name = ""


            md_name = method
            if len(name) > 0:
                md_name = "{}{}".format(method, name)

            input_folder = os.path.join(target_folder, method, name[1:])

            arcpy.AddMessage("Creating {} MD from {}".format(md_name, input_folder))
            try:
                if simple_footprint_path is None:
                    simple_footprint_path = "{}_Simple".format(footprint_path)
                    arcpy.SimplifyPolygon_cartography(in_features=footprint_path, out_feature_class=simple_footprint_path,
                                                    algorithm="POINT_REMOVE", tolerance=Raster.boundary_interval, minimum_area="0 SquareMeters",
                                                    error_option="RESOLVE_ERRORS", collapsed_point_option="NO_KEEP")
                    Utility.addToolMessages()
                    deleteFields(simple_footprint_path)
                    #try:
                    #    arcpy.DeleteField_management(in_table=simple_footprint_path, drop_field="Id;ORIG_FID;InPoly_FID;SimPgnFlag;MaxSimpTol;MinSimpTol")
                    #except:
                    #    pass

                if simple_lasd_boundary_path is None:
                    simple_lasd_boundary_path = "{}_Simple".format(lasd_boundary_path)
                    arcpy.SimplifyPolygon_cartography(in_features=lasd_boundary_path, out_feature_class=simple_lasd_boundary_path,
                                                    algorithm="POINT_REMOVE", tolerance=Raster.boundary_interval, minimum_area="0 SquareMeters",
                                                    error_option="RESOLVE_ERRORS", collapsed_point_option="NO_KEEP")
                    Utility.addToolMessages()
                    deleteFields(simple_lasd_boundary_path)
                    #try:
                    #    arcpy.DeleteField_management(in_table=simple_lasd_boundary_path, drop_field="Id;ORIG_FID;InPoly_FID;SimPgnFlag;MaxSimpTol;MinSimpTol")
                    #except:
                    #    pass
            except:
                arcpy.AddWarning("Failed to create simplified footprints and boundaries in '{}'".format(gdb_path))

            qa_md = createQARasterMosaicDataset(md_name, gdb_path, spatial_reference, input_folder, mxd, simple_footprint_path, simple_lasd_boundary_path)
            if qa_md is not None:
                mosaics.append(qa_md)






    md_name = CANOPY_DENSITY
    dhm_md_path = os.path.join(gdb_path, md_name)
    mosaics.append([dhm_md_path, md_name])

    if arcpy.Exists(dhm_md_path):
        arcpy.AddMessage("{} already exists.".format(md_name))
    else:
        try:
            vert_cs_name, vert_unit_name = Utility.getVertCSInfo(spatial_reference)  # @UnusedVariable
            # No need to update boundary and footprints since it will inherit from the original
            pc_all_md_path = os.path.join(gdb_path, "POINT_COUNT_ALL")
            createReferenceddMosaicDataset(pc_all_md_path, dhm_md_path, spatial_reference, vert_unit_name)
        except:
            arcpy.AddMessage("Failed to create {}".format(dhm_md_path))


    deleteFileIfExists(simple_footprint_path, True)
    deleteFileIfExists(simple_lasd_boundary_path, True)

    return mosaics
예제 #2
0
def createRasterBoundaryAndFootprints(fgdb_path, target_path, project_ID, project_path, project_UID):
    a = datetime.datetime.now()

    stat_out_folder = os.path.join(target_path, STAT_LAS_FOLDER)

    b_file_list = []
    c_file_list = []

    for f_name in [f for f in os.listdir(stat_out_folder) if (f.startswith('B_') and f.endswith('.shp'))]:
        b_path = os.path.join(stat_out_folder, f_name)
        c_path = os.path.join(stat_out_folder, "C{}".format(f_name[1:]))

        try:
            if not os.path.exists(b_path):
                arcpy.AddWarning("Failed to find B boundary file {}".format(b_path))
            else:
                b_file_list.append(b_path)
        except:
            pass
        try:
            if not os.path.exists(c_path):
                arcpy.AddWarning("Failed to find C boundary file {}".format(c_path))
            else:
                c_file_list.append(c_path)
                deleteFields(c_path)
        except:
            pass

    a = doTime(a, "Found {} footprints".format(len(b_file_list)))

    try:
        for file_type in [r'C_*.shp', r'B_*.shp']:
            bad_shape_type_list = list(filter(lambda x: arcpy.Describe(x).shapeType != 'Polygon',glob.glob(os.path.join(stat_out_folder, file_type))))
            if len(bad_shape_type_list) > 0:
                for bad_type in bad_shape_type_list:
                    arcpy.AddMessage("ERROR: Bad shape type in file '{}'".format(bad_type))
    except:
        pass

    las_footprint = getLasFootprintPath(fgdb_path)
    lasd_boundary = getLasdBoundaryPath(fgdb_path)
    if arcpy.Exists(las_footprint):
        arcpy.AddMessage("Footprints exist: {}".format(las_footprint))
    else:
        # Delete the boundary if the footprints don't exist (have to recreate anyway)
        deleteFileIfExists(lasd_boundary, True)
        lasd_boundary_B = "{}B".format(lasd_boundary)
        deleteFileIfExists(lasd_boundary_B, True)

        las_footprint_1 = os.path.join(fgdb_path, "{}B1".format(las_footprint))
        las_footprint_2 = os.path.join(fgdb_path, "{}B2".format(las_footprint))
        las_footprint_CP = os.path.join(fgdb_path, "{}B_CP".format(las_footprint))
        a = doTime(a, "\tMerging B footprints to {}".format(las_footprint_2))
        deleteFileIfExists(las_footprint_1, True)
        deleteFileIfExists(las_footprint_2, True)
        deleteFileIfExists(las_footprint_CP, True)
##Old Code        arcpy.Merge_management(inputs=b_file_list, output=las_footprint_2)
##New Code
        #BJN: Reduce memory usage by appending blocks of tiles instead of merging
        #     all of the tiles at once.
        out_path, out_name = os.path.split(las_footprint_2)
        cfs_template = b_file_list[0]
        arcpy.CreateFeatureclass_management(out_path, out_name, "POLYGON", template = cfs_template, spatial_reference = cfs_template)

        append_group_size = 1024 #appending x tiles at a time
        append_group_start = 0  #list offset for the current file group

        while append_group_start < len(b_file_list):
            #set the new file group endpoint
            append_group_end = append_group_start + append_group_size
            #Use the next append_group_size tiles, or up to the end of the list,
            #whichever is smaller.
            append_msg = '{}Adding {} tiles'.format(' '*8, append_group_size)
            if append_group_end < len(b_file_list):
                arcpy.Append_management(b_file_list[append_group_start:append_group_end], las_footprint_2)
            else:
                append_msg = '{}Adding {} tiles'.format(' '*8, len(b_file_list[append_group_start:]))
                arcpy.Append_management(b_file_list[append_group_start:], las_footprint_2)
            arcpy.AddMessage(append_msg)

            #Set the new start point
            append_group_start = append_group_end

        arcpy.Compact_management(out_path)
##End New Code

        #Utility.addToolMessages()
        deleteFields(las_footprint_2)
        arcpy.RepairGeometry_management(in_features=las_footprint_2, delete_null="DELETE_NULL")
        #Utility.addToolMessages()
        a = doTime(a, "\tMerged B and repaired footprints to {}".format(las_footprint_2))

        #arcpy.CreateCartographicPartitions_cartography(in_features=las_footprint_2, out_features=las_footprint_CP, feature_count=PARTITION_COUNT)
        #a = doTime(a, "\tCreated B carto parts")

        #arcpy.env.cartographicPartitions = las_footprint_CP
        #a = doTime(a, "\tSet B cartographic partitions to {}".format(las_footprint_CP))

        #arcpy.SimplifyPolygon_cartography(in_features=las_footprint_2, out_feature_class=las_footprint_1, algorithm="POINT_REMOVE", tolerance="0.5 Meters", minimum_area="0 Unknown", error_option="RESOLVE_ERRORS", collapsed_point_option="NO_KEEP", in_barriers="")
        #Utility.addToolMessages()
        #arcpy.env.cartographicPartitions = None
        #a = doTime(a, "\tSimplified B las footprints to {}".format(las_footprint_1))
        #deleteFileIfExists(las_footprint_2, True)
        #arcpy.RepairGeometry_management(in_features=las_footprint_1, delete_null="DELETE_NULL")
        #Utility.addToolMessages()

        #a = doTime(a, "Merged B las footprints {}".format(las_footprint_1))

        createBoundaryFeatureClass(las_footprint_2, lasd_boundary_B)
        deleteFileIfExists(las_footprint_2, True)
        a = datetime.datetime.now()


        # Merge the other footprints before clipping
        las_footprint_1 = os.path.join(fgdb_path, "{}C1".format(las_footprint))
        las_footprint_2 = os.path.join(fgdb_path, "{}C2".format(las_footprint))
        las_footprint_CP = os.path.join(fgdb_path, "{}C_CP".format(las_footprint))
        deleteFileIfExists(las_footprint_1, True)
        deleteFileIfExists(las_footprint_2, True)
        deleteFileIfExists(las_footprint_CP, True)
        a = doTime(a, "\tMerging C las footprints to {}".format(las_footprint_2))
        arcpy.Merge_management(inputs=c_file_list, output=las_footprint_2)
        #Utility.addToolMessages()
        deleteFields(las_footprint_2)
        arcpy.RepairGeometry_management(in_features=las_footprint_2, delete_null="DELETE_NULL")
        #Utility.addToolMessages()
        a = doTime(a, "\tMerged C las footprints to {}".format(las_footprint_2))

        #arcpy.CreateCartographicPartitions_cartography(in_features=las_footprint_2, out_features=las_footprint_CP, feature_count=PARTITION_COUNT)
        #a = doTime(a, "\tCreated C carto parts")

        #arcpy.env.cartographicPartitions = las_footprint_CP
        #a = doTime(a, "\tSet C cartographic partitions to {}".format(las_footprint_CP))

        #arcpy.SimplifyPolygon_cartography(in_features=las_footprint_2, out_feature_class=las_footprint_1, algorithm="POINT_REMOVE", tolerance="0.5 Meters", minimum_area="0 Unknown", error_option="RESOLVE_ERRORS", collapsed_point_option="NO_KEEP", in_barriers="")
        #Utility.addToolMessages()
        #arcpy.env.cartographicPartitions = None
        #a = doTime(a, "\tSimplified C las footprints to {}".format(las_footprint_1))
        #deleteFileIfExists(las_footprint_2, True)
        #arcpy.RepairGeometry_management(in_features=las_footprint_1, delete_null="DELETE_NULL")
        #Utility.addToolMessages()

        #a = doTime(a, "Merged C las footprints {}".format(las_footprint_1))

        lasd_boundary_C = "{}C".format(lasd_boundary)
        deleteFileIfExists(lasd_boundary_C, True)
        createBoundaryFeatureClass(las_footprint_2, lasd_boundary_C)

        lasd_boundary_SD = "{}_SD".format(lasd_boundary)
        lasd_boundary_SD1 = "{}_SD1".format(lasd_boundary)
        lasd_boundary_SD2 = "{}_SD2".format(lasd_boundary)
        lasd_boundary_SD3 = "{}_SD3".format(lasd_boundary)
        deleteFileIfExists(lasd_boundary_SD, True)
        deleteFileIfExists(lasd_boundary_SD1, True)
        deleteFileIfExists(lasd_boundary_SD2, True)
        deleteFileIfExists(lasd_boundary_SD3, True)
        # Replace a layer/table view name with a path to a dataset (which can be a layer file) or create the layer/table view within the script
        arcpy.SymDiff_analysis(in_features=lasd_boundary_B, update_features=lasd_boundary_C, out_feature_class=lasd_boundary_SD1, join_attributes="ONLY_FID", cluster_tolerance="3 Meters")
        arcpy.Buffer_analysis(in_features=lasd_boundary_SD1, out_feature_class=lasd_boundary_SD2, buffer_distance_or_field="-3 Meters", line_side="FULL", line_end_type="ROUND", dissolve_option="NONE", dissolve_field="", method="PLANAR")
        arcpy.MultipartToSinglepart_management(in_features=lasd_boundary_SD2, out_feature_class=lasd_boundary_SD3)
        arcpy.Buffer_analysis(in_features=lasd_boundary_SD3, out_feature_class=lasd_boundary_SD, buffer_distance_or_field="3 Meters", line_side="FULL", line_end_type="ROUND", dissolve_option="NONE", dissolve_field="", method="PLANAR")
        arcpy.DeleteField_management(in_table=lasd_boundary_SD, drop_field="FID_BoundaryLASDatasetB;FID_BoundaryLASDatasetC;BUFF_DIST;ORIG_FID")

        deleteFileIfExists(lasd_boundary_C, True)
        deleteFileIfExists(lasd_boundary_SD1, True)
        deleteFileIfExists(lasd_boundary_SD2, True)
        deleteFileIfExists(lasd_boundary_SD3, True)

        a = doTime(a, "Created symetrical difference in boundaries {}".format(lasd_boundary_SD))

        checkNullFields(las_footprint_2)
        a = datetime.datetime.now()

        deleteFileIfExists(las_footprint, True)
        arcpy.Clip_analysis(in_features=las_footprint_2, clip_features=lasd_boundary_B, out_feature_class=las_footprint, cluster_tolerance="")
        #deleteFileIfExists(las_footprint_1, True)
        deleteFileIfExists(lasd_boundary_B, True)

        #deleteFileIfExists(lasd_boundary, True)
        #deleteFileIfExists(las_footprint_CP, True)
        #arcpy.env.cartographicPartitions = None

        deleteFileIfExists(las_footprint_2, True)
        a = doTime(a, "Clipped las footprints to dataset boundary {} ".format(las_footprint))

    deleteFields(las_footprint)
    try:
        arcpy.RepairGeometry_management(in_features=las_footprint, delete_null="KEEP_NULL")
    except:
        pass

    if arcpy.Exists(lasd_boundary):
        arcpy.AddMessage("Boundary exists: {}".format(lasd_boundary))
    else:
        deleteFileIfExists(lasd_boundary, True)

        summary_string, field_alter = getStatsFields(las_footprint)
        createBoundaryFeatureClass(las_footprint, lasd_boundary, summary_string, field_alter)

        addProjectInfo(las_footprint, lasd_boundary, project_ID, project_path, project_UID)

    deleteFields(lasd_boundary)

    try:
        arcpy.RepairGeometry_management(in_features=lasd_boundary, delete_null="KEEP_NULL")
    except:
        pass

    return lasd_boundary, las_footprint
def createBoundaryFeatureClass(raster_footprint,
                               target_raster_boundary,
                               statistics_fields="",
                               alter_field_infos=None):
    a = datetime.datetime.now()
    aa = a

    raster_boundary_1 = "{}1".format(target_raster_boundary)
    deleteFileIfExists(raster_boundary_1, True)
    arcpy.Buffer_analysis(in_features=raster_footprint,
                          out_feature_class=raster_boundary_1,
                          buffer_distance_or_field="10 Meters",
                          line_side="FULL",
                          line_end_type="ROUND",
                          dissolve_option="NONE",
                          method="PLANAR")
    arcpy.RepairGeometry_management(in_features=raster_boundary_1,
                                    delete_null="DELETE_NULL")
    deleteFields(raster_boundary_1)
    a = doTime(a, "\tBuffer out into {}".format(raster_boundary_1))

    raster_boundary_2 = "{}2".format(target_raster_boundary)
    deleteFileIfExists(raster_boundary_2, True)
    arcpy.AddMessage(
        "\tDissolving with statistics: {}".format(statistics_fields))
    arcpy.Dissolve_management(in_features=raster_boundary_1,
                              out_feature_class=raster_boundary_2,
                              dissolve_field=FIELD_INFO[ELEV_TYPE][0],
                              statistics_fields=statistics_fields)
    arcpy.RepairGeometry_management(in_features=raster_boundary_2,
                                    delete_null="DELETE_NULL")
    deleteFields(raster_boundary_2)
    a = doTime(a, "\tDissolved to {}".format(raster_boundary_2))

    deleteFileIfExists(raster_boundary_1, True)

    alterFields(alter_field_infos, raster_boundary_2)
    a = doTime(a, "\tAltered Fields on {}".format(raster_boundary_2))

    raster_boundary_3 = "{}3".format(target_raster_boundary)
    deleteFileIfExists(raster_boundary_3, True)
    arcpy.EliminatePolygonPart_management(in_features=raster_boundary_2,
                                          out_feature_class=raster_boundary_3,
                                          condition="AREA",
                                          part_area="10000 SquareMiles",
                                          part_area_percent="0",
                                          part_option="CONTAINED_ONLY")
    arcpy.RepairGeometry_management(in_features=raster_boundary_3,
                                    delete_null="DELETE_NULL")
    deleteFields(raster_boundary_3)
    a = doTime(a,
               "\tEliminated internal parts on {}".format(raster_boundary_3))

    # Don't delete raster boundary 2 because we need it later

    # JWS 4/26 - Bend Simplify -> Point Remove & 20 Meters -> 0.1 Meters
    raster_boundary_4 = "{}4".format(target_raster_boundary)
    deleteFileIfExists(raster_boundary_4, True)
    arcpy.SimplifyPolygon_cartography(in_features=raster_boundary_3,
                                      out_feature_class=raster_boundary_4,
                                      algorithm="POINT_REMOVE",
                                      tolerance="0.1 Meters",
                                      minimum_area="0 Unknown",
                                      error_option="RESOLVE_ERRORS",
                                      collapsed_point_option="NO_KEEP",
                                      in_barriers="")
    arcpy.RepairGeometry_management(in_features=raster_boundary_4,
                                    delete_null="DELETE_NULL")
    deleteFields(raster_boundary_4)
    a = doTime(a, "\tSimplified to {}".format(raster_boundary_4))

    deleteFileIfExists(raster_boundary_3, True)

    deleteFileIfExists(target_raster_boundary, True)
    arcpy.Buffer_analysis(in_features=raster_boundary_4,
                          out_feature_class=target_raster_boundary,
                          buffer_distance_or_field="-10 Meters",
                          line_side="FULL",
                          line_end_type="ROUND",
                          dissolve_option="NONE",
                          method="PLANAR")
    arcpy.RepairGeometry_management(in_features=target_raster_boundary,
                                    delete_null="DELETE_NULL")
    deleteFields(target_raster_boundary)
    a = doTime(a, "\tBuffer back into {}".format(target_raster_boundary))

    deleteFileIfExists(raster_boundary_4, True)

    if alter_field_infos is not None and len(alter_field_infos) > 0:
        fields = ";".join([field[1] for field in alter_field_infos])
        arcpy.JoinField_management(in_data=target_raster_boundary,
                                   in_field="OBJECTID",
                                   join_table=raster_boundary_2,
                                   join_field="OBJECTID",
                                   fields=fields)
        # Utility.addToolMessages()
        a = doTime(
            a, "\tJoined {} with {}".format(target_raster_boundary,
                                            raster_boundary_2))

    deleteFileIfExists(raster_boundary_2, True)

    a = doTime(
        aa, "Dissolved raster footprints to dataset boundary {} ".format(
            target_raster_boundary))
예제 #4
0
def createBoundaryFeatureClass(raster_footprint, target_raster_boundary, statistics_fields="", alter_field_infos=None):
    a = datetime.datetime.now()
    aa = a
    deleteFields(raster_footprint)

    lasd_boundary_0 = "{}0".format(target_raster_boundary)
    lasd_boundary_1 = "{}1".format(target_raster_boundary)

    deleteFileIfExists(lasd_boundary_0, True)
    deleteFileIfExists(lasd_boundary_1, True)

    arcpy.AddMessage("\tMultipart to Singlepart")
    arcpy.MultipartToSinglepart_management(in_features=raster_footprint, out_feature_class=lasd_boundary_0)
    Utility.addToolMessages()
    arcpy.RepairGeometry_management(in_features=lasd_boundary_0, delete_null="DELETE_NULL")
    deleteFields(lasd_boundary_0)

    arcpy.AddMessage("\tBuffering")
    arcpy.Buffer_analysis(in_features=lasd_boundary_0, out_feature_class=lasd_boundary_1, buffer_distance_or_field="10 Meters", line_side="FULL", line_end_type="ROUND", dissolve_option="NONE", method="PLANAR")
    Utility.addToolMessages()
    arcpy.RepairGeometry_management(in_features=lasd_boundary_1, delete_null="DELETE_NULL")
    deleteFields(lasd_boundary_1)

    deleteFileIfExists(lasd_boundary_0, True)

    lasd_boundary_2 = "{}2".format(target_raster_boundary)
    deleteFileIfExists(lasd_boundary_2, True)
    arcpy.AddMessage("\tDissolving with statistics: {}".format(statistics_fields))
    arcpy.Dissolve_management(
        in_features=lasd_boundary_1,
        out_feature_class=lasd_boundary_2,
        statistics_fields=statistics_fields
        )
    Utility.addToolMessages()
    arcpy.RepairGeometry_management(in_features=lasd_boundary_2, delete_null="DELETE_NULL")
    deleteFields(lasd_boundary_2)
    a = doTime(a, "\tDissolved to {}".format(lasd_boundary_2))


    if alter_field_infos is not None:
        for alter_field_info in alter_field_infos:
            try:
                alterField(lasd_boundary_2, alter_field_info[0], alter_field_info[1], alter_field_info[2])
            except:
                pass

        a = doTime(a, "\tRenamed summary fields")

    lasd_boundary_3 = "{}3".format(target_raster_boundary)
    deleteFileIfExists(lasd_boundary_3, True)
    arcpy.EliminatePolygonPart_management(in_features=lasd_boundary_2, out_feature_class=lasd_boundary_3, condition="AREA", part_area="10000 SquareMiles", part_area_percent="0", part_option="CONTAINED_ONLY")
    arcpy.RepairGeometry_management(in_features=lasd_boundary_3, delete_null="DELETE_NULL")
    deleteFileIfExists(lasd_boundary_1, True)
    deleteFields(lasd_boundary_3)
    lasd_boundary_4 = "{}4".format(target_raster_boundary)
    deleteFileIfExists(lasd_boundary_4, True)
    arcpy.SimplifyPolygon_cartography(in_features=lasd_boundary_3, out_feature_class=lasd_boundary_4, algorithm="BEND_SIMPLIFY", tolerance="20 Meters", minimum_area="0 Unknown", error_option="RESOLVE_ERRORS", collapsed_point_option="NO_KEEP", in_barriers="")
    arcpy.RepairGeometry_management(in_features=lasd_boundary_4, delete_null="DELETE_NULL")
    deleteFields(lasd_boundary_4)
    #try:
    #    arcpy.DeleteField_management(in_table=lasd_boundary_4, drop_field="Id;ORIG_FID;InPoly_FID;SimPgnFlag;MaxSimpTol;MinSimpTol")
    #except:
    #    pass
    deleteFileIfExists(lasd_boundary_3, True)

    deleteFileIfExists(target_raster_boundary, True)
    arcpy.Buffer_analysis(in_features=lasd_boundary_4, out_feature_class=target_raster_boundary, buffer_distance_or_field="-10 Meters", line_side="FULL", line_end_type="ROUND", dissolve_option="ALL", method="PLANAR")
    arcpy.RepairGeometry_management(in_features=target_raster_boundary, delete_null="DELETE_NULL")
    deleteFields(target_raster_boundary)
    deleteFileIfExists(lasd_boundary_4, True)

    if alter_field_infos is not None and len(alter_field_infos) > 0:
        fields = ";".join([field[1] for field in alter_field_infos])
        arcpy.JoinField_management(in_data=target_raster_boundary, in_field="OBJECTID", join_table=lasd_boundary_2, join_field="OBJECTID", fields=fields)
        Utility.addToolMessages()

    deleteFileIfExists(lasd_boundary_2, True)

    a = doTime(aa, "Dissolved las footprints to dataset boundary {} ".format(target_raster_boundary))
def createRasterBoundaryAndFootprints(fgdb_path, target_path, project_ID,
                                      project_path, project_UID, elev_type):
    a = datetime.datetime.now()
    raster_footprint = None
    raster_boundary = None

    stat_out_folder = os.path.join(target_path, STAT_RASTER_FOLDER, elev_type)
    if not os.path.exists(stat_out_folder):
        arcpy.AddMessage(
            "Raster statistics for elevation type don't exist: {}".format(
                stat_out_folder))
    else:

        b_file_list = []
        for f_name in [
                f for f in os.listdir(stat_out_folder)
                if (f.startswith('B_') and f.endswith('.shp'))
        ]:
            b_path = os.path.join(stat_out_folder, f_name)

            try:
                if not os.path.exists(b_path):
                    arcpy.AddWarning(
                        "Failed to find B boundary file {}".format(b_path))
                else:
                    b_file_list.append(b_path)
            except:
                pass

        a = doTime(a, "Found boundaries {}".format(len(b_file_list)))

        raster_footprint = getRasterFootprintPath(fgdb_path, elev_type)
        raster_boundary = getRasterBoundaryPath(fgdb_path, elev_type)
        if arcpy.Exists(raster_footprint):
            arcpy.AddMessage(
                "Raster Footprints exist: {}".format(raster_footprint))
        else:

            deleteFileIfExists(raster_footprint, True)
            arcpy.Merge_management(inputs=b_file_list, output=raster_footprint)
            arcpy.RepairGeometry_management(in_features=raster_footprint,
                                            delete_null="DELETE_NULL")
            deleteFields(raster_footprint)

            field_alter = []
            for base_field in FIELD_INFO:
                field_name = base_field[0]
                new_field_name = base_field[0]
                new_field_alias = base_field[1]
                new_field = [field_name, new_field_name, new_field_alias]

                field_alter.append(new_field)
            alterFields(field_alter, raster_footprint)

            a = doTime(a,
                       "Merged raster footprints {}".format(raster_footprint))

            arcpy.RepairGeometry_management(in_features=raster_footprint,
                                            delete_null="DELETE_NULL")
            deleteFields(raster_footprint)

        if arcpy.Exists(raster_boundary):
            arcpy.AddMessage(
                "Raster Boundary exist: {}".format(raster_boundary))
        else:
            summary_string, field_alter = getStatsFields(raster_footprint)
            createBoundaryFeatureClass(raster_footprint, raster_boundary,
                                       summary_string, field_alter)

            addProjectInfo(raster_footprint, raster_boundary, project_ID,
                           project_path, project_UID)

        # Buffer Footprint @ 1 Meter & Clip to Avoid Gaps in Output Mosaic
        one_meter_buffer = arcpy.Buffer_analysis(
            raster_footprint,
            os.path.join(fgdb_path,
                         '{}_2m'.format(os.path.split(raster_footprint)[1])),
            '2 METER')
        arcpy.RepairGeometry_management(in_features=one_meter_buffer,
                                        delete_null="DELETE_NULL")
        deleteFields(one_meter_buffer)

        arcpy.Clip_analysis(one_meter_buffer, raster_boundary,
                            raster_footprint)
        arcpy.RepairGeometry_management(in_features=raster_footprint,
                                        delete_null="DELETE_NULL")
        deleteFields(raster_footprint)

        arcpy.Delete_management(one_meter_buffer)

        ## ?? DUPLICATE Code Block??
        # Buffer Footprint @ 1 Meter & Clip to Avoid Gaps in Output Mosaic
        #one_meter_buffer = arcpy.Buffer_analysis(
        #    raster_footprint,
        #    os.path.join(fgdb_path, '{}_1m'.format(os.path.split(raster_footprint)[1])),
        #    '1 METER'
        #    )
        #arcpy.Clip_analysis(one_meter_buffer, raster_boundary, raster_footprint)
        #arcpy.Delete_management(one_meter_buffer)
        #deleteFields(raster_footprint)

    return raster_footprint, raster_boundary