Esempio n. 1
0
 void Feature::set (const char *name, double val) {
     OGR_F_SetFieldDouble(feat, index(name), val);
 }
Esempio n. 2
0
int OGRCCreate(const char *pszFname)
{
    OGRSFDriverH    driver;
    int             i, numDrivers;
    OGRDataSourceH  datasource;
    OGRLayerH       layer;
    OGRFeatureDefnH layerDefn;
    OGRFieldDefnH   fieldDefn;
    OGRFeatureH     feature;
    OGRGeometryH    geometry, ring;

    /* Register all OGR drivers */
    OGRRegisterAll();

    /* Fetch MITAB driver - we want to create a TAB file */
    numDrivers = OGRGetDriverCount();
    for(i=0; i<numDrivers; i++)
    {
        driver = OGRGetDriver(i);
        if (EQUAL("MapInfo File", OGR_Dr_GetName(driver)))
            break;  /* Found it! */
        driver = NULL;
    }

    if (!driver)
    {
        printf("Driver not found!\n");
        return -1;
    }

    /* Create new file using this driver */
    datasource = OGR_Dr_CreateDataSource(driver, pszFname, NULL);

    if (datasource == NULL)
    {
        printf("Unable to create %s\n", pszFname);
        return -1;
    }

    /* MapInfo data sources are created with one empty layer.
       Fetch the layer handle */
    layer = OGR_DS_GetLayer(datasource, 0);

    if (layer == NULL)
    {
        printf("Unable to create new layer in %s\n", pszFname);
        return -1;
    }

    /* Add a few fields to the layer defn */
    fieldDefn = OGR_Fld_Create( "id", OFTInteger );
    OGR_L_CreateField(layer, fieldDefn, 0);

    fieldDefn = OGR_Fld_Create( "area", OFTReal );
    OGR_L_CreateField(layer, fieldDefn, 0);

    fieldDefn = OGR_Fld_Create( "name", OFTString );
    OGR_L_CreateField(layer, fieldDefn, 0);

    /* We'll need the layerDefn handle to create new features in this layer */
    layerDefn = OGR_L_GetLayerDefn( layer );

    /* Create a new point */
    feature = OGR_F_Create( layerDefn );
    OGR_F_SetFieldInteger( feature, 0, 1);
    OGR_F_SetFieldDouble( feature, 1, 123.45);
    OGR_F_SetFieldString( feature, 2, "Feature #1");

    geometry = OGR_G_CreateGeometry( wkbPoint );
    OGR_G_SetPoint(geometry, 0, 123.45, 456.78, 0);

    OGR_F_SetGeometryDirectly(feature, geometry);

    OGR_L_CreateFeature( layer, feature );

    /* Create a new line */
    feature = OGR_F_Create( layerDefn );
    OGR_F_SetFieldInteger( feature, 0, 2);
    OGR_F_SetFieldDouble( feature, 1, 42.45);
    OGR_F_SetFieldString( feature, 2, "Feature #2");

    geometry = OGR_G_CreateGeometry( wkbLineString );
    OGR_G_AddPoint(geometry, 123.45, 456.78, 0);
    OGR_G_AddPoint(geometry, 12.34,  45.67, 0);

    OGR_F_SetGeometryDirectly(feature, geometry);
 
    OGR_L_CreateFeature( layer, feature );

    /* Create a new polygon (square) */
    feature = OGR_F_Create( layerDefn );
    OGR_F_SetFieldInteger( feature, 0, 3);
    OGR_F_SetFieldDouble( feature, 1, 49.71);
    OGR_F_SetFieldString( feature, 2, "Feature #3");

    geometry = OGR_G_CreateGeometry( wkbPolygon );
    ring = OGR_G_CreateGeometry( wkbLinearRing );
    OGR_G_AddPoint(ring, 123.45, 456.78, 0);
    OGR_G_AddPoint(ring, 12.34,  456.78, 0);
    OGR_G_AddPoint(ring, 12.34,  45.67, 0);
    OGR_G_AddPoint(ring, 123.45, 45.67, 0);
    OGR_G_AddPoint(ring, 123.45, 456.78, 0);
    OGR_G_AddGeometryDirectly(geometry, ring);

    OGR_F_SetGeometryDirectly(feature, geometry);
 
    OGR_L_CreateFeature( layer, feature );

    /* Close data source */
    OGR_DS_Destroy( datasource );

    return 0;
}
Esempio n. 3
0
static CPLErr
EmitPolygonToLayer( OGRLayerH hOutLayer, int iPixValField,
                    RPolygonF *poRPoly, double *padfGeoTransform )

{
    OGRFeatureH hFeat;
    OGRGeometryH hPolygon;

/* -------------------------------------------------------------------- */
/*      Turn bits of lines into coherent rings.                         */
/* -------------------------------------------------------------------- */
    poRPoly->Coalesce();

/* -------------------------------------------------------------------- */
/*      Create the polygon geometry.                                    */
/* -------------------------------------------------------------------- */
    size_t iString;

    hPolygon = OGR_G_CreateGeometry( wkbPolygon );
    
    for( iString = 0; iString < poRPoly->aanXY.size(); iString++ )
    {
        std::vector<int> &anString = poRPoly->aanXY[iString];
        OGRGeometryH hRing = OGR_G_CreateGeometry( wkbLinearRing );

        int iVert;

        // we go last to first to ensure the linestring is allocated to 
        // the proper size on the first try.
        for( iVert = anString.size()/2 - 1; iVert >= 0; iVert-- )
        {
            double dfX, dfY;
            int    nPixelX, nPixelY;
            
            nPixelX = anString[iVert*2];
            nPixelY = anString[iVert*2+1];

            dfX = padfGeoTransform[0] 
                + nPixelX * padfGeoTransform[1]
                + nPixelY * padfGeoTransform[2];
            dfY = padfGeoTransform[3] 
                + nPixelX * padfGeoTransform[4]
                + nPixelY * padfGeoTransform[5];

            OGR_G_SetPoint_2D( hRing, iVert, dfX, dfY );
        }

        OGR_G_AddGeometryDirectly( hPolygon, hRing );
    }
    
/* -------------------------------------------------------------------- */
/*      Create the feature object.                                      */
/* -------------------------------------------------------------------- */
    hFeat = OGR_F_Create( OGR_L_GetLayerDefn( hOutLayer ) );

    OGR_F_SetGeometryDirectly( hFeat, hPolygon );

    if( iPixValField >= 0 )
        OGR_F_SetFieldDouble( hFeat, iPixValField, (double)poRPoly->fPolyValue );

/* -------------------------------------------------------------------- */
/*      Write the to the layer.                                         */
/* -------------------------------------------------------------------- */
    CPLErr eErr = CE_None;

    if( OGR_L_CreateFeature( hOutLayer, hFeat ) != OGRERR_NONE )
        eErr = CE_Failure;

    OGR_F_Destroy( hFeat );

    return eErr;
}
GDALDataset *
RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
                       int bStrict, char ** papszOptions, 
                       GDALProgressFunc pfnProgress, void * pProgressData )
{
    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0");
        return NULL;
    }
    
    const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
    GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
    if ( hTileDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
        return NULL;
    }
    
    GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
    if (hMemDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
        return NULL;
    }   

    int nXSize = GDALGetRasterXSize(poSrcDS);
    int nYSize = GDALGetRasterYSize(poSrcDS);
    
    double adfGeoTransform[6];
    if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None)
    {
        adfGeoTransform[0] = 0;
        adfGeoTransform[1] = 1;
        adfGeoTransform[2] = 0;
        adfGeoTransform[3] = 0;
        adfGeoTransform[4] = 0;
        adfGeoTransform[5] = -1;
    }
    else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms");
        return NULL;
    }

    int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES"));
    int nBlockXSize, nBlockYSize;
    if (bTiled)
    {
        nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));
        nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));
        if (nBlockXSize < 64) nBlockXSize = 64;
        else if (nBlockXSize > 4096)  nBlockXSize = 4096;
        if (nBlockYSize < 64) nBlockYSize = 64;
        else if (nBlockYSize > 4096)  nBlockYSize = 4096;
    }
    else
    {
        nBlockXSize = nXSize;
        nBlockYSize = nYSize;
    }
    
