python - 尝试将 .dem 文件转换为 .grid 文件时,Python 出现 DLL 加载失败错误

标签 python dll load gdal

我一直在尝试找到一种免费且简单的方法将 .dem 文件转换为 .grid 文件,并且我一直在努力获取一个在线的 python 程序来执行此操作。我遇到了一个我不明白的错误,在线查找表明人们以前已经遇到过这个错误,但不一定是在我发现它的上下文中,所以他们的解决方案涉及安装不同的模块这不是我需要的。

这是我的Python安装:

Python 3.4.0 (v3.4.0:04f714765c13) [MSC v.1600 64 bit (AMD64)] on win32

以下是我安装所需模块(名为 osgeo)的方法。我按照上述 python 安装的步骤进行操作,确保我对所有内容都使用了正确的版本: Instructions I used 遵循这些说明让我克服了 osgeo 不存在的错误,所以至少我在这方面取得了一些进展。

这是我一直尝试运行的代码:

import sys
import os
import osgeo.gdal as gd
from gdalconst import GA_ReadOnly, GDT_Byte, GDT_UInt16, GDT_Int16, \
     GDT_UInt32, GDT_Int32, GDT_Float32, GDT_Float64
import struct

# GDAL data types to packt data_types
gd_type = {GDT_Byte:    "b",
           GDT_UInt16:  "H",
           GDT_Int16:   "h",
           GDT_UInt32:  "I",
           GDT_Int32:   "i",
           GDT_Float32: "f",
           GDT_Float64: "d"}
# establish input file
ifilename = r"C:\Users\Nick\Desktop\sample.dem"
# generate output file name 
ofilename = os.path.splitext(ifilename)[0] + ".grid"
# use gdal to read DEM file
idataset = gd.Open(ifilename, GA_ReadOnly)
if idataset is None:
    print("Cannot read input file {}".format(ifilename));
    sys.exit(2)
# get size of dem
cols = idataset.RasterXSize
rows = idataset.RasterYSize
# get and calculate coordinate limits
tr = idataset.GetGeoTransform()
xul = tr[0]
yul = tr[3]
xlr = xul + (cols - 1) * tr[1] 
ylr = yul + (rows - 1) * tr[5]
# write data to binary output
of = open(ofilename, "wb")
of.write(struct.pack("2i", cols, rows))
of.write(struct.pack("4f", xul, ylr, xlr, yul))
band = idataset.GetRasterBand(1)
d = band.ReadRaster(0, 0, cols, rows, cols, rows, band.DataType)
data = struct.unpack(gd_type[band.DataType] * (rows * cols), d)
of.write(struct.pack("f" * (cols * rows), *data))
of.close()

这是我的错误消息:

Traceback (most recent call last):
  File "C:/Users/Nick/Desktop/demtogrid.py", line 3, in <module>
    import osgeo.gdal as gd
  File "C:\Python34\lib\site-packages\osgeo\__init__.py", line 21, in <module>
    _gdal = swig_import_helper()
  File "C:\Python34\lib\site-packages\osgeo\__init__.py", line 17, in swig_import_helper
    _mod = imp.load_module('_gdal', fp, pathname, description)
  File "C:\Python34\lib\imp.py", line 243, in load_module
    return load_dynamic(name, filename, file)
ImportError: DLL load failed: The specified module could not be found.

我还尝试了 this forum 中的其他代码,例如名为 siki 的用户的尝试,但我的所有尝试都以与上例所示相同的错误告终。

感谢任何提供帮助的人。再说一次,它不一定是一个为我进行转换的 python 脚本,我只需要一种免费的方式将 .dem 转换为 .grid,而像 ArcGIS 这样的典型程序并不是免费的。

最佳答案

