无法从python脚本运行草工具(草6.4,python 2.7,win7)

时间:2015-05-31 11:58:15

标签: python-2.7 grass

我是GRASS的新手,我无法开始使用。 我正在尝试编写一个将调用草工具的python脚本(此时它不是什么工具) 我以交互方式创建了位置和地图集,并设置了所有定义。我仍然无法获得grass.gisenv()'提供任何输出,但{}。

我的代码:

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()

我没有错误。只有" {}"。

请帮忙,

1 个答案:

答案 0 :(得分:0)

如何改进代码有一些方法,例如,添加到环境变量而不是设置它们:

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

然后GISRC变量应指向临时文件,而不是用户设置目录中的文件(如果您想以普通用户身份运行GRASS会话)。但无论如何,我建议重新开始使用新的脚本或方法。

首先,如果可能,请使用GRASS GIS 7。版本7.0.0在几个月前发布,它可以作为独立版本和OSGeo4W的一部分用于MS Windows。例如,您可能会收到更好的错误消息。

其次,审核related wiki page。它包含详细的指南,需要使用大量代码示例。以下是其中一个基本内容的提取(仅适用于MS Windows):

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)

但是,请注意,如何在Python中调用GRASS GIS功能(模块和Python库)最好是在GRASS会话中。因此,通常的工作流程是您编写一个依赖于正确设置的环境的脚本,即它立即调用GRASS功能。然后启动GRASS,它为您提供了正确的环境 - 可以运行脚本的GRASS会话。

此外,GRASS GIS的开发版本中还有a new option。如果您正在进行一些非生产开发(或者您正在编写实验性的东西),您可以尝试使用每日构建的开发版本(Subversion trunk,future 7.1),其中包含在GRASS命令行中指定脚本的可能性GIS可执行文件电话可能如下:

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()

上述解决方案的优势在于您可以在Linux和Mac OS X上正确锁定Mapset以及其他一些事情,从正确设置GRASS环境开始,没有太多工作。您只需知道可执行文件的路径或“PATH”上的可执行文件。

然后有一个类似于前一个版本的选项,适用于旧版本。您可以设置GRASS_BATCH_JOB环境变量。 GRASS进程将检查它并执行变量中指定的脚本。

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']

与上面的选项(将脚本作为参数传递)不同,您不能将参数传递给被调用的脚本,也不能直接调用GRASS模块。

最后,您可以在系统中设置环境变量,从而使GRASS会话始终可用。然后,当提供正确的GISRC变量和文件时,GRASS模块将作为普通程序运行。此选项可能会导致许多问题,例如:当使用两个版本的GRASS GIS时,不建议这样做。但是,可以在两者之间做一些事情:将GRASS可执行文件添加到路径中,然后您应该能够使用grass70调用GRASS,因为它在Linux上完成(路径可以在GRASS GIS的属性中找到)图标)。