/* -------------------------------------------------------------------- */
/*      Analyze arguments                                               */
/* -------------------------------------------------------------------- */
    
    CPLString osDBName;
    CPLString osTableName;
    VSIStatBuf sBuf;
    int bExists;

    /* Skip optionnal RASTERLITE: prefix */
    const char* pszFilenameWithoutPrefix = pszFilename;
    if (EQUALN(pszFilename, "RASTERLITE:", 11))
        pszFilenameWithoutPrefix += 11;
    
    char** papszTokens = CSLTokenizeStringComplex( 
                pszFilenameWithoutPrefix, ", ", FALSE, FALSE );
    int nTokens = CSLCount(papszTokens);
    if (nTokens == 0)
    {
        osDBName = pszFilenameWithoutPrefix;
        osTableName = CPLGetBasename(pszFilenameWithoutPrefix);
    }
    else
    {
        osDBName = papszTokens[0];
        
        int i;
        for(i=1;i<nTokens;i++)
        {
            if (EQUALN(papszTokens[i], "table=", 6))
                osTableName = papszTokens[i] + 6;
            else
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "Invalid option : %s", papszTokens[i]);
            }
        }
    }
    
    CSLDestroy(papszTokens);
    papszTokens = NULL;
    
    bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0);

    if (osTableName.size() == 0)
    {
        if (bExists)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Database already exists. Explicit table name must be specified");
            return NULL;
        }
        osTableName = CPLGetBasename(osDBName.c_str());
    }    
    
    CPLString osRasterLayer;
    osRasterLayer.Printf("%s_rasters", osTableName.c_str());
    
    CPLString osMetatadataLayer;
    osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());

/* -------------------------------------------------------------------- */
/*      Create or open the SQLite DB                                    */
/* -------------------------------------------------------------------- */
    
    if (OGRGetDriverCount() == 0)
        OGRRegisterAll();
        
    OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite");
    if (hSQLiteDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver");
        return NULL;
    }   
    
    OGRDataSourceH hDS;
    
    CPLString osOldVal =
        CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
    CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
    if (!bExists)
    {
        char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES");
        hDS = OGR_Dr_CreateDataSource(hSQLiteDriver,
                                      osDBName.c_str(), papszOGROptions);
        CSLDestroy(papszOGROptions);
    }
    else
    {
        hDS = OGROpen(osDBName.c_str(), TRUE, NULL);
    }
    CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
    
    if (hDS == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Cannot load or create SQLite database");
        return NULL;
    }

    CPLString osSQL;
    
/* -------------------------------------------------------------------- */
/*      Get the SRID for the SRS                                        */
/* -------------------------------------------------------------------- */
    int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef());

/* -------------------------------------------------------------------- */
/*      Create or wipe existing tables                                  */
/* -------------------------------------------------------------------- */
    int bWipeExistingData =
        CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO"));
        
    hDS = RasterliteCreateTables(hDS, osTableName.c_str(),
                                 nSRSId, bWipeExistingData);
    if (hDS == NULL)
        return NULL;

    OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
    OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
    if (hRasterLayer == NULL || hMetadataLayer == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Cannot find metadata and/or raster tables");
        OGRReleaseDataSource(hDS);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Check if there is overlapping data and warn the user            */
/* -------------------------------------------------------------------- */
    double minx = adfGeoTransform[0];
    double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1];
    double maxy = adfGeoTransform[3];
    double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5];
    
    osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" "
                 "WHERE rowid IN "
                 "(SELECT pkid FROM \"idx_%s_metadata_geometry\" "
                  "WHERE xmin < %.15f AND xmax > %.15f "
                  "AND ymin < %.15f  AND ymax > %.15f) "
                 "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
                 "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
                  osMetatadataLayer.c_str(),
                  osTableName.c_str(),
                  maxx, minx, maxy, miny,
                  adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15,
                  - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15);
    
    int nOverlappingGeoms = 0;
    OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    if (hCountLyr)
    {
        OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr);
        if (hFeat)
        {
            nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0);
            OGR_F_Destroy(hFeat);
        }
        OGR_DS_ReleaseResultSet(hDS, hCountLyr);
    }
    
    if (nOverlappingGeoms != 0)
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Raster tiles already exist in the %s table within "
                 "the extent of the data to be inserted in",
                 osTableName.c_str());
    }
   
/* -------------------------------------------------------------------- */
/*      Iterate over blocks to add data into raster and metadata tables */
/* -------------------------------------------------------------------- */
    int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize;
    int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize;

    GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
    GByte* pabyMEMDSBuffer =
        (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
    if (pabyMEMDSBuffer == NULL)
    {
        OGRReleaseDataSource(hDS);
        return NULL;
    }
    
    CPLString osTempFileName;
    osTempFileName.Printf("/vsimem/%p", hDS);
    
    int nTileId = 0;
    int nBlocks = 0;
    int nTotalBlocks = nXBlocks * nYBlocks;

    char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions);
    
    OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
    
    CPLErr eErr = CE_None;
    int nBlockXOff, nBlockYOff;
    for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
    {
        for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
        {
/* -------------------------------------------------------------------- */
/*      Create in-memory tile                                           */
/* -------------------------------------------------------------------- */
            int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
            if ((nBlockXOff+1) * nBlockXSize > nXSize)
                nReqXSize = nXSize - nBlockXOff * nBlockXSize;
            if ((nBlockYOff+1) * nBlockYSize > nYSize)
                nReqYSize = nYSize - nBlockYOff * nBlockYSize;

            eErr = poSrcDS->RasterIO(GF_Read,
                                     nBlockXOff * nBlockXSize,
                                     nBlockYOff * nBlockYSize,
                                     nReqXSize, nReqYSize,
                                     pabyMEMDSBuffer, nReqXSize, nReqYSize,
                                     eDataType, nBands, NULL,
                                     0, 0, 0);
            if (eErr != CE_None)
            {
                break;
            }
            
            GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
                                              nReqXSize, nReqYSize, 0, 
                                              eDataType, NULL);
            if (hMemDS == NULL)
            {
                eErr = CE_Failure;
                break;
            }
            
            int iBand;
            for(iBand = 0; iBand < nBands; iBand ++)
            {
                char** papszMEMDSOptions = NULL;
                char szTmp[64];
                memset(szTmp, 0, sizeof(szTmp));
                CPLPrintPointer(szTmp,
                                pabyMEMDSBuffer + iBand * nDataTypeSize *
                                nReqXSize * nReqYSize, sizeof(szTmp));
                papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp);
                GDALAddBand(hMemDS, eDataType, papszMEMDSOptions);
                CSLDestroy(papszMEMDSOptions);
            }
            
            GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
                                        osTempFileName.c_str(), hMemDS, FALSE,
                                        papszTileDriverOptions, NULL, NULL);

            GDALClose(hMemDS);
            if (hOutDS)
                GDALClose(hOutDS);
            else
            {
                eErr = CE_Failure;
                break;
            }

