在 Windows 上使用 QProcess 读取 GDAL /vsistdout/
Posted
技术标签:
【中文标题】在 Windows 上使用 QProcess 读取 GDAL /vsistdout/【英文标题】:reading GDAL /vsistdout/ with QProcess on Windows 【发布时间】:2019-12-03 14:03:46 【问题描述】:我使用 GDAL 的 ogr2ogr 来转换大数据文件。 og2ogr 是这样调用的:
ogr2ogr -options 输出文件输入文件。
还有一个特殊的输出通道 /vsistdout/ 将打印到控制台。
我使用 QProcess 来获取输出并让用户看到 GDAL 的进度并做我的更多工作,而不是等待进程结束。
void myProg::processOutput()
qDebug()<< "STD " << process.readAllStandardOutput();
void myProg::processError()
qDebug() << "ERR " << process.readAllStandardError();
connect (&process, SIGNAL(readyReadStandardOutput()), this, SLOT(processOutput()));
connect (&process, SIGNAL(readyReadStandardError()), this, SLOT(processError()));
process.start("C:/OSGeo4W64/bin/ogr2ogr",QProcess::Unbuffered | QProcess::ReadWrite);
// in a thread it will not freeze the GUI
process.waitForFinished();
使用上面的代码,og2ogr 没有参数,它运行良好,ogr2ogr 只是通过给出使用说明和丢失参数的失败通知来回答,并且所有内容都被插槽捕获。 但是我们可以在调试器窗口中看到,只有 ONE 输出到插槽。
缓冲输出问题?
现在,如果我们尝试使用 /vsistdout/ 进行真正的转换,例如:
process.start("C:/OSGeo4W64/bin/ogr2ogr -f PGDUMP --config PG_USE_COPY YES \"/vsistdout/\" -select code D:/geodata/myshape.shp",QProcess::Unbuffered | QProcess::ReadWrite);
// in a thread it will not freeze the GUI
process.waitForFinished();
但随后输出完全消失,就像在黑洞中一样,尽管它在 Windows 控制台中运行得非常好。
现在,如果我删除 de --config PG_USE_COPY YES,我会得到输出,但在完成所有工作后会进行一次大读取。这不是我需要的!
GDAL 真的是在 Windows 下写入 /vsistdout/ 还是仅在 Unix 下写入? 这是 QProcess 问题还是 GDAL 或 Windows?
我尝试了本网站和其他网站上的所有建议,但均未成功。 欢迎任何建议
PS:我在 Windows7 上使用 Qt 4.8
【问题讨论】:
【参考方案1】:经过更多尝试和搜索,我终于找到了可行的解决方法。
Ogr2ogr 有一个开关 -progress 在写入文件时将线索写入标准输出。 0...10...20...30...40...50...60...70...80...90...100 - 完成。
所以我把起始代码改成写入文件:
process.start("C:/OSGeo4W64/bin/ogr2ogr -progress -f PGDUMP --config PG_USE_COPY YES \"dump.sql\" -select code bigshape.shp",QProcess::Unbuffered | QProcess::ReadOnly);
这次我得到了GDAL的进度输出
STD "0...10"
STD ".."
STD ".20"
STD "."
STD ".."
STD "30."
现在我可以让用户看到进度并捕获最终取消信号以中止 GDAL。
我无法实时处理输出,但总比没有好。
关于 -progress ,GDAL 文档说:仅当输入层具有“快速特征计数”功能时才有效。
天知道谁有这种能力!
【讨论】:
以上是关于在 Windows 上使用 QProcess 读取 GDAL /vsistdout/的主要内容,如果未能解决你的问题,请参考以下文章
Qt学习之路(58): 进程间交互(QProcess.readAllStandardOutput可以读取控制台的输出)
如何在 Windows 上通过 QProcess 启动提升的子进程?
调用一个系统命令,并读取它的输出值(使用QProcess.readAll)