Pyinstaller — вызов GDAL из os.system (gdal_translate)

Приветствую ученых товарищей. Запуск 32-битного Python 2.7 в Windows 7.

У меня есть вопрос относительно включения исполняемых файлов GDAL в сборку pyinstaller. Я делаю системный вызов для запуска двух функций GDAL из выпуска FWTools. Эти функции находятся в переменной PATH в Windows 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, но поскольку после запуска скрипта происходит сбой, я не думаю, что он имеет в виду им.

Я включил файл спецификации ниже. Я мог бы воспользоваться некоторыми советами о том, как заставить сборку pyinstaller распознавать исполняемые файлы, запускаемые из системы в сценарии Python.

Спецификация:

# -*- 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 )

person Praxis    schedule 04.10.2015    source источник
comment
Пара проверок, прежде чем я отвечу. Я предполагаю, что вы не получаете ошибку типа IOError: [Errno 2] No such file or directory: 'gdal_translate.exe' при запуске pyinstaller? Я спрашиваю, потому что вы добавляете двоичные файлы без пути, чтобы pyinstaller мог их найти - обычно это не удается ... Предполагая, что они добавляют OK - вы видите gdal_translate.exe и gdalinfo.exe в своем каталоге dist после запуска pyinstaller?   -  person J Richard Snape    schedule 08.10.2015
comment
@JRichardSnape Извините за поздний ответ, вещи продолжают мешать. Файлы gdal включены в папку, из которой я запускаю pyinstaller, поэтому, вероятно, поэтому он не падает во время сборки. Однако сообщение IOError: отсутствует. Сценарий работает до тех пор, пока не столкнется с вызовами os.system. После компиляции в папке сборки нет файлов, только исполняемый файл. Должен ли я запускать pyinstaller с флагом, чтобы активировать это? Я думаю, что проблема может зависеть от переменных системного пути? Хотя если бы файлы gdal были включены в компиляцию, можно было бы подумать, что он их просто найдет.   -  person Praxis    schedule 11.10.2015
comment
ОК - я могу повторить сейчас. Кстати, чтобы помочь вам в отладке, вы можете сначала попробовать вариант, отличный от одного файла (с разделами EXE и COL), который, если вы поместите исполняемые файлы gdal в раздел col, убедит вас, что они собираются и включаются. Однако причина, по которой они не работают, в том, что exe не может найти их внутри себя. Есть обходной путь - не могу вспомнить его прямо сейчас, но посмотрю и отвечу / укажу вам на него завтра   -  person J Richard Snape    schedule 11.10.2015
comment
ОК - вот 3 вопроса, которые в основном касаются вашей проблемы. Если вы не можете заставить его работать с одним из них, я напишу ответ... stackoverflow.com/questions/13946650/ stackoverflow.com/questions/7674790/ stackoverflow.com/questions/19669640/   -  person J Richard Snape    schedule 11.10.2015
comment
@JRichardSnape. Большое спасибо за помощь в этом. Добавление chdir(sys._MEIPASS) к моему сценарию направило путь среды выполнения к правильному месту назначения, откуда исполняемый файл распаковывался и запускался. затем удалось найти плагины GDAL. После того, как a.binaries +=['gdal_translate.exe', 'gdal_translate.exe', 'DATA'], был добавлен в файл спецификации, конечно.   -  person Praxis    schedule 15.10.2015
comment
Блестящий. Может быть, мы должны записать ответ   -  person J Richard Snape    schedule 15.10.2015


Ответы (1)


Из GDAL 2.1 вы можете использовать «либрифицированную» версию gdal_translate в привязках python, которая может быть более надежной и избавит вас от необходимости возиться с путем:

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.

person jramm    schedule 17.08.2016