/* -------------------------------------------------------------------- */
/*      Insert new entry into raster table                              */
/* -------------------------------------------------------------------- */

            vsi_l_offset nDataLength;
            GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
                                                   &nDataLength, FALSE);

            OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
            OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
            
            OGR_L_CreateFeature(hRasterLayer, hFeat);
            /* Query raster ID to set it as the ID of the associated metadata */
            int nRasterID = (int)OGR_F_GetFID(hFeat);
            
            OGR_F_Destroy(hFeat);
            
            VSIUnlink(osTempFileName.c_str());
            
/* -------------------------------------------------------------------- */
/*      Insert new entry into metadata table                            */
/* -------------------------------------------------------------------- */
            
            hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
            OGR_F_SetFID(hFeat, nRasterID);
            OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS));
            OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
            OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
            OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
            OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]);
            OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]);
            
            minx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff) * adfGeoTransform[1];
            maxx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1];
            maxy = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff) * adfGeoTransform[5];
            miny = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5];
            
            OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
            OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
            
            OGR_F_SetGeometryDirectly(hFeat, hRectangle);
            
            OGR_L_CreateFeature(hMetadataLayer, hFeat);
            OGR_F_Destroy(hFeat);
            
            nBlocks++;
            if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
                                            NULL, pProgressData))
                eErr = CE_Failure;
        }
    }
    
    if (eErr == CE_None)
        OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
    else
        OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
    
    CSLDestroy(papszTileDriverOptions);
    
    VSIFree(pabyMEMDSBuffer);
    
    OGRReleaseDataSource(hDS);
        
    return (GDALDataset*) GDALOpen(pszFilename, GA_Update);
}
CPLErr RasterliteDataset::CreateOverviewLevel(int nOvrFactor,
                                              GDALProgressFunc pfnProgress,
                                              void * pProgressData)
{

    double dfXResolution = padfXResolutions[0] * nOvrFactor;
    double dfYResolution = padfXResolutions[0] * nOvrFactor;
    
    CPLString osSQL;

    int nBlockXSize = 256;
    int nBlockYSize = 256;
    int nOvrXSize = nRasterXSize / nOvrFactor;
    int nOvrYSize = nRasterYSize / nOvrFactor;
    
    if (nOvrXSize == 0 || nOvrYSize == 0)
        return CE_Failure;
    
    int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize;
    int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize;
    
    const char* pszDriverName = "GTiff";
    GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
    if (hTileDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
        return CE_Failure;
    }
    
    GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
    if (hMemDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
        return CE_Failure;
    }   

    GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType();
    int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
    GByte* pabyMEMDSBuffer =
        (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
    if (pabyMEMDSBuffer == NULL)
    {
        return CE_Failure;
    }
    
    char** papszTileDriverOptions = NULL;
    
    CPLString osTempFileName;
    osTempFileName.Printf("/vsimem/%p", hDS);
    
    int nTileId = 0;
    int nBlocks = 0;
    int nTotalBlocks = nXBlocks * nYBlocks;
    
    CPLString osRasterLayer;
    osRasterLayer.Printf("%s_rasters", osTableName.c_str());
    
    CPLString osMetatadataLayer;
    osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());
    
    OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
    OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
    
    CPLString osSourceName = "unknown";
    
    osSQL.Printf("SELECT source_name FROM \"%s\" WHERE "
                 "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
                 "pixel_y_size >= %.15f AND pixel_y_size <= %.15f LIMIT 1",
                 osMetatadataLayer.c_str(),
                 padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
                 padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
    OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    if (hSQLLyr)
    {
        OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
        if (hFeat)
        {
            const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0);
            if (pszVal)
                osSourceName = pszVal;
            OGR_F_Destroy(hFeat);
        }
        OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
    }
    
/* -------------------------------------------------------------------- */
/*      Compute up to which existing overview level we can use for      */
/*      computing the requested overview                                */
/* -------------------------------------------------------------------- */
    int iLev;
    nLimitOvrCount = 0;
    for(iLev=1;iLev<nResolutions;iLev++)
    {
        if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 &&
              padfYResolutions[iLev] < dfYResolution - 1e-10))
        {
            break;
        }
        nLimitOvrCount++;
    }
    
/* -------------------------------------------------------------------- */
/*      Iterate over blocks to add data into raster and metadata tables */
/* -------------------------------------------------------------------- */

    OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
    
    CPLErr eErr = CE_None;
    int nBlockXOff, nBlockYOff;
    for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
    {
        for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
        {
/* -------------------------------------------------------------------- */
/*      Create in-memory tile                                           */
/* -------------------------------------------------------------------- */
            int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
            if ((nBlockXOff+1) * nBlockXSize > nOvrXSize)
                nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize;
            if ((nBlockYOff+1) * nBlockYSize > nOvrYSize)
                nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize;
            
            eErr = RasterIO(GF_Read,
                            nBlockXOff * nBlockXSize * nOvrFactor,
                            nBlockYOff * nBlockYSize * nOvrFactor,
                            nReqXSize * nOvrFactor, nReqYSize * nOvrFactor,
                            pabyMEMDSBuffer, nReqXSize, nReqYSize,
                            eDataType, nBands, NULL,
                            0, 0, 0);
            if (eErr != CE_None)
            {
                break;
            }
            
            GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
                                              nReqXSize, nReqYSize, 0, 
                                              eDataType, NULL);
            if (hMemDS == NULL)
            {
                eErr = CE_Failure;
                break;
            }
            
            int iBand;
            for(iBand = 0; iBand < nBands; iBand ++)
            {
                char** papszOptions = NULL;
                char szTmp[64];
                memset(szTmp, 0, sizeof(szTmp));
                CPLPrintPointer(szTmp,
                                pabyMEMDSBuffer + iBand * nDataTypeSize *
                                nReqXSize * nReqYSize, sizeof(szTmp));
                papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
                GDALAddBand(hMemDS, eDataType, papszOptions);
                CSLDestroy(papszOptions);
            }
            
            GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
                                        osTempFileName.c_str(), hMemDS, FALSE,
                                        papszTileDriverOptions, NULL, NULL);

            GDALClose(hMemDS);
            if (hOutDS)
                GDALClose(hOutDS);
            else
            {
                eErr = CE_Failure;
                break;
            }

/* -------------------------------------------------------------------- */
/*      Insert new entry into raster table                              */
/* -------------------------------------------------------------------- */

            vsi_l_offset nDataLength;
            GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
                                                   &nDataLength, FALSE);

            OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
            OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
            
            OGR_L_CreateFeature(hRasterLayer, hFeat);
            /* Query raster ID to set it as the ID of the associated metadata */
            int nRasterID = (int)OGR_F_GetFID(hFeat);
            
            OGR_F_Destroy(hFeat);
            
            VSIUnlink(osTempFileName.c_str());
            
/* -------------------------------------------------------------------- */
/*      Insert new entry into metadata table                            */
/* -------------------------------------------------------------------- */
            
            hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
            OGR_F_SetFID(hFeat, nRasterID);
            OGR_F_SetFieldString(hFeat, 0, osSourceName);
            OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
            OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
            OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
            OGR_F_SetFieldDouble(hFeat, 4, dfXResolution);
            OGR_F_SetFieldDouble(hFeat, 5, dfYResolution);
            
            double minx, maxx, maxy, miny;
            minx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff) * dfXResolution;
            maxx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution;
            maxy = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff) * (-dfYResolution);
            miny = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution);
            
            OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
            OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
            
            OGR_F_SetGeometryDirectly(hFeat, hRectangle);
            
            OGR_L_CreateFeature(hMetadataLayer, hFeat);
            OGR_F_Destroy(hFeat);
            
            nBlocks++;
            if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
                                            NULL, pProgressData))
                eErr = CE_Failure;
        }
    }
    
    nLimitOvrCount = -1;
    
    if (eErr == CE_None)
        OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
    else
        OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
    
    VSIFree(pabyMEMDSBuffer);
    
