Python 子流程制定
Python subprocess formulation
我一直在试验 Python 的子进程模块。我想模拟以下成功的命令:
命令行:
ogr2ogr -f GeoJSON -clipsrc cutting.json output.json input.json
Python 实施:
import subprocess
subprocess.call(["ogr2ogr", "-f", "GeoJSON", "-clipsrc", "cutting.json", "output.json", "input.json"], shell=True)
然而,python 脚本输出:
FAILURE: no target datasource provided
从文档中,我可以看到语法是正确的,并且我以正确的顺序指定了源数据源和目标数据源。当然,因为它在命令行上工作,我倾向于认为数据方向是正确的。我是否错误地调用了子流程?
供参考,ogr2ogr
用法:
Usage: ogr2ogr [--help-general] [-skipfailures] [-append] [-update]
[-select field_list] [-where restricted_where]
[-progress] [-sql <sql statement>] [-dialect dialect]
[-preserve_fid] [-fid FID]
[-spat xmin ymin xmax ymax] [-geomfield field]
[-a_srs srs_def] [-t_srs srs_def] [-s_srs srs_def]
[-f format_name] [-overwrite] [[-dsco NAME=VALUE] ...]
dst_datasource_name src_datasource_name
[-lco NAME=VALUE] [-nln name] [-nlt type] [-dim 2|3|layer_dim] [layer [layer ...]]
Advanced options :
[-gt n]
[-clipsrc [xmin ymin xmax ymax]|WKT|datasource|spat_extent]
[-clipsrcsql sql_statement] [-clipsrclayer layer]
[-clipsrcwhere expression]
[-clipdst [xmin ymin xmax ymax]|WKT|datasource]
[-clipdstsql sql_statement] [-clipdstlayer layer]
[-clipdstwhere expression]
[-wrapdateline][-datelineoffset val]
[[-simplify tolerance] | [-segmentize max_dist]]
[-addfields]
[-relaxedFieldNameMatch]
[-fieldTypeToString All|(type1[,type2]*)] [-unsetFieldWidth]
[-fieldmap identity | index1[,index2]*]
[-splitlistfields] [-maxsubfields val]
[-explodecollections] [-zfield field_name]
[-gcp pixel line easting northing [elevation]]* [-order n | -tps]
我个人在基于 *nix 的机器上使用类似下面的东西来完全从 python 脚本调度调用。也许它对您有帮助(或者您可以根据自己的需要定制它)。
import os, subprocess, time
name = 'ogr2ogr_{}'.format(time.time())
call = ['nohup', 'ogr2ogr', '-f', 'GeoJSON', '-clipsrc',
'cutting.json', 'output.json', 'input.json']
o_std = open(os.path.join('/my/log/dir', '{}.log'.format(name)), 'w')
o_err = open(os.path.join('/my/log/dir', '{}.err'.format(name)), 'w')
r = subprocess.Popen(call, stdout=o_std, stderr=o_err, preexec_fn=os.setpgrp)
如果你不想分派子进程,只需删除nohup
列表项并且不要将os.setpgrp
设置为preexec_fn
。
我通常使用 subprocess 来调用命令行,因为 ogr2ogr
我有一些东西可以通过在调用中添加 shell=True
选项来工作:
ProcessToCall = ['ogr2ogr'+" "+str(OutShp)+" "+str(InShp)+" "+'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry FROM'+" "+str(InShp).split(".")[0]+'"']
subprocess.call(ProcessToCall, shell=True)
我一直在试验 Python 的子进程模块。我想模拟以下成功的命令:
命令行:
ogr2ogr -f GeoJSON -clipsrc cutting.json output.json input.json
Python 实施:
import subprocess
subprocess.call(["ogr2ogr", "-f", "GeoJSON", "-clipsrc", "cutting.json", "output.json", "input.json"], shell=True)
然而,python 脚本输出:
FAILURE: no target datasource provided
从文档中,我可以看到语法是正确的,并且我以正确的顺序指定了源数据源和目标数据源。当然,因为它在命令行上工作,我倾向于认为数据方向是正确的。我是否错误地调用了子流程?
供参考,ogr2ogr
用法:
Usage: ogr2ogr [--help-general] [-skipfailures] [-append] [-update]
[-select field_list] [-where restricted_where]
[-progress] [-sql <sql statement>] [-dialect dialect]
[-preserve_fid] [-fid FID]
[-spat xmin ymin xmax ymax] [-geomfield field]
[-a_srs srs_def] [-t_srs srs_def] [-s_srs srs_def]
[-f format_name] [-overwrite] [[-dsco NAME=VALUE] ...]
dst_datasource_name src_datasource_name
[-lco NAME=VALUE] [-nln name] [-nlt type] [-dim 2|3|layer_dim] [layer [layer ...]]
Advanced options :
[-gt n]
[-clipsrc [xmin ymin xmax ymax]|WKT|datasource|spat_extent]
[-clipsrcsql sql_statement] [-clipsrclayer layer]
[-clipsrcwhere expression]
[-clipdst [xmin ymin xmax ymax]|WKT|datasource]
[-clipdstsql sql_statement] [-clipdstlayer layer]
[-clipdstwhere expression]
[-wrapdateline][-datelineoffset val]
[[-simplify tolerance] | [-segmentize max_dist]]
[-addfields]
[-relaxedFieldNameMatch]
[-fieldTypeToString All|(type1[,type2]*)] [-unsetFieldWidth]
[-fieldmap identity | index1[,index2]*]
[-splitlistfields] [-maxsubfields val]
[-explodecollections] [-zfield field_name]
[-gcp pixel line easting northing [elevation]]* [-order n | -tps]
我个人在基于 *nix 的机器上使用类似下面的东西来完全从 python 脚本调度调用。也许它对您有帮助(或者您可以根据自己的需要定制它)。
import os, subprocess, time
name = 'ogr2ogr_{}'.format(time.time())
call = ['nohup', 'ogr2ogr', '-f', 'GeoJSON', '-clipsrc',
'cutting.json', 'output.json', 'input.json']
o_std = open(os.path.join('/my/log/dir', '{}.log'.format(name)), 'w')
o_err = open(os.path.join('/my/log/dir', '{}.err'.format(name)), 'w')
r = subprocess.Popen(call, stdout=o_std, stderr=o_err, preexec_fn=os.setpgrp)
如果你不想分派子进程,只需删除nohup
列表项并且不要将os.setpgrp
设置为preexec_fn
。
我通常使用 subprocess 来调用命令行,因为 ogr2ogr
我有一些东西可以通过在调用中添加 shell=True
选项来工作:
ProcessToCall = ['ogr2ogr'+" "+str(OutShp)+" "+str(InShp)+" "+'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry FROM'+" "+str(InShp).split(".")[0]+'"']
subprocess.call(ProcessToCall, shell=True)