在使用 bat 脚本更新环境后,从 java 调用 GDAL 的可移植二进制文件时模块 osgeo (embd.py) 的导入错误。路径变量
ImportError for module osgeo (embd. py) while invoking portable binaries of GDAL from java, after using a bat script to update env. path variables
编辑 1:忘记提及 python,我使用的是嵌入式 python。
我已经从 GIS Internals 下载了 windows 个 GDAL 二进制文件。
前提:
目录结构:
Parent
|gnuplot
|mysoft.exe
|gdal
|python-embedded
|jvm
|gsl2
|mybinaries
|mysoftlaunch.bat
bat文件是GDAL二进制文件提供的,我对文件和放入的目录做了相关修改
@echo off
set SDK_ROOT=%~dp0gdal\
set SDK_ROOT=%SDK_ROOT:\=\%
set GNUPLOT_ROOT=%~dp0gnuplot\
set PYTHON_ROOT=%~dp0python-3.7.3-embed-amd64\
@echo %SDK_ROOT%
@echo %GNUPLOT_ROOT%
goto setenv
if "%1" == "setenv" goto setenv
%comspec% /k "%SDK_ROOT%SDKShell.bat" setenv %1
goto exit
:setenv
@echo Setting environment for using the GDAL and MapServer tools.
if "%2"=="hideoci" goto hideoci
set ocipath=0
set _path="%PATH:;=" "%"
for %%p in (%_path%) do if not "%%~p"=="" if exist %%~p\oci.dll set ocipath=1
if "%ocipath%"=="0" goto hideoci
@echo WARNING: If you encounter problems with missing oci libraries then type:
@echo SDKShell hideoci
goto setenv2
...
...
:setenv2
@echo at set env 2
SET "PATH=%SDK_ROOT%bin;%SDK_ROOT%bin\gdal\python\osgeo;%SDK_ROOT%bin\proj6\apps;%SDK_ROOT%bin\gdal\apps;%SDK_ROOT%bin\ms\apps;%SDK_ROOT%bin\gdal\csharp;%SDK_ROOT%bin\ms\csharp;%SDK_ROOT%bin\curl;%GNUPLOT_ROOT%bin\;%SDK_ROOT%gsl2\bin\;%PATH%"
SET "GDAL_DATA=%SDK_ROOT%bin\gdal-data"
SET "GDAL_DRIVER_PATH=%SDK_ROOT%bin\gdal\plugins"
SET "PYTHONPATH=%SDK_ROOT%bin\gdal\python\osgeo;%SDK_ROOT%bin\gdal\python;%SDK_ROOT%bin\ms\python;%PYTHON_ROOT%"
SET "PROJ_LIB=%SDK_ROOT%bin\proj6\SHARE"
SET "LD_LIB_PATH=%SDK_ROOT%gsl2\lib"
@echo done setting variables
start "MYSOFT" cmd /c java -jar "%~dp0mysoft.exe%"
@echo started mysoftware
exit
:exit
这里有几件事:
- 我已经使用 launch4j 为我的 jar 文件提供了到 jvm 的路径,并使它成为一个 exe,这就是为什么有 mysoft.exe
- 我在我的软件中指定了相对路径以访问所需的可执行文件或脚本。
- 我使用了 python-embedded 并给出了 python 脚本的相对路径,我会像
gdal_merge.py
. 那样调用它
- 我不想在 bat 文件和 运行 软件中直接执行
setx
一次,因为如果用户更改软件目录和 运行 脚本同样,windows 中的路径大小限制将用尽,这将是一场灾难。 (为什么我要从 bat 文件启动软件。)
该脚本应该为所有启动的子进程设置环境变量。
我可以确认 gdal_translate
工作正常。 [我确实指定了它的相对路径,而不是从环境中调用它。]
工作流程:
- 我在 bat 文件中设置环境变量并启动 java 程序。
- 我有一个 Java 程序作为用户界面。 Java 程序调用一些可执行文件或脚本,其中包括
gdal_merge.py
.
- 我在代码中指定 gdal_merge.py 的完整路径并使用 ProcessBuilder
调用它
错误:
from osgeo import gdal
ModuleNotFoundError: No module named 'osgeo'.
预期的解决方案:
从 bat 文件设置路径后(到 embedded-python、jvm、gdal{都需要像 gdal_data、gdal_driver、二进制文件的路径等),启动 Java 软件继承那些启动 gdal_merge.py
文件的环境变量。
以下方式:
String path = System.getProperty("user.dir");
ProcessBuilder pb = new ProcessBuilder();
pb.inheritIO();
pb.command(Paths.get(path+"/python-embedded/python.exe").toString(),Paths.get(path+"/gdal/....../python/scripts/gdal_merge.py").toString(),...{other parameters required for gdal_merge.py});
PS:
Paths.get(x+"abc/def/").toString()
- 我正在使用将 *NIX 样式路径转换为 Windows 样式路径。
根据 Issue28245 Python bugs,这是一个故意的功能。嵌入式 python 与您的系统环境完全隔离。
要包含此嵌入式 python 查找包的路径,您需要编辑 pythonxx._pth 文件。
只需在每一行中添加一个路径即可。不需要变量。您也可以添加相对路径。
._pth 文件示例:
pythonxx.zip # default value
. # default value
..\gdal\bin\gdal\python\
..\gdal\bin\gdal\python\osgeo\
..\gdal\bin\gdal\python\scripts\
..\gdal\bin\ms\python\
这很有魅力。
编辑 1:忘记提及 python,我使用的是嵌入式 python。
我已经从 GIS Internals 下载了 windows 个 GDAL 二进制文件。 前提:
目录结构:
Parent
|gnuplot
|mysoft.exe
|gdal
|python-embedded
|jvm
|gsl2
|mybinaries
|mysoftlaunch.bat
bat文件是GDAL二进制文件提供的,我对文件和放入的目录做了相关修改
@echo off
set SDK_ROOT=%~dp0gdal\
set SDK_ROOT=%SDK_ROOT:\=\%
set GNUPLOT_ROOT=%~dp0gnuplot\
set PYTHON_ROOT=%~dp0python-3.7.3-embed-amd64\
@echo %SDK_ROOT%
@echo %GNUPLOT_ROOT%
goto setenv
if "%1" == "setenv" goto setenv
%comspec% /k "%SDK_ROOT%SDKShell.bat" setenv %1
goto exit
:setenv
@echo Setting environment for using the GDAL and MapServer tools.
if "%2"=="hideoci" goto hideoci
set ocipath=0
set _path="%PATH:;=" "%"
for %%p in (%_path%) do if not "%%~p"=="" if exist %%~p\oci.dll set ocipath=1
if "%ocipath%"=="0" goto hideoci
@echo WARNING: If you encounter problems with missing oci libraries then type:
@echo SDKShell hideoci
goto setenv2
...
...
:setenv2
@echo at set env 2
SET "PATH=%SDK_ROOT%bin;%SDK_ROOT%bin\gdal\python\osgeo;%SDK_ROOT%bin\proj6\apps;%SDK_ROOT%bin\gdal\apps;%SDK_ROOT%bin\ms\apps;%SDK_ROOT%bin\gdal\csharp;%SDK_ROOT%bin\ms\csharp;%SDK_ROOT%bin\curl;%GNUPLOT_ROOT%bin\;%SDK_ROOT%gsl2\bin\;%PATH%"
SET "GDAL_DATA=%SDK_ROOT%bin\gdal-data"
SET "GDAL_DRIVER_PATH=%SDK_ROOT%bin\gdal\plugins"
SET "PYTHONPATH=%SDK_ROOT%bin\gdal\python\osgeo;%SDK_ROOT%bin\gdal\python;%SDK_ROOT%bin\ms\python;%PYTHON_ROOT%"
SET "PROJ_LIB=%SDK_ROOT%bin\proj6\SHARE"
SET "LD_LIB_PATH=%SDK_ROOT%gsl2\lib"
@echo done setting variables
start "MYSOFT" cmd /c java -jar "%~dp0mysoft.exe%"
@echo started mysoftware
exit
:exit
这里有几件事:
- 我已经使用 launch4j 为我的 jar 文件提供了到 jvm 的路径,并使它成为一个 exe,这就是为什么有 mysoft.exe
- 我在我的软件中指定了相对路径以访问所需的可执行文件或脚本。
- 我使用了 python-embedded 并给出了 python 脚本的相对路径,我会像
gdal_merge.py
. 那样调用它
- 我不想在 bat 文件和 运行 软件中直接执行
setx
一次,因为如果用户更改软件目录和 运行 脚本同样,windows 中的路径大小限制将用尽,这将是一场灾难。 (为什么我要从 bat 文件启动软件。)
该脚本应该为所有启动的子进程设置环境变量。
我可以确认 gdal_translate
工作正常。 [我确实指定了它的相对路径,而不是从环境中调用它。]
工作流程:
- 我在 bat 文件中设置环境变量并启动 java 程序。
- 我有一个 Java 程序作为用户界面。 Java 程序调用一些可执行文件或脚本,其中包括
gdal_merge.py
. - 我在代码中指定 gdal_merge.py 的完整路径并使用 ProcessBuilder 调用它
错误:
from osgeo import gdal
ModuleNotFoundError: No module named 'osgeo'.
预期的解决方案:
从 bat 文件设置路径后(到 embedded-python、jvm、gdal{都需要像 gdal_data、gdal_driver、二进制文件的路径等),启动 Java 软件继承那些启动 gdal_merge.py
文件的环境变量。
以下方式:
String path = System.getProperty("user.dir");
ProcessBuilder pb = new ProcessBuilder();
pb.inheritIO();
pb.command(Paths.get(path+"/python-embedded/python.exe").toString(),Paths.get(path+"/gdal/....../python/scripts/gdal_merge.py").toString(),...{other parameters required for gdal_merge.py});
PS:
Paths.get(x+"abc/def/").toString()
- 我正在使用将 *NIX 样式路径转换为 Windows 样式路径。
根据 Issue28245 Python bugs,这是一个故意的功能。嵌入式 python 与您的系统环境完全隔离。
要包含此嵌入式 python 查找包的路径,您需要编辑 pythonxx._pth 文件。
只需在每一行中添加一个路径即可。不需要变量。您也可以添加相对路径。
._pth 文件示例:
pythonxx.zip # default value
. # default value
..\gdal\bin\gdal\python\
..\gdal\bin\gdal\python\osgeo\
..\gdal\bin\gdal\python\scripts\
..\gdal\bin\ms\python\
这很有魅力。