/* -------------------------------------------------------------------- */
/*      Update raster_pyramids table                                    */
/* -------------------------------------------------------------------- */
    if (eErr == CE_None)
    {
        OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
        if (hRasterPyramidsLyr == NULL)
        {
            osSQL.Printf   ("CREATE TABLE raster_pyramids ("
                            "table_prefix TEXT NOT NULL,"
                            "pixel_x_size DOUBLE NOT NULL,"
                            "pixel_y_size DOUBLE NOT NULL,"
                            "tile_count INTEGER NOT NULL)");
            OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
            
            /* Re-open the DB to take into account the new tables*/
            OGRReleaseDataSource(hDS);
            
            CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
            CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
            hDS = OGROpen(osFileName.c_str(), TRUE, NULL);
            CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
        }

        /* Insert base resolution into raster_pyramids if not already done */
        int bHasBaseResolution = FALSE;
        osSQL.Printf("SELECT * FROM raster_pyramids WHERE "
                     "table_prefix = '%s' AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
                     "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
                     osTableName.c_str(),
                     padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
                     padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
        hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
        if (hSQLLyr)
        {
            OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
            if (hFeat)
            {
                bHasBaseResolution = TRUE;
                OGR_F_Destroy(hFeat);
            }
            OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
        }

        if (!bHasBaseResolution)
        {
            osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE "
                          "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
                          "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
                          osMetatadataLayer.c_str(),
                          padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
                          padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);

            int nBlocksMainRes = 0;

            hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
            if (hSQLLyr)
            {
                OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
                if (hFeat)
                {
                    nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0);
                    OGR_F_Destroy(hFeat);
                }
                OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
            }

            osSQL.Printf("INSERT INTO raster_pyramids "
                         "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) "
                         "VALUES ( '%s', %.18f, %.18f, %d )",
                         osTableName.c_str(), padfXResolutions[0], padfYResolutions[0],
                         nBlocksMainRes);
            OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
        }

        osSQL.Printf("INSERT INTO raster_pyramids "
                     "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) "
                     "VALUES ( '%s', %.18f, %.18f, %d )",
                     osTableName.c_str(), dfXResolution, dfYResolution,
                     nTotalBlocks);
        OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    }

    return eErr;
}
Esempio n. 6
0
int main(int argc, char* argv[])
{
    int rc = 0;

#ifdef HAVE_GDAL
    try
    {
        ::OGRRegisterAll();

        // Parse command-line options
        std::string in_file;
        std::string out_file;
        std::string out_frmt;
        {
            int on_arg = 1;
            while (on_arg < argc)
            {
                std::string arg(argv[on_arg]);
                if (arg == "-h")
                {
                    usage();
                    return 0;
                }
                else if (arg == "-formats")
                {
                    report_ogr_formats(std::cout);
                    return 0;
                }
                else if (arg == "-i" && (on_arg + 1 < argc))
                {
                    ++on_arg;
                    assert(on_arg < argc);
                    in_file = argv[on_arg];
                }
                else if (arg == "-o" && (on_arg + 1 < argc))
                {
                    ++on_arg;
                    assert(on_arg < argc);
                    out_file = argv[on_arg];
                    out_frmt = "ESRI Shapefile"; // default output format
                }
                else if (arg == "-f" && (on_arg + 1 < argc))
                {
                    ++on_arg;
                    assert(on_arg < argc);
                    out_frmt = argv[on_arg];
                }
                else
                {
                    throw std::runtime_error(std::string("unrecognized parameter: ") + arg);
                }
                ++on_arg;
            }

            if (in_file.empty() || out_file.empty() || out_frmt.empty())
            {
                throw std::runtime_error("missing input paremeters");
            }
        }

        //
        // Source
        //
        std::cout << "Source:" << "\n - dataset: " << in_file << std::endl;

        std::ifstream ifs;
        if (!liblas::Open(ifs, in_file.c_str()))
        {
            throw std::runtime_error(std::string("Can not open \'") + in_file + "\'");
        }
        liblas::Reader reader(ifs);

        //
        // Target
        //
        std::string const lyrname(out_file.substr(0, out_file.find_last_of('.')));

        std::cout << "Target:"
                  << "\n - format: " << out_frmt
                  << "\n - dataset: " << out_file
                  << "\n - layer: " << lyrname
                  << std::endl;

        OGRSFDriverH drv = OGRGetDriverByName(out_frmt.c_str());
        if (0 == drv)
        {
            throw std::runtime_error(out_frmt + " driver not available");
        }

        ogr_wrapper<OGRDataSourceH> ds(OGR_Dr_CreateDataSource(drv, out_file.c_str(), 0), OGR_DS_Destroy);
        if (0 == ds.get())
        {
            throw std::runtime_error(out_file + " datasource creation failed");
        }

        OGRLayerH lyr = OGR_DS_CreateLayer(ds, lyrname.c_str(), 0, wkbPoint25D, 0);
        if (0 == lyr)
        {
            throw std::runtime_error(out_file + " layer creation failed");
        }

        // Prepare layer schema
        create_layer_def(lyr);

        //
        // Translation of points cloud to features set
        //
        boost::uint32_t i = 0;
        boost::uint32_t const size = reader.GetHeader().GetPointRecordsCount();

        std::cout << "Translating " << size << " points:\n";

        ogr_wrapper<OGRFeatureH> feat(OGR_F_Create(OGR_L_GetLayerDefn(lyr)), OGR_F_Destroy);

        while (reader.ReadNextPoint())
        {
            liblas::Point const& p = reader.GetPoint();

            OGR_F_SetFieldInteger(feat, 0, p.GetReturnNumber());
            OGR_F_SetFieldInteger(feat, 1, p.GetScanAngleRank());
            OGR_F_SetFieldInteger(feat, 2, p.GetIntensity());

            std::ostringstream os;
            os << p.GetClassification();
            OGR_F_SetFieldString(feat, 3, os.str().c_str());

            OGR_F_SetFieldInteger(feat, 4, p.GetNumberOfReturns());
            OGR_F_SetFieldDouble(feat, 5, p.GetTime());

            ogr_wrapper<OGRGeometryH> geom(OGR_G_CreateGeometry(wkbPoint25D), OGR_G_DestroyGeometry);
            OGR_G_SetPoint(geom, 0, p.GetX(), p.GetY(), p.GetZ());
            if (OGRERR_NONE != OGR_F_SetGeometry(feat, geom))
            {
                throw std::runtime_error("geometry creation failed");
            }

            if (OGRERR_NONE != OGR_L_CreateFeature(lyr, feat))
            {
                throw std::runtime_error("feature creation failed");
            }

            term_progress(std::cout, (i + 1) / static_cast<double>(size));
            i++;
        }

        std::cout << std::endl;
    }
    catch (std::exception const& e)
    {
        std::cerr << "Error: " << e.what() << std::endl;
        rc = -1;
    }
    catch (...)
    {
        std::cerr << "Unknown error\n";
        rc = -1;
    }
#else
    std::cout << "Missing GDAL/OGR support built-in las2ogr. Aborted." << std::endl;
#endif // #ifdef HAVE_GDAL

    ::OGRCleanupAll();
    return rc;
}
CPLErr RasterliteDataset::CreateOverviewLevel(const char * pszResampling,
                                              int nOvrFactor,
                                              char** papszOptions,
                                              GDALProgressFunc pfnProgress,
                                              void * pProgressData)
{

    double dfXResolution = padfXResolutions[0] * nOvrFactor;
    double dfYResolution = padfXResolutions[0] * nOvrFactor;
    
    CPLString osSQL;

    int nOvrXSize = nRasterXSize / nOvrFactor;
    int nOvrYSize = nRasterYSize / nOvrFactor;
    
    if (nOvrXSize == 0 || nOvrYSize == 0)
        return CE_Failure;

    int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES"));
    int nBlockXSize, nBlockYSize;
    if (bTiled)
    {
        nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));
        nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));
        if (nBlockXSize < 64) nBlockXSize = 64;
        else if (nBlockXSize > 4096)  nBlockXSize = 4096;
        if (nBlockYSize < 64) nBlockYSize = 64;
        else if (nBlockYSize > 4096)  nBlockYSize = 4096;
    }
    else
    {
        nBlockXSize = nOvrXSize;
        nBlockYSize = nOvrYSize;
    }
    
    int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize;
    int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize;
    
    const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
    if (EQUAL(pszDriverName, "MEM") || EQUAL(pszDriverName, "VRT"))
    {
        CPLError(CE_Failure, CPLE_AppDefined, "GDAL %s driver cannot be used as underlying driver",
                 pszDriverName);
        return CE_Failure;
    }
    GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
    if (hTileDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
        return CE_Failure;
    }

    GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
    if (hMemDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
        return CE_Failure;
    }   

    GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType();
    int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
    GByte* pabyMEMDSBuffer =
        (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
    if (pabyMEMDSBuffer == NULL)
    {
        return CE_Failure;
    }
    
    CPLString osTempFileName;
    osTempFileName.Printf("/vsimem/%p", hDS);
    
    int nTileId = 0;
    int nBlocks = 0;
    int nTotalBlocks = nXBlocks * nYBlocks;
    
    CPLString osRasterLayer;
    osRasterLayer.Printf("%s_rasters", osTableName.c_str());
    
    CPLString osMetatadataLayer;
    osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());
    
    OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
    OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
    
    CPLString osSourceName = "unknown";
    
    osSQL.Printf("SELECT source_name FROM \"%s\" WHERE "
                 "%s LIMIT 1",
                 osMetatadataLayer.c_str(),
                 RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str());
    OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    if (hSQLLyr)
    {
        OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
        if (hFeat)
        {
            const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0);
            if (pszVal)
                osSourceName = pszVal;
            OGR_F_Destroy(hFeat);
        }
        OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
    }
    
