Pyinstaller - 从os.system(gdal_translate)调用GDAL

3

尊敬的学习者们,您好。我在Windows 7上运行32位Python2.7。

我有一个关于在pyinstaller构建中包含GDAL可执行文件的问题。我正在使用系统调用来运行FWTools版本中的两个GDAL函数。这些函数在Windows的PATH变量中C:\Program Files (x86)\FWTools2.4.7\bin,所以在Python27环境中可以正常运行。但是,在pyinstaller构建中,该路径没有被包含。

相关代码正在调用GDAL函数,将图像重新转换为不同的地理空间坐标。

os.system("gdal_translate -of GTiff -a_ullr  694440.7939 6403967.2406  696438.7261 6404791.6774 -a_srs EPSG:28355 site.tif siteGR.tif")

os.system("gdalinfo siteGR.tif")

运行时在执行上述代码行时出现问题,然后返回以下错误:

'gdal_translate' is not recognized as an internal or external command,
operable program or batch file.

'gdalinfo' is not recognized as an internal or external command,
operable program or batch file.

我尝试将gdal_translate.exe和gdalinfo.exe作为二进制文件包含在构建文件夹中,就像你为.dll文件做的那样,但由于脚本运行后失败,我认为它没有引用它们。

下面是我的spec文件。我需要一些建议,如何让pyinstaller构建识别从Python脚本中运行的系统可执行文件。

Spec:

# -*- mode: python -*-

a = Analysis(['gis_helper.py'],
             pathex=['C:\\Users\\Hp\\PycharmProjects\\GISdev'],
             hiddenimports=['scipy.linalg.cython_blas', 'scipy.linalg.cython_lapack', 'scipy.special._ufuncs_cxx', 'ctypes.util', 'pandas.util', 'distutils.util', 'shapely', '_socket', '_proj', 'multiprocessing', '_multiprocessing', 'multiprocessing.process', 'multiprocessing.util'],
             hookspath=['C:\\Python27\\Lib\\site-packages\\PyInstaller\\hooks'], 
             runtime_hooks=None)


a.binaries1=['geos_c.dll', 'geos_c.dll', 'BINARY'],
a.binaries2=['python27.dll', 'python27.dll', 'BINARY'],
a.binaries3=['_socket.pyd', '_socket.pyd', 'BINARY'],
a.binaries4=['win32api.pyd', 'win32api.pyd', 'BINARY'],
a.binaries5=['pywintypes27.dll', 'pywintypes27.dll', 'BINARY'],
a.binaries6=['pythoncom27.dll', 'pythoncom27.dll', 'BINARY'],
a.binaries7=['_imaging.pyd', '_imaging.pyd', 'BINARY'],
a.binaries8=['_fblas.pyd', '_fblas.pyd', 'BINARY'],
a.binaries9=['gdal_translate.exe', 'gdal_translate.exe', 'BINARY'],
a.binaries10=['gdalinfo.exe', 'gdalinfo.exe', 'BINARY'],

import mpl_toolkits.basemap
import os

src_basedata = os.path.join(mpl_toolkits.basemap.__path__[0], "data")
tgt_basedata = os.path.join('mpl_toolkits', 'basemap', 'data')

pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          [('v',None,'OPTION')],
          a.binaries,  # This needs to be included
          a.binaries1,
          a.binaries2,
          a.binaries3,
          a.binaries4,
          a.binaries5,
          a.binaries6,
          a.binaries7,
          a.binaries8,
          a.binaries9,
          a.binaries10,
          a.zipfiles,
          a.datas + Tree(src_basedata, prefix=tgt_basedata),
          name='gis_helper.exe',
          debug=True,
          strip=None,
          upx=True,
          console=True )

在我回答之前,先进行几项检查。我假设你运行pyinstaller时不会出现像“IOError: [Errno 2] No such file or directory: 'gdal_translate.exe'”这样的错误?我问这个问题是因为你添加了没有路径供pyinstaller查找的二进制文件,这通常会失败... 假设它们被成功添加 - 在运行pyinstaller后,你是否在你的“dist”目录中看到了“gdal_translate.exe”和“gdalinfo.exe”? - J Richard Snape
@JRichardSnape 很抱歉回复晚了,事情一直在拖延。gdal文件包含在我执行pyinstaller的文件夹中,所以可能是这个原因导致它在构建过程中没有崩溃。但没有IOError:消息。脚本运行直到它遇到os.system调用。编译后的文件夹中没有任何文件,只有可执行文件。我应该使用标志来激活pyinstaller吗?我认为问题可能取决于系统路径变量?虽然如果gdal文件已经包含在编译中,你会认为它会找到它们。 - Praxis
好的-现在我可以复制了。顺便说一句,为了帮助你自己进行调试,你可以首先尝试使用非一个文件选项(带有“EXE”和“COL”部分),如果你将gdal exes放在col节中,就可以确信它们已经被收集和包含了。然而,他们无法运行的原因是“exe”无法在自身内部“找到”它们。有一个解决方法-我现在记不清了,但明天会查找并回答/指向它。 - J Richard Snape
好的 - 这里有三个基本上解决了你的问题的问题。如果你无法通过其中一个使其工作,我会写出一个答案... https://dev59.com/j2Yr5IYBdhLWcg3wG2pJ https://dev59.com/EGsz5IYBdhLWcg3wxax3 https://dev59.com/cGIk5IYBdhLWcg3wBZ_7 - J Richard Snape
@JRichardSnape。非常感谢您的帮助。将 chdir(sys._MEIPASS) 添加到我的脚本中,将运行时路径定向到正确的目标位置,即 exe 被解压和运行的位置。然后就能找到 GDAL 插件了。当然,在 spec 文件中添加了 a.binaries +=['gdal_translate.exe', 'gdal_translate.exe', 'DATA'] - Praxis
太棒了。也许我们应该写下一个答案。 - J Richard Snape
1个回答

0

从GDAL 2.1开始,您可以在Python绑定中使用“librified”版本的gdal_translate,这可能更加健壮,并防止您必须处理路径:

import gdal
gdal.Translate(<options>)

它的一些使用示例可以在gdal存储库的测试套件中找到: https://svn.osgeo.org/gdal/trunk/autotest/utilities/test_gdal_translate_lib.py

您可以pip install gdal,我相信它是2.1版本(在Linux上)。对于Windows,最简单的安装方式是使用conda

这样做可以避免您不必太多地包含二进制文件/路径在pyinstaller中,因为它可以像任何Python模块一样处理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接