Я пытаюсь создать пакет, чтобы другие программы на других компьютерах могли его использовать. Пакет состоит в том, чтобы просто преобразовать восточную, северную координаты utm в wgs84, поэтому в качестве примера необходимо взять два аргумента -e 234234.534 и -n 234235.5344. И он должен вывести преобразованную координату wgs84 (x, y).
Я на Windows10 64-битной ОС.
Мой подход - написать функцию в python, используя пакеты поставляются с osgeo4w и используют pyinstaller для экспорта его в виде пакета, чтобы я мог вызвать файл .exe.
Когда я запускаю .exe в osgeo4w.bat, он работает. Но когда я просто использую CMD или использую файл python (используя Python38), чтобы вызвать этот файл .exe, он терпит неудачу.
См. Вопросы в нижней части поста.
Вот шаги я взял более подробно:
Вот файл, который я пытаюсь упаковать, чтобы я мог использовать его в других программах (например, python 2.7.5, поставляемый с ArcGIS10.2, или даже использовать CMD в windows).
##utmsa_to_wgs.py
from osgeo import osr
from osgeo import ogr
import sys
import subprocess
EXE_ROOT = r'{0}'.format('/'.join(sys.argv[0].split('\\')[:-1]))
sys.path.insert(0,EXE_ROOT)
def U_W(easting=0, northing=0):
source = osr.SpatialReference()
source.ImportFromEPSG(3107)
target = osr.SpatialReference()
target.ImportFromEPSG(4326)
transform = osr.CoordinateTransformation(source, target)
point = ogr.CreateGeometryFromWkt("POINT ({0} {1})".format(easting, northing))
point.Transform(transform)
return str((point.GetX(), point.GetY())) ##e.g. -33.8434, 151.20534
##print (U_W(northing=1681295.7765812099,easting=2491253.6273768987)) ## northing, easting
if __name__=="__main__":
a = sys.argv
for i in range(len(a)):
if a[i] == '-e':
easting = a[i+1]
if a[i] == '-n':
northing = a[i+1]
if a[i] == '-c':
exec(' lambda easting, northing : U_W(easting=easting,northing=northing)')
sys.stdout.write(U_W(easting=easting,northing=northing))
sys.exit(0)
Чтобы проверить сам файл python, я могу использовать osgeo4w.bat. Тест в порядке:
C:\OSGeo4W64>python convert_utmsa_to_wgs84/convert_utm_wgs.py -n 1681295.7765812099 -e 2491253.6273768987
(-33.86732713160471, 151.2083407968708)
C:\OSGeo4W64>
И перейдите к py3_env в osgeo4w.bat, чтобы проверить снова: Тест в порядке.
C:\OSGeo4W64>py3_env
C:\OSGeo4W64>SET PYTHONHOME=C:\OSGEO4~1\apps\Python37
C:\OSGeo4W64>SET PYTHONPATH=C:\OSGEO4~1\apps\Python37;C:\OSGEO4~1\apps\Python37\Scripts
C:\OSGeo4W64>PATH C:\OSGEO4~1\apps\Python37;C:\OSGEO4~1\apps\Python37\Scripts;{app};C:\Program Files\MiKTeX 2.9\miktex\bin;C:\OSGEO4~1\apps\Python27\Scripts;C:\OSGEO4~1\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32\WBem;C:\Program Files\R\R-3.6.3\bin\x64
C:\OSGeo4W64>python convert_utmsa_to_wgs84/convert_utm_wgs.py -n 1681295.7765812099 -e 2491253.6273768987
(-33.86732713160471, 151.2083407968708)
C:\OSGeo4W64>
Теперь, чтобы попробовать сделать .exe, я открыл osgeo4w .bat shell и вызывается по умолчанию env
pyinstaller convert_utmsa_to_wgs84/convert_utm_wgs.py
И проверено ОК:
(-33.86732713160471, 151.2083407968708)
C:\OSGeo4W64>
И попытался использовать py3_env. Тест OK:
C:\OSGeo4W64>py3_env
C:\OSGeo4W64>SET PYTHONHOME=C:\OSGEO4~1\apps\Python37
C:\OSGeo4W64>SET PYTHONPATH=C:\OSGEO4~1\apps\Python37;C:\OSGEO4~1\apps\Python37\Scripts
C:\OSGeo4W64>PATH C:\OSGEO4~1\apps\Python37;C:\OSGEO4~1\apps\Python37\Scripts;{app};C:\Program Files\MiKTeX 2.9\miktex\bin;C:\OSGEO4~1\apps\Python27\Scripts;C:\OSGEO4~1\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32\WBem;C:\Program Files\R\R-3.6.3\bin\x64
C:\OSGeo4W64>dist\convert_utm_wgs\convert_utm_wgs.exe -n 1681295.7765812099 -e 2491253.6273768987
(-33.86732713160471, 151.2083407968708)
C:\OSGeo4W64>
Если я сначала попытаюсь перейти к py3_env, а затем с помощью pyinstaller создать файл .exe, а затем проверить, я получу ошибки:
C:\OSGeo4W64>dist\convert_utm_wgs\convert_utm_wgs.exe -n 1681295.7765812099 -e 2491253.6273768987
Traceback (most recent call last):
File "lib\site-packages\osgeo\__init__.py", line 18, in swig_import_helper
File "lib\imp.py", line 297, in find_module
ImportError: No module named '_gdal'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "convert_utmsa_to_wgs84\convert_utm_wgs.py", line 2, in <module>
from osgeo import osr
File "C:\OSGEO4~1\apps\Python37\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 623, in exec_module
exec(bytecode, module.__dict__)
File "lib\site-packages\osgeo\__init__.py", line 41, in <module>
File "lib\site-packages\osgeo\__init__.py", line 20, in swig_import_helper
ModuleNotFoundError: No module named '_gdal'
[113704] Failed to execute script convert_utm_wgs
И когда Я закрываю osgeo4w.bat и снова открываю его, чтобы он находился в среде по умолчанию, затем снова запускаю тест, я получаю:
В CMD (после изменения в нужный каталог):
C:\OSGeo4W64>C:\OSGeo4W64\dist\convert_utm_wgs\convert_utm_wgs.exe -n 1681295.7765812099 -e 2491253.6273768987
ERROR 1: PROJ: proj_create_from_database: Cannot find proj.db
ERROR 1: PROJ: proj_create_from_database: Cannot find proj.db
ERROR 1: PROJ: proj_create: unrecognized format / unknown name
ERROR 6: Cannot find coordinate operations from `' to `'
Traceback (most recent call last):
File "convert_utmsa_to_wgs84\convert_utm_wgs.py", line 36, in <module>
sys.stdout.write(U_W(easting=easting,northing=northing))
File "convert_utmsa_to_wgs84\convert_utm_wgs.py", line 21, in U_W
point.Transform(transform)
File "site-packages\osgeo\ogr.py", line 7036, in Transform
TypeError: in method 'Geometry_Transform', argument 2 of type 'OSRCoordinateTransformationShadow *'
[119504] Failed to execute script convert_utm_wgs
C:\OSGeo4W64>
И с помощью файла test.py:
## test.py
import os
import sys
##result = os.system("""C:/OSGeo4W64/convert_utmsa_to_wgs84/dist/convert_utm_wgs/convert_utm_wgs.exe -n 1681295.7765812099 -e 2491253.6273768987""")
sys.path.insert(0,r'C:/OSGeo4W64/convert_utmsa_to_wgs84/convert_utm_wgs.py')
##print (result)
import subprocess
result = subprocess.Popen(["cmd", "C:/OSGeo4W64/convert_utmsa_to_wgs84/dist/convert_utm_wgs/convert_utm_wgs.exe", "-n", "1681295.7765812099", "-e", "2491253.6273768987"],stdout=subprocess.PIPE)
print (result.communicate())
##result = subprocess.check_call(["C:/OSGeo4W64/convert_utmsa_to_wgs84/dist/convert_utm_wgs/convert_utm_wgs.exe", "-n", "1681295.7765812099", "-e", "2491253.6273768987"])
##print (result)
def run(cmd):
## os.environ['PYTHONUNBUFFERED'] = "1"
proc = subprocess.Popen(cmd,
## stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT,
)
stdout, stderr = proc.communicate()
return proc.returncode, stdout, stderr
print (sys.executable)
code, out, err = run([r'C:\\OSGeo4W64\\dist\\convert_utm_wgs\\convert_utm_wgs.exe',
'-n', '1681295.7765812099', '-e','2491253.6273768987'])# -n 1681295.7765812099 -e 2491253.6273768987'])
print("out: '{}'".format(out))
print("err: '{}'".format(err))
print("exit: {}".format(code))
Вывод:
(b'', None)
C:\Python38\pythonw.exe
out: 'b'ERROR 1: PROJ: proj_create_from_database: Cannot find proj.db\r\nERROR 1: PROJ: proj_create_from_database: Cannot find proj.db\r\nERROR 1: PROJ: proj_create: unrecognized format / unknown name\r\nERROR 6: Cannot find coordinate operations from `\' to `\'\r\n[119696] Failed to execute script convert_utm_wgs\r\nTraceback (most recent call last):\r\n File "convert_utmsa_to_wgs84\\convert_utm_wgs.py", line 36, in <module>\r\n File "convert_utmsa_to_wgs84\\convert_utm_wgs.py", line 21, in U_W\r\n File "site-packages\\osgeo\\ogr.py", line 7036, in Transform\r\nTypeError: in method \'Geometry_Transform\', argument 2 of type \'OSRCoordinateTransformationShadow *\'\r\n''
err: 'None'
exit: 4294967295
У меня три вопроса:
Судя по ошибкам, которые я получаю из test.py и CMD, похоже, что это относится к файлам, внешним по отношению к пакету, созданному pyinstaller. Разве pyinstaller не импортирует все зависимости, чтобы его можно было доставлять самостоятельно (со всеми файлами .dll и т. Д. c)?
Как я могу исправить эти ошибки, которые я получаю в тестах CMD и test.py?
Существует ли более разумный способ сделать эту функцию доступной, чтобы другие программы могли вызывать ее с аргументами -e 2342324.534 -n 2342324.534?