java - 使用 bat 脚本更新 env 后,从 java 调用 GDAL 的可移植二进制文件时,模块 osgeo (embd.py) 出现导入错误。路径变量

标签 java batch-file environment-variables python-import gdal

编辑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

这里有一些事情:

  1. 我使用 launch4j 为我的 jar 文件提供 jvm 的路径,并将其制作为 exe,这就是为什么有 mysoft.exe
  2. 我已在软件中指定相对路径来访问所需的可执行文件或脚本。
  3. 我使用了 python-embedded 并给出了我要调用的 python 脚本的相对路径,如 gdal_merge.py .
  4. 我不想做 setx一旦进入bat文件并直接运行软件,因为如果用户更改软件的目录并再次运行脚本,Windows中的路径大小限制将被耗尽,这将是一场灾难。 (为什么我从 bat 文件启动该软件。)

该脚本应该为启动的所有子进程设置环境变量。

我可以确认gdal_translate工作得很好。 [我确实指定了它的相对路径,而不是从环境中调用它。]

工作流程:

  1. 我在bat文件中设置环境变量并启动java程序。
  2. 我有一个 Java 程序作为用户界面。 Java 程序调用一些可执行文件或脚本,其中包括 gdal_merge.py .
  3. 我在代码中指定 gdal_merge.py 的完整路径,并使用 ProcessBuilder 调用它

错误:

from osgeo import gdal
ModuleNotFoundError: No module named 'osgeo'.

预期的解决方案: 从bat文件设置路径(到嵌入式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\

这就像一个魅力。

关于java - 使用 bat 脚本更新 env 后,从 java 调用 GDAL 的可移植二进制文件时,模块 osgeo (embd.py) 出现导入错误。路径变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56883778/

相关文章:

git - 如何在github中存储.env文件?

python - 多次执行 Python 脚本的批处理脚本

jenkins - 使用kubernetes yml文件时如何在gradle中处理环境替换?

linux - 使用 Capistrano 跨集群设置环境变量

java - 有没有更好的方法来测试以下方法而无需模拟返回模拟?

windows - 使用脚本模拟鼠标点击windows启动

batch-file - msdeploy deploy.cmd 文件未正确解析参数

java - 如何用mockito拦截普通对象数组的参数?

java - gradle proj同步失败,尝试了每种方法

java - 对于随机数