I've been trying to find a free and easy way to convert .dem files to .grid files, and I've been working on getting a python program that was online to do it. I've been getting an error that I don't understand, and looking it up online has shown me that people have gotten this error before, but not necessarily in the context that I'm finding it, so their solutions involve installing different modules that are not the one that I need.
Here is my python installment:
Python 3.4.0 (v3.4.0:04f714765c13) [MSC v.1600 64 bit (AMD64)] on win32
Here is how I installed a module I needed, called osgeo. I followed the steps based on the above python installment, making sure that I used the correct versions for everything: Instructions I used Following those instructions allowed me to get past an error that osgeo didn't exist, so at least I've made some progress in that aspect.
Here is the code I've been trying to run:
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()
Here is my error message:
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.
I've also tried other code from this forum, such as the one by a user named siki, but all of my attempts have ended up with the same error as shown in the example above.
Thanks for anyone who helps. Again, it doesn't HAVE to be a python script that does the conversion for me, I just need a free way to convert .dem to .grid, and the typical programs for this like ArcGIS are not free.
You didn't set your %PATH% env var right. I managed to reproduce the problem, and also to fix it. Some of the steps that I took are different than the regular ones, for reasons that I'll explain later:
Saved your code on my computer (code.py). Running it, (obviously) failed:
(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'
Downloaded:
msiexec /a GDAL-2.2.3.win-amd64-py3.4.msi TARGETDIR="E:\Work\Dev\StackOverflow\q048854161\gdal_py"
(msiexec
's Adminstrative Installation as shown on [SuperUser]: How do I extract files from an MSI package?, check [MS.Docs]: Command-Line Options for more details)
Adding gdal_py to %PYTHONPATH% (not necessary for regular installation of #2., as the files are already in Python's module search path - check the moving operation that I had to do earlier), and running it again, yielded:
(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.
This is exactly your error. So, it tries to load _gdal.pyd and fails, not because it can't find it, but because (some of) its dependencies could not be found (here, the error message is misleading, if the module wouldn't have been found the error would be: ImportError: No module named '_gdal'
).
Below is a picture of _gdal.pyd loaded in Dependency Walker. Note that the regular #2. installation places it under %PYTHON34X64_INSTALL_DIR%\Lib\site-packages\osgeo (that's not a real env var, just a path placeholder):
As seen, it depends on gdal202.dll. So, when _gdal.pyd is imported, the OS needs to find all of its dependencies: note that this is done recursively (dependencies, dependencies' dependencies, and so on). This is what the %PATH% env var setting in the tutorial was about. For me, the simplest way was to add gdal202.dll dir (as it is part of #1., that would be gdal\bin) to %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
It worked! Well, it didn't quite work, because there are other things in your script that I don't have, but it successfully passed this step. Now, there could be errors in the script, that would prevent you to achieve your goal, but those are not related to the current problem.