<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://grasswiki.osgeo.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%E2%9A%A0%EF%B8%8FPietro</id>
	<title>GRASS-Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://grasswiki.osgeo.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%E2%9A%A0%EF%B8%8FPietro"/>
	<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/wiki/Special:Contributions/%E2%9A%A0%EF%B8%8FPietro"/>
	<updated>2026-05-25T17:59:25Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Working_with_GRASS_without_starting_it_explicitly&amp;diff=25201</id>
		<title>Working with GRASS without starting it explicitly</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Working_with_GRASS_without_starting_it_explicitly&amp;diff=25201"/>
		<updated>2018-04-03T13:26:37Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: Add ctypes examples using grass-session&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GRASS GIS modules and the import of GRASS Python packages works only in a specific environmental settings (GRASS session). This settings is ensured by starting GRASS GIS application which prepares this GRASS session for you. It is possible to set up you system in the way that the GRASS session will be always active (i.e. the GRASS startup script is not running, just the environmental settings are done). People often prefer to set up the GRASS environment in their script or program and this is what this article discuss. However, it must be noted that the the generally preferred (and easy) way is to create scripts and programs as GRASS modules which means that your don't have to bother with setting up the environment since the GRASS module should be always invoked only in GRASS session.&lt;br /&gt;
&lt;br /&gt;
== GRASS sessions ==&lt;br /&gt;
&lt;br /&gt;
It is possible to access GRASS modules without explicitly starting a &amp;quot;GRASS session&amp;quot;. GRASS libraries require certain [http://grass.osgeo.org/grass72/manuals/variables.html environment variables] to be set. In fact a &amp;quot;GRASS session&amp;quot; is just a set of processes (e.g. a shell and/or GUI) which have the necessary environment settings, specifically:&lt;br /&gt;
&lt;br /&gt;
* '''GISBASE''' needs to be set to the top-level directory of the GRASS installation.&lt;br /&gt;
* '''GISRC''' needs to contain the absolute path to a file containing settings for '''GISDBASE''', '''LOCATION_NAME''' and '''MAPSET'''.&lt;br /&gt;
* '''PATH''' needs to include '''$GISBASE/bin''' and '''$GISBASE/scripts'''.&lt;br /&gt;
&lt;br /&gt;
If the GRASS libraries are shared libraries, the loader needs to be able to find them. This normally means that '''LD_LIBRARY_PATH''' (Linux, Solaris), '''DYLD_LIBRARY_PATH''' (MacOSX) or '''PATH''' (Windows) need to contain '''$GISBASE/lib''', although there are other means to the same end (e.g. on Linux, putting $GISBASE/lib (with $GISBASE replaced by its actual value) into /etc/ld.so.conf then running ldconfig).&lt;br /&gt;
&lt;br /&gt;
Some libraries and modules use other variables. More information for most of them is available in the file ''$GISBASE/docs/html/variables.html''. The display libraries used by ''d.*'' commands use additional variables, which are documented along with the individual drivers.&lt;br /&gt;
&lt;br /&gt;
=== Batch jobs ===&lt;br /&gt;
&lt;br /&gt;
You can run GRASS scripts non-interactively from outside of a GRASS session with the GRASS_BATCH_JOB environment variable. When GRASS is started with this environment variable set it will automatically run the contents of the script given in the variable, then close the GRASS session when complete. In this way full lock-checking, GRASS variables setup, and temporary file cleaning tasks are still performed.&lt;br /&gt;
&lt;br /&gt;
See the [[GRASS_and_Shell#GRASS_Batch_jobs|Batch jobs]] section of the GRASS shell-help wiki page for details.&lt;br /&gt;
&lt;br /&gt;
=== Starting a GRASS session and terminating it automatically ===&lt;br /&gt;
&lt;br /&gt;
A GRASS session can be started and terminated automatically with the -e flag.&lt;br /&gt;
&lt;br /&gt;
Since GRASS GIS 7.2.x you can execute commands from outside by passing the command to be executed (or a script with a collection of GRASS GIS commands) to the --exec flag:&lt;br /&gt;
&lt;br /&gt;
Creating a new Location based on a geodata file's projection (-c) and exit (-e) immediately:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 -c elevation.tiff -e /path/to/grassdata/test1/&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Linking external raster data to PERMANENT Mapset:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ -e --exec r.external input=basins.tiff output=basins&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ -e --exec r.external input=elevation.tiff output=elevation&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get statistics for one raster map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ -e --exec r.univar map=elevation&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Start a GRASS session but do not terminate it automatically ====&lt;br /&gt;
&lt;br /&gt;
Compare the rasters visually:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ --exec g.gui.mapswipe first=elevation second=basins&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read more in the [https://grass.osgeo.org/grass72/manuals/grass7.html#batch-jobs-with-the-exec-interface manual].&lt;br /&gt;
&lt;br /&gt;
==== Python examples ====&lt;br /&gt;
&lt;br /&gt;
For details on GRASS GIS Python programming, see also [[GRASS Python Scripting Library]].&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 with an external library: grass-session =====&lt;br /&gt;
&lt;br /&gt;
The [https://github.com/zarch/grass-session &amp;quot;grass-session&amp;quot; Python library] is under development. To contribute at the code, documentation and testing it is possible to install the current version with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pip install grass-session&lt;br /&gt;
# for the latest development version use:&lt;br /&gt;
# pip install git+https://github.com/zarch/grass-session.git&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then write &lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# filename: test_session.py&lt;br /&gt;
&lt;br /&gt;
from grass_session import Session&lt;br /&gt;
from grass.script import core as gcore&lt;br /&gt;
&lt;br /&gt;
# create a new location from EPSG code (can also be a GeoTIFF or SHP or ... file)&lt;br /&gt;
with Session(gisdb=&amp;quot;/tmp&amp;quot;, location=&amp;quot;location&amp;quot;,&lt;br /&gt;
             create_opts=&amp;quot;EPSG:4326&amp;quot;):&lt;br /&gt;
   # do something in permanent&lt;br /&gt;
   print(gcore.parse_command(&amp;quot;g.gisenv&amp;quot;, flags=&amp;quot;s&amp;quot;))&lt;br /&gt;
# {u'GISDBASE': u&amp;quot;'/tmp/';&amp;quot;,&lt;br /&gt;
#  u'LOCATION_NAME': u&amp;quot;'epsg3035';&amp;quot;,&lt;br /&gt;
#  u'MAPSET': u&amp;quot;'PERMANENT';&amp;quot;,}&lt;br /&gt;
&lt;br /&gt;
# create a new mapset in an existing location&lt;br /&gt;
with Session(gisdb=&amp;quot;/tmp&amp;quot;, location=&amp;quot;location&amp;quot;, mapset=&amp;quot;test&amp;quot;,&lt;br /&gt;
             create_opts=&amp;quot;&amp;quot;):&lt;br /&gt;
    # do something in the test mapset.&lt;br /&gt;
    print(gcore.parse_command(&amp;quot;g.gisenv&amp;quot;, flags=&amp;quot;s&amp;quot;))&lt;br /&gt;
# {u'GISDBASE': u&amp;quot;'/tmp/';&amp;quot;,&lt;br /&gt;
#  u'LOCATION_NAME': u&amp;quot;'epsg3035';&amp;quot;,&lt;br /&gt;
#  u'MAPSET': u&amp;quot;'test';&amp;quot;,}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The grass-session library looks at the &amp;lt;tt&amp;gt;GRASSBIN&amp;lt;/tt&amp;gt; environmental variable. If the variable is not set, the library tries to use the current stable release of GRASS GIS (e.g. &amp;lt;tt&amp;gt;grass74&amp;lt;/tt&amp;gt; on Linux for the 7.4 release).&lt;br /&gt;
For instance, to execute the previous example using a custom installation of 7.5 version, write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
GRASSBIN=$HOME/bin/grass75 python test_session.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you need to use python libraries that are using ctypes, like for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# file: test_session_ctypes.py&lt;br /&gt;
import grass_session&lt;br /&gt;
from grass.pygrass.vector import VectorTopo&lt;br /&gt;
&lt;br /&gt;
print('DONE!')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above script will raise an exception because is not possible to dynamically import the linked library in the same process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ GRASSBIN=/home/pietro/.local/bin/grass75 python test.py &lt;br /&gt;
GRASSBIN: /home/pietro/.local/bin/grass75&lt;br /&gt;
GISBASE: /home/pietro/.local/grass-7.5.svn&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;test.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;br /&gt;
    from grass.pygrass.vector import VectorTopo&lt;br /&gt;
  File &amp;quot;/home/pietro/.local/grass-7.5.svn/etc/python/grass/pygrass/vector/__init__.py&amp;quot;, line 5, in &amp;lt;module&amp;gt;&lt;br /&gt;
    import grass.lib.gis as libgis&lt;br /&gt;
  File &amp;quot;/home/pietro/.local/grass-7.5.svn/etc/python/grass/lib/gis.py&amp;quot;, line 23, in &amp;lt;module&amp;gt;&lt;br /&gt;
    _libs[&amp;quot;grass_gis.7.5.svn&amp;quot;] = load_library(&amp;quot;grass_gis.7.5.svn&amp;quot;)&lt;br /&gt;
  File &amp;quot;/home/pietro/.local/grass-7.5.svn/etc/python/grass/lib/ctypes_loader.py&amp;quot;, line 62, in load_library&lt;br /&gt;
    return self.load(path)&lt;br /&gt;
  File &amp;quot;/home/pietro/.local/grass-7.5.svn/etc/python/grass/lib/ctypes_loader.py&amp;quot;, line 78, in load&lt;br /&gt;
    raise ImportError(e)&lt;br /&gt;
ImportError: libgrass_datetime.7.5.svn.so: cannot open shared object file: No such file or directory&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But you can set the &amp;lt;tt&amp;gt;LD_LIBRARY_PATH&amp;lt;/tt&amp;gt; variable before launching the program. For instance from the command line you can define:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ LD_LIBRARY_PATH=/home/pietro/.local/grass-7.5.svn/lib \&lt;br /&gt;
   GRASSBIN=/home/pietro/.local/bin/grass75 \&lt;br /&gt;
   python test_session_ctypes.py&lt;br /&gt;
GRASSBIN: /home/pietro/.local/bin/grass75&lt;br /&gt;
GISBASE: /home/pietro/.local/grass-7.5.svn&lt;br /&gt;
DONE!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The use of the &amp;lt;tt&amp;gt;with-statement&amp;lt;/tt&amp;gt; close automatically the session.&lt;br /&gt;
If you have to manage more complex workflow you can manually define the opening and closing actions.&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
# import grass_session&lt;br /&gt;
from grass_session import Session&lt;br /&gt;
&lt;br /&gt;
# import grass python libraries&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# set some common environmental variables, like:&lt;br /&gt;
os.environ.update(dict(GRASS_COMPRESS_NULLS='1',&lt;br /&gt;
                       GRASS_COMPRESSOR='ZSTD'))&lt;br /&gt;
&lt;br /&gt;
# create a PERMANENT mapset&lt;br /&gt;
# create a Session instance&lt;br /&gt;
PERMANENT = Session()&lt;br /&gt;
PERMANENT.open(gisdb='/tmp', location='mytest',&lt;br /&gt;
               create_opts='EPSG:4326')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# execute some command inside PERMANENT&lt;br /&gt;
g.mapsets(flags=&amp;quot;l&amp;quot;)&lt;br /&gt;
g.list(type=&amp;quot;raster&amp;quot;, flags=&amp;quot;m&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# exit from PERMANENT&lt;br /&gt;
PERMANENT.close()&lt;br /&gt;
&lt;br /&gt;
# create a new mapset in the same location&lt;br /&gt;
user = Session()&lt;br /&gt;
user.open(gisdb='/tmp', location='mytest', mapset='user',&lt;br /&gt;
               create_opts='')&lt;br /&gt;
&lt;br /&gt;
# execute some command inside user&lt;br /&gt;
g.mapsets(flags=&amp;quot;l&amp;quot;)&lt;br /&gt;
g.list(type=&amp;quot;raster&amp;quot;, flags=&amp;quot;m&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# exit from user&lt;br /&gt;
user.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Hint: find the path to the GRASS GIS package start script =====&lt;br /&gt;
&lt;br /&gt;
Hint: in order to find the '''path to the GRASS GIS package''', launch it with &amp;lt;tt&amp;gt; --config path&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Linux&lt;br /&gt;
grass72 --config path&lt;br /&gt;
/usr/bin/grass-7.2.0&lt;br /&gt;
&lt;br /&gt;
# Windows&lt;br /&gt;
C:\&amp;gt;grass72.bat --config path&lt;br /&gt;
C:\OSGeo4W\apps\grass\grass-7.2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 with existing location =====&lt;br /&gt;
&lt;br /&gt;
See the example in the [https://grass.osgeo.org/grass72/manuals/libpython/script.html#module-script.setup documentation] or the script which initializes the session and lists available raster and vector maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import subprocess&lt;br /&gt;
&lt;br /&gt;
# path to the GRASS GIS launch script&lt;br /&gt;
# MS Windows&lt;br /&gt;
grass7bin_win = r'C:\OSGeo4W\bin\grass72svn.bat'&lt;br /&gt;
# uncomment when using standalone WinGRASS installer&lt;br /&gt;
# grass7bin_win = r'C:\Program Files (x86)\GRASS GIS 7.2.0\grass72.bat'&lt;br /&gt;
# Linux&lt;br /&gt;
grass7bin_lin = 'grass72'&lt;br /&gt;
# Mac OS X&lt;br /&gt;
# this is TODO&lt;br /&gt;
grass7bin_mac = '/Applications/GRASS/GRASS-7.2.app/'&lt;br /&gt;
&lt;br /&gt;
# DATA&lt;br /&gt;
# define GRASS DATABASE&lt;br /&gt;
# add your path to grassdata (GRASS GIS database) directory&lt;br /&gt;
gisdb = os.path.join(os.path.expanduser(&amp;quot;~&amp;quot;), &amp;quot;grassdata&amp;quot;)&lt;br /&gt;
# the following path is the default path on MS Windows&lt;br /&gt;
# gisdb = os.path.join(os.path.expanduser(&amp;quot;~&amp;quot;), &amp;quot;Documents/grassdata&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# specify (existing) location and mapset&lt;br /&gt;
location = &amp;quot;nc_spm_08&amp;quot;&lt;br /&gt;
mapset   = &amp;quot;user1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
########### SOFTWARE&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
    # we assume that the GRASS GIS start script is available and in the PATH&lt;br /&gt;
    # query GRASS 7 itself for its GISBASE&lt;br /&gt;
    grass7bin = grass7bin_lin&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    grass7bin = grass7bin_win&lt;br /&gt;
else:&lt;br /&gt;
    raise OSError('Platform not configured.')&lt;br /&gt;
&lt;br /&gt;
# query GRASS 7 itself for its GISBASE&lt;br /&gt;
startcmd = [grass7bin, '--config', 'path']&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=False,&lt;br /&gt;
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, &amp;quot;ERROR: Cannot find GRASS GIS 7 start script (%s)&amp;quot; % startcmd&lt;br /&gt;
    sys.exit(-1)&lt;br /&gt;
gisbase = out.strip('\n\r')&lt;br /&gt;
&lt;br /&gt;
# Set GISBASE environment variable&lt;br /&gt;
os.environ['GISBASE'] = gisbase&lt;br /&gt;
# the following not needed with trunk&lt;br /&gt;
os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'extrabin')&lt;br /&gt;
# add path to GRASS addons&lt;br /&gt;
home = os.path.expanduser(&amp;quot;~&amp;quot;)&lt;br /&gt;
os.environ['PATH'] += os.pathsep + os.path.join(home, '.grass7', 'addons', 'scripts')&lt;br /&gt;
&lt;br /&gt;
# define GRASS-Python environment&lt;br /&gt;
gpydir = os.path.join(gisbase, &amp;quot;etc&amp;quot;, &amp;quot;python&amp;quot;)&lt;br /&gt;
sys.path.append(gpydir)&lt;br /&gt;
&lt;br /&gt;
########### DATA&lt;br /&gt;
# Set GISDBASE environment variable&lt;br /&gt;
os.environ['GISDBASE'] = gisdb&lt;br /&gt;
 &lt;br /&gt;
# import GRASS Python bindings (see also pygrass)&lt;br /&gt;
import grass.script as gscript&lt;br /&gt;
import grass.script.setup as gsetup&lt;br /&gt;
 &lt;br /&gt;
###########&lt;br /&gt;
# launch session&lt;br /&gt;
gsetup.init(gisbase,&lt;br /&gt;
            gisdb, location, mapset)&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Current GRASS GIS 7 environment:')&lt;br /&gt;
print gscript.gisenv()&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Available raster maps:')&lt;br /&gt;
for rast in gscript.list_strings(type = 'rast'):&lt;br /&gt;
    print rast&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Available vector maps:')&lt;br /&gt;
for vect in gscript.list_strings(type = 'vect'):&lt;br /&gt;
    print vect&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 without existing location using metadata only =====&lt;br /&gt;
&lt;br /&gt;
The script initializes the GRASS GIS session, creates a temporary GRASS location and lists available raster and vector maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
# Python script to generate a new GRASS GIS 7 location simply from metadata&lt;br /&gt;
# Markus Neteler, 2014&lt;br /&gt;
&lt;br /&gt;
# ?? LINUX USAGE: First set LIBRARY SEARCH PATH&lt;br /&gt;
#export LD_LIBRARY_PATH=$(grass72 --config path)/lib&lt;br /&gt;
#python start_grass7_create_new_location_ADVANCED.py&lt;br /&gt;
&lt;br /&gt;
# some predefined variables&lt;br /&gt;
&lt;br /&gt;
# Windows&lt;br /&gt;
grass7path = r'C:\OSGeo4W\apps\grass\grass-7.2.svn'&lt;br /&gt;
grass7bin_win = r'C:\OSGeo4W\bin\grass72svn.bat'&lt;br /&gt;
# Linux&lt;br /&gt;
grass7bin_lin = 'grass72'&lt;br /&gt;
# MacOSX&lt;br /&gt;
grass7bin_mac = '/Applications/GRASS/GRASS-7.1.app/'&lt;br /&gt;
#myepsg = '4326' # latlong&lt;br /&gt;
myepsg = '3044' # ETRS-TM32, http://spatialreference.org/ref/epsg/3044/&lt;br /&gt;
#myfile = '/home/neteler/markus_repo/books/kluwerbook/data3rd/lidar/lidar_raleigh_nc_spm.shp'&lt;br /&gt;
myfile = '/data/maps/world_natural_earth_250m/europe_north_east.tif'&lt;br /&gt;
#myfile = r'C:\Dati\Padergnone\square_p95.tif'&lt;br /&gt;
&lt;br /&gt;
###########&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import subprocess&lt;br /&gt;
import shutil&lt;br /&gt;
import binascii&lt;br /&gt;
import tempfile&lt;br /&gt;
&lt;br /&gt;
########### SOFTWARE&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
    # we assume that the GRASS GIS start script is available and in the PATH&lt;br /&gt;
    # query GRASS 7 itself for its GISBASE&lt;br /&gt;
    grass7bin = grass7bin_lin&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    grass7bin = grass7bin_win&lt;br /&gt;
else:&lt;br /&gt;
    OSError('Platform not configured.')&lt;br /&gt;
&lt;br /&gt;
startcmd = grass7bin + ' --config path'&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=True, &lt;br /&gt;
					 stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
	print &amp;gt;&amp;gt;sys.stderr, 'ERROR: %s' % err&lt;br /&gt;
	print &amp;gt;&amp;gt;sys.stderr, &amp;quot;ERROR: Cannot find GRASS GIS 7 start script (%s)&amp;quot; % startcmd&lt;br /&gt;
	sys.exit(-1)&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
	gisbase = out.strip('\n')&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    if out.find(&amp;quot;OSGEO4W home is&amp;quot;) != -1:&lt;br /&gt;
		gisbase = out.strip().split('\n')[1]&lt;br /&gt;
    else:&lt;br /&gt;
		gisbase = out.strip('\n')&lt;br /&gt;
    os.environ['GRASS_SH'] = os.path.join(gisbase, 'msys', 'bin', 'sh.exe')&lt;br /&gt;
&lt;br /&gt;
# Set GISBASE environment variable&lt;br /&gt;
os.environ['GISBASE'] = gisbase&lt;br /&gt;
# define GRASS-Python environment&lt;br /&gt;
gpydir = os.path.join(gisbase, &amp;quot;etc&amp;quot;, &amp;quot;python&amp;quot;)&lt;br /&gt;
sys.path.append(gpydir)&lt;br /&gt;
########&lt;br /&gt;
# define GRASS DATABASE&lt;br /&gt;
if sys.platform.startswith('win'):&lt;br /&gt;
    gisdb = os.path.join(os.getenv('APPDATA', 'grassdata'))&lt;br /&gt;
else:&lt;br /&gt;
    gisdb = os.path.join(os.getenv('HOME', 'grassdata'))&lt;br /&gt;
&lt;br /&gt;
# override for now with TEMP dir&lt;br /&gt;
gisdb = os.path.join(tempfile.gettempdir(), 'grassdata')&lt;br /&gt;
try:&lt;br /&gt;
    os.stat(gisdb)&lt;br /&gt;
except:&lt;br /&gt;
    os.mkdir(gisdb)&lt;br /&gt;
&lt;br /&gt;
# location/mapset: use random names for batch jobs&lt;br /&gt;
string_length = 16&lt;br /&gt;
location = binascii.hexlify(os.urandom(string_length))&lt;br /&gt;
mapset   = 'PERMANENT'&lt;br /&gt;
location_path = os.path.join(gisdb, location)&lt;br /&gt;
&lt;br /&gt;
# Create new location (we assume that grass7bin is in the PATH)&lt;br /&gt;
#  from EPSG code:&lt;br /&gt;
startcmd = grass7bin + ' -c epsg:' + myepsg + ' -e ' + location_path&lt;br /&gt;
#  from SHAPE or GeoTIFF file&lt;br /&gt;
#startcmd = grass7bin + ' -c ' + myfile + ' -e ' + location_path&lt;br /&gt;
&lt;br /&gt;
print startcmd&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=True, &lt;br /&gt;
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, 'ERROR: %s' % err&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, 'ERROR: Cannot generate location (%s)' % startcmd&lt;br /&gt;
    sys.exit(-1)&lt;br /&gt;
else:&lt;br /&gt;
    print 'Created location %s' % location_path&lt;br /&gt;
&lt;br /&gt;
# Now the location with PERMANENT mapset exists.&lt;br /&gt;
&lt;br /&gt;
########&lt;br /&gt;
# Now we can use PyGRASS or GRASS Scripting library etc. after &lt;br /&gt;
# having started the session with gsetup.init() etc&lt;br /&gt;
&lt;br /&gt;
# Set GISDBASE environment variable&lt;br /&gt;
os.environ['GISDBASE'] = gisdb&lt;br /&gt;
&lt;br /&gt;
# Linux: Set path to GRASS libs (TODO: NEEDED?)&lt;br /&gt;
path = os.getenv('LD_LIBRARY_PATH')&lt;br /&gt;
dir  = os.path.join(gisbase, 'lib')&lt;br /&gt;
if path:&lt;br /&gt;
    path = dir + os.pathsep + path&lt;br /&gt;
else:&lt;br /&gt;
    path = dir&lt;br /&gt;
os.environ['LD_LIBRARY_PATH'] = path&lt;br /&gt;
&lt;br /&gt;
# language&lt;br /&gt;
os.environ['LANG'] = 'en_US'&lt;br /&gt;
os.environ['LOCALE'] = 'C'&lt;br /&gt;
&lt;br /&gt;
# Windows: NEEDED?&lt;br /&gt;
#path = os.getenv('PYTHONPATH')&lt;br /&gt;
#dirr = os.path.join(gisbase, 'etc', 'python')&lt;br /&gt;
#if path:&lt;br /&gt;
#    path = dirr + os.pathsep + path&lt;br /&gt;
#else:&lt;br /&gt;
#    path = dirr&lt;br /&gt;
#os.environ['PYTHONPATH'] = path&lt;br /&gt;
&lt;br /&gt;
#print os.environ&lt;br /&gt;
&lt;br /&gt;
## Import GRASS Python bindings&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
import grass.script.setup as gsetup&lt;br /&gt;
&lt;br /&gt;
###########&lt;br /&gt;
# Launch session and do something&lt;br /&gt;
gsetup.init(gisbase, gisdb, location, mapset)&lt;br /&gt;
&lt;br /&gt;
# say hello&lt;br /&gt;
grass.message('--- GRASS GIS 7: Current GRASS GIS 7 environment:')&lt;br /&gt;
print grass.gisenv()&lt;br /&gt;
&lt;br /&gt;
# do something in GRASS now...&lt;br /&gt;
&lt;br /&gt;
grass.message('--- GRASS GIS 7: Checking projection info:')&lt;br /&gt;
in_proj = grass.read_command('g.proj', flags = 'jf')&lt;br /&gt;
&lt;br /&gt;
# selective proj parameter printing&lt;br /&gt;
kv = grass.parse_key_val(in_proj)&lt;br /&gt;
print kv&lt;br /&gt;
print kv['+proj']&lt;br /&gt;
&lt;br /&gt;
# print full proj parameter printing&lt;br /&gt;
in_proj = in_proj.strip()&lt;br /&gt;
grass.message(&amp;quot;--- Found projection parameters: '%s'&amp;quot; % in_proj)&lt;br /&gt;
&lt;br /&gt;
# show current region:&lt;br /&gt;
grass.message('--- GRASS GIS 7: Checking computational region info:')&lt;br /&gt;
in_region = grass.region()&lt;br /&gt;
grass.message(&amp;quot;--- Computational region: '%s'&amp;quot; % in_region)&lt;br /&gt;
&lt;br /&gt;
# do something else: r.mapcalc, v.rectify, ...&lt;br /&gt;
&lt;br /&gt;
# Finally remove the temporary batch location from disk&lt;br /&gt;
print 'Removing location %s' % location_path&lt;br /&gt;
shutil.rmtree(location_path)&lt;br /&gt;
&lt;br /&gt;
sys.exit(0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Bash examples (GNU/Linux) ====&lt;br /&gt;
&lt;br /&gt;
'''''Note: see [[GRASS_and_Shell#GRASS_Batch_jobs|GRASS Batch jobs]] for a really easy approach.'''''&lt;br /&gt;
&lt;br /&gt;
Below an example of a '''~/.bash_profile''' script to set the required settings in order to access GRASS commands outside of a GRASS GIS session&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
export GISBASE=/usr/local/grass-7.2.svn&lt;br /&gt;
export GRASS_VERSION=&amp;quot;7.2.svn&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#generate GISRCRC&lt;br /&gt;
MYGISDBASE=$HOME/grassdata&lt;br /&gt;
MYLOC=nc_spm_08_grass7&lt;br /&gt;
MYMAPSET=user1&lt;br /&gt;
&lt;br /&gt;
# Set the global grassrc file to individual file name&lt;br /&gt;
MYGISRC=&amp;quot;$HOME/.grassrc.$GRASS_VERSION.$$&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;GISDBASE: $MYGISDBASE&amp;quot; &amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;LOCATION_NAME: $MYLOC&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;MAPSET: $MYMAPSET&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;GRASS_GUI: text&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# path to GRASS settings file&lt;br /&gt;
export GISRC=$MYGISRC&lt;br /&gt;
export GRASS_PYTHON=python&lt;br /&gt;
export GRASS_MESSAGE_FORMAT=plain&lt;br /&gt;
export GRASS_TRUECOLOR=TRUE&lt;br /&gt;
export GRASS_TRANSPARENT=TRUE&lt;br /&gt;
export GRASS_PNG_AUTO_WRITE=TRUE&lt;br /&gt;
export GRASS_GNUPLOT='gnuplot -persist'&lt;br /&gt;
export GRASS_WIDTH=640&lt;br /&gt;
export GRASS_HEIGHT=480&lt;br /&gt;
export GRASS_HTML_BROWSER=firefox&lt;br /&gt;
export GRASS_PAGER=cat&lt;br /&gt;
&lt;br /&gt;
#For the temporal modules&lt;br /&gt;
export TGISDB_DRIVER=sqlite&lt;br /&gt;
export TGISDB_DATABASE=$MYGISDBASE/$MYLOC/PERMANENT/tgis/sqlite.db&lt;br /&gt;
&lt;br /&gt;
# for fun, we can even set the shell prompt to contain a hint on GRASS GIS env being active&lt;br /&gt;
export PS1=&amp;quot;[\u@\h \W G-$GRASS_VERSION]$ &amp;quot;&lt;br /&gt;
&lt;br /&gt;
# system vars&lt;br /&gt;
export PATH=&amp;quot;$GISBASE/bin:$GISBASE/scripts:$PATH&amp;quot;&lt;br /&gt;
export LD_LIBRARY_PATH=&amp;quot;$GISBASE/lib&amp;quot;&lt;br /&gt;
export GRASS_LD_LIBRARY_PATH=&amp;quot;$LD_LIBRARY_PATH&amp;quot;&lt;br /&gt;
export PYTHONPATH=&amp;quot;$GISBASE/etc/python:$PYTHONPATH&amp;quot;&lt;br /&gt;
export MANPATH=$MANPATH:$GISBASE/man&lt;br /&gt;
&lt;br /&gt;
# test a command&lt;br /&gt;
g.list rast&lt;br /&gt;
v.info zipcodes_wake&lt;br /&gt;
&lt;br /&gt;
######### below not needed ########&lt;br /&gt;
# GRASS 7&lt;br /&gt;
tmp=/tmp/grass7-&amp;quot;`whoami`&amp;quot;-$GIS_LOCK&lt;br /&gt;
&lt;br /&gt;
export GISRC=&amp;quot;$tmp/rc&amp;quot;&lt;br /&gt;
mkdir &amp;quot;$tmp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
cp $HOME/.grass7/rc &amp;quot;$GISRC&amp;quot;&lt;br /&gt;
&lt;br /&gt;
######### END below not needed ########&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above script will allow GRASS commands to be used anywhere. Furthermore, if the '''~/.Xsession''' sources the bash startup scripts, the settings aren't limited to interactive shells, but also work for e.g. M-! in XEmacs). Each interactive shell gets a separate &amp;quot;session&amp;quot; (i.e. a separate $GISRC file), while GUI programs share a common session.&lt;br /&gt;
&lt;br /&gt;
Note, however, that '''~/.bash_profile''' is a personal initialization startup script and, thus, read during the login process. Any modifications to it will be read after (re-)login or explicitly sourcing it.&lt;br /&gt;
&lt;br /&gt;
At the end of the ~/.bash_profile file, the following lines can be added to ensure no duplication of entries in the PATH variable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 PATH=`awk -F: '{for(i=1;i&amp;lt;=NF;i++){if(!($i in a)){a[$i];printf s$i;s=&amp;quot;:&amp;quot;}}}'&amp;lt;&amp;lt;&amp;lt;$PATH`&lt;br /&gt;
 PYTHONPATH=`awk -F: '{for(i=1;i&amp;lt;=NF;i++){if(!($i in a)){a[$i];printf s$i;s=&amp;quot;:&amp;quot;}}}'&amp;lt;&amp;lt;&amp;lt;$PYTHONPATH`&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Important notes ===&lt;br /&gt;
&lt;br /&gt;
Launching a grassXY session could still permit access on GRASS modules of the version that is set with the above script. The reason being is that grassXY scripts (e.g.: grass64, grass65, grass72) prepend the GRASS directories to '''PATH''', '''LD_LIBRARY_PATH''', etc. They won't remove any entries which are already there. A solution to this is to ''switch'' between GRASS versions by using a script like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
        strippath()&lt;br /&gt;
        {&lt;br /&gt;
            (&lt;br /&gt;
            oldpath=&amp;quot;$1&amp;quot;&lt;br /&gt;
            newpath=&lt;br /&gt;
            IFS=:&lt;br /&gt;
            for dir in $oldpath ; do&lt;br /&gt;
                case &amp;quot;${dir}&amp;quot; in&lt;br /&gt;
                *grass*)&lt;br /&gt;
                        ;;&lt;br /&gt;
                *)&lt;br /&gt;
                        newpath=&amp;quot;$newpath:$dir&amp;quot;&lt;br /&gt;
                        ;;&lt;br /&gt;
                esac&lt;br /&gt;
            done&lt;br /&gt;
            echo &amp;quot;${newpath#:}&amp;quot;&lt;br /&gt;
            )&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        PATH=`strippath $PATH`&lt;br /&gt;
        &lt;br /&gt;
        export GISBASE=$PWD/dist.i686-pc-linux-gnu&lt;br /&gt;
        export PATH=&amp;quot;$GISBASE/bin:$GISBASE/scripts:$PATH&amp;quot;&lt;br /&gt;
        export LD_LIBRARY_PATH=&amp;quot;$GISBASE/lib&amp;quot;&lt;br /&gt;
        export PYTHONPATH=&amp;quot;$GISBASE/etc/python&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note: the above script needs to be &amp;quot;source&amp;quot;d; executing it won't work. It might also require some adjustments (e.g. the ''GISBASE'' variable).'''&lt;br /&gt;
&lt;br /&gt;
Using normal grass sessions commands are recorded in '''$GISDBASE/$LOCATION_NAME/$MAPSET/.bash_history'''. While working with &amp;quot;pure&amp;quot; bash, shell entries go in '''~/.bash_history'''. Merging existing &amp;quot;grass-bash_history(-ies)&amp;quot; with the bash history log, would probably be not a good idea. Perhaps it is wise(r) to use normal GRASS sessions when working on real projects. Nevertheless, it is upon the users preferences and expertise level to decide what is best.&lt;br /&gt;
&lt;br /&gt;
=== Hints and troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
Some hints for MS Windows users:&lt;br /&gt;
&lt;br /&gt;
# The Python interpreter (python.exe) needs to be in the PATH&lt;br /&gt;
# Python needs to be associated with the .py extension&lt;br /&gt;
# PATHEXT needs to include .py if you want to be able to omit the extension&lt;br /&gt;
&lt;br /&gt;
When everything works well, the installer should take care of all of these.&lt;br /&gt;
&lt;br /&gt;
To manage parallel sessions on Linux, use process ID (PID) as lock file number and set the GIS_LOCK variable, for example&lt;br /&gt;
&lt;br /&gt;
  export GIS_LOCK=$$&lt;br /&gt;
&lt;br /&gt;
in Bash.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* Instructions and discussion on [http://n2.nabble.com/can-I-access-mapset-outside-of-grass-by-using-python-td3405902.html#a3405902 how to access GRASS mapsets outside of a GRASS session] in the grass-user mailing list.&lt;br /&gt;
* removing duplicate entries in $PATH taken from [http://chunchung.blogspot.com/2007/11/remove-duplicate-paths-from-path-in.html]&lt;br /&gt;
&lt;br /&gt;
== GRASS databases ==&lt;br /&gt;
&lt;br /&gt;
(project file structure)&lt;br /&gt;
&lt;br /&gt;
=== Minimal mapsets ===&lt;br /&gt;
&lt;br /&gt;
within a functional LOCATION (see below) the minimal mapset is a subdirectory of the MAPSET's name, containing a WIND file. The WIND file can simply be copied from PERMANENT/DEFAULT_WIND. Optionally you can put a VAR file in there too to define the default database driver to use.&lt;br /&gt;
&lt;br /&gt;
* You can create a new mapset when starting GRASS with the -c flag. e.g.&lt;br /&gt;
 grass64 -c /path/to/location/new_mapset_name&lt;br /&gt;
&lt;br /&gt;
=== Minimal locations ===&lt;br /&gt;
&lt;br /&gt;
Within the GISDATABASE (which is simply a subdirectory some where), the minimum LOCATION consists of a directory giving the LOCATION its name, which in turn contains a PERMANENT subdirectory for the PERMANENT mapset. The PERMANENT mapset contains a few special files that regular mapsets don't. These are:&lt;br /&gt;
; PROJ_INFO: contains the location's projection information&lt;br /&gt;
; PROJ_UNITS: contains the location's map units definition&lt;br /&gt;
; DEFAULT_WIND: the default region (WINDow file). The format is identical to the WIND files created by g.region&lt;br /&gt;
; WIND: (optional?)&lt;br /&gt;
&lt;br /&gt;
* see also {{src|demolocation}} in the GRASS source code&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[GRASS_and_Shell#GRASS_Batch_jobs|GRASS Batch jobs]]&lt;br /&gt;
&lt;br /&gt;
[[Category: FAQ]]&lt;br /&gt;
[[Category: Linking to other languages]]&lt;br /&gt;
[[Category: bash]]&lt;br /&gt;
[[Category:Scripting]]&lt;br /&gt;
[[Category: Python]]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Working_with_GRASS_without_starting_it_explicitly&amp;diff=25157</id>
		<title>Working with GRASS without starting it explicitly</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Working_with_GRASS_without_starting_it_explicitly&amp;diff=25157"/>
		<updated>2018-03-23T14:07:37Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Python: GRASS GIS 7 with an external library: grass-session */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GRASS GIS modules and the import of GRASS Python packages works only in a specific environmental settings (GRASS session). This settings is ensured by starting GRASS GIS application which prepares this GRASS session for you. It is possible to set up you system in the way that the GRASS session will be always active (i.e. the GRASS startup script is not running, just the environmental settings are done). People often prefer to set up the GRASS environment in their script or program and this is what this article discuss. However, it must be noted that the the generally preferred (and easy) way is to create scripts and programs as GRASS modules which means that your don't have to bother with setting up the environment since the GRASS module should be always invoked only in GRASS session.&lt;br /&gt;
&lt;br /&gt;
== GRASS sessions ==&lt;br /&gt;
&lt;br /&gt;
It is possible to access GRASS modules without explicitly starting a &amp;quot;GRASS session&amp;quot;. GRASS libraries require certain [http://grass.osgeo.org/grass72/manuals/variables.html environment variables] to be set. In fact a &amp;quot;GRASS session&amp;quot; is just a set of processes (e.g. a shell and/or GUI) which have the necessary environment settings, specifically:&lt;br /&gt;
&lt;br /&gt;
* '''GISBASE''' needs to be set to the top-level directory of the GRASS installation.&lt;br /&gt;
* '''GISRC''' needs to contain the absolute path to a file containing settings for '''GISDBASE''', '''LOCATION_NAME''' and '''MAPSET'''.&lt;br /&gt;
* '''PATH''' needs to include '''$GISBASE/bin''' and '''$GISBASE/scripts'''.&lt;br /&gt;
&lt;br /&gt;
If the GRASS libraries are shared libraries, the loader needs to be able to find them. This normally means that '''LD_LIBRARY_PATH''' (Linux, Solaris), '''DYLD_LIBRARY_PATH''' (MacOSX) or '''PATH''' (Windows) need to contain '''$GISBASE/lib''', although there are other means to the same end (e.g. on Linux, putting $GISBASE/lib (with $GISBASE replaced by its actual value) into /etc/ld.so.conf then running ldconfig).&lt;br /&gt;
&lt;br /&gt;
Some libraries and modules use other variables. More information for most of them is available in the file ''$GISBASE/docs/html/variables.html''. The display libraries used by ''d.*'' commands use additional variables, which are documented along with the individual drivers.&lt;br /&gt;
&lt;br /&gt;
=== Batch jobs ===&lt;br /&gt;
&lt;br /&gt;
You can run GRASS scripts non-interactively from outside of a GRASS session with the GRASS_BATCH_JOB environment variable. When GRASS is started with this environment variable set it will automatically run the contents of the script given in the variable, then close the GRASS session when complete. In this way full lock-checking, GRASS variables setup, and temporary file cleaning tasks are still performed.&lt;br /&gt;
&lt;br /&gt;
See the [[GRASS_and_Shell#GRASS_Batch_jobs|Batch jobs]] section of the GRASS shell-help wiki page for details.&lt;br /&gt;
&lt;br /&gt;
=== Starting a GRASS session and terminating it automatically ===&lt;br /&gt;
&lt;br /&gt;
A GRASS session can be started and terminated automatically with the -e flag.&lt;br /&gt;
&lt;br /&gt;
Since GRASS GIS 7.2.x you can execute commands from outside by passing the command to be executed (or a script with a collection of GRASS GIS commands) to the --exec flag:&lt;br /&gt;
&lt;br /&gt;
Creating a new Location based on a geodata file's projection (-c) and exit (-e) immediately:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 -c elevation.tiff -e /path/to/grassdata/test1/&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Linking external raster data to PERMANENT Mapset:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ -e --exec r.external input=basins.tiff output=basins&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ -e --exec r.external input=elevation.tiff output=elevation&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get statistics for one raster map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ -e --exec r.univar map=elevation&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Start a GRASS session but do not terminate it automatically ====&lt;br /&gt;
&lt;br /&gt;
Compare the rasters visually:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ --exec g.gui.mapswipe first=elevation second=basins&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read more in the [https://grass.osgeo.org/grass72/manuals/grass7.html#batch-jobs-with-the-exec-interface manual].&lt;br /&gt;
&lt;br /&gt;
==== Python examples ====&lt;br /&gt;
&lt;br /&gt;
For details on GRASS GIS Python programming, see also [[GRASS Python Scripting Library]].&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 with an external library: grass-session =====&lt;br /&gt;
&lt;br /&gt;
The [https://github.com/zarch/grass-session &amp;quot;grass-session&amp;quot; Python library] is under development. To contribute at the code, documentation and testing it is possible to install the current version with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pip install grass-session&lt;br /&gt;
# for the latest development version use:&lt;br /&gt;
# pip install git+https://github.com/zarch/grass-session.git&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then write &lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# filename: test_session.py&lt;br /&gt;
&lt;br /&gt;
from grass_session import Session&lt;br /&gt;
from grass.script import core as gcore&lt;br /&gt;
&lt;br /&gt;
# create a new location from EPSG code (can also be a GeoTIFF or SHP or ... file)&lt;br /&gt;
with Session(gisdb=&amp;quot;/tmp&amp;quot;, location=&amp;quot;location&amp;quot;,&lt;br /&gt;
             create_opts=&amp;quot;EPSG:4326&amp;quot;):&lt;br /&gt;
   # do something in permanent&lt;br /&gt;
   print(gcore.parse_command(&amp;quot;g.gisenv&amp;quot;, flags=&amp;quot;s&amp;quot;))&lt;br /&gt;
# {u'GISDBASE': u&amp;quot;'/tmp/';&amp;quot;,&lt;br /&gt;
#  u'LOCATION_NAME': u&amp;quot;'epsg3035';&amp;quot;,&lt;br /&gt;
#  u'MAPSET': u&amp;quot;'PERMANENT';&amp;quot;,}&lt;br /&gt;
&lt;br /&gt;
# create a new mapset in an existing location&lt;br /&gt;
with Session(gisdb=&amp;quot;/tmp&amp;quot;, location=&amp;quot;location&amp;quot;, mapset=&amp;quot;test&amp;quot;,&lt;br /&gt;
             create_opts=&amp;quot;&amp;quot;):&lt;br /&gt;
    # do something in the test mapset.&lt;br /&gt;
    print(gcore.parse_command(&amp;quot;g.gisenv&amp;quot;, flags=&amp;quot;s&amp;quot;))&lt;br /&gt;
# {u'GISDBASE': u&amp;quot;'/tmp/';&amp;quot;,&lt;br /&gt;
#  u'LOCATION_NAME': u&amp;quot;'epsg3035';&amp;quot;,&lt;br /&gt;
#  u'MAPSET': u&amp;quot;'test';&amp;quot;,}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The grass-session library looks at the &amp;lt;tt&amp;gt;GRASSBIN&amp;lt;/tt&amp;gt; environmental variable. If the variable is not set, the library tries to use the current stable release of GRASS GIS (e.g. &amp;lt;tt&amp;gt;grass74&amp;lt;/tt&amp;gt; on Linux for the 7.4 release).&lt;br /&gt;
For instance, to execute the previous example using a custom installation of 7.5 version, write:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
GRASSBIN=$HOME/.local/bin/grass75 python test_session.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The use of the &amp;lt;tt&amp;gt;with-statement&amp;lt;/tt&amp;gt; close automatically the session.&lt;br /&gt;
If you have to manage more complex workflow you can manually defined the opening and clossing actions.&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
# import grass_session&lt;br /&gt;
from grass_session import Session&lt;br /&gt;
&lt;br /&gt;
# import grass python libraries&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# set some common environmental variables, like:&lt;br /&gt;
os.environ.update(dict(GRASS_COMPRESS_NULLS='1',&lt;br /&gt;
                       GRASS_COMPRESSOR='ZSTD'))&lt;br /&gt;
&lt;br /&gt;
# create a PERMANENT mapset&lt;br /&gt;
# create a Session instance&lt;br /&gt;
PERMANENT = Session()&lt;br /&gt;
PERMANENT.open(gisdb='/tmp', location='mytest',&lt;br /&gt;
               create_opts='EPSG:4326')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# execute some command inside PERMANENT&lt;br /&gt;
g.mapsets(flags=&amp;quot;l&amp;quot;)&lt;br /&gt;
g.list(type=&amp;quot;raster&amp;quot;, flags=&amp;quot;m&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# exit from PERMANENT&lt;br /&gt;
PERMANENT.close()&lt;br /&gt;
&lt;br /&gt;
# create a new mapset in the same location&lt;br /&gt;
user = Session()&lt;br /&gt;
user.open(gisdb='/tmp', location='mytest', mapset='user',&lt;br /&gt;
               create_opts='')&lt;br /&gt;
&lt;br /&gt;
# execute some command inside user&lt;br /&gt;
g.mapsets(flags=&amp;quot;l&amp;quot;)&lt;br /&gt;
g.list(type=&amp;quot;raster&amp;quot;, flags=&amp;quot;m&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# exit from user&lt;br /&gt;
user.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Hint: find the path to the GRASS GIS package start script =====&lt;br /&gt;
&lt;br /&gt;
Hint: in order to find the '''path to the GRASS GIS package''', launch it with &amp;lt;tt&amp;gt; --config path&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Linux&lt;br /&gt;
grass72 --config path&lt;br /&gt;
/usr/bin/grass-7.2.0&lt;br /&gt;
&lt;br /&gt;
# Windows&lt;br /&gt;
C:\&amp;gt;grass72.bat --config path&lt;br /&gt;
C:\OSGeo4W\apps\grass\grass-7.2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 with existing location =====&lt;br /&gt;
&lt;br /&gt;
See the example in the [https://grass.osgeo.org/grass72/manuals/libpython/script.html#module-script.setup documentation] or the script which initializes the session and lists available raster and vector maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import subprocess&lt;br /&gt;
&lt;br /&gt;
# path to the GRASS GIS launch script&lt;br /&gt;
# MS Windows&lt;br /&gt;
grass7bin_win = r'C:\OSGeo4W\bin\grass72svn.bat'&lt;br /&gt;
# uncomment when using standalone WinGRASS installer&lt;br /&gt;
# grass7bin_win = r'C:\Program Files (x86)\GRASS GIS 7.2.0\grass72.bat'&lt;br /&gt;
# Linux&lt;br /&gt;
grass7bin_lin = 'grass72'&lt;br /&gt;
# Mac OS X&lt;br /&gt;
# this is TODO&lt;br /&gt;
grass7bin_mac = '/Applications/GRASS/GRASS-7.2.app/'&lt;br /&gt;
&lt;br /&gt;
# DATA&lt;br /&gt;
# define GRASS DATABASE&lt;br /&gt;
# add your path to grassdata (GRASS GIS database) directory&lt;br /&gt;
gisdb = os.path.join(os.path.expanduser(&amp;quot;~&amp;quot;), &amp;quot;grassdata&amp;quot;)&lt;br /&gt;
# the following path is the default path on MS Windows&lt;br /&gt;
# gisdb = os.path.join(os.path.expanduser(&amp;quot;~&amp;quot;), &amp;quot;Documents/grassdata&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# specify (existing) location and mapset&lt;br /&gt;
location = &amp;quot;nc_spm_08&amp;quot;&lt;br /&gt;
mapset   = &amp;quot;user1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
########### SOFTWARE&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
    # we assume that the GRASS GIS start script is available and in the PATH&lt;br /&gt;
    # query GRASS 7 itself for its GISBASE&lt;br /&gt;
    grass7bin = grass7bin_lin&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    grass7bin = grass7bin_win&lt;br /&gt;
else:&lt;br /&gt;
    raise OSError('Platform not configured.')&lt;br /&gt;
&lt;br /&gt;
# query GRASS 7 itself for its GISBASE&lt;br /&gt;
startcmd = [grass7bin, '--config', 'path']&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=False,&lt;br /&gt;
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, &amp;quot;ERROR: Cannot find GRASS GIS 7 start script (%s)&amp;quot; % startcmd&lt;br /&gt;
    sys.exit(-1)&lt;br /&gt;
gisbase = out.strip('\n\r')&lt;br /&gt;
&lt;br /&gt;
# Set GISBASE environment variable&lt;br /&gt;
os.environ['GISBASE'] = gisbase&lt;br /&gt;
# the following not needed with trunk&lt;br /&gt;
os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'extrabin')&lt;br /&gt;
# add path to GRASS addons&lt;br /&gt;
home = os.path.expanduser(&amp;quot;~&amp;quot;)&lt;br /&gt;
os.environ['PATH'] += os.pathsep + os.path.join(home, '.grass7', 'addons', 'scripts')&lt;br /&gt;
&lt;br /&gt;
# define GRASS-Python environment&lt;br /&gt;
gpydir = os.path.join(gisbase, &amp;quot;etc&amp;quot;, &amp;quot;python&amp;quot;)&lt;br /&gt;
sys.path.append(gpydir)&lt;br /&gt;
&lt;br /&gt;
########### DATA&lt;br /&gt;
# Set GISDBASE environment variable&lt;br /&gt;
os.environ['GISDBASE'] = gisdb&lt;br /&gt;
 &lt;br /&gt;
# import GRASS Python bindings (see also pygrass)&lt;br /&gt;
import grass.script as gscript&lt;br /&gt;
import grass.script.setup as gsetup&lt;br /&gt;
 &lt;br /&gt;
###########&lt;br /&gt;
# launch session&lt;br /&gt;
gsetup.init(gisbase,&lt;br /&gt;
            gisdb, location, mapset)&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Current GRASS GIS 7 environment:')&lt;br /&gt;
print gscript.gisenv()&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Available raster maps:')&lt;br /&gt;
for rast in gscript.list_strings(type = 'rast'):&lt;br /&gt;
    print rast&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Available vector maps:')&lt;br /&gt;
for vect in gscript.list_strings(type = 'vect'):&lt;br /&gt;
    print vect&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 without existing location using metadata only =====&lt;br /&gt;
&lt;br /&gt;
The script initializes the GRASS GIS session, creates a temporary GRASS location and lists available raster and vector maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
# Python script to generate a new GRASS GIS 7 location simply from metadata&lt;br /&gt;
# Markus Neteler, 2014&lt;br /&gt;
&lt;br /&gt;
# ?? LINUX USAGE: First set LIBRARY SEARCH PATH&lt;br /&gt;
#export LD_LIBRARY_PATH=$(grass72 --config path)/lib&lt;br /&gt;
#python start_grass7_create_new_location_ADVANCED.py&lt;br /&gt;
&lt;br /&gt;
# some predefined variables&lt;br /&gt;
&lt;br /&gt;
# Windows&lt;br /&gt;
grass7path = r'C:\OSGeo4W\apps\grass\grass-7.2.svn'&lt;br /&gt;
grass7bin_win = r'C:\OSGeo4W\bin\grass72svn.bat'&lt;br /&gt;
# Linux&lt;br /&gt;
grass7bin_lin = 'grass72'&lt;br /&gt;
# MacOSX&lt;br /&gt;
grass7bin_mac = '/Applications/GRASS/GRASS-7.1.app/'&lt;br /&gt;
#myepsg = '4326' # latlong&lt;br /&gt;
myepsg = '3044' # ETRS-TM32, http://spatialreference.org/ref/epsg/3044/&lt;br /&gt;
#myfile = '/home/neteler/markus_repo/books/kluwerbook/data3rd/lidar/lidar_raleigh_nc_spm.shp'&lt;br /&gt;
myfile = '/data/maps/world_natural_earth_250m/europe_north_east.tif'&lt;br /&gt;
#myfile = r'C:\Dati\Padergnone\square_p95.tif'&lt;br /&gt;
&lt;br /&gt;
###########&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import subprocess&lt;br /&gt;
import shutil&lt;br /&gt;
import binascii&lt;br /&gt;
import tempfile&lt;br /&gt;
&lt;br /&gt;
########### SOFTWARE&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
    # we assume that the GRASS GIS start script is available and in the PATH&lt;br /&gt;
    # query GRASS 7 itself for its GISBASE&lt;br /&gt;
    grass7bin = grass7bin_lin&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    grass7bin = grass7bin_win&lt;br /&gt;
else:&lt;br /&gt;
    OSError('Platform not configured.')&lt;br /&gt;
&lt;br /&gt;
startcmd = grass7bin + ' --config path'&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=True, &lt;br /&gt;
					 stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
	print &amp;gt;&amp;gt;sys.stderr, 'ERROR: %s' % err&lt;br /&gt;
	print &amp;gt;&amp;gt;sys.stderr, &amp;quot;ERROR: Cannot find GRASS GIS 7 start script (%s)&amp;quot; % startcmd&lt;br /&gt;
	sys.exit(-1)&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
	gisbase = out.strip('\n')&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    if out.find(&amp;quot;OSGEO4W home is&amp;quot;) != -1:&lt;br /&gt;
		gisbase = out.strip().split('\n')[1]&lt;br /&gt;
    else:&lt;br /&gt;
		gisbase = out.strip('\n')&lt;br /&gt;
    os.environ['GRASS_SH'] = os.path.join(gisbase, 'msys', 'bin', 'sh.exe')&lt;br /&gt;
&lt;br /&gt;
# Set GISBASE environment variable&lt;br /&gt;
os.environ['GISBASE'] = gisbase&lt;br /&gt;
# define GRASS-Python environment&lt;br /&gt;
gpydir = os.path.join(gisbase, &amp;quot;etc&amp;quot;, &amp;quot;python&amp;quot;)&lt;br /&gt;
sys.path.append(gpydir)&lt;br /&gt;
########&lt;br /&gt;
# define GRASS DATABASE&lt;br /&gt;
if sys.platform.startswith('win'):&lt;br /&gt;
    gisdb = os.path.join(os.getenv('APPDATA', 'grassdata'))&lt;br /&gt;
else:&lt;br /&gt;
    gisdb = os.path.join(os.getenv('HOME', 'grassdata'))&lt;br /&gt;
&lt;br /&gt;
# override for now with TEMP dir&lt;br /&gt;
gisdb = os.path.join(tempfile.gettempdir(), 'grassdata')&lt;br /&gt;
try:&lt;br /&gt;
    os.stat(gisdb)&lt;br /&gt;
except:&lt;br /&gt;
    os.mkdir(gisdb)&lt;br /&gt;
&lt;br /&gt;
# location/mapset: use random names for batch jobs&lt;br /&gt;
string_length = 16&lt;br /&gt;
location = binascii.hexlify(os.urandom(string_length))&lt;br /&gt;
mapset   = 'PERMANENT'&lt;br /&gt;
location_path = os.path.join(gisdb, location)&lt;br /&gt;
&lt;br /&gt;
# Create new location (we assume that grass7bin is in the PATH)&lt;br /&gt;
#  from EPSG code:&lt;br /&gt;
startcmd = grass7bin + ' -c epsg:' + myepsg + ' -e ' + location_path&lt;br /&gt;
#  from SHAPE or GeoTIFF file&lt;br /&gt;
#startcmd = grass7bin + ' -c ' + myfile + ' -e ' + location_path&lt;br /&gt;
&lt;br /&gt;
print startcmd&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=True, &lt;br /&gt;
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, 'ERROR: %s' % err&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, 'ERROR: Cannot generate location (%s)' % startcmd&lt;br /&gt;
    sys.exit(-1)&lt;br /&gt;
else:&lt;br /&gt;
    print 'Created location %s' % location_path&lt;br /&gt;
&lt;br /&gt;
# Now the location with PERMANENT mapset exists.&lt;br /&gt;
&lt;br /&gt;
########&lt;br /&gt;
# Now we can use PyGRASS or GRASS Scripting library etc. after &lt;br /&gt;
# having started the session with gsetup.init() etc&lt;br /&gt;
&lt;br /&gt;
# Set GISDBASE environment variable&lt;br /&gt;
os.environ['GISDBASE'] = gisdb&lt;br /&gt;
&lt;br /&gt;
# Linux: Set path to GRASS libs (TODO: NEEDED?)&lt;br /&gt;
path = os.getenv('LD_LIBRARY_PATH')&lt;br /&gt;
dir  = os.path.join(gisbase, 'lib')&lt;br /&gt;
if path:&lt;br /&gt;
    path = dir + os.pathsep + path&lt;br /&gt;
else:&lt;br /&gt;
    path = dir&lt;br /&gt;
os.environ['LD_LIBRARY_PATH'] = path&lt;br /&gt;
&lt;br /&gt;
# language&lt;br /&gt;
os.environ['LANG'] = 'en_US'&lt;br /&gt;
os.environ['LOCALE'] = 'C'&lt;br /&gt;
&lt;br /&gt;
# Windows: NEEDED?&lt;br /&gt;
#path = os.getenv('PYTHONPATH')&lt;br /&gt;
#dirr = os.path.join(gisbase, 'etc', 'python')&lt;br /&gt;
#if path:&lt;br /&gt;
#    path = dirr + os.pathsep + path&lt;br /&gt;
#else:&lt;br /&gt;
#    path = dirr&lt;br /&gt;
#os.environ['PYTHONPATH'] = path&lt;br /&gt;
&lt;br /&gt;
#print os.environ&lt;br /&gt;
&lt;br /&gt;
## Import GRASS Python bindings&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
import grass.script.setup as gsetup&lt;br /&gt;
&lt;br /&gt;
###########&lt;br /&gt;
# Launch session and do something&lt;br /&gt;
gsetup.init(gisbase, gisdb, location, mapset)&lt;br /&gt;
&lt;br /&gt;
# say hello&lt;br /&gt;
grass.message('--- GRASS GIS 7: Current GRASS GIS 7 environment:')&lt;br /&gt;
print grass.gisenv()&lt;br /&gt;
&lt;br /&gt;
# do something in GRASS now...&lt;br /&gt;
&lt;br /&gt;
grass.message('--- GRASS GIS 7: Checking projection info:')&lt;br /&gt;
in_proj = grass.read_command('g.proj', flags = 'jf')&lt;br /&gt;
&lt;br /&gt;
# selective proj parameter printing&lt;br /&gt;
kv = grass.parse_key_val(in_proj)&lt;br /&gt;
print kv&lt;br /&gt;
print kv['+proj']&lt;br /&gt;
&lt;br /&gt;
# print full proj parameter printing&lt;br /&gt;
in_proj = in_proj.strip()&lt;br /&gt;
grass.message(&amp;quot;--- Found projection parameters: '%s'&amp;quot; % in_proj)&lt;br /&gt;
&lt;br /&gt;
# show current region:&lt;br /&gt;
grass.message('--- GRASS GIS 7: Checking computational region info:')&lt;br /&gt;
in_region = grass.region()&lt;br /&gt;
grass.message(&amp;quot;--- Computational region: '%s'&amp;quot; % in_region)&lt;br /&gt;
&lt;br /&gt;
# do something else: r.mapcalc, v.rectify, ...&lt;br /&gt;
&lt;br /&gt;
# Finally remove the temporary batch location from disk&lt;br /&gt;
print 'Removing location %s' % location_path&lt;br /&gt;
shutil.rmtree(location_path)&lt;br /&gt;
&lt;br /&gt;
sys.exit(0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Bash examples (GNU/Linux) ====&lt;br /&gt;
&lt;br /&gt;
'''''Note: see [[GRASS_and_Shell#GRASS_Batch_jobs|GRASS Batch jobs]] for a really easy approach.'''''&lt;br /&gt;
&lt;br /&gt;
Below an example of a '''~/.bash_profile''' script to set the required settings in order to access GRASS commands outside of a GRASS GIS session&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
export GISBASE=/usr/local/grass-7.2.svn&lt;br /&gt;
export GRASS_VERSION=&amp;quot;7.2.svn&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#generate GISRCRC&lt;br /&gt;
MYGISDBASE=$HOME/grassdata&lt;br /&gt;
MYLOC=nc_spm_08_grass7&lt;br /&gt;
MYMAPSET=user1&lt;br /&gt;
&lt;br /&gt;
# Set the global grassrc file to individual file name&lt;br /&gt;
MYGISRC=&amp;quot;$HOME/.grassrc.$GRASS_VERSION.$$&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;GISDBASE: $MYGISDBASE&amp;quot; &amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;LOCATION_NAME: $MYLOC&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;MAPSET: $MYMAPSET&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;GRASS_GUI: text&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# path to GRASS settings file&lt;br /&gt;
export GISRC=$MYGISRC&lt;br /&gt;
export GRASS_PYTHON=python&lt;br /&gt;
export GRASS_MESSAGE_FORMAT=plain&lt;br /&gt;
export GRASS_TRUECOLOR=TRUE&lt;br /&gt;
export GRASS_TRANSPARENT=TRUE&lt;br /&gt;
export GRASS_PNG_AUTO_WRITE=TRUE&lt;br /&gt;
export GRASS_GNUPLOT='gnuplot -persist'&lt;br /&gt;
export GRASS_WIDTH=640&lt;br /&gt;
export GRASS_HEIGHT=480&lt;br /&gt;
export GRASS_HTML_BROWSER=firefox&lt;br /&gt;
export GRASS_PAGER=cat&lt;br /&gt;
&lt;br /&gt;
#For the temporal modules&lt;br /&gt;
export TGISDB_DRIVER=sqlite&lt;br /&gt;
export TGISDB_DATABASE=$MYGISDBASE/$MYLOC/PERMANENT/tgis/sqlite.db&lt;br /&gt;
&lt;br /&gt;
# for fun, we can even set the shell prompt to contain a hint on GRASS GIS env being active&lt;br /&gt;
export PS1=&amp;quot;[\u@\h \W G-$GRASS_VERSION]$ &amp;quot;&lt;br /&gt;
&lt;br /&gt;
# system vars&lt;br /&gt;
export PATH=&amp;quot;$GISBASE/bin:$GISBASE/scripts:$PATH&amp;quot;&lt;br /&gt;
export LD_LIBRARY_PATH=&amp;quot;$GISBASE/lib&amp;quot;&lt;br /&gt;
export GRASS_LD_LIBRARY_PATH=&amp;quot;$LD_LIBRARY_PATH&amp;quot;&lt;br /&gt;
export PYTHONPATH=&amp;quot;$GISBASE/etc/python:$PYTHONPATH&amp;quot;&lt;br /&gt;
export MANPATH=$MANPATH:$GISBASE/man&lt;br /&gt;
&lt;br /&gt;
# test a command&lt;br /&gt;
g.list rast&lt;br /&gt;
v.info zipcodes_wake&lt;br /&gt;
&lt;br /&gt;
######### below not needed ########&lt;br /&gt;
# GRASS 7&lt;br /&gt;
tmp=/tmp/grass7-&amp;quot;`whoami`&amp;quot;-$GIS_LOCK&lt;br /&gt;
&lt;br /&gt;
export GISRC=&amp;quot;$tmp/rc&amp;quot;&lt;br /&gt;
mkdir &amp;quot;$tmp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
cp $HOME/.grass7/rc &amp;quot;$GISRC&amp;quot;&lt;br /&gt;
&lt;br /&gt;
######### END below not needed ########&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above script will allow GRASS commands to be used anywhere. Furthermore, if the '''~/.Xsession''' sources the bash startup scripts, the settings aren't limited to interactive shells, but also work for e.g. M-! in XEmacs). Each interactive shell gets a separate &amp;quot;session&amp;quot; (i.e. a separate $GISRC file), while GUI programs share a common session.&lt;br /&gt;
&lt;br /&gt;
Note, however, that '''~/.bash_profile''' is a personal initialization startup script and, thus, read during the login process. Any modifications to it will be read after (re-)login or explicitly sourcing it.&lt;br /&gt;
&lt;br /&gt;
At the end of the ~/.bash_profile file, the following lines can be added to ensure no duplication of entries in the PATH variable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 PATH=`awk -F: '{for(i=1;i&amp;lt;=NF;i++){if(!($i in a)){a[$i];printf s$i;s=&amp;quot;:&amp;quot;}}}'&amp;lt;&amp;lt;&amp;lt;$PATH`&lt;br /&gt;
 PYTHONPATH=`awk -F: '{for(i=1;i&amp;lt;=NF;i++){if(!($i in a)){a[$i];printf s$i;s=&amp;quot;:&amp;quot;}}}'&amp;lt;&amp;lt;&amp;lt;$PYTHONPATH`&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Important notes ===&lt;br /&gt;
&lt;br /&gt;
Launching a grassXY session could still permit access on GRASS modules of the version that is set with the above script. The reason being is that grassXY scripts (e.g.: grass64, grass65, grass72) prepend the GRASS directories to '''PATH''', '''LD_LIBRARY_PATH''', etc. They won't remove any entries which are already there. A solution to this is to ''switch'' between GRASS versions by using a script like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
        strippath()&lt;br /&gt;
        {&lt;br /&gt;
            (&lt;br /&gt;
            oldpath=&amp;quot;$1&amp;quot;&lt;br /&gt;
            newpath=&lt;br /&gt;
            IFS=:&lt;br /&gt;
            for dir in $oldpath ; do&lt;br /&gt;
                case &amp;quot;${dir}&amp;quot; in&lt;br /&gt;
                *grass*)&lt;br /&gt;
                        ;;&lt;br /&gt;
                *)&lt;br /&gt;
                        newpath=&amp;quot;$newpath:$dir&amp;quot;&lt;br /&gt;
                        ;;&lt;br /&gt;
                esac&lt;br /&gt;
            done&lt;br /&gt;
            echo &amp;quot;${newpath#:}&amp;quot;&lt;br /&gt;
            )&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        PATH=`strippath $PATH`&lt;br /&gt;
        &lt;br /&gt;
        export GISBASE=$PWD/dist.i686-pc-linux-gnu&lt;br /&gt;
        export PATH=&amp;quot;$GISBASE/bin:$GISBASE/scripts:$PATH&amp;quot;&lt;br /&gt;
        export LD_LIBRARY_PATH=&amp;quot;$GISBASE/lib&amp;quot;&lt;br /&gt;
        export PYTHONPATH=&amp;quot;$GISBASE/etc/python&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note: the above script needs to be &amp;quot;source&amp;quot;d; executing it won't work. It might also require some adjustments (e.g. the ''GISBASE'' variable).'''&lt;br /&gt;
&lt;br /&gt;
Using normal grass sessions commands are recorded in '''$GISDBASE/$LOCATION_NAME/$MAPSET/.bash_history'''. While working with &amp;quot;pure&amp;quot; bash, shell entries go in '''~/.bash_history'''. Merging existing &amp;quot;grass-bash_history(-ies)&amp;quot; with the bash history log, would probably be not a good idea. Perhaps it is wise(r) to use normal GRASS sessions when working on real projects. Nevertheless, it is upon the users preferences and expertise level to decide what is best.&lt;br /&gt;
&lt;br /&gt;
=== Hints and troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
Some hints for MS Windows users:&lt;br /&gt;
&lt;br /&gt;
# The Python interpreter (python.exe) needs to be in the PATH&lt;br /&gt;
# Python needs to be associated with the .py extension&lt;br /&gt;
# PATHEXT needs to include .py if you want to be able to omit the extension&lt;br /&gt;
&lt;br /&gt;
When everything works well, the installer should take care of all of these.&lt;br /&gt;
&lt;br /&gt;
To manage parallel sessions on Linux, use process ID (PID) as lock file number and set the GIS_LOCK variable, for example&lt;br /&gt;
&lt;br /&gt;
  export GIS_LOCK=$$&lt;br /&gt;
&lt;br /&gt;
in Bash.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* Instructions and discussion on [http://n2.nabble.com/can-I-access-mapset-outside-of-grass-by-using-python-td3405902.html#a3405902 how to access GRASS mapsets outside of a GRASS session] in the grass-user mailing list.&lt;br /&gt;
* removing duplicate entries in $PATH taken from [http://chunchung.blogspot.com/2007/11/remove-duplicate-paths-from-path-in.html]&lt;br /&gt;
&lt;br /&gt;
== GRASS databases ==&lt;br /&gt;
&lt;br /&gt;
(project file structure)&lt;br /&gt;
&lt;br /&gt;
=== Minimal mapsets ===&lt;br /&gt;
&lt;br /&gt;
within a functional LOCATION (see below) the minimal mapset is a subdirectory of the MAPSET's name, containing a WIND file. The WIND file can simply be copied from PERMANENT/DEFAULT_WIND. Optionally you can put a VAR file in there too to define the default database driver to use.&lt;br /&gt;
&lt;br /&gt;
* You can create a new mapset when starting GRASS with the -c flag. e.g.&lt;br /&gt;
 grass64 -c /path/to/location/new_mapset_name&lt;br /&gt;
&lt;br /&gt;
=== Minimal locations ===&lt;br /&gt;
&lt;br /&gt;
Within the GISDATABASE (which is simply a subdirectory some where), the minimum LOCATION consists of a directory giving the LOCATION its name, which in turn contains a PERMANENT subdirectory for the PERMANENT mapset. The PERMANENT mapset contains a few special files that regular mapsets don't. These are:&lt;br /&gt;
; PROJ_INFO: contains the location's projection information&lt;br /&gt;
; PROJ_UNITS: contains the location's map units definition&lt;br /&gt;
; DEFAULT_WIND: the default region (WINDow file). The format is identical to the WIND files created by g.region&lt;br /&gt;
; WIND: (optional?)&lt;br /&gt;
&lt;br /&gt;
* see also {{src|demolocation}} in the GRASS source code&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[GRASS_and_Shell#GRASS_Batch_jobs|GRASS Batch jobs]]&lt;br /&gt;
&lt;br /&gt;
[[Category: FAQ]]&lt;br /&gt;
[[Category: Linking to other languages]]&lt;br /&gt;
[[Category: bash]]&lt;br /&gt;
[[Category:Scripting]]&lt;br /&gt;
[[Category: Python]]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Working_with_GRASS_without_starting_it_explicitly&amp;diff=24918</id>
		<title>Working with GRASS without starting it explicitly</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Working_with_GRASS_without_starting_it_explicitly&amp;diff=24918"/>
		<updated>2017-12-15T22:51:12Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: Update how to install and use the current development version of grass-session&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GRASS GIS modules and the import of GRASS Python packages works only in a specific environmental settings (GRASS session). This settings is ensured by starting GRASS GIS application which prepares this GRASS session for you. It is possible to set up you system in the way that the GRASS session will be always active (i.e. the GRASS startup script is not running, just the environmental settings are done). People often prefer to set up the GRASS environment in their script or program and this is what this article discuss. However, it must be noted that the the generally preferred (and easy) way is to create scripts and programs as GRASS modules which means that your don't have to bother with setting up the environment since the GRASS module should be always invoked only in GRASS session.&lt;br /&gt;
&lt;br /&gt;
== GRASS sessions ==&lt;br /&gt;
&lt;br /&gt;
It is possible to access GRASS modules without explicitly starting a &amp;quot;GRASS session&amp;quot;. GRASS libraries require certain [http://grass.osgeo.org/grass72/manuals/variables.html environment variables] to be set. In fact a &amp;quot;GRASS session&amp;quot; is just a set of processes (e.g. a shell and/or GUI) which have the necessary environment settings, specifically:&lt;br /&gt;
&lt;br /&gt;
* '''GISBASE''' needs to be set to the top-level directory of the GRASS installation.&lt;br /&gt;
* '''GISRC''' needs to contain the absolute path to a file containing settings for '''GISDBASE''', '''LOCATION_NAME''' and '''MAPSET'''.&lt;br /&gt;
* '''PATH''' needs to include '''$GISBASE/bin''' and '''$GISBASE/scripts'''.&lt;br /&gt;
&lt;br /&gt;
If the GRASS libraries are shared libraries, the loader needs to be able to find them. This normally means that '''LD_LIBRARY_PATH''' (Linux, Solaris), '''DYLD_LIBRARY_PATH''' (MacOSX) or '''PATH''' (Windows) need to contain '''$GISBASE/lib''', although there are other means to the same end (e.g. on Linux, putting $GISBASE/lib (with $GISBASE replaced by its actual value) into /etc/ld.so.conf then running ldconfig).&lt;br /&gt;
&lt;br /&gt;
Some libraries and modules use other variables. More information for most of them is available in the file ''$GISBASE/docs/html/variables.html''. The display libraries used by ''d.*'' commands use additional variables, which are documented along with the individual drivers.&lt;br /&gt;
&lt;br /&gt;
=== Batch jobs ===&lt;br /&gt;
&lt;br /&gt;
You can run GRASS scripts non-interactively from outside of a GRASS session with the GRASS_BATCH_JOB environment variable. When GRASS is started with this environment variable set it will automatically run the contents of the script given in the variable, then close the GRASS session when complete. In this way full lock-checking, GRASS variables setup, and temporary file cleaning tasks are still performed.&lt;br /&gt;
&lt;br /&gt;
See the [[GRASS_and_Shell#GRASS_Batch_jobs|Batch jobs]] section of the GRASS shell-help wiki page for details.&lt;br /&gt;
&lt;br /&gt;
=== Accessing GRASS modules without starting a GRASS session ===&lt;br /&gt;
&lt;br /&gt;
==== The easiest way: the --exec flag ====&lt;br /&gt;
&lt;br /&gt;
Since GRASS GIS 7.2.x you can execute commands from outside by passing the command to be executed (or a script with a collection of GRASS GIS commands) to the --exec flag:&lt;br /&gt;
&lt;br /&gt;
Creating a new Location based on a geodata file's projection (-c) and exit (-e) immediately:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 -c elevation.tiff -e /path/to/grassdata/test1/&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Linking external raster data to PERMANENT Mapset:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ --exec r.external input=basins.tiff output=basins&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ --exec r.external input=elevation.tiff output=elevation&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get statistics for one raster map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ --exec r.univar map=elevation&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compare the rasters visually:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ --exec g.gui.mapswipe first=elevation second=basins&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read more in the [https://grass.osgeo.org/grass72/manuals/grass7.html#batch-jobs-with-the-exec-interface manual].&lt;br /&gt;
&lt;br /&gt;
==== Python examples ====&lt;br /&gt;
&lt;br /&gt;
See also [[GRASS Python Scripting Library]]&lt;br /&gt;
&lt;br /&gt;
===== Hint: find the path to the GRASS GIS package =====&lt;br /&gt;
&lt;br /&gt;
Hint: in order to find the '''path to the GRASS GIS package''', launch it with &amp;lt;tt&amp;gt; --config path&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Linux&lt;br /&gt;
grass72 --config path&lt;br /&gt;
/usr/bin/grass-7.2.0&lt;br /&gt;
&lt;br /&gt;
# Windows&lt;br /&gt;
C:\&amp;gt;grass72.bat --config path&lt;br /&gt;
C:\OSGeo4W\apps\grass\grass-7.2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 with existing location =====&lt;br /&gt;
&lt;br /&gt;
See the example in the [https://grass.osgeo.org/grass72/manuals/libpython/script.html#module-script.setup documentation] or the script which initializes the session and lists available raster and vector maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import subprocess&lt;br /&gt;
&lt;br /&gt;
# path to the GRASS GIS launch script&lt;br /&gt;
# MS Windows&lt;br /&gt;
grass7bin_win = r'C:\OSGeo4W\bin\grass72svn.bat'&lt;br /&gt;
# uncomment when using standalone WinGRASS installer&lt;br /&gt;
# grass7bin_win = r'C:\Program Files (x86)\GRASS GIS 7.2.0\grass72.bat'&lt;br /&gt;
# Linux&lt;br /&gt;
grass7bin_lin = 'grass72'&lt;br /&gt;
# Mac OS X&lt;br /&gt;
# this is TODO&lt;br /&gt;
grass7bin_mac = '/Applications/GRASS/GRASS-7.2.app/'&lt;br /&gt;
&lt;br /&gt;
# DATA&lt;br /&gt;
# define GRASS DATABASE&lt;br /&gt;
# add your path to grassdata (GRASS GIS database) directory&lt;br /&gt;
gisdb = os.path.join(os.path.expanduser(&amp;quot;~&amp;quot;), &amp;quot;grassdata&amp;quot;)&lt;br /&gt;
# the following path is the default path on MS Windows&lt;br /&gt;
# gisdb = os.path.join(os.path.expanduser(&amp;quot;~&amp;quot;), &amp;quot;Documents/grassdata&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# specify (existing) location and mapset&lt;br /&gt;
location = &amp;quot;nc_spm_08&amp;quot;&lt;br /&gt;
mapset   = &amp;quot;user1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
########### SOFTWARE&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
    # we assume that the GRASS GIS start script is available and in the PATH&lt;br /&gt;
    # query GRASS 7 itself for its GISBASE&lt;br /&gt;
    grass7bin = grass7bin_lin&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    grass7bin = grass7bin_win&lt;br /&gt;
else:&lt;br /&gt;
    raise OSError('Platform not configured.')&lt;br /&gt;
&lt;br /&gt;
# query GRASS 7 itself for its GISBASE&lt;br /&gt;
startcmd = [grass7bin, '--config', 'path']&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=False,&lt;br /&gt;
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, &amp;quot;ERROR: Cannot find GRASS GIS 7 start script (%s)&amp;quot; % startcmd&lt;br /&gt;
    sys.exit(-1)&lt;br /&gt;
gisbase = out.strip('\n\r')&lt;br /&gt;
&lt;br /&gt;
# Set GISBASE environment variable&lt;br /&gt;
os.environ['GISBASE'] = gisbase&lt;br /&gt;
# the following not needed with trunk&lt;br /&gt;
os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'extrabin')&lt;br /&gt;
# add path to GRASS addons&lt;br /&gt;
home = os.path.expanduser(&amp;quot;~&amp;quot;)&lt;br /&gt;
os.environ['PATH'] += os.pathsep + os.path.join(home, '.grass7', 'addons', 'scripts')&lt;br /&gt;
&lt;br /&gt;
# define GRASS-Python environment&lt;br /&gt;
gpydir = os.path.join(gisbase, &amp;quot;etc&amp;quot;, &amp;quot;python&amp;quot;)&lt;br /&gt;
sys.path.append(gpydir)&lt;br /&gt;
&lt;br /&gt;
########### DATA&lt;br /&gt;
# Set GISDBASE environment variable&lt;br /&gt;
os.environ['GISDBASE'] = gisdb&lt;br /&gt;
 &lt;br /&gt;
# import GRASS Python bindings (see also pygrass)&lt;br /&gt;
import grass.script as gscript&lt;br /&gt;
import grass.script.setup as gsetup&lt;br /&gt;
 &lt;br /&gt;
###########&lt;br /&gt;
# launch session&lt;br /&gt;
gsetup.init(gisbase,&lt;br /&gt;
            gisdb, location, mapset)&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Current GRASS GIS 7 environment:')&lt;br /&gt;
print gscript.gisenv()&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Available raster maps:')&lt;br /&gt;
for rast in gscript.list_strings(type = 'rast'):&lt;br /&gt;
    print rast&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Available vector maps:')&lt;br /&gt;
for vect in gscript.list_strings(type = 'vect'):&lt;br /&gt;
    print vect&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 without existing location using metadata only =====&lt;br /&gt;
&lt;br /&gt;
The script initializes the session, creates a temporary GRASS location and lists available raster and vector maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
# Python script to generate a new GRASS GIS 7 location simply from metadata&lt;br /&gt;
# Markus Neteler, 2014&lt;br /&gt;
&lt;br /&gt;
# ?? LINUX USAGE: First set LIBRARY SEARCH PATH&lt;br /&gt;
#export LD_LIBRARY_PATH=$(grass72 --config path)/lib&lt;br /&gt;
#python start_grass7_create_new_location_ADVANCED.py&lt;br /&gt;
&lt;br /&gt;
# some predefined variables&lt;br /&gt;
&lt;br /&gt;
# Windows&lt;br /&gt;
grass7path = r'C:\OSGeo4W\apps\grass\grass-7.2.svn'&lt;br /&gt;
grass7bin_win = r'C:\OSGeo4W\bin\grass72svn.bat'&lt;br /&gt;
# Linux&lt;br /&gt;
grass7bin_lin = 'grass72'&lt;br /&gt;
# MacOSX&lt;br /&gt;
grass7bin_mac = '/Applications/GRASS/GRASS-7.1.app/'&lt;br /&gt;
#myepsg = '4326' # latlong&lt;br /&gt;
myepsg = '3044' # ETRS-TM32, http://spatialreference.org/ref/epsg/3044/&lt;br /&gt;
#myfile = '/home/neteler/markus_repo/books/kluwerbook/data3rd/lidar/lidar_raleigh_nc_spm.shp'&lt;br /&gt;
myfile = '/data/maps/world_natural_earth_250m/europe_north_east.tif'&lt;br /&gt;
#myfile = r'C:\Dati\Padergnone\square_p95.tif'&lt;br /&gt;
&lt;br /&gt;
###########&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import subprocess&lt;br /&gt;
import shutil&lt;br /&gt;
import binascii&lt;br /&gt;
import tempfile&lt;br /&gt;
&lt;br /&gt;
########### SOFTWARE&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
    # we assume that the GRASS GIS start script is available and in the PATH&lt;br /&gt;
    # query GRASS 7 itself for its GISBASE&lt;br /&gt;
    grass7bin = grass7bin_lin&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    grass7bin = grass7bin_win&lt;br /&gt;
else:&lt;br /&gt;
    OSError('Platform not configured.')&lt;br /&gt;
&lt;br /&gt;
startcmd = grass7bin + ' --config path'&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=True, &lt;br /&gt;
					 stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
	print &amp;gt;&amp;gt;sys.stderr, 'ERROR: %s' % err&lt;br /&gt;
	print &amp;gt;&amp;gt;sys.stderr, &amp;quot;ERROR: Cannot find GRASS GIS 7 start script (%s)&amp;quot; % startcmd&lt;br /&gt;
	sys.exit(-1)&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
	gisbase = out.strip('\n')&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    if out.find(&amp;quot;OSGEO4W home is&amp;quot;) != -1:&lt;br /&gt;
		gisbase = out.strip().split('\n')[1]&lt;br /&gt;
    else:&lt;br /&gt;
		gisbase = out.strip('\n')&lt;br /&gt;
    os.environ['GRASS_SH'] = os.path.join(gisbase, 'msys', 'bin', 'sh.exe')&lt;br /&gt;
&lt;br /&gt;
# Set GISBASE environment variable&lt;br /&gt;
os.environ['GISBASE'] = gisbase&lt;br /&gt;
# define GRASS-Python environment&lt;br /&gt;
gpydir = os.path.join(gisbase, &amp;quot;etc&amp;quot;, &amp;quot;python&amp;quot;)&lt;br /&gt;
sys.path.append(gpydir)&lt;br /&gt;
########&lt;br /&gt;
# define GRASS DATABASE&lt;br /&gt;
if sys.platform.startswith('win'):&lt;br /&gt;
    gisdb = os.path.join(os.getenv('APPDATA', 'grassdata'))&lt;br /&gt;
else:&lt;br /&gt;
    gisdb = os.path.join(os.getenv('HOME', 'grassdata'))&lt;br /&gt;
&lt;br /&gt;
# override for now with TEMP dir&lt;br /&gt;
gisdb = os.path.join(tempfile.gettempdir(), 'grassdata')&lt;br /&gt;
try:&lt;br /&gt;
    os.stat(gisdb)&lt;br /&gt;
except:&lt;br /&gt;
    os.mkdir(gisdb)&lt;br /&gt;
&lt;br /&gt;
# location/mapset: use random names for batch jobs&lt;br /&gt;
string_length = 16&lt;br /&gt;
location = binascii.hexlify(os.urandom(string_length))&lt;br /&gt;
mapset   = 'PERMANENT'&lt;br /&gt;
location_path = os.path.join(gisdb, location)&lt;br /&gt;
&lt;br /&gt;
# Create new location (we assume that grass7bin is in the PATH)&lt;br /&gt;
#  from EPSG code:&lt;br /&gt;
startcmd = grass7bin + ' -c epsg:' + myepsg + ' -e ' + location_path&lt;br /&gt;
#  from SHAPE or GeoTIFF file&lt;br /&gt;
#startcmd = grass7bin + ' -c ' + myfile + ' -e ' + location_path&lt;br /&gt;
&lt;br /&gt;
print startcmd&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=True, &lt;br /&gt;
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, 'ERROR: %s' % err&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, 'ERROR: Cannot generate location (%s)' % startcmd&lt;br /&gt;
    sys.exit(-1)&lt;br /&gt;
else:&lt;br /&gt;
    print 'Created location %s' % location_path&lt;br /&gt;
&lt;br /&gt;
# Now the location with PERMANENT mapset exists.&lt;br /&gt;
&lt;br /&gt;
########&lt;br /&gt;
# Now we can use PyGRASS or GRASS Scripting library etc. after &lt;br /&gt;
# having started the session with gsetup.init() etc&lt;br /&gt;
&lt;br /&gt;
# Set GISDBASE environment variable&lt;br /&gt;
os.environ['GISDBASE'] = gisdb&lt;br /&gt;
&lt;br /&gt;
# Linux: Set path to GRASS libs (TODO: NEEDED?)&lt;br /&gt;
path = os.getenv('LD_LIBRARY_PATH')&lt;br /&gt;
dir  = os.path.join(gisbase, 'lib')&lt;br /&gt;
if path:&lt;br /&gt;
    path = dir + os.pathsep + path&lt;br /&gt;
else:&lt;br /&gt;
    path = dir&lt;br /&gt;
os.environ['LD_LIBRARY_PATH'] = path&lt;br /&gt;
&lt;br /&gt;
# language&lt;br /&gt;
os.environ['LANG'] = 'en_US'&lt;br /&gt;
os.environ['LOCALE'] = 'C'&lt;br /&gt;
&lt;br /&gt;
# Windows: NEEDED?&lt;br /&gt;
#path = os.getenv('PYTHONPATH')&lt;br /&gt;
#dirr = os.path.join(gisbase, 'etc', 'python')&lt;br /&gt;
#if path:&lt;br /&gt;
#    path = dirr + os.pathsep + path&lt;br /&gt;
#else:&lt;br /&gt;
#    path = dirr&lt;br /&gt;
#os.environ['PYTHONPATH'] = path&lt;br /&gt;
&lt;br /&gt;
#print os.environ&lt;br /&gt;
&lt;br /&gt;
## Import GRASS Python bindings&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
import grass.script.setup as gsetup&lt;br /&gt;
&lt;br /&gt;
###########&lt;br /&gt;
# Launch session and do something&lt;br /&gt;
gsetup.init(gisbase, gisdb, location, mapset)&lt;br /&gt;
&lt;br /&gt;
# say hello&lt;br /&gt;
grass.message('--- GRASS GIS 7: Current GRASS GIS 7 environment:')&lt;br /&gt;
print grass.gisenv()&lt;br /&gt;
&lt;br /&gt;
# do something in GRASS now...&lt;br /&gt;
&lt;br /&gt;
grass.message('--- GRASS GIS 7: Checking projection info:')&lt;br /&gt;
in_proj = grass.read_command('g.proj', flags = 'jf')&lt;br /&gt;
&lt;br /&gt;
# selective proj parameter printing&lt;br /&gt;
kv = grass.parse_key_val(in_proj)&lt;br /&gt;
print kv&lt;br /&gt;
print kv['+proj']&lt;br /&gt;
&lt;br /&gt;
# print full proj parameter printing&lt;br /&gt;
in_proj = in_proj.strip()&lt;br /&gt;
grass.message(&amp;quot;--- Found projection parameters: '%s'&amp;quot; % in_proj)&lt;br /&gt;
&lt;br /&gt;
# show current region:&lt;br /&gt;
grass.message('--- GRASS GIS 7: Checking computational region info:')&lt;br /&gt;
in_region = grass.region()&lt;br /&gt;
grass.message(&amp;quot;--- Computational region: '%s'&amp;quot; % in_region)&lt;br /&gt;
&lt;br /&gt;
# do something else: r.mapcalc, v.rectify, ...&lt;br /&gt;
&lt;br /&gt;
# Finally remove the temporary batch location from disk&lt;br /&gt;
print 'Removing location %s' % location_path&lt;br /&gt;
shutil.rmtree(location_path)&lt;br /&gt;
&lt;br /&gt;
sys.exit(0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 6 =====&lt;br /&gt;
&lt;br /&gt;
The script initializes the session and lists available raster maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
gisbase = os.environ['GISBASE'] = &amp;quot;/usr/local/src/grass_trunk/dist.x86_64-unknown-linux-gnu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
gisdbase = os.path.join(os.environ['HOME'], &amp;quot;grassdata&amp;quot;)&lt;br /&gt;
location = &amp;quot;nc_spm_08&amp;quot;&lt;br /&gt;
mapset   = &amp;quot;user1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
sys.path.append(os.path.join(os.environ['GISBASE'], &amp;quot;etc&amp;quot;, &amp;quot;python&amp;quot;))&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
import grass.script.setup as gsetup&lt;br /&gt;
&lt;br /&gt;
gsetup.init(gisbase,&lt;br /&gt;
            gisdbase, location, mapset)&lt;br /&gt;
&lt;br /&gt;
print grass.gisenv()&lt;br /&gt;
&lt;br /&gt;
grass.message('Raster maps:')&lt;br /&gt;
for rast in grass.list_strings(type = 'rast'):&lt;br /&gt;
    print rast&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 with an external library: grass-session =====&lt;br /&gt;
&lt;br /&gt;
The grass-session library is under development. To contribute at the code, documentation and testing it is possible to install the current development version using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pip install git+https://github.com/zarch/grass-session.git&lt;br /&gt;
# in the future the stable release would be available with:&lt;br /&gt;
# pip install grass-session&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then write &lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# filename: test_session.py&lt;br /&gt;
&lt;br /&gt;
from grass_session import Session&lt;br /&gt;
from grass.script import core as gcore&lt;br /&gt;
&lt;br /&gt;
# create a new location&lt;br /&gt;
with Session(gisdb=&amp;quot;/tmp&amp;quot;, location=&amp;quot;location&amp;quot;,&lt;br /&gt;
             create_opts=&amp;quot;EPSG:4326&amp;quot;):&lt;br /&gt;
   # do something in permanent&lt;br /&gt;
   print(gcore.parse_command(&amp;quot;g.gisenv&amp;quot;, flags=&amp;quot;s&amp;quot;))&lt;br /&gt;
# {u'GISDBASE': u&amp;quot;'/tmp/';&amp;quot;,&lt;br /&gt;
#  u'LOCATION_NAME': u&amp;quot;'epsg3035';&amp;quot;,&lt;br /&gt;
#  u'MAPSET': u&amp;quot;'PERMANENT';&amp;quot;,}&lt;br /&gt;
&lt;br /&gt;
# create a new mapset in an existing location&lt;br /&gt;
with Session(gisdb=&amp;quot;/tmp&amp;quot;, location=&amp;quot;location&amp;quot;, mapset=&amp;quot;test&amp;quot;,&lt;br /&gt;
             create_opts=&amp;quot;&amp;quot;):&lt;br /&gt;
    # do something in the test mapset.&lt;br /&gt;
    print(gcore.parse_command(&amp;quot;g.gisenv&amp;quot;, flags=&amp;quot;s&amp;quot;))&lt;br /&gt;
# {u'GISDBASE': u&amp;quot;'/tmp/';&amp;quot;,&lt;br /&gt;
#  u'LOCATION_NAME': u&amp;quot;'epsg3035';&amp;quot;,&lt;br /&gt;
#  u'MAPSET': u&amp;quot;'test';&amp;quot;,}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The grass-session library look at the GRASSBIN environmental variable if not set by default try to use the current stable release of grass (e.g. grass74).&lt;br /&gt;
For instance, to execute the previous example using grass75, write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
GRASSBIN=$HOME/.local/bin/grass75 python test_session.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Bash examples (GNU/Linux) ====&lt;br /&gt;
&lt;br /&gt;
'''''Note: see [[GRASS_and_Shell#GRASS_Batch_jobs|GRASS Batch jobs]] for a really easy approach.'''''&lt;br /&gt;
&lt;br /&gt;
Below an example of a '''~/.bash_profile''' script to set the required settings in order to access GRASS commands outside of a GRASS-session. Specifically it is for GRASS 7 (commented parts for GRASS 6.4.2):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
# example for GRASS 7&lt;br /&gt;
export GISBASE=/usr/local/grass-7.2.svn&lt;br /&gt;
# example for GRASS 6.4.2&lt;br /&gt;
### export GISBASE=/usr/local/grass-6.4.2svn&lt;br /&gt;
&lt;br /&gt;
# GRASS 7&lt;br /&gt;
export GRASS_VERSION=&amp;quot;7.2.svn&amp;quot;&lt;br /&gt;
# GRASS 6.4.2&lt;br /&gt;
### export GRASS_VERSION=&amp;quot;6.4.2svn&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#generate GISRCRC&lt;br /&gt;
MYGISDBASE=$HOME/grassdata&lt;br /&gt;
MYLOC=nc_spm_08&lt;br /&gt;
MYMAPSET=user1&lt;br /&gt;
&lt;br /&gt;
# Set the global grassrc file to individual file name&lt;br /&gt;
MYGISRC=&amp;quot;$HOME/.grassrc.$GRASS_VERSION.$$&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;GISDBASE: $MYGISDBASE&amp;quot; &amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;LOCATION_NAME: $MYLOC&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;MAPSET: $MYMAPSET&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;GRASS_GUI: text&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# path to GRASS settings file&lt;br /&gt;
export GISRC=$MYGISRC&lt;br /&gt;
export GRASS_PYTHON=python&lt;br /&gt;
export GRASS_MESSAGE_FORMAT=plain&lt;br /&gt;
export GRASS_TRUECOLOR=TRUE&lt;br /&gt;
export GRASS_TRANSPARENT=TRUE&lt;br /&gt;
export GRASS_PNG_AUTO_WRITE=TRUE&lt;br /&gt;
export GRASS_GNUPLOT='gnuplot -persist'&lt;br /&gt;
export GRASS_WIDTH=640&lt;br /&gt;
export GRASS_HEIGHT=480&lt;br /&gt;
export GRASS_HTML_BROWSER=firefox&lt;br /&gt;
export GRASS_PAGER=cat&lt;br /&gt;
export GRASS_WISH=wish&lt;br /&gt;
        &lt;br /&gt;
export PATH=&amp;quot;$GISBASE/bin:$GISBASE/scripts:$PATH&amp;quot;&lt;br /&gt;
export LD_LIBRARY_PATH=&amp;quot;$GISBASE/lib&amp;quot;&lt;br /&gt;
export GRASS_LD_LIBRARY_PATH=&amp;quot;$LD_LIBRARY_PATH&amp;quot;&lt;br /&gt;
export PYTHONPATH=&amp;quot;$GISBASE/etc/python:$PYTHONPATH&amp;quot;&lt;br /&gt;
export MANPATH=$MANPATH:$GISBASE/man&lt;br /&gt;
&lt;br /&gt;
#For the temporal modules&lt;br /&gt;
export TGISDB_DRIVER=sqlite&lt;br /&gt;
export TGISDB_DATABASE=$MYGISDBASE/$MYLOC/PERMANENT/tgis/sqlite.db&lt;br /&gt;
&lt;br /&gt;
# test a command&lt;br /&gt;
g.list rast&lt;br /&gt;
&lt;br /&gt;
######### below not needed ########&lt;br /&gt;
# GRASS 7&lt;br /&gt;
tmp=/tmp/grass7-&amp;quot;`whoami`&amp;quot;-$GIS_LOCK&lt;br /&gt;
# GRASS 6.4.2&lt;br /&gt;
### tmp=/tmp/grass6-&amp;quot;`whoami`&amp;quot;-$GIS_LOCK&lt;br /&gt;
&lt;br /&gt;
export GISRC=&amp;quot;$tmp/rc&amp;quot;&lt;br /&gt;
mkdir &amp;quot;$tmp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# GRASS 7&lt;br /&gt;
cp ~/.grass7/rc &amp;quot;$GISRC&amp;quot;&lt;br /&gt;
# GRASS 6.4.2&lt;br /&gt;
### cp ~/.grassrc6 &amp;quot;$GISRC&amp;quot;&lt;br /&gt;
######### END below not needed ########&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above script will allow GRASS commands to be used anywhere. Furthermore, if the '''~/.Xsession''' sources the bash startup scripts, the settings aren't limited to interactive shells, but also work for e.g. M-! in XEmacs). Each interactive shell gets a separate &amp;quot;session&amp;quot; (i.e. a separate $GISRC file), while GUI programs share a common session.&lt;br /&gt;
&lt;br /&gt;
Note, however, that '''~/.bash_profile''' is a personal initialization startup script and, thus, read during the login process. Any modifications to it will be read after (re-)login or explicitly sourcing it.&lt;br /&gt;
&lt;br /&gt;
At the end of the ~/.bash_profile file, the following lines can be added to ensure no duplication of entries in the PATH variable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 PATH=`awk -F: '{for(i=1;i&amp;lt;=NF;i++){if(!($i in a)){a[$i];printf s$i;s=&amp;quot;:&amp;quot;}}}'&amp;lt;&amp;lt;&amp;lt;$PATH`&lt;br /&gt;
 PYTHONPATH=`awk -F: '{for(i=1;i&amp;lt;=NF;i++){if(!($i in a)){a[$i];printf s$i;s=&amp;quot;:&amp;quot;}}}'&amp;lt;&amp;lt;&amp;lt;$PYTHONPATH`&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Important notes ===&lt;br /&gt;
&lt;br /&gt;
Launching a grassXY session could still permit access on GRASS modules of the version that is set with the above script. The reason being is that grassXY scripts (e.g.: grass64, grass65, grass72) prepend the GRASS directories to '''PATH''', '''LD_LIBRARY_PATH''', etc. They won't remove any entries which are already there. A solution to this is to ''switch'' between GRASS versions by using a script like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
        strippath()&lt;br /&gt;
        {&lt;br /&gt;
            (&lt;br /&gt;
            oldpath=&amp;quot;$1&amp;quot;&lt;br /&gt;
            newpath=&lt;br /&gt;
            IFS=:&lt;br /&gt;
            for dir in $oldpath ; do&lt;br /&gt;
                case &amp;quot;${dir}&amp;quot; in&lt;br /&gt;
                *grass*)&lt;br /&gt;
                        ;;&lt;br /&gt;
                *)&lt;br /&gt;
                        newpath=&amp;quot;$newpath:$dir&amp;quot;&lt;br /&gt;
                        ;;&lt;br /&gt;
                esac&lt;br /&gt;
            done&lt;br /&gt;
            echo &amp;quot;${newpath#:}&amp;quot;&lt;br /&gt;
            )&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        PATH=`strippath $PATH`&lt;br /&gt;
        &lt;br /&gt;
        export GISBASE=$PWD/dist.i686-pc-linux-gnu&lt;br /&gt;
        export PATH=&amp;quot;$GISBASE/bin:$GISBASE/scripts:$PATH&amp;quot;&lt;br /&gt;
        export LD_LIBRARY_PATH=&amp;quot;$GISBASE/lib&amp;quot;&lt;br /&gt;
        export PYTHONPATH=&amp;quot;$GISBASE/etc/python&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note: the above script needs to be &amp;quot;source&amp;quot;d; executing it won't work. It might also require some adjustments (e.g. the ''GISBASE'' variable).'''&lt;br /&gt;
&lt;br /&gt;
Using normal grass sessions commands are recorded in '''$GISDBASE/$LOCATION_NAME/$MAPSET/.bash_history'''. While working with &amp;quot;pure&amp;quot; bash, shell entries go in '''~/.bash_history'''. Merging existing &amp;quot;grass-bash_history(-ies)&amp;quot; with the bash history log, would probably be not a good idea. Perhaps it is wise(r) to use normal GRASS sessions when working on real projects. Nevertheless, it is upon the users preferences and expertise level to decide what is best.&lt;br /&gt;
&lt;br /&gt;
=== Hints and troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
Some hints for MS Windows users:&lt;br /&gt;
&lt;br /&gt;
# The Python interpreter (python.exe) needs to be in the PATH&lt;br /&gt;
# Python needs to be associated with the .py extension&lt;br /&gt;
# PATHEXT needs to include .py if you want to be able to omit the extension&lt;br /&gt;
&lt;br /&gt;
When everything works well, the installer should take care of all of these.&lt;br /&gt;
&lt;br /&gt;
To manage parallel sessions on Linux, use process ID (PID) as lock file number and set the GIS_LOCK variable, for example&lt;br /&gt;
&lt;br /&gt;
  export GIS_LOCK=$$&lt;br /&gt;
&lt;br /&gt;
in Bash.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* Instructions and discussion on [http://n2.nabble.com/can-I-access-mapset-outside-of-grass-by-using-python-td3405902.html#a3405902 how to access GRASS mapsets outside of a GRASS session] in the grass-user mailing list.&lt;br /&gt;
* removing duplicate entries in $PATH taken from [http://chunchung.blogspot.com/2007/11/remove-duplicate-paths-from-path-in.html]&lt;br /&gt;
&lt;br /&gt;
== GRASS databases ==&lt;br /&gt;
&lt;br /&gt;
(project file structure)&lt;br /&gt;
&lt;br /&gt;
=== Minimal mapsets ===&lt;br /&gt;
&lt;br /&gt;
within a functional LOCATION (see below) the minimal mapset is a subdirectory of the MAPSET's name, containing a WIND file. The WIND file can simply be copied from PERMANENT/DEFAULT_WIND. Optionally you can put a VAR file in there too to define the default database driver to use.&lt;br /&gt;
&lt;br /&gt;
* You can create a new mapset when starting GRASS with the -c flag. e.g.&lt;br /&gt;
 grass64 -c /path/to/location/new_mapset_name&lt;br /&gt;
&lt;br /&gt;
=== Minimal locations ===&lt;br /&gt;
&lt;br /&gt;
Within the GISDATABASE (which is simply a subdirectory some where), the minimum LOCATION consists of a directory giving the LOCATION its name, which in turn contains a PERMANENT subdirectory for the PERMANENT mapset. The PERMANENT mapset contains a few special files that regular mapsets don't. These are:&lt;br /&gt;
; PROJ_INFO: contains the location's projection information&lt;br /&gt;
; PROJ_UNITS: contains the location's map units definition&lt;br /&gt;
; DEFAULT_WIND: the default region (WINDow file). The format is identical to the WIND files created by g.region&lt;br /&gt;
; WIND: (optional?)&lt;br /&gt;
&lt;br /&gt;
* see also {{src|demolocation}} in the GRASS source code&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[GRASS_and_Shell#GRASS_Batch_jobs|GRASS Batch jobs]]&lt;br /&gt;
&lt;br /&gt;
[[Category: FAQ]]&lt;br /&gt;
[[Category: Linking to other languages]]&lt;br /&gt;
[[Category: bash]]&lt;br /&gt;
[[Category:Scripting]]&lt;br /&gt;
[[Category: Python]]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Working_with_GRASS_without_starting_it_explicitly&amp;diff=24906</id>
		<title>Working with GRASS without starting it explicitly</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Working_with_GRASS_without_starting_it_explicitly&amp;diff=24906"/>
		<updated>2017-12-11T19:11:24Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Python examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GRASS GIS modules and the import of GRASS Python packages works only in a specific environmental settings (GRASS session). This settings is ensured by starting GRASS GIS application which prepares this GRASS session for you. It is possible to set up you system in the way that the GRASS session will be always active (i.e. the GRASS startup script is not running, just the environmental settings are done). People often prefer to set up the GRASS environment in their script or program and this is what this article discuss. However, it must be noted that the the generally preferred (and easy) way is to create scripts and programs as GRASS modules which means that your don't have to bother with setting up the environment since the GRASS module should be always invoked only in GRASS session.&lt;br /&gt;
&lt;br /&gt;
== GRASS sessions ==&lt;br /&gt;
&lt;br /&gt;
It is possible to access GRASS modules without explicitly starting a &amp;quot;GRASS session&amp;quot;. GRASS libraries require certain [http://grass.osgeo.org/grass72/manuals/variables.html environment variables] to be set. In fact a &amp;quot;GRASS session&amp;quot; is just a set of processes (e.g. a shell and/or GUI) which have the necessary environment settings, specifically:&lt;br /&gt;
&lt;br /&gt;
* '''GISBASE''' needs to be set to the top-level directory of the GRASS installation.&lt;br /&gt;
* '''GISRC''' needs to contain the absolute path to a file containing settings for '''GISDBASE''', '''LOCATION_NAME''' and '''MAPSET'''.&lt;br /&gt;
* '''PATH''' needs to include '''$GISBASE/bin''' and '''$GISBASE/scripts'''.&lt;br /&gt;
&lt;br /&gt;
If the GRASS libraries are shared libraries, the loader needs to be able to find them. This normally means that '''LD_LIBRARY_PATH''' (Linux, Solaris), '''DYLD_LIBRARY_PATH''' (MacOSX) or '''PATH''' (Windows) need to contain '''$GISBASE/lib''', although there are other means to the same end (e.g. on Linux, putting $GISBASE/lib (with $GISBASE replaced by its actual value) into /etc/ld.so.conf then running ldconfig).&lt;br /&gt;
&lt;br /&gt;
Some libraries and modules use other variables. More information for most of them is available in the file ''$GISBASE/docs/html/variables.html''. The display libraries used by ''d.*'' commands use additional variables, which are documented along with the individual drivers.&lt;br /&gt;
&lt;br /&gt;
=== Batch jobs ===&lt;br /&gt;
&lt;br /&gt;
You can run GRASS scripts non-interactively from outside of a GRASS session with the GRASS_BATCH_JOB environment variable. When GRASS is started with this environment variable set it will automatically run the contents of the script given in the variable, then close the GRASS session when complete. In this way full lock-checking, GRASS variables setup, and temporary file cleaning tasks are still performed.&lt;br /&gt;
&lt;br /&gt;
See the [[GRASS_and_Shell#GRASS_Batch_jobs|Batch jobs]] section of the GRASS shell-help wiki page for details.&lt;br /&gt;
&lt;br /&gt;
=== Accessing GRASS modules without starting a GRASS session ===&lt;br /&gt;
&lt;br /&gt;
==== The easiest way: the --exec flag ====&lt;br /&gt;
&lt;br /&gt;
Since GRASS GIS 7.2.x you can execute commands from outside by passing the command to be executed (or a script with a collection of GRASS GIS commands) to the --exec flag:&lt;br /&gt;
&lt;br /&gt;
Creating a new Location based on a geodata file's projection (-c) and exit (-e) immediately:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 -c elevation.tiff -e /path/to/grassdata/test1/&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Linking external raster data to PERMANENT Mapset:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ --exec r.external input=basins.tiff output=basins&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ --exec r.external input=elevation.tiff output=elevation&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get statistics for one raster map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ --exec r.univar map=elevation&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compare the rasters visually:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grass72 /path/to/grassdata/test1/PERMANENT/ --exec g.gui.mapswipe first=elevation second=basins&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read more in the [https://grass.osgeo.org/grass72/manuals/grass7.html#batch-jobs-with-the-exec-interface manual].&lt;br /&gt;
&lt;br /&gt;
==== Python examples ====&lt;br /&gt;
&lt;br /&gt;
See also [[GRASS Python Scripting Library]]&lt;br /&gt;
&lt;br /&gt;
===== Hint: find the path to the GRASS GIS package =====&lt;br /&gt;
&lt;br /&gt;
Hint: in order to find the '''path to the GRASS GIS package''', launch it with &amp;lt;tt&amp;gt; --config path&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Linux&lt;br /&gt;
grass72 --config path&lt;br /&gt;
/usr/bin/grass-7.2.0&lt;br /&gt;
&lt;br /&gt;
# Windows&lt;br /&gt;
C:\&amp;gt;grass72.bat --config path&lt;br /&gt;
C:\OSGeo4W\apps\grass\grass-7.2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 with existing location =====&lt;br /&gt;
&lt;br /&gt;
See the example in the [https://grass.osgeo.org/grass72/manuals/libpython/script.html#module-script.setup documentation] or the script which initializes the session and lists available raster and vector maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import subprocess&lt;br /&gt;
&lt;br /&gt;
# path to the GRASS GIS launch script&lt;br /&gt;
# MS Windows&lt;br /&gt;
grass7bin_win = r'C:\OSGeo4W\bin\grass72svn.bat'&lt;br /&gt;
# uncomment when using standalone WinGRASS installer&lt;br /&gt;
# grass7bin_win = r'C:\Program Files (x86)\GRASS GIS 7.2.0\grass72.bat'&lt;br /&gt;
# Linux&lt;br /&gt;
grass7bin_lin = 'grass72'&lt;br /&gt;
# Mac OS X&lt;br /&gt;
# this is TODO&lt;br /&gt;
grass7bin_mac = '/Applications/GRASS/GRASS-7.2.app/'&lt;br /&gt;
&lt;br /&gt;
# DATA&lt;br /&gt;
# define GRASS DATABASE&lt;br /&gt;
# add your path to grassdata (GRASS GIS database) directory&lt;br /&gt;
gisdb = os.path.join(os.path.expanduser(&amp;quot;~&amp;quot;), &amp;quot;grassdata&amp;quot;)&lt;br /&gt;
# the following path is the default path on MS Windows&lt;br /&gt;
# gisdb = os.path.join(os.path.expanduser(&amp;quot;~&amp;quot;), &amp;quot;Documents/grassdata&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# specify (existing) location and mapset&lt;br /&gt;
location = &amp;quot;nc_spm_08&amp;quot;&lt;br /&gt;
mapset   = &amp;quot;user1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
########### SOFTWARE&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
    # we assume that the GRASS GIS start script is available and in the PATH&lt;br /&gt;
    # query GRASS 7 itself for its GISBASE&lt;br /&gt;
    grass7bin = grass7bin_lin&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    grass7bin = grass7bin_win&lt;br /&gt;
else:&lt;br /&gt;
    raise OSError('Platform not configured.')&lt;br /&gt;
&lt;br /&gt;
# query GRASS 7 itself for its GISBASE&lt;br /&gt;
startcmd = [grass7bin, '--config', 'path']&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=False,&lt;br /&gt;
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, &amp;quot;ERROR: Cannot find GRASS GIS 7 start script (%s)&amp;quot; % startcmd&lt;br /&gt;
    sys.exit(-1)&lt;br /&gt;
gisbase = out.strip('\n\r')&lt;br /&gt;
&lt;br /&gt;
# Set GISBASE environment variable&lt;br /&gt;
os.environ['GISBASE'] = gisbase&lt;br /&gt;
# the following not needed with trunk&lt;br /&gt;
os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'extrabin')&lt;br /&gt;
# add path to GRASS addons&lt;br /&gt;
home = os.path.expanduser(&amp;quot;~&amp;quot;)&lt;br /&gt;
os.environ['PATH'] += os.pathsep + os.path.join(home, '.grass7', 'addons', 'scripts')&lt;br /&gt;
&lt;br /&gt;
# define GRASS-Python environment&lt;br /&gt;
gpydir = os.path.join(gisbase, &amp;quot;etc&amp;quot;, &amp;quot;python&amp;quot;)&lt;br /&gt;
sys.path.append(gpydir)&lt;br /&gt;
&lt;br /&gt;
########### DATA&lt;br /&gt;
# Set GISDBASE environment variable&lt;br /&gt;
os.environ['GISDBASE'] = gisdb&lt;br /&gt;
 &lt;br /&gt;
# import GRASS Python bindings (see also pygrass)&lt;br /&gt;
import grass.script as gscript&lt;br /&gt;
import grass.script.setup as gsetup&lt;br /&gt;
 &lt;br /&gt;
###########&lt;br /&gt;
# launch session&lt;br /&gt;
gsetup.init(gisbase,&lt;br /&gt;
            gisdb, location, mapset)&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Current GRASS GIS 7 environment:')&lt;br /&gt;
print gscript.gisenv()&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Available raster maps:')&lt;br /&gt;
for rast in gscript.list_strings(type = 'rast'):&lt;br /&gt;
    print rast&lt;br /&gt;
 &lt;br /&gt;
gscript.message('Available vector maps:')&lt;br /&gt;
for vect in gscript.list_strings(type = 'vect'):&lt;br /&gt;
    print vect&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 without existing location using metadata only =====&lt;br /&gt;
&lt;br /&gt;
The script initializes the session, creates a temporary GRASS location and lists available raster and vector maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
# Python script to generate a new GRASS GIS 7 location simply from metadata&lt;br /&gt;
# Markus Neteler, 2014&lt;br /&gt;
&lt;br /&gt;
# ?? LINUX USAGE: First set LIBRARY SEARCH PATH&lt;br /&gt;
#export LD_LIBRARY_PATH=$(grass72 --config path)/lib&lt;br /&gt;
#python start_grass7_create_new_location_ADVANCED.py&lt;br /&gt;
&lt;br /&gt;
# some predefined variables&lt;br /&gt;
&lt;br /&gt;
# Windows&lt;br /&gt;
grass7path = r'C:\OSGeo4W\apps\grass\grass-7.2.svn'&lt;br /&gt;
grass7bin_win = r'C:\OSGeo4W\bin\grass72svn.bat'&lt;br /&gt;
# Linux&lt;br /&gt;
grass7bin_lin = 'grass72'&lt;br /&gt;
# MacOSX&lt;br /&gt;
grass7bin_mac = '/Applications/GRASS/GRASS-7.1.app/'&lt;br /&gt;
#myepsg = '4326' # latlong&lt;br /&gt;
myepsg = '3044' # ETRS-TM32, http://spatialreference.org/ref/epsg/3044/&lt;br /&gt;
#myfile = '/home/neteler/markus_repo/books/kluwerbook/data3rd/lidar/lidar_raleigh_nc_spm.shp'&lt;br /&gt;
myfile = '/data/maps/world_natural_earth_250m/europe_north_east.tif'&lt;br /&gt;
#myfile = r'C:\Dati\Padergnone\square_p95.tif'&lt;br /&gt;
&lt;br /&gt;
###########&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import subprocess&lt;br /&gt;
import shutil&lt;br /&gt;
import binascii&lt;br /&gt;
import tempfile&lt;br /&gt;
&lt;br /&gt;
########### SOFTWARE&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
    # we assume that the GRASS GIS start script is available and in the PATH&lt;br /&gt;
    # query GRASS 7 itself for its GISBASE&lt;br /&gt;
    grass7bin = grass7bin_lin&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    grass7bin = grass7bin_win&lt;br /&gt;
else:&lt;br /&gt;
    OSError('Platform not configured.')&lt;br /&gt;
&lt;br /&gt;
startcmd = grass7bin + ' --config path'&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=True, &lt;br /&gt;
					 stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
	print &amp;gt;&amp;gt;sys.stderr, 'ERROR: %s' % err&lt;br /&gt;
	print &amp;gt;&amp;gt;sys.stderr, &amp;quot;ERROR: Cannot find GRASS GIS 7 start script (%s)&amp;quot; % startcmd&lt;br /&gt;
	sys.exit(-1)&lt;br /&gt;
if sys.platform.startswith('linux'):&lt;br /&gt;
	gisbase = out.strip('\n')&lt;br /&gt;
elif sys.platform.startswith('win'):&lt;br /&gt;
    if out.find(&amp;quot;OSGEO4W home is&amp;quot;) != -1:&lt;br /&gt;
		gisbase = out.strip().split('\n')[1]&lt;br /&gt;
    else:&lt;br /&gt;
		gisbase = out.strip('\n')&lt;br /&gt;
    os.environ['GRASS_SH'] = os.path.join(gisbase, 'msys', 'bin', 'sh.exe')&lt;br /&gt;
&lt;br /&gt;
# Set GISBASE environment variable&lt;br /&gt;
os.environ['GISBASE'] = gisbase&lt;br /&gt;
# define GRASS-Python environment&lt;br /&gt;
gpydir = os.path.join(gisbase, &amp;quot;etc&amp;quot;, &amp;quot;python&amp;quot;)&lt;br /&gt;
sys.path.append(gpydir)&lt;br /&gt;
########&lt;br /&gt;
# define GRASS DATABASE&lt;br /&gt;
if sys.platform.startswith('win'):&lt;br /&gt;
    gisdb = os.path.join(os.getenv('APPDATA', 'grassdata'))&lt;br /&gt;
else:&lt;br /&gt;
    gisdb = os.path.join(os.getenv('HOME', 'grassdata'))&lt;br /&gt;
&lt;br /&gt;
# override for now with TEMP dir&lt;br /&gt;
gisdb = os.path.join(tempfile.gettempdir(), 'grassdata')&lt;br /&gt;
try:&lt;br /&gt;
    os.stat(gisdb)&lt;br /&gt;
except:&lt;br /&gt;
    os.mkdir(gisdb)&lt;br /&gt;
&lt;br /&gt;
# location/mapset: use random names for batch jobs&lt;br /&gt;
string_length = 16&lt;br /&gt;
location = binascii.hexlify(os.urandom(string_length))&lt;br /&gt;
mapset   = 'PERMANENT'&lt;br /&gt;
location_path = os.path.join(gisdb, location)&lt;br /&gt;
&lt;br /&gt;
# Create new location (we assume that grass7bin is in the PATH)&lt;br /&gt;
#  from EPSG code:&lt;br /&gt;
startcmd = grass7bin + ' -c epsg:' + myepsg + ' -e ' + location_path&lt;br /&gt;
#  from SHAPE or GeoTIFF file&lt;br /&gt;
#startcmd = grass7bin + ' -c ' + myfile + ' -e ' + location_path&lt;br /&gt;
&lt;br /&gt;
print startcmd&lt;br /&gt;
p = subprocess.Popen(startcmd, shell=True, &lt;br /&gt;
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
out, err = p.communicate()&lt;br /&gt;
if p.returncode != 0:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, 'ERROR: %s' % err&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, 'ERROR: Cannot generate location (%s)' % startcmd&lt;br /&gt;
    sys.exit(-1)&lt;br /&gt;
else:&lt;br /&gt;
    print 'Created location %s' % location_path&lt;br /&gt;
&lt;br /&gt;
# Now the location with PERMANENT mapset exists.&lt;br /&gt;
&lt;br /&gt;
########&lt;br /&gt;
# Now we can use PyGRASS or GRASS Scripting library etc. after &lt;br /&gt;
# having started the session with gsetup.init() etc&lt;br /&gt;
&lt;br /&gt;
# Set GISDBASE environment variable&lt;br /&gt;
os.environ['GISDBASE'] = gisdb&lt;br /&gt;
&lt;br /&gt;
# Linux: Set path to GRASS libs (TODO: NEEDED?)&lt;br /&gt;
path = os.getenv('LD_LIBRARY_PATH')&lt;br /&gt;
dir  = os.path.join(gisbase, 'lib')&lt;br /&gt;
if path:&lt;br /&gt;
    path = dir + os.pathsep + path&lt;br /&gt;
else:&lt;br /&gt;
    path = dir&lt;br /&gt;
os.environ['LD_LIBRARY_PATH'] = path&lt;br /&gt;
&lt;br /&gt;
# language&lt;br /&gt;
os.environ['LANG'] = 'en_US'&lt;br /&gt;
os.environ['LOCALE'] = 'C'&lt;br /&gt;
&lt;br /&gt;
# Windows: NEEDED?&lt;br /&gt;
#path = os.getenv('PYTHONPATH')&lt;br /&gt;
#dirr = os.path.join(gisbase, 'etc', 'python')&lt;br /&gt;
#if path:&lt;br /&gt;
#    path = dirr + os.pathsep + path&lt;br /&gt;
#else:&lt;br /&gt;
#    path = dirr&lt;br /&gt;
#os.environ['PYTHONPATH'] = path&lt;br /&gt;
&lt;br /&gt;
#print os.environ&lt;br /&gt;
&lt;br /&gt;
## Import GRASS Python bindings&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
import grass.script.setup as gsetup&lt;br /&gt;
&lt;br /&gt;
###########&lt;br /&gt;
# Launch session and do something&lt;br /&gt;
gsetup.init(gisbase, gisdb, location, mapset)&lt;br /&gt;
&lt;br /&gt;
# say hello&lt;br /&gt;
grass.message('--- GRASS GIS 7: Current GRASS GIS 7 environment:')&lt;br /&gt;
print grass.gisenv()&lt;br /&gt;
&lt;br /&gt;
# do something in GRASS now...&lt;br /&gt;
&lt;br /&gt;
grass.message('--- GRASS GIS 7: Checking projection info:')&lt;br /&gt;
in_proj = grass.read_command('g.proj', flags = 'jf')&lt;br /&gt;
&lt;br /&gt;
# selective proj parameter printing&lt;br /&gt;
kv = grass.parse_key_val(in_proj)&lt;br /&gt;
print kv&lt;br /&gt;
print kv['+proj']&lt;br /&gt;
&lt;br /&gt;
# print full proj parameter printing&lt;br /&gt;
in_proj = in_proj.strip()&lt;br /&gt;
grass.message(&amp;quot;--- Found projection parameters: '%s'&amp;quot; % in_proj)&lt;br /&gt;
&lt;br /&gt;
# show current region:&lt;br /&gt;
grass.message('--- GRASS GIS 7: Checking computational region info:')&lt;br /&gt;
in_region = grass.region()&lt;br /&gt;
grass.message(&amp;quot;--- Computational region: '%s'&amp;quot; % in_region)&lt;br /&gt;
&lt;br /&gt;
# do something else: r.mapcalc, v.rectify, ...&lt;br /&gt;
&lt;br /&gt;
# Finally remove the temporary batch location from disk&lt;br /&gt;
print 'Removing location %s' % location_path&lt;br /&gt;
shutil.rmtree(location_path)&lt;br /&gt;
&lt;br /&gt;
sys.exit(0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 6 =====&lt;br /&gt;
&lt;br /&gt;
The script initializes the session and lists available raster maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
gisbase = os.environ['GISBASE'] = &amp;quot;/usr/local/src/grass_trunk/dist.x86_64-unknown-linux-gnu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
gisdbase = os.path.join(os.environ['HOME'], &amp;quot;grassdata&amp;quot;)&lt;br /&gt;
location = &amp;quot;nc_spm_08&amp;quot;&lt;br /&gt;
mapset   = &amp;quot;user1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
sys.path.append(os.path.join(os.environ['GISBASE'], &amp;quot;etc&amp;quot;, &amp;quot;python&amp;quot;))&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
import grass.script.setup as gsetup&lt;br /&gt;
&lt;br /&gt;
gsetup.init(gisbase,&lt;br /&gt;
            gisdbase, location, mapset)&lt;br /&gt;
&lt;br /&gt;
print grass.gisenv()&lt;br /&gt;
&lt;br /&gt;
grass.message('Raster maps:')&lt;br /&gt;
for rast in grass.list_strings(type = 'rast'):&lt;br /&gt;
    print rast&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Python: GRASS GIS 7 with an external library: grass-session =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pip install grass-session&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then write &lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
from grass_session import Session&lt;br /&gt;
from grass.script import core as gcore&lt;br /&gt;
&lt;br /&gt;
# create a new location&lt;br /&gt;
with Session(gisdb=&amp;quot;/tmp&amp;quot;, location=&amp;quot;location&amp;quot;,&lt;br /&gt;
             create_opts=&amp;quot;EPSG:4326&amp;quot;):&lt;br /&gt;
   # do something in permanent&lt;br /&gt;
   print(gcore.parse_command(&amp;quot;g.gisenv&amp;quot;, flags=&amp;quot;s&amp;quot;))&lt;br /&gt;
# {u'GISDBASE': u&amp;quot;'/tmp/';&amp;quot;,&lt;br /&gt;
#  u'LOCATION_NAME': u&amp;quot;'epsg3035';&amp;quot;,&lt;br /&gt;
#  u'MAPSET': u&amp;quot;'PERMANENT';&amp;quot;,}&lt;br /&gt;
&lt;br /&gt;
# create a new mapset in an existing location&lt;br /&gt;
with Session(gisdb=&amp;quot;/tmp&amp;quot;, location=&amp;quot;location&amp;quot;, mapset=&amp;quot;test&amp;quot;,&lt;br /&gt;
             create_opts=&amp;quot;&amp;quot;):&lt;br /&gt;
    # do something in the test mapset.&lt;br /&gt;
    print(gcore.parse_command(&amp;quot;g.gisenv&amp;quot;, flags=&amp;quot;s&amp;quot;))&lt;br /&gt;
# {u'GISDBASE': u&amp;quot;'/tmp/';&amp;quot;,&lt;br /&gt;
#  u'LOCATION_NAME': u&amp;quot;'epsg3035';&amp;quot;,&lt;br /&gt;
#  u'MAPSET': u&amp;quot;'test';&amp;quot;,}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Bash examples (GNU/Linux) ====&lt;br /&gt;
&lt;br /&gt;
'''''Note: see [[GRASS_and_Shell#GRASS_Batch_jobs|GRASS Batch jobs]] for a really easy approach.'''''&lt;br /&gt;
&lt;br /&gt;
Below an example of a '''~/.bash_profile''' script to set the required settings in order to access GRASS commands outside of a GRASS-session. Specifically it is for GRASS 7 (commented parts for GRASS 6.4.2):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
# example for GRASS 7&lt;br /&gt;
export GISBASE=/usr/local/grass-7.2.svn&lt;br /&gt;
# example for GRASS 6.4.2&lt;br /&gt;
### export GISBASE=/usr/local/grass-6.4.2svn&lt;br /&gt;
&lt;br /&gt;
# GRASS 7&lt;br /&gt;
export GRASS_VERSION=&amp;quot;7.2.svn&amp;quot;&lt;br /&gt;
# GRASS 6.4.2&lt;br /&gt;
### export GRASS_VERSION=&amp;quot;6.4.2svn&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#generate GISRCRC&lt;br /&gt;
MYGISDBASE=$HOME/grassdata&lt;br /&gt;
MYLOC=nc_spm_08&lt;br /&gt;
MYMAPSET=user1&lt;br /&gt;
&lt;br /&gt;
# Set the global grassrc file to individual file name&lt;br /&gt;
MYGISRC=&amp;quot;$HOME/.grassrc.$GRASS_VERSION.$$&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;GISDBASE: $MYGISDBASE&amp;quot; &amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;LOCATION_NAME: $MYLOC&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;MAPSET: $MYMAPSET&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
echo &amp;quot;GRASS_GUI: text&amp;quot; &amp;gt;&amp;gt; &amp;quot;$MYGISRC&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# path to GRASS settings file&lt;br /&gt;
export GISRC=$MYGISRC&lt;br /&gt;
export GRASS_PYTHON=python&lt;br /&gt;
export GRASS_MESSAGE_FORMAT=plain&lt;br /&gt;
export GRASS_TRUECOLOR=TRUE&lt;br /&gt;
export GRASS_TRANSPARENT=TRUE&lt;br /&gt;
export GRASS_PNG_AUTO_WRITE=TRUE&lt;br /&gt;
export GRASS_GNUPLOT='gnuplot -persist'&lt;br /&gt;
export GRASS_WIDTH=640&lt;br /&gt;
export GRASS_HEIGHT=480&lt;br /&gt;
export GRASS_HTML_BROWSER=firefox&lt;br /&gt;
export GRASS_PAGER=cat&lt;br /&gt;
export GRASS_WISH=wish&lt;br /&gt;
        &lt;br /&gt;
export PATH=&amp;quot;$GISBASE/bin:$GISBASE/scripts:$PATH&amp;quot;&lt;br /&gt;
export LD_LIBRARY_PATH=&amp;quot;$GISBASE/lib&amp;quot;&lt;br /&gt;
export GRASS_LD_LIBRARY_PATH=&amp;quot;$LD_LIBRARY_PATH&amp;quot;&lt;br /&gt;
export PYTHONPATH=&amp;quot;$GISBASE/etc/python:$PYTHONPATH&amp;quot;&lt;br /&gt;
export MANPATH=$MANPATH:$GISBASE/man&lt;br /&gt;
&lt;br /&gt;
#For the temporal modules&lt;br /&gt;
export TGISDB_DRIVER=sqlite&lt;br /&gt;
export TGISDB_DATABASE=$MYGISDBASE/$MYLOC/PERMANENT/tgis/sqlite.db&lt;br /&gt;
&lt;br /&gt;
# test a command&lt;br /&gt;
g.list rast&lt;br /&gt;
&lt;br /&gt;
######### below not needed ########&lt;br /&gt;
# GRASS 7&lt;br /&gt;
tmp=/tmp/grass7-&amp;quot;`whoami`&amp;quot;-$GIS_LOCK&lt;br /&gt;
# GRASS 6.4.2&lt;br /&gt;
### tmp=/tmp/grass6-&amp;quot;`whoami`&amp;quot;-$GIS_LOCK&lt;br /&gt;
&lt;br /&gt;
export GISRC=&amp;quot;$tmp/rc&amp;quot;&lt;br /&gt;
mkdir &amp;quot;$tmp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# GRASS 7&lt;br /&gt;
cp ~/.grass7/rc &amp;quot;$GISRC&amp;quot;&lt;br /&gt;
# GRASS 6.4.2&lt;br /&gt;
### cp ~/.grassrc6 &amp;quot;$GISRC&amp;quot;&lt;br /&gt;
######### END below not needed ########&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above script will allow GRASS commands to be used anywhere. Furthermore, if the '''~/.Xsession''' sources the bash startup scripts, the settings aren't limited to interactive shells, but also work for e.g. M-! in XEmacs). Each interactive shell gets a separate &amp;quot;session&amp;quot; (i.e. a separate $GISRC file), while GUI programs share a common session.&lt;br /&gt;
&lt;br /&gt;
Note, however, that '''~/.bash_profile''' is a personal initialization startup script and, thus, read during the login process. Any modifications to it will be read after (re-)login or explicitly sourcing it.&lt;br /&gt;
&lt;br /&gt;
At the end of the ~/.bash_profile file, the following lines can be added to ensure no duplication of entries in the PATH variable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 PATH=`awk -F: '{for(i=1;i&amp;lt;=NF;i++){if(!($i in a)){a[$i];printf s$i;s=&amp;quot;:&amp;quot;}}}'&amp;lt;&amp;lt;&amp;lt;$PATH`&lt;br /&gt;
 PYTHONPATH=`awk -F: '{for(i=1;i&amp;lt;=NF;i++){if(!($i in a)){a[$i];printf s$i;s=&amp;quot;:&amp;quot;}}}'&amp;lt;&amp;lt;&amp;lt;$PYTHONPATH`&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Important notes ===&lt;br /&gt;
&lt;br /&gt;
Launching a grassXY session could still permit access on GRASS modules of the version that is set with the above script. The reason being is that grassXY scripts (e.g.: grass64, grass65, grass72) prepend the GRASS directories to '''PATH''', '''LD_LIBRARY_PATH''', etc. They won't remove any entries which are already there. A solution to this is to ''switch'' between GRASS versions by using a script like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
        strippath()&lt;br /&gt;
        {&lt;br /&gt;
            (&lt;br /&gt;
            oldpath=&amp;quot;$1&amp;quot;&lt;br /&gt;
            newpath=&lt;br /&gt;
            IFS=:&lt;br /&gt;
            for dir in $oldpath ; do&lt;br /&gt;
                case &amp;quot;${dir}&amp;quot; in&lt;br /&gt;
                *grass*)&lt;br /&gt;
                        ;;&lt;br /&gt;
                *)&lt;br /&gt;
                        newpath=&amp;quot;$newpath:$dir&amp;quot;&lt;br /&gt;
                        ;;&lt;br /&gt;
                esac&lt;br /&gt;
            done&lt;br /&gt;
            echo &amp;quot;${newpath#:}&amp;quot;&lt;br /&gt;
            )&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        PATH=`strippath $PATH`&lt;br /&gt;
        &lt;br /&gt;
        export GISBASE=$PWD/dist.i686-pc-linux-gnu&lt;br /&gt;
        export PATH=&amp;quot;$GISBASE/bin:$GISBASE/scripts:$PATH&amp;quot;&lt;br /&gt;
        export LD_LIBRARY_PATH=&amp;quot;$GISBASE/lib&amp;quot;&lt;br /&gt;
        export PYTHONPATH=&amp;quot;$GISBASE/etc/python&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note: the above script needs to be &amp;quot;source&amp;quot;d; executing it won't work. It might also require some adjustments (e.g. the ''GISBASE'' variable).'''&lt;br /&gt;
&lt;br /&gt;
Using normal grass sessions commands are recorded in '''$GISDBASE/$LOCATION_NAME/$MAPSET/.bash_history'''. While working with &amp;quot;pure&amp;quot; bash, shell entries go in '''~/.bash_history'''. Merging existing &amp;quot;grass-bash_history(-ies)&amp;quot; with the bash history log, would probably be not a good idea. Perhaps it is wise(r) to use normal GRASS sessions when working on real projects. Nevertheless, it is upon the users preferences and expertise level to decide what is best.&lt;br /&gt;
&lt;br /&gt;
=== Hints and troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
Some hints for MS Windows users:&lt;br /&gt;
&lt;br /&gt;
# The Python interpreter (python.exe) needs to be in the PATH&lt;br /&gt;
# Python needs to be associated with the .py extension&lt;br /&gt;
# PATHEXT needs to include .py if you want to be able to omit the extension&lt;br /&gt;
&lt;br /&gt;
When everything works well, the installer should take care of all of these.&lt;br /&gt;
&lt;br /&gt;
To manage parallel sessions on Linux, use process ID (PID) as lock file number and set the GIS_LOCK variable, for example&lt;br /&gt;
&lt;br /&gt;
  export GIS_LOCK=$$&lt;br /&gt;
&lt;br /&gt;
in Bash.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* Instructions and discussion on [http://n2.nabble.com/can-I-access-mapset-outside-of-grass-by-using-python-td3405902.html#a3405902 how to access GRASS mapsets outside of a GRASS session] in the grass-user mailing list.&lt;br /&gt;
* removing duplicate entries in $PATH taken from [http://chunchung.blogspot.com/2007/11/remove-duplicate-paths-from-path-in.html]&lt;br /&gt;
&lt;br /&gt;
== GRASS databases ==&lt;br /&gt;
&lt;br /&gt;
(project file structure)&lt;br /&gt;
&lt;br /&gt;
=== Minimal mapsets ===&lt;br /&gt;
&lt;br /&gt;
within a functional LOCATION (see below) the minimal mapset is a subdirectory of the MAPSET's name, containing a WIND file. The WIND file can simply be copied from PERMANENT/DEFAULT_WIND. Optionally you can put a VAR file in there too to define the default database driver to use.&lt;br /&gt;
&lt;br /&gt;
* You can create a new mapset when starting GRASS with the -c flag. e.g.&lt;br /&gt;
 grass64 -c /path/to/location/new_mapset_name&lt;br /&gt;
&lt;br /&gt;
=== Minimal locations ===&lt;br /&gt;
&lt;br /&gt;
Within the GISDATABASE (which is simply a subdirectory some where), the minimum LOCATION consists of a directory giving the LOCATION its name, which in turn contains a PERMANENT subdirectory for the PERMANENT mapset. The PERMANENT mapset contains a few special files that regular mapsets don't. These are:&lt;br /&gt;
; PROJ_INFO: contains the location's projection information&lt;br /&gt;
; PROJ_UNITS: contains the location's map units definition&lt;br /&gt;
; DEFAULT_WIND: the default region (WINDow file). The format is identical to the WIND files created by g.region&lt;br /&gt;
; WIND: (optional?)&lt;br /&gt;
&lt;br /&gt;
* see also {{src|demolocation}} in the GRASS source code&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[GRASS_and_Shell#GRASS_Batch_jobs|GRASS Batch jobs]]&lt;br /&gt;
&lt;br /&gt;
[[Category: FAQ]]&lt;br /&gt;
[[Category: Linking to other languages]]&lt;br /&gt;
[[Category: bash]]&lt;br /&gt;
[[Category:Scripting]]&lt;br /&gt;
[[Category: Python]]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Team&amp;diff=24129</id>
		<title>Team</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Team&amp;diff=24129"/>
		<updated>2017-04-27T09:05:31Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: Added my name and move Nikos to respect the alphabetical order&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GRASS GIS project is an international team effort with scientists and developers participating from various fields. Below is a list of the current team.&lt;br /&gt;
&lt;br /&gt;
All general queries concerning GRASS should be addressed to the respective [http://grass.osgeo.org/support/mailing-lists/ GRASS mailing lists]. If you miss yourself or somebody else on the lists below, please feel free to edit this Wiki page or send mail to the [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]. &lt;br /&gt;
__TOC__&lt;br /&gt;
== Current contributors to the development of the GRASS code ==&lt;br /&gt;
&lt;br /&gt;
In alphabetical order; see for example [http://www.ohloh.net/p/grass_gis/contributors here] for contribution statistics.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em auto 1em auto; text-align:left&amp;quot;&lt;br /&gt;
| width=200px | [[Image:Grasslogo vector small.png|100px|center]]&lt;br /&gt;
| '''Anna Kratochvílová''': GRASS 7 wxGUI development, Prague, CZ, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:benjamin.png|100px|center|center]] &lt;br /&gt;
| '''Benjamin Ducke''': extension manager, spatial statistics, archaeological applications, predictive modelling Location: Berlin, Germany, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]] &lt;br /&gt;
| '''Glynn Clements''': core development, UK, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list ]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:hamish.jpg|100px|center]] &lt;br /&gt;
| '''Hamish Bowman''': Development of display, PostScript, raster, and GPS modules as well as general sanitation of the code, help, and web pages. Location: Department of Marine Science, University of Otago. Dunedin, New Zealand mail: hamish_b AT yahoo com [http://hamish.bowman.googlepages.com/grassfiles http://hamish.bowman.googlepages.com/grassfiles] &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:helena.jpg|100px|center]] &lt;br /&gt;
| '''Helena Mitasova''': surface and volume modeling and analysis (RST modules), topographic analysis, hydrologic and erosion modelling, assistance with visualization, working with students on new module development, testing, and bug fixing Location: Raleigh, North Carolina, USA, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list ][http://www4.ncsu.edu/~hmitaso/ http://www4.ncsu.edu/~hmitaso/]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:hellik.png|100px|center]]&lt;br /&gt;
| '''Helmut Kudrnovsky''': [http://grass.osgeo.org/grass64/binary/mswindows/native/ winGRASS packaging],german translation, Austria, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]] &lt;br /&gt;
| '''Huidae Cho''': Hydrologic modeling (TOPMODEL modules), DXF modules, FreeType support, Korean translation. Location: Atlanta, Georgia, USA mail: grass4u AT gmail com, IRC Nick: grass4u [http://idea.isnew.info http://idea.isnew.info]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:lucadelu.png|100px|center]]&lt;br /&gt;
| '''Luca Delucchi''': Python GRASS development (GUI and Modules), Documentation, Italian Translation, Location: Trento (Italy), mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Maris_nartiss.jpg|100px|center]]&lt;br /&gt;
| '''[[user:MarisN|Maris Nartiss]]''': Tcl/TK GUI development, Latvia, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]]&lt;br /&gt;
| '''Markus Metz''': GRASS 7 development, massive data processing, vector library, Italy + Germany, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:markus.jpg|100px|center]] &lt;br /&gt;
| '''Markus Neteler''': various contributions, coordination, main Web site and mailing lists maintenance, Location: Bonn, Germany, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list], IRC Nick: markusN [http://www.grassbook.org/neteler/ http://www.grassbook.org/neteler/]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:mlanda.png|100px|center]] &lt;br /&gt;
| '''Martin Landa''': various contributions, vector engine improvements, [[wxGUI]], Location: Prague, Czech Republic Mail: landa.martin AT gmail.com Homepage: [http://geo.fsv.cvut.cz/~landa http://geo.fsv.cvut.cz/~landa]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:michael.jpg|100px|center]] &lt;br /&gt;
| '''Michael Barton ''': GRASS native GUI development, Mac binaries, Location: Tempe, Arizona, USA mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list ][http://www.public.asu.edu/~cmbarton/ http://www.public.asu.edu/~cmbarton/]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]]&lt;br /&gt;
| '''Moritz Lennert''': display tools, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]]&lt;br /&gt;
| '''Nikos Alexandris''': tester, contributed add-ons, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]] &lt;br /&gt;
| '''Pietro Zambelli''': GRASS7 Python API (mainly pygrass), Location: Europe, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list], link: ''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]] &lt;br /&gt;
| '''Soeren Gebbert''': improvements of [http://www-pool.math.tu-berlin.de/~soeren/grass/ 3D functionality] mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]]&lt;br /&gt;
| '''Stepan Turek''': GRASS 7 wxGUI development, Prague, CZ, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]]&lt;br /&gt;
| '''Vaclav Petras''': GRASS 7 wxGUI development, Prague, CZ, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]]&lt;br /&gt;
| '''William Kyngesburye''': [http://www.kyngchaos.com/software:grass/ Mac OS X packaging], USA, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]]&lt;br /&gt;
| '''Yann Chemin''': image processing, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]] &lt;br /&gt;
| '''''your name''': what-you-do, Location: xyz, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list], link: ''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Former or currently inactive developers ==&lt;br /&gt;
&lt;br /&gt;
(in alphabetical order)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em auto 1em auto; text-align:left&amp;quot;&lt;br /&gt;
| width=200px | [[Image:Grasslogo vector small.png|100px|center]] &lt;br /&gt;
| '''Bob Covill''' Role: visualization, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list ]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]] &lt;br /&gt;
| '''Brad Douglas''' Role: bug fixing, code portability, imagery modules Location: Fremont, California, USA, IRC Nick: bdouglas, mail: rez AT touchofmadness com &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:cedric.jpg|100px|center]] &lt;br /&gt;
| '''Cedric Shock''' Role: user interface enhancements, debugging Location: Eugene, Oregon, USA, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list], [http://www.shockfamily.net/cedric/ http://www.shockfamily.net/cedric/] &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:DaveSampson.png|100px|center]]&lt;br /&gt;
| '''Dave Sampson''' Role: tutorials, data sets &amp;amp;amp; public data licensing, GRASS map gallery, Ottawa Chapter of OSGeo, Location: Ottawa, Ontario, Canada, mail: samper.d at gmail dot com [http://davidsampson.ca/ http://davidsampson.ca] &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:jachym.png|100px|center]] &lt;br /&gt;
| '''Jachym Cepicky''' Role: bug fixing, support of 3D vectors, tester and translator, UI developer, Czech Republic, mail: jachym.cepicky AT gmail.com [http://les-ejk.cz/ http://les-ejk.cz/] &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]] &lt;br /&gt;
| '''Jaroslav Hofierka''' Role: development of modules for solar irradiation, flow routing, surface and volume modelling and analysis (RST modules), hydrologic and erosion modelling, assistance with visualization Location: Presov, Slovakia, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list ]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:maciek.png|100px|center]] &lt;br /&gt;
| '''Maciej Sieczka''' Role: power user, testing Location: Wroclaw, Poland, mail: msieczka AT sieczka.org [http://www.sieczka.org/ http://www.sieczka.org] &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]] &lt;br /&gt;
| '''Marco Pasetti''' Role: Microsoft Windows native binary port of GRASS Location: Brescia, Italy, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list], link: [http://grass.osgeo.org/grass64/binary/mswindows/native/ WinGRASS Project Homepage] &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Grasslogo vector small.png|100px|center]] &lt;br /&gt;
| '''Paul Kelly''' Role: Proj integration, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list ]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:radim.jpg|100px|center]]&lt;br /&gt;
| '''Radim Blazek''' Role: DBMI, vector engine core developer, Location: Trento, Italy till 2006, mail: [http://lists.osgeo.org/mailman/listinfo/grass-dev GRASS developers mailing list]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:scott.jpg|100px|center]] &lt;br /&gt;
| '''Scott Mitchell''' Role: tutorial and documentation development, web site maintenance, Ottawa User's Group, OSGeo Journal News and Events Editor Location: Ottawa, Ontario, Canada, mail: [http://lists.osgeo.org/mailman/listinfo/grass-web GRASS web site maintenance mailing list] [http://www.carleton.ca/~smitch http://www.carleton.ca/~smitch] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The following institutions are currently supporting the GRASS-Project ==&lt;br /&gt;
&lt;br /&gt;
Please see our [http://grass.osgeo.org/donations/ GRASS sponsoring] page. &lt;br /&gt;
&lt;br /&gt;
And a ''thank-you'' to:&lt;br /&gt;
&lt;br /&gt;
* the many people who have contributed in the past&lt;br /&gt;
* the various users who have contributed bug reports and tested unstable GRASS versions; &lt;br /&gt;
* all the sites (and the people behind them) that provide mirrors for the GRASS web pages.&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=22904</id>
		<title>Python/pygrass</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=22904"/>
		<updated>2016-03-29T09:47:08Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Interface to copying maps (g.copy) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''PyGRASS'' is a library that extends the GRASS GIS 7 capabilities to allow users to access the low-level GRASS API.&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
Detailed PyGRASS documentation: http://grass.osgeo.org/grass71/manuals/libpython/&lt;br /&gt;
&lt;br /&gt;
== How to test library ==&lt;br /&gt;
&lt;br /&gt;
''pygrass'' has 'doctest' included in its code. You can run doctest in the [http://grass.osgeo.org/sampledata/north_carolina/nc_basic_spm_grass7.tar.gz North Carolina basic location], using the mapset '''user1'''. &lt;br /&gt;
&lt;br /&gt;
To test a single module (file) you have to change into the source code directory of pygrass and run the following code (this is an example of functions.py):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python -m doctest functions.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* Zambelli, P., Gebbert, S., Ciolli, M., 2013. ''Pygrass: An Object Oriented Python Application Programming Interface (API) for Geographic Resources Analysis Support System (GRASS) Geographic Information System (GIS)''. ISPRS International Journal of Geo-Information 2, 201–219. ([http://dx.doi.org/10.3390/ijgi2010201 DOI] | [http://www.mdpi.com/2220-9964/2/1/201/pdf PDF])&lt;br /&gt;
&lt;br /&gt;
* [http://grass.osgeo.org/grass71/manuals/libpython/ pyGrass documentation] (updated weekly from SVN)&lt;br /&gt;
&lt;br /&gt;
== Sample PyGRASS scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Training material ===&lt;br /&gt;
&lt;br /&gt;
Two workshops were presented during the [http://geomorfolab.arch.unige.it/genova2013/ XIV Italian meeting of GRASS] at Genova.&lt;br /&gt;
The workshops use '''ipython notebook''' to show the python and pygrass API, all the material are available on github ([https://github.com/zarch/workshop-python python], [https://github.com/zarch/workshop-pygrass pygrass]). All the execute examples are reported here:&lt;br /&gt;
&lt;br /&gt;
* python training (Genova)&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/00_intro.ipynb      Introduction]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/01_data_types.ipynb Data Types]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/02_syntax.ipynb     Syntax]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/03_function.ipynb   Function]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/04_class.ipynb      Class]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/05_other.ipynb      Other]&lt;br /&gt;
&lt;br /&gt;
* python training (EURAC)&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/00_intro.ipynb Introduction]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/01_data_types.ipynb Data Types]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/02_syntax.ipynb Syntax]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/03_version_control_system.ipynb Version Control System (hg)]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/04_objects.ipynb Objects]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/05_python_debugger.ipynb Debugger]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/06_functions.ipynb Functions]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/07_numpy.ipynb Numpy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/08_matplotlib.ipynb Matplotlib]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/09_scipy.ipynb Scipy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/10_pandas.ipynb Pandas]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/11_sympy.ipynb Sympy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/12_user_interfaces.ipynb GUI]&lt;br /&gt;
&lt;br /&gt;
* pygrass training&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/00_Modules.ipynb Modules]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/01_GIS_objects.ipynb GIS]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/02_Vector.ipynb Vector]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/03_Raster.ipynb Raster]&lt;br /&gt;
&lt;br /&gt;
=== Interface to listing maps (g.list/g.mlist) ===&lt;br /&gt;
&lt;br /&gt;
Here we call a GRASS module that writes to stdout and do not call a Python function that returns a Python object, therefore we can save stdout and then parse it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
import subprocess as sub&lt;br /&gt;
&lt;br /&gt;
gl = g.list   # GRASS 7&lt;br /&gt;
gl(type='raster', pattern='elev-*', stdout=sub.PIPE)&lt;br /&gt;
gl.outputs.stdout.split()&lt;br /&gt;
['elev-000-000', 'elev-000-001', 'elev-000-002', 'elev-001-000',&lt;br /&gt;
'elev-001-001', 'elev-001-002', 'elev-002-000', 'elev-002-001',&lt;br /&gt;
'elev-002-002']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use the &amp;quot;glist&amp;quot; method of the Mapset class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.gis import Mapset&lt;br /&gt;
m = Mapset()&lt;br /&gt;
m.glist('rast', pattern='elev-*')&lt;br /&gt;
['elev-002-000',  'elev-000-000',  'elev-000-002',  'elev-000-001',&lt;br /&gt;
'elev-001-001',  'elev-002-002',  'elev-002-001',  'elev-001-000',&lt;br /&gt;
'elev-001-002']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... that uses the &amp;quot;G_list&amp;quot; function through ctypes and therefore is faster.&lt;br /&gt;
&lt;br /&gt;
Note: If you choose the first solution it is better if you use directly the&lt;br /&gt;
function in [http://grass.osgeo.org/programming7/namespacepython_1_1script_1_1core.html python.script.core.mlist_grouped() etc.].&lt;br /&gt;
&lt;br /&gt;
=== Interface to copying maps (g.copy) ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
&lt;br /&gt;
vectinmap = 'zipcodes_wake'&lt;br /&gt;
vectoutmap = 'zip_elev_zonal'&lt;br /&gt;
g.copy(vector=(vectinmap,vectoutmap))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample script for opening, query and closing of a vector map ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
# Example for pyGRASS usage - vector API&lt;br /&gt;
&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
from grass.pygrass.vector import VectorTopo&lt;br /&gt;
 &lt;br /&gt;
g.message(&amp;quot;Assessing vector topology...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
vectmap = 'zipcodes_wake'&lt;br /&gt;
zipcodes = VectorTopo(vectmap)&lt;br /&gt;
&lt;br /&gt;
# Open the map with topology:&lt;br /&gt;
zipcodes.open()&lt;br /&gt;
&lt;br /&gt;
# query number of topological features&lt;br /&gt;
areas   = zipcodes.number_of(&amp;quot;areas&amp;quot;)&lt;br /&gt;
islands = zipcodes.number_of(&amp;quot;islands&amp;quot;)&lt;br /&gt;
print 'Map: &amp;lt;' + vectmap + '&amp;gt; with %d areas and %d islands' % (areas, islands)&lt;br /&gt;
&lt;br /&gt;
# http://www.ing.unitn.it/~zambelli/projects/pygrass/attributes.html&lt;br /&gt;
# (note that above documentation is slightly outdated)&lt;br /&gt;
dblink = zipcodes.dblinks[0]&lt;br /&gt;
print 'DB name:'&lt;br /&gt;
print dblink.database&lt;br /&gt;
table = dblink.table()&lt;br /&gt;
print 'Column names:'&lt;br /&gt;
print table.columns.names()&lt;br /&gt;
print 'Column types:'&lt;br /&gt;
print table.columns.types()&lt;br /&gt;
&lt;br /&gt;
zipcodes.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample script for Landsat 7 processing ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
#Date: 7th February, 2013&lt;br /&gt;
#Public domain, GRASS GIS&lt;br /&gt;
&lt;br /&gt;
#Run this script in the terminal as:&lt;br /&gt;
#python python-grass.py&lt;br /&gt;
#For debugging, run as:&lt;br /&gt;
#python -i python-grass.py&lt;br /&gt;
#PURPOSE&lt;br /&gt;
#This script processes LANDSAT 7 ETM+ images&lt;br /&gt;
#1 - unzip *.gz files&lt;br /&gt;
#2 - import files in GRASS GIS Location of your choice (r.in.gdal)&lt;br /&gt;
#3 - DN to Top of Atmosphere reflectance (i.landsat.toar)&lt;br /&gt;
#4 - TOA reflectance to Surface reflectance (i.atcorr)&lt;br /&gt;
#5 - NDVI (i.vi), Albedo (i.albedo), Emissivity (i.emissivity)&lt;br /&gt;
&lt;br /&gt;
#USER HAS TO SET THOSE&lt;br /&gt;
#QUIET REPORTS&lt;br /&gt;
QIET=True&lt;br /&gt;
#OVERWRITE EXISTING FILES&lt;br /&gt;
OVR=False&lt;br /&gt;
#Define Landsat 7 sensor for i.landsat.toar&lt;br /&gt;
LSENSOR=&amp;quot;tm7&amp;quot;&lt;br /&gt;
#Setup the path to the Landsat 7 Directories&lt;br /&gt;
rsdatapath=&amp;quot;/home/yann/RSDATA/Myanmar/L7&amp;quot;&lt;br /&gt;
#Setup your GRASS GIS working directory&lt;br /&gt;
gisdb=&amp;quot;/home/yann/GRASSDATA&amp;quot;&lt;br /&gt;
location=&amp;quot;L7_Myanmar&amp;quot;&lt;br /&gt;
print location&lt;br /&gt;
mapset=&amp;quot;PERMANENT&amp;quot;&lt;br /&gt;
#DEM input to atmospheric correction&lt;br /&gt;
inDEM=rsdatapath+&amp;quot;/dem.tif&amp;quot;&lt;br /&gt;
#set L7 Metadata wildcards&lt;br /&gt;
wldc_mtl=&amp;quot;*_MTL.txt&amp;quot;&lt;br /&gt;
#wldc_met=&amp;quot;*.met&amp;quot;&lt;br /&gt;
#Visibility distance [Km]&lt;br /&gt;
vis=18&lt;br /&gt;
&lt;br /&gt;
#Set python path to enable finding of grass.script lib&lt;br /&gt;
&lt;br /&gt;
#END OF USER CHANGES&lt;br /&gt;
###DO NOT CHANGE ANYTHING AFTER THIS LINE !&lt;br /&gt;
###&lt;br /&gt;
#Load necessary libraries&lt;br /&gt;
import os, glob, time, re&lt;br /&gt;
from grass import script as g&lt;br /&gt;
from grass.script import setup as gsetup&lt;br /&gt;
gisbase=os.environ['GISBASE']&lt;br /&gt;
gsetup.init(gisbase,gisdb,location,mapset)&lt;br /&gt;
from grass.pygrass.modules.shortcuts import raster as r&lt;br /&gt;
from grass.pygrass.modules.shortcuts import imagery as i&lt;br /&gt;
from grass.pygrass.modules.shortcuts import display as d&lt;br /&gt;
#Needed for floor()&lt;br /&gt;
from math import *&lt;br /&gt;
#env = os.environ.copy()&lt;br /&gt;
#env['GRASS_MESSAGE_FORMAT'] = 'gui'&lt;br /&gt;
#Function to get a list of L7 Directories in the rsdatapath&lt;br /&gt;
def fn(path):&lt;br /&gt;
	for top, dirs, files in os.walk(path):&lt;br /&gt;
		return [os.path.join(top, dir) for dir in dirs]&lt;br /&gt;
&lt;br /&gt;
#START PROCESS&lt;br /&gt;
### PART 0: PRE-PROCESSING STUFF ###&lt;br /&gt;
#import DEM for atmospheric correction&lt;br /&gt;
#r.in.gdal(input=inDEM,output=&amp;quot;dem&amp;quot;,overwrite=OVR)&lt;br /&gt;
#r.mapcalc(expression=&amp;quot;dem=25&amp;quot;,overwrite=OVR)&lt;br /&gt;
#create a visibility map&lt;br /&gt;
r.mapcalc(expression=&amp;quot;vis=18&amp;quot;,overwrite=OVR)&lt;br /&gt;
#Find the central location of the Landsat file from metadata&lt;br /&gt;
metadata=[]&lt;br /&gt;
fileList=[]&lt;br /&gt;
L7Dirs=fn(rsdatapath)&lt;br /&gt;
for L7Dir in L7Dirs:&lt;br /&gt;
	#Ungzip all of your Landsat7 images in all your directories&lt;br /&gt;
#	print &amp;quot;Ungzip Landsat files in\t&amp;quot;,L7Dir&lt;br /&gt;
#	p=os.system(&amp;quot;gzip -d -q &amp;quot;+L7Dir+&amp;quot;/*.gz&amp;quot;)&lt;br /&gt;
	#Using pthreads on multi-core machines&lt;br /&gt;
	#p=os.system(&amp;quot;pigz -d &amp;quot;+L7Dir+&amp;quot;/*.gz&amp;quot;)&lt;br /&gt;
	#Wait ten seconds for gzip to create the tif images&lt;br /&gt;
#	time.sleep(10)&lt;br /&gt;
	print &amp;quot;Import in GRASS GIS&amp;quot;&lt;br /&gt;
	for L7f in glob.glob(os.path.join(L7Dir,&amp;quot;*.[tT][iI][fF]&amp;quot;)):&lt;br /&gt;
		f1=L7f.replace(L7Dir+&amp;quot;/&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		f2=f1.replace(&amp;quot;.TIF&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		f3=f2.replace(&amp;quot;_B10&amp;quot;,&amp;quot;.1&amp;quot;)&lt;br /&gt;
		f4=f3.replace(&amp;quot;_B20&amp;quot;,&amp;quot;.2&amp;quot;)&lt;br /&gt;
		f5=f4.replace(&amp;quot;_B30&amp;quot;,&amp;quot;.3&amp;quot;)&lt;br /&gt;
		f6=f5.replace(&amp;quot;_B40&amp;quot;,&amp;quot;.4&amp;quot;)&lt;br /&gt;
		f7=f6.replace(&amp;quot;_B50&amp;quot;,&amp;quot;.5&amp;quot;)&lt;br /&gt;
		f8=f7.replace(&amp;quot;_B61&amp;quot;,&amp;quot;.61&amp;quot;)&lt;br /&gt;
		f9=f8.replace(&amp;quot;_B62&amp;quot;,&amp;quot;.62&amp;quot;)&lt;br /&gt;
		f10=f9.replace(&amp;quot;_B70&amp;quot;,&amp;quot;.7&amp;quot;)&lt;br /&gt;
		f11=f10.replace(&amp;quot;_B80&amp;quot;,&amp;quot;.8&amp;quot;)&lt;br /&gt;
		f12=f11.replace(&amp;quot;L72&amp;quot;,&amp;quot;L71&amp;quot;)&lt;br /&gt;
		L7r=f12.replace(&amp;quot;_VCID_&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,L7r&lt;br /&gt;
		r.in_gdal(input=L7f,output=L7r,flags=&amp;quot;e&amp;quot;,overwrite=OVR)&lt;br /&gt;
		fileList.append(L7r)&lt;br /&gt;
&lt;br /&gt;
	#reproject the DEM World map for the new PERMANENT location extents&lt;br /&gt;
	r.proj(input=&amp;quot;dem&amp;quot;,location=&amp;quot;Myanmar&amp;quot;,memory=10000,resolution=90.0,overwrite=OVR)&lt;br /&gt;
	#Get list of metadata files&lt;br /&gt;
	for metaf in glob.glob(os.path.join(L7Dir,wldc_mtl)):&lt;br /&gt;
		metadata.append(metaf)&lt;br /&gt;
	print &amp;quot;Metadata in:\n&amp;quot;,metadata[0]&lt;br /&gt;
	with open(metadata[0],&amp;quot;r&amp;quot;) as f:&lt;br /&gt;
		data=f.read()&lt;br /&gt;
&lt;br /&gt;
	f.close()&lt;br /&gt;
	dt=data.split(&amp;quot;\n&amp;quot;)&lt;br /&gt;
	for idx in range(len(dt)):&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_UL_LON_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			ulx=float(dt[idx].replace(&amp;quot;CORNER_UL_LON_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_UL_LAT_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			uly=float(dt[idx].replace(&amp;quot;CORNER_UL_LAT_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_LR_LON_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			lrx=float(dt[idx].replace(&amp;quot;CORNER_LR_LON_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_LR_LAT_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			lry=float(dt[idx].replace(&amp;quot;CORNER_LR_LAT_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		#Two cases, because a string starting by 0 is not converted well&lt;br /&gt;
		found=dt[idx].find(&amp;quot;SCENE_CENTER_TIME = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			tim=dt[idx].replace(&amp;quot;SCENE_CENTER_TIME = &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
			print &amp;quot;timestamp=&amp;quot;,str(tim)&lt;br /&gt;
			gmth=float(tim.split(&amp;quot;:&amp;quot;)[0])&lt;br /&gt;
			gmtm=float(tim.split(&amp;quot;:&amp;quot;)[1])&lt;br /&gt;
			gmtdec=float(tim.split(&amp;quot;:&amp;quot;)[2].replace(&amp;quot;Z&amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
			print gmth,gmtm,gmtdec&lt;br /&gt;
		found=dt[idx].find(&amp;quot;DATE_ACQUIRED = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			dat=dt[idx].replace(&amp;quot;DATE_ACQUIRED = &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
			date=dat.split(&amp;quot;-&amp;quot;)&lt;br /&gt;
		found=dt[idx].find(&amp;quot;SUN_ELEVATION = &amp;quot;)&lt;br /&gt;
                if found &amp;gt; 0:&lt;br /&gt;
                        sunza=90-float(dt[idx].replace(&amp;quot;SUN_ELEVATION = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	#L7 DN-&amp;gt;Rad-&amp;gt;Ref&lt;br /&gt;
	print &amp;quot;Convert DN to Rad to TOARef&amp;quot;&lt;br /&gt;
	f1=sorted(fileList)[0]&lt;br /&gt;
	f2=f1.replace(L7Dir+&amp;quot;/&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
	pref=f2[:-1]&lt;br /&gt;
	outpref=pref[:-2]+&amp;quot;.toar.&amp;quot;&lt;br /&gt;
	print &amp;quot;Prefix IN:\t&amp;quot;,pref&lt;br /&gt;
	print &amp;quot;Prefix OUT:\t&amp;quot;, outpref&lt;br /&gt;
	i.landsat_toar(input_prefix=pref,output_prefix=outpref,metfile=metadata[0],sensor=LSENSOR,quiet=QIET,overwrite=OVR)&lt;br /&gt;
	#Atmospheric Correction&lt;br /&gt;
	print &amp;quot;Atmospheric Correction&amp;quot;&lt;br /&gt;
	# Basic script for i.atcorr for L 7 ETM+&lt;br /&gt;
	#Geometrical conditions (L7ETM+)&lt;br /&gt;
	geom=7&lt;br /&gt;
	#Sensor height (satellite is -1000)&lt;br /&gt;
	sens_height=-1000&lt;br /&gt;
	#Here we suppose you have altitude (DEM) and Visibility (VIS) maps ready&lt;br /&gt;
	#---------------------------------------------&lt;br /&gt;
	#Visibility dummy value (overwritten by VIS raster input)&lt;br /&gt;
	vis=15&lt;br /&gt;
	#Altitude dummy value (in Km should be negative in this param file)&lt;br /&gt;
	#(overwritten by DEM raster input)&lt;br /&gt;
	alt=-1.200&lt;br /&gt;
	#datetime of satellite overpass (month, day, GMT decimal hour)&lt;br /&gt;
	mdh=str(int(date[1]))+&amp;quot; &amp;quot;+str(int(date[2]))+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % (gmth+gmtm/60.0+gmtdec/3600.0))&lt;br /&gt;
	print &amp;quot;MM DD hh.ddd:\t&amp;quot;,mdh&lt;br /&gt;
	# Central Lat/Long&lt;br /&gt;
	Long=ulx+(lrx-ulx)/2.0&lt;br /&gt;
	Lat=lry+(uly-lry)/2.0&lt;br /&gt;
	print &amp;quot;Center:\t(&amp;quot;,Long, &amp;quot;,&amp;quot;, Lat,&amp;quot;)&amp;quot;&lt;br /&gt;
	#Atmospheric mode&lt;br /&gt;
	atm_mode=1 #Tropical&lt;br /&gt;
	#Aerosol model&lt;br /&gt;
	aerosol_mode=2 #Sri Lanka is a small island (maritime)&lt;br /&gt;
	#satellite band number (L5TM [25,26,27,28,29,30], L7ETM+ [61,62,63,64,65,66,67])&lt;br /&gt;
	satbandno=61 #Band 1 of L7ETM+ is first to undergo atmospheric correction&lt;br /&gt;
	#make time stamp for use in time series analysis&lt;br /&gt;
	dat1=str(date[2])+&amp;quot;-&amp;quot;+str(date[1])+&amp;quot;-&amp;quot;+str(date[0])&lt;br /&gt;
	dat=dat1.replace(&amp;quot; &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
	timestamp=time.strftime(&amp;quot;%d %b %Y&amp;quot;,time.strptime(dat,&amp;quot;%d-%m-%Y&amp;quot;))&lt;br /&gt;
	print &amp;quot;Timestamp:\t&amp;quot;,timestamp&lt;br /&gt;
	for idx in [1,2,3,4,5,7]:&lt;br /&gt;
		b=pref[:-2]+&amp;quot;.toar.&amp;quot;+str(idx)&lt;br /&gt;
		b_out=b.replace(&amp;quot;.toar.&amp;quot;,&amp;quot;.surf.&amp;quot;)&lt;br /&gt;
		param=[]&lt;br /&gt;
		param.append(str(geom)+&amp;quot; - geometrical conditions=Landsat 7 ETM+\n&amp;quot;)&lt;br /&gt;
		param.append(str(mdh)+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % Long)+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % Lat)+&amp;quot; - month day hh.ddd longitude latitude (hh.ddd is in decimal hours GMT)\n&amp;quot;)&lt;br /&gt;
		param.append(str(atm_mode)+&amp;quot; - atmospheric mode=tropical\n&amp;quot;)&lt;br /&gt;
		param.append(str(aerosol_mode)+&amp;quot; - aerosols model=maritime\n&amp;quot;)&lt;br /&gt;
		param.append(str(vis)+&amp;quot; - visibility [km] (aerosol model concentration), not used as there is raster input\n&amp;quot;)&lt;br /&gt;
		param.append(str(alt)+&amp;quot; - mean target elevation above sea level [km] (here 600m asl), not used as there is raster input\n&amp;quot;)&lt;br /&gt;
		param.append(str(sens_height)+&amp;quot; - sensor height (here, sensor on board a satellite)\n&amp;quot;)&lt;br /&gt;
		param.append(str(satbandno)+&amp;quot; - i th band of ETM+ Landsat 7 (atcorr internal no)\n&amp;quot;)&lt;br /&gt;
		f=open(os.path.join(L7Dir,&amp;quot;param_L7.txt&amp;quot;),&amp;quot;w&amp;quot;)&lt;br /&gt;
		f.writelines(param)&lt;br /&gt;
		f.close()&lt;br /&gt;
		prm=os.path.join(L7Dir,&amp;quot;param_L7.txt&amp;quot;)&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,b&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,b_out&lt;br /&gt;
		i.atcorr(input=b, elevation=&amp;quot;dem&amp;quot;, visibility=&amp;quot;vis&amp;quot;, parameters=prm, output=b_out, flags=&amp;quot;ra&amp;quot;, range=[0,1],quiet=QIET,overwrite=OVR)&lt;br /&gt;
		r.timestamp(map=b_out,date=timestamp,finish_=False)&lt;br /&gt;
		satbandno = satbandno + 1&lt;br /&gt;
&lt;br /&gt;
	#Allocate surface reflectance names&lt;br /&gt;
	b1=pref[:-2]+&amp;quot;.surf.1&amp;quot;&lt;br /&gt;
	b2=pref[:-2]+&amp;quot;.surf.2&amp;quot;&lt;br /&gt;
	b3=pref[:-2]+&amp;quot;.surf.3&amp;quot;&lt;br /&gt;
	b4=pref[:-2]+&amp;quot;.surf.4&amp;quot;&lt;br /&gt;
	b5=pref[:-2]+&amp;quot;.surf.5&amp;quot;&lt;br /&gt;
	b61=pref[:-2]+&amp;quot;.toar.61&amp;quot;&lt;br /&gt;
	b62=pref[:-2]+&amp;quot;.toar.62&amp;quot;&lt;br /&gt;
	b7=pref[:-2]+&amp;quot;.surf.7&amp;quot;&lt;br /&gt;
	b8=pref[:-2]+&amp;quot;.surf.8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	### PART 1: BASIC STUFF ###&lt;br /&gt;
	b_in=pref[:-2]+&amp;quot;.toar.&amp;quot;&lt;br /&gt;
	b_clouds=pref[:-2]+&amp;quot;.toar.acca&amp;quot;&lt;br /&gt;
	print &amp;quot;Clouds:\t\t&amp;gt;&amp;quot;,b_clouds&lt;br /&gt;
	i.landsat_acca(input_prefix=b_in,output=b_clouds,overwrite=OVR)&lt;br /&gt;
	#png_clouds=L7Dir+&amp;quot;/&amp;quot;+pref[:-2]+&amp;quot;.clouds.png&amp;quot;&lt;br /&gt;
	#d.mon(start='png',output=png_clouds,width=800,height=800)&lt;br /&gt;
	print &amp;quot;MASK:\t\tON&amp;quot;&lt;br /&gt;
	#Should always be rewritten!&lt;br /&gt;
	r.mask(raster=b_clouds,flags=&amp;quot;i&amp;quot;,overwrite=True)&lt;br /&gt;
&lt;br /&gt;
	b_ndvi=pref[:-2]+&amp;quot;.surf.ndvi&amp;quot;&lt;br /&gt;
	print &amp;quot;NDVI:\t&amp;quot;,b_ndvi&lt;br /&gt;
	i.vi(red=b3,nir=b4,output=b_ndvi,viname=&amp;quot;ndvi&amp;quot;,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
&lt;br /&gt;
	b_in=[b1,b2,b3,b4,b5,b7]&lt;br /&gt;
	b_albedo=pref[:-2]+&amp;quot;.surf.albedo&amp;quot;&lt;br /&gt;
	print &amp;quot;Albedo:\t&amp;quot;,b_albedo&lt;br /&gt;
	i.albedo(input=b_in,output=b_albedo,flags=&amp;quot;lc&amp;quot;,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
	&lt;br /&gt;
	b_emissivity=pref[:-2]+&amp;quot;.surf.emissivity&amp;quot;&lt;br /&gt;
	print &amp;quot;Emissivity:\t&amp;quot;,b_emissivity&lt;br /&gt;
	i.emissivity(input=b_ndvi, output=b_emissivity,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiprocessing example: parallelized SHAPE file import ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
Multiprocessing example: parallelized SHAPE file import&lt;br /&gt;
&lt;br /&gt;
Created on Fri, Oct 18, 2013, posted to grass-user@lists.osgeo.org&lt;br /&gt;
&lt;br /&gt;
@author: Pietro Zambelli, freely inspired by: http://stackoverflow.com/a/16071616&lt;br /&gt;
         http://lists.osgeo.org/pipermail//grass-user/2013-October/069130.html&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Directory containing SHAPE files to import&lt;br /&gt;
DIR = '/data/shp'&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
from multiprocessing import Queue, Process, cpu_count&lt;br /&gt;
from os.path import split&lt;br /&gt;
from subprocess import Popen&lt;br /&gt;
&lt;br /&gt;
from grass.pygrass.functions import findfiles&lt;br /&gt;
&lt;br /&gt;
def spawn(func):&lt;br /&gt;
    def fun(q_in, q_out):&lt;br /&gt;
        while True:&lt;br /&gt;
            path, cmdstr = q_in.get()&lt;br /&gt;
            if path is None:&lt;br /&gt;
                break&lt;br /&gt;
            q_out.put(func(path, cmdstr))&lt;br /&gt;
    return fun&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mltp_importer(dirpath, match, cmdstr, func, nprocs=cpu_count()):&lt;br /&gt;
    q_in = Queue(1)&lt;br /&gt;
    q_out = Queue()&lt;br /&gt;
    procs = [Process(target=spawn(func), args=(q_in, q_out))&lt;br /&gt;
             for _ in range(nprocs)]&lt;br /&gt;
    for proc in procs:&lt;br /&gt;
        proc.daemon = True&lt;br /&gt;
        proc.start()&lt;br /&gt;
&lt;br /&gt;
    # set the parameters&lt;br /&gt;
    sent = [q_in.put((path, cmdstr)) for path in findfiles(dirpath, match)]&lt;br /&gt;
    # set the end of the cycle&lt;br /&gt;
    [q_in.put((None, None)) for proc in procs]&lt;br /&gt;
    [proc.join() for proc in procs]&lt;br /&gt;
    return [q_out.get() for _ in range(len(sent))]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def importer(path, cmdstr):&lt;br /&gt;
    name = split(path)[-1][:-4]&lt;br /&gt;
    print name&lt;br /&gt;
    popen = Popen(cmdstr.format(path=path, name=name), shell=True)&lt;br /&gt;
    popen.wait()&lt;br /&gt;
    return path, name, False if popen.returncode else True&lt;br /&gt;
&lt;br /&gt;
CMD = 'v.in.ogr dsn={path} layer={name} output={name}'&lt;br /&gt;
&lt;br /&gt;
processed = mltp_importer(DIR, '*.shp', CMD, importer)&lt;br /&gt;
# check for errors&lt;br /&gt;
errors = [p for p in processed if not p[2]]&lt;br /&gt;
if errors:&lt;br /&gt;
    # do something (print list of failed SHP files at end)&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Python}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=22903</id>
		<title>Python/pygrass</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=22903"/>
		<updated>2016-03-29T09:43:29Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Interface to copying maps (g.copy) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''PyGRASS'' is a library that extends the GRASS GIS 7 capabilities to allow users to access the low-level GRASS API.&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
Detailed PyGRASS documentation: http://grass.osgeo.org/grass71/manuals/libpython/&lt;br /&gt;
&lt;br /&gt;
== How to test library ==&lt;br /&gt;
&lt;br /&gt;
''pygrass'' has 'doctest' included in its code. You can run doctest in the [http://grass.osgeo.org/sampledata/north_carolina/nc_basic_spm_grass7.tar.gz North Carolina basic location], using the mapset '''user1'''. &lt;br /&gt;
&lt;br /&gt;
To test a single module (file) you have to change into the source code directory of pygrass and run the following code (this is an example of functions.py):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python -m doctest functions.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* Zambelli, P., Gebbert, S., Ciolli, M., 2013. ''Pygrass: An Object Oriented Python Application Programming Interface (API) for Geographic Resources Analysis Support System (GRASS) Geographic Information System (GIS)''. ISPRS International Journal of Geo-Information 2, 201–219. ([http://dx.doi.org/10.3390/ijgi2010201 DOI] | [http://www.mdpi.com/2220-9964/2/1/201/pdf PDF])&lt;br /&gt;
&lt;br /&gt;
* [http://grass.osgeo.org/grass71/manuals/libpython/ pyGrass documentation] (updated weekly from SVN)&lt;br /&gt;
&lt;br /&gt;
== Sample PyGRASS scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Training material ===&lt;br /&gt;
&lt;br /&gt;
Two workshops were presented during the [http://geomorfolab.arch.unige.it/genova2013/ XIV Italian meeting of GRASS] at Genova.&lt;br /&gt;
The workshops use '''ipython notebook''' to show the python and pygrass API, all the material are available on github ([https://github.com/zarch/workshop-python python], [https://github.com/zarch/workshop-pygrass pygrass]). All the execute examples are reported here:&lt;br /&gt;
&lt;br /&gt;
* python training (Genova)&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/00_intro.ipynb      Introduction]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/01_data_types.ipynb Data Types]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/02_syntax.ipynb     Syntax]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/03_function.ipynb   Function]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/04_class.ipynb      Class]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/05_other.ipynb      Other]&lt;br /&gt;
&lt;br /&gt;
* python training (EURAC)&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/00_intro.ipynb Introduction]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/01_data_types.ipynb Data Types]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/02_syntax.ipynb Syntax]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/03_version_control_system.ipynb Version Control System (hg)]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/04_objects.ipynb Objects]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/05_python_debugger.ipynb Debugger]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/06_functions.ipynb Functions]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/07_numpy.ipynb Numpy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/08_matplotlib.ipynb Matplotlib]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/09_scipy.ipynb Scipy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/10_pandas.ipynb Pandas]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/11_sympy.ipynb Sympy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/12_user_interfaces.ipynb GUI]&lt;br /&gt;
&lt;br /&gt;
* pygrass training&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/00_Modules.ipynb Modules]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/01_GIS_objects.ipynb GIS]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/02_Vector.ipynb Vector]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/03_Raster.ipynb Raster]&lt;br /&gt;
&lt;br /&gt;
=== Interface to listing maps (g.list/g.mlist) ===&lt;br /&gt;
&lt;br /&gt;
Here we call a GRASS module that writes to stdout and do not call a Python function that returns a Python object, therefore we can save stdout and then parse it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
import subprocess as sub&lt;br /&gt;
&lt;br /&gt;
gl = g.list   # GRASS 7&lt;br /&gt;
gl(type='raster', pattern='elev-*', stdout=sub.PIPE)&lt;br /&gt;
gl.outputs.stdout.split()&lt;br /&gt;
['elev-000-000', 'elev-000-001', 'elev-000-002', 'elev-001-000',&lt;br /&gt;
'elev-001-001', 'elev-001-002', 'elev-002-000', 'elev-002-001',&lt;br /&gt;
'elev-002-002']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use the &amp;quot;glist&amp;quot; method of the Mapset class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.gis import Mapset&lt;br /&gt;
m = Mapset()&lt;br /&gt;
m.glist('rast', pattern='elev-*')&lt;br /&gt;
['elev-002-000',  'elev-000-000',  'elev-000-002',  'elev-000-001',&lt;br /&gt;
'elev-001-001',  'elev-002-002',  'elev-002-001',  'elev-001-000',&lt;br /&gt;
'elev-001-002']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... that uses the &amp;quot;G_list&amp;quot; function through ctypes and therefore is faster.&lt;br /&gt;
&lt;br /&gt;
Note: If you choose the first solution it is better if you use directly the&lt;br /&gt;
function in [http://grass.osgeo.org/programming7/namespacepython_1_1script_1_1core.html python.script.core.mlist_grouped() etc.].&lt;br /&gt;
&lt;br /&gt;
=== Interface to copying maps (g.copy) ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
&lt;br /&gt;
vectinmap = 'zipcodes_wake'&lt;br /&gt;
vectoutmap = 'zip_elev_zonal'&lt;br /&gt;
g.copy(vect=(vectinmap,vectoutmap) )&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample script for opening, query and closing of a vector map ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
# Example for pyGRASS usage - vector API&lt;br /&gt;
&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
from grass.pygrass.vector import VectorTopo&lt;br /&gt;
 &lt;br /&gt;
g.message(&amp;quot;Assessing vector topology...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
vectmap = 'zipcodes_wake'&lt;br /&gt;
zipcodes = VectorTopo(vectmap)&lt;br /&gt;
&lt;br /&gt;
# Open the map with topology:&lt;br /&gt;
zipcodes.open()&lt;br /&gt;
&lt;br /&gt;
# query number of topological features&lt;br /&gt;
areas   = zipcodes.number_of(&amp;quot;areas&amp;quot;)&lt;br /&gt;
islands = zipcodes.number_of(&amp;quot;islands&amp;quot;)&lt;br /&gt;
print 'Map: &amp;lt;' + vectmap + '&amp;gt; with %d areas and %d islands' % (areas, islands)&lt;br /&gt;
&lt;br /&gt;
# http://www.ing.unitn.it/~zambelli/projects/pygrass/attributes.html&lt;br /&gt;
# (note that above documentation is slightly outdated)&lt;br /&gt;
dblink = zipcodes.dblinks[0]&lt;br /&gt;
print 'DB name:'&lt;br /&gt;
print dblink.database&lt;br /&gt;
table = dblink.table()&lt;br /&gt;
print 'Column names:'&lt;br /&gt;
print table.columns.names()&lt;br /&gt;
print 'Column types:'&lt;br /&gt;
print table.columns.types()&lt;br /&gt;
&lt;br /&gt;
zipcodes.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample script for Landsat 7 processing ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
#Date: 7th February, 2013&lt;br /&gt;
#Public domain, GRASS GIS&lt;br /&gt;
&lt;br /&gt;
#Run this script in the terminal as:&lt;br /&gt;
#python python-grass.py&lt;br /&gt;
#For debugging, run as:&lt;br /&gt;
#python -i python-grass.py&lt;br /&gt;
#PURPOSE&lt;br /&gt;
#This script processes LANDSAT 7 ETM+ images&lt;br /&gt;
#1 - unzip *.gz files&lt;br /&gt;
#2 - import files in GRASS GIS Location of your choice (r.in.gdal)&lt;br /&gt;
#3 - DN to Top of Atmosphere reflectance (i.landsat.toar)&lt;br /&gt;
#4 - TOA reflectance to Surface reflectance (i.atcorr)&lt;br /&gt;
#5 - NDVI (i.vi), Albedo (i.albedo), Emissivity (i.emissivity)&lt;br /&gt;
&lt;br /&gt;
#USER HAS TO SET THOSE&lt;br /&gt;
#QUIET REPORTS&lt;br /&gt;
QIET=True&lt;br /&gt;
#OVERWRITE EXISTING FILES&lt;br /&gt;
OVR=False&lt;br /&gt;
#Define Landsat 7 sensor for i.landsat.toar&lt;br /&gt;
LSENSOR=&amp;quot;tm7&amp;quot;&lt;br /&gt;
#Setup the path to the Landsat 7 Directories&lt;br /&gt;
rsdatapath=&amp;quot;/home/yann/RSDATA/Myanmar/L7&amp;quot;&lt;br /&gt;
#Setup your GRASS GIS working directory&lt;br /&gt;
gisdb=&amp;quot;/home/yann/GRASSDATA&amp;quot;&lt;br /&gt;
location=&amp;quot;L7_Myanmar&amp;quot;&lt;br /&gt;
print location&lt;br /&gt;
mapset=&amp;quot;PERMANENT&amp;quot;&lt;br /&gt;
#DEM input to atmospheric correction&lt;br /&gt;
inDEM=rsdatapath+&amp;quot;/dem.tif&amp;quot;&lt;br /&gt;
#set L7 Metadata wildcards&lt;br /&gt;
wldc_mtl=&amp;quot;*_MTL.txt&amp;quot;&lt;br /&gt;
#wldc_met=&amp;quot;*.met&amp;quot;&lt;br /&gt;
#Visibility distance [Km]&lt;br /&gt;
vis=18&lt;br /&gt;
&lt;br /&gt;
#Set python path to enable finding of grass.script lib&lt;br /&gt;
&lt;br /&gt;
#END OF USER CHANGES&lt;br /&gt;
###DO NOT CHANGE ANYTHING AFTER THIS LINE !&lt;br /&gt;
###&lt;br /&gt;
#Load necessary libraries&lt;br /&gt;
import os, glob, time, re&lt;br /&gt;
from grass import script as g&lt;br /&gt;
from grass.script import setup as gsetup&lt;br /&gt;
gisbase=os.environ['GISBASE']&lt;br /&gt;
gsetup.init(gisbase,gisdb,location,mapset)&lt;br /&gt;
from grass.pygrass.modules.shortcuts import raster as r&lt;br /&gt;
from grass.pygrass.modules.shortcuts import imagery as i&lt;br /&gt;
from grass.pygrass.modules.shortcuts import display as d&lt;br /&gt;
#Needed for floor()&lt;br /&gt;
from math import *&lt;br /&gt;
#env = os.environ.copy()&lt;br /&gt;
#env['GRASS_MESSAGE_FORMAT'] = 'gui'&lt;br /&gt;
#Function to get a list of L7 Directories in the rsdatapath&lt;br /&gt;
def fn(path):&lt;br /&gt;
	for top, dirs, files in os.walk(path):&lt;br /&gt;
		return [os.path.join(top, dir) for dir in dirs]&lt;br /&gt;
&lt;br /&gt;
#START PROCESS&lt;br /&gt;
### PART 0: PRE-PROCESSING STUFF ###&lt;br /&gt;
#import DEM for atmospheric correction&lt;br /&gt;
#r.in.gdal(input=inDEM,output=&amp;quot;dem&amp;quot;,overwrite=OVR)&lt;br /&gt;
#r.mapcalc(expression=&amp;quot;dem=25&amp;quot;,overwrite=OVR)&lt;br /&gt;
#create a visibility map&lt;br /&gt;
r.mapcalc(expression=&amp;quot;vis=18&amp;quot;,overwrite=OVR)&lt;br /&gt;
#Find the central location of the Landsat file from metadata&lt;br /&gt;
metadata=[]&lt;br /&gt;
fileList=[]&lt;br /&gt;
L7Dirs=fn(rsdatapath)&lt;br /&gt;
for L7Dir in L7Dirs:&lt;br /&gt;
	#Ungzip all of your Landsat7 images in all your directories&lt;br /&gt;
#	print &amp;quot;Ungzip Landsat files in\t&amp;quot;,L7Dir&lt;br /&gt;
#	p=os.system(&amp;quot;gzip -d -q &amp;quot;+L7Dir+&amp;quot;/*.gz&amp;quot;)&lt;br /&gt;
	#Using pthreads on multi-core machines&lt;br /&gt;
	#p=os.system(&amp;quot;pigz -d &amp;quot;+L7Dir+&amp;quot;/*.gz&amp;quot;)&lt;br /&gt;
	#Wait ten seconds for gzip to create the tif images&lt;br /&gt;
#	time.sleep(10)&lt;br /&gt;
	print &amp;quot;Import in GRASS GIS&amp;quot;&lt;br /&gt;
	for L7f in glob.glob(os.path.join(L7Dir,&amp;quot;*.[tT][iI][fF]&amp;quot;)):&lt;br /&gt;
		f1=L7f.replace(L7Dir+&amp;quot;/&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		f2=f1.replace(&amp;quot;.TIF&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		f3=f2.replace(&amp;quot;_B10&amp;quot;,&amp;quot;.1&amp;quot;)&lt;br /&gt;
		f4=f3.replace(&amp;quot;_B20&amp;quot;,&amp;quot;.2&amp;quot;)&lt;br /&gt;
		f5=f4.replace(&amp;quot;_B30&amp;quot;,&amp;quot;.3&amp;quot;)&lt;br /&gt;
		f6=f5.replace(&amp;quot;_B40&amp;quot;,&amp;quot;.4&amp;quot;)&lt;br /&gt;
		f7=f6.replace(&amp;quot;_B50&amp;quot;,&amp;quot;.5&amp;quot;)&lt;br /&gt;
		f8=f7.replace(&amp;quot;_B61&amp;quot;,&amp;quot;.61&amp;quot;)&lt;br /&gt;
		f9=f8.replace(&amp;quot;_B62&amp;quot;,&amp;quot;.62&amp;quot;)&lt;br /&gt;
		f10=f9.replace(&amp;quot;_B70&amp;quot;,&amp;quot;.7&amp;quot;)&lt;br /&gt;
		f11=f10.replace(&amp;quot;_B80&amp;quot;,&amp;quot;.8&amp;quot;)&lt;br /&gt;
		f12=f11.replace(&amp;quot;L72&amp;quot;,&amp;quot;L71&amp;quot;)&lt;br /&gt;
		L7r=f12.replace(&amp;quot;_VCID_&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,L7r&lt;br /&gt;
		r.in_gdal(input=L7f,output=L7r,flags=&amp;quot;e&amp;quot;,overwrite=OVR)&lt;br /&gt;
		fileList.append(L7r)&lt;br /&gt;
&lt;br /&gt;
	#reproject the DEM World map for the new PERMANENT location extents&lt;br /&gt;
	r.proj(input=&amp;quot;dem&amp;quot;,location=&amp;quot;Myanmar&amp;quot;,memory=10000,resolution=90.0,overwrite=OVR)&lt;br /&gt;
	#Get list of metadata files&lt;br /&gt;
	for metaf in glob.glob(os.path.join(L7Dir,wldc_mtl)):&lt;br /&gt;
		metadata.append(metaf)&lt;br /&gt;
	print &amp;quot;Metadata in:\n&amp;quot;,metadata[0]&lt;br /&gt;
	with open(metadata[0],&amp;quot;r&amp;quot;) as f:&lt;br /&gt;
		data=f.read()&lt;br /&gt;
&lt;br /&gt;
	f.close()&lt;br /&gt;
	dt=data.split(&amp;quot;\n&amp;quot;)&lt;br /&gt;
	for idx in range(len(dt)):&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_UL_LON_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			ulx=float(dt[idx].replace(&amp;quot;CORNER_UL_LON_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_UL_LAT_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			uly=float(dt[idx].replace(&amp;quot;CORNER_UL_LAT_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_LR_LON_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			lrx=float(dt[idx].replace(&amp;quot;CORNER_LR_LON_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_LR_LAT_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			lry=float(dt[idx].replace(&amp;quot;CORNER_LR_LAT_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		#Two cases, because a string starting by 0 is not converted well&lt;br /&gt;
		found=dt[idx].find(&amp;quot;SCENE_CENTER_TIME = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			tim=dt[idx].replace(&amp;quot;SCENE_CENTER_TIME = &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
			print &amp;quot;timestamp=&amp;quot;,str(tim)&lt;br /&gt;
			gmth=float(tim.split(&amp;quot;:&amp;quot;)[0])&lt;br /&gt;
			gmtm=float(tim.split(&amp;quot;:&amp;quot;)[1])&lt;br /&gt;
			gmtdec=float(tim.split(&amp;quot;:&amp;quot;)[2].replace(&amp;quot;Z&amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
			print gmth,gmtm,gmtdec&lt;br /&gt;
		found=dt[idx].find(&amp;quot;DATE_ACQUIRED = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			dat=dt[idx].replace(&amp;quot;DATE_ACQUIRED = &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
			date=dat.split(&amp;quot;-&amp;quot;)&lt;br /&gt;
		found=dt[idx].find(&amp;quot;SUN_ELEVATION = &amp;quot;)&lt;br /&gt;
                if found &amp;gt; 0:&lt;br /&gt;
                        sunza=90-float(dt[idx].replace(&amp;quot;SUN_ELEVATION = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	#L7 DN-&amp;gt;Rad-&amp;gt;Ref&lt;br /&gt;
	print &amp;quot;Convert DN to Rad to TOARef&amp;quot;&lt;br /&gt;
	f1=sorted(fileList)[0]&lt;br /&gt;
	f2=f1.replace(L7Dir+&amp;quot;/&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
	pref=f2[:-1]&lt;br /&gt;
	outpref=pref[:-2]+&amp;quot;.toar.&amp;quot;&lt;br /&gt;
	print &amp;quot;Prefix IN:\t&amp;quot;,pref&lt;br /&gt;
	print &amp;quot;Prefix OUT:\t&amp;quot;, outpref&lt;br /&gt;
	i.landsat_toar(input_prefix=pref,output_prefix=outpref,metfile=metadata[0],sensor=LSENSOR,quiet=QIET,overwrite=OVR)&lt;br /&gt;
	#Atmospheric Correction&lt;br /&gt;
	print &amp;quot;Atmospheric Correction&amp;quot;&lt;br /&gt;
	# Basic script for i.atcorr for L 7 ETM+&lt;br /&gt;
	#Geometrical conditions (L7ETM+)&lt;br /&gt;
	geom=7&lt;br /&gt;
	#Sensor height (satellite is -1000)&lt;br /&gt;
	sens_height=-1000&lt;br /&gt;
	#Here we suppose you have altitude (DEM) and Visibility (VIS) maps ready&lt;br /&gt;
	#---------------------------------------------&lt;br /&gt;
	#Visibility dummy value (overwritten by VIS raster input)&lt;br /&gt;
	vis=15&lt;br /&gt;
	#Altitude dummy value (in Km should be negative in this param file)&lt;br /&gt;
	#(overwritten by DEM raster input)&lt;br /&gt;
	alt=-1.200&lt;br /&gt;
	#datetime of satellite overpass (month, day, GMT decimal hour)&lt;br /&gt;
	mdh=str(int(date[1]))+&amp;quot; &amp;quot;+str(int(date[2]))+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % (gmth+gmtm/60.0+gmtdec/3600.0))&lt;br /&gt;
	print &amp;quot;MM DD hh.ddd:\t&amp;quot;,mdh&lt;br /&gt;
	# Central Lat/Long&lt;br /&gt;
	Long=ulx+(lrx-ulx)/2.0&lt;br /&gt;
	Lat=lry+(uly-lry)/2.0&lt;br /&gt;
	print &amp;quot;Center:\t(&amp;quot;,Long, &amp;quot;,&amp;quot;, Lat,&amp;quot;)&amp;quot;&lt;br /&gt;
	#Atmospheric mode&lt;br /&gt;
	atm_mode=1 #Tropical&lt;br /&gt;
	#Aerosol model&lt;br /&gt;
	aerosol_mode=2 #Sri Lanka is a small island (maritime)&lt;br /&gt;
	#satellite band number (L5TM [25,26,27,28,29,30], L7ETM+ [61,62,63,64,65,66,67])&lt;br /&gt;
	satbandno=61 #Band 1 of L7ETM+ is first to undergo atmospheric correction&lt;br /&gt;
	#make time stamp for use in time series analysis&lt;br /&gt;
	dat1=str(date[2])+&amp;quot;-&amp;quot;+str(date[1])+&amp;quot;-&amp;quot;+str(date[0])&lt;br /&gt;
	dat=dat1.replace(&amp;quot; &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
	timestamp=time.strftime(&amp;quot;%d %b %Y&amp;quot;,time.strptime(dat,&amp;quot;%d-%m-%Y&amp;quot;))&lt;br /&gt;
	print &amp;quot;Timestamp:\t&amp;quot;,timestamp&lt;br /&gt;
	for idx in [1,2,3,4,5,7]:&lt;br /&gt;
		b=pref[:-2]+&amp;quot;.toar.&amp;quot;+str(idx)&lt;br /&gt;
		b_out=b.replace(&amp;quot;.toar.&amp;quot;,&amp;quot;.surf.&amp;quot;)&lt;br /&gt;
		param=[]&lt;br /&gt;
		param.append(str(geom)+&amp;quot; - geometrical conditions=Landsat 7 ETM+\n&amp;quot;)&lt;br /&gt;
		param.append(str(mdh)+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % Long)+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % Lat)+&amp;quot; - month day hh.ddd longitude latitude (hh.ddd is in decimal hours GMT)\n&amp;quot;)&lt;br /&gt;
		param.append(str(atm_mode)+&amp;quot; - atmospheric mode=tropical\n&amp;quot;)&lt;br /&gt;
		param.append(str(aerosol_mode)+&amp;quot; - aerosols model=maritime\n&amp;quot;)&lt;br /&gt;
		param.append(str(vis)+&amp;quot; - visibility [km] (aerosol model concentration), not used as there is raster input\n&amp;quot;)&lt;br /&gt;
		param.append(str(alt)+&amp;quot; - mean target elevation above sea level [km] (here 600m asl), not used as there is raster input\n&amp;quot;)&lt;br /&gt;
		param.append(str(sens_height)+&amp;quot; - sensor height (here, sensor on board a satellite)\n&amp;quot;)&lt;br /&gt;
		param.append(str(satbandno)+&amp;quot; - i th band of ETM+ Landsat 7 (atcorr internal no)\n&amp;quot;)&lt;br /&gt;
		f=open(os.path.join(L7Dir,&amp;quot;param_L7.txt&amp;quot;),&amp;quot;w&amp;quot;)&lt;br /&gt;
		f.writelines(param)&lt;br /&gt;
		f.close()&lt;br /&gt;
		prm=os.path.join(L7Dir,&amp;quot;param_L7.txt&amp;quot;)&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,b&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,b_out&lt;br /&gt;
		i.atcorr(input=b, elevation=&amp;quot;dem&amp;quot;, visibility=&amp;quot;vis&amp;quot;, parameters=prm, output=b_out, flags=&amp;quot;ra&amp;quot;, range=[0,1],quiet=QIET,overwrite=OVR)&lt;br /&gt;
		r.timestamp(map=b_out,date=timestamp,finish_=False)&lt;br /&gt;
		satbandno = satbandno + 1&lt;br /&gt;
&lt;br /&gt;
	#Allocate surface reflectance names&lt;br /&gt;
	b1=pref[:-2]+&amp;quot;.surf.1&amp;quot;&lt;br /&gt;
	b2=pref[:-2]+&amp;quot;.surf.2&amp;quot;&lt;br /&gt;
	b3=pref[:-2]+&amp;quot;.surf.3&amp;quot;&lt;br /&gt;
	b4=pref[:-2]+&amp;quot;.surf.4&amp;quot;&lt;br /&gt;
	b5=pref[:-2]+&amp;quot;.surf.5&amp;quot;&lt;br /&gt;
	b61=pref[:-2]+&amp;quot;.toar.61&amp;quot;&lt;br /&gt;
	b62=pref[:-2]+&amp;quot;.toar.62&amp;quot;&lt;br /&gt;
	b7=pref[:-2]+&amp;quot;.surf.7&amp;quot;&lt;br /&gt;
	b8=pref[:-2]+&amp;quot;.surf.8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	### PART 1: BASIC STUFF ###&lt;br /&gt;
	b_in=pref[:-2]+&amp;quot;.toar.&amp;quot;&lt;br /&gt;
	b_clouds=pref[:-2]+&amp;quot;.toar.acca&amp;quot;&lt;br /&gt;
	print &amp;quot;Clouds:\t\t&amp;gt;&amp;quot;,b_clouds&lt;br /&gt;
	i.landsat_acca(input_prefix=b_in,output=b_clouds,overwrite=OVR)&lt;br /&gt;
	#png_clouds=L7Dir+&amp;quot;/&amp;quot;+pref[:-2]+&amp;quot;.clouds.png&amp;quot;&lt;br /&gt;
	#d.mon(start='png',output=png_clouds,width=800,height=800)&lt;br /&gt;
	print &amp;quot;MASK:\t\tON&amp;quot;&lt;br /&gt;
	#Should always be rewritten!&lt;br /&gt;
	r.mask(raster=b_clouds,flags=&amp;quot;i&amp;quot;,overwrite=True)&lt;br /&gt;
&lt;br /&gt;
	b_ndvi=pref[:-2]+&amp;quot;.surf.ndvi&amp;quot;&lt;br /&gt;
	print &amp;quot;NDVI:\t&amp;quot;,b_ndvi&lt;br /&gt;
	i.vi(red=b3,nir=b4,output=b_ndvi,viname=&amp;quot;ndvi&amp;quot;,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
&lt;br /&gt;
	b_in=[b1,b2,b3,b4,b5,b7]&lt;br /&gt;
	b_albedo=pref[:-2]+&amp;quot;.surf.albedo&amp;quot;&lt;br /&gt;
	print &amp;quot;Albedo:\t&amp;quot;,b_albedo&lt;br /&gt;
	i.albedo(input=b_in,output=b_albedo,flags=&amp;quot;lc&amp;quot;,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
	&lt;br /&gt;
	b_emissivity=pref[:-2]+&amp;quot;.surf.emissivity&amp;quot;&lt;br /&gt;
	print &amp;quot;Emissivity:\t&amp;quot;,b_emissivity&lt;br /&gt;
	i.emissivity(input=b_ndvi, output=b_emissivity,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiprocessing example: parallelized SHAPE file import ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
Multiprocessing example: parallelized SHAPE file import&lt;br /&gt;
&lt;br /&gt;
Created on Fri, Oct 18, 2013, posted to grass-user@lists.osgeo.org&lt;br /&gt;
&lt;br /&gt;
@author: Pietro Zambelli, freely inspired by: http://stackoverflow.com/a/16071616&lt;br /&gt;
         http://lists.osgeo.org/pipermail//grass-user/2013-October/069130.html&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Directory containing SHAPE files to import&lt;br /&gt;
DIR = '/data/shp'&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
from multiprocessing import Queue, Process, cpu_count&lt;br /&gt;
from os.path import split&lt;br /&gt;
from subprocess import Popen&lt;br /&gt;
&lt;br /&gt;
from grass.pygrass.functions import findfiles&lt;br /&gt;
&lt;br /&gt;
def spawn(func):&lt;br /&gt;
    def fun(q_in, q_out):&lt;br /&gt;
        while True:&lt;br /&gt;
            path, cmdstr = q_in.get()&lt;br /&gt;
            if path is None:&lt;br /&gt;
                break&lt;br /&gt;
            q_out.put(func(path, cmdstr))&lt;br /&gt;
    return fun&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mltp_importer(dirpath, match, cmdstr, func, nprocs=cpu_count()):&lt;br /&gt;
    q_in = Queue(1)&lt;br /&gt;
    q_out = Queue()&lt;br /&gt;
    procs = [Process(target=spawn(func), args=(q_in, q_out))&lt;br /&gt;
             for _ in range(nprocs)]&lt;br /&gt;
    for proc in procs:&lt;br /&gt;
        proc.daemon = True&lt;br /&gt;
        proc.start()&lt;br /&gt;
&lt;br /&gt;
    # set the parameters&lt;br /&gt;
    sent = [q_in.put((path, cmdstr)) for path in findfiles(dirpath, match)]&lt;br /&gt;
    # set the end of the cycle&lt;br /&gt;
    [q_in.put((None, None)) for proc in procs]&lt;br /&gt;
    [proc.join() for proc in procs]&lt;br /&gt;
    return [q_out.get() for _ in range(len(sent))]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def importer(path, cmdstr):&lt;br /&gt;
    name = split(path)[-1][:-4]&lt;br /&gt;
    print name&lt;br /&gt;
    popen = Popen(cmdstr.format(path=path, name=name), shell=True)&lt;br /&gt;
    popen.wait()&lt;br /&gt;
    return path, name, False if popen.returncode else True&lt;br /&gt;
&lt;br /&gt;
CMD = 'v.in.ogr dsn={path} layer={name} output={name}'&lt;br /&gt;
&lt;br /&gt;
processed = mltp_importer(DIR, '*.shp', CMD, importer)&lt;br /&gt;
# check for errors&lt;br /&gt;
errors = [p for p in processed if not p[2]]&lt;br /&gt;
if errors:&lt;br /&gt;
    # do something (print list of failed SHP files at end)&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Python}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=22902</id>
		<title>Python/pygrass</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=22902"/>
		<updated>2016-03-29T09:42:55Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Interface to listing maps (g.list/g.mlist) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''PyGRASS'' is a library that extends the GRASS GIS 7 capabilities to allow users to access the low-level GRASS API.&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
Detailed PyGRASS documentation: http://grass.osgeo.org/grass71/manuals/libpython/&lt;br /&gt;
&lt;br /&gt;
== How to test library ==&lt;br /&gt;
&lt;br /&gt;
''pygrass'' has 'doctest' included in its code. You can run doctest in the [http://grass.osgeo.org/sampledata/north_carolina/nc_basic_spm_grass7.tar.gz North Carolina basic location], using the mapset '''user1'''. &lt;br /&gt;
&lt;br /&gt;
To test a single module (file) you have to change into the source code directory of pygrass and run the following code (this is an example of functions.py):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python -m doctest functions.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* Zambelli, P., Gebbert, S., Ciolli, M., 2013. ''Pygrass: An Object Oriented Python Application Programming Interface (API) for Geographic Resources Analysis Support System (GRASS) Geographic Information System (GIS)''. ISPRS International Journal of Geo-Information 2, 201–219. ([http://dx.doi.org/10.3390/ijgi2010201 DOI] | [http://www.mdpi.com/2220-9964/2/1/201/pdf PDF])&lt;br /&gt;
&lt;br /&gt;
* [http://grass.osgeo.org/grass71/manuals/libpython/ pyGrass documentation] (updated weekly from SVN)&lt;br /&gt;
&lt;br /&gt;
== Sample PyGRASS scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Training material ===&lt;br /&gt;
&lt;br /&gt;
Two workshops were presented during the [http://geomorfolab.arch.unige.it/genova2013/ XIV Italian meeting of GRASS] at Genova.&lt;br /&gt;
The workshops use '''ipython notebook''' to show the python and pygrass API, all the material are available on github ([https://github.com/zarch/workshop-python python], [https://github.com/zarch/workshop-pygrass pygrass]). All the execute examples are reported here:&lt;br /&gt;
&lt;br /&gt;
* python training (Genova)&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/00_intro.ipynb      Introduction]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/01_data_types.ipynb Data Types]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/02_syntax.ipynb     Syntax]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/03_function.ipynb   Function]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/04_class.ipynb      Class]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/05_other.ipynb      Other]&lt;br /&gt;
&lt;br /&gt;
* python training (EURAC)&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/00_intro.ipynb Introduction]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/01_data_types.ipynb Data Types]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/02_syntax.ipynb Syntax]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/03_version_control_system.ipynb Version Control System (hg)]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/04_objects.ipynb Objects]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/05_python_debugger.ipynb Debugger]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/06_functions.ipynb Functions]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/07_numpy.ipynb Numpy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/08_matplotlib.ipynb Matplotlib]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/09_scipy.ipynb Scipy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/10_pandas.ipynb Pandas]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/11_sympy.ipynb Sympy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/12_user_interfaces.ipynb GUI]&lt;br /&gt;
&lt;br /&gt;
* pygrass training&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/00_Modules.ipynb Modules]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/01_GIS_objects.ipynb GIS]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/02_Vector.ipynb Vector]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/03_Raster.ipynb Raster]&lt;br /&gt;
&lt;br /&gt;
=== Interface to listing maps (g.list/g.mlist) ===&lt;br /&gt;
&lt;br /&gt;
Here we call a GRASS module that writes to stdout and do not call a Python function that returns a Python object, therefore we can save stdout and then parse it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
import subprocess as sub&lt;br /&gt;
&lt;br /&gt;
gl = g.list   # GRASS 7&lt;br /&gt;
gl(type='raster', pattern='elev-*', stdout=sub.PIPE)&lt;br /&gt;
gl.outputs.stdout.split()&lt;br /&gt;
['elev-000-000', 'elev-000-001', 'elev-000-002', 'elev-001-000',&lt;br /&gt;
'elev-001-001', 'elev-001-002', 'elev-002-000', 'elev-002-001',&lt;br /&gt;
'elev-002-002']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use the &amp;quot;glist&amp;quot; method of the Mapset class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.gis import Mapset&lt;br /&gt;
m = Mapset()&lt;br /&gt;
m.glist('rast', pattern='elev-*')&lt;br /&gt;
['elev-002-000',  'elev-000-000',  'elev-000-002',  'elev-000-001',&lt;br /&gt;
'elev-001-001',  'elev-002-002',  'elev-002-001',  'elev-001-000',&lt;br /&gt;
'elev-001-002']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... that uses the &amp;quot;G_list&amp;quot; function through ctypes and therefore is faster.&lt;br /&gt;
&lt;br /&gt;
Note: If you choose the first solution it is better if you use directly the&lt;br /&gt;
function in [http://grass.osgeo.org/programming7/namespacepython_1_1script_1_1core.html python.script.core.mlist_grouped() etc.].&lt;br /&gt;
&lt;br /&gt;
=== Interface to copying maps (g.copy) ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
&lt;br /&gt;
vectinmap = 'zipcodes_wake'&lt;br /&gt;
vectoutmap = 'zip_elev_zonal'&lt;br /&gt;
g.copy(vect=&amp;quot;%s,%s&amp;quot; % (vectinmap,vectoutmap) )&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample script for opening, query and closing of a vector map ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
# Example for pyGRASS usage - vector API&lt;br /&gt;
&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
from grass.pygrass.vector import VectorTopo&lt;br /&gt;
 &lt;br /&gt;
g.message(&amp;quot;Assessing vector topology...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
vectmap = 'zipcodes_wake'&lt;br /&gt;
zipcodes = VectorTopo(vectmap)&lt;br /&gt;
&lt;br /&gt;
# Open the map with topology:&lt;br /&gt;
zipcodes.open()&lt;br /&gt;
&lt;br /&gt;
# query number of topological features&lt;br /&gt;
areas   = zipcodes.number_of(&amp;quot;areas&amp;quot;)&lt;br /&gt;
islands = zipcodes.number_of(&amp;quot;islands&amp;quot;)&lt;br /&gt;
print 'Map: &amp;lt;' + vectmap + '&amp;gt; with %d areas and %d islands' % (areas, islands)&lt;br /&gt;
&lt;br /&gt;
# http://www.ing.unitn.it/~zambelli/projects/pygrass/attributes.html&lt;br /&gt;
# (note that above documentation is slightly outdated)&lt;br /&gt;
dblink = zipcodes.dblinks[0]&lt;br /&gt;
print 'DB name:'&lt;br /&gt;
print dblink.database&lt;br /&gt;
table = dblink.table()&lt;br /&gt;
print 'Column names:'&lt;br /&gt;
print table.columns.names()&lt;br /&gt;
print 'Column types:'&lt;br /&gt;
print table.columns.types()&lt;br /&gt;
&lt;br /&gt;
zipcodes.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample script for Landsat 7 processing ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
#Date: 7th February, 2013&lt;br /&gt;
#Public domain, GRASS GIS&lt;br /&gt;
&lt;br /&gt;
#Run this script in the terminal as:&lt;br /&gt;
#python python-grass.py&lt;br /&gt;
#For debugging, run as:&lt;br /&gt;
#python -i python-grass.py&lt;br /&gt;
#PURPOSE&lt;br /&gt;
#This script processes LANDSAT 7 ETM+ images&lt;br /&gt;
#1 - unzip *.gz files&lt;br /&gt;
#2 - import files in GRASS GIS Location of your choice (r.in.gdal)&lt;br /&gt;
#3 - DN to Top of Atmosphere reflectance (i.landsat.toar)&lt;br /&gt;
#4 - TOA reflectance to Surface reflectance (i.atcorr)&lt;br /&gt;
#5 - NDVI (i.vi), Albedo (i.albedo), Emissivity (i.emissivity)&lt;br /&gt;
&lt;br /&gt;
#USER HAS TO SET THOSE&lt;br /&gt;
#QUIET REPORTS&lt;br /&gt;
QIET=True&lt;br /&gt;
#OVERWRITE EXISTING FILES&lt;br /&gt;
OVR=False&lt;br /&gt;
#Define Landsat 7 sensor for i.landsat.toar&lt;br /&gt;
LSENSOR=&amp;quot;tm7&amp;quot;&lt;br /&gt;
#Setup the path to the Landsat 7 Directories&lt;br /&gt;
rsdatapath=&amp;quot;/home/yann/RSDATA/Myanmar/L7&amp;quot;&lt;br /&gt;
#Setup your GRASS GIS working directory&lt;br /&gt;
gisdb=&amp;quot;/home/yann/GRASSDATA&amp;quot;&lt;br /&gt;
location=&amp;quot;L7_Myanmar&amp;quot;&lt;br /&gt;
print location&lt;br /&gt;
mapset=&amp;quot;PERMANENT&amp;quot;&lt;br /&gt;
#DEM input to atmospheric correction&lt;br /&gt;
inDEM=rsdatapath+&amp;quot;/dem.tif&amp;quot;&lt;br /&gt;
#set L7 Metadata wildcards&lt;br /&gt;
wldc_mtl=&amp;quot;*_MTL.txt&amp;quot;&lt;br /&gt;
#wldc_met=&amp;quot;*.met&amp;quot;&lt;br /&gt;
#Visibility distance [Km]&lt;br /&gt;
vis=18&lt;br /&gt;
&lt;br /&gt;
#Set python path to enable finding of grass.script lib&lt;br /&gt;
&lt;br /&gt;
#END OF USER CHANGES&lt;br /&gt;
###DO NOT CHANGE ANYTHING AFTER THIS LINE !&lt;br /&gt;
###&lt;br /&gt;
#Load necessary libraries&lt;br /&gt;
import os, glob, time, re&lt;br /&gt;
from grass import script as g&lt;br /&gt;
from grass.script import setup as gsetup&lt;br /&gt;
gisbase=os.environ['GISBASE']&lt;br /&gt;
gsetup.init(gisbase,gisdb,location,mapset)&lt;br /&gt;
from grass.pygrass.modules.shortcuts import raster as r&lt;br /&gt;
from grass.pygrass.modules.shortcuts import imagery as i&lt;br /&gt;
from grass.pygrass.modules.shortcuts import display as d&lt;br /&gt;
#Needed for floor()&lt;br /&gt;
from math import *&lt;br /&gt;
#env = os.environ.copy()&lt;br /&gt;
#env['GRASS_MESSAGE_FORMAT'] = 'gui'&lt;br /&gt;
#Function to get a list of L7 Directories in the rsdatapath&lt;br /&gt;
def fn(path):&lt;br /&gt;
	for top, dirs, files in os.walk(path):&lt;br /&gt;
		return [os.path.join(top, dir) for dir in dirs]&lt;br /&gt;
&lt;br /&gt;
#START PROCESS&lt;br /&gt;
### PART 0: PRE-PROCESSING STUFF ###&lt;br /&gt;
#import DEM for atmospheric correction&lt;br /&gt;
#r.in.gdal(input=inDEM,output=&amp;quot;dem&amp;quot;,overwrite=OVR)&lt;br /&gt;
#r.mapcalc(expression=&amp;quot;dem=25&amp;quot;,overwrite=OVR)&lt;br /&gt;
#create a visibility map&lt;br /&gt;
r.mapcalc(expression=&amp;quot;vis=18&amp;quot;,overwrite=OVR)&lt;br /&gt;
#Find the central location of the Landsat file from metadata&lt;br /&gt;
metadata=[]&lt;br /&gt;
fileList=[]&lt;br /&gt;
L7Dirs=fn(rsdatapath)&lt;br /&gt;
for L7Dir in L7Dirs:&lt;br /&gt;
	#Ungzip all of your Landsat7 images in all your directories&lt;br /&gt;
#	print &amp;quot;Ungzip Landsat files in\t&amp;quot;,L7Dir&lt;br /&gt;
#	p=os.system(&amp;quot;gzip -d -q &amp;quot;+L7Dir+&amp;quot;/*.gz&amp;quot;)&lt;br /&gt;
	#Using pthreads on multi-core machines&lt;br /&gt;
	#p=os.system(&amp;quot;pigz -d &amp;quot;+L7Dir+&amp;quot;/*.gz&amp;quot;)&lt;br /&gt;
	#Wait ten seconds for gzip to create the tif images&lt;br /&gt;
#	time.sleep(10)&lt;br /&gt;
	print &amp;quot;Import in GRASS GIS&amp;quot;&lt;br /&gt;
	for L7f in glob.glob(os.path.join(L7Dir,&amp;quot;*.[tT][iI][fF]&amp;quot;)):&lt;br /&gt;
		f1=L7f.replace(L7Dir+&amp;quot;/&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		f2=f1.replace(&amp;quot;.TIF&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		f3=f2.replace(&amp;quot;_B10&amp;quot;,&amp;quot;.1&amp;quot;)&lt;br /&gt;
		f4=f3.replace(&amp;quot;_B20&amp;quot;,&amp;quot;.2&amp;quot;)&lt;br /&gt;
		f5=f4.replace(&amp;quot;_B30&amp;quot;,&amp;quot;.3&amp;quot;)&lt;br /&gt;
		f6=f5.replace(&amp;quot;_B40&amp;quot;,&amp;quot;.4&amp;quot;)&lt;br /&gt;
		f7=f6.replace(&amp;quot;_B50&amp;quot;,&amp;quot;.5&amp;quot;)&lt;br /&gt;
		f8=f7.replace(&amp;quot;_B61&amp;quot;,&amp;quot;.61&amp;quot;)&lt;br /&gt;
		f9=f8.replace(&amp;quot;_B62&amp;quot;,&amp;quot;.62&amp;quot;)&lt;br /&gt;
		f10=f9.replace(&amp;quot;_B70&amp;quot;,&amp;quot;.7&amp;quot;)&lt;br /&gt;
		f11=f10.replace(&amp;quot;_B80&amp;quot;,&amp;quot;.8&amp;quot;)&lt;br /&gt;
		f12=f11.replace(&amp;quot;L72&amp;quot;,&amp;quot;L71&amp;quot;)&lt;br /&gt;
		L7r=f12.replace(&amp;quot;_VCID_&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,L7r&lt;br /&gt;
		r.in_gdal(input=L7f,output=L7r,flags=&amp;quot;e&amp;quot;,overwrite=OVR)&lt;br /&gt;
		fileList.append(L7r)&lt;br /&gt;
&lt;br /&gt;
	#reproject the DEM World map for the new PERMANENT location extents&lt;br /&gt;
	r.proj(input=&amp;quot;dem&amp;quot;,location=&amp;quot;Myanmar&amp;quot;,memory=10000,resolution=90.0,overwrite=OVR)&lt;br /&gt;
	#Get list of metadata files&lt;br /&gt;
	for metaf in glob.glob(os.path.join(L7Dir,wldc_mtl)):&lt;br /&gt;
		metadata.append(metaf)&lt;br /&gt;
	print &amp;quot;Metadata in:\n&amp;quot;,metadata[0]&lt;br /&gt;
	with open(metadata[0],&amp;quot;r&amp;quot;) as f:&lt;br /&gt;
		data=f.read()&lt;br /&gt;
&lt;br /&gt;
	f.close()&lt;br /&gt;
	dt=data.split(&amp;quot;\n&amp;quot;)&lt;br /&gt;
	for idx in range(len(dt)):&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_UL_LON_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			ulx=float(dt[idx].replace(&amp;quot;CORNER_UL_LON_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_UL_LAT_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			uly=float(dt[idx].replace(&amp;quot;CORNER_UL_LAT_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_LR_LON_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			lrx=float(dt[idx].replace(&amp;quot;CORNER_LR_LON_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_LR_LAT_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			lry=float(dt[idx].replace(&amp;quot;CORNER_LR_LAT_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		#Two cases, because a string starting by 0 is not converted well&lt;br /&gt;
		found=dt[idx].find(&amp;quot;SCENE_CENTER_TIME = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			tim=dt[idx].replace(&amp;quot;SCENE_CENTER_TIME = &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
			print &amp;quot;timestamp=&amp;quot;,str(tim)&lt;br /&gt;
			gmth=float(tim.split(&amp;quot;:&amp;quot;)[0])&lt;br /&gt;
			gmtm=float(tim.split(&amp;quot;:&amp;quot;)[1])&lt;br /&gt;
			gmtdec=float(tim.split(&amp;quot;:&amp;quot;)[2].replace(&amp;quot;Z&amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
			print gmth,gmtm,gmtdec&lt;br /&gt;
		found=dt[idx].find(&amp;quot;DATE_ACQUIRED = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			dat=dt[idx].replace(&amp;quot;DATE_ACQUIRED = &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
			date=dat.split(&amp;quot;-&amp;quot;)&lt;br /&gt;
		found=dt[idx].find(&amp;quot;SUN_ELEVATION = &amp;quot;)&lt;br /&gt;
                if found &amp;gt; 0:&lt;br /&gt;
                        sunza=90-float(dt[idx].replace(&amp;quot;SUN_ELEVATION = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	#L7 DN-&amp;gt;Rad-&amp;gt;Ref&lt;br /&gt;
	print &amp;quot;Convert DN to Rad to TOARef&amp;quot;&lt;br /&gt;
	f1=sorted(fileList)[0]&lt;br /&gt;
	f2=f1.replace(L7Dir+&amp;quot;/&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
	pref=f2[:-1]&lt;br /&gt;
	outpref=pref[:-2]+&amp;quot;.toar.&amp;quot;&lt;br /&gt;
	print &amp;quot;Prefix IN:\t&amp;quot;,pref&lt;br /&gt;
	print &amp;quot;Prefix OUT:\t&amp;quot;, outpref&lt;br /&gt;
	i.landsat_toar(input_prefix=pref,output_prefix=outpref,metfile=metadata[0],sensor=LSENSOR,quiet=QIET,overwrite=OVR)&lt;br /&gt;
	#Atmospheric Correction&lt;br /&gt;
	print &amp;quot;Atmospheric Correction&amp;quot;&lt;br /&gt;
	# Basic script for i.atcorr for L 7 ETM+&lt;br /&gt;
	#Geometrical conditions (L7ETM+)&lt;br /&gt;
	geom=7&lt;br /&gt;
	#Sensor height (satellite is -1000)&lt;br /&gt;
	sens_height=-1000&lt;br /&gt;
	#Here we suppose you have altitude (DEM) and Visibility (VIS) maps ready&lt;br /&gt;
	#---------------------------------------------&lt;br /&gt;
	#Visibility dummy value (overwritten by VIS raster input)&lt;br /&gt;
	vis=15&lt;br /&gt;
	#Altitude dummy value (in Km should be negative in this param file)&lt;br /&gt;
	#(overwritten by DEM raster input)&lt;br /&gt;
	alt=-1.200&lt;br /&gt;
	#datetime of satellite overpass (month, day, GMT decimal hour)&lt;br /&gt;
	mdh=str(int(date[1]))+&amp;quot; &amp;quot;+str(int(date[2]))+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % (gmth+gmtm/60.0+gmtdec/3600.0))&lt;br /&gt;
	print &amp;quot;MM DD hh.ddd:\t&amp;quot;,mdh&lt;br /&gt;
	# Central Lat/Long&lt;br /&gt;
	Long=ulx+(lrx-ulx)/2.0&lt;br /&gt;
	Lat=lry+(uly-lry)/2.0&lt;br /&gt;
	print &amp;quot;Center:\t(&amp;quot;,Long, &amp;quot;,&amp;quot;, Lat,&amp;quot;)&amp;quot;&lt;br /&gt;
	#Atmospheric mode&lt;br /&gt;
	atm_mode=1 #Tropical&lt;br /&gt;
	#Aerosol model&lt;br /&gt;
	aerosol_mode=2 #Sri Lanka is a small island (maritime)&lt;br /&gt;
	#satellite band number (L5TM [25,26,27,28,29,30], L7ETM+ [61,62,63,64,65,66,67])&lt;br /&gt;
	satbandno=61 #Band 1 of L7ETM+ is first to undergo atmospheric correction&lt;br /&gt;
	#make time stamp for use in time series analysis&lt;br /&gt;
	dat1=str(date[2])+&amp;quot;-&amp;quot;+str(date[1])+&amp;quot;-&amp;quot;+str(date[0])&lt;br /&gt;
	dat=dat1.replace(&amp;quot; &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
	timestamp=time.strftime(&amp;quot;%d %b %Y&amp;quot;,time.strptime(dat,&amp;quot;%d-%m-%Y&amp;quot;))&lt;br /&gt;
	print &amp;quot;Timestamp:\t&amp;quot;,timestamp&lt;br /&gt;
	for idx in [1,2,3,4,5,7]:&lt;br /&gt;
		b=pref[:-2]+&amp;quot;.toar.&amp;quot;+str(idx)&lt;br /&gt;
		b_out=b.replace(&amp;quot;.toar.&amp;quot;,&amp;quot;.surf.&amp;quot;)&lt;br /&gt;
		param=[]&lt;br /&gt;
		param.append(str(geom)+&amp;quot; - geometrical conditions=Landsat 7 ETM+\n&amp;quot;)&lt;br /&gt;
		param.append(str(mdh)+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % Long)+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % Lat)+&amp;quot; - month day hh.ddd longitude latitude (hh.ddd is in decimal hours GMT)\n&amp;quot;)&lt;br /&gt;
		param.append(str(atm_mode)+&amp;quot; - atmospheric mode=tropical\n&amp;quot;)&lt;br /&gt;
		param.append(str(aerosol_mode)+&amp;quot; - aerosols model=maritime\n&amp;quot;)&lt;br /&gt;
		param.append(str(vis)+&amp;quot; - visibility [km] (aerosol model concentration), not used as there is raster input\n&amp;quot;)&lt;br /&gt;
		param.append(str(alt)+&amp;quot; - mean target elevation above sea level [km] (here 600m asl), not used as there is raster input\n&amp;quot;)&lt;br /&gt;
		param.append(str(sens_height)+&amp;quot; - sensor height (here, sensor on board a satellite)\n&amp;quot;)&lt;br /&gt;
		param.append(str(satbandno)+&amp;quot; - i th band of ETM+ Landsat 7 (atcorr internal no)\n&amp;quot;)&lt;br /&gt;
		f=open(os.path.join(L7Dir,&amp;quot;param_L7.txt&amp;quot;),&amp;quot;w&amp;quot;)&lt;br /&gt;
		f.writelines(param)&lt;br /&gt;
		f.close()&lt;br /&gt;
		prm=os.path.join(L7Dir,&amp;quot;param_L7.txt&amp;quot;)&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,b&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,b_out&lt;br /&gt;
		i.atcorr(input=b, elevation=&amp;quot;dem&amp;quot;, visibility=&amp;quot;vis&amp;quot;, parameters=prm, output=b_out, flags=&amp;quot;ra&amp;quot;, range=[0,1],quiet=QIET,overwrite=OVR)&lt;br /&gt;
		r.timestamp(map=b_out,date=timestamp,finish_=False)&lt;br /&gt;
		satbandno = satbandno + 1&lt;br /&gt;
&lt;br /&gt;
	#Allocate surface reflectance names&lt;br /&gt;
	b1=pref[:-2]+&amp;quot;.surf.1&amp;quot;&lt;br /&gt;
	b2=pref[:-2]+&amp;quot;.surf.2&amp;quot;&lt;br /&gt;
	b3=pref[:-2]+&amp;quot;.surf.3&amp;quot;&lt;br /&gt;
	b4=pref[:-2]+&amp;quot;.surf.4&amp;quot;&lt;br /&gt;
	b5=pref[:-2]+&amp;quot;.surf.5&amp;quot;&lt;br /&gt;
	b61=pref[:-2]+&amp;quot;.toar.61&amp;quot;&lt;br /&gt;
	b62=pref[:-2]+&amp;quot;.toar.62&amp;quot;&lt;br /&gt;
	b7=pref[:-2]+&amp;quot;.surf.7&amp;quot;&lt;br /&gt;
	b8=pref[:-2]+&amp;quot;.surf.8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	### PART 1: BASIC STUFF ###&lt;br /&gt;
	b_in=pref[:-2]+&amp;quot;.toar.&amp;quot;&lt;br /&gt;
	b_clouds=pref[:-2]+&amp;quot;.toar.acca&amp;quot;&lt;br /&gt;
	print &amp;quot;Clouds:\t\t&amp;gt;&amp;quot;,b_clouds&lt;br /&gt;
	i.landsat_acca(input_prefix=b_in,output=b_clouds,overwrite=OVR)&lt;br /&gt;
	#png_clouds=L7Dir+&amp;quot;/&amp;quot;+pref[:-2]+&amp;quot;.clouds.png&amp;quot;&lt;br /&gt;
	#d.mon(start='png',output=png_clouds,width=800,height=800)&lt;br /&gt;
	print &amp;quot;MASK:\t\tON&amp;quot;&lt;br /&gt;
	#Should always be rewritten!&lt;br /&gt;
	r.mask(raster=b_clouds,flags=&amp;quot;i&amp;quot;,overwrite=True)&lt;br /&gt;
&lt;br /&gt;
	b_ndvi=pref[:-2]+&amp;quot;.surf.ndvi&amp;quot;&lt;br /&gt;
	print &amp;quot;NDVI:\t&amp;quot;,b_ndvi&lt;br /&gt;
	i.vi(red=b3,nir=b4,output=b_ndvi,viname=&amp;quot;ndvi&amp;quot;,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
&lt;br /&gt;
	b_in=[b1,b2,b3,b4,b5,b7]&lt;br /&gt;
	b_albedo=pref[:-2]+&amp;quot;.surf.albedo&amp;quot;&lt;br /&gt;
	print &amp;quot;Albedo:\t&amp;quot;,b_albedo&lt;br /&gt;
	i.albedo(input=b_in,output=b_albedo,flags=&amp;quot;lc&amp;quot;,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
	&lt;br /&gt;
	b_emissivity=pref[:-2]+&amp;quot;.surf.emissivity&amp;quot;&lt;br /&gt;
	print &amp;quot;Emissivity:\t&amp;quot;,b_emissivity&lt;br /&gt;
	i.emissivity(input=b_ndvi, output=b_emissivity,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiprocessing example: parallelized SHAPE file import ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
Multiprocessing example: parallelized SHAPE file import&lt;br /&gt;
&lt;br /&gt;
Created on Fri, Oct 18, 2013, posted to grass-user@lists.osgeo.org&lt;br /&gt;
&lt;br /&gt;
@author: Pietro Zambelli, freely inspired by: http://stackoverflow.com/a/16071616&lt;br /&gt;
         http://lists.osgeo.org/pipermail//grass-user/2013-October/069130.html&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Directory containing SHAPE files to import&lt;br /&gt;
DIR = '/data/shp'&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
from multiprocessing import Queue, Process, cpu_count&lt;br /&gt;
from os.path import split&lt;br /&gt;
from subprocess import Popen&lt;br /&gt;
&lt;br /&gt;
from grass.pygrass.functions import findfiles&lt;br /&gt;
&lt;br /&gt;
def spawn(func):&lt;br /&gt;
    def fun(q_in, q_out):&lt;br /&gt;
        while True:&lt;br /&gt;
            path, cmdstr = q_in.get()&lt;br /&gt;
            if path is None:&lt;br /&gt;
                break&lt;br /&gt;
            q_out.put(func(path, cmdstr))&lt;br /&gt;
    return fun&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mltp_importer(dirpath, match, cmdstr, func, nprocs=cpu_count()):&lt;br /&gt;
    q_in = Queue(1)&lt;br /&gt;
    q_out = Queue()&lt;br /&gt;
    procs = [Process(target=spawn(func), args=(q_in, q_out))&lt;br /&gt;
             for _ in range(nprocs)]&lt;br /&gt;
    for proc in procs:&lt;br /&gt;
        proc.daemon = True&lt;br /&gt;
        proc.start()&lt;br /&gt;
&lt;br /&gt;
    # set the parameters&lt;br /&gt;
    sent = [q_in.put((path, cmdstr)) for path in findfiles(dirpath, match)]&lt;br /&gt;
    # set the end of the cycle&lt;br /&gt;
    [q_in.put((None, None)) for proc in procs]&lt;br /&gt;
    [proc.join() for proc in procs]&lt;br /&gt;
    return [q_out.get() for _ in range(len(sent))]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def importer(path, cmdstr):&lt;br /&gt;
    name = split(path)[-1][:-4]&lt;br /&gt;
    print name&lt;br /&gt;
    popen = Popen(cmdstr.format(path=path, name=name), shell=True)&lt;br /&gt;
    popen.wait()&lt;br /&gt;
    return path, name, False if popen.returncode else True&lt;br /&gt;
&lt;br /&gt;
CMD = 'v.in.ogr dsn={path} layer={name} output={name}'&lt;br /&gt;
&lt;br /&gt;
processed = mltp_importer(DIR, '*.shp', CMD, importer)&lt;br /&gt;
# check for errors&lt;br /&gt;
errors = [p for p in processed if not p[2]]&lt;br /&gt;
if errors:&lt;br /&gt;
    # do something (print list of failed SHP files at end)&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Python}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=FOSS4G_Europe_2015:_GRASS_related_workshops_and_presentations&amp;diff=21799</id>
		<title>FOSS4G Europe 2015: GRASS related workshops and presentations</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=FOSS4G_Europe_2015:_GRASS_related_workshops_and_presentations&amp;diff=21799"/>
		<updated>2015-08-18T08:33:43Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: add presentation from EURAC and UNITN&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
FOSS4G Europe 2015, Como, Italy in July 14th-17th 2015, http://europe.foss4g.org/2015/&lt;br /&gt;
&lt;br /&gt;
== Workshops ==&lt;br /&gt;
&lt;br /&gt;
* Zambelli, P., Neteler, M., Delucchi, L., Petras, V., Petrasova, A., 2015: [https://github.com/wenzeslaus/python-grass-addon How to write a Python GRASS GIS 7 addon]. Workshop at [http://europe.foss4g.org/2015/ FOSS4G Europe 2015], 14-17 Jul 2015, Como, Italy ([http://europe.foss4g.org/2015/Workshops in program])&lt;br /&gt;
&lt;br /&gt;
== Presentations ==&lt;br /&gt;
&lt;br /&gt;
* Garegnani G., Zambelli P., Grilli G. Vettorato D. (2015): ''Evaluation of wind, solar and hydro energy potential using GRASS''. [http://europe.foss4g.org/2015/ FOSS4G Europe 2015], 14-17 Jul 2015, Como, Italy.&lt;br /&gt;
&lt;br /&gt;
* Garegnani G., Geri F., Zambelli P., Grilli G., Sacchelli S., Paletto A., Curetti G. Ciolli M., Vettorato D. (2015): ''A new open source DSS for assessment and planning of renewable energy: r.green''. [http://europe.foss4g.org/2015/ FOSS4G Europe 2015], 14-17 Jul 2015, Como, Italy.&lt;br /&gt;
&lt;br /&gt;
* Mezzini, E., Antisari, L. V., Ventura, F., Magnan, F. (2015): ''[https://drive.google.com/open?id=0B46kztqdEkOHUnlyZWZzUllPM2s RUSLE model application with GRASS GIS: Rio Centonara catchment]''. [http://europe.foss4g.org/2015/ FOSS4G Europe 2015], 14-17 Jul 2015, Como, Italy.&lt;br /&gt;
&lt;br /&gt;
* Mitasova, H., Jeziorska, J., Petrasova, A., Petras V., Zajkowski, T. (2015): ''[http://ncsu-osgeorel.github.io/uav-talk Flow analysis using sUAS and lidar data]''. [http://europe.foss4g.org/2015/ FOSS4G Europe 2015], 14-17 Jul 2015, Como, Italy.&lt;br /&gt;
&lt;br /&gt;
* Pareeth, S., Delucchi, L., Metz, M., Salmaso, N., Neteler, M. (2015): An open source framework for processing daily satellite images (AVHRR) over last 28 years. [http://europe.foss4g.org/2015/ FOSS4G Europe 2015], 14-17 Jul 2015, Como, Italy. ([http://geomatica.como.polimi.it/workbooks/n12/FOSS4G-eu15_submission_137.pdf Abstract])&lt;br /&gt;
&lt;br /&gt;
* Petras V., Petrasova, A., Cepero-Perez, K., Neteler, M., Delucchi, L., Landa, M., Mitasova, H. (2015): ''[https://drive.google.com/open?id=0B46kztqdEkOHX3g4QUlyME4tYXc Using Free and Open Source Solutions in Geospatial Science Education]''. [http://europe.foss4g.org/2015/ FOSS4G Europe 2015], 14-17 Jul 2015, Como, Italy. ([http://wenzeslaus.github.io/foss-in-geospatial-science-education/ alternative location], [https://github.com/wenzeslaus/foss-in-geospatial-science-education source code for slides])&lt;br /&gt;
&lt;br /&gt;
* Petrasova, A., Petras V., Shoemaker, D. A., Dorning, M. A., Meentemeyer, R. K. (2015): ''[https://drive.google.com/open?id=0B46kztqdEkOHSXhBRG8wOXllZVE The integration of land change modeling framework FUTURES in GRASS GIS 7]''. [http://europe.foss4g.org/2015/ FOSS4G Europe 2015], 14-17 Jul 2015, Como, Italy.&lt;br /&gt;
&lt;br /&gt;
== Code sprint ==&lt;br /&gt;
&lt;br /&gt;
* 18 July: FOSS4G EU 2015 Code Sprint&lt;br /&gt;
* 19-22 July: GRASS Community Sprint&lt;br /&gt;
&lt;br /&gt;
See details at [[GRASS Community Sprint Como 2015]] and [[Talk:GRASS Community Sprint Como 2015]].&lt;br /&gt;
&lt;br /&gt;
[[Category: Workshops]]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=User:Pietro&amp;diff=20837</id>
		<title>User:Pietro</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=User:Pietro&amp;diff=20837"/>
		<updated>2014-09-27T15:45:39Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: add extra ideas on grass and sphinx docs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pietro Zambelli is ph.D. student of University of Trento, in April 2012 proposed a GSoC on [[GRASS_SoC_Ideas_2012/High_level_map_interaction | High level map interaction ]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TO DO ==&lt;br /&gt;
&lt;br /&gt;
* Write email about GRASS8 and HDF5&lt;br /&gt;
* Try to move GRASS from SVN to GIT using [http://subgit.com/ SubGit]&lt;br /&gt;
* Rewrite pygrass.vector, split primary from topological features&lt;br /&gt;
* start porting GRASS to python3&lt;br /&gt;
* waiting ipython 4.0 to implement ipython interfaces and facilities for GRASS, see the ipython [https://github.com/ipython/ipython/wiki/Roadmap:-IPython roadmap].&lt;br /&gt;
* Remove RasterNumpy class&lt;br /&gt;
* Go on to implement the raster interface with [http://cython.org/ Cython] and do a benchmark&lt;br /&gt;
* try to substitute the make system with [https://jpakkane.github.io/meson/ Meson]&lt;br /&gt;
* i.segment add auto find threshold if given some draw segments&lt;br /&gt;
* add the sphinx numpydoc extension to remove/hide docstring characters and output from the doc, to make easier to copy and paste.&lt;br /&gt;
  could be great have also a live terminal such as in sympy with a http://live.sympy.org/.&lt;br /&gt;
* split the sphinx doc in sub-documents.&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=User:Pietro&amp;diff=20821</id>
		<title>User:Pietro</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=User:Pietro&amp;diff=20821"/>
		<updated>2014-09-20T13:36:23Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* TO DO */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pietro Zambelli is ph.D. student of University of Trento, in April 2012 proposed a GSoC on [[GRASS_SoC_Ideas_2012/High_level_map_interaction | High level map interaction ]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TO DO ==&lt;br /&gt;
&lt;br /&gt;
* Write email about GRASS8 and HDF5&lt;br /&gt;
* Try to move GRASS from SVN to GIT using [http://subgit.com/ SubGit]&lt;br /&gt;
* Rewrite pygrass.vector, split primary from topological features&lt;br /&gt;
* start porting GRASS to python3&lt;br /&gt;
* waiting ipython 4.0 to implement ipython interfaces and facilities for GRASS, see the ipython [https://github.com/ipython/ipython/wiki/Roadmap:-IPython roadmap].&lt;br /&gt;
* Remove RasterNumpy class&lt;br /&gt;
* Go on to implement the raster interface with [http://cython.org/ Cython] and do a benchmark&lt;br /&gt;
* try to substitute the make system with [https://jpakkane.github.io/meson/ Meson]&lt;br /&gt;
* i.segment add auto find threshold if given some draw segments&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=User:Pietro&amp;diff=20819</id>
		<title>User:Pietro</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=User:Pietro&amp;diff=20819"/>
		<updated>2014-09-18T14:06:52Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: to not forget ideas&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pietro Zambelli is ph.D. student of University of Trento, in April 2012 proposed a GSoC on [[GRASS_SoC_Ideas_2012/High_level_map_interaction | High level map interaction ]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TO DO ==&lt;br /&gt;
&lt;br /&gt;
* Write email about GRASS8 and HDF5&lt;br /&gt;
* Try to move GRASS from SVN to GIT using [http://subgit.com/ SubGit]&lt;br /&gt;
* Rewrite pygrass.vector, split primary from topological features&lt;br /&gt;
* start porting GRASS to python3&lt;br /&gt;
* waiting ipython 4.0 to implement ipython interfaces and facilities for GRASS, see the ipython [https://github.com/ipython/ipython/wiki/Roadmap:-IPython roadmap].&lt;br /&gt;
* Remove RasterNumpy class&lt;br /&gt;
* Go on to implement the raster interface with [http://cython.org/ Cython] and do a benchmark&lt;br /&gt;
* try to substitute the make system with [https://jpakkane.github.io/meson/ Meson]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R_statistics&amp;diff=20589</id>
		<title>R statistics</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R_statistics&amp;diff=20589"/>
		<updated>2014-07-07T13:27:15Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* GRASS 6: calling GRASS from R: add a less trivial example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Q:''' How do I enjoy high quality statistic analysis in GRASS?&lt;br /&gt;
&lt;br /&gt;
'''A:''' Well, GRASS has got an interface to the most powerful statistics analysis package around: '''''R''''' (http://www.r-project.org)&lt;br /&gt;
: The [http://cran.r-project.org/web/packages/spgrass6/ '''spgrass6'''] ''R'' addon package provides the R &amp;amp;larr;&amp;amp;rarr; GRASS interface.&lt;br /&gt;
&lt;br /&gt;
Using R in GRASS GIS directly has two meanings:&lt;br /&gt;
&lt;br /&gt;
* The '''first''' is that R is run &amp;quot;on top of&amp;quot; GRASS, transferring GRASS data to R to run statistical functions on the imported data as R objects in memory, and possibly transfer the results back to GRASS.&lt;br /&gt;
* The '''second''' is to leave the data mostly in GRASS, and to use R as a scripting language &amp;quot;on top of&amp;quot; GRASS with execGRASS() - in this case, little data is moved to R, so memory constraints are not important, but R functionality is available.&lt;br /&gt;
&lt;br /&gt;
=== Quick start ===&lt;br /&gt;
&lt;br /&gt;
For the impatient just start it:&lt;br /&gt;
&lt;br /&gt;
  &amp;gt; R&lt;br /&gt;
  &lt;br /&gt;
  #and install packages directly from the net&lt;br /&gt;
  pkgs &amp;lt;- c('akima', 'spgrass6', 'RODBC', 'VR', 'gstat')&lt;br /&gt;
  &lt;br /&gt;
  install.packages(pkgs, dependencies=TRUE, type='source') &lt;br /&gt;
&lt;br /&gt;
or to get all packages for spatial analysis in one:&lt;br /&gt;
&lt;br /&gt;
  &amp;gt; R&lt;br /&gt;
&lt;br /&gt;
  #To automatically install the spatial task view, the ctv package needs to be installed, e.g., via&lt;br /&gt;
  install.packages(&amp;quot;ctv&amp;quot;)&lt;br /&gt;
  library(&amp;quot;ctv&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  install.views(&amp;quot;Spatial&amp;quot;)&lt;br /&gt;
  #or&lt;br /&gt;
  update.views(&amp;quot;Spatial&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you have '''''R''''' and '''''spgrass6''''' on your system, have a look at this tutorial:&lt;br /&gt;
: http://grassold.osgeo.org/statsgrass/grass_geostats.html (from 2001)&lt;br /&gt;
&lt;br /&gt;
=== Installation ===&lt;br /&gt;
&lt;br /&gt;
First of all you need to install '''''R''''' onto your system.&lt;br /&gt;
&lt;br /&gt;
R and many of its addon packages are pre-built and distributed through the CRAN network of mirrors. In addition many Linux distributions prepackage R and a number of the most popular addon toolboxes.&lt;br /&gt;
&lt;br /&gt;
All the necessary functions for the GRASS 6 interface are now in packages on CRAN, so that on Linux/Unix (or Mac OSX) installing '''rgdal''' from source with PROJ4 and GDAL installed, or Windows installing from binary, the required packages are: '''sp'''; '''maptools''' (now includes spmaptools); '''rgdal''' (now includes spGDAL, spproj); '''spgrass6''' - now all on CRAN.&lt;br /&gt;
&lt;br /&gt;
==== Source packages ====&lt;br /&gt;
&lt;br /&gt;
From the R console first pick a local mirror:&lt;br /&gt;
 chooseCRANmirror()&lt;br /&gt;
&lt;br /&gt;
you can then see what it picked with&lt;br /&gt;
 options(&amp;quot;repos&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
To permanently save the mirror site add it to &amp;lt;tt&amp;gt;~/.Rprofile&amp;lt;/tt&amp;gt;. For example:&lt;br /&gt;
 options(repos=c(CRAN=&amp;quot;&amp;lt;nowiki&amp;gt;http://cran.stat.auckland.ac.nz&amp;lt;/nowiki&amp;gt;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
and then run &amp;lt;tt&amp;gt;install.packages()&amp;lt;/tt&amp;gt; as in the Quick Start section above.&lt;br /&gt;
&lt;br /&gt;
For more information see http://cran.r-project.org/doc/manuals/R-admin.html&lt;br /&gt;
&lt;br /&gt;
==== Linux ====&lt;br /&gt;
&lt;br /&gt;
===== Debian and Ubuntu =====&lt;br /&gt;
&lt;br /&gt;
''R'' and a number of pre-build cran packages are already present in the main repositories. Start with:&lt;br /&gt;
&lt;br /&gt;
 # apt-get install r-base r-cran-vr r-cran-rodbc r-cran-xml&lt;br /&gt;
&lt;br /&gt;
Once those are installed start &amp;quot;&amp;lt;tt&amp;gt;R&amp;lt;/tt&amp;gt;&amp;quot; at the command prompt and install the libraries not packaged by the OS:&lt;br /&gt;
: ''n.b. &amp;lt;tt&amp;gt;r-cran-sp&amp;lt;/tt&amp;gt; is now shipped as an official Debian/Ubuntu package and can be installed with &amp;lt;tt&amp;gt;apt&amp;lt;/tt&amp;gt; as above''&lt;br /&gt;
&lt;br /&gt;
 install.packages(&amp;quot;sp&amp;quot;)&lt;br /&gt;
 install.packages(&amp;quot;gstat&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Debian/Lenny ships with ''R'' 2.7.1 which is too old for the modern ''rgdal'' package. So we have to fetch an old one from the archive and build it from the Linux command line:&lt;br /&gt;
 $ wget http://cran.r-project.org/src/contrib/Archive/rgdal/rgdal_0.6-24.tar.gz&lt;br /&gt;
 $ R CMD INSTALL -l /usr/local/lib/R/site-library rgdal_0.6-24.tar.gz&lt;br /&gt;
&lt;br /&gt;
If you are using a newer version of R than that you can install the ''rgdal'' CRAN package directly:&lt;br /&gt;
  install.packages(&amp;quot;rgdal&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
And finally, back inside the ''R'' session:&lt;br /&gt;
 install.packages(&amp;quot;spgrass6&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* [http://cran.r-project.org/bin/linux/debian/README Debian] and [http://cran.r-project.org/bin/linux/ubuntu/README Ubuntu] specific help is also available from the R-project website.&lt;br /&gt;
&lt;br /&gt;
You can also use the CRAN Debian package repository: (pick one; adjust distribution as needed [here &amp;quot;Debian/testing&amp;quot;])&lt;br /&gt;
 deb http://debian.cran.r-project.org/cran2deb/debian-i386 testing/&lt;br /&gt;
 deb http://debian.cran.r-project.org/cran2deb/debian-amd64 testing/&lt;br /&gt;
&lt;br /&gt;
===== RPM based =====&lt;br /&gt;
&lt;br /&gt;
* '''RedHat, Fedora, openSuse, Mandriva''' and similar distros: take the latest '''''R''''' RPM and install it&lt;br /&gt;
&lt;br /&gt;
''R'' and a number of pre-build cran packages are already present in the main repositories. Start with:&lt;br /&gt;
&lt;br /&gt;
 # su&lt;br /&gt;
 # yum install R-core R-core-devel R-XML&lt;br /&gt;
 # exit&lt;br /&gt;
&lt;br /&gt;
Once those are installed, start as normal user &amp;quot;&amp;lt;tt&amp;gt;R&amp;lt;/tt&amp;gt;&amp;quot; at the command prompt and install the libraries not packaged by the distro provider:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
R&lt;br /&gt;
install.packages(&amp;quot;spgrass6&amp;quot;, dependencies = TRUE)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Usage:''' You have the best user experience if you launch R within a running GRASS GIS session (then R automatically recognises the current settings of the [[Computational region]] and &amp;quot;sees&amp;quot; the GRASS maps).&lt;br /&gt;
&lt;br /&gt;
==== Mac OSX ====&lt;br /&gt;
&lt;br /&gt;
Start a R session, then&lt;br /&gt;
&lt;br /&gt;
* for install.packages() you might have to rely on building packages from source code. try:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
R&lt;br /&gt;
install.packages(&amp;quot;spgrass6&amp;quot;, type=&amp;quot;source&amp;quot;, dependencies = TRUE)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Startup of GRASS from within R:'''&lt;br /&gt;
&lt;br /&gt;
First you need to find the path to the GRASS binaries: Control-click on the GRASS.app and you'll get a popup menu; select &amp;quot;Show Package Contents&amp;quot; - this opens you to the directory structure. Go to Contents-&amp;gt;MacOS which would be &amp;quot;GISBASE&amp;quot;; So, in my case, the &amp;quot;gisBase&amp;quot; parameter is &amp;quot;/HD/Applications/Grass-6.4/Contents/MacOS&amp;quot;. If you Command-click at the top of the window on the folder icon beside &amp;quot;MacOS&amp;quot; (from the line above this one), you can see the full path.&lt;br /&gt;
&lt;br /&gt;
Now we can run GRASS from within a R session:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
initGRASS(gisBase ='/Applications/GRASS/GRASS-6.4.app/Contents/MacOS', &lt;br /&gt;
          location = 'geostat2012_ll', mapset = 'user1', &lt;br /&gt;
          gisDbase = '/Users/Lars/Documents/Biologi/grassdata', override = TRUE)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Troubleshooting =====&lt;br /&gt;
If you get an error message when trying to call GRASS from R containing this line: dyld: Library not loaded: /usr/local/lib/libintl.8.dylib you need to establish a link from /Applications/Grass/GRASS-7.0.app/Contents/MacOS/lib/libintl.8.dylib to /usr/local/lib. This can be done through Terminal with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo ln -s /Applications/Grass/GRASS-7.0.app/Contents/MacOS/lib/libintl.8.dylib /usr/local/lib/&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The path to the GRASS-x.x.app must reflect your own configuration.&lt;br /&gt;
&lt;br /&gt;
==== MS Windows ====&lt;br /&gt;
&lt;br /&gt;
===== Installation =====&lt;br /&gt;
Run:&lt;br /&gt;
 install.packages(&amp;quot;spgrass6&amp;quot;, dependencies = TRUE)&lt;br /&gt;
&lt;br /&gt;
or install Task View 'Spatial' - Analysis of Spatial Data&lt;br /&gt;
 install.packages(&amp;quot;ctv&amp;quot;)&lt;br /&gt;
 library(&amp;quot;ctv&amp;quot;)&lt;br /&gt;
 install.views(&amp;quot;Spatial&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
===== GRASS 6: Calling R from GRASS =====&lt;br /&gt;
On Windows, the easiest way is calling  R in a running GRASS 6 session by specifying the full path to the R startup executable. Note that all &amp;quot;\&amp;quot; must be changed to &amp;quot;/&amp;quot;, furthermore quote white spaces in the path:&lt;br /&gt;
&lt;br /&gt;
   GRASS 6.4&amp;gt; C:/Users/&amp;quot;Catherine user&amp;quot;/Documents/R/R-2.15.1/bin/i386/R.exe&lt;br /&gt;
   R version 2.15.1 (2012-06-22) -- &amp;quot;Roasted Marshmallows&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   library(spgrass6)&lt;br /&gt;
&lt;br /&gt;
In some cases, you can use this path:&lt;br /&gt;
- For 32 bits:  &amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;C:/&amp;quot;Program Files&amp;quot;/R/R-2.15.1/bin/i386/R.exe --save&amp;lt;/source&amp;gt;&lt;br /&gt;
- For 64 bits: &amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;C:/&amp;quot;Program Files&amp;quot;/R/R-2.15.1/bin/x64/R.exe --save&amp;lt;/source&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
The best solution is then to add this path to the %PATH% entry in the grass64.bat-starting script.&lt;br /&gt;
&lt;br /&gt;
===== GRASS 6: calling GRASS from R =====&lt;br /&gt;
On Windows, the second easiest way is calling GRASS from R with ''initGRASS()'' from the R package spgrass6(). After GRASS has been initialized for R, you have access to GRASS commands from within R (you may need to adjust the path):&lt;br /&gt;
&lt;br /&gt;
   spgrass6()&lt;br /&gt;
   loc &amp;lt;- initGRASS(&amp;quot;C:\\Program Files\\GRASS 6.4&amp;quot;, home=tempdir())&lt;br /&gt;
&lt;br /&gt;
or using an already existing mapset:&lt;br /&gt;
&lt;br /&gt;
   spgrass6()&lt;br /&gt;
   loc &amp;lt;- initGRASS(gisBase=&amp;quot;C:\\Program Files\\GRASS 6.4&amp;quot;,&lt;br /&gt;
                    gisDbase = &amp;quot;'C:\\Users\\netler\\Documents\\grassdata'&amp;quot;,&lt;br /&gt;
                    location = &amp;quot;spearfish60&amp;quot;, mapset = &amp;quot;user1&amp;quot;, SG=&amp;quot;elevation.dem&amp;quot;,&lt;br /&gt;
                    override = TRUE)&lt;br /&gt;
&lt;br /&gt;
For an example, see http://geomorphometry.org/content/geomorphometry-r-saga-ilwis-grass&lt;br /&gt;
&lt;br /&gt;
===== GRASS 6 Usage III (taken from the grass-stats-ML) =====&lt;br /&gt;
&lt;br /&gt;
http://lists.osgeo.org/pipermail/grass-stats/2010-September/001274.html&lt;br /&gt;
&lt;br /&gt;
at the moment there is following for a Grass-R-connection implemented in WinGRASS 64&lt;br /&gt;
&lt;br /&gt;
(1) the WinGrass64-installer searches during installation for a installed R and writes - &lt;br /&gt;
if found - the R-installation-path to %PATH% in the grass64.bat-starting script&lt;br /&gt;
(see http://trac.osgeo.org/grass/browser/grass/branches/develbranch_6/mswindows/GRASS-Installer.nsi#L660)&lt;br /&gt;
&lt;br /&gt;
--&amp;gt; this means that you FIRST have to install R and then winGRASS!&lt;br /&gt;
&lt;br /&gt;
(2) you can start &amp;quot;GRASS-command-line&amp;quot; - it's a windows-command-line, not a msys-rxvt-terminal &lt;br /&gt;
(you can find this starting option under Programs -&amp;gt; GRASS64 -&amp;gt; Grass command line; but not as a desktop icon)&lt;br /&gt;
&lt;br /&gt;
with this starting option you start a Grass-session in the good old text mode. &lt;br /&gt;
if you type R in the command line, then you start R inside a GRASS-session like in Linux.&lt;br /&gt;
&lt;br /&gt;
===== GRASS 7 Usage =====&lt;br /&gt;
&lt;br /&gt;
In WinGRASS 7 ([http://grass.osgeo.org/download/software.php#g70x standalone installer]) the [http://code.google.com/p/batchfiles/ Windows batchfiles for use with R] are now integrated for a smooth WinGRASS-R-integration. The R-installation-path is dynamically loaded into PATH.&lt;br /&gt;
&lt;br /&gt;
Following R starting options are availabe:&lt;br /&gt;
&lt;br /&gt;
* R cd - cd to R_ROOT, typically to C:\Program Files\R (0)&lt;br /&gt;
* R cmd - Run Rcmd.exe&lt;br /&gt;
* R dir - List contents of R_ROOT in chronological order showing R versions (0)&lt;br /&gt;
* R gui - Run Rgui.exe&lt;br /&gt;
* R help - Help info (0)&lt;br /&gt;
* R path - Add R_TOOLS, R_MIKTEX &amp;amp; R_PATH to path for this cmd line session (0)&lt;br /&gt;
* R Run R.exe (0)&lt;br /&gt;
* R script - Run Rscript.exe&lt;br /&gt;
* R show - Show R_ variable values used. R_PATH, etc. (0)&lt;br /&gt;
* R SetReg - Run RSetReg; see 2.17 in R FAQ for Windows (A)&lt;br /&gt;
* R tools - Add R_TOOLS and R_MIKTEX to path for this cmd line session (0)&lt;br /&gt;
* R touch - Change date on R_HOME to now (0) (A)&lt;br /&gt;
&lt;br /&gt;
Start WinGRASS 7, bring the WinGRASS-windows console in front and type ''R'' for opening a R-session (command line mode) inside a GRASS-session.&lt;br /&gt;
&lt;br /&gt;
[[Image:wingrass7_R_integration.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
Start WinGRASS 7, bring the WinGRASS-windows console in front and type ''R gui'' for opening a R-session (GUI mode) inside a GRASS-session.&lt;br /&gt;
&lt;br /&gt;
[[Image:wingrass7_RGui_integration.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
===== Open tickets =====&lt;br /&gt;
&lt;br /&gt;
* Ticket {{trac|1103}} (new enhancement) WinGrass64 - windows-commandline not released: a Grass-session with wxGui, command-line and R inside a Grass-session would be possible (as already does in WinGrass7)&lt;br /&gt;
* Ticket {{trac|1149}} (new enhancement) WinGrass - load R-installation-path dynamically into PATH:  Wingrass would recognize also an upgraded R-installation (which does not at the moment)&lt;br /&gt;
&lt;br /&gt;
=== Command help ===&lt;br /&gt;
&lt;br /&gt;
Start the ''R'' help browser:&lt;br /&gt;
 help.start()&lt;br /&gt;
&lt;br /&gt;
* Select '''Packages''' and then '''spgrass6'''.&lt;br /&gt;
&lt;br /&gt;
=== Running ===&lt;br /&gt;
: ''by Roger Bivand''&lt;br /&gt;
&lt;br /&gt;
The ''R'' interface for GRASS 5.4 was provided by a CRAN package called ''grass''. Changes going forward to the current GRASS 6 release meant that the interface had to be rewritten, and this provided the opportunity to adapt it to the ''sp'' CRAN package classes. Because GRASS provides the same kinds of data as ''sp'' classes handle, and relies on much of the same open source infrastructure (PROJ.4, GDAL, OGR), this step seemed sensible. Wherever possible ''spgrass6'' tries to respect the [[current region]] in GRASS to avoid handling raster data with different resolutions or extents. ''R'' is assumed to be running within GRASS:&lt;br /&gt;
&lt;br /&gt;
==== Startup ====&lt;br /&gt;
* Start GRASS. At the GRASS command line start ''R''.&lt;br /&gt;
: ''In this example we will use the sample Spearfish dataset.''&lt;br /&gt;
&lt;br /&gt;
Reset the region settings to the defaults&lt;br /&gt;
 GRASS&amp;gt; g.region -d&lt;br /&gt;
&lt;br /&gt;
Launch R from the GRASS prompt&lt;br /&gt;
 GRASS&amp;gt; R&lt;br /&gt;
&lt;br /&gt;
Load the ''spgrass6'' library:&lt;br /&gt;
 &amp;gt; library(spgrass6)&lt;br /&gt;
&lt;br /&gt;
Get the GRASS environment (mapset, region, map projection, etc.); you can display the metadata for your location by printing G:&lt;br /&gt;
 &amp;gt; G &amp;lt;- gmeta6()&lt;br /&gt;
&lt;br /&gt;
==== Listing of existing maps ====&lt;br /&gt;
&lt;br /&gt;
List available vector maps:&lt;br /&gt;
 execGRASS(&amp;quot;g.mlist&amp;quot;, parameters = list(type = &amp;quot;vect&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
List selected vector maps (wildcard):&lt;br /&gt;
 execGRASS(&amp;quot;g.mlist&amp;quot;, parameters = list(type = &amp;quot;vect&amp;quot;, pattern = &amp;quot;precip*&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
Save selected vector maps into R vector:&lt;br /&gt;
 my_vmaps &amp;lt;- execGRASS(&amp;quot;g.mlist&amp;quot;, parameters = list(type = &amp;quot;vect&amp;quot;, pattern = &amp;quot;precip*&amp;quot;))&lt;br /&gt;
 attributes(my_vmaps)&lt;br /&gt;
 attributes(my_vmaps)$resOut&lt;br /&gt;
&lt;br /&gt;
List available raster maps:&lt;br /&gt;
 execGRASS(&amp;quot;g.mlist&amp;quot;, parameters = list(type = &amp;quot;rast&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
List selected raster maps (wildcard):&lt;br /&gt;
 execGRASS(&amp;quot;g.mlist&amp;quot;, parameters = list(type = &amp;quot;rast&amp;quot;, pattern = &amp;quot;lsat7_2000*&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
==== Reading in data ====&lt;br /&gt;
Read in two raster maps:&lt;br /&gt;
 &amp;gt; spear &amp;lt;- readRAST6(c(&amp;quot;geology&amp;quot;, &amp;quot;elevation.dem&amp;quot;),&lt;br /&gt;
 +          cat=c(TRUE, FALSE), ignore.stderr=TRUE,&lt;br /&gt;
 +          plugin=NULL)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metadata are accessed and available, but are not (yet) used to structure the ''sp'' class objects, here a SpatialGridDataFrame object filled with data from two Spearfish layers. Here is a plot of the elevation data:&lt;br /&gt;
 &amp;gt; image(spear, attr = 2, col = terrain.colors(20))&lt;br /&gt;
&lt;br /&gt;
Add a title to the plot:&lt;br /&gt;
 &amp;gt; title(&amp;quot;Spearfish elevation&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
[[Image:R_stats_elev.png|center]]&lt;br /&gt;
&lt;br /&gt;
In addition, we can show what is going on inside the objects read into R:&lt;br /&gt;
 &amp;gt; '''str(G)'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
List of 26&lt;br /&gt;
 $ GISDBASE     : chr &amp;quot;/home/rsb/topics/grassdata&amp;quot;&lt;br /&gt;
 $ LOCATION_NAME: chr &amp;quot;spearfish57&amp;quot;&lt;br /&gt;
 $ MAPSET       : chr &amp;quot;rsb&amp;quot;&lt;br /&gt;
 $ DEBUG        : chr &amp;quot;0&amp;quot;&lt;br /&gt;
 $ GRASS_GUI    : chr &amp;quot;text&amp;quot;&lt;br /&gt;
 $ projection   : chr &amp;quot;1 (UTM)&amp;quot;&lt;br /&gt;
 $ zone         : chr &amp;quot;13&amp;quot;&lt;br /&gt;
 $ datum        : chr &amp;quot;nad27&amp;quot;&lt;br /&gt;
 $ ellipsoid    : chr &amp;quot;clark66&amp;quot;&lt;br /&gt;
 $ north        : num 4928010&lt;br /&gt;
 $ south        : num 4913700&lt;br /&gt;
 $ west         : num 589980&lt;br /&gt;
 $ east         : num 609000&lt;br /&gt;
 $ top          : num 1&lt;br /&gt;
 $ bottom       : num 0&lt;br /&gt;
 $ nsres        : num 30&lt;br /&gt;
 $ nsres3       : num 30&lt;br /&gt;
 $ ewres        : num 30&lt;br /&gt;
 $ ewres3       : num 30&lt;br /&gt;
 $ tbres        : num 1&lt;br /&gt;
 $ rows         : int 477&lt;br /&gt;
 $ rows3        : int 477&lt;br /&gt;
 $ cols         : int 634&lt;br /&gt;
 $ cols3        : int 634&lt;br /&gt;
 $ depths       : int 1&lt;br /&gt;
 $ proj4        : chr &amp;quot;+proj=utm +zone=13 +a=6378206.4 +rf=294.9786982 +no_defs +nadgrids=/home/rsb/topics/grass61/grass-6.1.cvs/etc/nad/conus&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;gt; '''summary(spear)'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Object of class SpatialGridDataFrame&lt;br /&gt;
Coordinates:&lt;br /&gt;
              min     max&lt;br /&gt;
coords.x1  589980  609000&lt;br /&gt;
coords.x2 4913700 4928010&lt;br /&gt;
Is projected: TRUE &lt;br /&gt;
proj4string : [+proj=utm +zone=13 +a=6378206.4 +rf=294.9786982 +no_defs +nadgrids=/home/rsb/topics/grass61/grass-6.1.cvs/etc/nad/conus]&lt;br /&gt;
Number of points: 2&lt;br /&gt;
Grid attributes:&lt;br /&gt;
  cellcentre.offset cellsize cells.dim&lt;br /&gt;
1            589995       30       634&lt;br /&gt;
2           4913715       30       477&lt;br /&gt;
Data attributes:&lt;br /&gt;
      geology      elevation.dem  &lt;br /&gt;
 sandstone:74959   Min.   : 1066  &lt;br /&gt;
 limestone:61355   1st Qu.: 1200  &lt;br /&gt;
 shale    :46423   Median : 1316  &lt;br /&gt;
 sand     :36561   Mean   : 1354  &lt;br /&gt;
 igneous  :36534   3rd Qu.: 1488  &lt;br /&gt;
 (Other)  :37636   Max.   : 1840  &lt;br /&gt;
 NA's     : 8950   NA's   :10101  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Summarizing data ====&lt;br /&gt;
We can create a table of cell counts:&lt;br /&gt;
 &amp;gt; '''table(spear$geology)'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!metamorphic&lt;br /&gt;
!transition&lt;br /&gt;
!igneous&lt;br /&gt;
!sandstone&lt;br /&gt;
!limestone&lt;br /&gt;
!shale&lt;br /&gt;
!sandy shale&lt;br /&gt;
!claysand&lt;br /&gt;
!sand&lt;br /&gt;
|-&lt;br /&gt;
|11693&lt;br /&gt;
|142&lt;br /&gt;
|36534&lt;br /&gt;
|74959&lt;br /&gt;
|61355&lt;br /&gt;
|46423&lt;br /&gt;
|11266&lt;br /&gt;
|14535&lt;br /&gt;
|36561&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And compare with the equivalent GRASS module:&lt;br /&gt;
 &amp;gt; '''execGRASS(&amp;quot;r.stats&amp;quot;, flags=c(&amp;quot;c&amp;quot;, &amp;quot;l&amp;quot;), parameters=list(input=&amp;quot;geology&amp;quot;), ignore.stderr=TRUE)'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1 metamorphic 11693&lt;br /&gt;
2 transition 142&lt;br /&gt;
3 igneous 36534&lt;br /&gt;
4 sandstone 74959&lt;br /&gt;
5 limestone 61355&lt;br /&gt;
6 shale 46423&lt;br /&gt;
7 sandy shale 11266&lt;br /&gt;
8 claysand 14535&lt;br /&gt;
9 sand 36561&lt;br /&gt;
* no data 8950&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a box plot of geologic types at different elevations:&lt;br /&gt;
 &amp;gt; '''boxplot(spear$elevation.dem ~ spear$geology, medlwd = 1)'''&lt;br /&gt;
&lt;br /&gt;
[[Image:R_stats_boxplot_geo.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Exporting data back to GRASS ====&lt;br /&gt;
Finally, a SpatialGridDataFrame object is written back to a GRASS raster map:&lt;br /&gt;
&lt;br /&gt;
First prepare some data:  (square root of elevation)&lt;br /&gt;
 &amp;gt; spear$sqdem &amp;lt;- sqrt(spear$elevation.dem)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Export data from ''R'' back into a GRASS raster map:&lt;br /&gt;
 &amp;gt; writeRAST6(spear, &amp;quot;sqdemSP&amp;quot;, zcol=&amp;quot;sqdem&amp;quot;, ignore.stderr=TRUE)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Check that it imported into GRASS ok:&lt;br /&gt;
 &amp;gt; '''execGRASS(&amp;quot;r.info&amp;quot;, parameters=list(map=&amp;quot;sqdemSP&amp;quot;))'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 +----------------------------------------------------------------------------+&lt;br /&gt;
 | Layer:    sqdemSP                        Date: Sun May 14 21:59:26 2006    |&lt;br /&gt;
 | Mapset:   rsb                            Login of Creator: rsb             |&lt;br /&gt;
 | Location: spearfish57                                                      |&lt;br /&gt;
 | DataBase: /home/rsb/topics/grassdata                                       |&lt;br /&gt;
 | Title:     ( sqdemSP )                                                     |&lt;br /&gt;
 |----------------------------------------------------------------------------|&lt;br /&gt;
 |                                                                            |&lt;br /&gt;
 |   Type of Map:  raster              Number of Categories: 255              |&lt;br /&gt;
 |   Data Type:    FCELL                                                      |&lt;br /&gt;
 |   Rows:         477                                                        |&lt;br /&gt;
 |   Columns:      634                                                        |&lt;br /&gt;
 |   Total Cells:  302418                                                     |&lt;br /&gt;
 |        Projection: UTM (zone 13)                                           |&lt;br /&gt;
 |            N:    4928010    S:    4913700   Res:    30                     |&lt;br /&gt;
 |            E:     609000    W:     589980   Res:    30                     |&lt;br /&gt;
 |   Range of data:    min =  32.649654 max = 42.895222                       |&lt;br /&gt;
 |                                                                            |&lt;br /&gt;
 |   Data Source:                                                             |&lt;br /&gt;
 |                                                                            |&lt;br /&gt;
 |                                                                            |&lt;br /&gt;
 |                                                                            |&lt;br /&gt;
 |   Data Description:                                                        |&lt;br /&gt;
 |    generated by r.in.gdal                                                  |&lt;br /&gt;
 |                                                                            |&lt;br /&gt;
 |                                                                            |&lt;br /&gt;
 +----------------------------------------------------------------------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling GRASS functionality in R batch job ===&lt;br /&gt;
&lt;br /&gt;
To call GRASS functionality within a R batch job, use the initGRASS() function to define the GRASS settings:&lt;br /&gt;
&lt;br /&gt;
    library(spgrass6)&lt;br /&gt;
    &lt;br /&gt;
    # initialisation and the use of spearfish60 data&lt;br /&gt;
    initGRASS(gisBase = &amp;quot;/usr/local/grass-6.4.1&amp;quot;, home = tempdir(), &lt;br /&gt;
              gisDbase = &amp;quot;/home/neteler/grassdata/&amp;quot;,&lt;br /&gt;
              location = &amp;quot;spearfish60&amp;quot;, mapset = &amp;quot;user1&amp;quot;, SG=&amp;quot;elevation.dem&amp;quot;,&lt;br /&gt;
              override = TRUE)&lt;br /&gt;
    &lt;br /&gt;
    system(&amp;quot;g.region -d&amp;quot;)&lt;br /&gt;
    # verify&lt;br /&gt;
    gmeta6()&lt;br /&gt;
    &lt;br /&gt;
    spear &amp;lt;- readRAST6(c(&amp;quot;geology&amp;quot;, &amp;quot;elevation.dem&amp;quot;),&lt;br /&gt;
              cat=c(TRUE, FALSE), ignore.stderr=TRUE,&lt;br /&gt;
              plugin=NULL)&lt;br /&gt;
    &lt;br /&gt;
    summary(spear$geology)&lt;br /&gt;
&lt;br /&gt;
Run this script with&lt;br /&gt;
&lt;br /&gt;
    R CMD BATCH batch.R&lt;br /&gt;
&lt;br /&gt;
The result is (shorted here):&lt;br /&gt;
&lt;br /&gt;
    cat batch.Rout&lt;br /&gt;
    &lt;br /&gt;
    R version 2.10.0 (2009-10-26)&lt;br /&gt;
    Copyright (C) 2009 The R Foundation for Statistical Computing&lt;br /&gt;
    ISBN 3-900051-07-0&lt;br /&gt;
    ...&lt;br /&gt;
    &amp;gt; library(spgrass6)&lt;br /&gt;
    Loading required package: sp&lt;br /&gt;
    Loading required package: rgdal&lt;br /&gt;
    Geospatial Data Abstraction Library extensions to R successfully loaded&lt;br /&gt;
    Loaded GDAL runtime: GDAL 1.7.2, released 2010/04/23&lt;br /&gt;
    Path to GDAL shared files: /usr/local/share/gdal&lt;br /&gt;
    Loaded PROJ.4 runtime: Rel. 4.7.1, 23 September 2009&lt;br /&gt;
    Path to PROJ.4 shared files: (autodetected)&lt;br /&gt;
    Loading required package: XML&lt;br /&gt;
    GRASS GIS interface loaded with GRASS version: (GRASS not running)&lt;br /&gt;
    &amp;gt; &lt;br /&gt;
    &amp;gt; # initialisation and the use of spearfish60 data&lt;br /&gt;
    &amp;gt; initGRASS(gisBase = &amp;quot;/usr/local/grass-6.4.1&amp;quot;, home = tempdir(), gisDbase = &amp;quot;/home/neteler/grassdata/&amp;quot;,&lt;br /&gt;
    +           location = &amp;quot;spearfish60&amp;quot;, mapset = &amp;quot;user1&amp;quot;, SG=&amp;quot;elevation.dem&amp;quot;, override = TRUE)&lt;br /&gt;
    gisdbase    /home/neteler/grassdata/ &lt;br /&gt;
    location    spearfish60 &lt;br /&gt;
    mapset      user1 &lt;br /&gt;
    rows        477 &lt;br /&gt;
    columns     634 &lt;br /&gt;
    north       4928010 &lt;br /&gt;
    south       4913700 &lt;br /&gt;
    west        589980 &lt;br /&gt;
    east        609000 &lt;br /&gt;
    nsres       30 &lt;br /&gt;
    ewres       30 &lt;br /&gt;
    projection  +proj=utm +zone=13 +a=6378206.4 +rf=294.9786982 +no_defs&lt;br /&gt;
    +nadgrids=/usr/local/grass-6.4.1/etc/nad/conus +to_meter=1.0 &lt;br /&gt;
    Warning messages:&lt;br /&gt;
    1: In dir.create(gisDbase) : '/home/neteler/grassdata' already exists&lt;br /&gt;
    2: In dir.create(loc_path) :&lt;br /&gt;
      '/home/neteler/grassdata//spearfish60' already exists&lt;br /&gt;
    &amp;gt; &lt;br /&gt;
    &amp;gt; system(&amp;quot;g.region -d&amp;quot;)&lt;br /&gt;
    &amp;gt; # verify&lt;br /&gt;
    &amp;gt; gmeta6()&lt;br /&gt;
    gisdbase    /home/neteler/grassdata/ &lt;br /&gt;
    location    spearfish60 &lt;br /&gt;
    mapset      user1 &lt;br /&gt;
    rows        477 &lt;br /&gt;
    columns     634 &lt;br /&gt;
    north       4928010 &lt;br /&gt;
    ...&lt;br /&gt;
    &amp;gt; &lt;br /&gt;
    &amp;gt; spear &amp;lt;- readRAST6(c(&amp;quot;geology&amp;quot;, &amp;quot;elevation.dem&amp;quot;),&lt;br /&gt;
    +           cat=c(TRUE, FALSE), ignore.stderr=TRUE,&lt;br /&gt;
    +           plugin=NULL)&lt;br /&gt;
    &amp;gt; &lt;br /&gt;
    &amp;gt; summary(spear$geology)&lt;br /&gt;
    metamorphic  transition     igneous   sandstone   limestone       shale &lt;br /&gt;
          11693         142       36534       74959       61355       46423 &lt;br /&gt;
    sandy shale    claysand        sand        NA's &lt;br /&gt;
          11266       14535       36561        8950 &lt;br /&gt;
    &amp;gt; &lt;br /&gt;
    &amp;gt; &lt;br /&gt;
    &amp;gt; proc.time()&lt;br /&gt;
       user  system elapsed &lt;br /&gt;
      2.891   0.492   3.412 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== GRASS Modules ===&lt;br /&gt;
&lt;br /&gt;
==== v.krige ====&lt;br /&gt;
&lt;br /&gt;
{{cmd|v.krige|version=70}} is a GRASS python script which performs kriging operations in the GRASS environment, using R functions for the back-end interpolation. It is present in GRASS 6.5svn, and further developed in GRASS 7svn. It requires a number of dependencies: '''python-rpy2''' (''needs to be &amp;quot;Rpy2&amp;quot;, &amp;quot;Rpy&amp;quot; will not do'' unless it is rpy 2.x), then the following R-CRAN packages:&lt;br /&gt;
* gstat, spgrass6 (as above)&lt;br /&gt;
 install.packages(c(&amp;quot;gstat&amp;quot;,&amp;quot;spgrass6&amp;quot;))&lt;br /&gt;
* maptools&lt;br /&gt;
 install.packages(&amp;quot;maptools&amp;quot;)&lt;br /&gt;
* automap (optional), with gpclib (or rgeos)&lt;br /&gt;
 install.packages(&amp;quot;automap&amp;quot;)&lt;br /&gt;
 install.packages(&amp;quot;rgeos&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
(''merge further info from man page here'')&lt;br /&gt;
&lt;br /&gt;
=== Getting Support ===&lt;br /&gt;
&lt;br /&gt;
* Primary support for ''R'' + GRASS and the ''spgrass6'' package is through the [http://lists.osgeo.org/mailman/listinfo/grass-stats grass-stats] mailing list.&lt;br /&gt;
&lt;br /&gt;
=== See also ===&lt;br /&gt;
&lt;br /&gt;
* R. Bivand, 2007: [http://spatial.nhh.no/R/etc/FBK07 Interfacing R and OSGeo projects: status and perspectives] (Presentation with slides and scripts)&lt;br /&gt;
&lt;br /&gt;
* http://grass.ibiblio.org/statsgrass/index.php#grassR&lt;br /&gt;
&lt;br /&gt;
* Using GRASS and R: http://grassold.osgeo.org/statsgrass/grass6_r_interface.html&lt;br /&gt;
&lt;br /&gt;
* Connecting R to RDBMS: http://grassold.osgeo.org/statsgrass/r_and_dbms.html&lt;br /&gt;
&lt;br /&gt;
* [http://www.r-project.org R-Statistics homepage]&lt;br /&gt;
&lt;br /&gt;
* [http://r-spatial.sourceforge.net/ R-spatial main web page]&lt;br /&gt;
&lt;br /&gt;
* [http://geodacenter.asu.edu/r-spatial-projects R Spatial Projects at ASU]&lt;br /&gt;
&lt;br /&gt;
* Neural Networks with GRASS and R (posted by Markus Neteler on the grass-user mailing list) http://www.uam.es/proyectosinv/Mclim/pdf/MBenito_EcoMod.pdf&lt;br /&gt;
&lt;br /&gt;
* A detailed example on the use of GRASS and R, with spearfish data: http://casoilresource.lawr.ucdavis.edu/drupal/node/438&lt;br /&gt;
&lt;br /&gt;
* Using R and GRASS with cygwin: It is possible to use Rterm inside the GRASS shell in cygwin, just as in Unix/Linux or OSX. You should not, however, start Rterm from a cygwin xterm, because Rterm is not expecting to be run in an xterm under Windows, and loses its input. If you use the regular cygwin bash shell, but need to start display windows, start X from within GRASS with startx &amp;amp;, and then start Rterm in the same cygwin shell, not in the xterm.&lt;br /&gt;
&lt;br /&gt;
* [http://r-spatial.sourceforge.net/ Spatial data in R] (&amp;lt;code&amp;gt;sp&amp;lt;/code&amp;gt;) is a '''''R''''' library that provides classes and methods for spatial data (points, lines, polygons, grids), and to new or existing spatial statistics '''''R''''' packages that use sp, depend on sp, or will become dependent on &amp;lt;code&amp;gt;sp&amp;lt;/code&amp;gt;, such as &amp;lt;code&amp;gt;maptools&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;rgdal&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;splancs&amp;lt;/code&amp;gt;, '''&amp;lt;code&amp;gt;spgrass6&amp;lt;/code&amp;gt;''', &amp;lt;code&amp;gt;gstat&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;spgwr&amp;lt;/code&amp;gt; and many others.&lt;br /&gt;
&lt;br /&gt;
* [http://rpy.sourceforge.net/ RPy] - Python interface to the R Programming Language&lt;br /&gt;
&lt;br /&gt;
=== Workshop material ===&lt;br /&gt;
&lt;br /&gt;
* M. Neteler and M. Metz, 2011: ''Introduction to GRASS GIS''. GEOSTAT 2011 Landau. [http://geostat-course.org/Topic_NetelerMetz_2011 Download workshop material] '''(includes a R session)'''&lt;br /&gt;
&lt;br /&gt;
=== Articles ===&lt;br /&gt;
&lt;br /&gt;
* [http://grass.osgeo.org/newsletter/grassnews3.html GRASS News vol.3], June 2005 (R. Bivand. Interfacing GRASS 6 and R. ''GRASS Newsletter'', 3:11-16, June 2005. ISSN 1614-8746).&lt;br /&gt;
* [http://www.osgeo.org/journal OSGeo Journal] vol. 1 May 2007 (R. Bivand. Using the R— GRASS interface. ''OSGeo Journal'', 1:31-33, May 2007. ISSN 1614-8746).&lt;br /&gt;
* [http://www.grassbook.org GRASS Book, last chapter]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Linking to other languages]]&lt;br /&gt;
[[Category:R]]&lt;br /&gt;
[[Category:Statistics]]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=20457</id>
		<title>Python/pygrass</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=20457"/>
		<updated>2014-05-15T09:07:31Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: Add trainign materials on Python&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''PyGRASS'' is a library that extends the GRASS GIS 7 capabilities to allow users to access the low-level GRASS API.&lt;br /&gt;
&lt;br /&gt;
== Architecture ==&lt;br /&gt;
&lt;br /&gt;
=== Training material ===&lt;br /&gt;
&lt;br /&gt;
Two workshops were presented during the [http://geomorfolab.arch.unige.it/genova2013/ XIV Italian meeting of GRASS] at Genova.&lt;br /&gt;
The workshops use '''ipython notebook''' to show the python and pygrass API, all the material are available on github ([https://github.com/zarch/workshop-python python], [https://github.com/zarch/workshop-pygrass pygrass]). All the execute examples are reported here:&lt;br /&gt;
&lt;br /&gt;
* python (Genova)&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/00_intro.ipynb      Introduction]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/01_data_types.ipynb Data Types]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/02_syntax.ipynb     Syntax]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/03_function.ipynb   Function]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/04_class.ipynb      Class]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/05_other.ipynb      Other]&lt;br /&gt;
&lt;br /&gt;
* python (EURAC)&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/00_intro.ipynb Introduction]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/01_data_types.ipynb Data Types]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/02_syntax.ipynb Syntax]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/03_version_control_system.ipynb Version Control System (hg)]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/04_objects.ipynb Objects]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/05_python_debugger.ipynb Debugger]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/06_functions.ipynb Functions]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/07_numpy.ipynb Numpy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/08_matplotlib.ipynb Matplotlib]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/09_scipy.ipynb Scipy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/10_pandas.ipynb Pandas]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/11_sympy.ipynb Sympy]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/bitbucket.org/zarch/python-course/raw/teacher/12_user_interfaces.ipynb GUI]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* pygrass&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/00_Modules.ipynb     Modules]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/01_GIS_objects.ipynb GIS]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/02_Vector.ipynb      Vector]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/03_Raster.ipynb      Raster]&lt;br /&gt;
&lt;br /&gt;
== How to test library ==&lt;br /&gt;
&lt;br /&gt;
''pygrass'' has doctest inside its code. You can run doctest inside the [http://grass.osgeo.org/sampledata/north_carolina/nc_basic_spm_grass7.tar.gz North Carolina basic location], using the mapset '''user1'''. &lt;br /&gt;
&lt;br /&gt;
To test the single module (file) you have to move to the source code of pygrass and run the following code (this is an example of functions.py):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python -m doctest functions.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Already tested modules ===&lt;br /&gt;
&lt;br /&gt;
==== Working ====&lt;br /&gt;
&lt;br /&gt;
The files are found in GRASS GIS 7, lib/python/pygrass/&lt;br /&gt;
* functions.py&lt;br /&gt;
* gis/region.py&lt;br /&gt;
* gis/__init__.py&lt;br /&gt;
* modules/__init.py&lt;br /&gt;
* vector/abstract.py&lt;br /&gt;
* vector/__init__.py&lt;br /&gt;
* vector/basic.py&lt;br /&gt;
* vector/table.py&lt;br /&gt;
* vector/geometry.py&lt;br /&gt;
* raster/abstract.py&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
See https://svn.osgeo.org/grass/grass/trunk/lib/python/&lt;br /&gt;
&lt;br /&gt;
==== Not working ====&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* Zambelli, P., Gebbert, S., Ciolli, M., 2013. ''Pygrass: An Object Oriented Python Application Programming Interface (API) for Geographic Resources Analysis Support System (GRASS) Geographic Information System (GIS)''. ISPRS International Journal of Geo-Information 2, 201–219. ([http://dx.doi.org/10.3390/ijgi2010201 DOI] | [http://www.mdpi.com/2220-9964/2/1/201/pdf PDF])&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;[http://www.ing.unitn.it/~zambelli/projects/pygrass/ (old) pyGrass documentation]&amp;lt;/strike&amp;gt;&lt;br /&gt;
* [http://grass.osgeo.org/programming7/pygrass/ pyGrass documentation] (updated weekly from SVN)&lt;br /&gt;
&lt;br /&gt;
== Sample PyGRASS scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Interface to listing maps (g.list/g.mlist) ===&lt;br /&gt;
In this case we are calling a GRASS module that write to the stdout and not a Python function that return a Python object, therefore you can save the stdout and then parse it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
import subprocess as sub&lt;br /&gt;
gl = g.mlist&lt;br /&gt;
gl(type='rast', pattern='elev-*', stdout=sub.PIPE)&lt;br /&gt;
gl.outputs.stdout.split()&lt;br /&gt;
['elev-000-000', 'elev-000-001', 'elev-000-002', 'elev-001-000',&lt;br /&gt;
'elev-001-001', 'elev-001-002', 'elev-002-000', 'elev-002-001',&lt;br /&gt;
'elev-002-002']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use the &amp;quot;glist&amp;quot; method of the Mapset class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.gis import Mapset&lt;br /&gt;
m = Mapset()&lt;br /&gt;
m.glist('rast', pattern='elev-*')&lt;br /&gt;
['elev-002-000',  'elev-000-000',  'elev-000-002',  'elev-000-001',&lt;br /&gt;
'elev-001-001',  'elev-002-002',  'elev-002-001',  'elev-001-000',&lt;br /&gt;
'elev-001-002']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
that uses the &amp;quot;G_list&amp;quot; function through ctypes and therefore is faster.&lt;br /&gt;
&lt;br /&gt;
If you choose the first solution is better if you use directly the&lt;br /&gt;
function in [http://grass.osgeo.org/programming7/namespacepython_1_1script_1_1core.html python.script.core.mlist_grouped() etc.].&lt;br /&gt;
&lt;br /&gt;
=== Sample script for opening, query and closing of a vector map ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
# Example for pyGRASS usage - vector API&lt;br /&gt;
&lt;br /&gt;
from grass.pygrass.modules.shortcuts import general as g&lt;br /&gt;
from grass.pygrass.vector import VectorTopo&lt;br /&gt;
 &lt;br /&gt;
g.message(&amp;quot;Assessing vector topology...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
vectmap = 'zipcodes_wake'&lt;br /&gt;
zipcodes = VectorTopo(vectmap)&lt;br /&gt;
&lt;br /&gt;
# Open the map with topology:&lt;br /&gt;
zipcodes.open()&lt;br /&gt;
&lt;br /&gt;
# query number of topological features&lt;br /&gt;
areas   = zipcodes.number_of(&amp;quot;areas&amp;quot;)&lt;br /&gt;
islands = zipcodes.number_of(&amp;quot;islands&amp;quot;)&lt;br /&gt;
print 'Map: &amp;lt;' + vectmap + '&amp;gt; with %d areas and %d islands' % (areas, islands)&lt;br /&gt;
&lt;br /&gt;
# http://www.ing.unitn.it/~zambelli/projects/pygrass/attributes.html&lt;br /&gt;
# (note that above documentation is slightly outdated)&lt;br /&gt;
dblink = zipcodes.dblinks[0]&lt;br /&gt;
print 'DB name:'&lt;br /&gt;
print dblink.database&lt;br /&gt;
table = dblink.table()&lt;br /&gt;
print 'Column names:'&lt;br /&gt;
print table.columns.names()&lt;br /&gt;
print 'Column types:'&lt;br /&gt;
print table.columns.types()&lt;br /&gt;
&lt;br /&gt;
zipcodes.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample script for Landsat 7 processing ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
#Date: 7th February, 2013&lt;br /&gt;
#Public domain, GRASS GIS&lt;br /&gt;
&lt;br /&gt;
#Run this script in the terminal as:&lt;br /&gt;
#python python-grass.py&lt;br /&gt;
#For debugging, run as:&lt;br /&gt;
#python -i python-grass.py&lt;br /&gt;
#PURPOSE&lt;br /&gt;
#This script processes LANDSAT 7 ETM+ images&lt;br /&gt;
#1 - unzip *.gz files&lt;br /&gt;
#2 - import files in GRASS GIS Location of your choice (r.in.gdal)&lt;br /&gt;
#3 - DN to Top of Atmosphere reflectance (i.landsat.toar)&lt;br /&gt;
#4 - TOA reflectance to Surface reflectance (i.atcorr)&lt;br /&gt;
#5 - NDVI (i.vi), Albedo (i.albedo), Emissivity (i.emissivity)&lt;br /&gt;
&lt;br /&gt;
#USER HAS TO SET THOSE&lt;br /&gt;
#QUIET REPORTS&lt;br /&gt;
QIET=True&lt;br /&gt;
#OVERWRITE EXISTING FILES&lt;br /&gt;
OVR=False&lt;br /&gt;
#Define Landsat 7 sensor for i.landsat.toar&lt;br /&gt;
LSENSOR=&amp;quot;tm7&amp;quot;&lt;br /&gt;
#Setup the path to the Landsat 7 Directories&lt;br /&gt;
rsdatapath=&amp;quot;/home/yann/RSDATA/Myanmar/L7&amp;quot;&lt;br /&gt;
#Setup your GRASS GIS working directory&lt;br /&gt;
gisdb=&amp;quot;/home/yann/GRASSDATA&amp;quot;&lt;br /&gt;
location=&amp;quot;L7_Myanmar&amp;quot;&lt;br /&gt;
print location&lt;br /&gt;
mapset=&amp;quot;PERMANENT&amp;quot;&lt;br /&gt;
#DEM input to atmospheric correction&lt;br /&gt;
inDEM=rsdatapath+&amp;quot;/dem.tif&amp;quot;&lt;br /&gt;
#set L7 Metadata wildcards&lt;br /&gt;
wldc_mtl=&amp;quot;*_MTL.txt&amp;quot;&lt;br /&gt;
#wldc_met=&amp;quot;*.met&amp;quot;&lt;br /&gt;
#Visibility distance [Km]&lt;br /&gt;
vis=18&lt;br /&gt;
&lt;br /&gt;
#Set python path to enable finding of grass.script lib&lt;br /&gt;
&lt;br /&gt;
#END OF USER CHANGES&lt;br /&gt;
###DO NOT CHANGE ANYTHING AFTER THIS LINE !&lt;br /&gt;
###&lt;br /&gt;
#Load necessary libraries&lt;br /&gt;
import os, glob, time, re&lt;br /&gt;
from grass import script as g&lt;br /&gt;
from grass.script import setup as gsetup&lt;br /&gt;
gisbase=os.environ['GISBASE']&lt;br /&gt;
gsetup.init(gisbase,gisdb,location,mapset)&lt;br /&gt;
from grass.pygrass.modules.shortcuts import raster as r&lt;br /&gt;
from grass.pygrass.modules.shortcuts import imagery as i&lt;br /&gt;
from grass.pygrass.modules.shortcuts import display as d&lt;br /&gt;
#Needed for floor()&lt;br /&gt;
from math import *&lt;br /&gt;
#env = os.environ.copy()&lt;br /&gt;
#env['GRASS_MESSAGE_FORMAT'] = 'gui'&lt;br /&gt;
#Function to get a list of L7 Directories in the rsdatapath&lt;br /&gt;
def fn(path):&lt;br /&gt;
	for top, dirs, files in os.walk(path):&lt;br /&gt;
		return [os.path.join(top, dir) for dir in dirs]&lt;br /&gt;
&lt;br /&gt;
#START PROCESS&lt;br /&gt;
### PART 0: PRE-PROCESSING STUFF ###&lt;br /&gt;
#import DEM for atmospheric correction&lt;br /&gt;
#r.in.gdal(input=inDEM,output=&amp;quot;dem&amp;quot;,overwrite=OVR)&lt;br /&gt;
#r.mapcalc(expression=&amp;quot;dem=25&amp;quot;,overwrite=OVR)&lt;br /&gt;
#create a visibility map&lt;br /&gt;
r.mapcalc(expression=&amp;quot;vis=18&amp;quot;,overwrite=OVR)&lt;br /&gt;
#Find the central location of the Landsat file from metadata&lt;br /&gt;
metadata=[]&lt;br /&gt;
fileList=[]&lt;br /&gt;
L7Dirs=fn(rsdatapath)&lt;br /&gt;
for L7Dir in L7Dirs:&lt;br /&gt;
	#Ungzip all of your Landsat7 images in all your directories&lt;br /&gt;
#	print &amp;quot;Ungzip Landsat files in\t&amp;quot;,L7Dir&lt;br /&gt;
#	p=os.system(&amp;quot;gzip -d -q &amp;quot;+L7Dir+&amp;quot;/*.gz&amp;quot;)&lt;br /&gt;
	#Using pthreads on multi-core machines&lt;br /&gt;
	#p=os.system(&amp;quot;pigz -d &amp;quot;+L7Dir+&amp;quot;/*.gz&amp;quot;)&lt;br /&gt;
	#Wait ten seconds for gzip to create the tif images&lt;br /&gt;
#	time.sleep(10)&lt;br /&gt;
	print &amp;quot;Import in GRASS GIS&amp;quot;&lt;br /&gt;
	for L7f in glob.glob(os.path.join(L7Dir,&amp;quot;*.[tT][iI][fF]&amp;quot;)):&lt;br /&gt;
		f1=L7f.replace(L7Dir+&amp;quot;/&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		f2=f1.replace(&amp;quot;.TIF&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		f3=f2.replace(&amp;quot;_B10&amp;quot;,&amp;quot;.1&amp;quot;)&lt;br /&gt;
		f4=f3.replace(&amp;quot;_B20&amp;quot;,&amp;quot;.2&amp;quot;)&lt;br /&gt;
		f5=f4.replace(&amp;quot;_B30&amp;quot;,&amp;quot;.3&amp;quot;)&lt;br /&gt;
		f6=f5.replace(&amp;quot;_B40&amp;quot;,&amp;quot;.4&amp;quot;)&lt;br /&gt;
		f7=f6.replace(&amp;quot;_B50&amp;quot;,&amp;quot;.5&amp;quot;)&lt;br /&gt;
		f8=f7.replace(&amp;quot;_B61&amp;quot;,&amp;quot;.61&amp;quot;)&lt;br /&gt;
		f9=f8.replace(&amp;quot;_B62&amp;quot;,&amp;quot;.62&amp;quot;)&lt;br /&gt;
		f10=f9.replace(&amp;quot;_B70&amp;quot;,&amp;quot;.7&amp;quot;)&lt;br /&gt;
		f11=f10.replace(&amp;quot;_B80&amp;quot;,&amp;quot;.8&amp;quot;)&lt;br /&gt;
		f12=f11.replace(&amp;quot;L72&amp;quot;,&amp;quot;L71&amp;quot;)&lt;br /&gt;
		L7r=f12.replace(&amp;quot;_VCID_&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,L7r&lt;br /&gt;
		r.in_gdal(input=L7f,output=L7r,flags=&amp;quot;e&amp;quot;,overwrite=OVR)&lt;br /&gt;
		fileList.append(L7r)&lt;br /&gt;
&lt;br /&gt;
	#reproject the DEM World map for the new PERMANENT location extents&lt;br /&gt;
	r.proj(input=&amp;quot;dem&amp;quot;,location=&amp;quot;Myanmar&amp;quot;,memory=10000,resolution=90.0,overwrite=OVR)&lt;br /&gt;
	#Get list of metadata files&lt;br /&gt;
	for metaf in glob.glob(os.path.join(L7Dir,wldc_mtl)):&lt;br /&gt;
		metadata.append(metaf)&lt;br /&gt;
	print &amp;quot;Metadata in:\n&amp;quot;,metadata[0]&lt;br /&gt;
	with open(metadata[0],&amp;quot;r&amp;quot;) as f:&lt;br /&gt;
		data=f.read()&lt;br /&gt;
&lt;br /&gt;
	f.close()&lt;br /&gt;
	dt=data.split(&amp;quot;\n&amp;quot;)&lt;br /&gt;
	for idx in range(len(dt)):&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_UL_LON_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			ulx=float(dt[idx].replace(&amp;quot;CORNER_UL_LON_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_UL_LAT_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			uly=float(dt[idx].replace(&amp;quot;CORNER_UL_LAT_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_LR_LON_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			lrx=float(dt[idx].replace(&amp;quot;CORNER_LR_LON_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_LR_LAT_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			lry=float(dt[idx].replace(&amp;quot;CORNER_LR_LAT_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		#Two cases, because a string starting by 0 is not converted well&lt;br /&gt;
		found=dt[idx].find(&amp;quot;SCENE_CENTER_TIME = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			tim=dt[idx].replace(&amp;quot;SCENE_CENTER_TIME = &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
			print &amp;quot;timestamp=&amp;quot;,str(tim)&lt;br /&gt;
			gmth=float(tim.split(&amp;quot;:&amp;quot;)[0])&lt;br /&gt;
			gmtm=float(tim.split(&amp;quot;:&amp;quot;)[1])&lt;br /&gt;
			gmtdec=float(tim.split(&amp;quot;:&amp;quot;)[2].replace(&amp;quot;Z&amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
			print gmth,gmtm,gmtdec&lt;br /&gt;
		found=dt[idx].find(&amp;quot;DATE_ACQUIRED = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			dat=dt[idx].replace(&amp;quot;DATE_ACQUIRED = &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
			date=dat.split(&amp;quot;-&amp;quot;)&lt;br /&gt;
		found=dt[idx].find(&amp;quot;SUN_ELEVATION = &amp;quot;)&lt;br /&gt;
                if found &amp;gt; 0:&lt;br /&gt;
                        sunza=90-float(dt[idx].replace(&amp;quot;SUN_ELEVATION = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	#L7 DN-&amp;gt;Rad-&amp;gt;Ref&lt;br /&gt;
	print &amp;quot;Convert DN to Rad to TOARef&amp;quot;&lt;br /&gt;
	f1=sorted(fileList)[0]&lt;br /&gt;
	f2=f1.replace(L7Dir+&amp;quot;/&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
	pref=f2[:-1]&lt;br /&gt;
	outpref=pref[:-2]+&amp;quot;.toar.&amp;quot;&lt;br /&gt;
	print &amp;quot;Prefix IN:\t&amp;quot;,pref&lt;br /&gt;
	print &amp;quot;Prefix OUT:\t&amp;quot;, outpref&lt;br /&gt;
	i.landsat_toar(input_prefix=pref,output_prefix=outpref,metfile=metadata[0],sensor=LSENSOR,quiet=QIET,overwrite=OVR)&lt;br /&gt;
	#Atmospheric Correction&lt;br /&gt;
	print &amp;quot;Atmospheric Correction&amp;quot;&lt;br /&gt;
	# Basic script for i.atcorr for L 7 ETM+&lt;br /&gt;
	#Geometrical conditions (L7ETM+)&lt;br /&gt;
	geom=7&lt;br /&gt;
	#Sensor height (satellite is -1000)&lt;br /&gt;
	sens_height=-1000&lt;br /&gt;
	#Here we suppose you have altitude (DEM) and Visibility (VIS) maps ready&lt;br /&gt;
	#---------------------------------------------&lt;br /&gt;
	#Visibility dummy value (overwritten by VIS raster input)&lt;br /&gt;
	vis=15&lt;br /&gt;
	#Altitude dummy value (in Km should be negative in this param file)&lt;br /&gt;
	#(overwritten by DEM raster input)&lt;br /&gt;
	alt=-1.200&lt;br /&gt;
	#datetime of satellite overpass (month, day, GMT decimal hour)&lt;br /&gt;
	mdh=str(int(date[1]))+&amp;quot; &amp;quot;+str(int(date[2]))+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % (gmth+gmtm/60.0+gmtdec/3600.0))&lt;br /&gt;
	print &amp;quot;MM DD hh.ddd:\t&amp;quot;,mdh&lt;br /&gt;
	# Central Lat/Long&lt;br /&gt;
	Long=ulx+(lrx-ulx)/2.0&lt;br /&gt;
	Lat=lry+(uly-lry)/2.0&lt;br /&gt;
	print &amp;quot;Center:\t(&amp;quot;,Long, &amp;quot;,&amp;quot;, Lat,&amp;quot;)&amp;quot;&lt;br /&gt;
	#Atmospheric mode&lt;br /&gt;
	atm_mode=1 #Tropical&lt;br /&gt;
	#Aerosol model&lt;br /&gt;
	aerosol_mode=2 #Sri Lanka is a small island (maritime)&lt;br /&gt;
	#satellite band number (L5TM [25,26,27,28,29,30], L7ETM+ [61,62,63,64,65,66,67])&lt;br /&gt;
	satbandno=61 #Band 1 of L7ETM+ is first to undergo atmospheric correction&lt;br /&gt;
	#make time stamp for use in time series analysis&lt;br /&gt;
	dat1=str(date[2])+&amp;quot;-&amp;quot;+str(date[1])+&amp;quot;-&amp;quot;+str(date[0])&lt;br /&gt;
	dat=dat1.replace(&amp;quot; &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
	timestamp=time.strftime(&amp;quot;%d %b %Y&amp;quot;,time.strptime(dat,&amp;quot;%d-%m-%Y&amp;quot;))&lt;br /&gt;
	print &amp;quot;Timestamp:\t&amp;quot;,timestamp&lt;br /&gt;
	for idx in [1,2,3,4,5,7]:&lt;br /&gt;
		b=pref[:-2]+&amp;quot;.toar.&amp;quot;+str(idx)&lt;br /&gt;
		b_out=b.replace(&amp;quot;.toar.&amp;quot;,&amp;quot;.surf.&amp;quot;)&lt;br /&gt;
		param=[]&lt;br /&gt;
		param.append(str(geom)+&amp;quot; - geometrical conditions=Landsat 7 ETM+\n&amp;quot;)&lt;br /&gt;
		param.append(str(mdh)+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % Long)+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % Lat)+&amp;quot; - month day hh.ddd longitude latitude (hh.ddd is in decimal hours GMT)\n&amp;quot;)&lt;br /&gt;
		param.append(str(atm_mode)+&amp;quot; - atmospheric mode=tropical\n&amp;quot;)&lt;br /&gt;
		param.append(str(aerosol_mode)+&amp;quot; - aerosols model=maritime\n&amp;quot;)&lt;br /&gt;
		param.append(str(vis)+&amp;quot; - visibility [km] (aerosol model concentration), not used as there is raster input\n&amp;quot;)&lt;br /&gt;
		param.append(str(alt)+&amp;quot; - mean target elevation above sea level [km] (here 600m asl), not used as there is raster input\n&amp;quot;)&lt;br /&gt;
		param.append(str(sens_height)+&amp;quot; - sensor height (here, sensor on board a satellite)\n&amp;quot;)&lt;br /&gt;
		param.append(str(satbandno)+&amp;quot; - i th band of ETM+ Landsat 7 (atcorr internal no)\n&amp;quot;)&lt;br /&gt;
		f=open(os.path.join(L7Dir,&amp;quot;param_L7.txt&amp;quot;),&amp;quot;w&amp;quot;)&lt;br /&gt;
		f.writelines(param)&lt;br /&gt;
		f.close()&lt;br /&gt;
		prm=os.path.join(L7Dir,&amp;quot;param_L7.txt&amp;quot;)&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,b&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,b_out&lt;br /&gt;
		i.atcorr(input=b, elevation=&amp;quot;dem&amp;quot;, visibility=&amp;quot;vis&amp;quot;, parameters=prm, output=b_out, flags=&amp;quot;ra&amp;quot;, range=[0,1],quiet=QIET,overwrite=OVR)&lt;br /&gt;
		r.timestamp(map=b_out,date=timestamp,finish_=False)&lt;br /&gt;
		satbandno = satbandno + 1&lt;br /&gt;
&lt;br /&gt;
	#Allocate surface reflectance names&lt;br /&gt;
	b1=pref[:-2]+&amp;quot;.surf.1&amp;quot;&lt;br /&gt;
	b2=pref[:-2]+&amp;quot;.surf.2&amp;quot;&lt;br /&gt;
	b3=pref[:-2]+&amp;quot;.surf.3&amp;quot;&lt;br /&gt;
	b4=pref[:-2]+&amp;quot;.surf.4&amp;quot;&lt;br /&gt;
	b5=pref[:-2]+&amp;quot;.surf.5&amp;quot;&lt;br /&gt;
	b61=pref[:-2]+&amp;quot;.toar.61&amp;quot;&lt;br /&gt;
	b62=pref[:-2]+&amp;quot;.toar.62&amp;quot;&lt;br /&gt;
	b7=pref[:-2]+&amp;quot;.surf.7&amp;quot;&lt;br /&gt;
	b8=pref[:-2]+&amp;quot;.surf.8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	### PART 1: BASIC STUFF ###&lt;br /&gt;
	b_in=pref[:-2]+&amp;quot;.toar.&amp;quot;&lt;br /&gt;
	b_clouds=pref[:-2]+&amp;quot;.toar.acca&amp;quot;&lt;br /&gt;
	print &amp;quot;Clouds:\t\t&amp;gt;&amp;quot;,b_clouds&lt;br /&gt;
	i.landsat_acca(input_prefix=b_in,output=b_clouds,overwrite=OVR)&lt;br /&gt;
	#png_clouds=L7Dir+&amp;quot;/&amp;quot;+pref[:-2]+&amp;quot;.clouds.png&amp;quot;&lt;br /&gt;
	#d.mon(start='png',output=png_clouds,width=800,height=800)&lt;br /&gt;
	print &amp;quot;MASK:\t\tON&amp;quot;&lt;br /&gt;
	#Should always be rewritten!&lt;br /&gt;
	r.mask(raster=b_clouds,flags=&amp;quot;i&amp;quot;,overwrite=True)&lt;br /&gt;
&lt;br /&gt;
	b_ndvi=pref[:-2]+&amp;quot;.surf.ndvi&amp;quot;&lt;br /&gt;
	print &amp;quot;NDVI:\t&amp;quot;,b_ndvi&lt;br /&gt;
	i.vi(red=b3,nir=b4,output=b_ndvi,viname=&amp;quot;ndvi&amp;quot;,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
&lt;br /&gt;
	b_in=[b1,b2,b3,b4,b5,b7]&lt;br /&gt;
	b_albedo=pref[:-2]+&amp;quot;.surf.albedo&amp;quot;&lt;br /&gt;
	print &amp;quot;Albedo:\t&amp;quot;,b_albedo&lt;br /&gt;
	i.albedo(input=b_in,output=b_albedo,flags=&amp;quot;lc&amp;quot;,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
	&lt;br /&gt;
	b_emissivity=pref[:-2]+&amp;quot;.surf.emissivity&amp;quot;&lt;br /&gt;
	print &amp;quot;Emissivity:\t&amp;quot;,b_emissivity&lt;br /&gt;
	i.emissivity(input=b_ndvi, output=b_emissivity,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiprocessing example: parallelized SHAPE file import ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
Multiprocessing example: parallelized SHAPE file import&lt;br /&gt;
&lt;br /&gt;
Created on Fri, Oct 18, 2013, posted to grass-user@lists.osgeo.org&lt;br /&gt;
&lt;br /&gt;
@author: Pietro Zambelli, freely inspired by: http://stackoverflow.com/a/16071616&lt;br /&gt;
         http://lists.osgeo.org/pipermail//grass-user/2013-October/069130.html&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Directory containing SHAPE files to import&lt;br /&gt;
DIR = '/data/shp'&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
from multiprocessing import Queue, Process, cpu_count&lt;br /&gt;
from os.path import split&lt;br /&gt;
from subprocess import Popen&lt;br /&gt;
&lt;br /&gt;
from grass.pygrass.functions import findfiles&lt;br /&gt;
&lt;br /&gt;
def spawn(func):&lt;br /&gt;
    def fun(q_in, q_out):&lt;br /&gt;
        while True:&lt;br /&gt;
            path, cmdstr = q_in.get()&lt;br /&gt;
            if path is None:&lt;br /&gt;
                break&lt;br /&gt;
            q_out.put(func(path, cmdstr))&lt;br /&gt;
    return fun&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mltp_importer(dirpath, match, cmdstr, func, nprocs=cpu_count()):&lt;br /&gt;
    q_in = Queue(1)&lt;br /&gt;
    q_out = Queue()&lt;br /&gt;
    procs = [Process(target=spawn(func), args=(q_in, q_out))&lt;br /&gt;
             for _ in range(nprocs)]&lt;br /&gt;
    for proc in procs:&lt;br /&gt;
        proc.daemon = True&lt;br /&gt;
        proc.start()&lt;br /&gt;
&lt;br /&gt;
    # set the parameters&lt;br /&gt;
    sent = [q_in.put((path, cmdstr)) for path in findfiles(dirpath, match)]&lt;br /&gt;
    # set the end of the cycle&lt;br /&gt;
    [q_in.put((None, None)) for proc in procs]&lt;br /&gt;
    [proc.join() for proc in procs]&lt;br /&gt;
    return [q_out.get() for _ in range(len(sent))]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def importer(path, cmdstr):&lt;br /&gt;
    name = split(path)[-1][:-4]&lt;br /&gt;
    print name&lt;br /&gt;
    popen = Popen(cmdstr.format(path=path, name=name), shell=True)&lt;br /&gt;
    popen.wait()&lt;br /&gt;
    return path, name, False if popen.returncode else True&lt;br /&gt;
&lt;br /&gt;
CMD = 'v.in.ogr dsn={path} layer={name} output={name}'&lt;br /&gt;
&lt;br /&gt;
processed = mltp_importer(DIR, '*.shp', CMD, importer)&lt;br /&gt;
# check for errors&lt;br /&gt;
errors = [p for p in processed if not p[2]]&lt;br /&gt;
if errors:&lt;br /&gt;
    # do something (print list of failed SHP files at end)&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Python}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Test_Suite&amp;diff=19840</id>
		<title>Test Suite</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Test_Suite&amp;diff=19840"/>
		<updated>2013-10-29T09:53:09Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: add my name to the list of interested people&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= GRASS GIS 7 Test Suite =&lt;br /&gt;
&lt;br /&gt;
We aim at creating a comprehensive test suite for GRASS GIS 7 modules and libraries.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
See what has been done so far by Sören Gebbert and others here: [[Development#QA]] and the good [http://www.vtk.org/Wiki/images/b/bc/Testing.cover.txt VKT test suite]&lt;br /&gt;
&lt;br /&gt;
Keep an eye on [[GRASS_7_ideas_collection#Complete_GRASS_Test_Suite:_see_activity_on_Test_Suite_development_page | GRASS 7 ideas collection]]&lt;br /&gt;
&lt;br /&gt;
== Main picture ==&lt;br /&gt;
&lt;br /&gt;
We plan to run unit tests and integration tests for both libraries and modules. The test suite will be run after compilation, with a command like:&lt;br /&gt;
&lt;br /&gt;
  $ make tests [ proj ]&lt;br /&gt;
&lt;br /&gt;
Options:&lt;br /&gt;
* proj: run the tests with a [list of] CRS, so that reprojection and map unit handling are tested.&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
Tests are executed recursively. If the &amp;quot;make tests&amp;quot; command is executed in the root source folder all libraries and modules are tested. To test only the libraries you need to switch in the '''lib''' directory and execute &amp;quot;make tests&amp;quot;. If you want to test only raster modules switch into the '''raster''' directory and run &amp;quot;make tests&amp;quot;, same for other modules directories. To test a single module switch into the module directory and run &amp;quot;make tests&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Testing should work in parallel, so that make -j6 tests will execute as maximum 6 tests in parallel. The framework should take care that parallel testing test runs can be performed.&lt;br /&gt;
&lt;br /&gt;
== Tests == &lt;br /&gt;
&lt;br /&gt;
=== Modules ===&lt;br /&gt;
Tests are targeted to cover all modules as well as library test modules.&lt;br /&gt;
&lt;br /&gt;
The modules tests should as independent as possible from other GRASS modules.&lt;br /&gt;
&lt;br /&gt;
Tests are written as simple shell script with annotations. Test script should start with '''test.''' followed by the module name i.e. '''r.mapcalc.''' and further ending with '''.sh'''. Example '''test.r.mapcalc.1.sh'''. All test should be well documented using shell comments.&lt;br /&gt;
&lt;br /&gt;
The framework will execute all test scripts starting with '''test.''' and ending with '''.sh''' located in module or library directories.&lt;br /&gt;
&lt;br /&gt;
Annotations are integrated in the test documentation (simple shell comments) and specify pre-processing steps, the tests and the type of the data to validate. The following annotations should be supported:&lt;br /&gt;
&lt;br /&gt;
* The '''@preprocess''' annotation&lt;br /&gt;
** All commands below this annotation are handled as preprocessing steps for the tests. &lt;br /&gt;
** If any of the preprocess commands fail, the framework should stop testing an create a detailed error report. &lt;br /&gt;
** Preprocessing steps may be data generation, region settings and so on.&lt;br /&gt;
** The preprocess annotation is valid till a '''@test''' annotation specifies the begin of a test&lt;br /&gt;
** Preprocess annotations can be specified at between tests&lt;br /&gt;
* The '''@test''' annotation&lt;br /&gt;
** All command below a this annotation are handled as tests by the framework&lt;br /&gt;
** The test annotation must be integrated in the comment block which describes the test&lt;br /&gt;
** Data validation is performed by the framework for tests if reference data is present&lt;br /&gt;
** The test annotation is valid till a '''@preprocess''' annotation specifies the begin of a preprocess block for further test runs&lt;br /&gt;
** The data type annotations&lt;br /&gt;
*** Data type annotations should be specified in the same comment block as the '''@test''' annotation&lt;br /&gt;
*** Data type annotations specify the grass data types which should be validated with reference data&lt;br /&gt;
*** The following data type annotations should be specified&lt;br /&gt;
**** '''@file''' the framework should compare the reference data with files&lt;br /&gt;
**** '''@raster''' the framework should compare the reference data with raster maps using r.out.ascii for export&lt;br /&gt;
**** '''@vector''' the framework should compare the reference data with vector maps using v.out.ascii for export&lt;br /&gt;
**** '''@raster3d''' the framework should compare the reference data with raster3d maps using r3.out.ascii for export&lt;br /&gt;
**** '''@color''' the framework should compare the reference data with color rules using r.color.out for export&lt;br /&gt;
**** '''@color3d''' the framework should compare the reference data with 3d color rules using r3.color.out for export&lt;br /&gt;
**** '''@table''' the framework should compare the reference data with SQL tables  using db.select for export&lt;br /&gt;
**** ... please add more&lt;br /&gt;
** The '''@precision=[positive integer]''' annotation&lt;br /&gt;
*** Should be located in a test comment block&lt;br /&gt;
*** Specifies the precision to use to export grass data for validation with reference files&lt;br /&gt;
*** In case the precision is not provided the default behavior of the export module is used&lt;br /&gt;
&lt;br /&gt;
Reference data for validation must be located in the module/library reference directory. The reference data names must be identical with the generated data (files, maps, ...) except that reference data always has a '''.ref''' suffix.  &lt;br /&gt;
&lt;br /&gt;
Tests are in each module's and in each library's folder. To test library functions special modules must be implemented. Library test modules test the library functions directly and should be written in C. Have a look at the test directories in the g3d, gpde and gmath libraries of grass7.&lt;br /&gt;
&lt;br /&gt;
Framework should be able to generate and compare grass data types: raster, vector, raster3d, general, db, icon, imagery, d.*?&lt;br /&gt;
&lt;br /&gt;
wxGUI testing should be tested separately.&lt;br /&gt;
&lt;br /&gt;
Automated tests on server generates HTML report. Test several platforms.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here some examples already available in grass7:&lt;br /&gt;
&lt;br /&gt;
=== test.v.random.sh ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# This is a simple test for v.random&lt;br /&gt;
# We create several identical pseudo random points maps :)&lt;br /&gt;
# using the seed option for rand and drand48&lt;br /&gt;
&lt;br /&gt;
# In the @preprocess step we set up a suitable region&lt;br /&gt;
g.region n=80 s=0 w=0 e=120 res=10 -p&lt;br /&gt;
&lt;br /&gt;
# First @test the rand function. Create a 3d vector map with attribute table&lt;br /&gt;
# The validation is based on @vector map with a @precision=3&lt;br /&gt;
v.random --o -z output=test_random_vect_1 n=20 zmin=0 zmax=100 seed=501&lt;br /&gt;
# Now the attribute @table should be validated. Booth maps are identical&lt;br /&gt;
v.random --o -z output=test_random_vect_2 n=20 zmin=0 zmax=100 column=height seed=501&lt;br /&gt;
&lt;br /&gt;
# Second @test the drand48 function. Create a 3d vector map with attribute table&lt;br /&gt;
# The validation is based on @vector map with a @precision=3&lt;br /&gt;
v.random --o -zd output=test_random_vect_3 n=20 zmin=0 zmax=100 seed=501&lt;br /&gt;
# Now the attribute @table should be validated. Booth maps are identical&lt;br /&gt;
v.random --o -zd output=test_random_vect_4 n=20 zmin=0 zmax=100 column=height seed=501&lt;br /&gt;
&lt;br /&gt;
# Export the generated data as references&lt;br /&gt;
# v.out.ascii --o format=point dp=3 input=test_random_vect_1 output=test_random_vect_1.ref&lt;br /&gt;
# db.select &amp;quot;select * from test_random_vect_2&amp;quot; &amp;gt; test_random_vect_2.ref&lt;br /&gt;
# v.out.ascii --o format=point dp=3 input=test_random_vect_3 output=test_random_vect_3.ref&lt;br /&gt;
# db.select &amp;quot;select * from test_random_vect_4&amp;quot; &amp;gt; test_random_vect_4.ref&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following reference files are located in the v.random directory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-rw-r--r--  1 soeren users  460 18. Jun 01:20 test_random_vect_1.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  257 18. Jun 01:20 test_random_vect_2.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  455 18. Jun 01:20 test_random_vect_3.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  256 18. Jun 01:20 test_random_vect_4.ref&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== test.r3.out.vtk.sh ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# This script tests the export of voxel data&lt;br /&gt;
# into the VTK format. Almost all options of&lt;br /&gt;
# r3.out.vtk are tested. Validation data for each test&lt;br /&gt;
# is located in the module source directory&lt;br /&gt;
&lt;br /&gt;
# We need to set a specific region in the&lt;br /&gt;
# @preprocess step of this test. We generate&lt;br /&gt;
# raster and voxel data with r.mapcalc and r3.mapcalc&lt;br /&gt;
# The region setting should work for UTM and LL test locations&lt;br /&gt;
g.region s=0 n=80 w=0 e=120 b=0 t=50 res=10 res3=10 -p3&lt;br /&gt;
# Now generate two elevation maps, we have 8 rows and use&lt;br /&gt;
# them for elevation computation. The rows are counted from north&lt;br /&gt;
# to south. So in the south the elevation must have a maximum.&lt;br /&gt;
r.mapcalc --o expr=&amp;quot;elev_bottom = row()&amp;quot;&lt;br /&gt;
r.mapcalc --o expr=&amp;quot;elev_top = row() + 50&amp;quot;&lt;br /&gt;
# Now create a voxel map with value = col + row + depth. &lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume = col() + row() + depth()&amp;quot;&lt;br /&gt;
# Add null value information&lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume_null = if(row() == 2 || row() == 7, null(), volume)&amp;quot;&lt;br /&gt;
# Create the rgb maps&lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume_rgb = volume_null * 5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# The first @test just exports the volume map as cell and point data&lt;br /&gt;
# using a low precision and replaces the default null value with 0&lt;br /&gt;
# the created @files should be compared with the reference data&lt;br /&gt;
r3.out.vtk --o input=volume_null output=test_volume_null_1_cells.vtk dp=3 null=0&lt;br /&gt;
r3.out.vtk -p --o input=volume_null output=test_volume_null_1_points.vtk dp=3 null=0&lt;br /&gt;
&lt;br /&gt;
# The second @test adds rgb and vector maps. We re-use the created volume map&lt;br /&gt;
# for vector creation. The rgb value must range fom 0 - 255. The generated @files&lt;br /&gt;
# should be compared with the reference data.&lt;br /&gt;
r3.out.vtk --o rgbmaps=volume_rgb,volume_rgb,volume_rgb vectormaps=volume_null,volume_null,volume_null input=volume_null output=test_volume_null_1_cells_rgb_vect.vtk dp=3 null=-1.0&lt;br /&gt;
r3.out.vtk -p --o rgbmaps=volume_rgb,volume_rgb,volume_rgb vectormaps=volume_null,volume_null,volume_null input=volume_null output=test_volume_null_1_points_rgb_vect.vtk dp=3 null=-1.0&lt;br /&gt;
&lt;br /&gt;
# The third @test uses raster maps to create volume data with an elevation surface&lt;br /&gt;
# The maximum elevation should be in the south. Reference @files are present for validation.&lt;br /&gt;
r3.out.vtk -s --o top=elev_top bottom=elev_bottom input=volume_null output=test_volume_null_1_cells_elevation.vtk dp=3 null=0&lt;br /&gt;
r3.out.vtk -sp --o top=elev_top bottom=elev_bottom input=volume_null output=test_volume_null_1_points_elevation.vtk dp=3 null=0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following reference files are located in the r3.out.vtk directory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-rw-r--r-- 1 soeren users 104556 16. Jun 18:14 test_volume_null_1_cells_elevation.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users   3434 16. Jun 18:14 test_volume_null_1_cells.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users  22749 16. Jun 18:14 test_volume_null_1_cells_rgb_vect.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users  13360 16. Jun 18:14 test_volume_null_1_points_elevation.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users   3435 16. Jun 18:14 test_volume_null_1_points.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users  22750 16. Jun 18:14 test_volume_null_1_points_rgb_vect.ref&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== test.r3.cross.rast.sh ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# This script tests the r3.cross.rast module to compute&lt;br /&gt;
# cross section raster maps based on a raster3d and elevation map&lt;br /&gt;
&lt;br /&gt;
# We need to set a specific region in the&lt;br /&gt;
# @preprocess step of this test. We generate&lt;br /&gt;
# raster and voxel data with r.mapcalc and r3.mapcalc&lt;br /&gt;
# The region setting should work for UTM and LL test locations&lt;br /&gt;
g.region s=0 n=80 w=0 e=100 b=0 t=50 res=10 res3=10 -p3&lt;br /&gt;
# We create several elevation maps to create slices of the voxel map&lt;br /&gt;
# We start from bottom and raise to the top. Value equal or greater 50 &lt;br /&gt;
# should generate grass NULL values&lt;br /&gt;
r.mapcalc --o expr=&amp;quot;elev_0 = 0&amp;quot;&lt;br /&gt;
r.mapcalc --o expr=&amp;quot;elev_1 = 5&amp;quot;&lt;br /&gt;
r.mapcalc --o expr=&amp;quot;elev_2 = 15&amp;quot;&lt;br /&gt;
r.mapcalc --o expr=&amp;quot;elev_3 = 25&amp;quot;&lt;br /&gt;
r.mapcalc --o expr=&amp;quot;elev_4 = 35&amp;quot;&lt;br /&gt;
r.mapcalc --o expr=&amp;quot;elev_5 = 45&amp;quot;&lt;br /&gt;
r.mapcalc --o expr=&amp;quot;elev_NAN = 50&amp;quot;&lt;br /&gt;
r.mapcalc --o expr=&amp;quot;elev_cross = float(col()* 5)&amp;quot;&lt;br /&gt;
# Now create a voxel map with value = col + row + depth. &lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume = col() + row() + depth()&amp;quot;&lt;br /&gt;
# Add null value information&lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume_null = if(row() == 1 || row() == 5, null(), volume)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# We @test the creation of slices and a cross section of the voxel map. Reference data&lt;br /&gt;
# for @raster map validation is located in the r3.cross.rast source directory.&lt;br /&gt;
# Slice 0 and 1 should be identical. The last slice should consist only of grass NULL values&lt;br /&gt;
r3.cross.rast --o input=volume_null elevation=elev_0 output=test_cross_section_slice_0&lt;br /&gt;
r3.cross.rast --o input=volume_null elevation=elev_1 output=test_cross_section_slice_1&lt;br /&gt;
r3.cross.rast --o input=volume_null elevation=elev_2 output=test_cross_section_slice_2&lt;br /&gt;
r3.cross.rast --o input=volume_null elevation=elev_3 output=test_cross_section_slice_3&lt;br /&gt;
r3.cross.rast --o input=volume_null elevation=elev_4 output=test_cross_section_slice_4&lt;br /&gt;
r3.cross.rast --o input=volume_null elevation=elev_5 output=test_cross_section_slice_5&lt;br /&gt;
r3.cross.rast --o input=volume_null elevation=elev_NAN output=test_cross_section_slice_NAN&lt;br /&gt;
r3.cross.rast --o input=volume_null elevation=elev_cross output=test_cross_section_result&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following reference files are located in the r3.cross.rast directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-rw-r--r-- 1 soeren users   264 16. Jun 18:14 test_cross_section_result.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users   264 16. Jun 18:14 test_cross_section_slice_0.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users   264 16. Jun 18:14 test_cross_section_slice_1.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users   269 16. Jun 18:14 test_cross_section_slice_2.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users   273 16. Jun 18:14 test_cross_section_slice_3.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users   276 16. Jun 18:14 test_cross_section_slice_4.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users   279 16. Jun 18:14 test_cross_section_slice_5.ref&lt;br /&gt;
-rw-r--r-- 1 soeren users   222 16. Jun 18:14 test_cross_section_slice_NAN.ref&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== test.r3.out.ascii.sh ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Tests for r3.out.ascii and r3.in.ascii&lt;br /&gt;
# This script tests the export of voxel data using r3.out.ascii&lt;br /&gt;
# as well as the import of the generated data with r3.in.ascii&lt;br /&gt;
# using different row and depth ordering options.&lt;br /&gt;
&lt;br /&gt;
# We set up a specific region in the&lt;br /&gt;
# @preprocess step of this test. We generate&lt;br /&gt;
# voxel data with r3.mapcalc. The region setting&lt;br /&gt;
# should work for UTM and LL test locations&lt;br /&gt;
g.region s=0 n=80 w=0 e=120 b=0 t=50 res=10 res3=10 -p3&lt;br /&gt;
# Now create several (float, double, null value) voxel map&lt;br /&gt;
# with value = col + row + depth.&lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume_float = float(col() + row() + depth())&amp;quot;&lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume_double = double(col() + row() + depth())&amp;quot;&lt;br /&gt;
# Add null value information&lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume_float_null = if(row() == 1 || row() == 5, null(), volume_float)&amp;quot;&lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume_double_null = if(row() == 1 || row() == 5, null(), volume_double)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# We export float data in the first @test using different order and precision&lt;br /&gt;
# as text @files for valdiation of correct ordering and null data handling&lt;br /&gt;
r3.out.ascii --o     input=volume_float_null output=test_float_nsbt_null.txt dp=0 null=*&lt;br /&gt;
r3.out.ascii --o -r  input=volume_float_null output=test_float_snbt_null.txt dp=0 null=*&lt;br /&gt;
r3.out.ascii --o -d  input=volume_float_null output=test_float_nstb_null.txt dp=0 null=*&lt;br /&gt;
r3.out.ascii --o -rd input=volume_float_null output=test_float_sntb_null.txt dp=0 null=*&lt;br /&gt;
# Different precision and null values than default&lt;br /&gt;
r3.out.ascii --o     input=volume_float_null output=test_float_nsbt_null_prec5.txt dp=5 null=-1000&lt;br /&gt;
r3.out.ascii --o -rd input=volume_float_null output=test_float_sntb_null_prec8.txt dp=8 null=-2000&lt;br /&gt;
# Test the no header and grass6 compatibility flags&lt;br /&gt;
r3.out.ascii --o -h input=volume_float_null output=test_float_nsbt_null_no_header.txt dp=3 null=*&lt;br /&gt;
r3.out.ascii --o -c input=volume_float_null output=test_float_nsbt_null_grass6_comp_1.txt dp=3 null=*&lt;br /&gt;
# Any row or depth order should be ignored in case grass6 compatibility is enabled&lt;br /&gt;
# The rsult of comp_1, _2 and _3 must be identical&lt;br /&gt;
r3.out.ascii --o -cr  input=volume_float_null output=test_float_nsbt_null_grass6_comp_2.txt dp=3 null=*&lt;br /&gt;
r3.out.ascii --o -crd input=volume_float_null output=test_float_nsbt_null_grass6_comp_3.txt dp=3 null=*&lt;br /&gt;
&lt;br /&gt;
# We export double data in the second @test using different order and precision&lt;br /&gt;
# as text @files for valdiation of correct ordering and null data handling. Its hte same&lt;br /&gt;
# procedure as with float data&lt;br /&gt;
r3.out.ascii --o     input=volume_double_null output=test_double_nsbt_null.txt dp=0 null=*&lt;br /&gt;
r3.out.ascii --o -r  input=volume_double_null output=test_double_snbt_null.txt dp=0 null=*&lt;br /&gt;
r3.out.ascii --o -d  input=volume_double_null output=test_double_nstb_null.txt dp=0 null=*&lt;br /&gt;
r3.out.ascii --o -rd input=volume_double_null output=test_double_sntb_null.txt dp=0 null=*&lt;br /&gt;
# Different precision and null values than default&lt;br /&gt;
r3.out.ascii --o     input=volume_double_null output=test_double_nsbt_null_prec5.txt dp=5 null=-1000&lt;br /&gt;
r3.out.ascii --o -rd input=volume_double_null output=test_double_sntb_null_prec8.txt dp=8 null=-2000&lt;br /&gt;
# Test the no header and grass6 compatibility flags&lt;br /&gt;
r3.out.ascii --o -h input=volume_double_null output=test_double_nsbt_null_no_header.txt dp=3 null=*&lt;br /&gt;
r3.out.ascii --o -c input=volume_double_null output=test_double_nsbt_null_grass6_comp_1.txt dp=3 null=*&lt;br /&gt;
# Any row or depth order should be ignored in case grass6 compatibility is enabled&lt;br /&gt;
# The result of comp_1, _2 and _3 must be identical&lt;br /&gt;
r3.out.ascii --o -cr  input=volume_double_null output=test_double_nsbt_null_grass6_comp_2.txt dp=3 null=*&lt;br /&gt;
r3.out.ascii --o -crd input=volume_double_null output=test_double_nsbt_null_grass6_comp_3.txt dp=3 null=*&lt;br /&gt;
&lt;br /&gt;
# In the third @test we import all the generated data using r3.in.ascii&lt;br /&gt;
# The created @raster maps should be identical to the map &amp;quot;volume_double_null&amp;quot;&lt;br /&gt;
# The export of the created g3d map should use as @precision=0 for data validation&lt;br /&gt;
# The same raster name is used for all the imported data and so for the validation reference file&lt;br /&gt;
r3.in.ascii --o output=test_double_nsbt_null input=test_double_nsbt_null.txt nv=*&lt;br /&gt;
r3.in.ascii --o output=test_double_nsbt_null input=test_double_snbt_null.txt nv=*&lt;br /&gt;
r3.in.ascii --o output=test_double_nsbt_null input=test_double_nstb_null.txt nv=*&lt;br /&gt;
r3.in.ascii --o output=test_double_nsbt_null input=test_double_sntb_null.txt nv=*&lt;br /&gt;
# Different precision and null values than default&lt;br /&gt;
r3.in.ascii --o output=test_double_nsbt_null input=test_double_nsbt_null_prec5.txt nv=-1000&lt;br /&gt;
r3.in.ascii --o output=test_double_nsbt_null input=test_double_sntb_null_prec8.txt nv=-2000&lt;br /&gt;
# Any row or depth order should be ignored in case grass6 compatibility is enabled&lt;br /&gt;
r3.in.ascii --o output=test_double_nsbt_null input=test_double_nsbt_null_grass6_comp_1.txt&lt;br /&gt;
&lt;br /&gt;
# In this @preprocess step for the last test we create a large region and&lt;br /&gt;
# generate large input data to test the handling of large files&lt;br /&gt;
g.region s=0 n=800 w=0 e=1200 b=0 t=50 res=10 res3=1.5 -p3&lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume_double_large = double(col() + row() + depth())&amp;quot;&lt;br /&gt;
# Add null value information&lt;br /&gt;
r3.mapcalc --o expr=&amp;quot;volume_double_null_large = if(row() == 1 || row() == 5, null(), volume_double_large)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Now @test the export and import of large data without validation&lt;br /&gt;
r3.out.ascii --o input=volume_double_null_large output=test_double_nsbt_null_large.txt dp=0 null=*&lt;br /&gt;
r3.in.ascii --o output=test_double_nsbt_null_large input=test_double_nsbt_null_large.txt nv=*&lt;br /&gt;
# Just for the logs&lt;br /&gt;
r3.info test_double_nsbt_null_large&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following reference files are located in the r3.out.ascii directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-rw-r--r--  1 soeren users  2875 17. Jun 21:36 test_double_nsbt_null_grass6_comp_1.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  2875 17. Jun 21:36 test_double_nsbt_null_grass6_comp_2.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  2875 17. Jun 21:36 test_double_nsbt_null_grass6_comp_3.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  2751 17. Jun 21:36 test_double_nsbt_null_no_header.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  4103 17. Jun 21:36 test_double_nsbt_null_prec5.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  1463 17. Jun 21:36 test_double_nsbt_null.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  1463 17. Jun 21:36 test_double_nstb_null.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  1463 17. Jun 21:36 test_double_snbt_null.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  5183 17. Jun 21:36 test_double_sntb_null_prec8.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  1463 17. Jun 21:36 test_double_sntb_null.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  2875 17. Jun 21:36 test_float_nsbt_null_grass6_comp_1.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  2875 17. Jun 21:36 test_float_nsbt_null_grass6_comp_2.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  2875 17. Jun 21:36 test_float_nsbt_null_grass6_comp_3.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  2751 17. Jun 21:36 test_float_nsbt_null_no_header.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  4103 17. Jun 21:36 test_float_nsbt_null_prec5.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  1463 17. Jun 21:36 test_float_nsbt_null.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  1463 17. Jun 21:36 test_float_nstb_null.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  1463 17. Jun 21:36 test_float_snbt_null.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  5183 17. Jun 21:36 test_float_sntb_null_prec8.ref&lt;br /&gt;
-rw-r--r--  1 soeren users  1463 17. Jun 21:36 test_float_sntb_null.ref&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test framework: ==&lt;br /&gt;
&lt;br /&gt;
What the test framework should do:&lt;br /&gt;
&lt;br /&gt;
* Creation of a test mapset for each test case in a specific test location located in the grass sources&lt;br /&gt;
* Setting the environment variables to the test location and grass installation (grass environment to run modules)&lt;br /&gt;
* For each test case a separate temporary directory should be created in which the test is executed. After testing the temporary directory get removed. The temporary directory should be located in the temporary mapset which will be automatically removed after testing.&lt;br /&gt;
* Parsing and interpretation and execution of test scripts&lt;br /&gt;
* Support of several test scripts in a single module directory&lt;br /&gt;
* Run of location specific test scripts (only LL or UTM test scripts)&lt;br /&gt;
* Handles module test results codes and stderr messages&lt;br /&gt;
* Validation of module output based on reference data and data type annotations in the test description&lt;br /&gt;
* Creates a HTML report for single modules and the whole test run&lt;br /&gt;
* Deletion of the generated test mapset to clean up the test location&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
* All test cases must be implemented as text files in shell style including annotations in comment blocks&lt;br /&gt;
* The test framework should be implemented in Python, parsing and analyzing and executing the test cases line by line&lt;br /&gt;
* The Make-System must be modified to start the tests by typing &amp;quot;make tests&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Test framework Python approach === &lt;br /&gt;
&lt;br /&gt;
I suggest the following Python classes:&lt;br /&gt;
* TestBase class - implements the test logic&lt;br /&gt;
** LatLongTest class - for LatLong test location initialization and test run, derived from TestBase class&lt;br /&gt;
** UTMTest class - for UTM test location initialization and test run, derived from TestBase class&lt;br /&gt;
* A CommandBase class - implements command line specific methods and attributes and executes a command, logging return value and stderr using the subprocess module&lt;br /&gt;
** PreProcess class - derived from CommandBase class for preprocess execution&lt;br /&gt;
** TestCase class - derived from CommandBase class for test execution&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
The TestBase class implementing the following methods:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class TestBase:&lt;br /&gt;
  def StartGrassSession(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Abstract method, should be overwritten in a subclass&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
  def Run(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Create the environment variables for the grass session, create a mapset and execute all tests&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    self.StartGrassSession()&lt;br /&gt;
    self.CreateTestMapset()&lt;br /&gt;
    self.CheckForReferenceFiles()&lt;br /&gt;
    self.ExecuteAll()&lt;br /&gt;
  &lt;br /&gt;
  def CreateTestMapset(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Creates a temporary mapset for the test using g.mapset&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
  &lt;br /&gt;
  def CreateExecutionOrder(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    * Reads the entire test case into memory and parses the file line by line&lt;br /&gt;
    * Creates the execution order list as internal structure to store specific execution settings&lt;br /&gt;
    * For each command in the test case a specific CommandBase object is created and stored in the execution order list&lt;br /&gt;
    * TestCase objects store the validation type (@file, ...) and the validation precision (@precision=1) ... and maybe more&lt;br /&gt;
   &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   pass&lt;br /&gt;
  &lt;br /&gt;
  def ExecuteAll(self):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  * Create a temporary test directory in the temporary mapset&lt;br /&gt;
  * Calls ExecuteTest or ExecutePreProcess for each entry in the execution order list&lt;br /&gt;
  * Summarize the HTML and text summary content for each entry in the list&lt;br /&gt;
  * Clean up the temporary directories generate for each command&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  pass&lt;br /&gt;
  &lt;br /&gt;
  def ExecuteTest(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    * Execute a single test command using the TestCase object &lt;br /&gt;
    * Logs stderr and return value from TestCase object&lt;br /&gt;
    * Analyses return value and stderr in case of an error&lt;br /&gt;
    * Checks for new generated maps/files of the command &lt;br /&gt;
    * Checks if reference files are present&lt;br /&gt;
    * Export data with data specific commands (r/r3/v.out.ascii, r/r3.colors.out, ...)&lt;br /&gt;
    * Compares reference files with exported files&lt;br /&gt;
    * Creates HTML and text logfile entry&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
  &lt;br /&gt;
  def CheckForReferenceFiles(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Lists all available reference files of a directory in an internal dict, &lt;br /&gt;
    base name, path and full name are stored&amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    pass&lt;br /&gt;
  &lt;br /&gt;
  def ExecutePreprocess(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    * Execute a single preprocess command using the PreProcess object &lt;br /&gt;
    * Logs stderr and return value from PreProcess object&lt;br /&gt;
    * Analyses return value and stderr in case of an error&lt;br /&gt;
    * Creates HTML and text logfile entry&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
   &lt;br /&gt;
  def CompareVectorMap(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    * Exports vector map with v.out.ascii using the default or specific TestCase precision&lt;br /&gt;
    * Compares exported file with reference file&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
   &lt;br /&gt;
  def CompareRasterMap(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    * Exports raster map with r.out.ascii using the default or specific TestCase precision&lt;br /&gt;
    * Compares exported file with reference file&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
     &lt;br /&gt;
  def CompareRaster3dMap(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    * Exports raster3d map with r3.out.ascii using the default or specific TestCase precision&lt;br /&gt;
    * Compares exported file with reference file&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
  &lt;br /&gt;
  def CompareColor(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   * Export raster color with r.colors.out&lt;br /&gt;
   * Compares exported file with reference file&lt;br /&gt;
   &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   pass&lt;br /&gt;
  &lt;br /&gt;
  def CompareColor3d(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   * Export raster3d color with r3.colors.out&lt;br /&gt;
   * Compares exported file with reference file&lt;br /&gt;
   &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   pass&lt;br /&gt;
  &lt;br /&gt;
  def CreateHTMLTestSummary(self):&lt;br /&gt;
    pass&lt;br /&gt;
  &lt;br /&gt;
  def CreateTextTestSummary(self):&lt;br /&gt;
    pass&lt;br /&gt;
  &lt;br /&gt;
  def CleanUp(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Remove the temporary test mapset and all generated test files &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
  &lt;br /&gt;
# ... many more&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LatLongTest implements the following method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class LatLongTest(BaseTest):&lt;br /&gt;
  def StartGrassSession(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;starts the grass7 session in a LatLong test location&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The UTMTest implements the following method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class UTMTest(BaseTest):&lt;br /&gt;
  def StartGrassSession(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;starts the grass7 session in a UTM test location&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CommandBase class:&lt;br /&gt;
&lt;br /&gt;
* Uses the subprocess module to execute a command&lt;br /&gt;
* Is able to identify some shell specific commands in the command line (&amp;quot;&amp;amp;&amp;amp;, |, &amp;lt;, &amp;gt;&amp;quot;)&lt;br /&gt;
* Acts as a very simple shell interpreter &lt;br /&gt;
** In case if &amp;quot;|&amp;quot; connects multiple commands in a command line with subprocess.PIPE&lt;br /&gt;
** In case of &amp;quot;&amp;gt;&amp;quot; or &amp;quot;&amp;lt;&amp;quot; uses stdout or stdin io&lt;br /&gt;
** No support for complex shell functionality (for, test, ...)&lt;br /&gt;
&lt;br /&gt;
=== Make system ===&lt;br /&gt;
&lt;br /&gt;
New rules should be added to the make system so that:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
make test ll&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Will start recursively library and/or module tests from the current directory in the LatLong test location.&lt;br /&gt;
The Make system should execute the Python test framework main Python file in each Module or Library directory.&lt;br /&gt;
I guess test specific entries must be added to the modules and library Makefiles?&lt;br /&gt;
&lt;br /&gt;
== Timeline and status ==&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|'''Task''' || '''Status''' || '''Developer(s)'''&lt;br /&gt;
|-&lt;br /&gt;
| Implementation of modules' tests || Progress || Sören&lt;br /&gt;
|-&lt;br /&gt;
| Implementation of r3.* tests || Progress || Sören&lt;br /&gt;
|-&lt;br /&gt;
| Implementation of test framework || Starting || Anne&lt;br /&gt;
|-&lt;br /&gt;
| Make integration || To be done || - &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Interested people == &lt;br /&gt;
&lt;br /&gt;
* [[User:huhabla | Sören Gebbert]]&lt;br /&gt;
* [[User:AnneGhisla| Anne Ghisla]]&lt;br /&gt;
* [[User:Landa|Martin Landa]]&lt;br /&gt;
* [[User:Wenzeslaus|Vaclav Petras]]&lt;br /&gt;
* [[User:Pietro|Pietro Zambelli]]&lt;br /&gt;
* Add your name here&lt;br /&gt;
&lt;br /&gt;
[[Category: Development]]&lt;br /&gt;
[[Category: Testing]]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=19801</id>
		<title>Python/pygrass</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=19801"/>
		<updated>2013-10-10T14:08:14Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Update link to examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''pygrass'' is a library that extends the GRASS capabilities to allow users to access the low-level GRASS API.&lt;br /&gt;
&lt;br /&gt;
== Workshops ==&lt;br /&gt;
&lt;br /&gt;
=== XIV Italian meeting of GRASS and GFOSS users ===&lt;br /&gt;
&lt;br /&gt;
Two workshops were presented during the [http://geomorfolab.arch.unige.it/genova2013/ XIV Italian meeting of GRASS] at Genova.&lt;br /&gt;
The workshops use '''ipython notebook''' to show the python and pygrass API, all the material are available on github ([https://github.com/zarch/workshop-python python], [https://github.com/zarch/workshop-pygrass pygrass]). All the execute examples are reported here:&lt;br /&gt;
&lt;br /&gt;
* python&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/00_intro.ipynb      Introduction]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/01_data_types.ipynb Data Types]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/02_syntax.ipynb     Syntax]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/03_function.ipynb   Function]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/04_class.ipynb      Class]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-python/master/05_other.ipynb      Other]&lt;br /&gt;
&lt;br /&gt;
* pygrass&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/00_Modules.ipynb     Modules]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/01_GIS_objects.ipynb GIS]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/02_Vector.ipynb      Vector]&lt;br /&gt;
** [http://nbviewer.ipython.org/urls/raw.github.com/zarch/workshop-pygrass/master/03_Raster.ipynb      Raster]&lt;br /&gt;
&lt;br /&gt;
== How to test library ==&lt;br /&gt;
&lt;br /&gt;
''pygrass'' has doctest inside its code. You can run doctest inside the [http://grass.osgeo.org/sampledata/north_carolina/nc_basic_spm_grass7.tar.gz North Carolina basic location], using the mapset '''user1'''. &lt;br /&gt;
&lt;br /&gt;
To test the single module (file) you have to move to the source code of pygrass and run the following code (this is an example of functions.py):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 python -m doctest functions.py&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Already tested modules ===&lt;br /&gt;
&lt;br /&gt;
==== Working ====&lt;br /&gt;
&lt;br /&gt;
* functions.py&lt;br /&gt;
* gis/region.py&lt;br /&gt;
* gis/__init__.py&lt;br /&gt;
* modules/__init.py&lt;br /&gt;
* vector/abstract.py&lt;br /&gt;
* vector/__init__.py&lt;br /&gt;
* vector/basic.py&lt;br /&gt;
* vector/table.py&lt;br /&gt;
* vector/geometry.py&lt;br /&gt;
* raster/abstract.py&lt;br /&gt;
&lt;br /&gt;
==== Not working ====&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* Zambelli, P., Gebbert, S., Ciolli, M., 2013. ''Pygrass: An Object Oriented Python Application Programming Interface (API) for Geographic Resources Analysis Support System (GRASS) Geographic Information System (GIS)''. ISPRS International Journal of Geo-Information 2, 201–219. ([http://dx.doi.org/10.3390/ijgi2010201 DOI] | [http://www.mdpi.com/2220-9964/2/1/201/pdf PDF])&lt;br /&gt;
&lt;br /&gt;
* [http://www.ing.unitn.it/~zambelli/projects/pygrass/ pyGrass documentation]&lt;br /&gt;
&lt;br /&gt;
== Some script for Landsat 7 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
#Date: 7th February, 2013&lt;br /&gt;
#Public domain, GRASS GIS&lt;br /&gt;
&lt;br /&gt;
#Run this script in the terminal as:&lt;br /&gt;
#python python-grass.py&lt;br /&gt;
#For debugging, run as:&lt;br /&gt;
#python -i python-grass.py&lt;br /&gt;
#PURPOSE&lt;br /&gt;
#This script processes LANDSAT 7 ETM+ images&lt;br /&gt;
#1 - unzip *.gz files&lt;br /&gt;
#2 - import files in GRASS GIS Location of your choice (r.in.gdal)&lt;br /&gt;
#3 - DN to Top of Atmosphere reflectance (i.landsat.toar)&lt;br /&gt;
#4 - TOA reflectance to Surface reflectance (i.atcorr)&lt;br /&gt;
#5 - NDVI (i.vi), Albedo (i.albedo), Emissivity (i.emissivity)&lt;br /&gt;
&lt;br /&gt;
#USER HAS TO SET THOSE&lt;br /&gt;
#QUIET REPORTS&lt;br /&gt;
QIET=True&lt;br /&gt;
#OVERWRITE EXISTING FILES&lt;br /&gt;
OVR=False&lt;br /&gt;
#Define Landsat 7 sensor for i.landsat.toar&lt;br /&gt;
LSENSOR=&amp;quot;tm7&amp;quot;&lt;br /&gt;
#Setup the path to the Landsat 7 Directories&lt;br /&gt;
rsdatapath=&amp;quot;/home/yann/RSDATA/Myanmar/L7&amp;quot;&lt;br /&gt;
#Setup your GRASS GIS working directory&lt;br /&gt;
gisdb=&amp;quot;/home/yann/GRASSDATA&amp;quot;&lt;br /&gt;
location=&amp;quot;L7_Myanmar&amp;quot;&lt;br /&gt;
print location&lt;br /&gt;
mapset=&amp;quot;PERMANENT&amp;quot;&lt;br /&gt;
#DEM input to atmospheric correction&lt;br /&gt;
inDEM=rsdatapath+&amp;quot;/dem.tif&amp;quot;&lt;br /&gt;
#set L7 Metadata wildcards&lt;br /&gt;
wldc_mtl=&amp;quot;*_MTL.txt&amp;quot;&lt;br /&gt;
#wldc_met=&amp;quot;*.met&amp;quot;&lt;br /&gt;
#Visibility distance [Km]&lt;br /&gt;
vis=18&lt;br /&gt;
&lt;br /&gt;
#Set python path to enable finding of grass.script lib&lt;br /&gt;
&lt;br /&gt;
#END OF USER CHANGES&lt;br /&gt;
###DO NOT CHANGE ANYTHING AFTER THIS LINE !&lt;br /&gt;
###&lt;br /&gt;
#Load necessary libraries&lt;br /&gt;
import os, glob, time, re&lt;br /&gt;
from grass import script as g&lt;br /&gt;
from grass.script import setup as gsetup&lt;br /&gt;
gisbase=os.environ['GISBASE']&lt;br /&gt;
gsetup.init(gisbase,gisdb,location,mapset)&lt;br /&gt;
from grass.pygrass.modules.shortcuts import raster as r&lt;br /&gt;
from grass.pygrass.modules.shortcuts import imagery as i&lt;br /&gt;
from grass.pygrass.modules.shortcuts import display as d&lt;br /&gt;
#Needed for floor()&lt;br /&gt;
from math import *&lt;br /&gt;
#env = os.environ.copy()&lt;br /&gt;
#env['GRASS_MESSAGE_FORMAT'] = 'gui'&lt;br /&gt;
#Function to get a list of L7 Directories in the rsdatapath&lt;br /&gt;
def fn(path):&lt;br /&gt;
	for top, dirs, files in os.walk(path):&lt;br /&gt;
		return [os.path.join(top, dir) for dir in dirs]&lt;br /&gt;
&lt;br /&gt;
#START PROCESS&lt;br /&gt;
### PART 0: PRE-PROCESSING STUFF ###&lt;br /&gt;
#import DEM for atmospheric correction&lt;br /&gt;
#r.in.gdal(input=inDEM,output=&amp;quot;dem&amp;quot;,overwrite=OVR)&lt;br /&gt;
#r.mapcalc(expression=&amp;quot;dem=25&amp;quot;,overwrite=OVR)&lt;br /&gt;
#create a visibility map&lt;br /&gt;
r.mapcalc(expression=&amp;quot;vis=18&amp;quot;,overwrite=OVR)&lt;br /&gt;
#Find the central location of the Landsat file from metadata&lt;br /&gt;
metadata=[]&lt;br /&gt;
fileList=[]&lt;br /&gt;
L7Dirs=fn(rsdatapath)&lt;br /&gt;
for L7Dir in L7Dirs:&lt;br /&gt;
	#Ungzip all of your Landsat7 images in all your directories&lt;br /&gt;
#	print &amp;quot;Ungzip Landsat files in\t&amp;quot;,L7Dir&lt;br /&gt;
#	p=os.system(&amp;quot;gzip -d -q &amp;quot;+L7Dir+&amp;quot;/*.gz&amp;quot;)&lt;br /&gt;
	#Using pthreads on multi-core machines&lt;br /&gt;
	#p=os.system(&amp;quot;pigz -d &amp;quot;+L7Dir+&amp;quot;/*.gz&amp;quot;)&lt;br /&gt;
	#Wait ten seconds for gzip to create the tif images&lt;br /&gt;
#	time.sleep(10)&lt;br /&gt;
	print &amp;quot;Import in GRASS GIS&amp;quot;&lt;br /&gt;
	for L7f in glob.glob(os.path.join(L7Dir,&amp;quot;*.[tT][iI][fF]&amp;quot;)):&lt;br /&gt;
		f1=L7f.replace(L7Dir+&amp;quot;/&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		f2=f1.replace(&amp;quot;.TIF&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		f3=f2.replace(&amp;quot;_B10&amp;quot;,&amp;quot;.1&amp;quot;)&lt;br /&gt;
		f4=f3.replace(&amp;quot;_B20&amp;quot;,&amp;quot;.2&amp;quot;)&lt;br /&gt;
		f5=f4.replace(&amp;quot;_B30&amp;quot;,&amp;quot;.3&amp;quot;)&lt;br /&gt;
		f6=f5.replace(&amp;quot;_B40&amp;quot;,&amp;quot;.4&amp;quot;)&lt;br /&gt;
		f7=f6.replace(&amp;quot;_B50&amp;quot;,&amp;quot;.5&amp;quot;)&lt;br /&gt;
		f8=f7.replace(&amp;quot;_B61&amp;quot;,&amp;quot;.61&amp;quot;)&lt;br /&gt;
		f9=f8.replace(&amp;quot;_B62&amp;quot;,&amp;quot;.62&amp;quot;)&lt;br /&gt;
		f10=f9.replace(&amp;quot;_B70&amp;quot;,&amp;quot;.7&amp;quot;)&lt;br /&gt;
		f11=f10.replace(&amp;quot;_B80&amp;quot;,&amp;quot;.8&amp;quot;)&lt;br /&gt;
		f12=f11.replace(&amp;quot;L72&amp;quot;,&amp;quot;L71&amp;quot;)&lt;br /&gt;
		L7r=f12.replace(&amp;quot;_VCID_&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,L7r&lt;br /&gt;
		r.in_gdal(input=L7f,output=L7r,flags=&amp;quot;e&amp;quot;,overwrite=OVR)&lt;br /&gt;
		fileList.append(L7r)&lt;br /&gt;
&lt;br /&gt;
	#reproject the DEM World map for the new PERMANENT location extents&lt;br /&gt;
	r.proj(input=&amp;quot;dem&amp;quot;,location=&amp;quot;Myanmar&amp;quot;,memory=10000,resolution=90.0,overwrite=OVR)&lt;br /&gt;
	#Get list of metadata files&lt;br /&gt;
	for metaf in glob.glob(os.path.join(L7Dir,wldc_mtl)):&lt;br /&gt;
		metadata.append(metaf)&lt;br /&gt;
	print &amp;quot;Metadata in:\n&amp;quot;,metadata[0]&lt;br /&gt;
	with open(metadata[0],&amp;quot;r&amp;quot;) as f:&lt;br /&gt;
		data=f.read()&lt;br /&gt;
&lt;br /&gt;
	f.close()&lt;br /&gt;
	dt=data.split(&amp;quot;\n&amp;quot;)&lt;br /&gt;
	for idx in range(len(dt)):&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_UL_LON_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			ulx=float(dt[idx].replace(&amp;quot;CORNER_UL_LON_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_UL_LAT_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			uly=float(dt[idx].replace(&amp;quot;CORNER_UL_LAT_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_LR_LON_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			lrx=float(dt[idx].replace(&amp;quot;CORNER_LR_LON_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		found=dt[idx].find(&amp;quot;CORNER_LR_LAT_PRODUCT = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			lry=float(dt[idx].replace(&amp;quot;CORNER_LR_LAT_PRODUCT = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
		#Two cases, because a string starting by 0 is not converted well&lt;br /&gt;
		found=dt[idx].find(&amp;quot;SCENE_CENTER_TIME = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			tim=dt[idx].replace(&amp;quot;SCENE_CENTER_TIME = &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
			print &amp;quot;timestamp=&amp;quot;,str(tim)&lt;br /&gt;
			gmth=float(tim.split(&amp;quot;:&amp;quot;)[0])&lt;br /&gt;
			gmtm=float(tim.split(&amp;quot;:&amp;quot;)[1])&lt;br /&gt;
			gmtdec=float(tim.split(&amp;quot;:&amp;quot;)[2].replace(&amp;quot;Z&amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
			print gmth,gmtm,gmtdec&lt;br /&gt;
		found=dt[idx].find(&amp;quot;DATE_ACQUIRED = &amp;quot;)&lt;br /&gt;
		if found &amp;gt; 0:&lt;br /&gt;
			dat=dt[idx].replace(&amp;quot;DATE_ACQUIRED = &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
			date=dat.split(&amp;quot;-&amp;quot;)&lt;br /&gt;
		found=dt[idx].find(&amp;quot;SUN_ELEVATION = &amp;quot;)&lt;br /&gt;
                if found &amp;gt; 0:&lt;br /&gt;
                        sunza=90-float(dt[idx].replace(&amp;quot;SUN_ELEVATION = &amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	#L7 DN-&amp;gt;Rad-&amp;gt;Ref&lt;br /&gt;
	print &amp;quot;Convert DN to Rad to TOARef&amp;quot;&lt;br /&gt;
	f1=sorted(fileList)[0]&lt;br /&gt;
	f2=f1.replace(L7Dir+&amp;quot;/&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
	pref=f2[:-1]&lt;br /&gt;
	outpref=pref[:-2]+&amp;quot;.toar.&amp;quot;&lt;br /&gt;
	print &amp;quot;Prefix IN:\t&amp;quot;,pref&lt;br /&gt;
	print &amp;quot;Prefix OUT:\t&amp;quot;, outpref&lt;br /&gt;
	i.landsat_toar(input_prefix=pref,output_prefix=outpref,metfile=metadata[0],sensor=LSENSOR,quiet=QIET,overwrite=OVR)&lt;br /&gt;
	#Atmospheric Correction&lt;br /&gt;
	print &amp;quot;Atmospheric Correction&amp;quot;&lt;br /&gt;
	# Basic script for i.atcorr for L 7 ETM+&lt;br /&gt;
	#Geometrical conditions (L7ETM+)&lt;br /&gt;
	geom=7&lt;br /&gt;
	#Sensor height (satellite is -1000)&lt;br /&gt;
	sens_height=-1000&lt;br /&gt;
	#Here we suppose you have altitude (DEM) and Visibility (VIS) maps ready&lt;br /&gt;
	#---------------------------------------------&lt;br /&gt;
	#Visibility dummy value (overwritten by VIS raster input)&lt;br /&gt;
	vis=15&lt;br /&gt;
	#Altitude dummy value (in Km should be negative in this param file)&lt;br /&gt;
	#(overwritten by DEM raster input)&lt;br /&gt;
	alt=-1.200&lt;br /&gt;
	#datetime of satellite overpass (month, day, GMT decimal hour)&lt;br /&gt;
	mdh=str(int(date[1]))+&amp;quot; &amp;quot;+str(int(date[2]))+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % (gmth+gmtm/60.0+gmtdec/3600.0))&lt;br /&gt;
	print &amp;quot;MM DD hh.ddd:\t&amp;quot;,mdh&lt;br /&gt;
	# Central Lat/Long&lt;br /&gt;
	Long=ulx+(lrx-ulx)/2.0&lt;br /&gt;
	Lat=lry+(uly-lry)/2.0&lt;br /&gt;
	print &amp;quot;Center:\t(&amp;quot;,Long, &amp;quot;,&amp;quot;, Lat,&amp;quot;)&amp;quot;&lt;br /&gt;
	#Atmospheric mode&lt;br /&gt;
	atm_mode=1 #Tropical&lt;br /&gt;
	#Aerosol model&lt;br /&gt;
	aerosol_mode=2 #Sri Lanka is a small island (maritime)&lt;br /&gt;
	#satellite band number (L5TM [25,26,27,28,29,30], L7ETM+ [61,62,63,64,65,66,67])&lt;br /&gt;
	satbandno=61 #Band 1 of L7ETM+ is first to undergo atmospheric correction&lt;br /&gt;
	#make time stamp for use in time series analysis&lt;br /&gt;
	dat1=str(date[2])+&amp;quot;-&amp;quot;+str(date[1])+&amp;quot;-&amp;quot;+str(date[0])&lt;br /&gt;
	dat=dat1.replace(&amp;quot; &amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
	timestamp=time.strftime(&amp;quot;%d %b %Y&amp;quot;,time.strptime(dat,&amp;quot;%d-%m-%Y&amp;quot;))&lt;br /&gt;
	print &amp;quot;Timestamp:\t&amp;quot;,timestamp&lt;br /&gt;
	for idx in [1,2,3,4,5,7]:&lt;br /&gt;
		b=pref[:-2]+&amp;quot;.toar.&amp;quot;+str(idx)&lt;br /&gt;
		b_out=b.replace(&amp;quot;.toar.&amp;quot;,&amp;quot;.surf.&amp;quot;)&lt;br /&gt;
		param=[]&lt;br /&gt;
		param.append(str(geom)+&amp;quot; - geometrical conditions=Landsat 7 ETM+\n&amp;quot;)&lt;br /&gt;
		param.append(str(mdh)+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % Long)+&amp;quot; &amp;quot;+str(&amp;quot;%.2f&amp;quot; % Lat)+&amp;quot; - month day hh.ddd longitude latitude (hh.ddd is in decimal hours GMT)\n&amp;quot;)&lt;br /&gt;
		param.append(str(atm_mode)+&amp;quot; - atmospheric mode=tropical\n&amp;quot;)&lt;br /&gt;
		param.append(str(aerosol_mode)+&amp;quot; - aerosols model=maritime\n&amp;quot;)&lt;br /&gt;
		param.append(str(vis)+&amp;quot; - visibility [km] (aerosol model concentration), not used as there is raster input\n&amp;quot;)&lt;br /&gt;
		param.append(str(alt)+&amp;quot; - mean target elevation above sea level [km] (here 600m asl), not used as there is raster input\n&amp;quot;)&lt;br /&gt;
		param.append(str(sens_height)+&amp;quot; - sensor height (here, sensor on board a satellite)\n&amp;quot;)&lt;br /&gt;
		param.append(str(satbandno)+&amp;quot; - i th band of ETM+ Landsat 7 (atcorr internal no)\n&amp;quot;)&lt;br /&gt;
		f=open(os.path.join(L7Dir,&amp;quot;param_L7.txt&amp;quot;),&amp;quot;w&amp;quot;)&lt;br /&gt;
		f.writelines(param)&lt;br /&gt;
		f.close()&lt;br /&gt;
		prm=os.path.join(L7Dir,&amp;quot;param_L7.txt&amp;quot;)&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,b&lt;br /&gt;
		print &amp;quot;\t&amp;gt; &amp;quot;,b_out&lt;br /&gt;
		i.atcorr(input=b, elevation=&amp;quot;dem&amp;quot;, visibility=&amp;quot;vis&amp;quot;, parameters=prm, output=b_out, flags=&amp;quot;ra&amp;quot;, range=[0,1],quiet=QIET,overwrite=OVR)&lt;br /&gt;
		r.timestamp(map=b_out,date=timestamp,finish_=False)&lt;br /&gt;
		satbandno = satbandno + 1&lt;br /&gt;
&lt;br /&gt;
	#Allocate surface reflectance names&lt;br /&gt;
	b1=pref[:-2]+&amp;quot;.surf.1&amp;quot;&lt;br /&gt;
	b2=pref[:-2]+&amp;quot;.surf.2&amp;quot;&lt;br /&gt;
	b3=pref[:-2]+&amp;quot;.surf.3&amp;quot;&lt;br /&gt;
	b4=pref[:-2]+&amp;quot;.surf.4&amp;quot;&lt;br /&gt;
	b5=pref[:-2]+&amp;quot;.surf.5&amp;quot;&lt;br /&gt;
	b61=pref[:-2]+&amp;quot;.toar.61&amp;quot;&lt;br /&gt;
	b62=pref[:-2]+&amp;quot;.toar.62&amp;quot;&lt;br /&gt;
	b7=pref[:-2]+&amp;quot;.surf.7&amp;quot;&lt;br /&gt;
	b8=pref[:-2]+&amp;quot;.surf.8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	### PART 1: BASIC STUFF ###&lt;br /&gt;
	b_in=pref[:-2]+&amp;quot;.toar.&amp;quot;&lt;br /&gt;
	b_clouds=pref[:-2]+&amp;quot;.toar.acca&amp;quot;&lt;br /&gt;
	print &amp;quot;Clouds:\t\t&amp;gt;&amp;quot;,b_clouds&lt;br /&gt;
	i.landsat_acca(input_prefix=b_in,output=b_clouds,overwrite=OVR)&lt;br /&gt;
	#png_clouds=L7Dir+&amp;quot;/&amp;quot;+pref[:-2]+&amp;quot;.clouds.png&amp;quot;&lt;br /&gt;
	#d.mon(start='png',output=png_clouds,width=800,height=800)&lt;br /&gt;
	print &amp;quot;MASK:\t\tON&amp;quot;&lt;br /&gt;
	#Should always be rewritten!&lt;br /&gt;
	r.mask(raster=b_clouds,flags=&amp;quot;i&amp;quot;,overwrite=True)&lt;br /&gt;
&lt;br /&gt;
	b_ndvi=pref[:-2]+&amp;quot;.surf.ndvi&amp;quot;&lt;br /&gt;
	print &amp;quot;NDVI:\t&amp;quot;,b_ndvi&lt;br /&gt;
	i.vi(red=b3,nir=b4,output=b_ndvi,viname=&amp;quot;ndvi&amp;quot;,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
&lt;br /&gt;
	b_in=[b1,b2,b3,b4,b5,b7]&lt;br /&gt;
	b_albedo=pref[:-2]+&amp;quot;.surf.albedo&amp;quot;&lt;br /&gt;
	print &amp;quot;Albedo:\t&amp;quot;,b_albedo&lt;br /&gt;
	i.albedo(input=b_in,output=b_albedo,flags=&amp;quot;lc&amp;quot;,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
	&lt;br /&gt;
	b_emissivity=pref[:-2]+&amp;quot;.surf.emissivity&amp;quot;&lt;br /&gt;
	print &amp;quot;Emissivity:\t&amp;quot;,b_emissivity&lt;br /&gt;
	i.emissivity(input=b_ndvi, output=b_emissivity,quiet=QIET,overwrite=OVR,finish_=False)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Already tested modules ===&lt;br /&gt;
&lt;br /&gt;
{{Python}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Python/Closures&amp;diff=19699</id>
		<title>Python/Closures</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Python/Closures&amp;diff=19699"/>
		<updated>2013-09-09T19:32:52Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: Add a new page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=Why are useful=&lt;br /&gt;
A closure is a way to define a variable statically into a function. They are good to:&lt;br /&gt;
* Replace hard coded constants;&lt;br /&gt;
* Eliminate globals.&lt;br /&gt;
&lt;br /&gt;
=Some examples=&lt;br /&gt;
&lt;br /&gt;
Define a function that return another function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def print_something(msg):&lt;br /&gt;
    def _print(var):&lt;br /&gt;
        print msg % var&lt;br /&gt;
    return _print&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we can use to instantiate the function and define the string formatting statically and then call the returned function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; p = print_something('Hi %s!')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; p('Pietro')&lt;br /&gt;
Hi Pietro!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now a more interesting example for the grass users:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.modules import Module&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def get_module(cmd):&lt;br /&gt;
    mod = Module(cmd)&lt;br /&gt;
&lt;br /&gt;
    def do(**kwargs):&lt;br /&gt;
        mod(**kwargs)&lt;br /&gt;
    return do&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If we test the speed of a GRASS module, using ipython I got:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; %timeit Module('g.region', flags='p')&lt;br /&gt;
10 loops, best of 3: 30.8 ms per loop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead, using the python closure, I got:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; greg = get_module('g.region')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; %timeit greg(flags='p')&lt;br /&gt;
100 loops, best of 3: 12.8 ms per loop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: This example doesn't work with multiprocessing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [http://ynniv.com/blog/2007/08/closures-in-python.html Closures in Python]&lt;br /&gt;
* [http://www.shutupandship.com/2012/01/python-closures-explained.html Python closures explained]&lt;br /&gt;
* [http://effbot.org/zone/closure.htm Closure]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=17913</id>
		<title>Python/pygrass</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=17913"/>
		<updated>2013-02-15T10:47:43Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: Add workshops material&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''pygrass'' is a library that extends the GRASS capabilities to allow users to access the low-level GRASS API.&lt;br /&gt;
&lt;br /&gt;
== Workshops ==&lt;br /&gt;
&lt;br /&gt;
=== XIV Italian meeting of GRASS and GFOSS users ===&lt;br /&gt;
&lt;br /&gt;
Two workshops were presented during the [http://geomorfolab.arch.unige.it/genova2013/ XIV Italian meeting of GRASS] at Genova.&lt;br /&gt;
The workshops use '''ipython notebook''' to show the python and pygrass API, all the material are available on github ([https://github.com/zarch/workshop-python python], [https://github.com/zarch/workshop-pygrass pygrass]). All the execute examples are reported here:&lt;br /&gt;
&lt;br /&gt;
* python&lt;br /&gt;
** [http://www.ing.unitn.it/~zambelli/workshop/python/python-DataTypes.html Data Types]&lt;br /&gt;
** [http://www.ing.unitn.it/~zambelli/workshop/python/python-Syntax.html Syntax]&lt;br /&gt;
** [http://www.ing.unitn.it/~zambelli/workshop/python/python-Function.html Function]&lt;br /&gt;
** [http://www.ing.unitn.it/~zambelli/workshop/python/python-Class.html Class]&lt;br /&gt;
** [http://www.ing.unitn.it/~zambelli/workshop/python/python-Other.html Other]&lt;br /&gt;
&lt;br /&gt;
* pygrass&lt;br /&gt;
** [http://www.ing.unitn.it/~zambelli/workshop/pygrass/pygrass-Modules.html Modules]&lt;br /&gt;
** [http://www.ing.unitn.it/~zambelli/workshop/pygrass/pygrass-GIS.html GIS]&lt;br /&gt;
** [http://www.ing.unitn.it/~zambelli/workshop/pygrass/pygrass-Vector.html Vector]&lt;br /&gt;
** [http://www.ing.unitn.it/~zambelli/workshop/pygrass/pygrass-Raster.html Raster]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to test library ==&lt;br /&gt;
&lt;br /&gt;
''pygrass'' has doctest inside its code. You can run doctest inside the [http://grass.osgeo.org/sampledata/north_carolina/nc_basic_spm_grass7.tar.gz North Carolina basic location], using the mapset '''user1'''. &lt;br /&gt;
&lt;br /&gt;
To test the single module (file) you have to move to the source code of pygrass and run the following code (this is an example of functions.py):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 python -m doctest functions.py&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Already tested modules ===&lt;br /&gt;
&lt;br /&gt;
==== Working ====&lt;br /&gt;
&lt;br /&gt;
* functions.py&lt;br /&gt;
* gis/region.py&lt;br /&gt;
* gis/__init__.py&lt;br /&gt;
* modules/__init.py&lt;br /&gt;
* vector/abstract.py&lt;br /&gt;
* vector/__init__.py&lt;br /&gt;
* vector/basic.py&lt;br /&gt;
* vector/table.py&lt;br /&gt;
* vector/geometry.py&lt;br /&gt;
* raster/abstract.py&lt;br /&gt;
&lt;br /&gt;
==== Not working ====&lt;br /&gt;
&lt;br /&gt;
{{Python}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_and_Python&amp;diff=17666</id>
		<title>GRASS and Python</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_and_Python&amp;diff=17666"/>
		<updated>2013-02-03T17:11:45Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Python Scripting Library */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Python SIGs==&lt;br /&gt;
Python Special Interest Groups are focused collaborative efforts to develop, improve, or maintain specific Python resources. Each SIG has a charter, a coordinator, a mailing list, and a directory on the Python website. SIG membership is informal, defined by subscription to the SIG's mailing list. Anyone can join a SIG, and participate in the development discussions via the SIG's mailing list. Below is the list of currently active Python SIGs, with links to their resources. &lt;br /&gt;
&lt;br /&gt;
See more at http://www.python.org/community/sigs/&lt;br /&gt;
&lt;br /&gt;
==Writing Python scripts in GRASS==&lt;br /&gt;
&lt;br /&gt;
Python is a programming language which is more powerful than shell scripting but easier and more forgiving than C.&lt;br /&gt;
The Python script can contain simple module description definitions which will be processed with {{cmd|g.parser}}, as shown in the example below. In this way with no extra coding a GUI can be built, inputs checked, and a skeleton help page can be generated automatically. In addition it adds links to the GRASS message translation system. The library for &amp;quot;scripting&amp;quot; is &amp;quot;grass.script&amp;quot;, typically used as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The related files are at $GISBASE/etc/python/grass/script/*.py. See below for more details.&lt;br /&gt;
&lt;br /&gt;
''Note: For code which needs access to the power of C, you can access the GRASS C library functions via [[GRASS and Python#Python Ctypes Interface|the Python &amp;quot;ctypes&amp;quot; interface]].''&lt;br /&gt;
&lt;br /&gt;
=== Python script editor ===&lt;br /&gt;
&lt;br /&gt;
The [[wxGUI]] Layer Manager in GRASS 6.4.3+ comes with a &amp;quot;Python shell&amp;quot; which enables users to type and execute python commands directly in wxGUI environment.&lt;br /&gt;
&lt;br /&gt;
[[Image:wxgui-pyshell.png|center|350px|Embedded interactive Python Shell in wxGUI Layer Manager]]&lt;br /&gt;
&lt;br /&gt;
=== Using the GRASS Python Scripting Library ===&lt;br /&gt;
&lt;br /&gt;
You can run Python scripts easily in a GRASS session.&lt;br /&gt;
&lt;br /&gt;
To write these scripts, &lt;br /&gt;
* check the code in lib/python/ which provides grass.script in order to support GRASS scripts written in Python.&amp;lt;br&amp;gt;&lt;br /&gt;
  See the [[GRASS Python Scripting Library]] for notes and examples.&lt;br /&gt;
* The scripts/ directory of GRASS contains a series of examples actually provided to the end users.&lt;br /&gt;
&lt;br /&gt;
For the desired Python code style, have a look at {{src|SUBMITTING_PYTHON}}.&lt;br /&gt;
&lt;br /&gt;
=== Creating Python scripts that call GRASS functionality from outside ===&lt;br /&gt;
&lt;br /&gt;
Note: This is a more advanced use case of using GRASS' functionality from outside via Python. Commonly, a user will run GRASS Python script from inside a GRASS session, i.e. either from the command line or from the Python shell embedded in the wxGUI ([[:File:Wxgui-pyshell.png|screenshot]]).&lt;br /&gt;
&lt;br /&gt;
For calling GRASS functionality from outside, see also [[Working with GRASS without starting it explicitly]].&lt;br /&gt;
&lt;br /&gt;
==== MS-Windows ====&lt;br /&gt;
&lt;br /&gt;
In order to use GRASS functionality via Python from outside, some environment variables have to be set:&lt;br /&gt;
&lt;br /&gt;
 GISBASE= C:\GRASS-64&lt;br /&gt;
 GISRC= C:\Documents and Settings\user\.grassrc6&lt;br /&gt;
 LD_LIBRARY_PATH= C:\GRASS-64\lib&lt;br /&gt;
 PATH= C:\GRASS-64\etc;C:\GRASS-64\etc\python;C:\GRASS-64\lib;C:\GRASS-64\bin;C:\GRASS-64\extralib;C:\GRASS-64\msys\bin;C:\Python26;&lt;br /&gt;
 PYTHONLIB= C:\Python26&lt;br /&gt;
 PYTHONPATH= C:\GRASS-64\etc\python&lt;br /&gt;
 GRASS_SH= C:\GRASS-64\msys\bin\sh.exe&lt;br /&gt;
&lt;br /&gt;
Some hints:&lt;br /&gt;
&lt;br /&gt;
# The &amp;quot;.grassrc6&amp;quot; file listed above must exist. Run GRASS one time interactively to create it or see below for how to writing it&lt;br /&gt;
# The Python interpreter (python.exe) needs to be in the PATH&lt;br /&gt;
# Python needs to be associated with the .py extension&lt;br /&gt;
# PATHEXT needs to include .py if you want to be able to omit the extension&lt;br /&gt;
# PYTHONPATH needs to be set to %GISBASE%\etc\python&lt;br /&gt;
&lt;br /&gt;
Points 2-4 should be taken care of by the Python installer. 5 needs to be done by the startup (currently, this doesn't appear to be the case on MS-Windows).&lt;br /&gt;
&lt;br /&gt;
Alternatively to run GRASS interactively, you can also create the &amp;quot;.grassrc6&amp;quot; file yourself, e.g. (update to existing directory for &amp;quot;grassdata&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
 GISDBASE: C:\Documents and Settings\user\grassdata&lt;br /&gt;
 LOCATION_NAME: nc_spm_08&lt;br /&gt;
 MAPSET: user1&lt;br /&gt;
 GRASS_DB_ENCODING: ascii&lt;br /&gt;
&lt;br /&gt;
It doesn't matter what the file is called, so long as %GISRC% points to it and it contains the necessary settings.&lt;br /&gt;
&lt;br /&gt;
The normal location for GRASS 6.x on Windows is:&lt;br /&gt;
&lt;br /&gt;
 %APPDATA%\GRASS6\grassrc6&lt;br /&gt;
&lt;br /&gt;
On Windows 7, a typical setting for %APPDATA% is&lt;br /&gt;
&lt;br /&gt;
 C:\Users\&amp;lt;username&amp;gt;\AppData\Roaming&lt;br /&gt;
&lt;br /&gt;
==== Linux ====&lt;br /&gt;
&lt;br /&gt;
In order to use GRASS functionality via Python from outside, some environment variables have to be set:&lt;br /&gt;
&lt;br /&gt;
 export GISBASE=&amp;quot;/usr/local/grass-6.4.svn/&amp;quot;&lt;br /&gt;
 export PATH=&amp;quot;$PATH:$GISBASE/bin:$GISBASE/scripts&amp;quot;&lt;br /&gt;
 export LD_LIBRARY_PATH=&amp;quot;$LD_LIBRARY_PATH:$GISBASE/lib&amp;quot;&lt;br /&gt;
 # for parallel session management, we use process ID (PID) as lock file number:&lt;br /&gt;
 export GIS_LOCK=$$&lt;br /&gt;
 # path to GRASS settings file&lt;br /&gt;
 export GISRC=&amp;quot;$HOME/.grassrc6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Running external commands from Python ===&lt;br /&gt;
For information on running external commands from Python, see:&lt;br /&gt;
http://docs.python.org/lib/module-subprocess.html&lt;br /&gt;
&lt;br /&gt;
Avoid using the older os.* functions. Section 17.1.3 lists equivalents&lt;br /&gt;
using the Popen() interface, which is more robust (particularly on&lt;br /&gt;
Windows).&lt;br /&gt;
&lt;br /&gt;
=== Testing and installing Python extensions ===&lt;br /&gt;
&lt;br /&gt;
==== Debugging ====&lt;br /&gt;
&lt;br /&gt;
Make sure the script is executable:&lt;br /&gt;
&lt;br /&gt;
    chmod +x /path/to/my.extension.py&lt;br /&gt;
&lt;br /&gt;
During development, a Python script can be debugged using the Python Debugger (pdb):&lt;br /&gt;
&lt;br /&gt;
    python -m pdb /path/to/my.extension.py input=my_input_layer output=my_output_layer option=value -f&lt;br /&gt;
&lt;br /&gt;
==== Installation ====&lt;br /&gt;
&lt;br /&gt;
Once you're happy with your script, you can put it in the scripts/ folder of your GRASS install. To do so, first create a directory named after your extension, then create a Makefile for it, and a HTML man page:&lt;br /&gt;
&lt;br /&gt;
    cd /path/to/grass_src/&lt;br /&gt;
    cd scripts&lt;br /&gt;
    ls # It is useful to check out the existing scripts and their structure&lt;br /&gt;
    mkdir my.extension&lt;br /&gt;
    cd my.extension&lt;br /&gt;
    cp path/to/my.extension.py .&lt;br /&gt;
    touch my.extension.html&lt;br /&gt;
    touch Makefile&lt;br /&gt;
&lt;br /&gt;
Next step is to edit the Makefile. It is a very simple text file, the only thing to check is to put the right extension name (WITHOUT the .py file extension) after PGM:&lt;br /&gt;
&lt;br /&gt;
    MODULE_TOPDIR = ../..&lt;br /&gt;
    &lt;br /&gt;
    PGM = my.extension&lt;br /&gt;
    &lt;br /&gt;
    include $(MODULE_TOPDIR)/include/Make/Script.make&lt;br /&gt;
    &lt;br /&gt;
    default: script&lt;br /&gt;
&lt;br /&gt;
The HTML file would be generated automatically. If you want to add more precisions in it, you can do it (just make sure you start at DESCRIPTION. See existing scripts.)&lt;br /&gt;
&lt;br /&gt;
You can then run &amp;quot;make&amp;quot; within the my.extension folder. Running &amp;quot;make&amp;quot; in the extension directory places the resulting files in the staging directory (path/to/grass_src/dist.&amp;lt;YOUR_ARCH&amp;gt;/). If you're running GRASS from the staging directory (/path/to/grass_src/bin.&amp;lt;YOUR_ARCH&amp;gt;/grass7), subsequent commands will used the updated files. &lt;br /&gt;
&lt;br /&gt;
    # in your extension directory (/path/to/grass_src/scripts/my.extension/)&lt;br /&gt;
    make&lt;br /&gt;
    # Starting GRASS from the staging directory&lt;br /&gt;
    /path/to/grass_src/bin.&amp;lt;YOUR_ARCH&amp;gt;/grass7&lt;br /&gt;
    my.extension help&lt;br /&gt;
&lt;br /&gt;
You can also run &amp;quot;make install&amp;quot; from the top level directory of your GRASS install (say /usr/local/src/grass_trunk/). Running &amp;quot;make install&amp;quot; from the top level just copies the whole of the dist.&amp;lt;YOUR_ARCH&amp;gt;/ directory to the installation directory (e.g. /usr/local/grass70) and the bin.&amp;lt;YOUR_ARCH&amp;gt;/grass70 bin file to the bin directory (e.g. /usr/local/bin), and fixes any embedded paths in scripts and configuration files.&lt;br /&gt;
&lt;br /&gt;
    cd /path/to/grass_src&lt;br /&gt;
    make install&lt;br /&gt;
    # Starting GRASS as usual would work and show your extension available&lt;br /&gt;
    grass7&lt;br /&gt;
    my.extension help&lt;br /&gt;
&lt;br /&gt;
==Python extensions in GRASS GIS==&lt;br /&gt;
&lt;br /&gt;
=== Python Scripting Library ===&lt;br /&gt;
&lt;br /&gt;
* See [[GRASS Python Scripting Library]]&lt;br /&gt;
&lt;br /&gt;
=== pygrass Library ===&lt;br /&gt;
&lt;br /&gt;
* See [[Python/pygrass|pygrass]]&lt;br /&gt;
&lt;br /&gt;
=== Python Ctypes Interface ===&lt;br /&gt;
&lt;br /&gt;
This interface allows calling GRASS library functions from Python scripts. See [[Python Ctypes Examples]] for details.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
* GRASS 7: [http://trac.osgeo.org/grass/browser/grass/trunk/doc/python/raster_example_ctypes.py raster], [http://trac.osgeo.org/grass/browser/grass/trunk/doc/python/vector_example_ctypes.py vector] example&lt;br /&gt;
&lt;br /&gt;
* Latest and greatest: GRASS 7 Python {{src|scripts}}&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;[[PythonSwigExamples|More complicated examples]]&amp;lt;/strike&amp;gt; &amp;lt;&amp;lt;-- TODO: update to Ctypes&lt;br /&gt;
&lt;br /&gt;
Sample script for GRASS 6 raster access (use within GRASS, Spearfish session):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
## TODO: update example to Ctypes&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
from grass.lib import grass&lt;br /&gt;
&lt;br /&gt;
if &amp;quot;GISBASE&amp;quot; not in os.environ:&lt;br /&gt;
    print &amp;quot;You must be in GRASS GIS to run this program.&amp;quot;&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
if len(sys.argv)==2:&lt;br /&gt;
  input = sys.argv[1]&lt;br /&gt;
else:&lt;br /&gt;
  input = raw_input(&amp;quot;Raster Map Name? &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# initialize&lt;br /&gt;
grass.G_gisinit('')&lt;br /&gt;
&lt;br /&gt;
# find map in search path&lt;br /&gt;
mapset = grass.G_find_cell2(input, '')&lt;br /&gt;
&lt;br /&gt;
# determine the inputmap type (CELL/FCELL/DCELL) */&lt;br /&gt;
data_type = grass.G_raster_map_type(input, mapset)&lt;br /&gt;
&lt;br /&gt;
infd = grass.G_open_cell_old(input, mapset)&lt;br /&gt;
inrast = grass.G_allocate_raster_buf(data_type)&lt;br /&gt;
&lt;br /&gt;
rown = 0&lt;br /&gt;
while True:&lt;br /&gt;
    myrow = grass.G_get_raster_row(infd, inrast, rown, data_type)&lt;br /&gt;
    print rown, myrow[0:10]&lt;br /&gt;
    rown += 1&lt;br /&gt;
    if rown == 476:&lt;br /&gt;
        break&lt;br /&gt;
&lt;br /&gt;
grass.G_close_cell(inrast)&lt;br /&gt;
grass.G_free(cell)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample script for vector access (use within GRASS, Spearfish session):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
# run within GRASS Spearfish session&lt;br /&gt;
# run this before starting python to append module search path:&lt;br /&gt;
#   export PYTHONPATH=/usr/src/grass70/swig/python&lt;br /&gt;
#   check with &amp;quot;import sys; sys.path&amp;quot;&lt;br /&gt;
# or:&lt;br /&gt;
#   sys.path.append(&amp;quot;/usr/src/grass70/swig/python&amp;quot;)&lt;br /&gt;
# FIXME: install the grass bindings in $GISBASE/lib/ ?&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
from grass.lib import grass&lt;br /&gt;
from grass.lib import vector as grassvect&lt;br /&gt;
&lt;br /&gt;
if &amp;quot;GISBASE&amp;quot; not in os.environ:&lt;br /&gt;
    print &amp;quot;You must be in GRASS GIS to run this program.&amp;quot;&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
if len(sys.argv)==2:&lt;br /&gt;
  input = sys.argv[1]&lt;br /&gt;
else:&lt;br /&gt;
  input = raw_input(&amp;quot;Vector Map Name? &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# initialize&lt;br /&gt;
grass.G_gisinit('')&lt;br /&gt;
&lt;br /&gt;
# find map in search path&lt;br /&gt;
mapset = grass.G_find_vector2(input,'')&lt;br /&gt;
&lt;br /&gt;
# define map structure&lt;br /&gt;
map = grassvect.Map_info()&lt;br /&gt;
&lt;br /&gt;
# define open level (level 2: topology)&lt;br /&gt;
grassvect.Vect_set_open_level (2)&lt;br /&gt;
&lt;br /&gt;
# open existing map&lt;br /&gt;
grassvect.Vect_open_old(map, input, mapset)&lt;br /&gt;
&lt;br /&gt;
# query&lt;br /&gt;
print 'Vect map: ', input&lt;br /&gt;
print 'Vect is 3D: ', grassvect.Vect_is_3d (map)&lt;br /&gt;
print 'Vect DB links: ', grassvect.Vect_get_num_dblinks(map)&lt;br /&gt;
print 'Map Scale:  1:', grassvect.Vect_get_scale(map)&lt;br /&gt;
print 'Number of areas:', grassvect.Vect_get_num_areas(map)&lt;br /&gt;
&lt;br /&gt;
# close map&lt;br /&gt;
grassvect.Vect_close(map)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== wxPython GUI development ===&lt;br /&gt;
&lt;br /&gt;
* See the [[wxGUI]] wiki page&lt;br /&gt;
&lt;br /&gt;
=== Python-GRASS add-ons ===&lt;br /&gt;
&lt;br /&gt;
Stand-alone addons:&lt;br /&gt;
&lt;br /&gt;
* Jáchym Čepický's PyWPS, GRASS-Web Processing Service (http://pywps.wald.intevation.org)&lt;br /&gt;
&lt;br /&gt;
=== Using GRASS gui.tcl in Python ===&lt;br /&gt;
&lt;br /&gt;
Here is some example code to use the grass automatically generated guis in python code. This could (should) all be bundled up and abstracted away so that the implementation can be replaced later.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import Tkinter&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
# Startup (once):&lt;br /&gt;
&lt;br /&gt;
tk = Tkinter.Tk()&lt;br /&gt;
tk.eval (&amp;quot;wm withdraw .&amp;quot;)&lt;br /&gt;
tk.eval (&amp;quot;source $env(GISBASE)/etc/gui.tcl&amp;quot;)&lt;br /&gt;
# Here you could do various things to change what the gui does&lt;br /&gt;
# See gui.tcl and README.GUI&lt;br /&gt;
&lt;br /&gt;
# Make a gui (per dialog)&lt;br /&gt;
# This sets up a window for the command.&lt;br /&gt;
# This can be different to integrate with tkinter:&lt;br /&gt;
tk.eval ('set path &amp;quot;.dialog$dlg&amp;quot;')&lt;br /&gt;
tk.eval ('toplevel .dialog$dlg')&lt;br /&gt;
# Load the code for this command:&lt;br /&gt;
fd = os.popen (&amp;quot;d.vect --tcltk&amp;quot;)&lt;br /&gt;
gui = fd.read()&lt;br /&gt;
# Run it&lt;br /&gt;
tk.eval(gui)&lt;br /&gt;
dlg = tk.eval('set dlg') # This is used later to get and set &lt;br /&gt;
&lt;br /&gt;
# Get the current command in the gui we just made:&lt;br /&gt;
currentcommand = tk.eval (&amp;quot;dialog_get_command &amp;quot; + dlg)&lt;br /&gt;
&lt;br /&gt;
# Set the command in the dialog we just made:&lt;br /&gt;
tk.eval (&amp;quot;dialog_set_command &amp;quot; + dlg + &amp;quot; {d.vect map=roads}&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
* '''Q:''' Error message &amp;quot;execl() failed: Permission denied&amp;quot; - what to do?&lt;br /&gt;
: '''A:''' Be sure that the execute bit of the script is set.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
=== General guides ===&lt;br /&gt;
&lt;br /&gt;
* [http://en.wikibooks.org/wiki/Python_Programming/ Wikibook Python Programming]&lt;br /&gt;
* [http://www.poromenos.org/tutorials/python Quick Python tutorial] for programmers of other languages&lt;br /&gt;
*: [http://wiki.python.org/moin/BeginnersGuide/Programmers More Python tutorials] for programmers&lt;br /&gt;
* [http://www.python.org/dev/peps/pep-0008/ Python programming style guide]&lt;br /&gt;
* [http://wiki.python.org/moin/PythonEditors Python Editors]&lt;br /&gt;
&lt;br /&gt;
=== Programming ===&lt;br /&gt;
&lt;br /&gt;
* Python and GRASS:&lt;br /&gt;
** Library interfaces: [GRASS Python Scripting Library http://grass.osgeo.org/programming7/pythonlib.html]&lt;br /&gt;
** Graphical user interface (GIU): [GRASS wxPython-based GUI http://grass.osgeo.org/programming7/wxpythonlib.html]&lt;br /&gt;
** PyWPS, GRASS-Web Processing Service: [[WPS]]&lt;br /&gt;
&lt;br /&gt;
* Python and OSGeo:&lt;br /&gt;
** [http://wiki.osgeo.org/wiki/OSGeo_Python_Library OSGeo Python Library]&lt;br /&gt;
&lt;br /&gt;
* Python and GDAL/OGR:&lt;br /&gt;
** [http://mapserver.gis.umn.edu/community/conferences/MUM3/workshop/python Open Source Python GIS Hacks Mum'03]&lt;br /&gt;
** http://hobu.biz/software/OSGIS_Hacks - Python OSGIS Hacks '05&lt;br /&gt;
** http://zcologia.com/news/categorylist_html?cat_id=8&lt;br /&gt;
** http://www.perrygeo.net/wordpress/?p=4&lt;br /&gt;
&lt;br /&gt;
* Python bindings to PROJ:&lt;br /&gt;
** http://www.cdc.noaa.gov/people/jeffrey.s.whitaker/python/pyproj.html&lt;br /&gt;
&lt;br /&gt;
* Python and GIS:&lt;br /&gt;
** [http://gispython.org/ Open Source GIS-Python Laboratory]&lt;br /&gt;
&lt;br /&gt;
* Python and Statistics:&lt;br /&gt;
** [http://rpy.sourceforge.net/ RPy] - Python interface to the R-statistics programming language&lt;br /&gt;
&lt;br /&gt;
* Bindings:&lt;br /&gt;
** SIP (C/C++ bindings generator) http://directory.fsf.org/all/Python-SIP.html&lt;br /&gt;
** [http://www.cython.org/ Cython] - C-Extensions for Python (compile where speed is needed)&lt;br /&gt;
&lt;br /&gt;
* Other external projects&lt;br /&gt;
** [http://www.scipy.org Scientific Python]&lt;br /&gt;
** [http://wiki.python.org/moin/NumericAndScientific Numeric and Scientific]&lt;br /&gt;
** [http://w3.pppl.gov/~hammett/comp/python/python.html Info on Python for Scientific Applications]&lt;br /&gt;
&lt;br /&gt;
=== Presentations ===&lt;br /&gt;
&lt;br /&gt;
From FOSS4G2006:&lt;br /&gt;
* [http://www.foss4g2006.org/materialDisplay.py?contribId=136&amp;amp;amp;sessionId=48&amp;amp;amp;materialId=slides&amp;amp;amp;confId=1 A Python sweeps in the GRASS] - A. Frigeri 2006&lt;br /&gt;
* [http://www.foss4g2006.org/materialDisplay.py?contribId=67&amp;amp;amp;sessionId=48&amp;amp;amp;materialId=slides&amp;amp;amp;confId=1 GRASS goes web: PyWPS] - J. Cepicky 2006 (see also [[WPS]])&lt;br /&gt;
&lt;br /&gt;
{{Python}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=17665</id>
		<title>Python/pygrass</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Python/pygrass&amp;diff=17665"/>
		<updated>2013-02-03T17:09:20Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: Created page with &amp;quot;''pygrass'' it is a library that extent the GRASS capability allow users to access to the lower GRASS API.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''pygrass'' it is a library that extent the GRASS capability allow users to access to the lower GRASS API.&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_Community_Sprint_Genova_2013&amp;diff=17449</id>
		<title>GRASS Community Sprint Genova 2013</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_Community_Sprint_Genova_2013&amp;diff=17449"/>
		<updated>2013-01-07T22:17:55Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Participation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GRASS GIS team will organize a '''GRASS Developer and Power User Meeting, aka 'GRASS Community Sprint'''' from '''2-7 Feb, 2013'''. The sprint is at the same time of the [http://geomorfolab.arch.unige.it/genova2013/index.php?lang=en XIV Meeting degli Utenti Italiani Grass e Gfoss], 6-9 Feb 2013, University of Genova, Dipartimento di Scienze per l'Architettura della Scuola Politecnica, [http://en.wikipedia.org/wiki/Genoa Genova], [http://en.wikipedia.org/wiki/Italy Italy].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
This next edition of the GRASS GIS community sprint 2013 is a great occasion for folks to support the development by actively contributing to the source code, manuals or likewise. The '''community''' sprint is a get-together for GRASS project members and supporters and related [http://www.osgeo.org/ OSGeo] projects to make decisions and tackle larger problems. For this meeting, we welcome people committed to improving the GRASS GIS project and the interfaces to [[QGIS GRASS Cookbook|QGIS]], [[GDAL]], [[PostGIS]], [[R statistics]], [[GRASS and Sextante|Sextante, gvSIG]], OGC Services (esp. [[WPS]]) and more. This includes developers, documenters, bug reporters, translators and others.&lt;br /&gt;
&lt;br /&gt;
For this meeting, we welcome people committed to improving the GRASS GIS and related projects. This includes developers, document writers, wish and bug reporters, translators etc.&lt;br /&gt;
&lt;br /&gt;
== Sponsors ==&lt;br /&gt;
&lt;br /&gt;
We welcome '''financial contributions''' to support the meeting and we are looking for '''sponsors''' to cover costs such as meals or to help reducing travelling and accommodation expenses for GRASS developers with far arrival. If you are interested to sponsor the GRASS Community Sprint, please read about&lt;br /&gt;
&lt;br /&gt;
:::'''sponsoring the GRASS project at [http://grass.osgeo.org/donations/ http://grass.osgeo.org/donations/]'''&lt;br /&gt;
&lt;br /&gt;
For questions, please contact [[User:Lucadelu|Luca Delucchi]] &amp;lt;tt&amp;gt;&amp;lt;lucadeluge at gmail.com&amp;gt;&amp;lt;/tt&amp;gt;. Any surplus at the end of the event will be turned over to the GRASS GIS project.&lt;br /&gt;
&lt;br /&gt;
The third GRASS Community Sprint is a great occasion for you to support the development of GRASS. With your contribution you'll enable more developers to meet. The community sprint is an important opportunity for the GRASS developers to discuss and collaboratively resolve bugs, plan the direction for the project and work on new features. Please see below for the more detailed agenda. The developers and contributors are donating their valuable time, so it would be great if in-kind funding can be made available from within the community to cover out-of-pocket expenses. All of the work that takes place at the community sprint will be directly contributed back into the GRASS project to the benefit of everyone who uses it.&lt;br /&gt;
&lt;br /&gt;
== Timing  ==&lt;br /&gt;
&lt;br /&gt;
'''When''': 2-7 Feb, 2013&lt;br /&gt;
&lt;br /&gt;
Of course you are invited to join or leave the community sprint whenever you want.&lt;br /&gt;
&lt;br /&gt;
'''Duration''': 6 days&lt;br /&gt;
&lt;br /&gt;
== Venue ==&lt;br /&gt;
&lt;br /&gt;
For the 2nd and 3rd of February we are hosted by the [http://www.alid.it ALID association] at Circolo Zenzero in [http://osm.org/go/xX0m6qo~B-- Via Torti 35, Genova] (in Italy universities are closed during weekends).&lt;br /&gt;
&lt;br /&gt;
From 4th to 7th at University of Genova, Dipartimento di Scienze per l'Architettura della Scuola Politecnica, Genova, Italy.&lt;br /&gt;
&lt;br /&gt;
'''[http://geomorfolab.arch.unige.it/ Geomorfolab]''',&lt;br /&gt;
Dipartimento di Scienze per l'Architettura,&lt;br /&gt;
Scuola Politecnica - Università degli Studi di Genova,&lt;br /&gt;
[http://osm.org/go/xX0ml6cj7-- Stradone S. Agostino 37, 16128 Genova]&lt;br /&gt;
&lt;br /&gt;
Rooms: TBD&lt;br /&gt;
&lt;br /&gt;
== Accommodation and Costs ==&lt;br /&gt;
&lt;br /&gt;
* Bed and breakfast (few rooms) - close to venue (please contact [[User:Lucadelu|Luca Delucchi]] &amp;lt;tt&amp;gt;&amp;lt;lucadeluge at gmail.com&amp;gt;&amp;lt;/tt&amp;gt;)&lt;br /&gt;
* New youth hostel, http://www.manenahostel.it/ - close to venue (please contact [[User:Lucadelu|Luca Delucchi]] &amp;lt;tt&amp;gt;&amp;lt;lucadeluge at gmail.com&amp;gt;&amp;lt;/tt&amp;gt;)&lt;br /&gt;
* List of [http://geomorfolab.arch.unige.it/genova2013/index.php?option=com_content&amp;amp;view=article&amp;amp;id=42&amp;amp;Itemid=18 Site of XIV Meeting degli utenti italiani GRASS e GFOSS]&lt;br /&gt;
&lt;br /&gt;
== Weather and Common Item Prices ==&lt;br /&gt;
&lt;br /&gt;
== Agenda == &lt;br /&gt;
&lt;br /&gt;
=== Timeline ===&lt;br /&gt;
&lt;br /&gt;
==== Saturday, 2 Feb ====&lt;br /&gt;
* Kick-off in the [http://www.alid.it ALID association] at Circolo Zenzero in [http://osm.org/go/xX0m6qo~B-- Via Torti 35, Genova]&lt;br /&gt;
* Participants presentation&lt;br /&gt;
* Dinner: at Circolo Zenzero&lt;br /&gt;
&lt;br /&gt;
==== Sunday, 3 Feb ====&lt;br /&gt;
* 9:00-evening&lt;br /&gt;
* Meeting again in the at Circolo Zenzero&lt;br /&gt;
&lt;br /&gt;
List of topics:&lt;br /&gt;
* TBD&lt;br /&gt;
* Dinner: at Circolo Zenzero&lt;br /&gt;
&lt;br /&gt;
==== Monday, 4 Feb ====&lt;br /&gt;
* 9:00-evening&lt;br /&gt;
* Meeting at University of Genova, Dipartimento di Scienze per l'Architettura della Scuola Politecnica, Genova, Italy at the '''[http://geomorfolab.arch.unige.it/ Geomorfolab]''', [http://osm.org/go/xX0ml6cj7-- Stradone S. Agostino 37, 16128 Genova]&lt;br /&gt;
&lt;br /&gt;
List of topics:&lt;br /&gt;
* TBD&lt;br /&gt;
&lt;br /&gt;
==== Tuesday, 5 Feb ====&lt;br /&gt;
* 9:00-evening&lt;br /&gt;
* Meeting again at University of Genova, Geomorfolab&lt;br /&gt;
&lt;br /&gt;
List of topics:&lt;br /&gt;
* TBD&lt;br /&gt;
&lt;br /&gt;
==== Wednesday, 6 Feb ====&lt;br /&gt;
* 9:00-evening&lt;br /&gt;
* Meeting again at University of Genova, Geomorfolab&lt;br /&gt;
&lt;br /&gt;
List of topics:&lt;br /&gt;
* TBD&lt;br /&gt;
* Group photo!!&lt;br /&gt;
* Prepare press release&lt;br /&gt;
&lt;br /&gt;
==== Thursday, 7 Feb ====&lt;br /&gt;
* 9:00-evening&lt;br /&gt;
* Meeting again at University of Genova, Geomorfolab&lt;br /&gt;
&lt;br /&gt;
List of topics:&lt;br /&gt;
* TBD&lt;br /&gt;
* Prepare short presentations for Friday at the Italian GFOSS meeting&lt;br /&gt;
* Finish and publish press release&lt;br /&gt;
&lt;br /&gt;
Closing of community sprint&lt;br /&gt;
&lt;br /&gt;
==== Friday, 8 Feb ====&lt;br /&gt;
* Two hours of time for '''presenting Community Sprint results''' at Italian GFOSS meeting ([http://geomorfolab.arch.unige.it/genova2013/index.php?option=com_content&amp;amp;view=article&amp;amp;id=29&amp;amp;Itemid=21&amp;amp;lang=en venue])&lt;br /&gt;
&lt;br /&gt;
== Participation ==&lt;br /&gt;
&lt;br /&gt;
=== In person ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable sortable&amp;quot;   border=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;4&amp;quot; rules=&amp;quot;all&amp;quot; style=&amp;quot;margin:1em 1em 1em 0; border:solid 1px #AAAAAA; border-collapse:collapse; background-color:#edf9c7; font-size:95%; empty-cells:show;&amp;quot; &lt;br /&gt;
!width=50px|'''Number'''&lt;br /&gt;
!width=130px|'''Participant '''&lt;br /&gt;
!width=100px|'''Country'''&lt;br /&gt;
!width=100px|'''Arrival'''&lt;br /&gt;
!width=100px|'''Departure'''&lt;br /&gt;
!'''Topic'''&lt;br /&gt;
!width=75px|'''T-Shirt'''&lt;br /&gt;
!'''Notes'''&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|[[User:Lucadelu|Luca Delucchi]]&lt;br /&gt;
|Italy&lt;br /&gt;
| Feb 2&lt;br /&gt;
| Feb 10&lt;br /&gt;
|&lt;br /&gt;
| L&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|[[User:Neteler|Markus Neteler]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| M + S&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|[[User:Madi|Margherita Di Leo]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| L&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|[[User:pcav|Paolo Cavallini]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| L&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|[[User:lcasagrande|Luca Casagrande]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GRASS Tutorial with Open Data from Italy&lt;br /&gt;
| L&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|[[User:Annakrat|Anna Kratochvilova]]&lt;br /&gt;
|Czech Republic&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| M&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|Vaclav Petras&lt;br /&gt;
|Czech Republic&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| M&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|[[User:pietro|Pietro Zambelli]]&lt;br /&gt;
|Italy&lt;br /&gt;
| Feb 2&lt;br /&gt;
| Feb 9 &lt;br /&gt;
| Python and Pygrass workshops&lt;br /&gt;
| M&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
|[[User:Landa|Martin Landa]]&lt;br /&gt;
|Czech Republic&lt;br /&gt;
| Feb 2&lt;br /&gt;
| Feb 10&lt;br /&gt;
| [[wxGUI]], vector architecture, GRASS 7 development&lt;br /&gt;
| L&lt;br /&gt;
| Probably unable to come :-(&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|[[User:Maxi|Massimiliano Cannata]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| XL&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|11&lt;br /&gt;
|[[User:NikosA|Nikos Alexandris]]&lt;br /&gt;
|Greece&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GRASS-wiki, (re-)working on the idea for a practical &amp;amp; visual guide to GRASS-GIS, testing all landsat related (core + addons) modules&lt;br /&gt;
| M&lt;br /&gt;
| Will be there with Nikos V!&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|[[User:AnneGhisla|Anne Ghisla]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| fix v.krige, examine i.atcorr problems with RapidEye&lt;br /&gt;
| M&lt;br /&gt;
| Almost sure of participation&lt;br /&gt;
|-&lt;br /&gt;
|13&lt;br /&gt;
|[[User:vesnikos|Ves Nikos]]&lt;br /&gt;
|Greece&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| L&lt;br /&gt;
| Will try and come with Nikos Alexandris&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Via IRC chat ===&lt;br /&gt;
&lt;br /&gt;
: [irc://freenode/grass #grass] on Freenode&lt;br /&gt;
&lt;br /&gt;
For details, see [[IRC]]&lt;br /&gt;
&lt;br /&gt;
=== Collaborative document scratching ===&lt;br /&gt;
&lt;br /&gt;
== Individual Preparation ==&lt;br /&gt;
&lt;br /&gt;
* Bring your own computer&lt;br /&gt;
* Bring [http://en.wikipedia.org/wiki/Mains_electricity_by_country your power connector adapter] if needed ([http://en.wikipedia.org/wiki/File:L_plug.jpg Italy])&lt;br /&gt;
* Install subversion and the compiler tools, and come with a working GRASS development environment if possible.&lt;br /&gt;
&lt;br /&gt;
== Photos ==&lt;br /&gt;
&lt;br /&gt;
Also during the event :)&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
* How was it last time?&lt;br /&gt;
** Very cool, see [[GRASS Community Sprint Prague 2012]]!&lt;br /&gt;
* ''Is the GRASS Community Sprint just a coding event?''&lt;br /&gt;
** It is mainly a coding and documentation event. It is a working session for people who are already participants in the GRASS project and/or are committed to improving the GRASS project.&lt;br /&gt;
** On demand we can do some presentations of current working GRASS implementation and new upcoming features to spread the idea of Open Source GIS software&lt;br /&gt;
* ''Is the GRASS Community Sprint for developers only?''&lt;br /&gt;
** Not at all: anybody can help, with testing, checking out bugs and fixes, documentation and more.&lt;br /&gt;
* ''Where can I get help and more information about the community sprint?''&lt;br /&gt;
** Contact [[User:Lucadelu|Luca Delucchi]] &amp;lt;tt&amp;gt;&amp;lt;lucadeluge at gmail dot com&amp;gt;&amp;lt;/tt&amp;gt; or [[User:Neteler|Markus Neteler]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Workshops]]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_Community_Sprint_Genova_2013&amp;diff=16507</id>
		<title>GRASS Community Sprint Genova 2013</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_Community_Sprint_Genova_2013&amp;diff=16507"/>
		<updated>2012-10-06T14:14:57Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* In person */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GRASS GIS team will organize a '''GRASS Developer and Power User Meeting, aka 'GRASS Community Sprint'''' from '''2-7 Feb, 2013'''. The sprint is at the same time of the [http://geomorfolab.arch.unige.it/genova2013/ XIV Meeting degli Utenti Italiani Grass e Gfoss], 6-9 Feb 2013, University of Genova, Dipartimento di Scienze per l'Architettura della Scuola Politecnica, [http://en.wikipedia.org/wiki/Genoa Genova], [http://en.wikipedia.org/wiki/Italy Italy].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
This next edition of the GRASS GIS community sprint 2013 is a great occasion for folks to support the development by actively contributing to the source code, manuals or likewise. The '''community''' sprint is a get-together for GRASS project members and supporters and related [http://www.osgeo.org/ OSGeo] projects to make decisions and tackle larger problems. For this meeting, we welcome people committed to improving the GRASS GIS project and the interfaces to [[QGIS GRASS Cookbook|QGIS]], [[GDAL]], [[PostGIS]], [[R statistics]], [[GRASS and Sextante|Sextante, gvSIG]], OGC Services (esp. [[WPS]]) and more. This includes developers, documenters, bug reporters, translators and others.&lt;br /&gt;
&lt;br /&gt;
For this meeting, we welcome people committed to improving the GRASS GIS and related projects. This includes developers, document writers, wish and bug reporters, translators etc.&lt;br /&gt;
&lt;br /&gt;
== Sponsors ==&lt;br /&gt;
&lt;br /&gt;
We welcome financial contributions to support the meeting and we are looking for sponsors to cover costs such as meals or to help reducing travelling and accommodation expenses for GRASS developers with far arrival If you are interested to sponsor the GRASS Community Sprint, please read about&lt;br /&gt;
&lt;br /&gt;
:::'''sponsoring the GRASS project at [http://grass.osgeo.org/donation.php http://grass.osgeo.org/donation.php]'''&lt;br /&gt;
&lt;br /&gt;
and, if needed, contact [[User:Neteler|Markus Neteler]] &amp;lt;tt&amp;gt;&amp;lt;neteler at osgeo.org&amp;gt;&amp;lt;/tt&amp;gt;. Any surplus at the end of the event will be turned over to the GRASS GIS project.&lt;br /&gt;
&lt;br /&gt;
The third GRASS Community Sprint is a great occasion for you to support the development of GRASS. With your contribution you'll enable more developers to meet in Prague. The community sprint is an important opportunity for the GRASS developers to discuss and collaboratively resolve bugs, plan the direction for the project and work on new features. Please see below for the more detailed agenda. The developers and contributors are donating their valuable time, so it would be great if in-kind funding can be made available from within the community to cover out-of-pocket expenses. All of the work that takes place at the community sprint will be directly contributed back into the GRASS project to the benefit of everyone who uses it.&lt;br /&gt;
&lt;br /&gt;
== Timing  ==&lt;br /&gt;
&lt;br /&gt;
'''When''': 2-7 Feb, 2013&lt;br /&gt;
&lt;br /&gt;
Of course you are invited to join or leave the community sprint whenever you want.&lt;br /&gt;
&lt;br /&gt;
'''Duration''': 6 days&lt;br /&gt;
&lt;br /&gt;
== Venue ==&lt;br /&gt;
&lt;br /&gt;
University of Genova, Dipartimento di Scienze per l'Architettura della Scuola Politecnica, Genova, Italy.&lt;br /&gt;
&lt;br /&gt;
'''[http://geomorfolab.arch.unige.it/ Geomorfolab]''',&lt;br /&gt;
Dipartimento di Scienze per l'Architettura,&lt;br /&gt;
Scuola Politecnica - Università degli Studi di Genova,&lt;br /&gt;
Stradone S. Agostino 37, 16128 Genova&lt;br /&gt;
&lt;br /&gt;
Rooms: TBD&lt;br /&gt;
&lt;br /&gt;
== Accommodation and Costs ==&lt;br /&gt;
&lt;br /&gt;
== Weather and Common Item Prices ==&lt;br /&gt;
&lt;br /&gt;
== Agenda == &lt;br /&gt;
&lt;br /&gt;
=== Timeline ===&lt;br /&gt;
&lt;br /&gt;
== Participation ==&lt;br /&gt;
&lt;br /&gt;
=== In person ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable sortable&amp;quot;   border=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;4&amp;quot; rules=&amp;quot;all&amp;quot; style=&amp;quot;margin:1em 1em 1em 0; border:solid 1px #AAAAAA; border-collapse:collapse; background-color:#edf9c7; font-size:95%; empty-cells:show;&amp;quot; &lt;br /&gt;
!width=50px|'''Number'''&lt;br /&gt;
!width=130px|'''Participant '''&lt;br /&gt;
!width=100px|'''Country'''&lt;br /&gt;
!width=100px|'''Arrival'''&lt;br /&gt;
!width=100px|'''Departure'''&lt;br /&gt;
!'''Topic'''&lt;br /&gt;
!width=75px|'''T-Shirt'''&lt;br /&gt;
!'''Notes'''&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|[[User:Lucadelu|Luca Delucchi]]&lt;br /&gt;
|Italy&lt;br /&gt;
| Feb 2&lt;br /&gt;
| Feb 10&lt;br /&gt;
|&lt;br /&gt;
| L&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|[[User:Neteler|Markus Neteler]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| M + S&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|[[User:Madi|Margherita Di Leo]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| L&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|[[User:pcav|Paolo Cavallini]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| L&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|[[User:lcasagrande|Luca Casagrande]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GRASS Tutorial with Open Data from Italy&lt;br /&gt;
| L&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|[[User:Annakrat|Anna Kratochvilova]]&lt;br /&gt;
|Czech Republic&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| M&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|Vaclav Petras&lt;br /&gt;
|Czech Republic&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| M&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|[[User:pietro|Pietro Zambelli]]&lt;br /&gt;
|Italy&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
| M&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Via IRC chat ===&lt;br /&gt;
&lt;br /&gt;
: [irc://freenode/grass #grass] on Freenode&lt;br /&gt;
&lt;br /&gt;
For details, see [[IRC]]&lt;br /&gt;
&lt;br /&gt;
=== Collaborative document scratching ===&lt;br /&gt;
&lt;br /&gt;
== Individual Preparation ==&lt;br /&gt;
&lt;br /&gt;
* Bring your own computer&lt;br /&gt;
* Bring [http://en.wikipedia.org/wiki/Mains_electricity_by_country your power connector adapter] if needed ([http://en.wikipedia.org/wiki/File:L_plug.jpg Italy])&lt;br /&gt;
* Install subversion and the compiler tools, and come with a working GRASS development environment if possible.&lt;br /&gt;
&lt;br /&gt;
== Photos ==&lt;br /&gt;
&lt;br /&gt;
Also during the event :)&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
* How was it last time?&lt;br /&gt;
** Very cool, see [[GRASS Community Sprint Prague 2012]]!&lt;br /&gt;
* ''Is the GRASS Community Sprint just a coding event?''&lt;br /&gt;
** It is mainly a coding and documentation event. It is a working session for people who are already participants in the GRASS project and/or are committed to improving the GRASS project.&lt;br /&gt;
** On demand we can do some presentations of current working GRASS implementation and new upcoming features to spread the idea of Open Source GIS software&lt;br /&gt;
* ''Is the GRASS Community Sprint for developers only?''&lt;br /&gt;
** Not at all: anybody can help, with testing, checking out bugs and fixes, documentation and more.&lt;br /&gt;
* ''Where can I get help and more information about the community sprint?''&lt;br /&gt;
** Contact [[User:Lucadelu|Luca Delucchi]] &amp;lt;tt&amp;gt;&amp;lt;lucadeluge at gmail dot com&amp;gt;&amp;lt;/tt&amp;gt; or [[User:Neteler|Markus Neteler]]&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16332</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16332"/>
		<updated>2012-08-17T21:28:34Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report11 - 2012-08-17 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[GRASS SoC Ideas 2012/High level map interaction/Vector]] for more info.&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Add basic vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Add complex vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Add support for vector attributes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Add support to the Vector head structure || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== Report8 - 2012-07-20 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the pygrass modules class and start to study the GRASS vector API.&lt;br /&gt;
Yesterday and today I had some troubles with my OS installation and hard disk.&lt;br /&gt;
&lt;br /&gt;
The Module class read the xml module description and instantiate a Module class, that is a callable object, user can change parameters, and the object check if the parameter are or not valid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from pygrass.modules import Module&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp',  aspect='asp',&lt;br /&gt;
...              format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or it is possible to run all in one line, similar to run_command, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Module class allow user to run the command later, with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True, run_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class allow to manage the process, and read stdout and stderr, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module('r.slope.aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp', aspect='asp', overwrite=True, finish_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect.popen.wait() # *.kill(), *.terminate()&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; out, err = slope_aspect.popen.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for more info on the Module class look at: http://pygrass.readthedocs.org/en/latest/modules.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Work on the Vector interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, I need to better understand of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
== Report9 - 2012-07-27 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
I've worked on vector API, in particular on geometry feature.&lt;br /&gt;
&lt;br /&gt;
====Point====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* class Point(x, y, z=None, is2D=True)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.x&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.y&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
False&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt&lt;br /&gt;
Point(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print pnt&lt;br /&gt;
POINT(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return an Area object using the Vect_point_buffer2 C function. Creates buffer around the point (px, py).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* coords()&lt;br /&gt;
Return a tuple with the point coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
If the point is 2D return a x, y tuple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Calculate distance of 2 points, using the Vect_points_distance C function, If one of the point have z == None, return the 2D distance.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0 = Point(0, 0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1 = Point(1, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1.z = 1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1&lt;br /&gt;
Point(1.000000, 0.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.4142135623730951&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The distance method require a :class:Point or a tuple with the coordinates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkb()&lt;br /&gt;
Return a “well know binary” (WKB) geometry buffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a “well know text” (WKT) geometry string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.get_wkt()&lt;br /&gt;
'POINT(0.000000, 0.000000)'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Only POINT (2/3D) are supported, POINTM and POINT with: XYZM are not supported yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line====&lt;br /&gt;
&lt;br /&gt;
class Line(points=None, mapinfo=None, lineid=None, field=None, is2D=True)&lt;br /&gt;
Instantiate a new Line with a list of tuple, or with a list of Point.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                               &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, -1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* append(pnt)&lt;br /&gt;
Appends one point to the end of a line, using the Vect_append_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((10, 100))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((20, 200))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000), Point(20.000000, 200.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* bbox()&lt;br /&gt;
Return the bounding box of the line, using Vect_line_box C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (0, 1), (2, 1), (2, 0)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox = line.bbox()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.north&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.south&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.east&lt;br /&gt;
2.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.west&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.top&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.bottom&lt;br /&gt;
0.0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
It is possible to access to the C struct of the object with: bbox.c_bbox&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return the buffer area around the line, using the Vect_line_buffer2 C function.&lt;br /&gt;
Not implemented yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* delete(indx)&lt;br /&gt;
Remove the point in the index position.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.delete(-1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Return a tuple with: &lt;br /&gt;
  - the closest point on the line,&lt;br /&gt;
  - the distance between these two points,&lt;br /&gt;
  - distance of point from segment beginning&lt;br /&gt;
  - distance of point from line&lt;br /&gt;
The distance is compute using the Vect_line_distance C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* extend(line, forward=True)&lt;br /&gt;
Appends points to the end of a line.&lt;br /&gt;
&lt;br /&gt;
It is possible to extend a line, give a list of points, or directly with a line_pnts struct.&lt;br /&gt;
&lt;br /&gt;
If forward is True the line is extend forward otherwise is extend backward. The method use the Vect_append_points C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.extend( Line([(2, 2), (3, 3)]) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000),&lt;br /&gt;
      Point(3.000000, 3.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list, it is possible to extend a line, with another line or with a list of points.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* from_wkt(wkt)&lt;br /&gt;
Read a WKT string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.from_wkt(&amp;quot;LINESTRING(0 0,1 1,1 2)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(1.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_first_cat()&lt;br /&gt;
Fetches FIRST category number for given vector line and field, using the Vect_get_line_cat C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_pnt(distance, angle=0, slope=0)&lt;br /&gt;
Return a Point object on line in the specified distance, using the Vect_point_on_line C function. Raise a ValueError If the distance exceed the Line length.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(5)                           &lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
    ...&lt;br /&gt;
ValueError: The distance exceed the lenght of the line, that is: 1.414214&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(1)&lt;br /&gt;
Point(0.707107, 0.707107)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a Well Known Text string of the line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_wkt()&lt;br /&gt;
'LINESTRING(0.000000 0.000000, 1.000000 1.000000, 1.000000 2.000000)'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* insert(indx, pnt)&lt;br /&gt;
Insert new point at index position and move all old points at that position and above up, using Vect_line_insert_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.insert(0, Point(1.000000, -1.000000) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(1.000000, -1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length()&lt;br /&gt;
Calculate line length, 3D-length in case of 3D vector line, using Vect_line_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length_geodesic()&lt;br /&gt;
Calculate line length, usig Vect_line_geodesic_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length_geodesic()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* pop(indx)&lt;br /&gt;
Return the point in the index position and remove from the Line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt = line.pop(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune()&lt;br /&gt;
Remove duplicate points, i.e. zero length segments, using Vect_line_prune C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.prune()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune_thresh(threshold)&lt;br /&gt;
Remove points in threshold, using the Vect_line_prune_thresh C funtion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* remove(pnt)&lt;br /&gt;
Delete point at given index and move all points above down, using Vect_line_delete_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.remove((2, 2))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line[-1]&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reset()&lt;br /&gt;
Reset line, using Vect_reset_line C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reset()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reverse() &lt;br /&gt;
Reverse the order of vertices, using Vect_line_reverse C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reverse()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(2.000000, 2.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* segment(start, end)&lt;br /&gt;
Create line segment. using the Vect_line_segment C function.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* toarray()&lt;br /&gt;
Return an array of coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.toarray()                 &lt;br /&gt;
array([[ 0.,  0.],&lt;br /&gt;
       [ 1.,  1.],&lt;br /&gt;
       [ 2.,  0.],&lt;br /&gt;
       [ 1., -1.]])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* tolist()&lt;br /&gt;
Return a list of tuple.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.tolist()&lt;br /&gt;
[(0.0, 0.0), (1.0, 1.0), (2.0, 0.0), (1.0, -1.0)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the other vector features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, but I need more time to assimilate the ideas of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report10 - 2012-08-03 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the vector API, add more geometry feature like border, isle, and area, clean the code and study vector documentation and functions.&lt;br /&gt;
This week I did an university exam, the last one for this summer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Start to test the new vector classes add test and documentation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
As the last week I'm studying more and more the vector API of GRASS, I would like to have more time... :-)&lt;br /&gt;
&lt;br /&gt;
== Report11 - 2012-08-10 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
This week I did a lot of works:&lt;br /&gt;
&lt;br /&gt;
* move the documentation from ReadTheDocs to: http://www.ing.unitn.it/~zambelli/projects/pygrass in this way I'm able to use the sphinx automodule to document the API.&lt;br /&gt;
* Add more examples and documentation on vector geometry features: http://www.ing.unitn.it/~zambelli/projects/pygrass/vector.html&lt;br /&gt;
* Add a basic support for the vector attributes: http://www.ing.unitn.it/~zambelli/projects/pygrass/attributes.html&lt;br /&gt;
&lt;br /&gt;
To run the above examples you need to use the North Carolina mapset, copy and build the topology, and copy the table attributes from dbf to sqlite and/or postgresql.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
I will add the write mode to the Vector objects.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
== Report12 - 2012-08-17 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* Re-organize the code structure;&lt;br /&gt;
* Add more documentation for each class, and when possible add docstring http://www.ing.unitn.it/~zambelli/projects/pygrass/;&lt;br /&gt;
* Add README, AUTHOR, NEWS files to the project root;&lt;br /&gt;
* Add the setup.py file to the project;&lt;br /&gt;
* Split the Vector class into Vector (without topology) and in VectTopo (with the topology support);&lt;br /&gt;
* Add vector head information.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Going on cleaning and fixing the code.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16331</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16331"/>
		<updated>2012-08-17T21:26:52Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Project plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[GRASS SoC Ideas 2012/High level map interaction/Vector]] for more info.&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Add basic vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Add complex vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Add support for vector attributes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Add support to the Vector head structure || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== Report8 - 2012-07-20 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the pygrass modules class and start to study the GRASS vector API.&lt;br /&gt;
Yesterday and today I had some troubles with my OS installation and hard disk.&lt;br /&gt;
&lt;br /&gt;
The Module class read the xml module description and instantiate a Module class, that is a callable object, user can change parameters, and the object check if the parameter are or not valid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from pygrass.modules import Module&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp',  aspect='asp',&lt;br /&gt;
...              format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or it is possible to run all in one line, similar to run_command, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Module class allow user to run the command later, with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True, run_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class allow to manage the process, and read stdout and stderr, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module('r.slope.aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp', aspect='asp', overwrite=True, finish_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect.popen.wait() # *.kill(), *.terminate()&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; out, err = slope_aspect.popen.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for more info on the Module class look at: http://pygrass.readthedocs.org/en/latest/modules.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Work on the Vector interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, I need to better understand of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
== Report9 - 2012-07-27 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
I've worked on vector API, in particular on geometry feature.&lt;br /&gt;
&lt;br /&gt;
====Point====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* class Point(x, y, z=None, is2D=True)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.x&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.y&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
False&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt&lt;br /&gt;
Point(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print pnt&lt;br /&gt;
POINT(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return an Area object using the Vect_point_buffer2 C function. Creates buffer around the point (px, py).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* coords()&lt;br /&gt;
Return a tuple with the point coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
If the point is 2D return a x, y tuple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Calculate distance of 2 points, using the Vect_points_distance C function, If one of the point have z == None, return the 2D distance.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0 = Point(0, 0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1 = Point(1, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1.z = 1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1&lt;br /&gt;
Point(1.000000, 0.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.4142135623730951&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The distance method require a :class:Point or a tuple with the coordinates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkb()&lt;br /&gt;
Return a “well know binary” (WKB) geometry buffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a “well know text” (WKT) geometry string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.get_wkt()&lt;br /&gt;
'POINT(0.000000, 0.000000)'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Only POINT (2/3D) are supported, POINTM and POINT with: XYZM are not supported yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line====&lt;br /&gt;
&lt;br /&gt;
class Line(points=None, mapinfo=None, lineid=None, field=None, is2D=True)&lt;br /&gt;
Instantiate a new Line with a list of tuple, or with a list of Point.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                               &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, -1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* append(pnt)&lt;br /&gt;
Appends one point to the end of a line, using the Vect_append_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((10, 100))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((20, 200))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000), Point(20.000000, 200.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* bbox()&lt;br /&gt;
Return the bounding box of the line, using Vect_line_box C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (0, 1), (2, 1), (2, 0)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox = line.bbox()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.north&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.south&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.east&lt;br /&gt;
2.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.west&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.top&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.bottom&lt;br /&gt;
0.0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
It is possible to access to the C struct of the object with: bbox.c_bbox&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return the buffer area around the line, using the Vect_line_buffer2 C function.&lt;br /&gt;
Not implemented yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* delete(indx)&lt;br /&gt;
Remove the point in the index position.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.delete(-1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Return a tuple with: &lt;br /&gt;
  - the closest point on the line,&lt;br /&gt;
  - the distance between these two points,&lt;br /&gt;
  - distance of point from segment beginning&lt;br /&gt;
  - distance of point from line&lt;br /&gt;
The distance is compute using the Vect_line_distance C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* extend(line, forward=True)&lt;br /&gt;
Appends points to the end of a line.&lt;br /&gt;
&lt;br /&gt;
It is possible to extend a line, give a list of points, or directly with a line_pnts struct.&lt;br /&gt;
&lt;br /&gt;
If forward is True the line is extend forward otherwise is extend backward. The method use the Vect_append_points C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.extend( Line([(2, 2), (3, 3)]) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000),&lt;br /&gt;
      Point(3.000000, 3.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list, it is possible to extend a line, with another line or with a list of points.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* from_wkt(wkt)&lt;br /&gt;
Read a WKT string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.from_wkt(&amp;quot;LINESTRING(0 0,1 1,1 2)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(1.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_first_cat()&lt;br /&gt;
Fetches FIRST category number for given vector line and field, using the Vect_get_line_cat C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_pnt(distance, angle=0, slope=0)&lt;br /&gt;
Return a Point object on line in the specified distance, using the Vect_point_on_line C function. Raise a ValueError If the distance exceed the Line length.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(5)                           &lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
    ...&lt;br /&gt;
ValueError: The distance exceed the lenght of the line, that is: 1.414214&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(1)&lt;br /&gt;
Point(0.707107, 0.707107)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a Well Known Text string of the line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_wkt()&lt;br /&gt;
'LINESTRING(0.000000 0.000000, 1.000000 1.000000, 1.000000 2.000000)'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* insert(indx, pnt)&lt;br /&gt;
Insert new point at index position and move all old points at that position and above up, using Vect_line_insert_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.insert(0, Point(1.000000, -1.000000) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(1.000000, -1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length()&lt;br /&gt;
Calculate line length, 3D-length in case of 3D vector line, using Vect_line_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length_geodesic()&lt;br /&gt;
Calculate line length, usig Vect_line_geodesic_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length_geodesic()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* pop(indx)&lt;br /&gt;
Return the point in the index position and remove from the Line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt = line.pop(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune()&lt;br /&gt;
Remove duplicate points, i.e. zero length segments, using Vect_line_prune C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.prune()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune_thresh(threshold)&lt;br /&gt;
Remove points in threshold, using the Vect_line_prune_thresh C funtion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* remove(pnt)&lt;br /&gt;
Delete point at given index and move all points above down, using Vect_line_delete_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.remove((2, 2))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line[-1]&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reset()&lt;br /&gt;
Reset line, using Vect_reset_line C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reset()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reverse() &lt;br /&gt;
Reverse the order of vertices, using Vect_line_reverse C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reverse()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(2.000000, 2.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* segment(start, end)&lt;br /&gt;
Create line segment. using the Vect_line_segment C function.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* toarray()&lt;br /&gt;
Return an array of coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.toarray()                 &lt;br /&gt;
array([[ 0.,  0.],&lt;br /&gt;
       [ 1.,  1.],&lt;br /&gt;
       [ 2.,  0.],&lt;br /&gt;
       [ 1., -1.]])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* tolist()&lt;br /&gt;
Return a list of tuple.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.tolist()&lt;br /&gt;
[(0.0, 0.0), (1.0, 1.0), (2.0, 0.0), (1.0, -1.0)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the other vector features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, but I need more time to assimilate the ideas of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report10 - 2012-08-03 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the vector API, add more geometry feature like border, isle, and area, clean the code and study vector documentation and functions.&lt;br /&gt;
This week I did an university exam, the last one for this summer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Start to test the new vector classes add test and documentation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
As the last week I'm studying more and more the vector API of GRASS, I would like to have more time... :-)&lt;br /&gt;
&lt;br /&gt;
== Report11 - 2012-08-10 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
This week I did a lot of works:&lt;br /&gt;
&lt;br /&gt;
* move the documentation from ReadTheDocs to: http://www.ing.unitn.it/~zambelli/projects/pygrass in this way I'm able to use the sphinx automodule to document the API.&lt;br /&gt;
* Add more examples and documentation on vector geometry features: http://www.ing.unitn.it/~zambelli/projects/pygrass/vector.html&lt;br /&gt;
* Add a basic support for the vector attributes: http://www.ing.unitn.it/~zambelli/projects/pygrass/attributes.html&lt;br /&gt;
&lt;br /&gt;
To run the above examples you need to use the North Carolina mapset, copy and build the topology, and copy the table attributes from dbf to sqlite and/or postgresql.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
I will add the write mode to the Vector objects.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
== Report11 - 2012-08-17 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* Re-organize the code structure;&lt;br /&gt;
* Add more documentation for each class, and when possible add docstring http://www.ing.unitn.it/~zambelli/projects/pygrass/;&lt;br /&gt;
* Add README, AUTHOR, NEWS files to the project root;&lt;br /&gt;
* Add the setup.py file to the project;&lt;br /&gt;
* Split the Vector class into Vector (without topology) and in VectTopo (with the topology support);&lt;br /&gt;
* Add vector head information.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Going on cleaning and fixing the code.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16330</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16330"/>
		<updated>2012-08-17T21:24:58Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report12 - 2012-08-17 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[GRASS SoC Ideas 2012/High level map interaction/Vector]] for more info.&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Add basic vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Add complex vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Add support for vector attributes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== Report8 - 2012-07-20 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the pygrass modules class and start to study the GRASS vector API.&lt;br /&gt;
Yesterday and today I had some troubles with my OS installation and hard disk.&lt;br /&gt;
&lt;br /&gt;
The Module class read the xml module description and instantiate a Module class, that is a callable object, user can change parameters, and the object check if the parameter are or not valid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from pygrass.modules import Module&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp',  aspect='asp',&lt;br /&gt;
...              format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or it is possible to run all in one line, similar to run_command, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Module class allow user to run the command later, with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True, run_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class allow to manage the process, and read stdout and stderr, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module('r.slope.aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp', aspect='asp', overwrite=True, finish_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect.popen.wait() # *.kill(), *.terminate()&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; out, err = slope_aspect.popen.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for more info on the Module class look at: http://pygrass.readthedocs.org/en/latest/modules.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Work on the Vector interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, I need to better understand of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
== Report9 - 2012-07-27 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
I've worked on vector API, in particular on geometry feature.&lt;br /&gt;
&lt;br /&gt;
====Point====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* class Point(x, y, z=None, is2D=True)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.x&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.y&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
False&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt&lt;br /&gt;
Point(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print pnt&lt;br /&gt;
POINT(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return an Area object using the Vect_point_buffer2 C function. Creates buffer around the point (px, py).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* coords()&lt;br /&gt;
Return a tuple with the point coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
If the point is 2D return a x, y tuple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Calculate distance of 2 points, using the Vect_points_distance C function, If one of the point have z == None, return the 2D distance.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0 = Point(0, 0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1 = Point(1, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1.z = 1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1&lt;br /&gt;
Point(1.000000, 0.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.4142135623730951&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The distance method require a :class:Point or a tuple with the coordinates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkb()&lt;br /&gt;
Return a “well know binary” (WKB) geometry buffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a “well know text” (WKT) geometry string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.get_wkt()&lt;br /&gt;
'POINT(0.000000, 0.000000)'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Only POINT (2/3D) are supported, POINTM and POINT with: XYZM are not supported yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line====&lt;br /&gt;
&lt;br /&gt;
class Line(points=None, mapinfo=None, lineid=None, field=None, is2D=True)&lt;br /&gt;
Instantiate a new Line with a list of tuple, or with a list of Point.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                               &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, -1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* append(pnt)&lt;br /&gt;
Appends one point to the end of a line, using the Vect_append_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((10, 100))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((20, 200))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000), Point(20.000000, 200.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* bbox()&lt;br /&gt;
Return the bounding box of the line, using Vect_line_box C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (0, 1), (2, 1), (2, 0)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox = line.bbox()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.north&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.south&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.east&lt;br /&gt;
2.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.west&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.top&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.bottom&lt;br /&gt;
0.0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
It is possible to access to the C struct of the object with: bbox.c_bbox&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return the buffer area around the line, using the Vect_line_buffer2 C function.&lt;br /&gt;
Not implemented yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* delete(indx)&lt;br /&gt;
Remove the point in the index position.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.delete(-1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Return a tuple with: &lt;br /&gt;
  - the closest point on the line,&lt;br /&gt;
  - the distance between these two points,&lt;br /&gt;
  - distance of point from segment beginning&lt;br /&gt;
  - distance of point from line&lt;br /&gt;
The distance is compute using the Vect_line_distance C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* extend(line, forward=True)&lt;br /&gt;
Appends points to the end of a line.&lt;br /&gt;
&lt;br /&gt;
It is possible to extend a line, give a list of points, or directly with a line_pnts struct.&lt;br /&gt;
&lt;br /&gt;
If forward is True the line is extend forward otherwise is extend backward. The method use the Vect_append_points C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.extend( Line([(2, 2), (3, 3)]) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000),&lt;br /&gt;
      Point(3.000000, 3.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list, it is possible to extend a line, with another line or with a list of points.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* from_wkt(wkt)&lt;br /&gt;
Read a WKT string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.from_wkt(&amp;quot;LINESTRING(0 0,1 1,1 2)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(1.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_first_cat()&lt;br /&gt;
Fetches FIRST category number for given vector line and field, using the Vect_get_line_cat C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_pnt(distance, angle=0, slope=0)&lt;br /&gt;
Return a Point object on line in the specified distance, using the Vect_point_on_line C function. Raise a ValueError If the distance exceed the Line length.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(5)                           &lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
    ...&lt;br /&gt;
ValueError: The distance exceed the lenght of the line, that is: 1.414214&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(1)&lt;br /&gt;
Point(0.707107, 0.707107)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a Well Known Text string of the line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_wkt()&lt;br /&gt;
'LINESTRING(0.000000 0.000000, 1.000000 1.000000, 1.000000 2.000000)'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* insert(indx, pnt)&lt;br /&gt;
Insert new point at index position and move all old points at that position and above up, using Vect_line_insert_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.insert(0, Point(1.000000, -1.000000) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(1.000000, -1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length()&lt;br /&gt;
Calculate line length, 3D-length in case of 3D vector line, using Vect_line_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length_geodesic()&lt;br /&gt;
Calculate line length, usig Vect_line_geodesic_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length_geodesic()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* pop(indx)&lt;br /&gt;
Return the point in the index position and remove from the Line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt = line.pop(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune()&lt;br /&gt;
Remove duplicate points, i.e. zero length segments, using Vect_line_prune C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.prune()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune_thresh(threshold)&lt;br /&gt;
Remove points in threshold, using the Vect_line_prune_thresh C funtion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* remove(pnt)&lt;br /&gt;
Delete point at given index and move all points above down, using Vect_line_delete_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.remove((2, 2))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line[-1]&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reset()&lt;br /&gt;
Reset line, using Vect_reset_line C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reset()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reverse() &lt;br /&gt;
Reverse the order of vertices, using Vect_line_reverse C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reverse()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(2.000000, 2.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* segment(start, end)&lt;br /&gt;
Create line segment. using the Vect_line_segment C function.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* toarray()&lt;br /&gt;
Return an array of coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.toarray()                 &lt;br /&gt;
array([[ 0.,  0.],&lt;br /&gt;
       [ 1.,  1.],&lt;br /&gt;
       [ 2.,  0.],&lt;br /&gt;
       [ 1., -1.]])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* tolist()&lt;br /&gt;
Return a list of tuple.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.tolist()&lt;br /&gt;
[(0.0, 0.0), (1.0, 1.0), (2.0, 0.0), (1.0, -1.0)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the other vector features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, but I need more time to assimilate the ideas of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report10 - 2012-08-03 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the vector API, add more geometry feature like border, isle, and area, clean the code and study vector documentation and functions.&lt;br /&gt;
This week I did an university exam, the last one for this summer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Start to test the new vector classes add test and documentation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
As the last week I'm studying more and more the vector API of GRASS, I would like to have more time... :-)&lt;br /&gt;
&lt;br /&gt;
== Report11 - 2012-08-10 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
This week I did a lot of works:&lt;br /&gt;
&lt;br /&gt;
* move the documentation from ReadTheDocs to: http://www.ing.unitn.it/~zambelli/projects/pygrass in this way I'm able to use the sphinx automodule to document the API.&lt;br /&gt;
* Add more examples and documentation on vector geometry features: http://www.ing.unitn.it/~zambelli/projects/pygrass/vector.html&lt;br /&gt;
* Add a basic support for the vector attributes: http://www.ing.unitn.it/~zambelli/projects/pygrass/attributes.html&lt;br /&gt;
&lt;br /&gt;
To run the above examples you need to use the North Carolina mapset, copy and build the topology, and copy the table attributes from dbf to sqlite and/or postgresql.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
I will add the write mode to the Vector objects.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
== Report11 - 2012-08-17 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* Re-organize the code structure;&lt;br /&gt;
* Add more documentation for each class, and when possible add docstring http://www.ing.unitn.it/~zambelli/projects/pygrass/;&lt;br /&gt;
* Add README, AUTHOR, NEWS files to the project root;&lt;br /&gt;
* Add the setup.py file to the project;&lt;br /&gt;
* Split the Vector class into Vector (without topology) and in VectTopo (with the topology support);&lt;br /&gt;
* Add vector head information.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Going on cleaning and fixing the code.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16281</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16281"/>
		<updated>2012-08-10T22:20:23Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* What did I do this week? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[GRASS SoC Ideas 2012/High level map interaction/Vector]] for more info.&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Add basic vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Add complex vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Add support for vector attributes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== Report8 - 2012-07-20 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the pygrass modules class and start to study the GRASS vector API.&lt;br /&gt;
Yesterday and today I had some troubles with my OS installation and hard disk.&lt;br /&gt;
&lt;br /&gt;
The Module class read the xml module description and instantiate a Module class, that is a callable object, user can change parameters, and the object check if the parameter are or not valid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from pygrass.modules import Module&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp',  aspect='asp',&lt;br /&gt;
...              format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or it is possible to run all in one line, similar to run_command, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Module class allow user to run the command later, with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True, run_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class allow to manage the process, and read stdout and stderr, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module('r.slope.aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp', aspect='asp', overwrite=True, finish_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect.popen.wait() # *.kill(), *.terminate()&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; out, err = slope_aspect.popen.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for more info on the Module class look at: http://pygrass.readthedocs.org/en/latest/modules.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Work on the Vector interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, I need to better understand of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
== Report9 - 2012-07-27 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
I've worked on vector API, in particular on geometry feature.&lt;br /&gt;
&lt;br /&gt;
====Point====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* class Point(x, y, z=None, is2D=True)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.x&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.y&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
False&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt&lt;br /&gt;
Point(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print pnt&lt;br /&gt;
POINT(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return an Area object using the Vect_point_buffer2 C function. Creates buffer around the point (px, py).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* coords()&lt;br /&gt;
Return a tuple with the point coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
If the point is 2D return a x, y tuple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Calculate distance of 2 points, using the Vect_points_distance C function, If one of the point have z == None, return the 2D distance.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0 = Point(0, 0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1 = Point(1, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1.z = 1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1&lt;br /&gt;
Point(1.000000, 0.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.4142135623730951&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The distance method require a :class:Point or a tuple with the coordinates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkb()&lt;br /&gt;
Return a “well know binary” (WKB) geometry buffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a “well know text” (WKT) geometry string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.get_wkt()&lt;br /&gt;
'POINT(0.000000, 0.000000)'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Only POINT (2/3D) are supported, POINTM and POINT with: XYZM are not supported yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line====&lt;br /&gt;
&lt;br /&gt;
class Line(points=None, mapinfo=None, lineid=None, field=None, is2D=True)&lt;br /&gt;
Instantiate a new Line with a list of tuple, or with a list of Point.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                               &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, -1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* append(pnt)&lt;br /&gt;
Appends one point to the end of a line, using the Vect_append_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((10, 100))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((20, 200))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000), Point(20.000000, 200.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* bbox()&lt;br /&gt;
Return the bounding box of the line, using Vect_line_box C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (0, 1), (2, 1), (2, 0)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox = line.bbox()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.north&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.south&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.east&lt;br /&gt;
2.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.west&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.top&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.bottom&lt;br /&gt;
0.0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
It is possible to access to the C struct of the object with: bbox.c_bbox&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return the buffer area around the line, using the Vect_line_buffer2 C function.&lt;br /&gt;
Not implemented yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* delete(indx)&lt;br /&gt;
Remove the point in the index position.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.delete(-1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Return a tuple with: &lt;br /&gt;
  - the closest point on the line,&lt;br /&gt;
  - the distance between these two points,&lt;br /&gt;
  - distance of point from segment beginning&lt;br /&gt;
  - distance of point from line&lt;br /&gt;
The distance is compute using the Vect_line_distance C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* extend(line, forward=True)&lt;br /&gt;
Appends points to the end of a line.&lt;br /&gt;
&lt;br /&gt;
It is possible to extend a line, give a list of points, or directly with a line_pnts struct.&lt;br /&gt;
&lt;br /&gt;
If forward is True the line is extend forward otherwise is extend backward. The method use the Vect_append_points C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.extend( Line([(2, 2), (3, 3)]) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000),&lt;br /&gt;
      Point(3.000000, 3.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list, it is possible to extend a line, with another line or with a list of points.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* from_wkt(wkt)&lt;br /&gt;
Read a WKT string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.from_wkt(&amp;quot;LINESTRING(0 0,1 1,1 2)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(1.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_first_cat()&lt;br /&gt;
Fetches FIRST category number for given vector line and field, using the Vect_get_line_cat C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_pnt(distance, angle=0, slope=0)&lt;br /&gt;
Return a Point object on line in the specified distance, using the Vect_point_on_line C function. Raise a ValueError If the distance exceed the Line length.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(5)                           &lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
    ...&lt;br /&gt;
ValueError: The distance exceed the lenght of the line, that is: 1.414214&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(1)&lt;br /&gt;
Point(0.707107, 0.707107)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a Well Known Text string of the line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_wkt()&lt;br /&gt;
'LINESTRING(0.000000 0.000000, 1.000000 1.000000, 1.000000 2.000000)'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* insert(indx, pnt)&lt;br /&gt;
Insert new point at index position and move all old points at that position and above up, using Vect_line_insert_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.insert(0, Point(1.000000, -1.000000) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(1.000000, -1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length()&lt;br /&gt;
Calculate line length, 3D-length in case of 3D vector line, using Vect_line_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length_geodesic()&lt;br /&gt;
Calculate line length, usig Vect_line_geodesic_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length_geodesic()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* pop(indx)&lt;br /&gt;
Return the point in the index position and remove from the Line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt = line.pop(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune()&lt;br /&gt;
Remove duplicate points, i.e. zero length segments, using Vect_line_prune C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.prune()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune_thresh(threshold)&lt;br /&gt;
Remove points in threshold, using the Vect_line_prune_thresh C funtion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* remove(pnt)&lt;br /&gt;
Delete point at given index and move all points above down, using Vect_line_delete_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.remove((2, 2))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line[-1]&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reset()&lt;br /&gt;
Reset line, using Vect_reset_line C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reset()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reverse() &lt;br /&gt;
Reverse the order of vertices, using Vect_line_reverse C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reverse()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(2.000000, 2.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* segment(start, end)&lt;br /&gt;
Create line segment. using the Vect_line_segment C function.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* toarray()&lt;br /&gt;
Return an array of coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.toarray()                 &lt;br /&gt;
array([[ 0.,  0.],&lt;br /&gt;
       [ 1.,  1.],&lt;br /&gt;
       [ 2.,  0.],&lt;br /&gt;
       [ 1., -1.]])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* tolist()&lt;br /&gt;
Return a list of tuple.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.tolist()&lt;br /&gt;
[(0.0, 0.0), (1.0, 1.0), (2.0, 0.0), (1.0, -1.0)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the other vector features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, but I need more time to assimilate the ideas of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report10 - 2012-08-03 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the vector API, add more geometry feature like border, isle, and area, clean the code and study vector documentation and functions.&lt;br /&gt;
This week I did an university exam, the last one for this summer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Start to test the new vector classes add test and documentation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
As the last week I'm studying more and more the vector API of GRASS, I would like to have more time... :-)&lt;br /&gt;
&lt;br /&gt;
== Report11 - 2012-08-10 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
This week I did a lot of works:&lt;br /&gt;
&lt;br /&gt;
* move the documentation from ReadTheDocs to: http://www.ing.unitn.it/~zambelli/projects/pygrass in this way I'm able to use the sphinx automodule to document the API.&lt;br /&gt;
* Add more examples and documentation on vector geometry features: http://www.ing.unitn.it/~zambelli/projects/pygrass/vector.html&lt;br /&gt;
* Add a basic support for the vector attributes: http://www.ing.unitn.it/~zambelli/projects/pygrass/attributes.html&lt;br /&gt;
&lt;br /&gt;
To run the above examples you need to use the North Carolina mapset, copy and build the topology, and copy the table attributes from dbf to sqlite and/or postgresql.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
I will add the write mode to the Vector objects.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16280</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16280"/>
		<updated>2012-08-10T22:19:20Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report11 - 2012-08-10 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[GRASS SoC Ideas 2012/High level map interaction/Vector]] for more info.&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Add basic vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Add complex vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Add support for vector attributes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== Report8 - 2012-07-20 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the pygrass modules class and start to study the GRASS vector API.&lt;br /&gt;
Yesterday and today I had some troubles with my OS installation and hard disk.&lt;br /&gt;
&lt;br /&gt;
The Module class read the xml module description and instantiate a Module class, that is a callable object, user can change parameters, and the object check if the parameter are or not valid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from pygrass.modules import Module&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp',  aspect='asp',&lt;br /&gt;
...              format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or it is possible to run all in one line, similar to run_command, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Module class allow user to run the command later, with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True, run_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class allow to manage the process, and read stdout and stderr, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module('r.slope.aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp', aspect='asp', overwrite=True, finish_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect.popen.wait() # *.kill(), *.terminate()&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; out, err = slope_aspect.popen.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for more info on the Module class look at: http://pygrass.readthedocs.org/en/latest/modules.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Work on the Vector interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, I need to better understand of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
== Report9 - 2012-07-27 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
I've worked on vector API, in particular on geometry feature.&lt;br /&gt;
&lt;br /&gt;
====Point====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* class Point(x, y, z=None, is2D=True)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.x&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.y&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
False&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt&lt;br /&gt;
Point(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print pnt&lt;br /&gt;
POINT(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return an Area object using the Vect_point_buffer2 C function. Creates buffer around the point (px, py).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* coords()&lt;br /&gt;
Return a tuple with the point coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
If the point is 2D return a x, y tuple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Calculate distance of 2 points, using the Vect_points_distance C function, If one of the point have z == None, return the 2D distance.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0 = Point(0, 0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1 = Point(1, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1.z = 1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1&lt;br /&gt;
Point(1.000000, 0.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.4142135623730951&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The distance method require a :class:Point or a tuple with the coordinates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkb()&lt;br /&gt;
Return a “well know binary” (WKB) geometry buffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a “well know text” (WKT) geometry string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.get_wkt()&lt;br /&gt;
'POINT(0.000000, 0.000000)'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Only POINT (2/3D) are supported, POINTM and POINT with: XYZM are not supported yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line====&lt;br /&gt;
&lt;br /&gt;
class Line(points=None, mapinfo=None, lineid=None, field=None, is2D=True)&lt;br /&gt;
Instantiate a new Line with a list of tuple, or with a list of Point.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                               &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, -1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* append(pnt)&lt;br /&gt;
Appends one point to the end of a line, using the Vect_append_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((10, 100))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((20, 200))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000), Point(20.000000, 200.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* bbox()&lt;br /&gt;
Return the bounding box of the line, using Vect_line_box C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (0, 1), (2, 1), (2, 0)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox = line.bbox()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.north&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.south&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.east&lt;br /&gt;
2.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.west&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.top&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.bottom&lt;br /&gt;
0.0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
It is possible to access to the C struct of the object with: bbox.c_bbox&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return the buffer area around the line, using the Vect_line_buffer2 C function.&lt;br /&gt;
Not implemented yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* delete(indx)&lt;br /&gt;
Remove the point in the index position.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.delete(-1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Return a tuple with: &lt;br /&gt;
  - the closest point on the line,&lt;br /&gt;
  - the distance between these two points,&lt;br /&gt;
  - distance of point from segment beginning&lt;br /&gt;
  - distance of point from line&lt;br /&gt;
The distance is compute using the Vect_line_distance C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* extend(line, forward=True)&lt;br /&gt;
Appends points to the end of a line.&lt;br /&gt;
&lt;br /&gt;
It is possible to extend a line, give a list of points, or directly with a line_pnts struct.&lt;br /&gt;
&lt;br /&gt;
If forward is True the line is extend forward otherwise is extend backward. The method use the Vect_append_points C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.extend( Line([(2, 2), (3, 3)]) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000),&lt;br /&gt;
      Point(3.000000, 3.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list, it is possible to extend a line, with another line or with a list of points.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* from_wkt(wkt)&lt;br /&gt;
Read a WKT string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.from_wkt(&amp;quot;LINESTRING(0 0,1 1,1 2)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(1.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_first_cat()&lt;br /&gt;
Fetches FIRST category number for given vector line and field, using the Vect_get_line_cat C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_pnt(distance, angle=0, slope=0)&lt;br /&gt;
Return a Point object on line in the specified distance, using the Vect_point_on_line C function. Raise a ValueError If the distance exceed the Line length.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(5)                           &lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
    ...&lt;br /&gt;
ValueError: The distance exceed the lenght of the line, that is: 1.414214&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(1)&lt;br /&gt;
Point(0.707107, 0.707107)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a Well Known Text string of the line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_wkt()&lt;br /&gt;
'LINESTRING(0.000000 0.000000, 1.000000 1.000000, 1.000000 2.000000)'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* insert(indx, pnt)&lt;br /&gt;
Insert new point at index position and move all old points at that position and above up, using Vect_line_insert_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.insert(0, Point(1.000000, -1.000000) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(1.000000, -1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length()&lt;br /&gt;
Calculate line length, 3D-length in case of 3D vector line, using Vect_line_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length_geodesic()&lt;br /&gt;
Calculate line length, usig Vect_line_geodesic_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length_geodesic()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* pop(indx)&lt;br /&gt;
Return the point in the index position and remove from the Line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt = line.pop(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune()&lt;br /&gt;
Remove duplicate points, i.e. zero length segments, using Vect_line_prune C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.prune()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune_thresh(threshold)&lt;br /&gt;
Remove points in threshold, using the Vect_line_prune_thresh C funtion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* remove(pnt)&lt;br /&gt;
Delete point at given index and move all points above down, using Vect_line_delete_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.remove((2, 2))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line[-1]&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reset()&lt;br /&gt;
Reset line, using Vect_reset_line C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reset()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reverse() &lt;br /&gt;
Reverse the order of vertices, using Vect_line_reverse C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reverse()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(2.000000, 2.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* segment(start, end)&lt;br /&gt;
Create line segment. using the Vect_line_segment C function.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* toarray()&lt;br /&gt;
Return an array of coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.toarray()                 &lt;br /&gt;
array([[ 0.,  0.],&lt;br /&gt;
       [ 1.,  1.],&lt;br /&gt;
       [ 2.,  0.],&lt;br /&gt;
       [ 1., -1.]])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* tolist()&lt;br /&gt;
Return a list of tuple.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.tolist()&lt;br /&gt;
[(0.0, 0.0), (1.0, 1.0), (2.0, 0.0), (1.0, -1.0)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the other vector features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, but I need more time to assimilate the ideas of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report10 - 2012-08-03 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the vector API, add more geometry feature like border, isle, and area, clean the code and study vector documentation and functions.&lt;br /&gt;
This week I did an university exam, the last one for this summer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Start to test the new vector classes add test and documentation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
As the last week I'm studying more and more the vector API of GRASS, I would like to have more time... :-)&lt;br /&gt;
&lt;br /&gt;
== Report11 - 2012-08-10 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
This week I did a lot of works:&lt;br /&gt;
&lt;br /&gt;
* move the documentation from ReadTheDocs to: http://www.ing.unitn.it/~zambelli/projects/pygrass in this way I'm able to use the sphinx automodule to document the API.&lt;br /&gt;
* Add more examples and documentation on vector geometry features: http://www.ing.unitn.it/~zambelli/projects/pygrass/vector.html&lt;br /&gt;
* Add a basic support for the vector attributes:&lt;br /&gt;
http://www.ing.unitn.it/~zambelli/projects/pygrass/attributes.html&lt;br /&gt;
&lt;br /&gt;
To run the above examples you need to use the North Carolina mapset, copy and build the topology, and copy the table attributes from dbf to sqlite and/or postgresql.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
I will add the write mode to the Vector objects.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16279</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16279"/>
		<updated>2012-08-10T22:10:50Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Project plan */ update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[GRASS SoC Ideas 2012/High level map interaction/Vector]] for more info.&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Add basic vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Add complex vector features || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Add support for vector attributes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== Report8 - 2012-07-20 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the pygrass modules class and start to study the GRASS vector API.&lt;br /&gt;
Yesterday and today I had some troubles with my OS installation and hard disk.&lt;br /&gt;
&lt;br /&gt;
The Module class read the xml module description and instantiate a Module class, that is a callable object, user can change parameters, and the object check if the parameter are or not valid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from pygrass.modules import Module&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp',  aspect='asp',&lt;br /&gt;
...              format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or it is possible to run all in one line, similar to run_command, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Module class allow user to run the command later, with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True, run_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class allow to manage the process, and read stdout and stderr, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module('r.slope.aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp', aspect='asp', overwrite=True, finish_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect.popen.wait() # *.kill(), *.terminate()&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; out, err = slope_aspect.popen.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for more info on the Module class look at: http://pygrass.readthedocs.org/en/latest/modules.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Work on the Vector interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, I need to better understand of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
== Report9 - 2012-07-27 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
I've worked on vector API, in particular on geometry feature.&lt;br /&gt;
&lt;br /&gt;
====Point====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* class Point(x, y, z=None, is2D=True)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.x&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.y&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
False&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt&lt;br /&gt;
Point(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print pnt&lt;br /&gt;
POINT(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return an Area object using the Vect_point_buffer2 C function. Creates buffer around the point (px, py).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* coords()&lt;br /&gt;
Return a tuple with the point coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
If the point is 2D return a x, y tuple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Calculate distance of 2 points, using the Vect_points_distance C function, If one of the point have z == None, return the 2D distance.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0 = Point(0, 0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1 = Point(1, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1.z = 1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1&lt;br /&gt;
Point(1.000000, 0.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.4142135623730951&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The distance method require a :class:Point or a tuple with the coordinates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkb()&lt;br /&gt;
Return a “well know binary” (WKB) geometry buffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a “well know text” (WKT) geometry string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.get_wkt()&lt;br /&gt;
'POINT(0.000000, 0.000000)'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Only POINT (2/3D) are supported, POINTM and POINT with: XYZM are not supported yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line====&lt;br /&gt;
&lt;br /&gt;
class Line(points=None, mapinfo=None, lineid=None, field=None, is2D=True)&lt;br /&gt;
Instantiate a new Line with a list of tuple, or with a list of Point.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                               &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, -1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* append(pnt)&lt;br /&gt;
Appends one point to the end of a line, using the Vect_append_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((10, 100))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((20, 200))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000), Point(20.000000, 200.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* bbox()&lt;br /&gt;
Return the bounding box of the line, using Vect_line_box C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (0, 1), (2, 1), (2, 0)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox = line.bbox()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.north&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.south&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.east&lt;br /&gt;
2.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.west&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.top&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.bottom&lt;br /&gt;
0.0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
It is possible to access to the C struct of the object with: bbox.c_bbox&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return the buffer area around the line, using the Vect_line_buffer2 C function.&lt;br /&gt;
Not implemented yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* delete(indx)&lt;br /&gt;
Remove the point in the index position.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.delete(-1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Return a tuple with: &lt;br /&gt;
  - the closest point on the line,&lt;br /&gt;
  - the distance between these two points,&lt;br /&gt;
  - distance of point from segment beginning&lt;br /&gt;
  - distance of point from line&lt;br /&gt;
The distance is compute using the Vect_line_distance C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* extend(line, forward=True)&lt;br /&gt;
Appends points to the end of a line.&lt;br /&gt;
&lt;br /&gt;
It is possible to extend a line, give a list of points, or directly with a line_pnts struct.&lt;br /&gt;
&lt;br /&gt;
If forward is True the line is extend forward otherwise is extend backward. The method use the Vect_append_points C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.extend( Line([(2, 2), (3, 3)]) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000),&lt;br /&gt;
      Point(3.000000, 3.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list, it is possible to extend a line, with another line or with a list of points.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* from_wkt(wkt)&lt;br /&gt;
Read a WKT string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.from_wkt(&amp;quot;LINESTRING(0 0,1 1,1 2)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(1.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_first_cat()&lt;br /&gt;
Fetches FIRST category number for given vector line and field, using the Vect_get_line_cat C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_pnt(distance, angle=0, slope=0)&lt;br /&gt;
Return a Point object on line in the specified distance, using the Vect_point_on_line C function. Raise a ValueError If the distance exceed the Line length.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(5)                           &lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
    ...&lt;br /&gt;
ValueError: The distance exceed the lenght of the line, that is: 1.414214&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(1)&lt;br /&gt;
Point(0.707107, 0.707107)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a Well Known Text string of the line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_wkt()&lt;br /&gt;
'LINESTRING(0.000000 0.000000, 1.000000 1.000000, 1.000000 2.000000)'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* insert(indx, pnt)&lt;br /&gt;
Insert new point at index position and move all old points at that position and above up, using Vect_line_insert_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.insert(0, Point(1.000000, -1.000000) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(1.000000, -1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length()&lt;br /&gt;
Calculate line length, 3D-length in case of 3D vector line, using Vect_line_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length_geodesic()&lt;br /&gt;
Calculate line length, usig Vect_line_geodesic_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length_geodesic()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* pop(indx)&lt;br /&gt;
Return the point in the index position and remove from the Line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt = line.pop(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune()&lt;br /&gt;
Remove duplicate points, i.e. zero length segments, using Vect_line_prune C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.prune()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune_thresh(threshold)&lt;br /&gt;
Remove points in threshold, using the Vect_line_prune_thresh C funtion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* remove(pnt)&lt;br /&gt;
Delete point at given index and move all points above down, using Vect_line_delete_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.remove((2, 2))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line[-1]&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reset()&lt;br /&gt;
Reset line, using Vect_reset_line C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reset()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reverse() &lt;br /&gt;
Reverse the order of vertices, using Vect_line_reverse C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reverse()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(2.000000, 2.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* segment(start, end)&lt;br /&gt;
Create line segment. using the Vect_line_segment C function.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* toarray()&lt;br /&gt;
Return an array of coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.toarray()                 &lt;br /&gt;
array([[ 0.,  0.],&lt;br /&gt;
       [ 1.,  1.],&lt;br /&gt;
       [ 2.,  0.],&lt;br /&gt;
       [ 1., -1.]])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* tolist()&lt;br /&gt;
Return a list of tuple.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.tolist()&lt;br /&gt;
[(0.0, 0.0), (1.0, 1.0), (2.0, 0.0), (1.0, -1.0)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the other vector features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, but I need more time to assimilate the ideas of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report10 - 2012-08-03 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the vector API, add more geometry feature like border, isle, and area, clean the code and study vector documentation and functions.&lt;br /&gt;
This week I did an university exam, the last one for this summer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Start to test the new vector classes add test and documentation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
As the last week I'm studying more and more the vector API of GRASS, I would like to have more time... :-)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16253</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16253"/>
		<updated>2012-08-03T20:42:08Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report10 - 2012-08-03 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[GRASS SoC Ideas 2012/High level map interaction/Vector]] for more info.&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== Report8 - 2012-07-20 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the pygrass modules class and start to study the GRASS vector API.&lt;br /&gt;
Yesterday and today I had some troubles with my OS installation and hard disk.&lt;br /&gt;
&lt;br /&gt;
The Module class read the xml module description and instantiate a Module class, that is a callable object, user can change parameters, and the object check if the parameter are or not valid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from pygrass.modules import Module&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp',  aspect='asp',&lt;br /&gt;
...              format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or it is possible to run all in one line, similar to run_command, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Module class allow user to run the command later, with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True, run_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class allow to manage the process, and read stdout and stderr, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module('r.slope.aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp', aspect='asp', overwrite=True, finish_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect.popen.wait() # *.kill(), *.terminate()&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; out, err = slope_aspect.popen.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for more info on the Module class look at: http://pygrass.readthedocs.org/en/latest/modules.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Work on the Vector interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, I need to better understand of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
== Report9 - 2012-07-27 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
I've worked on vector API, in particular on geometry feature.&lt;br /&gt;
&lt;br /&gt;
====Point====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* class Point(x, y, z=None, is2D=True)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.x&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.y&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
False&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt&lt;br /&gt;
Point(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print pnt&lt;br /&gt;
POINT(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return an Area object using the Vect_point_buffer2 C function. Creates buffer around the point (px, py).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* coords()&lt;br /&gt;
Return a tuple with the point coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
If the point is 2D return a x, y tuple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Calculate distance of 2 points, using the Vect_points_distance C function, If one of the point have z == None, return the 2D distance.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0 = Point(0, 0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1 = Point(1, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1.z = 1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1&lt;br /&gt;
Point(1.000000, 0.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.4142135623730951&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The distance method require a :class:Point or a tuple with the coordinates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkb()&lt;br /&gt;
Return a “well know binary” (WKB) geometry buffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a “well know text” (WKT) geometry string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.get_wkt()&lt;br /&gt;
'POINT(0.000000, 0.000000)'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Only POINT (2/3D) are supported, POINTM and POINT with: XYZM are not supported yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line====&lt;br /&gt;
&lt;br /&gt;
class Line(points=None, mapinfo=None, lineid=None, field=None, is2D=True)&lt;br /&gt;
Instantiate a new Line with a list of tuple, or with a list of Point.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                               &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, -1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* append(pnt)&lt;br /&gt;
Appends one point to the end of a line, using the Vect_append_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((10, 100))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((20, 200))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000), Point(20.000000, 200.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* bbox()&lt;br /&gt;
Return the bounding box of the line, using Vect_line_box C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (0, 1), (2, 1), (2, 0)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox = line.bbox()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.north&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.south&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.east&lt;br /&gt;
2.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.west&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.top&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.bottom&lt;br /&gt;
0.0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
It is possible to access to the C struct of the object with: bbox.c_bbox&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return the buffer area around the line, using the Vect_line_buffer2 C function.&lt;br /&gt;
Not implemented yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* delete(indx)&lt;br /&gt;
Remove the point in the index position.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.delete(-1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Return a tuple with: &lt;br /&gt;
  - the closest point on the line,&lt;br /&gt;
  - the distance between these two points,&lt;br /&gt;
  - distance of point from segment beginning&lt;br /&gt;
  - distance of point from line&lt;br /&gt;
The distance is compute using the Vect_line_distance C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* extend(line, forward=True)&lt;br /&gt;
Appends points to the end of a line.&lt;br /&gt;
&lt;br /&gt;
It is possible to extend a line, give a list of points, or directly with a line_pnts struct.&lt;br /&gt;
&lt;br /&gt;
If forward is True the line is extend forward otherwise is extend backward. The method use the Vect_append_points C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.extend( Line([(2, 2), (3, 3)]) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000),&lt;br /&gt;
      Point(3.000000, 3.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list, it is possible to extend a line, with another line or with a list of points.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* from_wkt(wkt)&lt;br /&gt;
Read a WKT string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.from_wkt(&amp;quot;LINESTRING(0 0,1 1,1 2)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(1.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_first_cat()&lt;br /&gt;
Fetches FIRST category number for given vector line and field, using the Vect_get_line_cat C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_pnt(distance, angle=0, slope=0)&lt;br /&gt;
Return a Point object on line in the specified distance, using the Vect_point_on_line C function. Raise a ValueError If the distance exceed the Line length.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(5)                           &lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
    ...&lt;br /&gt;
ValueError: The distance exceed the lenght of the line, that is: 1.414214&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(1)&lt;br /&gt;
Point(0.707107, 0.707107)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a Well Known Text string of the line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_wkt()&lt;br /&gt;
'LINESTRING(0.000000 0.000000, 1.000000 1.000000, 1.000000 2.000000)'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* insert(indx, pnt)&lt;br /&gt;
Insert new point at index position and move all old points at that position and above up, using Vect_line_insert_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.insert(0, Point(1.000000, -1.000000) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(1.000000, -1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length()&lt;br /&gt;
Calculate line length, 3D-length in case of 3D vector line, using Vect_line_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length_geodesic()&lt;br /&gt;
Calculate line length, usig Vect_line_geodesic_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length_geodesic()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* pop(indx)&lt;br /&gt;
Return the point in the index position and remove from the Line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt = line.pop(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune()&lt;br /&gt;
Remove duplicate points, i.e. zero length segments, using Vect_line_prune C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.prune()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune_thresh(threshold)&lt;br /&gt;
Remove points in threshold, using the Vect_line_prune_thresh C funtion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* remove(pnt)&lt;br /&gt;
Delete point at given index and move all points above down, using Vect_line_delete_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.remove((2, 2))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line[-1]&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reset()&lt;br /&gt;
Reset line, using Vect_reset_line C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reset()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reverse() &lt;br /&gt;
Reverse the order of vertices, using Vect_line_reverse C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reverse()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(2.000000, 2.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* segment(start, end)&lt;br /&gt;
Create line segment. using the Vect_line_segment C function.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* toarray()&lt;br /&gt;
Return an array of coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.toarray()                 &lt;br /&gt;
array([[ 0.,  0.],&lt;br /&gt;
       [ 1.,  1.],&lt;br /&gt;
       [ 2.,  0.],&lt;br /&gt;
       [ 1., -1.]])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* tolist()&lt;br /&gt;
Return a list of tuple.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.tolist()&lt;br /&gt;
[(0.0, 0.0), (1.0, 1.0), (2.0, 0.0), (1.0, -1.0)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the other vector features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, but I need more time to assimilate the ideas of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report10 - 2012-08-03 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the vector API, add more geometry feature like border, isle, and area, clean the code and study vector documentation and functions.&lt;br /&gt;
This week I did an university exam, the last one for this summer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Start to test the new vector classes add test and documentation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
As the last week I'm studying more and more the vector API of GRASS, I would like to have more time... :-)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16244</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16244"/>
		<updated>2012-07-27T21:19:47Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report9 - 2012-07-27 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[GRASS SoC Ideas 2012/High level map interaction/Vector]] for more info.&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== Report8 - 2012-07-20 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the pygrass modules class and start to study the GRASS vector API.&lt;br /&gt;
Yesterday and today I had some troubles with my OS installation and hard disk.&lt;br /&gt;
&lt;br /&gt;
The Module class read the xml module description and instantiate a Module class, that is a callable object, user can change parameters, and the object check if the parameter are or not valid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from pygrass.modules import Module&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp',  aspect='asp',&lt;br /&gt;
...              format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or it is possible to run all in one line, similar to run_command, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Module class allow user to run the command later, with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True, run_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class allow to manage the process, and read stdout and stderr, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module('r.slope.aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp', aspect='asp', overwrite=True, finish_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect.popen.wait() # *.kill(), *.terminate()&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; out, err = slope_aspect.popen.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for more info on the Module class look at: http://pygrass.readthedocs.org/en/latest/modules.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Work on the Vector interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, I need to better understand of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
== Report9 - 2012-07-27 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
I've worked on vector API, in particular on geometry feature.&lt;br /&gt;
&lt;br /&gt;
====Point====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* class Point(x, y, z=None, is2D=True)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.x&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.y&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.z = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.is2D&lt;br /&gt;
False&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt&lt;br /&gt;
Point(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print pnt&lt;br /&gt;
POINT(0.000000, 0.000000, 0.000000)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return an Area object using the Vect_point_buffer2 C function. Creates buffer around the point (px, py).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* coords()&lt;br /&gt;
Return a tuple with the point coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.coords()&lt;br /&gt;
(0.0, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
If the point is 2D return a x, y tuple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Calculate distance of 2 points, using the Vect_points_distance C function, If one of the point have z == None, return the 2D distance.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0 = Point(0, 0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1 = Point(1, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1.z = 1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1&lt;br /&gt;
Point(1.000000, 0.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0.distance(pnt1)&lt;br /&gt;
1.4142135623730951&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The distance method require a :class:Point or a tuple with the coordinates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkb()&lt;br /&gt;
Return a “well know binary” (WKB) geometry buffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a “well know text” (WKT) geometry string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt = Point(0, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt.get_wkt()&lt;br /&gt;
'POINT(0.000000, 0.000000)'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Only POINT (2/3D) are supported, POINTM and POINT with: XYZM are not supported yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line====&lt;br /&gt;
&lt;br /&gt;
class Line(points=None, mapinfo=None, lineid=None, field=None, is2D=True)&lt;br /&gt;
Instantiate a new Line with a list of tuple, or with a list of Point.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                               &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, -1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* append(pnt)&lt;br /&gt;
Appends one point to the end of a line, using the Vect_append_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((10, 100))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.append((20, 200))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(10.000000, 100.000000), Point(20.000000, 200.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* bbox()&lt;br /&gt;
Return the bounding box of the line, using Vect_line_box C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (0, 1), (2, 1), (2, 0)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox = line.bbox()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.north&lt;br /&gt;
1.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.south&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.east&lt;br /&gt;
2.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.west&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.top&lt;br /&gt;
0.0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bbox.bottom&lt;br /&gt;
0.0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
It is possible to access to the C struct of the object with: bbox.c_bbox&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* buffer(dist=None, dist_x=None, dist_y=None, angle=0, round_=True, tol=0.1)&lt;br /&gt;
Return the buffer area around the line, using the Vect_line_buffer2 C function.&lt;br /&gt;
Not implemented yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* delete(indx)&lt;br /&gt;
Remove the point in the index position.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.delete(-1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* distance(pnt)&lt;br /&gt;
Return a tuple with: &lt;br /&gt;
  - the closest point on the line,&lt;br /&gt;
  - the distance between these two points,&lt;br /&gt;
  - distance of point from segment beginning&lt;br /&gt;
  - distance of point from line&lt;br /&gt;
The distance is compute using the Vect_line_distance C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* extend(line, forward=True)&lt;br /&gt;
Appends points to the end of a line.&lt;br /&gt;
&lt;br /&gt;
It is possible to extend a line, give a list of points, or directly with a line_pnts struct.&lt;br /&gt;
&lt;br /&gt;
If forward is True the line is extend forward otherwise is extend backward. The method use the Vect_append_points C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.extend( Line([(2, 2), (3, 3)]) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000),&lt;br /&gt;
      Point(3.000000, 3.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Like python list, it is possible to extend a line, with another line or with a list of points.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* from_wkt(wkt)&lt;br /&gt;
Read a WKT string.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.from_wkt(&amp;quot;LINESTRING(0 0,1 1,1 2)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(1.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_first_cat()&lt;br /&gt;
Fetches FIRST category number for given vector line and field, using the Vect_get_line_cat C function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_pnt(distance, angle=0, slope=0)&lt;br /&gt;
Return a Point object on line in the specified distance, using the Vect_point_on_line C function. Raise a ValueError If the distance exceed the Line length.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(5)                           &lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
    ...&lt;br /&gt;
ValueError: The distance exceed the lenght of the line, that is: 1.414214&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_pnt(1)&lt;br /&gt;
Point(0.707107, 0.707107)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get_wkt()&lt;br /&gt;
Return a Well Known Text string of the line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.get_wkt()&lt;br /&gt;
'LINESTRING(0.000000 0.000000, 1.000000 1.000000, 1.000000 2.000000)'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* insert(indx, pnt)&lt;br /&gt;
Insert new point at index position and move all old points at that position and above up, using Vect_line_insert_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.insert(0, Point(1.000000, -1.000000) )&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(1.000000, -1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length()&lt;br /&gt;
Calculate line length, 3D-length in case of 3D vector line, using Vect_line_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* length_geodesic()&lt;br /&gt;
Calculate line length, usig Vect_line_geodesic_length C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (0, 1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.length_geodesic()&lt;br /&gt;
2.414213562373095&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* pop(indx)&lt;br /&gt;
Return the point in the index position and remove from the Line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt = line.pop(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; midle_pnt&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([Point(0.000000, 0.000000), Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune()&lt;br /&gt;
Remove duplicate points, i.e. zero length segments, using Vect_line_prune C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.prune()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(0.000000, 0.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(2.000000, 2.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* prune_thresh(threshold)&lt;br /&gt;
Remove points in threshold, using the Vect_line_prune_thresh C funtion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* remove(pnt)&lt;br /&gt;
Delete point at given index and move all points above down, using Vect_line_delete_point C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.remove((2, 2))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line[-1]&lt;br /&gt;
Point(1.000000, 1.000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reset()&lt;br /&gt;
Reset line, using Vect_reset_line C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reset()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; len(line)&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line&lt;br /&gt;
Line([])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* reverse() &lt;br /&gt;
Reverse the order of vertices, using Vect_line_reverse C function.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 2)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.reverse()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line                           &lt;br /&gt;
Line([Point(2.000000, 2.000000),&lt;br /&gt;
      Point(1.000000, 1.000000),&lt;br /&gt;
      Point(0.000000, 0.000000)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* segment(start, end)&lt;br /&gt;
Create line segment. using the Vect_line_segment C function.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* toarray()&lt;br /&gt;
Return an array of coordinates.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.toarray()                 &lt;br /&gt;
array([[ 0.,  0.],&lt;br /&gt;
       [ 1.,  1.],&lt;br /&gt;
       [ 2.,  0.],&lt;br /&gt;
       [ 1., -1.]])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* tolist()&lt;br /&gt;
Return a list of tuple.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line.tolist()&lt;br /&gt;
[(0.0, 0.0), (1.0, 1.0), (2.0, 0.0), (1.0, -1.0)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the other vector features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, but I need more time to assimilate the ideas of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16215</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16215"/>
		<updated>2012-07-20T13:12:13Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report8 - 2012-07-20 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[GRASS SoC Ideas 2012/High level map interaction/Vector]] for more info.&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== Report8 - 2012-07-20 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the pygrass modules class and start to study the GRASS vector API.&lt;br /&gt;
Yesterday and today I had some troubles with my OS installation and hard disk.&lt;br /&gt;
&lt;br /&gt;
The Module class read the xml module description and instantiate a Module class, that is a callable object, user can change parameters, and the object check if the parameter are or not valid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from pygrass.modules import Module&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp',  aspect='asp',&lt;br /&gt;
...              format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or it is possible to run all in one line, similar to run_command, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Module class allow user to run the command later, with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module(&amp;quot;r.slope.aspect&amp;quot;, elevation='elevation',&lt;br /&gt;
...                        slope='slp',  aspect='asp',&lt;br /&gt;
...                        format='percent', overwrite=True, run_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class allow to manage the process, and read stdout and stderr, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect = Module('r.slope.aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect(elevation='elevation', slope='slp', aspect='asp', overwrite=True, finish_=False)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope_aspect.popen.wait() # *.kill(), *.terminate()&lt;br /&gt;
0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; out, err = slope_aspect.popen.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for more info on the Module class look at: http://pygrass.readthedocs.org/en/latest/modules.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Work on the Vector interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Not really, I need to better understand of the GRASS vector API.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16214</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16214"/>
		<updated>2012-07-20T12:58:23Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Project plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[GRASS SoC Ideas 2012/High level map interaction/Vector]] for more info.&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_SoC_Ideas_2012/High_level_map_interaction/Vector&amp;diff=16178</id>
		<title>GRASS SoC Ideas 2012/High level map interaction/Vector</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_SoC_Ideas_2012/High_level_map_interaction/Vector&amp;diff=16178"/>
		<updated>2012-07-16T18:55:34Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: vector brain storming&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Vector Maps=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vector Geometries==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I would like to implement different Geometry classes:&lt;br /&gt;
&lt;br /&gt;
* point&lt;br /&gt;
* (segment)&lt;br /&gt;
* line&lt;br /&gt;
* boundary&lt;br /&gt;
* centroid&lt;br /&gt;
* area&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0 = Point(x0, y0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt1 = Point(x1, y1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt2 = Point(x2, y2)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line0 = Line([pnt0, pnt1, pnt2])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bound0 = Boundary([pnt0, pnt1, pnt2])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; area = Area(bount0, Centroid(x3, y3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Line attributes and methods===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Line should have attributes, like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line0.length # return the length&lt;br /&gt;
960.5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line0.bbox # return the bbox&amp;gt;&amp;gt;&amp;gt; for segment in line.nseg&lt;br /&gt;
2&lt;br /&gt;
(pnt0, pnt1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; line0.number # return the number line&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for segment in line.nseg # return the number of segments&lt;br /&gt;
2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Line is iterable and return a point object.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for point in line0:&lt;br /&gt;
...     # do somenthing&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Line should have a method to return a Segments.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for segment in line.segs(): &lt;br /&gt;
...     # return a list of tuple [(pnt0, pnt1), (pnt1, pnt2),]&lt;br /&gt;
...     # do somethig&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; pnt0 in line0 # check if line contain point&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; lineX in line0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Boundary===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bound0.perimeter()&lt;br /&gt;
1023.8&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; bound.nseg # return the number of segments&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for point in bound0:&lt;br /&gt;
...     # do something&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for seg in bound0.segs():&lt;br /&gt;
...     # do something&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Area===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; area0.boundary # return a boundary object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; area0.centroid #return a point object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; area0.area() &lt;br /&gt;
2034&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
All the geometries object should have methods like the python sets (may be not all):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Operation	Equivalent	Result&lt;br /&gt;
len(s)	 	return the number of points&lt;br /&gt;
x in s	 	test x for membership in s&lt;br /&gt;
x not in s	 	test x for non-membership in s&lt;br /&gt;
s.issubset(t)	s &amp;lt;= t	test whether every element in s is in t&lt;br /&gt;
s.issuperset(t)	s &amp;gt;= t	test whether every element in t is in s&lt;br /&gt;
s.union(t)	s | t	new set with elements from both s and t&lt;br /&gt;
s.intersection(t)	s &amp;amp; t	new set with elements common to s and t&lt;br /&gt;
s.difference(t)	s - t	new set with elements in s but not in t&lt;br /&gt;
s.symmetric_difference(t)	s ^ t	new set with elements in either s or t but not both&lt;br /&gt;
s.copy()	 	new set with a shallow copy of s&lt;br /&gt;
&lt;br /&gt;
more details on python sets here:&lt;br /&gt;
&lt;br /&gt;
http://docs.python.org/library/sets.html#set-objects&lt;br /&gt;
&lt;br /&gt;
and/or use some methods like shapely:&lt;br /&gt;
&lt;br /&gt;
http://toblerity.github.com/shapely/manual.html#binary-predicates&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
http://toblerity.github.com/shapely/manual.html#spatial-analysis-methods&lt;br /&gt;
&lt;br /&gt;
another possibility could be to include shapely to add a native support to grass and topology.&lt;br /&gt;
&lt;br /&gt;
And point, line, boundary and Area should have a:&lt;br /&gt;
* buffer method, that return an Area object.&lt;br /&gt;
* distance method, that return the minimal distance between objcts&lt;br /&gt;
* wkt, return a well know text&lt;br /&gt;
* wkb, return well know binary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vector obj==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vect obj should have attributes like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; roads = Vect('roads')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; roads.name&lt;br /&gt;
'roads'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As for raster object should have an history object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; road.hist.creator&lt;br /&gt;
'pietro'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; roads.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; roads.isopen()&lt;br /&gt;
False&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in roads:&lt;br /&gt;
...     # do something&lt;br /&gt;
...     &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; roads.open(topology = True)&lt;br /&gt;
&lt;br /&gt;
===Layer===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Topology===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Categories===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Attributes table===&lt;br /&gt;
&lt;br /&gt;
The attributes table should be inherit from Structured Array class&lt;br /&gt;
&lt;br /&gt;
http://docs.scipy.org/doc/numpy/user/basics.rec.html#structured-arrays&lt;br /&gt;
&lt;br /&gt;
Vector should have a connection attribute:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; roads.connect&lt;br /&gt;
Connection (db='postgresql', user='pietro', etc.)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; roads.exist()&lt;br /&gt;
False&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; roads.attributes # return a OrderedDict&lt;br /&gt;
OrderedDict([('cat', int),('name', str),('geo', geometry)])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we can add a new column with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; roads.attributes['length'] = float&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
...     road['length'] = road.length&lt;br /&gt;
&lt;br /&gt;
#as for numpy array:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; (roads['length'] &amp;lt;= 1000).nonzero() # return the index of all the roads that respect this conditions &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
allow SQL query:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; roads.sql(&amp;quot;SELECT * FROM roads WHERE length &amp;lt;= 1000 ORDER BY length LIMIT 100&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16131</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16131"/>
		<updated>2012-07-13T20:58:03Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report7 - 2012-07-13 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report7 - 2012-07-13 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Start to work on the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Continue with the the pygrass modules class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, I wrote a first implementation of the pygrass modules, but after discussion with my mentor I have started to rewrite the class.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Pylint_rc_file_for_GRASS&amp;diff=16103</id>
		<title>Pylint rc file for GRASS</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Pylint_rc_file_for_GRASS&amp;diff=16103"/>
		<updated>2012-07-11T09:31:06Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Pylint rc file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pylint is static code analyser for Python. You can use it for detecting errors in your source codes or to help follow coding standards. However, default Pylint configuration is not compatible with GRASS Python coding style. The rc file is on this page (use copy and paste). You can specify it rc file by &amp;lt;tt&amp;gt;--rcfile&amp;lt;/tt&amp;gt; Pylint's command line option:&lt;br /&gt;
 pylint --rcfile=grass_pylintrc module_or_package&lt;br /&gt;
If you are using Python editor which allows Pylint analysis but not allows specify Pylint's command line parameters (e.g. Spyder) you can create or replace &amp;lt;tt&amp;gt;.pylintrc&amp;lt;/tt&amp;gt; file in your home directory.&lt;br /&gt;
 # for GNU/Linux&lt;br /&gt;
 cd ~&lt;br /&gt;
 cp .pylintrc .pylintrc_old&lt;br /&gt;
 cp grass_pylintrc .pylintrc&lt;br /&gt;
&lt;br /&gt;
Note that you can also use Pylint for error checking only:&lt;br /&gt;
 pylint --errors-only module_or_package&lt;br /&gt;
&lt;br /&gt;
== Pylint rc file ==&lt;br /&gt;
&lt;br /&gt;
''This version is not (yet) suitable for wxGUI but can be used for Python scripts.''&lt;br /&gt;
&lt;br /&gt;
Get a copy of the file with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git clone git://gist.github.com/3089272.git gist-3089272&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The content is: https://gist.github.com/3089272&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[MASTER]&lt;br /&gt;
&lt;br /&gt;
# Specify a configuration file.&lt;br /&gt;
#rcfile=&lt;br /&gt;
&lt;br /&gt;
# Python code to execute, usually for sys.path manipulation such as&lt;br /&gt;
# pygtk.require().&lt;br /&gt;
#init-hook=&lt;br /&gt;
&lt;br /&gt;
# Profiled execution.&lt;br /&gt;
profile=no&lt;br /&gt;
&lt;br /&gt;
# Add files or directories to the blacklist. They should be base names, not&lt;br /&gt;
# paths.&lt;br /&gt;
ignore=CVS&lt;br /&gt;
&lt;br /&gt;
# Pickle collected data for later comparisons.&lt;br /&gt;
persistent=yes&lt;br /&gt;
&lt;br /&gt;
# List of plugins (as comma separated values of python modules names) to load,&lt;br /&gt;
# usually to register additional checkers.&lt;br /&gt;
load-plugins=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[MESSAGES CONTROL]&lt;br /&gt;
&lt;br /&gt;
# Enable the message, report, category or checker with the given id(s). You can&lt;br /&gt;
# either give multiple identifier separated by comma (,) or put this option&lt;br /&gt;
# multiple time.&lt;br /&gt;
#enable=&lt;br /&gt;
&lt;br /&gt;
# Disable the message, report, category or checker with the given id(s). You&lt;br /&gt;
# can either give multiple identifier separated by comma (,) or put this option&lt;br /&gt;
# multiple time (only on the command line, not in the configuration file where&lt;br /&gt;
# it should appear only once).&lt;br /&gt;
#disable=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[REPORTS]&lt;br /&gt;
&lt;br /&gt;
# Set the output format. Available formats are text, parseable, colorized, msvs&lt;br /&gt;
# (visual studio) and html&lt;br /&gt;
output-format=text&lt;br /&gt;
&lt;br /&gt;
# Include message's id in output&lt;br /&gt;
include-ids=no&lt;br /&gt;
&lt;br /&gt;
# Put messages in a separate file for each module / package specified on the&lt;br /&gt;
# command line instead of printing them on stdout. Reports (if any) will be&lt;br /&gt;
# written in a file name &amp;quot;pylint_global.[txt|html]&amp;quot;.&lt;br /&gt;
files-output=no&lt;br /&gt;
&lt;br /&gt;
# Tells whether to display a full report or only the messages&lt;br /&gt;
reports=yes&lt;br /&gt;
&lt;br /&gt;
# Python expression which should return a note less than 10 (10 is the highest&lt;br /&gt;
# note). You have access to the variables errors warning, statement which&lt;br /&gt;
# respectively contain the number of errors / warnings messages and the total&lt;br /&gt;
# number of statements analyzed. This is used by the global evaluation report&lt;br /&gt;
# (RP0004).&lt;br /&gt;
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)&lt;br /&gt;
&lt;br /&gt;
# Add a comment according to your evaluation note. This is used by the global&lt;br /&gt;
# evaluation report (RP0004).&lt;br /&gt;
comment=no&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[VARIABLES]&lt;br /&gt;
&lt;br /&gt;
# Tells whether we should check for unused import in __init__ files.&lt;br /&gt;
init-import=yes&lt;br /&gt;
&lt;br /&gt;
# A regular expression matching the beginning of the name of dummy variables&lt;br /&gt;
# (i.e. not used).&lt;br /&gt;
dummy-variables-rgx=_|dummy&lt;br /&gt;
&lt;br /&gt;
# List of additional names supposed to be defined in builtins. Remember that&lt;br /&gt;
# you should avoid to define new builtins when possible.&lt;br /&gt;
additional-builtins=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[BASIC]&lt;br /&gt;
&lt;br /&gt;
# Required attributes for module, separated by a comma&lt;br /&gt;
required-attributes=&lt;br /&gt;
&lt;br /&gt;
# List of builtins function names that should not be used, separated by a comma&lt;br /&gt;
bad-functions=map,filter,apply,input&lt;br /&gt;
&lt;br /&gt;
# Regular expression which should only match correct module names&lt;br /&gt;
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$&lt;br /&gt;
&lt;br /&gt;
# Regular expression which should only match correct module level names&lt;br /&gt;
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$&lt;br /&gt;
&lt;br /&gt;
# Regular expression which should only match correct class names&lt;br /&gt;
class-rgx=[A-Z_][a-zA-Z0-9]+$&lt;br /&gt;
&lt;br /&gt;
# Regular expression which should only match correct function names&lt;br /&gt;
function-rgx=[a-z_][a-zA-Z0-9_]{2,30}$&lt;br /&gt;
&lt;br /&gt;
# Regular expression which should only match correct method names&lt;br /&gt;
method-rgx=[a-z_][a-zA-Z0-9_]{2,30}$&lt;br /&gt;
&lt;br /&gt;
# Regular expression which should only match correct instance attribute names&lt;br /&gt;
attr-rgx=[a-z_][a-zA-Z0-9_]{2,30}$&lt;br /&gt;
&lt;br /&gt;
# Regular expression which should only match correct argument names&lt;br /&gt;
argument-rgx=[a-z_][a-zA-Z0-9_]{2,30}$&lt;br /&gt;
&lt;br /&gt;
# Regular expression which should only match correct variable names&lt;br /&gt;
variable-rgx=[a-z_][a-zA-Z0-9_]{2,30}$|[a-z]&lt;br /&gt;
&lt;br /&gt;
# Regular expression which should only match correct list comprehension /&lt;br /&gt;
# generator expression variable names&lt;br /&gt;
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$&lt;br /&gt;
&lt;br /&gt;
# Good variable names which should always be accepted, separated by a comma&lt;br /&gt;
good-names=i,j,_,x,y,z,N,E,S,W&lt;br /&gt;
&lt;br /&gt;
# Bad variable names which should always be refused, separated by a comma&lt;br /&gt;
bad-names=foo,bar,baz,toto,tutu,tata&lt;br /&gt;
&lt;br /&gt;
# Regular expression which should only match functions or classes name which do&lt;br /&gt;
# not require a docstring&lt;br /&gt;
no-docstring-rgx=__.*__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[MISCELLANEOUS]&lt;br /&gt;
&lt;br /&gt;
# List of note tags to take in consideration, separated by a comma.&lt;br /&gt;
notes=FIXME,TODO&lt;br /&gt;
&lt;br /&gt;
# general regexp for convention, warning etc. would be great&lt;br /&gt;
&lt;br /&gt;
[TYPECHECK]&lt;br /&gt;
&lt;br /&gt;
# Tells whether missing members accessed in mixin class should be ignored. A&lt;br /&gt;
# mixin class is detected if its name ends with &amp;quot;mixin&amp;quot; (case insensitive).&lt;br /&gt;
ignore-mixin-members=yes&lt;br /&gt;
&lt;br /&gt;
# List of classes names for which member attributes should not be checked&lt;br /&gt;
# (useful for classes with attributes dynamically set).&lt;br /&gt;
ignored-classes=SQLObject&lt;br /&gt;
&lt;br /&gt;
# When zope mode is activated, add a predefined set of Zope acquired attributes&lt;br /&gt;
# to generated-members.&lt;br /&gt;
zope=no&lt;br /&gt;
&lt;br /&gt;
# List of members which are set dynamically and missed by pylint inference&lt;br /&gt;
# system, and so shouldn't trigger E0201 when accessed. Python regular&lt;br /&gt;
# expressions are accepted.&lt;br /&gt;
generated-members=REQUEST,acl_users,aq_parent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[FORMAT]&lt;br /&gt;
&lt;br /&gt;
# Maximum number of characters on a single line.&lt;br /&gt;
max-line-length=80&lt;br /&gt;
&lt;br /&gt;
# Maximum number of lines in a module&lt;br /&gt;
max-module-lines=1000&lt;br /&gt;
&lt;br /&gt;
# String used as indentation unit. This is usually &amp;quot; &amp;quot; (4 spaces) or &amp;quot;\t&amp;quot; (1&lt;br /&gt;
# tab).&lt;br /&gt;
indent-string='    '&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[SIMILARITIES]&lt;br /&gt;
&lt;br /&gt;
# Minimum lines number of a similarity.&lt;br /&gt;
min-similarity-lines=4&lt;br /&gt;
&lt;br /&gt;
# Ignore comments when computing similarities.&lt;br /&gt;
ignore-comments=yes&lt;br /&gt;
&lt;br /&gt;
# Ignore docstrings when computing similarities.&lt;br /&gt;
ignore-docstrings=yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[DESIGN]&lt;br /&gt;
&lt;br /&gt;
# Maximum number of arguments for function / method&lt;br /&gt;
max-args=5&lt;br /&gt;
&lt;br /&gt;
# Argument names that match this expression will be ignored. Default to name&lt;br /&gt;
# with leading underscore&lt;br /&gt;
ignored-argument-names=_.*&lt;br /&gt;
&lt;br /&gt;
# Maximum number of locals for function / method body&lt;br /&gt;
max-locals=15&lt;br /&gt;
&lt;br /&gt;
# Maximum number of return / yield for function / method body&lt;br /&gt;
max-returns=6&lt;br /&gt;
&lt;br /&gt;
# Maximum number of branch for function / method body&lt;br /&gt;
max-branchs=12&lt;br /&gt;
&lt;br /&gt;
# Maximum number of statements in function / method body&lt;br /&gt;
max-statements=50&lt;br /&gt;
&lt;br /&gt;
# Maximum number of parents for a class (see R0901).&lt;br /&gt;
max-parents=7&lt;br /&gt;
&lt;br /&gt;
# Maximum number of attributes for a class (see R0902).&lt;br /&gt;
max-attributes=7&lt;br /&gt;
&lt;br /&gt;
# Minimum number of public methods for a class (see R0903).&lt;br /&gt;
min-public-methods=2&lt;br /&gt;
&lt;br /&gt;
# Maximum number of public methods for a class (see R0904).&lt;br /&gt;
max-public-methods=20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[IMPORTS]&lt;br /&gt;
&lt;br /&gt;
# Deprecated modules which should not be used, separated by a comma&lt;br /&gt;
deprecated-modules=regsub,string,TERMIOS,Bastion,rexec&lt;br /&gt;
&lt;br /&gt;
# Create a graph of every (i.e. internal and external) dependencies in the&lt;br /&gt;
# given file (report RP0402 must not be disabled)&lt;br /&gt;
import-graph=&lt;br /&gt;
&lt;br /&gt;
# Create a graph of external dependencies in the given file (report RP0402 must&lt;br /&gt;
# not be disabled)&lt;br /&gt;
ext-import-graph=&lt;br /&gt;
&lt;br /&gt;
# Create a graph of internal dependencies in the given file (report RP0402 must&lt;br /&gt;
# not be disabled)&lt;br /&gt;
int-import-graph=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[CLASSES]&lt;br /&gt;
&lt;br /&gt;
# List of interface methods to ignore, separated by a comma. This is used for&lt;br /&gt;
# instance to not check methods defines in Zope's Interface base class.&lt;br /&gt;
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by&lt;br /&gt;
&lt;br /&gt;
# List of method names used to declare (i.e. assign) instance attributes.&lt;br /&gt;
defining-attr-methods=__init__,__new__,setUp&lt;br /&gt;
&lt;br /&gt;
# List of valid names for the first argument in a class method.&lt;br /&gt;
valid-classmethod-first-arg=cls&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[EXCEPTIONS]&lt;br /&gt;
&lt;br /&gt;
# Exceptions that will emit a warning when being caught. Defaults to&lt;br /&gt;
# &amp;quot;Exception&amp;quot;&lt;br /&gt;
overgeneral-exceptions=Exception&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Python}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16060</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16060"/>
		<updated>2012-07-06T15:56:45Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report6 - 2012-07-06 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== Report6 - 2012-07-06 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Add categories to the Raster classes:&lt;br /&gt;
&lt;br /&gt;
All the raster classes support raster categories and share commons methods to modify the raster category. It is possible to check if the map has or not the categories with the has_cats method.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.has_cats()&lt;br /&gt;
False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Opening a map that has category, for example the “landcove_1m” raster map from the North Carolina mapset. The has_cats method return True.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land = pygrass.RasterRow('landcover_1m')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.has_cats()&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get and set the categories title, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title&lt;br /&gt;
'Rural area: Landcover2'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats_title = 'Rural area: Landcover'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the number of categories of the map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.num_cats()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See all the categories with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats&lt;br /&gt;
[('pond', 1, None),&lt;br /&gt;
 ('forest', 2, None),&lt;br /&gt;
 ('developed', 3, None),&lt;br /&gt;
 ('bare', 4, None),&lt;br /&gt;
 ('paved road', 5, None),&lt;br /&gt;
 ('dirt road', 6, None),&lt;br /&gt;
 ('vineyard', 7, None),&lt;br /&gt;
 ('agriculture', 8, None),&lt;br /&gt;
 ('wetland', 9, None),&lt;br /&gt;
 ('bare ground path', 10, None),&lt;br /&gt;
 ('grass', 11, None)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access to single category, using Rast_get_ith_cat(), with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats[0]&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.cats['pond']&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat(0)&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('pond')&lt;br /&gt;
('pond', 1, None)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add new or change existing categories:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('label', 1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.get_cat('label')&lt;br /&gt;
('label', 1, None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cat('pond', 1, 1)&lt;br /&gt;
Sort categories, with:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.sort_cats()&lt;br /&gt;
Copy categories from another raster map with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.copy_cats(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read and Write:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; #land.write_cats()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a Category object or set from a Category object:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; cats = land.get_cats()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.set_cats(cats)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export and import from a file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.write_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; land.read_cats_rules('land_rules.csv', ';')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a new History class:&lt;br /&gt;
&lt;br /&gt;
Instantiate a new object, with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist = pygrass.History()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
read the history of a map:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.read('aspect')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then it is possible to read and change the history attributes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator&lt;br /&gt;
'helena'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.creator = 'pietro'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src1&lt;br /&gt;
'raster elevation file elev_ned10m'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.src2&lt;br /&gt;
''&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.keyword&lt;br /&gt;
'generated by r.slope.aspect'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.date&lt;br /&gt;
datetime.datetime(2006, 11, 7, 1, 11, 23)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.mapset&lt;br /&gt;
'PERMANENT'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.maptype&lt;br /&gt;
'raster'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hist.title&lt;br /&gt;
'asp_ned10m'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will work on a function factory to wrap all the Grass modules and see and interact with module as python functions.&lt;br /&gt;
&lt;br /&gt;
I would like something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev, slope, aspect, dxx = r.slope_aspect(elevation='elevation', &lt;br /&gt;
...                                           slope='slope',&lt;br /&gt;
...                                           aspect='aspect', &lt;br /&gt;
...                                           dxx='dxx', overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass.modules.raster as r&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; slope = pygrass.RasterRowIO('slope')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; aspect = pygrass.RasterSegment('aspect')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; dxx = pygrass.RasterNumpy('dxx')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; r.slope_aspect(elevation=elev, slope=slope aspect=aspect, dxx=dxx, overwrite = True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The behavior and the implementation need to be discuss with my mentor. This is just an idea.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16059</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16059"/>
		<updated>2012-07-06T15:25:38Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Project plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRASS as Python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call GRASS as a normal Python library outside GRASS environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16013</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=16013"/>
		<updated>2012-06-29T20:01:47Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /*  Report 5 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || missing&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== Report5 - 2012-06-29 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, it's working now:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation', 'PERMANENT')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
       [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
       [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
       [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
       [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [1, 1, 1],&lt;br /&gt;
       [0, 0, 0],&lt;br /&gt;
       [0, 0, 0]], dtype=int32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name == None&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # give a name to the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.remove()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the RasterNumpy class to the benchmarks.&lt;br /&gt;
Start to study the C API to implement the categories.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on to develop categories support for the raster classes,&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15996</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15996"/>
		<updated>2012-06-22T17:55:11Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report4 - 2012-06-22 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || missing&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== Report4 - 2012-06-22 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Change names, and add new directories (obj =&amp;gt; pygrass, docs, tests).&lt;br /&gt;
Start the documentation of the [http://pygrass.readthedocs.org/en/latest/raster.html | pygrass ]. Complete the RowIO class, and start to develop the RasterNumpy class. Start to develop tests using unittest. Benchmark the library, and compare the result with r.mapcalc.&lt;br /&gt;
Met the co-mentors (Luca de Lucchi and Martin Landa) to illustrate the work done and discuss with them the next steps.&lt;br /&gt;
&lt;br /&gt;
What can you do with the RowIO library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterRowIO('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the RasterNumpy class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import pygrass&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = pygrass.RasterNumpy('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # in this case RasterNumpy is an extention of the numpy class&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # therefore you may use all the fancy things of numpy.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[:5, :3]&lt;br /&gt;
RasterNumpy([[ 141.99613953,  141.27848816,  141.37904358],&lt;br /&gt;
   [ 142.90461731,  142.39450073,  142.68611145],&lt;br /&gt;
   [ 143.81854248,  143.54707336,  143.83972168],&lt;br /&gt;
   [ 144.56524658,  144.58493042,  144.86477661],&lt;br /&gt;
   [ 144.99488831,  145.22894287,  145.57142639]], dtype=float32)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = elev &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el[:5, :3]&lt;br /&gt;
RasterNumpy([[ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [ True,  True,  True],&lt;br /&gt;
   [False, False, False],&lt;br /&gt;
   [False, False, False]], dtype=bool)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.name = 'new'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el.close()&lt;br /&gt;
&lt;br /&gt;
# but I have problem to read the new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = pygrass.RasterNumpy('new', mtype = 'CELL')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[:5,:3]&lt;br /&gt;
RasterNumpy([[1124990723, 1124943691, 1124950281],&lt;br /&gt;
       [1125050261, 1125016830, 1125035941],&lt;br /&gt;
       [1125110156, 1125092365, 1125111544],&lt;br /&gt;
       [1125159092, 1125160382, 1125178722],&lt;br /&gt;
       [1125187249, 1125202588, 1125225033]], dtype=int32)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Finish the RasterNumpy class, start to work on raster categories and may be history.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No, Thank you to my mentor that give me the right hints!&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15976</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15976"/>
		<updated>2012-06-19T13:34:04Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Project plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Project plan =&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || missing&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15975</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15975"/>
		<updated>2012-06-19T13:32:41Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Save and Export */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Project plan ===&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|-&lt;br /&gt;
!Period !! Task !! Status / Notes&lt;br /&gt;
|-&lt;br /&gt;
|May 25 || Region class || using g.region {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 1 || Implement Raster class || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 8 || Split Raster class, for each method ||  {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 15 || Implement Buffer and RasterSegment classes || {{done}}&lt;br /&gt;
|-&lt;br /&gt;
|June 22 || Add documentation, doctest, and benchmark, RasterRowIO || missing&lt;br /&gt;
|-&lt;br /&gt;
|June 29 || Add RasterNumpy class || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 6 || Add categories to Rasters classes || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 13 || Implement module wrapper class or function generator || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''July 13''' || Mid-term evaluations deadline || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 20 || Continue the module wrapper part || missing&lt;br /&gt;
|-&lt;br /&gt;
|July 27 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 3 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 10 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 13''' || Suggested 'pencils down' date. Take a week to scrub code, write tests, improve documentation, etc. || missing&lt;br /&gt;
|-&lt;br /&gt;
|August 17 || Implement Vector class || missing&lt;br /&gt;
|-&lt;br /&gt;
|'''August 20''' || Final evaluation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15924</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15924"/>
		<updated>2012-06-15T16:53:49Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Did I meet with any stumbling blocks? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15923</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15923"/>
		<updated>2012-06-15T16:51:13Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* What will I be working on next week? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
Start to add more documentation and tests and benchmarks.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15922</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15922"/>
		<updated>2012-06-15T16:50:05Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* What will I be working on next week? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Next week I will start to work to integrate RowIO and Numpy.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15921</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15921"/>
		<updated>2012-06-15T16:48:45Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* What did I do this week? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.put_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the RasterSegment class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterSegment('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev[:5]: print(row[:3])&lt;br /&gt;
[ 141.99613953  141.27848816  141.37904358]&lt;br /&gt;
[ 142.90461731  142.39450073  142.68611145]&lt;br /&gt;
[ 143.81854248  143.54707336  143.83972168]&lt;br /&gt;
[ 144.56524658  144.58493042  144.86477661]&lt;br /&gt;
[ 144.99488831  145.22894287  145.57142639]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.RasterSegment('new')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for irow in xrange(elev.rows): new[irow] = elev[irow] &amp;lt; 144&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in new[:5]: print(row[:3])&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[1 1 1]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
[0 0 0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev[0, 0] == elev[0][0]&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new[0, 0]&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.close()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.exist()&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15893</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15893"/>
		<updated>2012-06-11T14:22:28Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report3 - 2012-06-08 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Report3 - 2012-06-15 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
Complete the Row class, the Row is an object that inherit from a [http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html | numpy.ndarray]. It is possible to read and write using the RastrRow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow(&amp;quot;elevation&amp;quot;); &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100 = obj.RasterRow('elev_le_100', 'w', mtype = 'CELL', overwrite = True)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.open() &lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     el_le_100.write_row( row &amp;lt;= 100 )&lt;br /&gt;
... &lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el_le_100.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15878</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15878"/>
		<updated>2012-06-08T15:47:55Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Did I meet with any stumbling blocks? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don't understand this behavior. Any hint?&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15877</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15877"/>
		<updated>2012-06-08T15:45:49Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report2 - 2012-06-08 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== Report2 - 2012-06-08 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* As suggested by the mentor I split the Raster class into:&lt;br /&gt;
&lt;br /&gt;
    - RasterAbstractBase;&lt;br /&gt;
    - RasterRow;&lt;br /&gt;
    - RasterRowIO;&lt;br /&gt;
    - RasterSegment;&lt;br /&gt;
    - RasterNumpy;&lt;br /&gt;
&lt;br /&gt;
* Discussed with my mentor the next steps;&lt;br /&gt;
* Studied the ctypes interface;&lt;br /&gt;
* Finished the module use to improve my C knowledge and to look the C API of grass [https://github.com/zarch/distdrop | r.distdrop];&lt;br /&gt;
* Took a course at the university;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Develop the RasterSegment class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
Still problem with &amp;quot;LP_c_float&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# import and open a map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import obj&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.RasterRow('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
&lt;br /&gt;
# instantiate a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0 = elev[0]&lt;br /&gt;
&lt;br /&gt;
# now if I look at the object return by Rast_get_row function&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
# rather than the row is&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[:3]&lt;br /&gt;
Row([  1.03014536e+15,   1.06602391e+15,   1.12519191e+15])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as you see there is not correspondence, so I'm not convert correctly the &lt;br /&gt;
LP_c_float into a buffer.&lt;br /&gt;
&lt;br /&gt;
I create the row with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def __getitem__(self, row):&lt;br /&gt;
    libraster.Rast_get_row(self._fd, self._pbuf, row, self._type)&lt;br /&gt;
    buf = np.core.multiarray.int_asbuffer( c.addressof(self._pbuf.contents),&lt;br /&gt;
                                           8*self._cols)&lt;br /&gt;
    self.row = Row( (self._cols, ), buffer = buf)&lt;br /&gt;
    return self.row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The good thing is that the elev._pbuf and row0 are looking at the same memory, &lt;br /&gt;
if I change the first row value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&amp;gt; row0[0]&lt;br /&gt;
1030145362214880.4&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[0.0, 2.5625, 141.37904357910156]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[0] = 1030145362214880.4&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:3]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if I change the second value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1]                     &lt;br /&gt;
1066023908387873.1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 0.0, 2.5625]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row0[1] = 1066023908387873.1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev._pbuf[:4]&lt;br /&gt;
[141.9961395263672, 141.2784881591797, 141.37904357910156, 142.2982177734375&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15814</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15814"/>
		<updated>2012-06-01T09:32:09Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* Report1 - 2012-06-01 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report1 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15813</id>
		<title>GRASS GSoC 2012 High level map interaction</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_GSoC_2012_High_level_map_interaction&amp;diff=15813"/>
		<updated>2012-06-01T09:31:24Z</updated>

		<summary type="html">&lt;p&gt;⚠️Pietro: /* correct identation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(See also other [[GRASS_SoC_Ideas_2012#Accepted_Ideas|GRASS GSoC 2012 projects]])''&lt;br /&gt;
&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|Student Name: || [[User:Pietro|Pietro Zambelli]], University of Trento, Italy&lt;br /&gt;
|-&lt;br /&gt;
|Organization: || [http://www.osgeo.org OSGeo - Open Source Geospatial Foundation]&lt;br /&gt;
|-&lt;br /&gt;
| Mentor Name: ||     Mentor: Sören Gebbert, Backup mentors: Luca Delucchi, Martin Landa &lt;br /&gt;
|-&lt;br /&gt;
| Title: || '''Proposal for a high level maps interaction'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Proposal for a high level maps interaction =&lt;br /&gt;
&lt;br /&gt;
The idea is: extend the python GRASS API to make it more pythonic :-)&lt;br /&gt;
&lt;br /&gt;
As you can see in the subsequent tests, a lot of functionality are redundant, similarly with `numpy` library&amp;lt;ref&amp;gt;http://numpy.scipy.org/&amp;lt;/ref&amp;gt; I think that could be a good idea binding all the grass functions and add some of them as methods of the class.&lt;br /&gt;
&lt;br /&gt;
For example you can use both:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize a RasterObject present in the mapset with&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = raster.Raster('dtm10')&lt;br /&gt;
&lt;br /&gt;
    # then you can print the info using the class method&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(dtm.info())&lt;br /&gt;
&lt;br /&gt;
    # or using grass function&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(r.info(dtm))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grass as python library ==&lt;br /&gt;
&lt;br /&gt;
I would like to have the ability to call grass as a normal python library outside grass environment::&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass&lt;br /&gt;
&lt;br /&gt;
    # specify the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.config(mapset='/path/to/gisdata/location/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Region as an object ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Attributes, read and write ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the new virtual extension of the GRASS API &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.region as region&lt;br /&gt;
&lt;br /&gt;
    # save as default region option: `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.default = True&lt;br /&gt;
&lt;br /&gt;
    # see region parameters as attribute of the class&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres&lt;br /&gt;
    10&lt;br /&gt;
&lt;br /&gt;
    # change the region parameters in a more pythonic way&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.nsres = 20&lt;br /&gt;
&lt;br /&gt;
    # view the region extension&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # change the region extension directly&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.bbox = [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
&lt;br /&gt;
    # view the convergence angle (degrees CCW)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.conv_angle&lt;br /&gt;
    0.0&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.name = 'Trento'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Region Methods ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # print the current region `-p`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; print(region)  # using the `__str__` method&lt;br /&gt;
&lt;br /&gt;
    # set as default region `-s`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_as_default() # It's equal to set `region.default = True`&lt;br /&gt;
&lt;br /&gt;
    # set from default region `-d`&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from(regionname='default')&lt;br /&gt;
&lt;br /&gt;
    # set region from a map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.set_from_map(MapObject)&lt;br /&gt;
&lt;br /&gt;
    # align region to resolution (default = align to bounds, works only for 2D resolution)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align()&lt;br /&gt;
&lt;br /&gt;
    # adjust region cells to cleanly align with this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.align(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # shrink region until it meets non-NULL data from this raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.zoom(RastObj)&lt;br /&gt;
&lt;br /&gt;
    # save current region settings in named region file&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; region.save('/your/path') # will produce a file: '/your/path/%s.region' % region.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Maps as objects == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MapObject class ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly with the region the MapObject is characterize by some attributes, but only some of these attributes are modifiable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Read and Write =====&lt;br /&gt;
&lt;br /&gt;
Suppose that we initialize a MapObject called `dtm`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.Raster as Raster&lt;br /&gt;
    &lt;br /&gt;
    # load an existing raster map, read mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm = Raster(name = &amp;quot;dtm&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'r', method = 'row')&lt;br /&gt;
    # create a new map, write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm2 = Raster(name = &amp;quot;dtm2&amp;quot;, mapset = &amp;quot;&amp;quot;, mode = 'w', method = 'row')&lt;br /&gt;
    # open the maps&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(); dtm2.open()&lt;br /&gt;
&lt;br /&gt;
    # access row by row&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for i in range(dtm.rows):&lt;br /&gt;
    ...     dtm2[i] = 2 * dtm[i] # dtm[i] return a numpy array&lt;br /&gt;
&lt;br /&gt;
    # access cell by cell&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for cell in row:&lt;br /&gt;
    ...         # do something&lt;br /&gt;
&lt;br /&gt;
    # close&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close(); dtm2.close()&lt;br /&gt;
&lt;br /&gt;
    # open in read &amp;amp; write mode&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.open(mode = 'rw', method = 'segmentation')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     row *= 2&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.close()&lt;br /&gt;
&lt;br /&gt;
    # to rename the map you have just to reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.name = 'dtm__10x10m'&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title&lt;br /&gt;
    &amp;quot;Digital Terrain Model compute from LIDAR2008&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to change the title, as before, you can just reassign the Map attribute&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.title = &amp;quot;Digital Terrain Model compute from LIDAR2008; Licence: Creative Common 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to see in witch mapset the map is&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset&lt;br /&gt;
    '/your/gisbase/location0/mapset'&lt;br /&gt;
&lt;br /&gt;
    # if you want to copy the map in another mapset changing the projection&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.mapset = '/your/gisbase/location1/mapset&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
This attributes are only readable, and are relative to the attributes of the map and not to the region.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north&lt;br /&gt;
    4928030&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.south&lt;br /&gt;
    4913690&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.east&lt;br /&gt;
    609000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.west&lt;br /&gt;
    589980&lt;br /&gt;
    &lt;br /&gt;
    # what append if the user try to change the resolution of the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.north = 4928000&lt;br /&gt;
    SyntaxError: invalid syntax.&lt;br /&gt;
        you can not modify the map attributes,&lt;br /&gt;
        please consider to change region parameters.&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bbox&lt;br /&gt;
    [(4928030,589980),(4913690, 609000)]&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.type&lt;br /&gt;
    'raster'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creator&lt;br /&gt;
    'pietro'&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.creationtime&lt;br /&gt;
    datetime.datetime(2012, 3, 9, 17, 25, 6, 406987)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Map Methods ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # return the args and the kargs that generated the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.generated_by()&lt;br /&gt;
    ([&amp;quot;r.in.ogr&amp;quot;, &amp;quot;bla&amp;quot;, &amp;quot;bla&amp;quot;], {'overwrite' : True})&lt;br /&gt;
&lt;br /&gt;
    # return the bash command string that generate the map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.bash()&lt;br /&gt;
    &amp;quot;r.in.ogr bla bla -overwrite=True&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # to rename the map in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rename('newname0')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap1')&lt;br /&gt;
&lt;br /&gt;
    # to copy the mapname in an other mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.copy('newmap2', mapset='path/to/your/mapset')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raster Map === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Raster attributes ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raster class is a child class of the MapObject and inherits all the attributes and methods, and add some more specific attributes and methods&lt;br /&gt;
&lt;br /&gt;
===== Read only attributes =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.min&lt;br /&gt;
    0.000000&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.max&lt;br /&gt;
    52.520164&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.nsres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.ewres&lt;br /&gt;
    30&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.datatype&lt;br /&gt;
    FCELL&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.rows&lt;br /&gt;
    477&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cols&lt;br /&gt;
    634&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtm.cells&lt;br /&gt;
    302418&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Raster Methods =====&lt;br /&gt;
&lt;br /&gt;
One thing that some time could be useful is the access to the low level of C library from python,&lt;br /&gt;
This is a stupid example, and for this kind of things is better to use the Map algebra, but I think that sometimes have an access to a low level function is useful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the raster object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.raster as raster&lt;br /&gt;
&lt;br /&gt;
    # initialize an empty raster map, copy from another&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; newmap = raster.Raster('newmap')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for row in dtm:&lt;br /&gt;
    ...     for pixel_coords in row.not_null():&lt;br /&gt;
    ...         # pixel_coords is a couple of values, with the row and col&lt;br /&gt;
    ...         # do something...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multilayer raster (i.group) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # initialize a multi raster map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi = raster.MultiRaster('multi')&lt;br /&gt;
&lt;br /&gt;
    # add layers&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'] = dtm&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['slope'] = slope_aspect(dtm, slope = 'slope')&lt;br /&gt;
&lt;br /&gt;
    # query to one point&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10]&lt;br /&gt;
    {'elev': 100, 'slope': 30}&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi['elev'][10,10]&lt;br /&gt;
    100&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi.layers() or multi.keys()&lt;br /&gt;
    ('elev', 'slope')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; multi[10,10].items()&lt;br /&gt;
    (val0, val1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Time raster ====&lt;br /&gt;
&lt;br /&gt;
I know that there are a lot of new staff regarding the time maps, but I don't know exactly how they works therefore any hint are welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Vector MapObject ===&lt;br /&gt;
&lt;br /&gt;
For the vector we can add some particular attributes and methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # import the vector object library&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.vector as vector&lt;br /&gt;
    &lt;br /&gt;
    # import a vector map from file into the location and load&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.import(fname = 'roads.shp', name = 'roads')&lt;br /&gt;
&lt;br /&gt;
    # or if the map already exist in the mapset&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads = vector.Vector('roads')&lt;br /&gt;
&lt;br /&gt;
    # add a category column&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; roads.add_column('length')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     road.cols.length = road.length()&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; for road in roads:&lt;br /&gt;
    ...     for point in road:&lt;br /&gt;
    ...         # do something with point&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Execute function==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.vector as v&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import grass.obj.function.raster as r&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; from math import pi&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; road_buff_50 = v.buffer(roads, dist = 50.)&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_deg, aspect = r.slope_aspect(dtm, slope = 'slope10_deg',&lt;br /&gt;
    ...                                    aspect = 'aspect10')&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope_rad = pi / 180 * slope_deg&lt;br /&gt;
&lt;br /&gt;
    # we can set that default values name are slope = 'slope' and aspect = 'aspect'&lt;br /&gt;
    # PROBLEM: some function like r.slope.aspect, may return a different number of maps&lt;br /&gt;
    # the function generate these map only if the name is given, could be?&lt;br /&gt;
    # we need to generate a python function that read all the C header and generate&lt;br /&gt;
    # the code, when the user build the package, using the GCC-XML?&lt;br /&gt;
    # idea? hint?&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect, dxx = r.slope_aspect(dtm,  slope = 'slope10_deg',&lt;br /&gt;
    ...                                     aspect = 'aspect10',&lt;br /&gt;
    ...                                     dxx = 'dxx')&lt;br /&gt;
&lt;br /&gt;
    # of course we need to handle wrong input map&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope, aspect = r.slope_aspect(road)&lt;br /&gt;
    TypeMapError: The function: &amp;quot;slope_aspect&amp;quot; require a raster map.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algebra and logic function ==&lt;br /&gt;
&lt;br /&gt;
Use mathematic functions and map algebra.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import numpy as np&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; drop = dtm.nsres * np.sin(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dist = dtm.nsres * np.cos(slope_rad)&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; length = np.sqrt(drop**2 + dist**2)&lt;br /&gt;
    &lt;br /&gt;
    # use logic ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope if slope&amp;lt;=30 else None&lt;br /&gt;
    &lt;br /&gt;
    # and similarly mixing raster and vector maps ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad = dtm if road else None&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dtmroad100 = dtm if road.cols.length &amp;lt;= 100 else None&lt;br /&gt;
&lt;br /&gt;
    # or you can make a mask, with boolean values: &lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30 = slope &amp;lt;= 30&lt;br /&gt;
&lt;br /&gt;
    # or query a vector map with:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; track = road.cols.highway == 'track'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Save and Export ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # save all the maps created during the session ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; grass.obj.session.save()&lt;br /&gt;
&lt;br /&gt;
    # or save or export, just one map: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save()&lt;br /&gt;
&lt;br /&gt;
    # or save specify another location and mapset, with: ::&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.save(location='locationname', mapset='mapsetname')&lt;br /&gt;
&lt;br /&gt;
    # export:&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='asciigrid')&lt;br /&gt;
&lt;br /&gt;
    # allow to convert a raster map to vector, like&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp')&lt;br /&gt;
    You are converting a raster map to vector.&lt;br /&gt;
    Choose your Feature type [POINT/line/area]: point&lt;br /&gt;
&lt;br /&gt;
    # or given directly the geometry type&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; slope30.export('filename', format='shp', feature_type = 'point')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Weekly reports =&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-05-25 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* studying the C-API of grass and ctypes;&lt;br /&gt;
* at the moment I'm in Prague at the [[GRASS_Community_Sprint_Prague_2012|Code Sprint]] with a lot of main developers and power users of the amazing GRASS community! and I have the opportunity to exchange ideas with them.&lt;br /&gt;
* start to develop a first implementation of the Raster and Region class.&lt;br /&gt;
* open a new website on [http://code.google.com/p/pygrass/ | google code]&lt;br /&gt;
* make a new repository, have a look: git clone https://code.google.com/p/pygrass/ or [http://code.google.com/p/pygrass/downloads/list | download] it.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Go on with the develop to open the Raster class using the read and write mode with the `row` method. Clean the Region class to use only ctypes and avoid the use grass.run_command.&lt;br /&gt;
Continue to study the segment library of the C API.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I had some problem trying to use the segment library, but I hope to solve during the next week.&lt;br /&gt;
&lt;br /&gt;
== Report0 - 2012-06-01 ==&lt;br /&gt;
&lt;br /&gt;
=== What did I do this week? ===&lt;br /&gt;
&lt;br /&gt;
* add more functionality to the raster object (rename, remove, del()):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open an existing map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev = obj.Raster('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.open()&lt;br /&gt;
# get the name of the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# rename the map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name = 'elev'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elev'&lt;br /&gt;
# or rename using the method&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.rename('elevation')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.name&lt;br /&gt;
'elevation'&lt;br /&gt;
# we can check if the map exist with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
True&lt;br /&gt;
# we can remove the map with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.remove()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; elev.exist()&lt;br /&gt;
False&lt;br /&gt;
# or we can remove the map and de-instantiate the map object with&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; del(elev)&lt;br /&gt;
&amp;lt;/source&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
* re-factoring some part of the code, the write row method has been changed from:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# open a new map&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new = obj.Raster('new', mode = 'w')&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; new.open()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; c = 0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev:&lt;br /&gt;
...     new[c] = row&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
when we are writing with 'row' method, we can not choose which row write, the above syntax could make the users confused, we just add one more row to the file, so I have changed the behavior adding a new method 'writerow', that is more explicit, so now we write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for row in elev: &lt;br /&gt;
...     new.writerow(row)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try to add a new Row object, to extend the capabilities, at the moment the Raster object return a LP_c_float, that support slice, but not support iteration and basic algebra:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(elev[0])&lt;br /&gt;
&amp;lt;class 'grass.lib.ctypes_preamble.LP_c_float'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# making a Row object&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row = Row(elev[0], elev._cols)&lt;br /&gt;
# add the support for a sum&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row2 = row + 2&lt;br /&gt;
# we can convert the row into an array&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; row.to_array()&lt;br /&gt;
array([  1.03014536e+015,   1.06602391e+015,   1.12519191e+015, ...,&lt;br /&gt;
         0.00000000e+000,   0.00000000e+000,   4.94065646e-324])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Continuing to study the segmentation library, add some new function and C struct, that should call by the Raster class using ctypes.&lt;br /&gt;
* Start to think how the map algebra should be implemented, may be I could use jinja to make a template to generate a C code that will be compile when user make GRASS, then the Raster class just call this function with ctypes.&lt;br /&gt;
&lt;br /&gt;
=== What will I be working on next week? ===&lt;br /&gt;
&lt;br /&gt;
Implement the read and write mode using the segmentation library.&lt;br /&gt;
&lt;br /&gt;
=== Did I meet with any stumbling blocks? ===&lt;br /&gt;
&lt;br /&gt;
I do not understand how should I extend the class object &amp;quot;LP_c_float&amp;quot;, without write a new class (Row).&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Python}}&lt;br /&gt;
{{GSoC}}&lt;/div&gt;</summary>
		<author><name>⚠️Pietro</name></author>
	</entry>
</feed>