2013-04-08 62 views
0

我正在嘗試編寫一個Python函數,它將給定的座標系轉換爲使用gdal的另一個座標系。問題是我試圖以一個字符串執行該命令,但在shell中,我必須在輸入座標之前按Enter鍵。使用Python命令的多行shell命令模塊

x = 1815421 
y = 557301 

ret = [] 

tmp = commands.getoutput('gdaltransform -s_srs \'+proj=lcc +lat_1=34.03333333333333 
+lat_2=35.46666666666667 +lat_0=33.5 +lon_0=-118 +x_0=2000000 +y_0=500000 +ellps=GRS80 
+units=m +no_defs\' -t_srs epsg:4326 \n' + str(x) + ' ' + str(y)) 

我試過用'\ n',但那不起作用。

+0

是否有任何理由不在Python中調用osr.CoordinateTransformation()? – 2013-04-09 06:30:44

回答

3

我的猜測是,你按Enter鍵運行gdaltransform和座標由從標準輸入程序本身讀,而不是外殼:

from subprocess import Popen, PIPE 

p = Popen(['gdaltransform', '-s_srs', ('+proj=lcc ' 
    '+lat_1=34.03333333333333 ' 
    '+lat_2=35.46666666666667 ' 
    '+lat_0=33.5 ' 
    '+lon_0=-118 +x_0=2000000 +y_0=500000 +ellps=GRS80 ' 
    '+units=m +no_defs'), '-t_srs', 'epsg:4326'], 
    stdin=PIPE, stdout=PIPE, universal_newlines=True) # run the program 
output = p.communicate("%s %s\n" % (x, y))[0] # pass coordinates 
1
from subprocess import * 

c = 'command 1 && command 2 && command 3' 
# for instance: c = 'dir && cd C:\\ && dir' 

handle = Popen(c, stdin=PIPE, stderr=PIPE, stdout=PIPE, shell=True) 
print handle.stdout.read() 
handle.flush() 

如果我沒有記錯,該命令將被執行在「會話」,從而讓你需要在命令之間任何niformation。

更準確地說,使用shell=True(從我所得到的)是如果給定一串命令而不是一個列表,它應該被使用。如果你想使用一個列表的建議是做如下:

import shlex 
c = shlex.split("program -w ith -a 'quoted argument'") 

handle = Popen(c, stdout=PIPE, stderr=PIPE, stdin=PIPE) 
print handle.stdout.read() 

再搭上輸出,或者你可以用一個開放的工作流和使用handle.stdin.write()但它是一個有點棘手。

除非你只想要執行,讀而不死,.communicate()是完美的,或者只是.check_output(<cmd>)

好信息n如何Popen作品都可以在這裏找到(本書雖然是不同的主題):python subprocess stdin.write a string error 22 invalid argument




解決方案

無論如何,這應該工作(你必須重定向STDIN和STDOUT):

from subprocess import * 

c = 'gdaltransform -s_srs \'+proj=lcc +lat_1=34.03333333333333 +lat_2=35.46666666666667 +lat_0=33.5 +lon_0=-118 +x_0=2000000 +y_0=500000 +ellps=GRS80 +units=m +no_defs\' -t_srs epsg:4326 \n' + str(x) + ' ' + str(y) + '\n' 

handle = Popen(c, stdin=PIPE, stderr=PIPE, stdout=PIPE, shell=True) 
print handle.stdout.read() 
handle.flush()