您没有正确设置 %PATH% 环境变量。我设法重现了该问题,并修复了它。我采取的一些步骤与常规步骤不同,原因稍后我将解释:

  • 我的机器上安装了大约 10 个Python(一些是安装的,一些是我构建的 - 使用不同的编译器;其中大多数是 x64,一些是 VEnved,但这应该没有任何区别),Python 3.4 x64(使用编译器 v1.600 构建 - VStudio 10.0>) 就在其中
  • 已将您的代码保存到我的计算机上 (code.py)。运行它,(显然)失败了:

    (py34x64_test) E:\Work\Dev\StackOverflow\q048854161>"e:\Work\Dev\VEnvs\py34x64_test\Scripts\python.exe" code.py
    Traceback (most recent call last):
      File "code.py", line 3, in <module>
        import osgeo.gdal as gd
    ImportError: No module named 'osgeo'
    
  • 已下载:

    1. [GISInternals]: release-1600-x64-gdal-2-2-3-mapserver-7-0-7.zip - 在单个 .zip 包中编译的二进制文件
    2. [GISInternals]: GDAL-2.2.3.win-amd64-py3.4.msi - GDAL python 绑定(bind)的安装程序(需要安装 GDAL 核心)
  • 解压(在当前目录中):
    • #1. 位于名为 gdal 的目录中 - 只需将其解压缩即可
    • #2. 在名为 gdal_py 的目录中 - 通过运行 msiexec/a GDAL-2.2.3.win-amd64 -py3.4.msi TARGETDIR="E:\Work\Dev\StackOverflow\q048854161\gdal_py"(msiexec管理安装,如 [SuperUser]: How do I extract files from an MSI package? 上所示,检查 [MS.Docs]: Command-Line Options 了解更多详细信息)
      • 由于正常安装将相关文件放在Python安装目录中,因此它也模仿它们,因此相关文件实际上安装在“gdal_py\Lib\site-packages”中”,为了简单起见,我将它们向上移动了 2 个文件夹(直接在 gdal_py 目录中)
    • 我这样做是因为我不想用我可能只会使用一次的pkg污染我的操作系统,所以我想这两个仅与这个问题相关。当然,这会带来额外的麻烦(开个玩笑:)),这在常规安装过程中不会发生
  • gdal_py添加到%PYTHONPATH%(对于常规安装#2.来说不是必需的,因为文件已经在Python的模块搜索路径 - 检查我之前必须执行的移动操作),然后再次运行它,得到:

    (py34x64_test) E:\Work\Dev\StackOverflow\q048854161>set PYTHONPATH=%PYTHONPATH%;gdal_py
    
    (py34x64_test) E:\Work\Dev\StackOverflow\q048854161>"e:\Work\Dev\VEnvs\py34x64_test\Scripts\python.exe" code.py
    Traceback (most recent call last):
      File "code.py", line 3, in <module>
        import osgeo.gdal as gd
      File "E:\Work\Dev\StackOverflow\q048854161\gdal_py\osgeo\__init__.py", line 21, in <module>
        _gdal = swig_import_helper()
      File "E:\Work\Dev\StackOverflow\q048854161\gdal_py\osgeo\__init__.py", line 17, in swig_import_helper
        _mod = imp.load_module('_gdal', fp, pathname, description)
      File "e:\Work\Dev\VEnvs\py34x64_test\lib\imp.py", line 243, in load_module
        return load_dynamic(name, filename, file)
    ImportError: DLL load failed: The specified module could not be found.
    
  • 这正是您的错误。因此,它尝试加载 _gdal.pyd 并失败,不是因为找不到它,而是因为找不到(某些)其依赖项(这里,错误消息具有误导性,如果找不到该模块,错误将是:ImportError:没有名为“_gdal”的模块)。
    下面是加载在 Dependency Walker 中的 _gdal.pyd 的图片。请注意,常规的#2.安装将其放置在%PYTHON34X64_INSTALL_DIR%\Lib\site-packages\osgeo下(这不是真正的环境变量,只是一个路径占位符):

    _gdal.pyd

  • 正如所见,它依赖于gdal202.dll。因此,当导入_gdal.pyd时,操作系统需要找到它的所有依赖项:请注意,这是递归地完成的(依赖项、依赖项' 依赖关系,等等)。这就是教程中的 %PATH% env var 设置的内容。对我来说,最简单的方法是添加 gdal202.dll 目录(因为它是 #1. 的一部分,即 gdal\bin ) 到 %PATH% ([MS.Docs]: Dynamic-Link Library Search Order):

    (py34x64_test) E:\Work\Dev\StackOverflow\q048854161>set PATH=%PATH%;gdal\bin
    
    (py34x64_test) E:\Work\Dev\StackOverflow\q048854161>"e:\Work\Dev\VEnvs\py34x64_test\Scripts\python.exe" code.py
    ERROR 4: C:\Users\Nick\Desktop\sample.dem: No such file or directory
    Cannot read input file C:\Users\Nick\Desktop\sample.dem
    
  • 成功了!好吧,它不太有效,因为你的脚本中有其他东西我没有,但它成功通过了这一步。现在,脚本中可能存在错误,这会阻止您实现目标,但这些错误与当前问题无关。

关于python - 尝试将 .dem 文件转换为 .grid 文件时,Python 出现 DLL 加载失败错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48854161/

相关文章:

python - Mitmproxy 上游服务器

wpf - 将一些 WPF 窗口放入 DLL

winapi - 从 Excel XLL 创建小型转储

c# - 如何在同一个包中使用 2 个不同版本的 dll?

jquery - 我想从链接将不同的图像加载到一个 div

JavaScript:文本区域加载

python - 将列表作为列添加到数据框的正确方法是什么?

python - 在 Python 中加载本体

python - 第二个循环中存在冲突的选项字符串

postgresql - 有什么简单的工具可以将 CSV 文件加载到 PostgreSQL 中吗?