Source code for raidnr.util.least_cost_path


# ---------------------------------------------------
# ¦¦¦¦¦¦¦    ¦¦¦¦¦   ¦¦¦¦  ¦¦¦¦¦¦¦¦  
#  ¦¦   ¦¦  ¦¦   ¦¦   ¦¦    ¦¦   ¦¦¦   
#  ¦¦¦¦¦¦   ¦¦¦¦¦¦¦   ¦¦    ¦¦   ¦¦¦   
#  ¦¦   ¦¦  ¦¦   ¦¦   ¦¦    ¦¦   ¦¦¦  
# ¦¦¦   ¦¦¦ ¦¦   ¦¦¦ ¦¦¦¦  ¦¦¦¦¦¦¦¦    
# ---------------------------------------------------
# Bryden Wood
# License: MIT, see full license in LICENSE.txt
# Web: repository-link
#-----------------------------------------------------
# Date: 30.09.2019
# Authors: Ioannis Toumpalidis
#-----------------------------------------------------
# Description
#-----------------------------------------------------
# Implementation of a random heightmap generation,
# and identifying a least cost path on the generated terrain. 
#-----------------------------------------------------
# Docs Reference : link to module docs
# Heightmap generation
# https://gamedev.stackexchange.com/questions/29044/how-can-i-generate-random-lakes-and-rivers-in-my-game
#-----------------------------------------------------

# modules
import noise
# scientific modules
import numpy as np
import matplotlib.pyplot as plt
from skimage.graph import route_through_array

[docs]def generateWorld(shape=(100,100)): """ Random noise surface cost. Parameters ---------- shape : tupple Shape of the cost surface Returns ------- world Surface cost, weights >0 """ scale = 100.0 octaves = 6 persistence = 0.5 lacunarity = 2.0 world = np.zeros(shape) for i in range(shape[0]): for j in range(shape[1]): world[i][j] = noise.pnoise2(i/scale, j/scale, octaves=octaves, persistence=persistence, lacunarity=lacunarity, repeatx=1024, repeaty=1024, base=0) # since noise generates negative values... # and the least cost path works only with positive values world+=abs(np.min(world))+0.1 return world
[docs]def get_least_cost(world, origin, destination, plot=False, ax=None): """ Uses the route_through_array function of skiimage, to compute a least_cost path in a raster. Parameters ---------- origin, destination : tupple Coordinates of the origin, destination. Since the cost surface is in a np.array use (y,x) instead of (x,y) plot : bool Returns plot of the path if path= True Returns ------- path : np.array Array of the least cost path. """ if(np.min(world)<=0): world+= (0.1 + abs(np.min(world))) indices, weight = route_through_array(world, origin, destination,geometric=True,fully_connected=True) indices = np.array(indices).T # path path = np.zeros_like(world) path[indices[0], indices[1]] = 40 # value for path on raster path_coords=np.array([indices[0],indices[1]], dtype='float64').transpose() newPath = path # w and path rasters minmax => (0,1) w = (world-world.min())/(world.max()-world.min()) p = (newPath-newPath.min())/(newPath.max()-newPath.min()) # plotting new path raster if (plot): b = ax == None if b: fig,ax = plt.subplots(figsize=(10,10)) ax.imshow(w*.5 + p*.5) if b: plt.show() return path_coords, p