<?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%8FJduckles</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%8FJduckles"/>
	<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/wiki/Special:Contributions/%E2%9A%A0%EF%B8%8FJduckles"/>
	<updated>2026-05-30T21:09:30Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_and_Python&amp;diff=14355</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=14355"/>
		<updated>2011-11-03T15:45:06Z</updated>

		<summary type="html">&lt;p&gt;⚠️Jduckles: /* Interfacing with NumPy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''(for discussions on the new GRASS GUI, see [[GRASS GUI|here]])''&lt;br /&gt;
&lt;br /&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.&lt;br /&gt;
For code which needs access to the power of C, you can access the GRASS C library functions via the Python &amp;quot;ctypes&amp;quot; interface.&lt;br /&gt;
&lt;br /&gt;
;GRASS Python Scripting Library&lt;br /&gt;
* http://grass.osgeo.org/programming6/pythonlib.html (GRASS 6)&lt;br /&gt;
* http://grass.osgeo.org/programming7/pythonlib.html (GRASS 7)&lt;br /&gt;
&lt;br /&gt;
Code style: Have a look at [http://trac.osgeo.org/grass/browser/grass/trunk/SUBMITTING_PYTHON SUBMITTING_PYTHON].&lt;br /&gt;
&lt;br /&gt;
=== Creating Python scripts that call GRASS functionality from outside ===&lt;br /&gt;
&lt;br /&gt;
In order to use GRASS from outside, some environment variables have to be set.&lt;br /&gt;
&lt;br /&gt;
==== MS-Windows ====&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 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 %WINGISBASE%\etc\python&lt;br /&gt;
&lt;br /&gt;
1-3 should be taken care of by the Python installer. 4 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;
Note:&lt;br /&gt;
&lt;br /&gt;
Currently (as of 22 Feb 2011) if you want to use Python for scripting GRASS on Windows, the best solution is to delete the bundled version of Python 2.5 from the GRASS installation, install Python and the required add-ons (wxPython, NumPy, PyWin32) from their official installers,&lt;br /&gt;
then edit the GRASS start-up script to remove any references to the bundled version.&lt;br /&gt;
&lt;br /&gt;
==== Linux ====&lt;br /&gt;
&lt;br /&gt;
The variables are set like this:&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;
=== Using the GRASS Python Scripting Library ===&lt;br /&gt;
&lt;br /&gt;
The code in lib/python/ provides 'grass.script' in order to support GRASS scripts written in Python. The scripts/ directory of GRASS 7 contains a series of examples actually provided to the end users (while the script in GRASS 6 are shell scripts).&lt;br /&gt;
&lt;br /&gt;
Python Scripting Library code details:&lt;br /&gt;
* [http://grass.osgeo.org/programming6/pythonlib.html for GRASS 6]: core.py, db.py, raster.py, vector.py, setup.py, array.py&lt;br /&gt;
* [http://grass.osgeo.org/programming7/pythonlib.html for GRASS 7]: core.py, db.py, raster.py, vector.py, setup.py, array.py&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
==== Display example ====&lt;br /&gt;
Example of Python script, which is processed by g.parser:&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;
############################################################################&lt;br /&gt;
#&lt;br /&gt;
# MODULE:      d.shadedmap&lt;br /&gt;
# AUTHOR(S):   Unknown; updated to GRASS 5.7 by Michael Barton&lt;br /&gt;
#              Converted to Python by Glynn Clements&lt;br /&gt;
# PURPOSE:     Uses d.his to drape a color raster over a shaded relief map&lt;br /&gt;
# COPYRIGHT:   (C) 2004,2008,2009 by the GRASS Development Team&lt;br /&gt;
#&lt;br /&gt;
#              This program is free software under the GNU General Public&lt;br /&gt;
#              License (&amp;gt;=v2). Read the file COPYING that comes with GRASS&lt;br /&gt;
#              for details.&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
&lt;br /&gt;
#%Module&lt;br /&gt;
#% description: Drapes a color raster over a shaded relief map using d.his&lt;br /&gt;
#%End&lt;br /&gt;
#%option&lt;br /&gt;
#% key: reliefmap&lt;br /&gt;
#% type: string&lt;br /&gt;
#% gisprompt: old,cell,raster&lt;br /&gt;
#% description: Name of shaded relief or aspect map&lt;br /&gt;
#% required : yes&lt;br /&gt;
#%end&lt;br /&gt;
#%option&lt;br /&gt;
#% key: drapemap&lt;br /&gt;
#% type: string&lt;br /&gt;
#% gisprompt: old,cell,raster&lt;br /&gt;
#% description: Name of raster to drape over relief map&lt;br /&gt;
#% required : yes&lt;br /&gt;
#%end&lt;br /&gt;
#%option&lt;br /&gt;
#% key: brighten&lt;br /&gt;
#% type: integer&lt;br /&gt;
#% description: Percent to brighten&lt;br /&gt;
#% options: -99-99&lt;br /&gt;
#% answer: 0&lt;br /&gt;
#%end&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
from grass.script import core as grass&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    drape_map = options['drapemap']&lt;br /&gt;
    relief_map = options['reliefmap']&lt;br /&gt;
    brighten = options['brighten']&lt;br /&gt;
    ret = grass.run_command(&amp;quot;d.his&amp;quot;, h_map = drape_map,  i_map = relief_map, brighten = brighten)&lt;br /&gt;
    sys.exit(ret)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    options, flags = grass.parser()&lt;br /&gt;
    main()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Parsing the options and flags  ====&lt;br /&gt;
&lt;br /&gt;
grass.parser() is an interface to g.parser, and allows to parse the options and flags passed to your script on the command line. It is to be called at the top-level:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    options, flags = grass.parser()&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Global variables &amp;quot;options&amp;quot; and &amp;quot;flags&amp;quot; are Python dictionaries containing the options/flags values, keyed by lower-case option/flag names. The values in &amp;quot;options&amp;quot; are strings, those in &amp;quot;flags&amp;quot; are Python booleans. All those variables have to be previously declared in the header of your script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; options, flags = grass.parser()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; options&lt;br /&gt;
{'input': 'my_map', 'output': 'map_out', 'option1': '21.472', 'option2': ''}&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; flags&lt;br /&gt;
{'c': True, 'm': False}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example for embedding r.mapcalc (map algebra) ====&lt;br /&gt;
&lt;br /&gt;
grass.mapcalc() accepts a template string followed by keyword&lt;br /&gt;
arguments for the substitutions, e.g. (code snippets):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
grass.mapcalc(&amp;quot;${out} = ${rast1} + ${rast2}&amp;quot;,&lt;br /&gt;
              out = options['output'],&lt;br /&gt;
              rast1 = options['raster1'],&lt;br /&gt;
              rast2 = options['raster2'])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Best practice'': first copy all of the options[] into separate variables at the beginning of main(), i.e.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def main():&lt;br /&gt;
    output = options['output']&lt;br /&gt;
    raster1 = options['raster1']&lt;br /&gt;
    raster2 = options['raster2']&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    grass.mapcalc(&amp;quot;${out} = ${rast1} + ${rast2}&amp;quot;,&lt;br /&gt;
                  out = output,&lt;br /&gt;
                  rast1 = raster1,&lt;br /&gt;
                  rast2 = raster2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example for parsing category numbers ====&lt;br /&gt;
&lt;br /&gt;
Q: How to obtain the number of cells of a certain category?&lt;br /&gt;
&lt;br /&gt;
A: It is recommended to use pipe_command() and parse the output, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       p = grass.pipe_command('r.stats',flags='c',input='map')&lt;br /&gt;
       result = {}&lt;br /&gt;
       for line in p.stdout:&lt;br /&gt;
           val,count = line.strip().split()&lt;br /&gt;
           result[int(val)] = int(count)&lt;br /&gt;
       p.wait()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example for getting the region's number of rows and columns ====&lt;br /&gt;
&lt;br /&gt;
Q: How to obtain the number of rows and columns of the current region?&lt;br /&gt;
&lt;br /&gt;
A: It is recommended to use the &amp;quot;grass.region()&amp;quot; function which will create a dictionary with values for extents and resolution, e.g.:&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;
#&lt;br /&gt;
############################################################################&lt;br /&gt;
#&lt;br /&gt;
# MODULE:       g.region.resolution&lt;br /&gt;
# AUTHOR(S):    based on a post at GRASS-USER mailing list [1]               &lt;br /&gt;
# PURPOSE:	Parses &amp;quot;g.region -g&amp;quot;, prints out number of rows, cols&lt;br /&gt;
# COPYLEFT:     ;-)&lt;br /&gt;
# COMMENT:      ...a lot of comments to be easy-to-read for/by beginners&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
#&lt;br /&gt;
#%Module&lt;br /&gt;
#% description: Print number of rows, cols of current geographic region&lt;br /&gt;
#% keywords: region&lt;br /&gt;
#%end&lt;br /&gt;
&lt;br /&gt;
# importing required modules&lt;br /&gt;
import sys # the sys module [2]&lt;br /&gt;
from grass.script import core as grass # the core module [3]&lt;br /&gt;
&lt;br /&gt;
# information about imported modules can be obtained using the dir() function&lt;br /&gt;
# e.g.: dir(sys)&lt;br /&gt;
&lt;br /&gt;
# define the &amp;quot;main&amp;quot; function: get number of rows, cols of region&lt;br /&gt;
def main():&lt;br /&gt;
    &lt;br /&gt;
    # #######################################################################&lt;br /&gt;
    # the following commented code works but is kept only for learning purposes&lt;br /&gt;
     &lt;br /&gt;
    ## assigning the output of the command &amp;quot;g.region -g&amp;quot; in a string called &amp;quot;return_rows_x_cols&amp;quot;&lt;br /&gt;
    # return_rows_x_cols = grass.read_command('g.region', flags = 'g')&lt;br /&gt;
    &lt;br /&gt;
    ## parsing arguments of interest (rows, cols) in a dictionary named &amp;quot;rows_x_cols&amp;quot;&lt;br /&gt;
    # rows_x_cols = grass.parse_key_val(return_rows_x_cols)&lt;br /&gt;
    &lt;br /&gt;
    ## selectively print rows, cols from the dictionary &amp;quot;rows_x_cols&amp;quot;&lt;br /&gt;
    # print 'rows=%d \ncols=%d' % (int(rows_x_cols['rows']), int(rows_x_cols['cols']))&lt;br /&gt;
    &lt;br /&gt;
    # #######################################################################&lt;br /&gt;
    &lt;br /&gt;
    # faster/ easier way: use of the &amp;quot;grass.region()&amp;quot; function&lt;br /&gt;
    gregion = grass.region()&lt;br /&gt;
    rows = gregion['rows']&lt;br /&gt;
    cols = gregion['cols']&lt;br /&gt;
    &lt;br /&gt;
    # print rows, cols properly formated &lt;br /&gt;
    print 'rows=%d \ncols=%d' % (rows, cols)&lt;br /&gt;
&lt;br /&gt;
# this &amp;quot;if&amp;quot; condition instructs execution of code contained in this script, *only* if the script is being executed directly &lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;: # this allows the script to be used as a module in other scripts or as a standalone script&lt;br /&gt;
    options, flags = grass.parser() #&lt;br /&gt;
    sys.exit(main()) #&lt;br /&gt;
&lt;br /&gt;
# Links&lt;br /&gt;
# [1] http://n2.nabble.com/Getting-rows-cols-of-a-region-in-a-script-tp2787474p2787509.html&lt;br /&gt;
# [2] http://www.python.org/doc/2.5.2/lib/module-sys.html&lt;br /&gt;
# [3] http://download.osgeo.org/grass/grass6_progman/pythonlib.html#pythonCore&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Managing mapsets ====&lt;br /&gt;
&lt;br /&gt;
To check if a certain mapset exists in the active location, use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.script.mapsets(False)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... returns a list of mapsets in the current location.&lt;br /&gt;
&lt;br /&gt;
==== r.mapcalc example ====&lt;br /&gt;
&lt;br /&gt;
Example of Python script, which is processed by {{cmd|g.parser}}:&lt;br /&gt;
&lt;br /&gt;
The shell script line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
  r.mapcalc &amp;quot;MASK = if(($cloudResampName &amp;lt; 0.01000),1,null())&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
would be written like this:&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;
&lt;br /&gt;
       ...&lt;br /&gt;
&lt;br /&gt;
       grass.mapcalc(&amp;quot;MASK=if(($cloudResampName &amp;lt; 0.01000),1,null())&amp;quot;,&lt;br /&gt;
                     cloudResampName = cloudResampName)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first argument to the mapcalc function is a template (see the Python library documentation for [http://docs.python.org/library/string.html string.Template]). Any keyword arguments (other than quiet, verbose or overwrite) specify substitutions.&lt;br /&gt;
&lt;br /&gt;
==== Using output from GRASS modules in the script ====&lt;br /&gt;
&lt;br /&gt;
Sometimes you need to use the output of a module for the next step. There are dedicated functions to obtain the result of, for example, a statistical analysis.&lt;br /&gt;
&lt;br /&gt;
Example: get the range of a raster map and use it in {{cmd|r.mapcalc}}. Here you can use &amp;lt;code&amp;gt;grass.script.raster_info()&amp;lt;/code&amp;gt;, e.g.:&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;
&lt;br /&gt;
       max = grass.raster_info(inmap)['max']&lt;br /&gt;
       grass.mapcalc(&amp;quot;$outmap = $inmap / $max&amp;quot;,&lt;br /&gt;
                     inmap = inmap, outmap = outmap, max = max)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Calling a GRASS module in Python  ====&lt;br /&gt;
&lt;br /&gt;
Imagine, you wanted to execute this command in Python:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
  r.profile -g input=mymap output=newfile profile=12244.256,-295112.597,12128.012,-295293.77&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All arguments except the first (which is a flag) are keyword arguments, i.e. &amp;lt;tt&amp;gt;arg = val&amp;lt;/tt&amp;gt;. For the flag, use &amp;lt;tt&amp;gt;flags = 'g'&amp;lt;/tt&amp;gt; (note that &amp;quot;-g&amp;quot; would be the negative of a Python variable named &amp;quot;g&amp;quot;!). So:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command(&lt;br /&gt;
               'r.profile',&lt;br /&gt;
               input = input_map,&lt;br /&gt;
               output = output_file,&lt;br /&gt;
               profile = [12244.256,-295112.597,12128.012,-295293.77]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
or:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
               profile = [(12244.256,-295112.597),(12128.012,-295293.77)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i.e. you need to provide the keyword, and the argument must be a valid Python expression. Function &amp;lt;code&amp;gt;run_command()&amp;lt;/code&amp;gt; etc accept lists and tuples.&lt;br /&gt;
&lt;br /&gt;
'''Differences between ''run_command()'' and ''read_command()'':'''&lt;br /&gt;
&lt;br /&gt;
* run_command() executes the command and waits for it to terminate; it doesn't redirect any of the standard streams.&lt;br /&gt;
* read_command() executes the command with stdout redirected to a pipe, and reads everything written to it. Once the command terminates, it returns the data written to stdout as a string.&lt;br /&gt;
&lt;br /&gt;
'''How to retrieve error messages from ''read_command()'':'''&lt;br /&gt;
&lt;br /&gt;
None of the existing *_command functions redirect stderr. You can do so with e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def read2_command(*args, **kwargs):&lt;br /&gt;
   kwargs['stdout'] = grass.PIPE&lt;br /&gt;
   kwargs['stderr'] = grass.PIPE&lt;br /&gt;
   ps = grass.start_command(*args, **kwargs)&lt;br /&gt;
   return ps.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This behaves like read_command() except that it returns a tuple of (stdout,stderr) rather than just stdout.&lt;br /&gt;
&lt;br /&gt;
==== Path to GISDBASE ====&lt;br /&gt;
&lt;br /&gt;
In order to a avoid hardcoded paths to GRASS mapset files like the SQLite DB file, you can get the GISDBASE variable from the environment:&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;
       import os.path&lt;br /&gt;
&lt;br /&gt;
       env = grass.gisenv()&lt;br /&gt;
&lt;br /&gt;
       gisdbase = env['GISDBASE']&lt;br /&gt;
       location = env['LOCATION_NAME']&lt;br /&gt;
       mapset = env['MAPSET']&lt;br /&gt;
&lt;br /&gt;
       path = os.path.join(gisdbase, location, mapset, 'sqlite.db')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Python extensions for GRASS GIS==&lt;br /&gt;
=== wxPython GUI development for GRASS ===&lt;br /&gt;
&lt;br /&gt;
* See the [[wxGUI]] wiki page&lt;br /&gt;
&lt;br /&gt;
=== GRASS Python Scripting Library ===&lt;br /&gt;
&lt;br /&gt;
See [http://grass.osgeo.org/programming7/pythonlib.html GRASS Python Scripting Library] (Programmer's manual). See also [[Converting Bash scripts to Python]], and [http://trac.osgeo.org/grass/browser/grass/trunk/scripts sample Python scripts in GRASS 7]&lt;br /&gt;
&lt;br /&gt;
==== Uses for read, feed and pipe, start and exec commands ====&lt;br /&gt;
&lt;br /&gt;
All of the *_command functions use make_command to construct a command&lt;br /&gt;
line for a program which uses the GRASS parser. Most of them then pass&lt;br /&gt;
that command line to ''subprocess.Popen()'' via ''start_command()'', except&lt;br /&gt;
for ''exec_command()'' which uses ''os.execvpe()''.&lt;br /&gt;
&lt;br /&gt;
[To be precise, they use grass.Popen(), which just calls&lt;br /&gt;
subprocess.Popen() with shell=True on Windows and shell=False&lt;br /&gt;
otherwise. On Windows, you need to use shell=True to be able to&lt;br /&gt;
execute scripts (including batch files); shell=False only works with&lt;br /&gt;
binary executables.]&lt;br /&gt;
&lt;br /&gt;
start_command() separates the arguments into those which&lt;br /&gt;
subprocess.Popen() understands and the rest. The rest are passed to&lt;br /&gt;
make_command() to construct a command line which is passed as the&lt;br /&gt;
&amp;quot;args&amp;quot; parameter to subprocess.Popen().&lt;br /&gt;
&lt;br /&gt;
In other words, start_command() is a GRASS-oriented interface to&lt;br /&gt;
subprocess.Popen(). It should be suitable for any situation where you&lt;br /&gt;
would use subprocess.Popen() to execute a normal GRASS command (one&lt;br /&gt;
which uses the GRASS parser, which is almost all of them; the main&lt;br /&gt;
exception is r.mapcalc in 6.x).&lt;br /&gt;
&lt;br /&gt;
Most of the others are convenience wrappers around start_command(), for common use cases.&lt;br /&gt;
&lt;br /&gt;
* run_command() calls the wait() method on the process, so it doesn't return until the command has finished, and returns the command's exit code. Similar to system().&lt;br /&gt;
&lt;br /&gt;
* pipe_command() calls start_command() with stdout=PIPE and returns the process object. You can use the process' .stdout member to read the command's stdout. Similar to popen(..., &amp;quot;r&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
* feed_command() calls start_command() with stdin=PIPE and returns the process object. You can use the process' .stdin member to write to the command's stdout. Similar to popen(..., &amp;quot;w&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* read_command() calls pipe_command(), reads the data from the command's stdout, and returns it as a string. Similar to `backticks` in the shell.&lt;br /&gt;
&lt;br /&gt;
* write_command() calls feed_command(), sends the string specified by the &amp;quot;stdin&amp;quot; argument to the command's stdin, waits for the command to finish and returns its exit code. Similar to &amp;quot;echo ... | command&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* parse_command() calls read_command() and parses its output as key-value pairs. Useful for obtaining information from g.region, g.proj, r.info, etc.&lt;br /&gt;
&lt;br /&gt;
* exec_command() doesn't use start_command() but os.execvpe(). This causes the specified command to replace the current program (i.e. the Python script), so exec_command() never returns. Similar to bash's &amp;quot;exec&amp;quot; command. This can be useful if the script is a &amp;quot;wrapper&amp;quot; around a single command, where you construct the command line and execute the command as the final step.&lt;br /&gt;
&lt;br /&gt;
If you have any other questions, you might want to look at the code ($GISBASE/etc/python/grass/script/core.py). Most of these functions are only a few lines long.&lt;br /&gt;
&lt;br /&gt;
==== Interfacing with NumPy ====&lt;br /&gt;
Note: This only works in GRASS 7.0+ due to changes in r.in.bin and r.out.bin.&lt;br /&gt;
&lt;br /&gt;
The {{api|pythonlib.html#pythonArray|grass.script.array}} module defines a {{api|classpython_1_1array_1_1array.html|class array}} which is a subclass of [http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html numpy.memmap] with &amp;lt;code&amp;gt;.read()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.write()&amp;lt;/code&amp;gt; methods to read/write the underlying file via {{cmd|r.out.bin}}/{{cmd|r.in.bin}}. Metadata can be read with {{api|namespacegrass_1_1script_1_1raster.html|raster::raster_info}}&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    import grass.script.core as gcore&lt;br /&gt;
    import grass.script.array as garray&lt;br /&gt;
    import grass.script.raster as graster&lt;br /&gt;
    a = garray.array()&lt;br /&gt;
    a.read(&amp;quot;elevation.dem&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # raster map info&lt;br /&gt;
    i = graster.raster_info(&amp;quot;elevation.dem&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # computational region info&lt;br /&gt;
    c = gcore.region()&lt;br /&gt;
    rows = c['rows']&lt;br /&gt;
    cols = c['cols']&lt;br /&gt;
&lt;br /&gt;
    b = garray.array()&lt;br /&gt;
    b[...] = (a / 50).astype(int) * 50  # or whatever&lt;br /&gt;
    b.write(&amp;quot;elev.50m&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The size of the array is taken from the current region ([[computational region]]).&lt;br /&gt;
&lt;br /&gt;
The main drawback of using numpy is that you're limited by available&lt;br /&gt;
memory. Using a subclass of &amp;lt;code&amp;gt;numpy.memmap&amp;lt;/code&amp;gt; lets you use files which may&lt;br /&gt;
be much larger, but processing the entire array in one go is likely to&lt;br /&gt;
produce in-memory results of a similar size.&lt;br /&gt;
&lt;br /&gt;
One may also use the scipy matlab interface:&lt;br /&gt;
    &lt;br /&gt;
    ### SH: in GRASS ###&lt;br /&gt;
    r.out.mat input=elevation output=elev.mat&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    ### PY ###&lt;br /&gt;
    import scipy.io as sio&lt;br /&gt;
    # load data&lt;br /&gt;
    elev = sio.loadmat('elev.mat')&lt;br /&gt;
    # retrive the actual array. the data set contains also the spatial reference&lt;br /&gt;
    elev.get('map_data')&lt;br /&gt;
    data = elev.get('map_data')&lt;br /&gt;
    # a first simple plot&lt;br /&gt;
    import pylab&lt;br /&gt;
    pylab.plot(data)&lt;br /&gt;
    pylab.show()&lt;br /&gt;
    # the contour plot&lt;br /&gt;
    pylab.contour(data)&lt;br /&gt;
    # obviously data needs to ne reversed&lt;br /&gt;
    import numpy as np&lt;br /&gt;
    data_rev = data[::-1]&lt;br /&gt;
    pylab.contour(data_rev)&lt;br /&gt;
    # =&amp;gt; this is a quick plot. basemap mapping may provide a nicer map!&lt;br /&gt;
    #######&lt;br /&gt;
&amp;lt;/source&amp;gt;&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 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;
=== &amp;lt;strike&amp;gt;Python SWIG interface&amp;lt;/strike&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
  Warning: The GRASS-SWIG interface has been removed. Please consider to use the Python ctypes GRASS above.&lt;br /&gt;
&lt;br /&gt;
There is a prototype GRASS-SWIG interface available (thanks to Sajith VK), find it in GRASS 6-CVS: '''swig/python/'''. Draft documentation is [http://download.osgeo.org/grass/grass6_progman/swig/ here]. It now wraps both raster and vector data C functions plus the general GIS (G_*()) functions.&lt;br /&gt;
&lt;br /&gt;
Background: [http://www.swig.org SWIG] (Simplified Wrapper and Interface Generator) is: &lt;br /&gt;
&lt;br /&gt;
* A compiler that turns ANSI C/C++ declarations into scripting language interfaces.&lt;br /&gt;
* Completely automated (produces a fully working Python extension module). &lt;br /&gt;
* Language neutral. SWIG can also target Tcl, Perl, Guile, MATLAB (try PyLab+Matplotlib from python), etc... &lt;br /&gt;
* Attempts to eliminate the tedium of writing extension modules.&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;strike&amp;gt;Python-SWIG examples&amp;lt;/strike&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
* Latest and greatest: [[http://trac.osgeo.org/grass/browser/grass/trunk/scripts GRASS 7 Python scripts]]&lt;br /&gt;
&lt;br /&gt;
* [[PythonSwigExamples|More complicated examples]]&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;
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;
==== TODO ====&lt;br /&gt;
&lt;br /&gt;
* Implement modules support in a Python class using --interface-description and a Python-XML parser. This should be a generic class with module's name as parameter, returning back an object which describes the module (description, flags, parameters, status of not/required). See [http://trac.osgeo.org/grass/browser/grass/trunk/gui/wxpython/ GRASS 6 wxPython interface] for inspiration. Important is to auto-generate the GRASS-Python class at compile time with a Python script.&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 G-ps.map, a GUI to typeset printable maps with ps.map (http://193.84.38.2/~jachym/index.py?cat=gpsmap)&lt;br /&gt;
# Jáchym Čepický's v.pydigit, a GUI to v.edit (http://les-ejk.cz/?cat=vpydigit)&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;
** GRASS Python interface to library functions: http://download.osgeo.org/grass/grass6_progman/swig/ based on SWIG http://www.swig.org/&lt;br /&gt;
** GRASS Python scripting library: http://download.osgeo.org/grass/grass6_progman/pythonlib.html&lt;br /&gt;
** PyWPS, GRASS-Web Processing Service http://pywps.wald.intevation.org&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>⚠️Jduckles</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_and_MapServer&amp;diff=6831</id>
		<title>GRASS and MapServer</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_and_MapServer&amp;diff=6831"/>
		<updated>2008-06-06T13:41:18Z</updated>

		<summary type="html">&lt;p&gt;⚠️Jduckles: /* Raster Maps */  Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==GRASS maps from mapfiles==&lt;br /&gt;
