Can't run grass tools from python script (grass 6.4, python 2.7, win7)

北城以北 提交于 2019-12-10 12:16:16

问题


I am new to GRASS, and i do not manage to get started. I am trying to write a python script that will call grass tool (at that point it does not really matter what tool) I created the location and mapset interactively, and set all the definitions. still I can't get 'grass.gisenv()' to give any output but {}.

my code:

import sys
import os

os.environ['GISBASE'] = r'C:\OSGeo4W\apps\grass\grass-6.4.4'
os.environ['GISRC']= r'C:\Users\USER\AppData\Roaming\GRASS6\grassrc6'
os.environ['LD_LIBRARY_PATH']= r'C:\OSGeo4W\apps\grass\grass-6.4.4\lib'
os.environ['PATH']= r'C:\OSGeo4W\apps\grass\grass-6.4.4\etc;C:\OSGeo4W\apps\grass\grass-6.4.4\etc\python;C:\OSGeo4W\apps\grass\grass-6.4.4\lib;C:\OSGeo4W\apps\grass\grass-6.4.4\bin;C:\OSGeo4W\apps\grass\grass-6.4.4\extralib;C:\OSGeo4W\apps\grass\grass-6.4.4\msys\bin;C:\Python27;'
os.environ['PYTHONLIB']= r'C:\OSGeo4W\apps\Python27'
os.environ['PYTHONPATH']= r'C:\OSGeo4W\apps\grass\grass-6.4.4\etc\python'


sys.path.append(os.path.join(os.environ['GISBASE'], 'etc', 'python'))

gisbase = os.environ['GISBASE'] #= "/usr/local/src/grass_trunk/dist.x86_64-unknown-linux-gnu"

gisdbase = os.path.join(r'C:\Users\USER\Documents', "grassdata")
location = "ISRAEL"
mapset   = "PERMANENT"

import grass.script as grass
import grass.script.setup as gsetup

gsetup.init(gisbase,gisdbase, location, mapset)

print grass.gisenv()

I get no error. only "{}".

Please help,


回答1:


There are some ways how to improve your code, for example, add to environmental variables rather then set them:

os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'bin')

Then the GISRC variable should point to a temporary file, rather then the file in user settings directory (in case you want to run GRASS session as a normal user). But anyway, I suggest to start over with a new script or approach.

First, use GRASS GIS 7 if possible. Version 7.0.0 was released several months ago and it is available for MS Windows both as standalone and as part of OSGeo4W. You might get better error messages, for example.

Second, review related wiki page. It contains a detailed guide what needs to be done with extensive code samples. Here is an extraction of basic things from one of them (for MS Windows only):

import os
import sys
import subprocess

# path to the GRASS GIS launch script
grass7bin = r'C:\OSGeo4W\bin\grass70svn.bat'
# uncomment when using standalone WinGRASS installer
# grass7bin = r'C:\Program Files (x86)\GRASS GIS 7.0.0\grass70.bat'

# query GRASS 7 itself for its GISBASE
startcmd = [grass7bin, '--config', 'path']

p = subprocess.Popen(startcmd, shell=False,
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if p.returncode != 0:
    print >>sys.stderr, "ERROR: Cannot find GRASS GIS 7 start script (%s)" % startcmd
    sys.exit(-1)
gisbase = out.strip('\n\r')
# this could be replaced by using the right gisbase
# directly instead of the executable

# Set GISBASE environment variable
os.environ['GISBASE'] = gisbase

# define GRASS-Python environment
gpydir = os.path.join(gisbase, "etc", "python")
sys.path.append(gpydir)

# data
gisdb = os.path.join(os.path.expanduser("~"), "Documents/grassdata")

# specify (existing) location and mapset
location = "nc_spm_08"
mapset = "user1"

# import GRASS Python bindings
import grass.script as gscript
import grass.script.setup as gsetup

# launch session
gsetup.init(gisbase,
            gisdb, location, mapset)

However, note that the best how to call GRASS GIS functionality (modules and Python libraries) in Python is from within a GRASS session. So the usual workflow is that you write a script which relies on the right environment being set, i.e. it calls GRASS functionality right away. Then you start GRASS which gives you the right environment - GRASS session where the script can run.

Also, there is a new option in the development version of GRASS GIS. In case you are doing some non-production development (yet) or you are writing something experimental, you can try to use daily build of development version (Subversion trunk, future 7.1) which contains a possibility to specify script in the command line of GRASS GIS executable. The call might look like:

grass7bin = r'C:\Program Files (x86)\GRASS GIS 7.0.0\grass70.bat'
gisdb = os.path.join(os.path.expanduser("~"), "Documents/grassdata")
location = "nc_spm_08"
mapset = "user1"
full_mapset = os.path.join(gisdb, location, mapset)
cmd = [grass7bin, full_mapset, '--exec', 'your_script.py']
p = subprocess.Popen(cmd, shell=False,
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()

The advantage of the solution above is that you get proper locking of Mapsets on Linux and Mac OS X plus several other things starting with correctly set GRASS environment without much work. You just need to know path to the executable or have the executable "on PATH".

Then there is an option similar to the previous one which works in older versions. You can set GRASS_BATCH_JOB environmental variable. GRASS process will check it and execute script specified in the variable.

grass7bin = r'C:\Program Files (x86)\GRASS GIS 7.0.0\grass70.bat'
gisdb = os.path.join(os.path.expanduser("~"), "Documents/grassdata")
location = "nc_spm_08"
mapset = "user1"
full_mapset = os.path.join(gisdb, location, mapset)
os.environ['GRASS_BATCH_JOB'] = 'your_script.py'

cmd = [grass7bin, full_mapset]
p = subprocess.Popen(cmd, shell=False,
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
# delete the variable just to be sure
# but using separate env would be more elegant
del os.environ['GRASS_BATCH_JOB']

Unlike the option above (passing script as arguments) you cannot pass parameters to the called script nor call GRASS modules directly.

Finally, you can set the environmental variables in your system and thus have the GRASS session always available. GRASS modules would then run as normal programs when the right GISRC variable and file is provided. This option may potentially cause many problems, e.g. when using two version of GRASS GIS, so it is not recommended. However, it is possible to do something in between: add GRASS executable to the path, then you should be able to call GRASS just with grass70 as it is done on Linux (the path can be found in properties of GRASS GIS icon).



来源:https://stackoverflow.com/questions/30557132/cant-run-grass-tools-from-python-script-grass-6-4-python-2-7-win7

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!