[GRASS-SVN] r58039 - grass/trunk/lib/python/pygrass/modules/grid
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Oct 18 01:40:16 PDT 2013
Author: zarch
Date: 2013-10-18 01:40:16 -0700 (Fri, 18 Oct 2013)
New Revision: 58039
Modified:
grass/trunk/lib/python/pygrass/modules/grid/grid.py
Log:
Improving the isolation between processes and clean the code
Modified: grass/trunk/lib/python/pygrass/modules/grid/grid.py
===================================================================
--- grass/trunk/lib/python/pygrass/modules/grid/grid.py 2013-10-18 04:38:35 UTC (rev 58038)
+++ grass/trunk/lib/python/pygrass/modules/grid/grid.py 2013-10-18 08:40:16 UTC (rev 58039)
@@ -11,13 +11,13 @@
from grass.script.setup import write_gisrc
-from grass.pygrass.gis import Mapset, Location, make_mapset
+from grass.pygrass.gis import Mapset, Location
from grass.pygrass.gis.region import Region
from grass.pygrass.modules import Module
from grass.pygrass.functions import get_mapset_raster
-from split import split_region_tiles
-from patch import rpatch_map
+from grass.pygrass.modules.grid.split import split_region_tiles
+from grass.pygrass.modules.grid.patch import rpatch_map
def select(parms, ptype):
@@ -37,12 +37,19 @@
par = parms[k]
if par.type == ptype or par.typedesc == ptype and par.value:
if par.multiple:
- for p in par.value:
- yield p
+ for val in par.value:
+ yield val
else:
yield par.value
+def copy_special_mapset_files(path_src, path_dst):
+ """Copy all the special GRASS files that are contained in
+ a mapset to another mapset."""
+ for fil in (fi for fi in os.listdir(path_src) if fi.isupper()):
+ sht.copy(os.path.join(path_src, fil), path_dst)
+
+
def copy_mapset(mapset, path):
"""Copy mapset to another place without copying raster and vector data.
"""
@@ -54,133 +61,141 @@
os.makedirs(per_new)
if not os.path.isdir(map_new):
os.mkdir(map_new)
- for f in (fi for fi in os.listdir(per_old) if fi.isupper()):
- sht.copy(os.path.join(per_old, f), per_new)
- for f in (fi for fi in os.listdir(map_old) if fi.isupper()):
- sht.copy(os.path.join(map_old, f), map_new)
+ copy_special_mapset_files(per_old, per_new)
+ copy_special_mapset_files(map_old, map_new)
gisdbase, location = os.path.split(path)
return Mapset(mapset.name, location, gisdbase)
-def copy_groups(groups, src, dst, gisrc_dst=None, region=None):
- """Copy groupd from one mapset to another, crop the raster to the region.
+def read_gisrc(gisrc):
+ """Read a GISRC file and return a tuple with the mapset, location
+ and gisdbase.
"""
+ with open(gisrc, 'r') as gfile:
+ gis = dict([(k.strip(), v.strip())
+ for k, v in [row.split(':') for row in gfile]])
+ return gis['MAPSET'], gis['LOCATION_NAME'], gis['GISDBASE']
+
+
+def get_mapset(gisrc_src, gisrc_dst):
+ """Get mapset from a GISRC source to a GISRC destination."""
+ msrc, lsrc, gsrc = read_gisrc(gisrc_src)
+ mdst, ldst, gdst = read_gisrc(gisrc_dst)
+ path_src = os.path.join(gsrc, lsrc, msrc)
+ path_dst = os.path.join(gdst, ldst, mdst)
+ if not os.path.isdir(path_dst):
+ os.makedirs(path_dst)
+ copy_special_mapset_files(path_src, path_dst)
+ src = Mapset(msrc, lsrc, gsrc)
+ dst = Mapset(mdst, ldst, gdst)
+ dst.visible.extend(src.visible)
+ return src, dst
+
+
+def copy_groups(groups, gisrc_src, gisrc_dst, region=None):
+ """Copy group from one mapset to another, crop the raster to the region.
+ """
env = os.environ.copy()
- # set region
- if region:
- region.set_current()
# instantiate modules
get_grp = Module('i.group', flags='lg', stdout_=sub.PIPE, run_=False)
set_grp = Module('i.group')
get_grp.run_ = True
- # get and set GISRC
- gisrc_src = env['GISRC']
- gisrc_dst = gisrc_dst if gisrc_dst else write_gisrc(dst.gisdbase,
- dst.location,
- dst.name)
-
for grp in groups:
# change gisdbase to src
env['GISRC'] = gisrc_src
get_grp(group=grp, env_=env)
rasts = get_grp.outputs.stdout.split()
+ copy_rasters(rasts, gisrc_src, gisrc_dst, region=region)
# change gisdbase to dst
env['GISRC'] = gisrc_dst
- set_grp(group=grp, input=rasts, env_=env)
- return gisrc_src, gisrc_dst
+ set_grp(group=grp,
+ input=[r.split('@')[0] if '@' in r else r for r in rasts],
+ env_=env)
-def copy_rasters(rasters, src, dst, gisrc_dst=None, region=None):
+def set_region(region, gisrc_src, gisrc_dst, env):
+ """Set a region into two different mapsets."""
+ reg_str = "g.region n=%(north)r s=%(south)r " \
+ "e=%(east)r w=%(west)r " \
+ "nsres=%(nsres)r ewres=%(ewres)r"
+ reg_cmd = reg_str % dict(region.items())
+ env['GISRC'] = gisrc_src
+ sub.Popen(reg_cmd, shell=True, env=env)
+ env['GISRC'] = gisrc_dst
+ sub.Popen(reg_cmd, shell=True, env=env)
+
+
+def copy_rasters(rasters, gisrc_src, gisrc_dst, region=None):
"""Copy rasters from one mapset to another, crop the raster to the region.
"""
env = os.environ.copy()
- # set region
if region:
- region.set_current()
+ set_region(region, gisrc_src, gisrc_dst, env)
- nam = "copy%d__%s" % (id(dst), '%s')
- expr = "%s=%s"
+ path_dst = os.path.join(*read_gisrc(gisrc_dst))
+ nam = "copy%d__%s" % (id(gisrc_dst), '%s')
# instantiate modules
mpclc = Module('r.mapcalc')
rpck = Module('r.pack')
rupck = Module('r.unpack')
- rm = Module('g.remove')
+ remove = Module('g.remove')
- # get and set GISRC
- gisrc_src = env['GISRC']
- gisrc_dst = gisrc_dst if gisrc_dst else write_gisrc(dst.gisdbase,
- dst.location,
- dst.name)
-
- pdst = dst.path()
for rast in rasters:
+ rast_clean = rast.split('@')[0] if '@' in rast else rast
# change gisdbase to src
env['GISRC'] = gisrc_src
- name = nam % rast
- mpclc(expression=expr % (name, rast), overwrite=True, env_=env)
- file_dst = "%s.pack" % os.path.join(pdst, name)
+ name = nam % rast_clean
+ mpclc(expression="%s=%s" % (name, rast), overwrite=True, env_=env)
+ file_dst = "%s.pack" % os.path.join(path_dst, name)
rpck(input=name, output=file_dst, overwrite=True, env_=env)
- rm(rast=name, env_=env)
+ remove(rast=name, env_=env)
# change gisdbase to dst
env['GISRC'] = gisrc_dst
- rupck(input=file_dst, output=rast, overwrite=True, env_=env)
+ rupck(input=file_dst, output=rast_clean, overwrite=True, env_=env)
os.remove(file_dst)
- return gisrc_src, gisrc_dst
-def copy_vectors(vectors, src, dst, gisrc_dst=None, region=None):
+def copy_vectors(vectors, gisrc_src, gisrc_dst):
"""Copy vectors from one mapset to another, crop the raster to the region.
"""
env = os.environ.copy()
- # set region
- if region:
- region.set_current()
+ path_dst = os.path.join(*read_gisrc(gisrc_dst))
+ nam = "copy%d__%s" % (id(gisrc_dst), '%s')
- nam = "copy%d__%s" % (id(dst), '%s')
-
# instantiate modules
vpck = Module('v.pack')
vupck = Module('v.unpack')
- rm = Module('g.remove')
+ remove = Module('g.remove')
- # get and set GISRC
- gisrc_src = env['GISRC']
- gisrc_dst = gisrc_dst if gisrc_dst else write_gisrc(dst.gisdbase,
- dst.location,
- dst.name)
-
- pdst = dst.path()
for vect in vectors:
# change gisdbase to src
env['GISRC'] = gisrc_src
name = nam % vect
- file_dst = "%s.pack" % os.path.join(pdst, name)
+ file_dst = "%s.pack" % os.path.join(path_dst, name)
vpck(input=name, output=file_dst, overwrite=True, env_=env)
- rm(vect=name, env_=env)
+ remove(vect=name, env_=env)
# change gisdbase to dst
env['GISRC'] = gisrc_dst
vupck(input=file_dst, output=vect, overwrite=True, env_=env)
os.remove(file_dst)
- return gisrc_src, gisrc_dst
def get_cmd(cmdd):
- """Transforma a cmd dictionary to a list of parameters"""
+ """Transform a cmd dictionary to a list of parameters"""
cmd = [cmdd['name'], ]
cmd.extend(("%s=%s" % (k, v) for k, v in cmdd['inputs']
if not isinstance(v, list)))
cmd.extend(("%s=%s" % (k, ','.join(vals if isinstance(vals[0], str)
- else map(repr, vals)))
+ else [repr(v) for v in vals]))
for k, vals in cmdd['inputs']
if isinstance(vals, list)))
cmd.extend(("%s=%s" % (k, v) for k, v in cmdd['outputs']
if not isinstance(v, list)))
- cmd.extend(("%s=%s" % (k, ','.join(map(repr, vals)))
- for k, vals in cmdd['outputs']
- if isinstance(vals, list)))
+ cmd.extend(("%s=%s" % (k, ','.join([repr(v) for v in vals]))
+ for k, vals in cmdd['outputs'] if isinstance(vals, list)))
cmd.extend(("%s" % (flg) for flg in cmdd['flags'] if len(flg) == 1))
cmd.extend(("--%s" % (flg[0]) for flg in cmdd['flags'] if len(flg) > 1))
return cmd
@@ -188,16 +203,10 @@
def cmd_exe(args):
"""Create a mapset, and execute a cmd inside."""
- bbox, mapnames, msetname, cmd, groups = args
- mset = Mapset()
- try:
- make_mapset(msetname)
- except:
- pass
- ms = Mapset(msetname)
- ms.visible.extend(mset.visible)
+ bbox, mapnames, gisrc_src, gisrc_dst, cmd, groups = args
+ get_mapset(gisrc_src, gisrc_dst)
env = os.environ.copy()
- env['GISRC'] = write_gisrc(mset.gisdbase, mset.location, msetname)
+ env['GISRC'] = gisrc_dst
if mapnames:
inputs = dict(cmd['inputs'])
# reset the inputs to
@@ -207,17 +216,16 @@
# set the region to the tile
sub.Popen(['g,region', 'rast=%s' % key], env=env).wait()
else:
- #reg = Region() nsres=reg.nsres, ewres=reg.ewres,
# set the computational region
lcmd = ['g.region', ]
lcmd.extend(["%s=%s" % (k, v) for k, v in bbox.iteritems()])
sub.Popen(lcmd, env=env).wait()
if groups:
- src, dst = copy_groups(groups, mset, ms, env['GISRC'])
+ copy_groups(groups, gisrc_src, gisrc_dst)
# run the grass command
sub.Popen(get_cmd(cmd), env=env).wait()
# remove temp GISRC
- os.remove(env['GISRC'])
+ os.remove(gisrc_dst)
class GridModule(object):
@@ -270,20 +278,26 @@
self.start_row = start_row
self.start_col = start_col
self.out_prefix = out_prefix
- self.n_mset = None
- self.gisrc_src = self.gisrc_dst = None
self.log = log
self.move = move
+ self.gisrc_src = os.environ['GISRC']
+ self.n_mset, self.gisrc_dst = None, None
if self.move:
self.n_mset = copy_mapset(self.mset, self.move)
- rasters = select(self.module.inputs, 'raster')
- self.gisrc_src, self.gisrc_dst = copy_rasters(rasters,
- self.mset,
- self.n_mset,
- region=self.region)
- vectors = select(self.module.inputs, 'vector')
- copy_vectors(vectors, self.mset, self.n_mset,
- gisrc_dst=self.gisrc_dst, region=self.region)
+ self.gisrc_dst = write_gisrc(self.n_mset.gisdbase,
+ self.n_mset.location,
+ self.n_mset.name)
+ rasters = [r for r in select(self.module.inputs, 'raster')]
+ if rasters:
+ copy_rasters(rasters, self.gisrc_src, self.gisrc_dst,
+ region=self.region)
+ vectors = [v for v in select(self.module.inputs, 'vector')]
+ if vectors:
+ copy_vectors(vectors, self.gisrc_src, self.gisrc_dst)
+ groups = [g for g in select(self.module.inputs, 'group')]
+ if groups:
+ copy_groups(groups, self.gisrc_src, self.gisrc_dst,
+ region=self.region)
self.bboxes = split_region_tiles(region=region,
width=width, height=height,
@@ -294,6 +308,11 @@
self.split()
self.debug = debug
+ def __del__(self):
+ if self.gisrc_dst:
+ # remove GISRC file
+ os.remove(self.gisrc_dst)
+
def clean_location(self, location=None):
"""Remove all created mapsets."""
location = location if location else Location()
@@ -318,6 +337,10 @@
"""Return a list of tuble with the parameters for cmd_exe function"""
works = []
reg = Region()
+ if self.move:
+ mdst, ldst, gdst = read_gisrc(self.gisrc_dst)
+ else:
+ ldst, gdst = self.mset.location, self.mset.gisdbase
cmd = self.module.get_dict()
groups = [g for g in select(self.module.inputs, 'group')]
for row, box_row in enumerate(self.bboxes):
@@ -334,17 +357,20 @@
bbox = dict([(k[0], str(v)) for k, v in box.items()[:-2]])
bbox['nsres'] = '%f' % reg.nsres
bbox['ewres'] = '%f' % reg.ewres
+ new_mset = self.msetstr % (self.start_row + row,
+ self.start_col + col),
works.append((bbox, inms,
- self.msetstr % (self.start_row + row,
- self.start_col + col),
+ self.gisrc_src,
+ write_gisrc(gdst, ldst, new_mset),
cmd, groups))
return works
def define_mapset_inputs(self):
+ """Add the mapset information to the input maps
+ """
for inmap in self.module.inputs:
inm = self.module.inputs[inmap]
- # (inm.type == 'raster' or inm.typedesc == 'group') and inm.value:
- if inm.type == 'raster' and inm.value:
+ if inm.type in ('raster', 'vector') and inm.value:
if '@' not in inm.value:
mset = get_mapset_raster(inm.value)
inm.value = inm.value + '@%s' % mset
@@ -363,18 +389,20 @@
if not result.successful():
raise RuntimeError
- self.mset.current()
-
if patch:
- self.patch()
+ if self.move:
+ os.environ['GISRC'] = self.gisrc_dst
+ self.n_mset.current()
+ self.patch()
+ os.environ['GISRC'] = self.gisrc_src
+ self.mset.current()
+ # copy the outputs from dst => src
+ routputs = [self.out_prefix + o
+ for o in select(self.module.outputs, 'raster')]
+ copy_rasters(routputs, self.gisrc_dst, self.gisrc_src)
+ else:
+ self.patch()
- if self.n_mset is not None:
- # move the raster outputs to the original mapset
- routputs = [self.out_prefix + o
- for o in select(self.module.outputs, 'raster')]
- copy_rasters(routputs, self.n_mset, self.mset,
- self.gisrc_src, self.region)
-
if self.log:
# record in the temp directory
from grass.lib.gis import G_tempfile
@@ -386,12 +414,11 @@
dirpath = os.path.join(tmpdir, par.name)
if not os.path.isdir(dirpath):
os.makedirs(dirpath)
- fp = open(os.path.join(dirpath,
- self.out_prefix + par.value), 'w+')
- fp.close()
+ fil = open(os.path.join(dirpath,
+ self.out_prefix + par.value), 'w+')
+ fil.close()
if clean:
- self.mset.current()
self.clean_location()
self.rm_tiles()
if self.n_mset:
@@ -405,7 +432,6 @@
def patch(self):
"""Patch the final results."""
- # patch all the outputs
bboxes = split_region_tiles(width=self.width, height=self.height)
for otmap in self.module.outputs:
otm = self.module.outputs[otmap]
More information about the grass-commit
mailing list