&lt;br /&gt;
MapServer needs a mapfile containing the information, how to create the maps. Examples of these can be found, so here you'll find GRASS specific information.&lt;br /&gt;
&lt;br /&gt;
==Raster Maps==&lt;br /&gt;
&lt;br /&gt;
A short example of a layer definition to access a GRASS raster:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;Example&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;/path/to/grassdb/location/mapset/cellhd/example&amp;quot;&lt;br /&gt;
  CLASS NAME &amp;quot;Example&amp;quot; # You need to have a class definition in the layer&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* The rasters are limited to values from 0 to 255, the values over this are interpreted as 255. Rescale (&amp;lt;code&amp;gt;r.rescale&amp;lt;/code&amp;gt;) your maps when necessary.&lt;br /&gt;
* You really need to have a CLASS in your layer, otherwise no data will be shown. An empty class is quite fine to show the whole map.&lt;br /&gt;
&lt;br /&gt;
==Vector Maps==&lt;br /&gt;
&lt;br /&gt;
A short example of a layer definition to access a GRASS vector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;Example&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CONNECTIONTYPE OGR&lt;br /&gt;
  CONNECTION &amp;quot;/path/to/grassdb/mapset/location/vector/example/head&amp;quot;&lt;br /&gt;
  DATA &amp;quot;1&amp;quot; # Layer number&lt;br /&gt;
  CLASS # You need to have a class definition; otherwise nothing is shown on the map&lt;br /&gt;
    NAME &amp;quot;Example&amp;quot;&lt;br /&gt;
    COLOR 155 155 0&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* You need to have GDAL with OGR and GRASS support for this to work. Note, that in this [http://grass.itc.it/start.html example] the maps are first exported to shapefiles. This is no longer necessary, as the maps can be accessed directly with OGR.&lt;br /&gt;
* Usually GRASS layers have no names and the layer number is used in DATA. However, it is possible that they do have names. This can happen for example when importing files with v.in.dxf, as the module keeps the dxf-file layer names and stores them into the GRASS vector. The layer names, if such there are, can be found in &amp;lt;tt&amp;gt;/path/to/grassdb/mapset/location/vector/vectorname/dbln&amp;lt;/tt&amp;gt;, or with &amp;lt;code&amp;gt;ogrinfo -ro /path/to/grassdb/mapset/location/vector/vectorname/dbln&amp;lt;/code&amp;gt;. Why this is so important is because if there are layer names defined, these layers cannot be accessed through the layer number with OGR. They ''have'' to be accessed through the layer name.&lt;br /&gt;
&lt;br /&gt;
==Examples and useful links==&lt;br /&gt;
&lt;br /&gt;
* [http://grass.itc.it/start.html Example] of GRASS with MapServer.&lt;br /&gt;
* [http://mapserver.gis.umn.edu UMN Mapserver homepage]&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>⚠️Jduckles</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_and_MapServer&amp;diff=6830</id>
		<title>GRASS and MapServer</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_and_MapServer&amp;diff=6830"/>
		<updated>2008-06-06T13:40:57Z</updated>

		<summary type="html">&lt;p&gt;⚠️Jduckles: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==GRASS maps from mapfiles==&lt;br /&gt;
&lt;br /&gt;
MapServer needs a mapfile containing the information, how to create the maps. Examples of these can be found, so here you'll find GRASS specific information.&lt;br /&gt;
&lt;br /&gt;
==Raster Maps==&lt;br /&gt;
&lt;br /&gt;
A short example of a layer definition to access a GRASS raster:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;Example&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;/path/to/grassdb/location/mapset/cellhd/example&amp;quot;&lt;br /&gt;
  CLASS NAME &amp;quot;Example&amp;quot; # You need to have a class definition in the layer&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* The rasters are limited to values form 0 to 255, the values over this are interpreted as 255. Rescale (&amp;lt;code&amp;gt;r.rescale&amp;lt;/code&amp;gt;) your maps when necessary.&lt;br /&gt;
* You really need to have a CLASS in your layer, otherwise no data will be shown. An empty class is quite fine to show the whole map.&lt;br /&gt;
&lt;br /&gt;
==Vector Maps==&lt;br /&gt;
&lt;br /&gt;
A short example of a layer definition to access a GRASS vector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;Example&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CONNECTIONTYPE OGR&lt;br /&gt;
  CONNECTION &amp;quot;/path/to/grassdb/mapset/location/vector/example/head&amp;quot;&lt;br /&gt;
  DATA &amp;quot;1&amp;quot; # Layer number&lt;br /&gt;
  CLASS # You need to have a class definition; otherwise nothing is shown on the map&lt;br /&gt;
    NAME &amp;quot;Example&amp;quot;&lt;br /&gt;
    COLOR 155 155 0&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* You need to have GDAL with OGR and GRASS support for this to work. Note, that in this [http://grass.itc.it/start.html example] the maps are first exported to shapefiles. This is no longer necessary, as the maps can be accessed directly with OGR.&lt;br /&gt;
* Usually GRASS layers have no names and the layer number is used in DATA. However, it is possible that they do have names. This can happen for example when importing files with v.in.dxf, as the module keeps the dxf-file layer names and stores them into the GRASS vector. The layer names, if such there are, can be found in &amp;lt;tt&amp;gt;/path/to/grassdb/mapset/location/vector/vectorname/dbln&amp;lt;/tt&amp;gt;, or with &amp;lt;code&amp;gt;ogrinfo -ro /path/to/grassdb/mapset/location/vector/vectorname/dbln&amp;lt;/code&amp;gt;. Why this is so important is because if there are layer names defined, these layers cannot be accessed through the layer number with OGR. They ''have'' to be accessed through the layer name.&lt;br /&gt;
&lt;br /&gt;
==Examples and useful links==&lt;br /&gt;
&lt;br /&gt;
* [http://grass.itc.it/start.html Example] of GRASS with MapServer.&lt;br /&gt;
* [http://mapserver.gis.umn.edu UMN Mapserver homepage]&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>⚠️Jduckles</name></author>
	</entry>
</feed>