/* -------------------------------------------------------------------- */
/*      Compute up to which existing overview level we can use for      */
/*      computing the requested overview                                */
/* -------------------------------------------------------------------- */
    int iLev;
    nLimitOvrCount = 0;
    for(iLev=1;iLev<nResolutions;iLev++)
    {
        if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 &&
              padfYResolutions[iLev] < dfYResolution - 1e-10))
        {
            break;
        }
        nLimitOvrCount++;
    }
/* -------------------------------------------------------------------- */
/*      Allocate buffer for tile of previous overview level             */
/* -------------------------------------------------------------------- */

    GDALDataset* poPrevOvrLevel =
        (papoOverviews != NULL && iLev >= 2 && iLev <= nResolutions && papoOverviews[iLev-2]) ?
            papoOverviews[iLev-2] : this;
    double dfRatioPrevOvr = poPrevOvrLevel->GetRasterBand(1)->GetXSize() / nOvrXSize;
    int nPrevOvrBlockXSize = (int)(nBlockXSize * dfRatioPrevOvr + 0.5);
    int nPrevOvrBlockYSize = (int)(nBlockYSize * dfRatioPrevOvr + 0.5);
    GByte* pabyPrevOvrMEMDSBuffer = NULL;

    if( !EQUALN(pszResampling, "NEAR", 4))
    {
        pabyPrevOvrMEMDSBuffer =
            (GByte*)VSIMalloc3(nPrevOvrBlockXSize, nPrevOvrBlockYSize, nBands * nDataTypeSize);
        if (pabyPrevOvrMEMDSBuffer == NULL)
        {
            VSIFree(pabyMEMDSBuffer);
            return CE_Failure;
        }
    }

/* -------------------------------------------------------------------- */
/*      Iterate over blocks to add data into raster and metadata tables */
/* -------------------------------------------------------------------- */

    char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions);

    OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
    
    CPLErr eErr = CE_None;
    int nBlockXOff, nBlockYOff;
    for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
    {
        for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
        {
            GDALDatasetH hPrevOvrMemDS = NULL;

/* -------------------------------------------------------------------- */
/*      Create in-memory tile                                           */
/* -------------------------------------------------------------------- */
            int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
            if ((nBlockXOff+1) * nBlockXSize > nOvrXSize)
                nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize;
            if ((nBlockYOff+1) * nBlockYSize > nOvrYSize)
                nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize;

            if( pabyPrevOvrMEMDSBuffer != NULL )
            {
                int nPrevOvrReqXSize =
                    (int)(nReqXSize * dfRatioPrevOvr + 0.5);
                int nPrevOvrReqYSize =
                    (int)(nReqYSize * dfRatioPrevOvr + 0.5);

                eErr = RasterIO(GF_Read,
                                nBlockXOff * nBlockXSize * nOvrFactor,
                                nBlockYOff * nBlockYSize * nOvrFactor,
                                nReqXSize * nOvrFactor, nReqYSize * nOvrFactor,
                                pabyPrevOvrMEMDSBuffer, nPrevOvrReqXSize, nPrevOvrReqYSize,
                                eDataType, nBands, NULL,
                                0, 0, 0, NULL);

                if (eErr != CE_None)
                {
                    break;
                }

                hPrevOvrMemDS = GDALCreate(hMemDriver, "MEM:::",
                                           nPrevOvrReqXSize, nPrevOvrReqYSize, 0,
                                           eDataType, NULL);

                if (hPrevOvrMemDS == NULL)
                {
                    eErr = CE_Failure;
                    break;
                }

                int iBand;
                for(iBand = 0; iBand < nBands; iBand ++)
                {
                    char** papszOptions = NULL;
                    char szTmp[64];
                    memset(szTmp, 0, sizeof(szTmp));
                    CPLPrintPointer(szTmp,
                                    pabyPrevOvrMEMDSBuffer + iBand * nDataTypeSize *
                                    nPrevOvrReqXSize * nPrevOvrReqYSize, sizeof(szTmp));
                    papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
                    GDALAddBand(hPrevOvrMemDS, eDataType, papszOptions);
                    CSLDestroy(papszOptions);
                }
            }
            else
            {
                eErr = RasterIO(GF_Read,
                                nBlockXOff * nBlockXSize * nOvrFactor,
                                nBlockYOff * nBlockYSize * nOvrFactor,
                                nReqXSize * nOvrFactor, nReqYSize * nOvrFactor,
                                pabyMEMDSBuffer, nReqXSize, nReqYSize,
                                eDataType, nBands, NULL,
                                0, 0, 0, NULL);
                if (eErr != CE_None)
                {
                    break;
                }
            }

            GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
                                              nReqXSize, nReqYSize, 0, 
                                              eDataType, NULL);
            if (hMemDS == NULL)
            {
                eErr = CE_Failure;
                break;
            }
            
            int iBand;
            for(iBand = 0; iBand < nBands; iBand ++)
            {
                char** papszOptions = NULL;
                char szTmp[64];
                memset(szTmp, 0, sizeof(szTmp));
                CPLPrintPointer(szTmp,
                                pabyMEMDSBuffer + iBand * nDataTypeSize *
                                nReqXSize * nReqYSize, sizeof(szTmp));
                papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
                GDALAddBand(hMemDS, eDataType, papszOptions);
                CSLDestroy(papszOptions);
            }

            if( hPrevOvrMemDS != NULL )
            {
                for(iBand = 0; iBand < nBands; iBand ++)
                {
                    GDALRasterBandH hDstOvrBand = GDALGetRasterBand(hMemDS, iBand+1);

                    eErr = GDALRegenerateOverviews( GDALGetRasterBand(hPrevOvrMemDS, iBand+1),
                                                    1, &hDstOvrBand,
                                                    pszResampling,
                                                    NULL, NULL );
                    if( eErr != CE_None )
                        break;
                }

                GDALClose(hPrevOvrMemDS);
            }

            GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
                                        osTempFileName.c_str(), hMemDS, FALSE,
                                        papszTileDriverOptions, NULL, NULL);

            GDALClose(hMemDS);
            if (hOutDS)
                GDALClose(hOutDS);
            else
            {
                eErr = CE_Failure;
                break;
            }

