def las_to_GandFrreturns(las_files, mask, name): '''This function takes a list of las files, creates a las dataset. Then it create a lasd for first and ground returns. After which it rasterizes the lasd and masks them to a specified area. las_files: a list of the paths for all the las files mask: ''' lasd = arcpy.CreateLasDataset_management(las_files, name) g_lasd = arcpy.MakeLasDatasetLayer_management(lasd, "ground", 2) g_ras = arcpy.LasDatasetToRaster_conversion( g_lasd, "g_rast.img", "ELEVATION", "BINNING AVERAGE NATURAL_NEIGHBOR", "FLOAT", "CELLSIZE", 0.5) g_mask = arcpy.sa.ExtractByMask(g_ras, mask) g_mask.save("g_mask" + name + ".img") f_lasd = arcpy.MakeLasDatasetLayer_management(lasd, "first", '', 1) f_ras = arcpy.LasDatasetToRaster_conversion( f_lasd, "f_rast.img", "ELEVATION", "BINNING MAXIMUM NATURAL_NEIGHBOR", "FLOAT", "CELLSIZE", 0.5) f_mask = arcpy.sa.ExtractByMask(f_ras, mask, name) f_mask.save("f_mask" + name + ".img") return f_mask, g_mask
'raster': os.path.join(support_folder, 'dhm.tif'), 'name': 'height' } intensity_files = { 'multipoint': None, 'tin': None, 'raster': os.path.join(support_folder, 'intensity.tif'), 'rawraster': os.path.join(support_folder, 'intensity.tif'), 'name': 'intensity' } arcpy.AddMessage("Generating DSM") surfaceLyr = arcpy.CreateUniqueName('First Return Layer') arcpy.MakeLasDatasetLayer_management( in_las_dataset=inlasd, out_layer=surfaceLyr, class_code=None, return_values=['Single Return', 'First of Many']) arcpy.LasDatasetToRaster_conversion( in_las_dataset=surfaceLyr, out_raster=surface_files['rawraster'], value_field='ELEVATION', interpolation_type= "TRIANGULATION NATURAL_NEIGHBOR NO_THINNING CLOSEST_TO_MEAN 0", # 'TRIANGULATION Linear {point_thinning_type} {point_selection_method} {resolution}', data_type='FLOAT', sampling_type='CELLSIZE', sampling_value=cell_edge_length, z_factor=z_factor) arcpy.AddMessage("Generating DEM")
def task(target_lasd, task_dir, dictionary): print('Starting Task: ', dictionary[0]) try: # Get Task ID task_id = dictionary[0] # Create Working Directory for Task Output dir_name = task_id + '__' + str(os.getpid()) + '__' working_dir = tempfile.mkdtemp(prefix=dir_name, dir=task_dir) # Set Extent for Task Processing proc_ext = dictionary[1] XMin = proc_ext[0] YMin = proc_ext[1] XMax = proc_ext[2] YMax = proc_ext[3] arcpy.env.extent = arcpy.Extent(XMin, YMin, XMax, YMax) # Create LAS Dataset Layer filter_name = 'in_memory/lasd_lyr_' + task_id filter_lasd = arcpy.MakeLasDatasetLayer_management( target_lasd, filter_name, '2;8') # A - Create Raster a_name = os.path.join(working_dir, 'a.tif') a = arcpy.LasPointStatsAsRaster_management(filter_lasd, a_name, 'POINT_COUNT', 'CELLSIZE', '10') # B - Zero Raster b = arcpy.Raster(a) * 0 b.save(os.path.join(working_dir, 'b.tif')) # B - Raster To Poly b_rtp_name = os.path.join(working_dir, 'b_rtp.shp') b_rtp = arcpy.RasterToPolygon_conversion(b, b_rtp_name, 'True', 'VALUE') # B - Get Envelope Based On Inner/Outer Grid Cell b_env_name = os.path.join(working_dir, 'b_env.shp') if task_id.endswith('_'): b_env = arcpy.MinimumBoundingGeometry_management( b_rtp, b_env_name, "ENVELOPE", "ALL") else: b_env = arcpy.MinimumBoundingGeometry_management( b_rtp, b_env_name, "CONVEX_HULL", "ALL") # C - Reclassify Raster c = arcpy.sa.Reclassify(b, 'VALUE', '0 0; NODATA 1') c.save(os.path.join(working_dir, 'c.tif')) # C - Raster To Poly c_rtp_name = os.path.join(working_dir, 'c_rtp.shp') c_rtp = arcpy.RasterToPolygon_conversion(c, c_rtp_name, 'False', 'VALUE') # D - Clip c_rtp by b_env d_name = os.path.join(working_dir, 'd.shp') d = arcpy.Clip_analysis(c_rtp, b_env, d_name) # Create Acres Field & Calculate on Merged D arcpy.AddField_management(d, 'ACRES', 'DOUBLE') arcpy.CalculateField_management(d, 'ACRES', '!shape.area@acres!') # E - Select & Copy Features e_sel_criteria = '"gridcode" = 1 AND "ACRES" > 1.5' e_sel_layer_name = 'e_sel_lyr_' + task_id e_sel_layer = arcpy.MakeFeatureLayer_management( d, e_sel_layer_name, e_sel_criteria) e_name = os.path.join(working_dir, 'e.shp') arcpy.CopyFeatures_management(e_sel_layer, e_name) arcpy.Delete_management(e_sel_layer) # F - Select & Copy Features f_sel_criteria = '"gridcode" = 0' f_sel_layer_name = 'f_sel_lyr_' + task_id f_sel_layer = arcpy.MakeFeatureLayer_management( c_rtp, f_sel_layer_name, f_sel_criteria) f_name = os.path.join(working_dir, 'f.shp') arcpy.CopyFeatures_management(f_sel_layer, f_name) arcpy.Delete_management(f_sel_layer) # Clear LAS Dataset Layer arcpy.Delete_management(filter_name) # Write Text File As Completion Flag open(os.path.join(working_dir, task_id + '.txt'), 'a').close() except Exception as e: print('Task Dropped: ', task_id) print('Exception: ', e) print('Finished Task: ', dictionary[0]) return task_id
else: print("%s exists!" % lasD) cellSize = 2 zFactor = "" arcpy.env.workspace = outLAS #Create DEM outDEMras = os.path.join(outDEM, nm + '_DEM_full.tif') print("Begin %s processing..." % (nm + '_DEM_full.tif')) lasDEM = arcpy.CreateUniqueName(nm + '_DEM_full') returnValue = '' #[2,9]#'ANY'#['LAST', 'SINGLE'] class_code = [2, 9] print(" Creating LAS layer...") arcpy.MakeLasDatasetLayer_management(lasD, lasDEM, class_code) print(" Creating surface...") arcpy.conversion.LasDatasetToRaster(lasDEM, outDEMras, 'ELEVATION', 'BINNING MINIMUM NATURAL_NEIGHBOR', 'FLOAT', 'CELLSIZE', cellSize, zFactor) print("%s processing completed!" % nm + '_DEM.tif') #Create DSM outDSMras = os.path.join(outDSM, nm + '_DSM_full.tif') print("Begin %s processing..." % (nm + '_DSM_full.tif')) lasDSM = arcpy.CreateUniqueName(nm + '_DSM_full') #returnValue = [3,4,5]#['FIRST', 'SINGLE']#[3,4,5] class_code = [0, 1, 2, 3, 4, 5, 9] print(" Creating LAS layer...") arcpy.MakeLasDatasetLayer_management(lasD, lasDSM, class_code) print(" Creating surface...")
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]))
arcpy.CheckOutExtension("Spatial") # Create a LAS dataset env.workspace = MainWorkspace arcpy.management.CreateLasDataset(inputLAS, 'lasDataset.lasd', "RECURSION", "", spatialRef, "COMPUTE_STATS") print ("lAS Dataset created") # Extract seperate LAS dataset and raster layers for Ground Returns and Canopy Returns. ground_returns = r'in_memory\ground_returns' canopy_returns = r'in_memory\canopy_returns' arcpy.MakeLasDatasetLayer_management('lasDataset.lasd', ground_returns, 2, 'Last Return', 'INCLUDE_UNFLAGGED', 'EXCLUDE_SYNTHETIC', 'INCLUDE_KEYPOINT', 'EXCLUDE_WITHHELD') arcpy.MakeLasDatasetLayer_management('lasDataset.lasd', canopy_returns, '', ['First of Many', 1], 'INCLUDE_UNFLAGGED', 'EXCLUDE_SYNTHETIC', 'INCLUDE_KEYPOINT', 'EXCLUDE_WITHHELD') env.workspace = FinalGDB arcpy.conversion.LasDatasetToRaster(ground_returns, "DEM", 'ELEVATION', 'BINNING AVERAGE NATURAL_NEIGHBOR', 'FLOAT', 'CELLSIZE', '1', '1') arcpy.conversion.LasDatasetToRaster(canopy_returns, "DSM", 'ELEVATION', 'BINNING AVERAGE NATURAL_NEIGHBOR', 'FLOAT', 'CELLSIZE', '1', '1') print ("DEM and DSM created")
def createMXD(las_qainfo, target_path, project_ID): mxd = None try: las_footprint_path = A04_C_ConsolidateLASInfo.getLasFootprintPath( las_qainfo.filegdb_path) lasd_boundary_path = A04_C_ConsolidateLASInfo.getLasdBoundaryPath( las_qainfo.filegdb_path) lasd_path = las_qainfo.las_dataset_path out_map_file_path = os.path.join(target_path, "{}.mxd".format(project_ID)) if os.path.exists(out_map_file_path): arcpy.AddMessage("MXD exists: {}".format(out_map_file_path)) else: mxd = arcpy.mapping.MapDocument( os.path.join(os.path.dirname(os.path.realpath(__file__)), "blank.mxd")) mxd.saveACopy(out_map_file_path) arcpy.AddMessage("Created MXD {}".format(out_map_file_path)) mxd = arcpy.mapping.MapDocument(out_map_file_path) mxd.relativePaths = True df = mxd.activeDataFrame if not (isLayerExist(mxd, df, "LAS Footprints") or isLayerExist( mxd, df, "FootprintLASFile")): #Changed condition 3 Apr 2019 BJN lyr_footprint = arcpy.MakeFeatureLayer_management( las_footprint_path, "FootprintLASFile").getOutput( 0) #Changed layer name 27 Mar 2019 BJN arcpy.mapping.AddLayer(df, lyr_footprint, 'BOTTOM') arcpy.AddMessage("Added layer to mxd: {}".format(lyr_footprint)) if not (isLayerExist(mxd, df, "LAS Boundary") or isLayerExist( mxd, df, "BoundaryLASDataset")): #Changed condition 3 Apr 2019 BJN lyr_boundary = arcpy.MakeFeatureLayer_management( lasd_boundary_path, "BoundaryLASDataset").getOutput( 0) #Changed layer name 27 Mar 2019 BJN arcpy.mapping.AddLayer(df, lyr_boundary, 'BOTTOM') arcpy.AddMessage("Added layer to mxd: {}".format(lyr_boundary)) if not isLayerExist(mxd, df, "LAS Dataset"): lyr_lasd = arcpy.MakeLasDatasetLayer_management( lasd_path, "LAS Dataset").getOutput(0) arcpy.mapping.AddLayer(df, lyr_lasd, 'TOP') arcpy.AddMessage("Added layer to mxd: {}".format(lyr_lasd)) if not (isLayerExist(mxd, df, "LAS Boundary Difference") or isLayerExist(mxd, df, "BoundaryLASDataset_SD") ): #Changed condition 3 Apr 2019 BJN lasd_boundary_SD = "{}_SD".format(lasd_boundary_path) lyr_diff = arcpy.MakeFeatureLayer_management( lasd_boundary_SD, "BoundaryLASDataset_SD").getOutput( 0) #Changed layer name 27 Mar 2019 BJN arcpy.mapping.AddLayer(df, lyr_diff, 'TOP') arcpy.AddMessage("Added layer to mxd: {}".format(lyr_diff)) mxd.save() except: arcpy.AddWarning("Failed to set up project MXD") return mxd