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.

Taras
  • 32,823
  • 4
  • 66
  • 137
a11
  • 940
  • 10
  • 22

1 Answers1

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
swiss_knight
  • 10,309
  • 9
  • 45
  • 117
user2856
  • 65,736
  • 6
  • 115
  • 196
  • 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 Jul 20 '21 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 Jul 20 '21 at 19:58
  • That was the problem, thanks for your help! – a11 Jul 20 '21 at 20:04