0

I have been writing a python script to convert an ascii grid into a geotiff file and when running the Create method in gdal i am receiving the following error message:

william@will-HP-EliteBook-850-G1:~/Smells$ python SmellsGeoTag.py ./SmellsTestData/test3/input/tile_1 ./output
Traceback (most recent call last):
  File "SmellsGeoTag.py", line 47, in <module>
    dst_ds = driver.Create(out , ncols, nrows, 1, gdal.GDT_Float32 )
  File "/usr/local/lib/python2.7/dist-packages/GDAL-1.11.0-py2.7-linux-x86_64.egg/osgeo/gdal.py", line 394, in Create
    return _gdal.Driver_Create(self, *args, **kwargs)
TypeError: in method 'Driver_Create', argument 3 of type 'int'

however unlike the problem here my ncols and nrows values are non zero ints, so i am rather stumped as to what the problem is

source code:

#!/usr/bin/python
import sys, getopt, os, numpy
from osgeo import osr, gdal

if len(sys.argv) != 3:
    print ("Please use the following arguements: input path, output path");
    exit();

inRoot = sys.argv[1]
outRoot = sys.argv[2]

#finding valid files
potentialDates = os.listdir(inRoot)
dates = []
for i in potentialDates:
    if os.path.isdir(os.path.join(inRoot, i)):
        dates.append(i)

for i in dates:
    potentialFiles = []
    files = []
    potentialFiles = os.listdir(os.path.join(inRoot, i))    
    for x in potentialFiles:
        if x.endswith(".asc"):
            files.append(x)
    #processing each valid file found
    for y in files:
        with open(os.path.join(inRoot, i, y), "r") as f:
            linelist = [line for line in f]
            junk, xllcorner = linelist.pop(0).split()
            float(xllcorner)
            junk, yllcorner = linelist.pop(0).split()
            float(yllcorner)
            junk, ncols = linelist.pop(0).split()
            int(ncols)
            junk, nrows = linelist.pop(0).split()
            int(nrows)
            junk, cellsize = linelist.pop(0).split()
            float(cellsize)
            junk, nodataval = linelist.pop(0).split()
            float(nodataval)
            data = [[float(digit) for digit in line.split()]for line in linelist]   
            driver = gdal.GetDriverByName("GTiff")
            if not os.path.exists(os.path.join(outRoot,i)):
                os.makedirs(os.path.join(outRoot,i))
            out = os.path.join(outRoot,i,y+".tif")
            dst_ds = driver.Create(out , ncols, nrows, 1, gdal.GDT_Float32 )
            dst_ds.SetGeoTransform( [xllcorner,cellsize,0,yllcorner,0,cellsize] )
            # set the reference info 
            srs = osr.SpatialReference()
            srs.SetWellKnownGeogCS("WGS84")
            dst_ds.SetProjection( srs.ExportToWkt() )
            # write the band
            dst_ds.GetRasterBand(1).WriteArray(data)

exit()
4

The values ncols, nrows you are passing to driver.Create are still strings and not integer values. After reading in the ncols variable in

junk, ncols = linelist.pop(0).split()

the ncols contains a string with your value. The line after int(ncols) converts it to an int but you don't store its result (int() function does not change the value in place), so you need to write that line as:

ncols = int(ncols)

In case of doubt you can output the type of every variable before the driver.Create(...) call for example with:

print 'ncols:', type(ncols), ' - nrows:', type(nrows)

Hope this helps.

P.S. As a side note: Just in case, I don't know if the gdal_translate program could help you in doing the ASCII raster to GeoTiff conversion. It is designed for converting one Raster file to another, and it can be used to do simple format translations, among many other things. Available Raster formats are here.

2
  • @Luke Thanks for pointing out my mistake. I was thinking of gdal_translate and was writing gdalwarp... Sorry for the misleading info. I have updated my answer accordingly. – chkaiser Sep 8 '15 at 10:28
  • thanks for the info, ill probably end up using gdal_translate or natively read in ascii using gdal.open, for future applications. Its quite useful to know that kind of functionality exists so thanks =) – willsta Sep 21 '15 at 10:57
2

Since GDAL can read ASCII grids natively, you don't need to parse it, just use GDAL to open it then use the GeoTIFF driver CreateCopy method.

#!/usr/bin/python
import sys, getopt, os, numpy
from osgeo import osr, gdal

if len(sys.argv) != 3:
    print ("Please use the following arguments: input path, output path");
    exit();

inRoot = sys.argv[1]
outRoot = sys.argv[2]

#Save a bit of time by only creating these objects once.
driver = gdal.GetDriverByName("GTiff")
# set the reference info
srs = osr.SpatialReference()
srs.SetWellKnownGeogCS("WGS84")

#finding valid files
potentialDates = os.listdir(inRoot)
dates = []
for i in potentialDates:
    if os.path.isdir(os.path.join(inRoot, i)):
        dates.append(i)

for i in dates:
    potentialFiles = []
    files = []
    potentialFiles = os.listdir(os.path.join(inRoot, i))
    for x in potentialFiles:
        if x.endswith(".asc"):
            files.append(x)
    #processing each valid file found
    for y in files:
        ds = gdal.Open(os.path.join(inRoot, i, y))
        if not os.path.exists(os.path.join(outRoot,i)):
            os.makedirs(os.path.join(outRoot,i))
        out = os.path.join(outRoot,i,y+".tif")
        dst_ds = driver.CreateCopy(out, ds)
        dst_ds.SetProjection( srs.ExportToWkt() )
        del dst_ds #Close the dataset to finalize the write

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.