The extract by mask tool in ArcGIS has only two required arguments. The first is inRaster
and the second is inMaskData
. The filename and format of the output raster are determined automatically. The following command will achieve this:
extracted_raster = arcpy.gp.ExtractByMask_sa(input_raster, extraction_buffer)
The output raster automatically gets a name like so: Extract_{in_raster_name}
. It gets dumped into arcpy.env.workspace
as expected.
In my case, I want my output raster to get dumped into in_memory
, but I also want arcpy
to automatically name it and pick the format for me. I tried doing this using two methods. The first consists of changing the workspace to in_memory
before I run the above command:
arcpy.env.workspace = 'in_memory'
extracted_raster = arcpy.gp.ExtractByMask_sa(input_raster, extraction_buffer)
This throws an error, since it cannot find my input_raster, which is not located in_memory
:
ERROR 000865: Input raster: .\input\elsus.tif does not exist. Failed to execute (ExtractByMask).
The second method is to hardcode the output_raster
location to in_memory
. But using this method does not allow me to force arcpy
to name the file:
arcpy.gp.ExtractByMask_sa(input_raster, extraction_buffer, r'in_memory\test')
I really don't care about the file name for this intermediate data. I prefer to store the features/rasters as objects and use the variable names instead.How can I force arcpy
to handle the naming of the file, such that I only have to worry about the output object variable name?
2 Answers 2
You cant have a file extension (for example .tif) for rasters in the in_memory workspace. Remove it and then use Copy Raster to set it when you save to disk.
For arcpy to find input_raster when you change workspace you can do:
import os,arcpy
arcpy.env.workspace = r'C:\database.gdb'
rasters = arcpy.ListRasters() #Will only list names, not complete path, so when you change workspace arcpy will not know where they are
rasters = [os.path.join(arcpy.env.workspace, r) for r in rasters] #Add path, now you can change workspace and arcpy will find them anyway
arcpy.env.workspace = r'in_memory'
for r in rasters:
#do something
I solved my problem a different way. It turns out I was using a bit of a weird python setup to actually run my script. This is what I was doing before from cmd
command line
C:\>
C:\> cd C:\Python27\ArcGIS10.6
C:\Python27\ArcGIS10.6> python C:\WorkspaceDirectory\script.py
Which meant that I could find no way, from my current directory, to extract the true relative paths of the input features. It always saw C:\Python27\ArcGIS10.6
as my current working directory which I now see is very bad practice.
Once I added the C:\Python27\ArcGIS10.6
to my PATH
variable, I could comfortably use os.path.abspath
to get the absolute path of the input feature classes. Once the inputs where created using absolute paths, I was perfectly able to do the following:
arcpy.env.workspace = 'in_memory'
extracted_raster = arcpy.gp.ExtractByMask_sa(input_raster, extraction_buffer)
with no issues at all.
Indeed arcpy
does not account for relative paths. It is therefore essential to define things with absolute paths, and to make sure that python system settings are correctly configured.
arcpy.FeatureSet
andarcpy.Raster
objects. Then I switch my workspace toin_memory
and want to start doing my work there. However I want to still be able to invoke the input datasets at will, even if they belong to a different workspace.