/* -------------------------------------------------------------------- */
/*      Insert new entry into raster table                              */
/* -------------------------------------------------------------------- */

            vsi_l_offset nDataLength;
            GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
                                                   &nDataLength, FALSE);

            OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
            OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
            
            OGR_L_CreateFeature(hRasterLayer, hFeat);
            /* Query raster ID to set it as the ID of the associated metadata */
            int nRasterID = (int)OGR_F_GetFID(hFeat);
            
            OGR_F_Destroy(hFeat);
            
            VSIUnlink(osTempFileName.c_str());
            
/* -------------------------------------------------------------------- */
/*      Insert new entry into metadata table                            */
/* -------------------------------------------------------------------- */
            
            hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
            OGR_F_SetFID(hFeat, nRasterID);
            OGR_F_SetFieldString(hFeat, 0, osSourceName);
            OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
            OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
            OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
            OGR_F_SetFieldDouble(hFeat, 4, dfXResolution);
            OGR_F_SetFieldDouble(hFeat, 5, dfYResolution);
            
            double minx, maxx, maxy, miny;
            minx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff) * dfXResolution;
            maxx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution;
            maxy = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff) * (-dfYResolution);
            miny = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution);
            
            OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
            OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
            
            OGR_F_SetGeometryDirectly(hFeat, hRectangle);
            
            OGR_L_CreateFeature(hMetadataLayer, hFeat);
            OGR_F_Destroy(hFeat);
            
            nBlocks++;
            if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
                                            NULL, pProgressData))
                eErr = CE_Failure;
        }
    }

    nLimitOvrCount = -1;
    
    if (eErr == CE_None)
        OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
    else
        OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
    
    VSIFree(pabyMEMDSBuffer);
    VSIFree(pabyPrevOvrMEMDSBuffer);

    CSLDestroy(papszTileDriverOptions);
    papszTileDriverOptions = NULL;

/* -------------------------------------------------------------------- */
/*      Update raster_pyramids table                                    */
/* -------------------------------------------------------------------- */
    if (eErr == CE_None)
    {
        OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
        if (hRasterPyramidsLyr == NULL)
        {
            osSQL.Printf   ("CREATE TABLE raster_pyramids ("
                            "table_prefix TEXT NOT NULL,"
                            "pixel_x_size DOUBLE NOT NULL,"
                            "pixel_y_size DOUBLE NOT NULL,"
                            "tile_count INTEGER NOT NULL)");
            OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
            
            /* Re-open the DB to take into account the new tables*/
            OGRReleaseDataSource(hDS);
            
            hDS = RasterliteOpenSQLiteDB(osFileName.c_str(), GA_Update);

            hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
            if (hRasterPyramidsLyr == NULL)
                return CE_Failure;
        }
        OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hRasterPyramidsLyr);

        /* Insert base resolution into raster_pyramids if not already done */
        int bHasBaseResolution = FALSE;
        osSQL.Printf("SELECT * FROM raster_pyramids WHERE "
                     "table_prefix = '%s' AND %s",
                     osTableName.c_str(),
                     RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str());
        hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
        if (hSQLLyr)
        {
            OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
            if (hFeat)
            {
                bHasBaseResolution = TRUE;
                OGR_F_Destroy(hFeat);
            }
            OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
        }

        if (!bHasBaseResolution)
        {
            osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE %s",
                          osMetatadataLayer.c_str(),
                          RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str());

            int nBlocksMainRes = 0;

            hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
            if (hSQLLyr)
            {
                OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
                if (hFeat)
                {
                    nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0);
                    OGR_F_Destroy(hFeat);
                }
                OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
            }

            OGRFeatureH hFeat = OGR_F_Create( hFDefn );
            OGR_F_SetFieldString(hFeat, OGR_FD_GetFieldIndex(hFDefn, "table_prefix"), osTableName.c_str());
            OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_x_size"), padfXResolutions[0]);
            OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_y_size"), padfYResolutions[0]);
            OGR_F_SetFieldInteger(hFeat, OGR_FD_GetFieldIndex(hFDefn, "tile_count"), nBlocksMainRes);
            OGR_L_CreateFeature(hRasterPyramidsLyr, hFeat);
            OGR_F_Destroy(hFeat);
        }

        OGRFeatureH hFeat = OGR_F_Create( hFDefn );
        OGR_F_SetFieldString(hFeat, OGR_FD_GetFieldIndex(hFDefn, "table_prefix"), osTableName.c_str());
        OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_x_size"), dfXResolution);
        OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_y_size"), dfYResolution);
        OGR_F_SetFieldInteger(hFeat, OGR_FD_GetFieldIndex(hFDefn, "tile_count"), nTotalBlocks);
        OGR_L_CreateFeature(hRasterPyramidsLyr, hFeat);
        OGR_F_Destroy(hFeat);
    }

    return eErr;
}
Esempio n. 8
0
int write_attributes(dbDriver *driver, int cat, const struct field_info *Fi,
                     OGRLayerH Ogr_layer, OGRFeatureH Ogr_feature)
{
    int j, ogrfieldnum;
    char buf[2000];
    int ncol, sqltype, ctype, ogrtype, more;
    const char *fidcol, *colname;
    dbTable *table;
    dbString dbstring;
    dbColumn *column;
    dbCursor cursor;
    dbValue *value;

    OGRFieldDefnH hFieldDefn;

    G_debug(3, "write_attributes(): cat = %d", cat);

    if (cat < 0) {
        G_warning(_("Feature without category of layer %d"), Fi->number);
        return 0;
    }

    db_init_string(&dbstring);

    /* read & set attributes */
    sprintf(buf, "SELECT * FROM %s WHERE %s = %d", Fi->table, Fi->key,
            cat);
    G_debug(4, "SQL: %s", buf);
    db_set_string(&dbstring, buf);

    /* select data */
    if (db_open_select_cursor(driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) {
        G_fatal_error(_("Unable to select attributes for category %d"),
                      cat);
    }

    if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
        G_fatal_error(_("Unable to fetch data from table <%s>"),
                      Fi->table);
    }

    if (!more) {
        G_warning(_("No database record for category %d, "
                    "no attributes will be written"),
                  cat);
        return -1;
    }

    fidcol = OGR_L_GetFIDColumn(Ogr_layer);

    table = db_get_cursor_table(&cursor);
    ncol = db_get_table_number_of_columns(table);
    for (j = 0; j < ncol; j++) {
        column = db_get_table_column(table, j);
        colname = db_get_column_name(column);
        if (fidcol && *fidcol && strcmp(colname, fidcol) == 0) {
            /* skip fid column */
            continue;
        }
        value = db_get_column_value(column);
        /* for debug only */
        db_convert_column_value_to_string(column, &dbstring);
        G_debug(2, "col %d : val = %s", j,
                db_get_string(&dbstring));

        sqltype = db_get_column_sqltype(column);
        ctype = db_sqltype_to_Ctype(sqltype);
        ogrtype = sqltype_to_ogrtype(sqltype);
        G_debug(2, "  colctype = %d", ctype);

        ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname);
        if (ogrfieldnum < 0) {
            /* create field if not exists */
            hFieldDefn = OGR_Fld_Create(colname, ogrtype);
            if (OGR_L_CreateField(Ogr_layer, hFieldDefn, TRUE) != OGRERR_NONE)
                G_warning(_("Unable to create field <%s>"), colname);
            ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname);
        }

        /* Reset */
        OGR_F_UnsetField(Ogr_feature, ogrfieldnum);

        /* prevent writing NULL values */
        if (!db_test_value_isnull(value)) {
            switch (ctype) {
            case DB_C_TYPE_INT:
                OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum,
                                      db_get_value_int(value));
                break;
            case DB_C_TYPE_DOUBLE:
                OGR_F_SetFieldDouble(Ogr_feature, ogrfieldnum,
                                     db_get_value_double(value));
                break;
            case DB_C_TYPE_STRING:
                OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
                                     db_get_value_string(value));
                break;
            case DB_C_TYPE_DATETIME:
                db_convert_column_value_to_string(column,
                                                  &dbstring);
                OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
                                     db_get_string(&dbstring));
                break;
            }
        }
    }

    db_close_cursor (&cursor);

    db_free_string(&dbstring);

    return 1;
}
Esempio n. 9
0
static CPLErr OGRPolygonContourWriter( double dfLevelMin, double dfLevelMax,
                                const OGRMultiPolygon& multipoly,
                                void *pInfo )

