GDAL:无法使用vsizip创建和编写zip文件

时间:2018-04-12 21:00:47

标签: zip gdal

我正在尝试使用GDAL库及其虚拟文件系统驱动程序vsizip编写一个GeoTIFF到zip文件。唉,它给了我一个错误:

ERROR 1: Random access not supported for writable file in /vsizip
ERROR 4: Attempt to create new tiff file `/vsizip/D:\Projects\oy_vey.zip\my.tif'
 failed: No such file or directory

我该如何应对?

P.S。这是我的代码:

#include "stdafx.h"
#include "MainWnd.h"
#include <QtWidgets/QApplication>

#include <gdal.h>
#include <gdal_priv.h>
#include <gdal_frmts.h>
#include <ogr_spatialref.h>

int main(int argc, char *argv[])
{
    //QApplication a(argc, argv);
    //MainWnd w;
    //w.show();
    //return a.exec();

    GDALRegister_GTiff();

    int numLatPx = 480;
    int numLonPx = 640;

    double northDeg = 3;
    double southDeg = 0;
    double westDeg = 0;
    double eastDeg = 4;


    double latStep = (northDeg - southDeg) / numLatPx;
    double lonStep = (eastDeg - westDeg) / numLonPx;


    GDALDriver* poDriver;
    char** papszMetadata;

    GDALDriverManager* driverManager = GetGDALDriverManager();
    poDriver = driverManager->GetDriverByName("GTiff");
    if (poDriver == NULL)
    {
        qDebug() << "GEOTIFF DRIVER NULL!!!";
        exit(1);
    }
    //it's okay so far...

    GDALDataset* poDstDS;

    double adfGeoTransform[6];
    adfGeoTransform[0] = westDeg; /* top left x */
    adfGeoTransform[1] = lonStep; /* w-e pixel resolution */
    adfGeoTransform[2] = 0; /* 0 */
    adfGeoTransform[3] = northDeg; /* top left y */
    adfGeoTransform[4] = 0; /* 0 */
    adfGeoTransform[5] = -latStep;/* n-s pixel resolution (negative value) */

    char** papszOptions = NULL;

    poDstDS = poDriver->Create("/vsizip/D:\\Projects\\oy_vey.zip\\my.tif", numLonPx, numLatPx, 1, GDT_Int16, papszOptions);
    // poDstDS will give NULL

    OGRSpatialReference oSRS;
    char *pszSRS_WKT = NULL;
    GDALRasterBand* poBand;

    poDstDS->SetGeoTransform(adfGeoTransform);
    //oSRS.importFromEPSG(4284); // PULKOVO 1942
    oSRS.exportToWkt(&pszSRS_WKT);

    poDstDS->SetProjection(pszSRS_WKT);
    CPLFree(pszSRS_WKT);
    poBand = poDstDS->GetRasterBand(1);

    GInt16* abyRaster = new GInt16[numLatPx * numLonPx];

    abyRaster[10000] = 0;
    abyRaster[10001] = 1;

    poBand->RasterIO(GF_Write, 0, 0, numLonPx, numLatPx, abyRaster, numLonPx, numLatPx, GDT_Int16, 0, 0);

    double minVal, maxVal, meanVal, stdDevVal;
    poBand->ComputeStatistics(false, &minVal, &maxVal, &meanVal, &stdDevVal, NULL, NULL);
    poBand->SetStatistics(minVal, maxVal, meanVal, stdDevVal);
    poBand->SetColorInterpretation(GCI_GrayIndex);


    /* Once we're done, close properly the dataset */
    GDALClose((GDALDatasetH)poDstDS);



    qDebug() << "^_^" << endl;
    return 0;
}

1 个答案:

答案 0 :(得分:1)

GTiff驱动程序Create()将尝试以读/写模式打开数据集,而vsizip虚拟文件系统不支持该模式。

作为解决方法,您可以执行以下操作:

  1. 创建临时TIFF文件
  2. 使用带有vsizip语法的CopyFiles方法
  3. 删除临时文件
  4. 以下是我更改代码的方式(我在Linux上我应该调整文件路径以在Windows上使用它。)

    int main(int argc, char *argv[])
    {
        //QApplication a(argc, argv);
        //MainWnd w;
        //w.show();
        //return a.exec();
    
        GDALAllRegister();
    
        int numLatPx = 480;
        int numLonPx = 640;
    
        double northDeg = 3;
        double southDeg = 0;
        double westDeg = 0;
        double eastDeg = 4;
    
    
        double latStep = (northDeg - southDeg) / numLatPx;
        double lonStep = (eastDeg - westDeg) / numLonPx;
    
    
        GDALDriver* poDriver;
        char** papszMetadata;
    
        GDALDriverManager* driverManager = GetGDALDriverManager();
        poDriver = driverManager->GetDriverByName("GTiff");
        if (poDriver == NULL)
        {
            qDebug() << "GEOTIFF DRIVER NULL!!!";
            exit(1);
        }
        //it's okay so far...
    
        GDALDataset* poDstDS;
    
        double adfGeoTransform[6];
        adfGeoTransform[0] = westDeg; /* top left x */
        adfGeoTransform[1] = lonStep; /* w-e pixel resolution */
        adfGeoTransform[2] = 0; /* 0 */
        adfGeoTransform[3] = northDeg; /* top left y */
        adfGeoTransform[4] = 0; /* 0 */
        adfGeoTransform[5] = -latStep;/* n-s pixel resolution (negative value) */
    
        char** papszOptions = NULL;
    
        poDstDS = poDriver->Create("/home/me/my.tif", numLonPx, numLatPx, 1, GDT_Int16, papszOptions);
        // poDstDS will give NULL
    
        OGRSpatialReference oSRS;
        char *pszSRS_WKT = NULL;
        GDALRasterBand* poBand;
    
        poDstDS->SetGeoTransform(adfGeoTransform);
        //oSRS.importFromEPSG(4284); // PULKOVO 1942
        oSRS.exportToWkt(&pszSRS_WKT);
    
        poDstDS->SetProjection(pszSRS_WKT);
        CPLFree(pszSRS_WKT);
        poBand = poDstDS->GetRasterBand(1);
    
        GInt16* abyRaster = new GInt16[numLatPx * numLonPx];
    
        abyRaster[10000] = 0;
        abyRaster[10001] = 1;
    
        poBand->RasterIO(GF_Write, 0, 0, numLonPx, numLatPx, abyRaster, numLonPx, numLatPx, GDT_Int16, 0, 0);
    
        double minVal, maxVal, meanVal, stdDevVal;
        poBand->ComputeStatistics(false, &minVal, &maxVal, &meanVal, &stdDevVal, NULL, NULL);
        poBand->SetStatistics(minVal, maxVal, meanVal, stdDevVal);
        poBand->SetColorInterpretation(GCI_GrayIndex);
    
    
        /* Once we're done, close properly the dataset */
       GDALClose((GDALDatasetH)poDstDS);
    
    
       poDriver->CopyFiles("/vsizip//home/me/test.zip/my.tif", "/home/me/my.tif");
    
    
        qDebug() << "^_^" << endl;
        return 0;
    }