This script calculates the distance from each cell to the nearest cell of a specific type (e.g. a road).
The script can be used used in the Carbon storage and wood production example, to calculate the distance to roads (node Distance_road) directly in gBay.
Download the carbon sequestration network and spatial data to run the network with gBay.
Input:
Output:
### Calculates the distance to the nearest cell with a specific state (e.g. road) ### Input: discrete raster of categories (e.g. 1 = road, 0 = no road) ### Sets evidence on node continuous node (Distance_road) # import packages import os import sys import numpy from osgeo.gdalconst import * from osgeo import gdal import math from node_utils import * from scipy.spatial import distance # set names for labelling the script while running SCRIPT_NAME = "CONT_DISTANCE: " # to add as a prefix for all messages CELLS_PRINTING = 10 # SET FUNCTION PARAMETERS # name of input node input_name = "road" # number of the state in the input raster that defines the cells (e.g. roads), the distance to which we are interested in state_number = 0; # name of output node output_name = "Distance_road" # function that finds cells of interest def isRoad(node, cell): return (getStateHighestLikelihood(node, cell) == state_number) # function that finds distance to the nearest cell of interest def findCloserRoadCell(cell, road_list, width): if (len(road_list) == 0): print("findCloserRoadCell: There are no roads in the map.") return None return min(distance.cdist([cell], road_list, 'euclidean')[0]) # function that writes distance to the output node def process(dataset,nodes_data,iteration): # only use it at the beginning if (iteration != -1): return [] node_road = getNodeByName(nodes_data, input_name) if (not node_road): print(SCRIPT_NAME, "ERROR Node", input_name, "is not in nodes_data") return [] total_cells = dataset.RasterXSize * dataset.RasterYSize ; # get pixel size pixelsize = dataset.GetGeoTransform()[1] print(SCRIPT_NAME, "pixelsize:", pixelsize) road_cells = []; for cell in range(total_cells ): if (isRoad(node_road,cell)): road_cells.append(cell); print(SCRIPT_NAME, "There are", len(road_cells), "cells that are roads") distances=[] # Transform to 2-dimensional array road_coords = list(map(lambda x: [x / dataset.RasterXSize, x % dataset.RasterXSize], road_cells)) # append distances to new array for cell in range(total_cells ): if (isNODATA(node_road, cell)): distances.append(PY_NODATA_VALUE) elif isRoad(node_road, cell): distances.append(0) else: distances.append(findCloserRoadCell([cell / dataset.RasterXSize, cell % dataset.RasterXSize], road_coords, dataset.RasterXSize) * pixelsize) new_nodes_data = [{'name' : output_name, 'type': PY_CONTINUOUS, 'data': distances}] for i in range(CELLS_PRINTING): print(SCRIPT_NAME, "cell:", i, ":" , new_nodes_data[0]['data'][i]) if (validResultData(new_nodes_data, total_cells)): return new_nodes_data else: print ("Some error here: ")