7

Following a comment on Error using SQL statement in ogr2ogr with Python string formatter, I am trying to use gdal.VectorTranslate() instead of ogr2ogr, but I keep receiving an error.

Using Windows, Python 3.7, and GDAL 3.3.1.

The following ogr2ogr approach works fine.

import os
import numpy as np
import pathlib

## example dummy ids
id1 = np.linspace(start=1, stop=5, num=5, endpoint=True, dtype=int)
id2 = np.linspace(start=301, stop=302, num=2, endpoint=True, dtype=int)

outpath = pathlib.Path("working").resolve()
for ii in id1:
    command = (
        ' ogr2ogr -f "KML" "{outfile}" "{infile}" '
        ' -where "ID_1 = {my_id}" '
        ' -dsco NameField = "{name}" '
    )
    fout = 'test' + str(ii) + '.kml'
    fout = outpath / fout
    os.system(command.format(outfile=fout, infile='points.shp', my_id=ii, name='county'))

But trying gdal.VectorTranslate() based on the documentation for VectorTranslate and VectorTranslateOptions here throws the error as shown. I want to try this approach to see if it passes SQL statements easier than the -sql option in ogr2ogr.

for ii in id1:
    command = (
        ' ogr2ogr -f "KML" "{outfile}" "{infile}" '
        ' -where "ID_1 = {my_id}" '
        ' -dsco NameField = "{name}" '
    )
    fout = 'test' + str(ii) + '.kml'
    fout = outpath / fout
    args = gdal.VectorTranslateOptions(
        format="KML",
        SQLStatement=command.format(outfile=fout, infile='points.shp', my_id=ii, name='county')
    )
    gdal.VectorTranslate(
        destNameOrDestDS=fout,
        srcDS=shpecs,
        options=args
    )

Error:

C:\Users\name\anaconda3\envs\myenv\python.exe "D:/Documents/test.py"
Traceback (most recent call last):
D:\Documents\points
  File "D:/Documents/test.py", line 51, in <module>
    options=args
D:\Documents\working
  File "C:\Users\name\anaconda3\envs\myenv\lib\site-packages\osgeo\gdal.py", line 857, in VectorTranslate
    return wrapper_GDALVectorTranslateDestDS(destNameOrDestDS, srcDS, opts, callback, callback_data)
  File "C:\Users\name\anaconda3\envs\myenv\lib\site-packages\osgeo\gdal.py", line 4625, in wrapper_GDALVectorTranslateDestDS
    return _gdal.wrapper_GDALVectorTranslateDestDS(*args)
TypeError: in method 'wrapper_GDALVectorTranslateDestDS', argument 1 of type 'GDALDatasetShadow *'

I receive the same error if I pass the options directly into VectorTranslate.

1 Answer 1

8

Here's how to use gdal.VectorTranslate, note that some ogr2ogr options map to slightly different arguments, but they should be easily figured out:

from osgeo import gdal
import numpy as np
import pathlib

gdal.UseExceptions()

## example dummy ids
id1 = np.linspace(start=1, stop=1, num=1, endpoint=True, dtype=int)
id2 = np.linspace(start=1, stop=1, num=1, endpoint=True, dtype=int)

infile = '/tmp/points.shp'
inlayer = pathlib.Path(infile).stem
outpath = pathlib.Path("/tmp").resolve()
name_field = 'county'

for ii in id1:
    for jj in id2:
        fout = str(outpath / f'test{ii}_{jj}.kml')

        ds = gdal.VectorTranslate(
            fout, infile,
            # SQLStatement=f'SELECT * from {inlayer} WHERE ID_1 = {ii} AND ID_2 = {jj}',
            where=f'ID_1 = {ii} AND ID_2 = {jj}',
            datasetCreationOptions=[f'NameField={name_field}'],
            layers=[inlayer],
            format='KML'
        )

Note:

  • I've changed your -sql argument clause to a simpler -where argument
  • I used f'string {variable}' aka "f strings" for a cleaner syntax
3
  • Thanks, another great explanation! I receive an error on the format='KML' line: File "C:\Users\name\anaconda3\envs\myenv\lib\site-packages\osgeo\gdal.py", line 855, in VectorTranslate return wrapper_GDALVectorTranslateDestName(destNameOrDestDS, srcDS, opts, callback, callback_data) File "C:\Users\name\anaconda3\envs\myenv\lib\site-packages\osgeo\gdal.py", line 4629, in wrapper_GDALVectorTranslateDestName return _gdal.wrapper_GDALVectorTranslateDestName(*args) TypeError: in method 'wrapper_GDALVectorTranslateDestName', argument 2 of type 'GDALDatasetShadow *'
    – a11
    Commented Jul 20, 2021 at 18:20
  • 1
    Works for me as is because I don't pass any pathlib.Paths to gdal. Make sure the paths are strings not pathlib.Paths. You can work with pathlib, just make sure every path is a string at the end when passing to gdal.
    – user2856
    Commented Jul 20, 2021 at 19:58
  • That was the problem, thanks for your help!
    – a11
    Commented Jul 20, 2021 at 20:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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