I have a single shapefile with many polygons, 100 for this example. I want to iterate through each polygon to generate a Euclidean distance raster for each polygon, using the extents of the initial shapefile. Since each Euclidean distance raster would be run for each individual polygon, isolated, this means that each of these rasters would show increasing distance values spreading out from the borders of the polygon out to the extents, with no other polygons to touch. This means that each of the Euclidean distance rasters would be calculated such that the shapefile only contained a single polygon. I would like to send all of these 100 raster files to the same folder.
How can this be scripted so that individual Euclidean distance raster files are generated for each polygon, where these polygons are treated as being isolated? I am not sure which spatial/raster analysis package would be best and most straightforward for generating these Euclidean distance rasters, whether using python, R, GDAL, etc. Specifically, I am trying to use a for loop so I can perform raster calculations on each produced Euclidean distance raster file, where for this example, I want to add 2 to each raster pixel, such as the following:
for i in polygons_shapefile:
Euclidean_Distance = generate Euclidean distance(i)
Altered_Euclidean_Distance = Euclidean_Distance + 2
Send Altered_Euclidean_Distance to "Outputs" folder
I unfortunately do not have an example shapefile to provide, but really my question could apply to any polygons shapefile.
Update:
I am trying to use the code suggestion from @user2856 with my NYC Boroughs shapefile. For reference, this is what the attribute table of this shapefile looks like:
And here is the code I am using to produce a proximity raster of each borough and then store the test_value
value:
#Create euclidean distance for each polygon and store "Values"
out_raster_template = "Boroughs_Test/out_{}.tif"
out_proximity_template = "Boroughs_Test/prox_{}.tif"
shape_file = "Boroughs_Test/Boroughs.shp"
pixel_size = 10
nodata = -9999
id_field = 'boro_code'
value_field = 'test_value'
drv = gdal.GetDriverByName("ESRI Shapefile")
shp_ds = gdal.OpenEx(shape_file, gdal.OF_VECTOR)
lyr = shp_ds.GetLayer()
xmin, xmax, ymin, ymax = lyr.GetExtent()
srs = lyr.GetSpatialRef()
feat_def = lyr.GetLayerDefn()
lyr.ResetReading()
for feat in lyr:
id = feat.GetField(id_field)
val = feat.GetField(value_field)
tmp_feat = feat.Clone()
out_raster = out_raster_template.format(id)
prox_raster = out_proximity_template.format(id)
tmp_fn = '/vsimem/tmp.shp'
tmp_ds = drv.Create(tmp_fn, 0, 0, 0, gdal.GDT_Unknown )
tmp_lyr = tmp_ds.CreateLayer(tmp_fn, None, feat_def.GetGeomType())
tmp_lyr.CreateFeature(tmp_feat)
tmp_feat, tmp_lyr, tmp_ds = None, None, None
out_ds = gdal.Rasterize(out_raster, tmp_fn,
outputType=gdal.GDT_Float32, format='GTIFF', creationOptions=["COMPRESS=DEFLATE"],
noData=nodata, initValues=nodata,
xRes=pixel_size, yRes=-pixel_size, outputBounds=(xmin, ymin, xmax, ymax), outputSRS=srs,
allTouched=True, burnValues=val)
out_ds = None
gdal.Translate(prox_raster, out_raster, creationOptions=["COMPRESS=DEFLATE"])
src_ds = gdal.OpenEx(out_raster, gdal.OF_RASTER)
dst_ds = gdal.OpenEx(prox_raster, gdal.OF_UPDATE)
src_band = src_ds.GetRasterBand(1)
dst_band = dst_ds.GetRasterBand(1)
gdal.ComputeProximity(src_band, dst_band, options=[f'VALUES={val}'])
dst_band, src_band, dst_ds, src_ds = None, None, None, None
drv.Delete(tmp_fn)
This code works and produces the desired rasters, but for some reason prox_1.0.tif
and prox_5.0.tif
yield no data to show (e.g. a scale of -1.79769e+308 to 1.79769e+308) when viewed in QGIS.