Hi all,
I am trying to improve my python skills, has anyone got some tips to improve this code.
The purpose of this is to quickly as possible convert a single band raster (Elevation) into a CSV table that has the rasters x,y,z values.
Obviously this can also be done with various ESRI tools, but it can take hours for large areas, whereas this code will do it much quicker.
I'm still learning python, any tips would be appreciated. Thanks
Also see attached for code
################################
import arcpy
from arcpy import env
import csv,os
import numpy
# Set local variables
inRaster = arcpy.GetParameterAsText(0)
csv_filepath = arcpy.GetParameterAsText(1)
roundValue = int(arcpy.GetParameterAsText(2))
createPointFC = arcpy.GetParameterAsText(3)
out_path = arcpy.GetParameterAsText(4)
out_name = arcpy.GetParameterAsText(5)
'''
# Set Fixed variables for testing
inRaster = r"D:\Input\Raster_clip.tif"
csv_filepath = r"D:\Output\Coordinates.csv"
roundValue = 2
createPointFC = "true" # false is default
out_path = r"D:\Output\Working.gdb"
out_name = "points"
'''
#variables
fld_names = ["X", "Y", "Z"] # For point file and CSV headers
noData = -100000000 #Value for no data to exclude later
# Execute Raster To NumPy Array for Dict of xyz values
arcpy.AddMessage("Creating raster dictionary...")
theRaster = inRaster
ras = arcpy.Raster(theRaster)
ar = arcpy.RasterToNumPyArray(theRaster, nodata_to_value=noData)
# Get Cellsize of raster
cellsize = (ras.meanCellHeight + ras.meanCellWidth) / 2
# Get XY extent
xmin = ras.extent.XMin
ymax = ras.extent.YMax
# Shift XY to center of cell
centerX = xmin + (cellsize/2)
centerY = ymax - (cellsize/2)
centerXj = centerX
# Amount of cells
yheight, xwidth = ar.shape
# Dictionary of (x,y): values
d={}
# Loop through X and Y for all cells and add X,Y,Z data to Dictionary
for j in range(yheight):#74
for i in range(xwidth):#84
value = ar.item(j, i)
if value != noData: # remove No Data values
rValue = round(value, roundValue)
rCenterX = round(centerX,roundValue)
rCenterY = round(centerY,roundValue)
d[rCenterX, rCenterY] = rValue
centerX = centerX + cellsize
centerY = centerY - cellsize
centerX = centerXj
# Create CSV and populate from Dictionary
arcpy.AddMessage("Creating CSV...")
my_dict = d
with open(csv_filepath, 'w') as csv_file:
writer = csv.writer(csv_file)
#writer.writerow(fld_names)
for key in my_dict.keys():
newKey = str(key).replace('(', '').replace(')', '')
csv_file.write("{}, {}\n".format(newKey,my_dict[key]))
csv_file.close()
# Create Point FC from Dictionary
if createPointFC == "true":
arcpy.AddMessage("Creating Point Featureclass...")
# Execute CreateFeatureclass
spatial_reference = arcpy.Describe(inRaster).spatialReference
ptFC = arcpy.CreateFeatureclass_management(out_path, out_name, geometry_type='POINT', has_z='ENABLED', spatial_reference=spatial_reference)
arcpy.management.AddField(ptFC, "X", "Float")
arcpy.management.AddField(ptFC, "Y", "Float")
arcpy.management.AddField(ptFC, "Z", "Float")
#fc = out_path &"\"& out_name
#fc = r"D:\Output\Working.gdb\Points"
fullPath = os.path.join(out_path, out_name)
with arcpy.da.InsertCursor(fullPath,['SHAPE@X', 'SHAPE@Y', 'SHAPE@Z'] + fld_names ) as c: #+ fld_names
for x,y in my_dict.keys():
z = my_dict[x,y]
shapeXYZ = x,y,z
c.insertRow((x,y,z,x,y,z))
del c