Hi,
I try to create a tiny script that allows to create a focal filter based on
r.cost. This means that rather using a moving window I use r.cost to create a
"buffer" around a cell which is then used for getting certain statistics of the
neighborhood of that cell (e.g. mean, max, sum) and create a new raster based
on these statistical values. I'd like to use r.cost as it also allows to create
distance buffers along rasterized lines (the main purpose for me). One example
can be: "Get the maximum raster value which is up- and downstream from a cell
in a river distance of 500 m"...
So far I think I have a plan how it can work and I tried to write the script in
python. Anyway there are some problems where I am not sure how I can solve
them...
1) I don't really know how I can loop over the points (raster cells) and update
the points with the statistical value (e.g. mean). I try following:
grass.write_command("db.execute", stdin = 'UPDATE point_tmp%s SET univar=%d
WHERE cat = %d' % (str(os.getpid()),stat,cat))
but I get a "time out" (WARNING: Busy SQLITE db, already waiting for 10
seconds, 20 sec...). Probably it is related to the fact the two processes are
using the same database table (loop over the points and update)...
2) I don't know what is the best way to get a variable based on the input,
which is like defining a global variable in a if-loop, but I am not sure if
that is a good way?
Best is to look at the script which is attached. Theoretically it should be
possible to be used on every raster. But as it loops over each cell it takes
really long time to process large maps.
Maybe anyone wants to help me further developing this tiny python script. Any
help is very much appreciated. Thank you!
Cheers
/johannes
--
NEU: FreePhone 3-fach-Flat mit kostenlosem Smartphone!
Jetzt informieren: http://mobile.1und1.de/?ac=OM.PW.PW003K20328T7073a
#!/usr/bin/env python
#
############################################################################
#
# SCRIPT: Creating focal statistical raster based on r.cost distance
#
# AUTHOR(S): Johannes Radinger
# DATE: 2012-05-03
#
#############################################################################
#%Module
#% description: Calculating focal raster based on a r.cost distance of a raster cell
#% keywords: raster
#%End
#%option
#% key: input
#% type: string
#% gisprompt: old,cell,raster
#% description: input raster
#% required: yes
#%end
#%option
#% key: stat
#% type: string
#% multiple:no
#% options:mean,max,sum
#% description: Desired focal statistic for output raster
#% required: yes
#%end
#%option
#% key: distance
#% type: double
#% required: yes
#% multiple: no
#% description: Distance for filter/buffer
#%End
import sys
import os
import atexit
import sqlite3
import grass.script as grass
tmp_map_rast = None
tmp_map_vect = None
def cleanup():
if (tmp_map_rast or tmp_map_vect):
grass.run_command("g.remove",
rast = tmp_map_rast,
vect = tmp_map_vect,
quiet = True)
def main():
#defining temporary maps
tmp_map_rast = ["MASK","tmp"+str(os.getpid()),"distance_mask"+str(os.getpid())]
tmp_map_vect = ["point_tmp"+str(os.getpid())]
#database-connection
env = grass.gisenv()
gisdbase = env['GISDBASE']
location = env['LOCATION_NAME']
mapset = env['MAPSET']
grass.run_command("db.connect",
driver = "sqlite",
database = os.path.join(gisdbase, location, mapset,'sqlite.db'))
database = sqlite3.connect(os.path.join(gisdbase, location, mapset, 'sqlite.db'))
db = database.cursor()
# Getting resolution of raster map
res = int(grass.read_command("g.region",
flags = "m").strip().split('\n')[4].split('=')[1])
# Defining variables
input = [options['input']]
distance = options['distance']
# Remove any mask before processing
grass.run_command("g.remove",
rast = "MASK")
for i in input:
grass.mapcalc("$tmp = if($raster,$res,null())", # creating temporary map
tmp = "tmp"+str(os.getpid()),
res = res,
raster = i)
# make points from raster
grass.run_command("r.to.vect",
overwrite = True,
input = "tmp"+str(os.getpid()),
output = "point_tmp"+str(os.getpid()),
feature = "point")
# Get coordinates for each point
grass.run_command("v.db.addcol",
map = "point_tmp"+str(os.getpid()),
columns = "X DOUBLE, Y DOUBLE, univar DOUBLE")
grass.run_command("v.to.db",
map = "point_tmp"+str(os.getpid()),
type = "point",
option = "coor",
columns = "X,Y")
#update database connection
db = database.cursor()
# loop over points
for cat,X,Y in db.execute('SELECT cat, X, Y FROM point_tmp%s' % str(os.getpid())):
coors = str(X)+","+str(Y)
# creating focal distance buffer as MASK (using r.cost and a distance/buffer)
grass.run_command("r.cost",
flags = 'n',
overwrite = True,
max_cost = distance,
input = "tmp"+str(os.getpid()),
output = "distance_mask"+str(os.getpid()),
coordinate = coors)
# creating MASK based on r.cost output
grass.mapcalc("$MASK= if(!isnull($distance_mask),1,null())",
MASK = "MASK",
distance_mask = "distance_mask"+str(os.getpid()))
# Getting focal statistics (e.g. mean) based on distance_mask
univar = grass.read_command("r.univar", map = i)
stat = float(univar.split('\n')[10].split(':')[1])
# Here are still problems to set the statistics conditional based on the input
# Getting different statistics based on input
#if str(options['stat']) is "sum":
# stat = float(univar.split('\n')[15].split(':')[1])
#elif str(options['stat']) is "mean":
# stat = float(univar.split('\n')[10].split(':')[1])
# print stat
#elif str(options['stat']) is "max":
# stat = float(univar.split('\n')[8].split(':')[1])
# print stat
#update point map with new stat value
grass.write_command("db.execute", stdin = 'UPDATE point_tmp%s SET univar=%d WHERE cat = %d' % (str(os.getpid()),stat,cat))
grass.run_command("g.remove",rast = ["MASK","distance_mask%d" % os.getpid()])
grass.run_command("v.to.rast",
input = "point_"+str(os.getpid()),
output = "d"+str(distance)+"_"+i,
use = "univar")
grass.run_command("g.remove",
rast = tmp_map_rast,
vect = tmp_map_vect)
return 0
if __name__ == "__main__":
options, flags = grass.parser()
atexit.register(cleanup)
sys.exit(main())
_______________________________________________
grass-user mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/grass-user