因为想要在Spyder中直接调用GRASS的Python包,实现在外部的IDE中运行GRASS,直接在Spyder中输入官网给出的实现代码,根据实际情况更改gisdb,grassbin目录等:
import os
import sys
import subprocess
#定义GRASS数据库
#添加自己的grassdb数据库路径
gisdb = os.path.join(os.path.expanduser("~"), "grassdata")
# the following path is the default path on MS Windows
# gisdb = os.path.join(os.path.expanduser("~"), "Documents/grassdata")
#指定现有location和mapset
location = "nc_spm_08"
mapset = "user1"
#指定GRASS的启动文件
grass7bin = 'grass78'
if sys.platform.startswith('win'):
# MS Windows
grass7bin = r'C:Program FilesGRASS GIS 7.8grass78.bat'
# uncomment when using standalone WinGRASS installer
# grass7bin = r'C:Program Files (x86)GRASS GIS 7.8.0grass78.bat'
# this can be avoided if GRASS executable is added to PATH
elif sys.platform == 'darwin':
# Mac OS X
# TODO: this have to be checked, maybe unix way is good enough
grass7bin = '/Applications/GRASS/GRASS-7.8.app/'
# query GRASS GIS itself for its GISBASE
startcmd = [grass7bin, '--config', 'path']
try:
p = subprocess.Popen(startcmd, shell=False,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
except OSError as error:
sys.exit("ERROR: Cannot find GRASS GIS start script"
" {cmd}: {error}".format(cmd=startcmd[0], error=error))
if p.returncode != 0:
sys.exit("ERROR: Issues running GRASS GIS start script"
" {cmd}: {error}"
.format(cmd=' '.join(startcmd), error=err))
#gisbase = out.strip(os.linesep.encode())
gisbase= r'C:Program FilesGRASS GIS 7.8'
# set GISBASE environment variable
os.environ['GISBASE'] = gisbase
# define GRASS-Python environment
grass_pydir = os.path.join(gisbase, "etc", "python")
sys.path.append(grass_pydir)
# import (some) GRASS Python bindings
import grass.script as gscript
import grass.script.setup as gsetup
# launch session
rcfile = gsetup.init(gisbase, gisdb, location, mapset)
# example calls
gscript.message('Current GRASS GIS 7 environment:')
print(gscript.gisenv())
gscript.message('Available raster maps:')
for rast in gscript.list_strings(type='raster'):
print(rast)
gscript.message('Available vector maps:')
for vect in gscript.list_strings(type='vector'):
print(vect)
# clean up at the end
gsetup.cleanup()
但在运行过程中,报了如下错误:
CalledModuleError: Module run None g.list --q -m type=raster ended with error
Process ended with non-zero return code 3221225785. See errors in the (error) output.`
以及弹出提示:
通过搜索了解到出现这个错误的主要原因是在GRASS运行时可能调用了错误的.dll动态链接库,网上给出的解决方法是:
找到系统中的同名的.dll文件,将其重命名,然后再运行程序:
几个主要的参考:
Is it possible to use GRASS GIS in Python stand alone scripts?
Error on libcurl.dll when using GDAL of OSGeo4W in Django
-
解决步骤如下:
需要用到的软件:
- Dependencies 用于查看.dll调用了的函数来源于哪个其他的.dlll
- Process Explorer 64 查看内存中载入了哪些.dll
以解决“无法定位程序输入点locale_charset于动态链接库C:\Program Files\GRASS GIS 7.8\spatialite.dll上”为例:
- 首先打开Dependencies,直接将spatialite.dll拖入软件
然后可以看到locale_charset这个变量,是需要由C:\Program Files\GRASS GIS 7.8\extrabin\iconv.dll这个dll提供的
所以问题很有可能就是在程序运行的时候没有调用到这个路径下的iconv.dll,而是用了其他路径的iconv.dll
2. 打开Process Explorer 64,查看此时内存中载入了哪些iconv.dll
可以看到,现在调用了D:\ProgramData\Anaconda3\Library\bin\iconv.dll这个dll,来自Anaconda虚拟环境的Library,将其重命名为iconv.dll.bak,然后重启spyder,再次用Process Explorer搜索,发现没有再次载入了
至此,解决了iconv.dll的问题,同样的方法,可以解决gdal300.dll的问题
最后重启spyder,运行程序,成功:
PS:这样重命名虚拟环境中dll的方法,可能会影响虚拟环境中其他软件的使用,所以最好在使用完GRASS GIS之后,把重命名的文件改回来。
(或者直接把Anaconda卸载了
后续应该要找到怎么样让程序直接找到对应的.dll文件的方法,从根本上解决问题
附:spyder的启动脚本:
# filename: grass_spyder.sh
# directory where GRASS GIS lives
# GRASS GIS 的安装信息
export GISBASE=`C:Program FilesGRASS GIS 7.8grass78.bat --config path` # or define path to binaries like /usr/local/grass-7.4.svn
#echo $GISBASE
# generate GISRC
# Defines the system wide value while in a GRASS session
# 设置GISDBASE LOCATION MAPSET
MYGISDBASE=G:grass_data # Change this path to reflect your own
MYLOC=futures_triangle_nc # Change this location name to reflect your own
MYMAPSET=PERMANENT
# Set the global grassrc file to individual file name
MYGISRC="C:Usersddd.grassrc"
echo "GISDBASE: $MYGISDBASE" > "$MYGISRC"
echo "LOCATION_NAME: $MYLOC" >> "$MYGISRC"
echo "MAPSET: $MYMAPSET" >> "$MYGISRC"
echo "GRASS_GUI: text" >> "$MYGISRC"
# path to GRASS settings file
export GISRC=$MYGISRC
export LD_LIBRARY_PATH=$GISBASE/lib:$LD_LIBRARY_PATH
export PYTHONPATH=$GISBASE/etc/python:$PYTHONPATH
export PATH=$GISBASE/bin:$GISBASE/scripts:$PATH
# start the notebook in the notebook folder
cd G:grass_data # change to notebooks folder (example; update to your path)
spyder
cd到文件目录,执行
sh grass_spyder.sh
来源:oschina
链接:https://my.oschina.net/jiangroubao/blog/4295495