_______________
Forgive me, my language is probably off - I'm very new to programming and this is the first real script I've been asked to write. It's simple, runs through some geoprocessing tools and then prints out a map. When I run it outside of a loop it works fine, however when I get to the point in the second iteration where a mask is extracted from an RGB image file it fails, this is the error I get:
File "C:/Iteration.py", line 34, in <module>
APN8_Raster.save(Extract_by_Mask)
RuntimeError: ERROR 000871: Output Raster: Unable to delete the output C:\Extract_RSF.
I've also gotten a schema lock error, my worry is that the shapefiles I'm looking to overwrite are locked for some reason. I run this script through PyCharm - ArcGIS Pro is closed so for the life of me I cannot figure out why it locks or why it cannot be overwritten. I believe it will do the same thing with the other 2 shape-files required in the process that need to be overwritten in every iteration.
Here's the code:
import arcpy
from arcpy import env
env.workspace = r"C:\Users\nahgl\Firewatch\Firewatch.gdb"
env.overwriteOutput = True
fc = "Parcels"
field = ["APN_8"]
RGB_of_RSF = arcpy.Raster("RSF_RGBe_FW2020")
Parcels = "Parcels"
Buildings = "Buildings"
SQL_Expression = "APN_8 = '26603028'"
Map_Expression = "OBJECTID = 1"
Symbology50 = r"C:\Users\nahgl\Firewatch\Python\Symbology_50.lyrx"
Symbology100 = r"C:\Users\nahgl\Firewatch\Python\Symbology_100.lyrx"
with arcpy.da.SearchCursor(fc, field) as cursor:
for row in cursor:
print(row[0])
APN = "APN_8 = " + "'" + row[0] + "'"
# Process: Select Parcel (Select) (analysis)
Selected_Parcel = r"C:\Users\nahgl\Firewatch\Firewatch.gdb\Parcels_Select"
arcpy.analysis.Select(in_features=Parcels, out_feature_class=Selected_Parcel, where_clause=APN)
# Process: Select Building (Select) (analysis)
Selected_Buildings = r"C:\Users\nahgl\Firewatch\Firewatch.gdb\Buildings_Select"
arcpy.analysis.Select(in_features=Buildings, out_feature_class=Selected_Buildings, where_clause=APN)
# Process: Extract by Mask (Extract by Mask) (sa)
APN8_Raster = r"memory\Extract_RSF"
Extract_by_Mask = APN8_Raster
APN8_Raster = arcpy.sa.ExtractByMask(in_raster=RGB_of_RSF, in_mask_data=Selected_Parcel)
APN8_Raster.save(Extract_by_Mask)
# Process: Buffer 100 (Buffer) (analysis)
Buffer_Output_100 = r"memory\Buffer_100"
arcpy.analysis.Buffer(in_features=Selected_Buildings, out_feature_class=Buffer_Output_100,
buffer_distance_or_field="100 Feet", line_side="FULL", line_end_type="ROUND",
dissolve_option="ALL", dissolve_field=[], method="PLANAR")
# Process: 100ft Buffer Symbology (Apply Symbology From Layer) (management)
Buffer_Output_100 = arcpy.management.ApplySymbologyFromLayer(in_layer=Buffer_Output_100,
in_symbology_layer=Symbology100,
symbology_fields=[],
update_symbology="DEFAULT")[0]
# Process: Buffer 50 (Buffer) (analysis)
Buffer_Output_50 = r"memory\Buffer_50"
arcpy.analysis.Buffer(in_features=Selected_Buildings, out_feature_class=Buffer_Output_50,
buffer_distance_or_field="50 Feet", line_side="FULL", line_end_type="ROUND",
dissolve_option="ALL", dissolve_field=[], method="PLANAR")
# Process: 50ft Buffer Symbology (Apply Symbology From Layer) (management)
Buffer_Output_50_Final = arcpy.management.ApplySymbologyFromLayer(in_layer=Buffer_Output_50,
in_symbology_layer=Symbology50,
symbology_fields=[],
update_symbology="DEFAULT")[0]
# Process: Selecting the Project file = Firewatch & Map = RSF_Parcels
project = arcpy.mp.ArcGISProject(r"C:\Users\nahgl\Firewatch\Firewatch.aprx")
map = project.listMaps('RSF_Parcels')[0]
print(map.name)
# Process: Selecting Buffer_100 as Zoom in layer (Or by Parcels)
layer = map.listLayers('Buffer_100')[0]
print(layer)
# layer = map.listLayers('Parcel')[0] ##If Parcel is used as zoom in layer Map_Expression must be changed to SQL_Expression
arcpy.SelectLayerByAttribute_management(layer, "NEW_SELECTION", Map_Expression)
# Process: Selecting Layout that will be used
lyt = project.listLayouts("RSF_Layout")[0]
print(lyt.name)
# Process: Listing all elements within the layout
mf = lyt.listElements('MAPFRAME_ELEMENT', '*')[0]
# Process: Setting the extent of the map camera to the selected layer (Buffer_100 or Parcel) & then zooming into frame
mf.camera.setExtent(mf.getLayerExtent(layer, True, True))
mf.zoomToAllLayers()
# Clear the 100 Buffer Selection so it isn't blue
arcpy.management.SelectLayerByAttribute(layer, "CLEAR_SELECTION")
# Process: Importing the layout with the zoomed in image to a JPEG (Needs better naming)
lyt.exportToJPEG(
r"C:\Users\nahgl\Firewatch\scratch\RGB_%s" % APN[9:-1])
I've tried deleting the shapefiles after the image is created, this is where I get the schema lock:
"arcgisscripting.ExecuteError: ERROR 000464: Cannot get exclusive schema lock. Either being edited or in use by another application or service.
Failed to execute (Delete)."
I've done a lot of Google sloothing which leads be to believe this could be a bug? Not sure, using Python 3.7, any advice or help would be much appreciated. Thank you.
you need to put your files into a folder... writing to, and reading from the root folder (C:\) is just asking for trouble.
Also, overwriting files is controlled at the project level in Pro, under Geoprocessing Options or by setting the flag within the script (arcpy.env.overwriteOutputs=True) as you have done. However, if a file is used within a loop it may not be able to be deleted until the whole process is complete.
ps
"C:\Fire.gdb\Fire.gdb\Buildings_Select"
a gdb in a gdb?
I removed the middle file paths, sorry for complicating things. Paths are like this:
To be sure of no unintended stuff going on with your paths I'd make sure everything is named with the same raw formatting r'...' as per
project = arcpy.mp.ArcGISProject(r"C:\Fire.aprx")
I think you could avoid a lot of the overrides by using the memory workspace and deleting the memory objects each loop.
I'd follow Dan's suggestions in the first instance.
A final irrelevant point, I've not seen % used in strings very often, I'd say f strings or .format() is preferred.
I was reading up on memory workspaces but not quite getting how to implement it. The extracted mask, buffer_100, and buffer_50 would only exist in memory and then it would erase it after the JPEG is produced?
I would try it at least. It is better than trying to delete things until outputs are derived
What about using the scratch workspace?
Did you try it? Nothing is going to happen to the inputs data if you try stuff in the scratch workspace or in_memory. Either or.. Focus on getting to work, then optimize for speed or convenience after