{
    OGRContourWriterInfo *poInfo = static_cast<OGRContourWriterInfo *>(pInfo);

    OGRFeatureDefnH hFDefn =
        OGR_L_GetLayerDefn( static_cast<OGRLayerH>(poInfo->hLayer) );

    OGRFeatureH hFeat = OGR_F_Create( hFDefn );

    if( poInfo->nIDField != -1 )
        OGR_F_SetFieldInteger( hFeat, poInfo->nIDField, poInfo->nNextID++ );

    if( poInfo->nElevFieldMin != -1 )
        OGR_F_SetFieldDouble( hFeat, poInfo->nElevFieldMin, dfLevelMin );

    if( poInfo->nElevFieldMax != -1 )
        OGR_F_SetFieldDouble( hFeat, poInfo->nElevFieldMax, dfLevelMax );

    const bool bHasZ = wkbHasZ(OGR_FD_GetGeomType(hFDefn));
    OGRGeometryH hGeom = OGR_G_CreateGeometry(
        bHasZ ? wkbMultiPolygon25D : wkbMultiPolygon );

    for ( int iPart = 0; iPart < multipoly.getNumGeometries(); iPart++ )
    {
        OGRPolygon* poNewPoly = new OGRPolygon();
        const OGRPolygon* poPolygon = static_cast<const OGRPolygon*>(multipoly.getGeometryRef(iPart));

        for ( int iRing = 0; iRing < poPolygon->getNumInteriorRings() + 1; iRing++ )
        {
            const OGRLinearRing* poRing = iRing == 0 ?
                poPolygon->getExteriorRing()
                : poPolygon->getInteriorRing(iRing - 1);

            OGRLinearRing* poNewRing = new OGRLinearRing();
            for ( int iPoint = 0; iPoint < poRing->getNumPoints(); iPoint++ )
            {
                const double dfX = poInfo->adfGeoTransform[0]
                    + poInfo->adfGeoTransform[1] * poRing->getX(iPoint)
                    + poInfo->adfGeoTransform[2] * poRing->getY(iPoint);
                const double dfY = poInfo->adfGeoTransform[3]
                    + poInfo->adfGeoTransform[4] * poRing->getX(iPoint)
                    + poInfo->adfGeoTransform[5] * poRing->getY(iPoint);
                if( bHasZ )
                    OGR_G_SetPoint( OGRGeometry::ToHandle( poNewRing ), iPoint, dfX, dfY, dfLevelMax );
                else
                    OGR_G_SetPoint_2D( OGRGeometry::ToHandle( poNewRing ), iPoint, dfX, dfY );
            }
            poNewPoly->addRingDirectly( poNewRing );
        }
        OGR_G_AddGeometryDirectly( hGeom, OGRGeometry::ToHandle( poNewPoly ) );
    }

    OGR_F_SetGeometryDirectly( hFeat, hGeom );

    const OGRErr eErr =
        OGR_L_CreateFeature(static_cast<OGRLayerH>(poInfo->hLayer), hFeat);
    OGR_F_Destroy( hFeat );

    return eErr == OGRERR_NONE ? CE_None : CE_Failure;
}
Esempio n. 10
0
int main(int argc, char* argv[])
{
    const char     *pszFormat = "ESRI Shapefile";
    char           *pszLayerName = NULL;
    const char     *pszSrcFilename = NULL, *pszDstFilename = NULL;
    int             iBand = 1;
    GDALDatasetH    hDS;
    GDALRasterBandH hBand;
    int             nXSize, nYSize;
    int             i, j;
    FILE           *fOut = NULL;
    double         *padfBuffer;
    double          adfGeotransform[6];
    OGRSFDriverH    hOGRDriver;
    OGRDataSourceH  hOGRDS;
    OGRLayerH       hOGRLayer;
    OGRwkbGeometryType eType = wkbPoint25D;
    int             xStep = 1, yStep = 1;

    OGRRegisterAll();
    GDALAllRegister();

    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

/* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
    for( i = 1; i < argc; i++ )
    {
        if ( EQUAL(argv[i], "-b") && i < argc - 1)
            iBand = atoi(argv[++i]);
        else if ( EQUAL(argv[i], "-f") && i < argc - 1)
            pszFormat = argv[++i];
        else if ( EQUAL(argv[i], "-l") && i < argc - 1)
            pszLayerName = CPLStrdup(argv[++i]);
        else if ( EQUAL(argv[i], "-t") && i < argc - 1)
        {
            i++;
            if (EQUAL(argv[i], "POLYGON"))
                eType = wkbPolygon;
            else if (EQUAL(argv[i], "POINT"))
                eType = wkbPoint;
            else if (EQUAL(argv[i], "POINT25D"))
                eType = wkbPoint25D;
            else
            {
                fprintf(stderr, "unhandled geometry type : %s\n", argv[i]);
            }
        }
        else if ( EQUAL(argv[i], "-step") && i < argc - 1)
            xStep = yStep = atoi(argv[++i]);
        else if ( argv[i][0] == '-')
            Usage();
        else if( pszSrcFilename == NULL )
            pszSrcFilename = argv[i];
        else if(  pszDstFilename == NULL )
            pszDstFilename = argv[i];
        else
            Usage();
    }

    if( pszSrcFilename == NULL || pszDstFilename == NULL)
        Usage();

/* -------------------------------------------------------------------- */
/*      Open GDAL source dataset                                        */
/* -------------------------------------------------------------------- */
    hDS = GDALOpen(pszSrcFilename, GA_ReadOnly);
    if (hDS == NULL)
    {
        fprintf(stderr, "Can't open %s\n", pszSrcFilename);
        exit(1);
    }

    hBand = GDALGetRasterBand(hDS, iBand);
    if (hBand == NULL)
    {
        fprintf(stderr, "Can't get band %d\n", iBand);
        exit(1);
    }

    if (GDALGetGeoTransform(hDS, adfGeotransform) != CE_None)
    {
        fprintf(stderr, "Can't get geotransform\n");
        exit(1);
    }

    nXSize = GDALGetRasterXSize(hDS);
    nYSize = GDALGetRasterYSize(hDS);

/* -------------------------------------------------------------------- */
/*     Create OGR destination dataset                                   */
/* -------------------------------------------------------------------- */
    /* Special case for CSV : we generate the appropriate VRT file in the same time */
    if (EQUAL(pszFormat, "CSV") && EQUAL(CPLGetExtension(pszDstFilename), "CSV"))
    {
        FILE* fOutCSVT;
        FILE* fOutVRT;
        char* pszDstFilenameCSVT;
        char* pszDstFilenameVRT;

        fOut = fopen(pszDstFilename, "wt");
        if (fOut == NULL)
        {
            fprintf(stderr, "Can't open %s for writing\n", pszDstFilename);
            exit(1);
        }
        fprintf(fOut, "x,y,z\n");

        pszDstFilenameCSVT = CPLMalloc(strlen(pszDstFilename) + 2);
        strcpy(pszDstFilenameCSVT, pszDstFilename);
        strcat(pszDstFilenameCSVT, "t");
        fOutCSVT = fopen(pszDstFilenameCSVT, "wt");
        if (fOutCSVT == NULL)
        {
            fprintf(stderr, "Can't open %s for writing\n", pszDstFilenameCSVT);
            exit(1);
        }
        CPLFree(pszDstFilenameCSVT);
        fprintf(fOutCSVT, "Real,Real,Real\n");
        fclose(fOutCSVT);
        fOutCSVT = NULL;

        pszDstFilenameVRT = CPLStrdup(pszDstFilename);
        strcpy(pszDstFilenameVRT + strlen(pszDstFilename) - 3, "vrt");
        fOutVRT = fopen(pszDstFilenameVRT, "wt");
        if (fOutVRT == NULL)
        {
            fprintf(stderr, "Can't open %s for writing\n", pszDstFilenameVRT);
            exit(1);
        }
        CPLFree(pszDstFilenameVRT);
        fprintf(fOutVRT, "<OGRVRTDataSource>\n");
        fprintf(fOutVRT, "  <OGRVRTLayer name=\"%s\">\n", CPLGetBasename(pszDstFilename));
        fprintf(fOutVRT, "    <SrcDataSource>%s</SrcDataSource> \n", pszDstFilename);
        fprintf(fOutVRT, "    <GeometryType>wkbPoint</GeometryType>\n");
        fprintf(fOutVRT, "    <GeometryField encoding=\"PointFromColumns\" x=\"x\" y=\"y\" z=\"z\"/>\n");
        fprintf(fOutVRT, "  </OGRVRTLayer>\n");
        fprintf(fOutVRT, "</OGRVRTDataSource>\n");
        fclose(fOutVRT);
        fOutVRT = NULL;
    }
    else
    {
        OGRSpatialReferenceH hSRS = NULL;
        const char* pszWkt;

        hOGRDriver = OGRGetDriverByName(pszFormat);
        if (hOGRDriver == NULL)
        {
            fprintf(stderr, "Can't find OGR driver %s\n", pszFormat);
            exit(1);
        }

        hOGRDS = OGR_Dr_CreateDataSource(hOGRDriver, pszDstFilename, NULL);
        if (hOGRDS == NULL)
        {
            fprintf(stderr, "Can't create OGR datasource %s\n", pszDstFilename);
            exit(1);
        }

        pszWkt = GDALGetProjectionRef(hDS);
        if (pszWkt && pszWkt[0])
        {
            hSRS = OSRNewSpatialReference(pszWkt);
        }

        if (pszLayerName == NULL)
            pszLayerName = CPLStrdup(CPLGetBasename(pszDstFilename));

        hOGRLayer = OGR_DS_CreateLayer( hOGRDS, pszLayerName,
                                        hSRS, eType, NULL);

        if (hSRS)
            OSRDestroySpatialReference(hSRS);

        if (hOGRLayer == NULL)
        {
            fprintf(stderr, "Can't create layer %s\n", pszLayerName);
            exit(1);
        }

        if (eType != wkbPoint25D)
        {
            OGRFieldDefnH hFieldDefn =  OGR_Fld_Create( "z", OFTReal );
            OGR_L_CreateField(hOGRLayer, hFieldDefn, 0);
            OGR_Fld_Destroy( hFieldDefn );
        }
    }


    padfBuffer = (double*)CPLMalloc(nXSize * sizeof(double));

#define GET_X(j, i) adfGeotransform[0] + (j) * adfGeotransform[1] + (i) * adfGeotransform[2]
#define GET_Y(j, i) adfGeotransform[3] + (j) * adfGeotransform[4] + (i) * adfGeotransform[5]
#define GET_XY(j, i) GET_X(j, i), GET_Y(j, i)

/* -------------------------------------------------------------------- */
/*     "Translate" the source dataset                                   */
/* -------------------------------------------------------------------- */
    for(i=0;i<nYSize;i+=yStep)
    {
        GDALRasterIO( hBand, GF_Read, 0, i, nXSize, 1,
                      padfBuffer, nXSize, 1, GDT_Float64, 0, 0);
        for(j=0;j<nXSize;j+=xStep)
        {
            if (fOut)
            {
                fprintf(fOut, "%f,%f,%f\n",
                        GET_XY(j + .5, i + .5), padfBuffer[j]);
            }
            else
            {
                OGRFeatureH hFeature = OGR_F_Create(OGR_L_GetLayerDefn(hOGRLayer));
                OGRGeometryH hGeometry = OGR_G_CreateGeometry(eType);
                if (eType == wkbPoint25D)
                {
                    OGR_G_SetPoint(hGeometry, 0, GET_XY(j + .5, i + .5),
                                   padfBuffer[j]);
                }
                else if (eType == wkbPoint)
                {
                    OGR_G_SetPoint_2D(hGeometry, 0, GET_XY(j + .5, i + .5));
                    OGR_F_SetFieldDouble(hFeature, 0, padfBuffer[j]);
                }
                else
                {
                    OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
                    OGR_G_SetPoint_2D(hLinearRing, 0, GET_XY(j + 0, i + 0));
                    OGR_G_SetPoint_2D(hLinearRing, 1, GET_XY(j + 1, i + 0));
                    OGR_G_SetPoint_2D(hLinearRing, 2, GET_XY(j + 1, i + 1));
                    OGR_G_SetPoint_2D(hLinearRing, 3, GET_XY(j + 0, i + 1));
                    OGR_G_SetPoint_2D(hLinearRing, 4, GET_XY(j + 0, i + 0));
                    OGR_G_AddGeometryDirectly(hGeometry, hLinearRing);
                    OGR_F_SetFieldDouble(hFeature, 0, padfBuffer[j]);
                }
                OGR_F_SetGeometryDirectly(hFeature, hGeometry);
                OGR_L_CreateFeature(hOGRLayer, hFeature);
                OGR_F_Destroy(hFeature);
            }
        }
    }

/* -------------------------------------------------------------------- */
/*     Cleanup                                                          */
/* -------------------------------------------------------------------- */
    if (fOut)
        fclose(fOut);
    else
        OGR_DS_Destroy(hOGRDS);
    GDALClose(hDS);

    CPLFree(padfBuffer);
    CPLFree(pszLayerName);

    GDALDumpOpenDatasets( stderr );
    GDALDestroyDriverManager();
    OGRCleanupAll();
    CSLDestroy( argv );

    return 0;
}