Example #1
0
/*!
  \brief Load data records (&D)

  Call VFKReader::OpenFile() before this function.

  \param poDataBlock limit to selected data block or NULL for all

  \return number of data records or -1 on error
*/
int VFKReaderSQLite::ReadDataRecords(IVFKDataBlock *poDataBlock)
{
    int         nDataRecords;
    int         iDataBlock;
    const char *pszName;
    CPLString   osSQL;

    IVFKDataBlock *poDataBlockCurrent;

    sqlite3_stmt *hStmt;

    pszName = NULL;

    if (poDataBlock) { /* read records only for selected data block */
        /* table name */
        pszName = poDataBlock->GetName();

        /* check for existing records (re-use already inserted data) */
        osSQL.Printf("SELECT num_records FROM %s WHERE "
                     "table_name = '%s'",
                     VFK_DB_TABLE, pszName);
        hStmt = PrepareStatement(osSQL.c_str());
        nDataRecords = -1;
        if (ExecuteSQL(hStmt) == OGRERR_NONE) {
            nDataRecords = sqlite3_column_int(hStmt, 0);
        }
        sqlite3_finalize(hStmt);
    }
    else {
                      /* read all data blocks */

        /* check for existing records (re-use already inserted data) */
        osSQL.Printf("SELECT COUNT(*) FROM %s WHERE num_records = -1", VFK_DB_TABLE);
        hStmt = PrepareStatement(osSQL.c_str());
        if (ExecuteSQL(hStmt) == OGRERR_NONE &&
            sqlite3_column_int(hStmt, 0) == 0)
            nDataRecords = 0;     /* -> read from DB */
        else
            nDataRecords = -1;    /* -> read from VFK file */

        sqlite3_finalize(hStmt);
    }

    if (nDataRecords > -1) {        /* read records from DB */
        /* read from  DB */
        long iFID;
        int  iRowId;
        VFKFeatureSQLite *poNewFeature = NULL;

        poDataBlockCurrent = NULL;
        for (iDataBlock = 0; iDataBlock < GetDataBlockCount(); iDataBlock++) {
            poDataBlockCurrent = GetDataBlock(iDataBlock);

            if (poDataBlock && poDataBlock != poDataBlockCurrent)
                continue;

            poDataBlockCurrent->SetFeatureCount(0); /* avoid recursive call */

            pszName = poDataBlockCurrent->GetName();
            CPLAssert(NULL != pszName);

            osSQL.Printf("SELECT %s,_rowid_ FROM %s ",
                         FID_COLUMN, pszName);
            if (EQUAL(pszName, "SBP"))
              osSQL += "WHERE PORADOVE_CISLO_BODU = 1 ";
            osSQL += "ORDER BY ";
            osSQL += FID_COLUMN;
            hStmt = PrepareStatement(osSQL.c_str());
            nDataRecords = 0;
            while (ExecuteSQL(hStmt) == OGRERR_NONE) {
                iFID = sqlite3_column_int(hStmt, 0);
                iRowId = sqlite3_column_int(hStmt, 1);
                poNewFeature = new VFKFeatureSQLite(poDataBlockCurrent, iRowId, iFID);
                poDataBlockCurrent->AddFeature(poNewFeature);
                nDataRecords++;
            }

            /* check DB consistency */
            osSQL.Printf("SELECT num_features FROM %s WHERE table_name = '%s'",
                         VFK_DB_TABLE, pszName);
            hStmt = PrepareStatement(osSQL.c_str());
            if (ExecuteSQL(hStmt) == OGRERR_NONE) {
                int nFeatDB;

                nFeatDB = sqlite3_column_int(hStmt, 0);
                if (nFeatDB > 0 && nFeatDB != poDataBlockCurrent->GetFeatureCount())
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "%s: Invalid number of features " CPL_FRMT_GIB " (should be %d)",
                             pszName, poDataBlockCurrent->GetFeatureCount(), nFeatDB);
            }
            sqlite3_finalize(hStmt);
        }
    }
    else {                          /* read from VFK file and insert records into DB */
        /* begin transaction */
        ExecuteSQL("BEGIN");

        /* INSERT ... */
        nDataRecords = VFKReader::ReadDataRecords(poDataBlock);

        /* update VFK_DB_TABLE table */
        poDataBlockCurrent = NULL;
        for (iDataBlock = 0; iDataBlock < GetDataBlockCount(); iDataBlock++) {
            poDataBlockCurrent = GetDataBlock(iDataBlock);

            if (poDataBlock && poDataBlock != poDataBlockCurrent)
                continue;

            osSQL.Printf("UPDATE %s SET num_records = %d WHERE "
                         "table_name = '%s'",
                         VFK_DB_TABLE, poDataBlockCurrent->GetRecordCount(),
                         poDataBlockCurrent->GetName());

            ExecuteSQL(osSQL);
        }

        /* commit transaction */
        ExecuteSQL("COMMIT");
    }

    return nDataRecords;
}
Example #2
0
GDALDataset *ARGDataset::CreateCopy( const char *pszFilename,
                                     GDALDataset *poSrcDS,
                                     int /* bStrict */ ,
                                     char ** /* papszOptions */ ,
                                     GDALProgressFunc /* pfnProgress */ ,
                                     void * /*pProgressData */ )
{
    const int nBands = poSrcDS->GetRasterCount();
    if( nBands != 1 )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
              "ARG driver doesn't support %d bands.  Must be 1 band.", nBands );
        return NULL;
    }

    CPLString pszDataType;
    int nPixelOffset = 0;

    GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    if( eType == GDT_Unknown ||
        eType == GDT_CInt16 ||
        eType == GDT_CInt32 ||
        eType == GDT_CFloat32 ||
        eType == GDT_CFloat64 )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "ARG driver doesn't support data type %s.",
                  GDALGetDataTypeName(eType) );
        return NULL;
    }
    else if (eType == GDT_Int16) {
        pszDataType = "int16";
        nPixelOffset = 2;
    }
    else if (eType == GDT_Int32) {
        pszDataType = "int32";
        nPixelOffset = 4;
    }
    else if (eType == GDT_Byte) {
        pszDataType = "uint8";
        nPixelOffset = 1;
    }
    else if (eType == GDT_UInt16) {
        pszDataType = "uint16";
        nPixelOffset = 2;
    }
    else if (eType == GDT_UInt32) {
        pszDataType = "uint32";
        nPixelOffset = 4;
    }
    else if (eType == GDT_Float32) {
        pszDataType = "float32";
        nPixelOffset = 4;
    }
    else if (eType == GDT_Float64) {
        pszDataType = "float64";
        nPixelOffset = 8;
    }

    double adfTransform[6];
    poSrcDS->GetGeoTransform( adfTransform );

    char *pszWKT = const_cast<char *>(poSrcDS->GetProjectionRef());
    OGRSpatialReference oSRS;
    OGRErr nErr = oSRS.importFromWkt(&pszWKT);
    if (nErr != OGRERR_NONE) {
        CPLError( CE_Failure, CPLE_NotSupported,
              "Cannot import spatial reference WKT from source dataset.");
        return NULL;
    }

    int nSrs = 0;
    if (oSRS.GetAuthorityCode("PROJCS") != NULL) {
        nSrs = atoi(oSRS.GetAuthorityCode("PROJCS"));
    }
    else if (oSRS.GetAuthorityCode("GEOGCS") != NULL) {
        nSrs = atoi(oSRS.GetAuthorityCode("GEOGCS"));
    }
    else {
        // could not determine projected or geographic code
        // default to EPSG:3857 if no code could be found
        nSrs = 3857;
    }

    /********************************************************************/
    /* Create JSON companion file.                                      */
    /********************************************************************/
    const CPLString osJSONFilename = GetJsonFilename(pszFilename);

    json_object *poJSONObject = json_object_new_object();

    char **pszTokens = poSrcDS->GetMetadata();
    const char *pszLayer = CSLFetchNameValue(pszTokens, "LAYER");

    if ( pszLayer == NULL) {
        // Set the layer
        json_object_object_add(poJSONObject, "layer", json_object_new_string(
            CPLGetBasename(osJSONFilename)
        ));
    }
    else {
        // Set the layer
        json_object_object_add(poJSONObject, "layer", json_object_new_string(
            pszLayer
        ));
    }

    // Set the type
    json_object_object_add(poJSONObject, "type", json_object_new_string("arg"));
    // Set the datatype
    json_object_object_add(poJSONObject, "datatype", json_object_new_string(pszDataType));

    const int nXSize = poSrcDS->GetRasterXSize();
    const int nYSize = poSrcDS->GetRasterYSize();

    // Set the number of rows
    json_object_object_add(poJSONObject, "rows", json_object_new_int(nYSize));
    // Set the number of columns
    json_object_object_add(poJSONObject, "cols", json_object_new_int(nXSize));
    // Set the xmin
    json_object_object_add(poJSONObject, "xmin", json_object_new_double(adfTransform[0]));
    // Set the ymax
    json_object_object_add(poJSONObject, "ymax", json_object_new_double(adfTransform[3]));
    // Set the cellwidth
    json_object_object_add(poJSONObject, "cellwidth", json_object_new_double(adfTransform[1]));
    // Set the cellheight
    json_object_object_add(poJSONObject, "cellheight", json_object_new_double(-adfTransform[5]));
    // Set the xmax
    json_object_object_add(poJSONObject, "xmax", json_object_new_double(adfTransform[0] + nXSize * adfTransform[1]));
    // Set the ymin
    json_object_object_add(poJSONObject, "ymin", json_object_new_double(adfTransform[3] + nYSize * adfTransform[5]));
    // Set the xskew
    json_object_object_add(poJSONObject, "xskew", json_object_new_double(adfTransform[2]));
    // Set the yskew
    json_object_object_add(poJSONObject, "yskew", json_object_new_double(adfTransform[4]));
    if (nSrs > 0) {
        // Set the epsg
        json_object_object_add(poJSONObject, "epsg", json_object_new_int(nSrs));
    }

    if (json_object_to_file(const_cast<char *>(osJSONFilename.c_str()), poJSONObject) < 0) {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "ARG driver can't write companion file.");

        json_object_put(poJSONObject);
        poJSONObject = NULL;

        return NULL;
    }

    json_object_put(poJSONObject);
    poJSONObject = NULL;

    VSILFILE *fpImage = VSIFOpenL(pszFilename, "wb");
    if (fpImage == NULL)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
              "ARG driver can't create data file %s.", pszFilename);

        // remove JSON file
        VSIUnlink( osJSONFilename.c_str() );

        return NULL;
    }

    // only 1 raster band
    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 );

#ifdef CPL_LSB
    int bNative = FALSE;
#else
    int bNative = TRUE;
#endif

    RawRasterBand *poDstBand = new RawRasterBand( fpImage, 0, nPixelOffset,
                                                  nPixelOffset * nXSize, eType, bNative,
                                                  nXSize, nYSize, TRUE, FALSE);

    int nXBlockSize, nYBlockSize;
    poSrcBand->GetBlockSize(&nXBlockSize, &nYBlockSize);

    void *pabyData = CPLMalloc(nXBlockSize * nPixelOffset);

    // convert any blocks into scanlines
    for (int nYBlock = 0; nYBlock * nYBlockSize < nYSize; nYBlock++) {
        for (int nYScanline = 0; nYScanline < nYBlockSize; nYScanline++) {
            if ((nYScanline+1) + nYBlock * nYBlockSize > poSrcBand->GetYSize() ) {
                continue;
            }

            for (int nXBlock = 0; nXBlock * nXBlockSize < nXSize; nXBlock++) {
                int nXValid;

                if( (nXBlock+1) * nXBlockSize > poSrcBand->GetXSize() )
                    nXValid = poSrcBand->GetXSize() - nXBlock * nXBlockSize;
                else
                    nXValid = nXBlockSize;

                CPLErr eErr = poSrcBand->RasterIO(GF_Read, nXBlock * nXBlockSize,
                    nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize,
                    1, eType, 0, 0, NULL);

                if (eErr != CE_None) {
                    CPLError(CE_Failure, CPLE_AppDefined, "Error reading.");

                    CPLFree( pabyData );
                    delete poDstBand;
                    VSIFCloseL( fpImage );

                    return NULL;
                }

                eErr = poDstBand->RasterIO(GF_Write, nXBlock * nXBlockSize,
                    nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize,
                    1, eType, 0, 0, NULL);

                if (eErr != CE_None) {
                    CPLError(CE_Failure, CPLE_AppDefined, "Error writing.");

                    CPLFree( pabyData );
                    delete poDstBand;
                    VSIFCloseL( fpImage );

                    return NULL;
                }
            }
        }
    }

    CPLFree( pabyData );
    delete poDstBand;
    VSIFCloseL( fpImage );

    return reinterpret_cast<GDALDataset *>( GDALOpen( pszFilename, GA_ReadOnly ) );
}
int OGRGPSBabelDataSource::Open( const char * pszDatasourceName,
                                 const char* pszGPSBabelDriverNameIn,
                                 char** papszOpenOptionsIn )

{
    if (!STARTS_WITH_CI(pszDatasourceName, "GPSBABEL:"))
    {
        CPLAssert(pszGPSBabelDriverNameIn);
        pszGPSBabelDriverName = CPLStrdup(pszGPSBabelDriverNameIn);
        pszFilename = CPLStrdup(pszDatasourceName);
    }
    else
    {
        if( CSLFetchNameValue(papszOpenOptionsIn, "FILENAME") )
            pszFilename = CPLStrdup(CSLFetchNameValue(papszOpenOptionsIn,
                                                      "FILENAME"));

        if( CSLFetchNameValue(papszOpenOptionsIn, "GPSBABEL_DRIVER") )
        {
            if( pszFilename == NULL )
            {
                CPLError(CE_Failure, CPLE_AppDefined, "Missing FILENAME");
                return FALSE;
            }

            pszGPSBabelDriverName
                = CPLStrdup(CSLFetchNameValue(papszOpenOptionsIn, "DRIVER"));

            /* A bit of validation to avoid command line injection */
            if (!IsValidDriverName(pszGPSBabelDriverName))
                return FALSE;
        }
    }

    pszName = CPLStrdup( pszDatasourceName );

    bool bExplicitFeatures = false;
    bool bWaypoints = true;
    bool bTracks = true;
    bool bRoutes = true;

    if (pszGPSBabelDriverName == NULL)
    {
        const char* pszSep = strchr(pszDatasourceName + 9, ':');
        if (pszSep == NULL)
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Wrong syntax. Expected GPSBabel:driver_name:file_name");
            return FALSE;
        }

        pszGPSBabelDriverName = CPLStrdup(pszDatasourceName + 9);
        *(strchr(pszGPSBabelDriverName, ':')) = '\0';

        /* A bit of validation to avoid command line injection */
        if (!IsValidDriverName(pszGPSBabelDriverName))
            return FALSE;

        /* Parse optional features= option */
        if (STARTS_WITH_CI(pszSep+1, "features="))
        {
            const char* pszNextSep = strchr(pszSep+1, ':');
            if (pszNextSep == NULL)
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "Wrong syntax. Expected "
                         "GPSBabel:driver_name[,options]*:["
                         "features=waypoints,tracks,routes:]file_name");
                return FALSE;
            }

            char* pszFeatures = CPLStrdup(pszSep+1+9);
            *strchr(pszFeatures, ':') = 0;
            char** papszTokens = CSLTokenizeString(pszFeatures);
            char** papszIter = papszTokens;
            bool bErr = false;
            bExplicitFeatures = true;
            bWaypoints = false;
            bTracks = false;
            bRoutes = false;
            while(papszIter && *papszIter)
            {
                if (EQUAL(*papszIter, "waypoints"))
                    bWaypoints = true;
                else if (EQUAL(*papszIter, "tracks"))
                    bTracks = true;
                else if (EQUAL(*papszIter, "routes"))
                    bRoutes = true;
                else
                {
                    CPLError( CE_Failure, CPLE_AppDefined,
                              "Wrong value for 'features' options");
                    bErr = true;
                }
                papszIter++;
            }
            CSLDestroy(papszTokens);
            CPLFree(pszFeatures);

            if (bErr)
                return FALSE;

            pszSep = pszNextSep;
        }

        if( pszFilename == NULL )
            pszFilename = CPLStrdup(pszSep+1);
    }

    const char* pszOptionUseTempFile = CPLGetConfigOption("USE_TEMPFILE", NULL);
    if (pszOptionUseTempFile && CPLTestBool(pszOptionUseTempFile))
        osTmpFileName = CPLGenerateTempFilename(NULL);
    else
        osTmpFileName.Printf("/vsimem/ogrgpsbabeldatasource_%p", this);

    bool bRet = false;
    if (IsSpecialFile(pszFilename))
    {
        /* Special file : don't try to open it */
        char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes,
                              bTracks, pszGPSBabelDriverName, pszFilename);
        VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb");
        bRet = (CPLSpawn(argv, NULL, tmpfp, TRUE) == 0);
        VSIFCloseL(tmpfp);
        tmpfp = NULL;
        CSLDestroy(argv);
        argv = NULL;
    }
    else
    {
        VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
        if (fp == NULL)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                    "Cannot open file %s", pszFilename);
            return FALSE;
        }

        char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes,
                              bTracks, pszGPSBabelDriverName, "-");

        VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb");

        CPLPushErrorHandler(CPLQuietErrorHandler);
        bRet = (CPLSpawn(argv, fp, tmpfp, TRUE) == 0);
        CPLPopErrorHandler();

        CSLDestroy(argv);
        argv = NULL;

        CPLErr nLastErrorType = CPLGetLastErrorType();
        CPLErrorNum nLastErrorNo = CPLGetLastErrorNo();
        CPLString osLastErrorMsg = CPLGetLastErrorMsg();

        VSIFCloseL(tmpfp);
        tmpfp = NULL;

        VSIFCloseL(fp);
        fp = NULL;

        if (!bRet)
        {
            if ( strstr(osLastErrorMsg.c_str(),
                        "This format cannot be used in piped commands") == NULL)
            {
                CPLError( nLastErrorType, nLastErrorNo, "%s",
                          osLastErrorMsg.c_str());
            }
            else
            {
                VSIStatBuf sStatBuf;
                if (VSIStat(pszFilename, &sStatBuf) != 0)
                {
                    CPLError( CE_Failure, CPLE_NotSupported,
                              "Driver %s only supports real (non virtual) "
                              "files",
                              pszGPSBabelDriverName );
                    return FALSE;
                }

                /* Try without piping in */
                argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes,
                              bTracks, pszGPSBabelDriverName, pszFilename);
                tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb");
                bRet = (CPLSpawn(argv, NULL, tmpfp, TRUE) == 0);
                VSIFCloseL(tmpfp);
                tmpfp = NULL;

                CSLDestroy(argv);
                argv = NULL;
            }
        }
    }


    if (bRet)
    {
        poGPXDS = static_cast<GDALDataset *>(
            GDALOpenEx( osTmpFileName.c_str(),
                        GDAL_OF_VECTOR, NULL, NULL, NULL ) );
        if (poGPXDS)
        {
            if (bWaypoints)
            {
                OGRLayer* poLayer = poGPXDS->GetLayerByName("waypoints");
                if (poLayer != NULL && poLayer->GetFeatureCount() != 0)
                    apoLayers[nLayers++] = poLayer;
            }

            if (bRoutes)
            {
                OGRLayer* poLayer = poGPXDS->GetLayerByName("routes");
                if (poLayer != NULL && poLayer->GetFeatureCount() != 0)
                    apoLayers[nLayers++] = poLayer;
                poLayer = poGPXDS->GetLayerByName("route_points");
                if (poLayer != NULL && poLayer->GetFeatureCount() != 0)
                    apoLayers[nLayers++] = poLayer;
            }

            if (bTracks)
            {
                OGRLayer* poLayer = poGPXDS->GetLayerByName("tracks");
                if (poLayer != NULL && poLayer->GetFeatureCount() != 0)
                    apoLayers[nLayers++] = poLayer;
                poLayer = poGPXDS->GetLayerByName("track_points");
                if (poLayer != NULL && poLayer->GetFeatureCount() != 0)
                    apoLayers[nLayers++] = poLayer;
            }
        }
    }

    return nLayers > 0;
}
CPLErr PostGISRasterRasterBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff,
    int nYOff, int nXSize, int nYSize, void * pData, int nBufXSize,
    int nBufYSize, GDALDataType eBufType, int nPixelSpace,
    int nLineSpace)
{
    PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS;

    CPLDebug("PostGIS_Raster",
        "PostGISRasterRasterBand::IRasterIO(): Table %s.%s (%s), Srid : %d",
        pszSchema, pszTable, pszColumn, poRDS->nSrid);

    if (eRWFlag == GF_Write) {

        /*
        ReportError(CE_Failure, CPLE_NotSupported,
            "Writing through PostGIS Raster band not supported yet");

        return CE_Failure;
        */

        // Delegate in generic IRasterIO to force IWriteBlock call.
        // TODO: This is not a solution for UPDATE scenario, but it works
        // for CREATE scenario.
        return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize,
            nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace,
            nLineSpace);
    }

    /*******************************************************************
     * Do we have overviews that would be appropriate to satisfy this
     * request?
     ******************************************************************/
    if( (nBufXSize < nXSize || nBufYSize < nYSize) &&
        GetOverviewCount() > 0 && eRWFlag == GF_Read)
    {
        if(OverviewRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize,
            pData, nBufXSize, nBufYSize, eBufType, nPixelSpace,
            nLineSpace) == CE_None)

        return CE_None;
    }

    int bSameWindowAsOtherBand =
        (nXOff == poRDS->nXOffPrev &&
         nYOff == poRDS->nYOffPrev &&
         nXSize == poRDS->nXSizePrev &&
         nYSize == poRDS->nYSizePrev);
    poRDS->nXOffPrev = nXOff;
    poRDS->nYOffPrev = nYOff;
    poRDS->nXSizePrev = nXSize;
    poRDS->nYSizePrev = nYSize;

    /* Logic to determine if bands are read in order 1, 2, ... N */
    /* If so, then use multi-band caching, otherwise do just single band caching */
    if( poRDS->bAssumeMultiBandReadPattern )
    {
        if( nBand != poRDS->nNextExpectedBand )
        {
            CPLDebug("PostGIS_Raster",
                    "Disabling multi-band caching since band access pattern does not match");
            poRDS->bAssumeMultiBandReadPattern = false;
            poRDS->nNextExpectedBand = 1;
        }
        else
        {
            poRDS->nNextExpectedBand ++;
            if( poRDS->nNextExpectedBand > poRDS->GetRasterCount() )
                poRDS->nNextExpectedBand = 1;
        }
    }
    else
    {
        if( nBand == poRDS->nNextExpectedBand )
        {
            poRDS->nNextExpectedBand ++;
            if( poRDS->nNextExpectedBand > poRDS->GetRasterCount() )
            {
                CPLDebug("PostGIS_Raster", "Re-enabling multi-band caching");
                poRDS->bAssumeMultiBandReadPattern = true;
                poRDS->nNextExpectedBand = 1;
            }
        }
    }

#ifdef DEBUG_VERBOSE
    CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IRasterIO: "
            "nBand = %d, nXOff = %d, nYOff = %d, nXSize = %d, nYSize = %d, nBufXSize = %d, nBufYSize = %d",
             nBand, nXOff, nYOff, nXSize,  nYSize, nBufXSize, nBufYSize);
#endif

#ifdef notdef
    /*******************************************************************
     * Optimization: We just have one tile. So, we can read it with
     * IReadBlock
     *
     * TODO: Review it. It's not working (see comment in
     * PostGISRasterDataset::ConstructOneDatasetFromTiles)
     ******************************************************************/

    if (poRDS->nTiles == 1) {

        return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize,
            nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace,
            nLineSpace);
    }
#endif

    /*******************************************************************
     * Several tiles: we first look in all our sources caches. Missing
     * blocks are queried
     ******************************************************************/
    double adfProjWin[8];
    int nFeatureCount = 0;
    CPLRectObj sAoi;

    poRDS->PolygonFromCoords(nXOff, nYOff, nXOff + nXSize, nYOff + nYSize, adfProjWin);
    // (p[6], p[7]) is the minimum (x, y), and (p[2], p[3]) the max
    sAoi.minx = adfProjWin[6];
    sAoi.maxx = adfProjWin[2];
    if( adfProjWin[7] < adfProjWin[3] )
    {
        sAoi.miny = adfProjWin[7];
        sAoi.maxy = adfProjWin[3];
    }
    else
    {
        sAoi.maxy = adfProjWin[7];
        sAoi.miny = adfProjWin[3];
    }

#ifdef DEBUG_VERBOSE
    CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IRasterIO: "
            "Intersection box: (%f, %f) - (%f, %f)", sAoi.minx,
            sAoi.miny, sAoi.maxx, sAoi.maxy);
#endif

    if (poRDS->hQuadTree == NULL)
    {
        ReportError(CE_Failure, CPLE_AppDefined,
            "Could not read metadata index.");
        return CE_Failure;
    }

    NullBuffer(pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace);

    if( poRDS->bBuildQuadTreeDynamically && !bSameWindowAsOtherBand )
    {
        if( !(poRDS->LoadSources(nXOff, nYOff, nXSize, nYSize, nBand)) )
            return CE_Failure;
    }

    // Matching sources, to avoid a dumb for loop over the sources
    PostGISRasterTileDataset ** papsMatchingTiles =
        (PostGISRasterTileDataset **)
            CPLQuadTreeSearch(poRDS->hQuadTree, &sAoi, &nFeatureCount);

    // No blocks found. This is not an error (the raster may have holes)
    if (nFeatureCount == 0) {
        CPLFree(papsMatchingTiles);

        return CE_None;
    }

    int i;

    /**
     * We need to store the max, min coords for the missing tiles in
     * any place. This is as good as any other
     **/
    sAoi.minx = 0.0;
    sAoi.miny = 0.0;
    sAoi.maxx = 0.0;
    sAoi.maxy = 0.0;

    GIntBig nMemoryRequiredForTiles = 0;
    CPLString osIDsToFetch;
    int nTilesToFetch = 0;
    int nBandDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;

    // Loop just over the intersecting sources
    for(i = 0; i < nFeatureCount; i++) {
        PostGISRasterTileDataset *poTile = papsMatchingTiles[i];
        PostGISRasterTileRasterBand* poTileBand =
            (PostGISRasterTileRasterBand *)poTile->GetRasterBand(nBand);

        nMemoryRequiredForTiles += poTileBand->GetXSize() * poTileBand->GetYSize() *
            nBandDataTypeSize;

        // Missing tile: we'll need to query for it
        if (!poTileBand->IsCached()) {

            // If we have a PKID, add the tile PKID to the list
            if (poTile->pszPKID != NULL)
            {
                if( osIDsToFetch.size() != 0 )
                    osIDsToFetch += ",";
                osIDsToFetch += "'";
                osIDsToFetch += poTile->pszPKID;
                osIDsToFetch += "'";
            }

            double dfTileMinX, dfTileMinY, dfTileMaxX, dfTileMaxY;
            poTile->GetExtent(&dfTileMinX, &dfTileMinY,
                              &dfTileMaxX, &dfTileMaxY);

            /**
             * We keep the general max and min values of all the missing
             * tiles, to raise a query that intersect just that area.
             *
             * TODO: In case of just a few tiles and very separated,
             * this strategy is clearly suboptimal. We'll get our
             * missing tiles, but with a lot of other not needed tiles.
             *
             * A possible optimization will be to simply rely on the
             * I/O method of the source (must be implemented), in case
             * we have minus than a reasonable amount of tiles missing.
             * Another criteria to decide would be how separated the
             * tiles are. Two queries for just two adjacent tiles is
             * also a dumb strategy.
             **/
            if( nTilesToFetch == 0 )
            {
                sAoi.minx = dfTileMinX;
                sAoi.miny = dfTileMinY;
                sAoi.maxx = dfTileMaxX;
                sAoi.maxy = dfTileMaxY;
            }
            else
            {
                if (dfTileMinX < sAoi.minx)
                    sAoi.minx = dfTileMinX;

                if (dfTileMinY < sAoi.miny)
                    sAoi.miny = dfTileMinY;

                if (dfTileMaxX > sAoi.maxx)
                    sAoi.maxx = dfTileMaxX;

                if (dfTileMaxY > sAoi.maxy)
                    sAoi.maxy = dfTileMaxY;
            }

            nTilesToFetch ++;

        }
    }

    /* Determine caching strategy */
    int bAllBandCaching = FALSE;
    if (nTilesToFetch > 0)
    {
        GIntBig nCacheMax = (GIntBig) GDALGetCacheMax64();
        if( nMemoryRequiredForTiles > nCacheMax )
        {
            CPLDebug("PostGIS_Raster",
                    "For best performance, the block cache should be able to store " CPL_FRMT_GIB
                    " bytes for the tiles of the requested window, "
                    "but it is only " CPL_FRMT_GIB " byte large",
                    nMemoryRequiredForTiles, nCacheMax );
            nTilesToFetch = 0;
        }

        if( poRDS->GetRasterCount() > 1 && poRDS->bAssumeMultiBandReadPattern )
        {
            GIntBig nMemoryRequiredForTilesAllBands =
                nMemoryRequiredForTiles * poRDS->GetRasterCount();
            if( nMemoryRequiredForTilesAllBands <= nCacheMax )
            {
                bAllBandCaching = TRUE;
            }
            else
            {
                CPLDebug("PostGIS_Raster", "Caching only this band, but not all bands. "
                         "Cache should be " CPL_FRMT_GIB " byte large for that",
                         nMemoryRequiredForTilesAllBands);
            }
        }
    }

    // Raise a query for missing tiles and cache them
    if (nTilesToFetch > 0) {

        /**
         * There are several options here, to raise the query.
         * - Get all the tiles which PKID is in a list of missing
         *   PKIDs.
         * - Get all the tiles that intersect a polygon constructed
         *   based on the (min - max) values calculated before.
         * - Get all the tiles with upper left pixel included in the
         *   range (min - max) calculated before.
         *
         * The first option is the most efficient one when a PKID exists.
         * After that, the second one is the most efficient one when a
         * spatial index exists.
         * The third one is the only one available when neither a PKID or spatial
         * index exist.
         **/
        CPLString osCommand;
        PGresult * poResult;

        CPLString osRasterToFetch;
        if (bAllBandCaching)
            osRasterToFetch = pszColumn;
        else
            osRasterToFetch.Printf("ST_Band(%s, %d)", pszColumn, nBand);

        int bHasWhere = FALSE;
        if (osIDsToFetch.size() && (poRDS->bIsFastPK || !(poRDS->HasSpatialIndex())) ) {
            osCommand.Printf("SELECT %s, "
                "ST_Metadata(%s), %s FROM %s.%s",
                osRasterToFetch.c_str(), pszColumn,
                poRDS->GetPrimaryKeyRef(), pszSchema, pszTable);
            if( nTilesToFetch < poRDS->nTiles || poRDS->bBuildQuadTreeDynamically )
            {
                bHasWhere = TRUE;
                osCommand += " WHERE ";
                osCommand += poRDS->pszPrimaryKeyName;
                osCommand += " IN (";
                osCommand += osIDsToFetch;
                osCommand += ")";
            }
        }

        else {
            CPLLocaleC oCLocale; // Force C locale to avoid commas instead of decimal points (for QGIS e.g.)
            bHasWhere = TRUE;
            osCommand.Printf("SELECT %s, ST_Metadata(%s), %s FROM %s.%s WHERE ",
                             osRasterToFetch.c_str(), pszColumn,
                             (poRDS->GetPrimaryKeyRef()) ? poRDS->GetPrimaryKeyRef() : "'foo'",
                             pszSchema, pszTable);
            if( poRDS->HasSpatialIndex() )
            {
                osCommand += CPLSPrintf("%s && "
                        "ST_GeomFromText('POLYGON((%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f))')",
                        pszColumn,
                        adfProjWin[0], adfProjWin[1],
                        adfProjWin[2], adfProjWin[3],
                        adfProjWin[4], adfProjWin[5],
                        adfProjWin[6], adfProjWin[7],
                        adfProjWin[0], adfProjWin[1]);
            }
            else
            {
                #define EPS 1e-5
                osCommand += CPLSPrintf("ST_UpperLeftX(%s)"
                    " BETWEEN %f AND %f AND ST_UpperLeftY(%s) BETWEEN "
                    "%f AND %f", pszColumn, sAoi.minx-EPS, sAoi.maxx+EPS,
                    pszColumn, sAoi.miny-EPS, sAoi.maxy+EPS);
            }
        }

        if( poRDS->pszWhere != NULL )
        {
            if( bHasWhere )
                osCommand += " AND (";
            else
                osCommand += " WHERE (";
            osCommand += poRDS->pszWhere;
            osCommand += ")";
        }

        poResult = PQexec(poRDS->poConn, osCommand.c_str());

#ifdef DEBUG_QUERY
        CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IRasterIO(): Query = \"%s\" --> number of rows = %d",
            osCommand.c_str(), poResult ? PQntuples(poResult) : 0 );
#endif

        if (poResult == NULL ||
            PQresultStatus(poResult) != PGRES_TUPLES_OK ||
            PQntuples(poResult) < 0) {

            if (poResult)
                PQclear(poResult);

            CPLError(CE_Failure, CPLE_AppDefined,
                "PostGISRasterRasterBand::IRasterIO(): %s",
                PQerrorMessage(poRDS->poConn));

            // Free the object that holds pointers to matching tiles
            CPLFree(papsMatchingTiles);
            return CE_Failure;
        }

        /**
         * No data. Return the buffer filled with nodata values
         **/
        else if (PQntuples(poResult) == 0) {
            PQclear(poResult);

            // Free the object that holds pointers to matching tiles
            CPLFree(papsMatchingTiles);
            return CE_None;
        }

        /**
         * Ok, we loop over the results
         **/
        int nTuples = PQntuples(poResult);
        for(i = 0; i < nTuples; i++)
        {
            const char* pszMetadata = PQgetvalue(poResult, i, 1);
            const char* pszRaster = PQgetvalue(poResult, i, 0);
            const char *pszPKID = (poRDS->GetPrimaryKeyRef() != NULL) ?  PQgetvalue(poResult, i, 2) : NULL;
            poRDS->CacheTile(pszMetadata, pszRaster, pszPKID, nBand, bAllBandCaching);
        } // All tiles have been added to cache

        PQclear(poResult);
    } // End missing tiles

/* -------------------------------------------------------------------- */
/*      Overlay each source in turn over top this.                      */
/* -------------------------------------------------------------------- */

    CPLErr eErr = CE_None;
    /* Sort tiles by ascending PKID, so that the draw order is determinist */
    if( poRDS->GetPrimaryKeyRef() != NULL )
    {
        qsort(papsMatchingTiles, nFeatureCount, sizeof(PostGISRasterTileDataset*),
              SortTilesByPKID);
    }

    for(i = 0; i < nFeatureCount && eErr == CE_None; i++)
    {
        PostGISRasterTileDataset *poTile = papsMatchingTiles[i];
        PostGISRasterTileRasterBand* poTileBand =
            (PostGISRasterTileRasterBand *)poTile->GetRasterBand(nBand);
        eErr =
            poTileBand->poSource->RasterIO( nXOff, nYOff, nXSize, nYSize,
                                            pData, nBufXSize, nBufYSize,
                                            eBufType, nPixelSpace, nLineSpace);
    }

    // Free the object that holds pointers to matching tiles
    CPLFree(papsMatchingTiles);

    return eErr;

}
Example #5
0
void OGRDXFDataSource::ReadHeaderSection()

{
    char szLineBuf[257];
    int  nCode;

    while( (nCode = ReadValue( szLineBuf, sizeof(szLineBuf) )) > -1 
           && !EQUAL(szLineBuf,"ENDSEC") )
    {
        if( nCode != 9 )
            continue;

        CPLString osName = szLineBuf;

        ReadValue( szLineBuf, sizeof(szLineBuf) );

        CPLString osValue = szLineBuf;

        oHeaderVariables[osName] = osValue;
    }

    if (nCode != -1)
    {
        nCode = ReadValue( szLineBuf, sizeof(szLineBuf) );
        UnreadValue();
    }

    /* Unusual DXF files produced by dxflib */
    /* such as http://www.ribbonsoft.com/library/architecture/plants/decd5.dxf */
    /* where there is a spurious ENDSEC in the middle of the header variables */
    if (nCode == 9 && EQUALN(szLineBuf,"$", 1) )
    {
        while( (nCode = ReadValue( szLineBuf, sizeof(szLineBuf) )) > -1
            && !EQUAL(szLineBuf,"ENDSEC") )
        {
            if( nCode != 9 )
                continue;

            CPLString osName = szLineBuf;

            ReadValue( szLineBuf, sizeof(szLineBuf) );

            CPLString osValue = szLineBuf;

            oHeaderVariables[osName] = osValue;
        }
    }

    CPLDebug( "DXF", "Read %d header variables.", 
              (int) oHeaderVariables.size() );

/* -------------------------------------------------------------------- */
/*      Decide on what CPLRecode() name to use for the files            */
/*      encoding or allow the encoding to be overridden.                */
/* -------------------------------------------------------------------- */
    CPLString osCodepage = GetVariable( "$DWGCODEPAGE", "ANSI_1252" );

    // not strictly accurate but works even without iconv.
    if( osCodepage == "ANSI_1252" )
        osEncoding = CPL_ENC_ISO8859_1; 
    else if( EQUALN(osCodepage,"ANSI_",5) )
    {
        osEncoding = "CP";
        osEncoding += osCodepage + 5;
    }
    else
    {
        // fallback to the default 
        osEncoding = CPL_ENC_ISO8859_1;
    }
                                       
    if( CPLGetConfigOption( "DXF_ENCODING", NULL ) != NULL )
        osEncoding = CPLGetConfigOption( "DXF_ENCODING", NULL );

    if( osEncoding != CPL_ENC_ISO8859_1 )
        CPLDebug( "DXF", "Treating DXF as encoding '%s', $DWGCODEPAGE='%s'", 
                  osEncoding.c_str(), osCodepage.c_str() );
}
Example #6
0
OGRErr OGRGFTTableLayer::ICreateFeature( OGRFeature *poFeature )

{
    if (!poDS->IsReadWrite())
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Operation not available in read-only mode");
        return OGRERR_FAILURE;
    }

    if (osTableId.size() == 0)
    {
        CreateTableIfNecessary();
        if (osTableId.size() == 0)
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "Cannot add feature to non-created table");
            return OGRERR_FAILURE;
        }
    }

    if (poDS->GetAccessToken().size() == 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Operation not available in unauthenticated mode");
        return OGRERR_FAILURE;
    }

    CPLString      osCommand;

    osCommand += "INSERT INTO ";
    osCommand += osTableId;
    osCommand += " (";

    int iField;
    int nFieldCount = poFeatureDefn->GetFieldCount();
    for(iField = 0; iField < nFieldCount; iField++)
    {
        if (iField > 0)
            osCommand += ", ";

        const char* pszFieldName =
            poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
        osCommand += EscapeAndQuote(pszFieldName);
    }
    if (bHiddenGeometryField)
    {
        if (iField > 0)
            osCommand += ", ";
        osCommand += EscapeAndQuote(GetGeometryColumn());
    }
    osCommand += ") VALUES (";
    for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++)
    {
        if (iField > 0)
            osCommand += ", ";

        OGRGeometry* poGeom = poFeature->GetGeometryRef();
        /* If there's a geometry, let's use it in priority over the textual */
        /* content of the field. */
        if (iGeometryField != iLatitudeField && iField == iGeometryField &&
            (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField )))
        {
            if (poGeom == NULL)
                osCommand += "''";
            else
            {
                char* pszKML;
                if (poGeom->getSpatialReference() != NULL &&
                    !poGeom->getSpatialReference()->IsSame(poSRS))
                {
                    OGRGeometry* poGeom4326 = poGeom->clone();
                    poGeom4326->transformTo(poSRS);
                    pszKML = poGeom4326->exportToKML();
                    delete poGeom4326;
                }
                else
                {
                    pszKML = poGeom->exportToKML();
                }
                osCommand += "'";
                osCommand += pszKML;
                osCommand += "'";
                CPLFree(pszKML);
            }
            continue;
        }

        if( !poFeature->IsFieldSet( iField ) )
        {
            osCommand += "''";
        }
        else
        {
            OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType();
            if (eType != OFTInteger && eType != OFTReal)
            {
                CPLString osTmp;
                const char* pszVal = poFeature->GetFieldAsString(iField);

                if (!CPLIsUTF8(pszVal, -1))
                {
                    static int bFirstTime = TRUE;
                    if (bFirstTime)
                    {
                        bFirstTime = FALSE;
                        CPLError(CE_Warning, CPLE_AppDefined,
                                "%s is not a valid UTF-8 string. Forcing it to ASCII.\n"
                                "This warning won't be issued anymore", pszVal);
                    }
                    else
                    {
                        CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII",
                                pszVal);
                    }
                    char* pszEscaped = CPLForceToASCII(pszVal, -1, '?');
                    osTmp = pszEscaped;
                    CPLFree(pszEscaped);
                    pszVal = osTmp.c_str();
                }

                osCommand += EscapeAndQuote(pszVal);
            }
            else
                osCommand += poFeature->GetFieldAsString(iField);
        }
    }

    osCommand += ")";

    //CPLDebug("GFT", "%s",  osCommand.c_str());

    if (bInTransaction)
    {
        nFeaturesInTransaction ++;
        if (nFeaturesInTransaction > 1)
            osTransaction += "; ";
        osTransaction += osCommand;
        return OGRERR_NONE;
    }

    CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
    if (psResult == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
        return OGRERR_FAILURE;
    }

    char* pszLine = (char*) psResult->pabyData;
    if (pszLine == NULL ||
        strncmp(pszLine, "rowid", 5) != 0 ||
        psResult->pszErrBuf != NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
        CPLHTTPDestroyResult(psResult);
        return OGRERR_FAILURE;
    }

    pszLine = OGRGFTGotoNextLine(pszLine);
    if (pszLine == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
        CPLHTTPDestroyResult(psResult);
        return OGRERR_FAILURE;
    }

    char* pszNextLine = OGRGFTGotoNextLine(pszLine);
    if (pszNextLine)
        pszNextLine[-1] = 0;

    CPLDebug("GFT", "Feature id = %s",  pszLine);

    int nFID = atoi(pszLine);
    if (strcmp(CPLSPrintf("%d", nFID), pszLine) == 0)
        poFeature->SetFID(nFID);

    CPLHTTPDestroyResult(psResult);

    return OGRERR_NONE;
}
/*****************************************************
 * \brief Read a natural block of raster band data
 *****************************************************/
CPLErr PostGISRasterRasterBand::IReadBlock(int nBlockXOff,
        int nBlockYOff, void * pImage)
{
    PGresult * poResult = NULL;
    CPLString osCommand;
    int nXOff = 0;
    int nYOff = 0;
    int nNaturalBlockXSize = 0;
    int nNaturalBlockYSize = 0;
    double adfProjWin[8];
    PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS;

    int nPixelSize = GDALGetDataTypeSize(eDataType) / 8;

    // Construct a polygon to intersect with
    GetBlockSize(&nNaturalBlockXSize, &nNaturalBlockYSize);

    nXOff = nBlockXOff * nNaturalBlockXSize;
    nYOff = nBlockYOff * nNaturalBlockYSize;

    poRDS->PolygonFromCoords(nXOff, nYOff, nXOff + nNaturalBlockXSize, nYOff + nNaturalBlockYSize, adfProjWin);

    // Raise the query
    if (poRDS->pszWhere == NULL) {
        osCommand.Printf("SELECT st_band(%s, %d) FROM %s.%s "
            "WHERE st_intersects(%s, ST_PolygonFromText"
            "('POLYGON((%.17f %.17f, %.17f %.17f, %.17f %.17f, %.17f "
            "%.17f, %.17f %.17f))', %d))", pszColumn, nBand, pszSchema,
            pszTable, pszColumn, adfProjWin[0], adfProjWin[1],
            adfProjWin[2], adfProjWin[3],  adfProjWin[4], adfProjWin[5],
            adfProjWin[6], adfProjWin[7], adfProjWin[0], adfProjWin[1],
            poRDS->nSrid);
    }

    else {
        osCommand.Printf("SELECT st_band(%s, %d) FROM %s.%s WHERE (%s) "
            "AND st_intersects(%s, ST_PolygonFromText"
            "('POLYGON((%.17f %.17f, %.17f %.17f, %.17f %.17f, %.17f "
            "%.17f, %.17f %.17f))', %d))", pszColumn, nBand, pszSchema,
            pszTable, poRDS->pszWhere, pszColumn, adfProjWin[0],
            adfProjWin[1], adfProjWin[2], adfProjWin[3], adfProjWin[4],
            adfProjWin[5], adfProjWin[6], adfProjWin[7], adfProjWin[0],
            adfProjWin[1], poRDS->nSrid);
    }

#ifdef DEBUG_QUERY
    CPLDebug("PostGIS_Raster",
        "PostGISRasterRasterBand::IReadBlock(): Query = %s",
            osCommand.c_str());
#endif

    poResult = PQexec(poRDS->poConn, osCommand.c_str());
    if (poResult == NULL ||
        PQresultStatus(poResult) != PGRES_TUPLES_OK ||
        PQntuples(poResult) < 0) {

        if (poResult)
            PQclear(poResult);

        ReportError(CE_Failure, CPLE_AppDefined,
            "Error retrieving raster data FROM database");

        CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IRasterIO(): %s",
                PQerrorMessage(poRDS->poConn));

        return CE_Failure;
    }

    /**
     * No data. Return the buffer filled with nodata values
     **/
    else if (PQntuples(poResult) == 0) {
        PQclear(poResult);

        CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IRasterIO(): Null block");

        NullBlock(pImage);

        return CE_None;
    }


    /**
     * Ok, we get the data. Only data size, without payload
     *
     * TODO: Check byte order
     **/
    int nExpectedDataSize = nNaturalBlockXSize * nNaturalBlockYSize *
        nPixelSize;

    int nWKBLength = 0;

    GByte * pbyData = CPLHexToBinary(PQgetvalue(poResult, 0, 0),
        &nWKBLength);

    char * pbyDataToRead = (char*)GET_BAND_DATA(pbyData,nBand,
            nPixelSize, nExpectedDataSize);

    memcpy(pImage, pbyDataToRead, nExpectedDataSize * sizeof(char));

    CPLDebug("PostGIS_Raster", "IReadBlock: Copied %d bytes FROM block "
            "(%d, %d) to %p", nExpectedDataSize, nBlockXOff,
            nBlockYOff, pImage);

    CPLFree(pbyData);
    PQclear(poResult);

    return CE_None;
}
void GDALPamProxyDB::SaveDB()

{
/* -------------------------------------------------------------------- */
/*      Open the database relating original names to proxy .aux.xml     */
/*      file names.                                                     */
/* -------------------------------------------------------------------- */
    CPLString osDBName = 
        CPLFormFilename( osProxyDBDir, "gdal_pam_proxy", "dat" );
    
    void *hLock = CPLLockFile( osDBName, 1.0 );

    // proceed even if lock fails - we need CPLBreakLockFile()!
    if( hLock == NULL )
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "GDALPamProxyDB::SaveDB() - Failed to lock %s file, proceeding anyways.",
                  osDBName.c_str() );
    }

    FILE *fpDB = VSIFOpenL( osDBName, "w" );
    if( fpDB == NULL )
    {
        if( hLock )
            CPLUnlockFile( hLock );
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to save %s Pam Proxy DB.\n%s", 
                  osDBName.c_str(), 
                  VSIStrerror( errno ) );
        return;
    }

/* -------------------------------------------------------------------- */
/*      Write header.                                                   */
/* -------------------------------------------------------------------- */
    GByte  abyHeader[100];

    memset( abyHeader, ' ', sizeof(abyHeader) );
    strncpy( (char *) abyHeader, "GDAL_PROXY", 10 );
    sprintf( (char *) abyHeader + 10, "%9d", nUpdateCounter );

    VSIFWriteL( abyHeader, 1, 100, fpDB );

/* -------------------------------------------------------------------- */
/*      Write names.                                                    */
/* -------------------------------------------------------------------- */
    unsigned int i;

    for( i = 0; i < aosOriginalFiles.size(); i++ )
    {
        size_t nBytesWritten;
        const char *pszProxyFile;

        VSIFWriteL( aosOriginalFiles[i].c_str(), 1, 
                    strlen(aosOriginalFiles[i].c_str())+1, fpDB );

        pszProxyFile = CPLGetFilename(aosProxyFiles[i]);
        nBytesWritten = VSIFWriteL( pszProxyFile, 1, 
                                    strlen(pszProxyFile)+1, fpDB );

        if( nBytesWritten != strlen(pszProxyFile)+1 )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "Failed to write complete %s Pam Proxy DB.\n%s",
                      osDBName.c_str(), 
                      VSIStrerror( errno ) );
            VSIFCloseL( fpDB );
            VSIUnlink( osDBName );
            return;
        }
    }

    VSIFCloseL( fpDB );

    if( hLock )
        CPLUnlockFile( hLock );
}
void GDALPamProxyDB::LoadDB()

{
/* -------------------------------------------------------------------- */
/*      Open the database relating original names to proxy .aux.xml     */
/*      file names.                                                     */
/* -------------------------------------------------------------------- */
    CPLString osDBName = 
        CPLFormFilename( osProxyDBDir, "gdal_pam_proxy", "dat" );
    FILE *fpDB = VSIFOpenL( osDBName, "r" );

    nUpdateCounter = 0;
    if( fpDB == NULL )
        return;

/* -------------------------------------------------------------------- */
/*      Read header, verify and extract update counter.                 */
/* -------------------------------------------------------------------- */
    GByte  abyHeader[100];

    if( VSIFReadL( abyHeader, 1, 100, fpDB ) != 100 
        || strncmp( (const char *) abyHeader, "GDAL_PROXY", 10 ) != 0 )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Problem reading %s header - short or corrupt?", 
                  osDBName.c_str() );
        return;
    }

    nUpdateCounter = atoi((const char *) abyHeader + 10);

/* -------------------------------------------------------------------- */
/*      Read the file in one gulp.                                      */
/* -------------------------------------------------------------------- */
    int nBufLength;
    char *pszDBData;

    VSIFSeekL( fpDB, 0, SEEK_END );
    nBufLength = (int) (VSIFTellL(fpDB) - 100);

    pszDBData = (char *) CPLCalloc(1,nBufLength+1);
    VSIFSeekL( fpDB, 100, SEEK_SET );
    VSIFReadL( pszDBData, 1, nBufLength, fpDB );

    VSIFCloseL( fpDB );

/* -------------------------------------------------------------------- */
/*      Parse the list of in/out names.                                 */
/* -------------------------------------------------------------------- */
    int iNext = 0;

    while( iNext < nBufLength )
    {
        CPLString osOriginal, osProxy;

        osOriginal.assign( pszDBData + iNext );

        for( ; iNext < nBufLength && pszDBData[iNext] != '\0'; iNext++ ) {}
        
        if( iNext == nBufLength )
            break;
        
        iNext++;

        osProxy = osProxyDBDir;
        osProxy += "/";
        osProxy += pszDBData + iNext;

        for( ; iNext < nBufLength && pszDBData[iNext] != '\0'; iNext++ ) {}
        iNext++;

        aosOriginalFiles.push_back( osOriginal );
        aosProxyFiles.push_back( osProxy );
    }        

    CPLFree( pszDBData );
}
OGRErr OGRSQLiteTableLayer::CreateField( OGRFieldDefn *poFieldIn, 
                                         int bApproxOK )

{
    OGRFieldDefn        oField( poFieldIn );

    ResetReading();

    if (!poDS->GetUpdate())
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Can't create fields on a read-only layer.");
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Do we want to "launder" the column names into SQLite            */
/*      friendly format?                                                */
/* -------------------------------------------------------------------- */
    if( bLaunderColumnNames )
    {
        char    *pszSafeName = poDS->LaunderName( oField.GetNameRef() );

        oField.SetName( pszSafeName );
        CPLFree( pszSafeName );
    }

/* -------------------------------------------------------------------- */
/*      How much space do we need for the list of fields.               */
/* -------------------------------------------------------------------- */
    int iField, nFieldListLen = 100;
    char *pszOldFieldList, *pszNewFieldList;

    for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
    {
        nFieldListLen += 
            strlen(poFeatureDefn->GetFieldDefn(iField)->GetNameRef()) + 50;
    }

    nFieldListLen += strlen( oField.GetNameRef() );

    pszOldFieldList = (char *) CPLCalloc(1,nFieldListLen);
    pszNewFieldList = (char *) CPLCalloc(1,nFieldListLen);

/* -------------------------------------------------------------------- */
/*      Build list of old fields, and the list of new fields.           */
/* -------------------------------------------------------------------- */
    const char *pszType;
    sprintf( pszOldFieldList, "%s", "OGC_FID" );
    sprintf( pszNewFieldList, "%s", "OGC_FID INTEGER PRIMARY KEY" );
    
    int iNextOrdinal = 3; /* _rowid_ is 1, OGC_FID is 2 */

    if( poFeatureDefn->GetGeomType() != wkbNone )
    {
        strcat( pszOldFieldList, "," );
        strcat( pszNewFieldList, "," );

        strcat( pszOldFieldList, osGeomColumn );
        strcat( pszNewFieldList, osGeomColumn );

        if ( eGeomFormat == OSGF_WKT )
            strcat( pszNewFieldList, " VARCHAR" );
        else
            strcat( pszNewFieldList, " BLOB" );

        iNextOrdinal++;
    }

    for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
    {
        OGRFieldDefn *poFldDefn = poFeatureDefn->GetFieldDefn(iField);

        // we already added OGC_FID so don't do it again
        if( EQUAL(poFldDefn->GetNameRef(),"OGC_FID") )
            continue;

        if( poFldDefn->GetType() == OFTInteger )
            pszType = "INTEGER";
        else if( poFldDefn->GetType() == OFTReal )
            pszType = "FLOAT";
        else if( poFldDefn->GetType() == OFTBinary )
            pszType = "BLOB";
        else
            pszType = "VARCHAR";
        
        sprintf( pszOldFieldList+strlen(pszOldFieldList), 
                 ", '%s'", poFldDefn->GetNameRef() );

        sprintf( pszNewFieldList+strlen(pszNewFieldList), 
                 ", '%s' %s", poFldDefn->GetNameRef(), pszType );

        iNextOrdinal++;
    }

/* -------------------------------------------------------------------- */
/*      Add the new field.                                              */
/* -------------------------------------------------------------------- */
    if( oField.GetType() == OFTInteger )
        pszType = "INTEGER";
    else if( oField.GetType() == OFTReal )
        pszType = "FLOAT";
    else if( oField.GetType() == OFTBinary )
        pszType = "BLOB";
    else
        pszType = "VARCHAR";
    
    sprintf( pszNewFieldList+strlen(pszNewFieldList), 
             ", '%s' %s", oField.GetNameRef(), pszType );

/* ==================================================================== */
/*      Backup, destroy, recreate and repopulate the table.  SQLite     */
/*      has no ALTER TABLE so we have to do all this to add a           */
/*      column.                                                         */
/* ==================================================================== */

/* -------------------------------------------------------------------- */
/*      Do this all in a transaction.                                   */
/* -------------------------------------------------------------------- */
    poDS->SoftStartTransaction();

/* -------------------------------------------------------------------- */
/*      Save existing related triggers and index                        */
/* -------------------------------------------------------------------- */
    int rc;
    char *pszErrMsg = NULL;
    sqlite3 *hDB = poDS->GetDB();
    CPLString osSQL;

    osSQL.Printf( "SELECT sql FROM sqlite_master WHERE type IN ('trigger','index') AND tbl_name='%s'",
                   pszEscapedTableName );

    int nRowTriggerIndexCount, nColTriggerIndexCount;
    char **papszTriggerIndexResult = NULL;
    rc = sqlite3_get_table( hDB, osSQL.c_str(), &papszTriggerIndexResult, 
                            &nRowTriggerIndexCount, &nColTriggerIndexCount, &pszErrMsg );

/* -------------------------------------------------------------------- */
/*      Make a backup of the table.                                     */
/* -------------------------------------------------------------------- */

    if( rc == SQLITE_OK )
        rc = sqlite3_exec( hDB, 
                       CPLSPrintf( "CREATE TEMPORARY TABLE t1_back(%s)",
                                   pszOldFieldList ),
                       NULL, NULL, &pszErrMsg );

    if( rc == SQLITE_OK )
        rc = sqlite3_exec( hDB, 
                           CPLSPrintf( "INSERT INTO t1_back SELECT %s FROM '%s'",
                                       pszOldFieldList, 
                                       pszEscapedTableName ),
                           NULL, NULL, &pszErrMsg );


/* -------------------------------------------------------------------- */
/*      Drop the original table, and recreate with new field.           */
/* -------------------------------------------------------------------- */
    if( rc == SQLITE_OK )
        rc = sqlite3_exec( hDB, 
                           CPLSPrintf( "DROP TABLE '%s'", 
                                       pszEscapedTableName ),
                           NULL, NULL, &pszErrMsg );

    if( rc == SQLITE_OK )
    {
        const char *pszCmd = 
            CPLSPrintf( "CREATE TABLE '%s' (%s)", 
                        pszEscapedTableName,
                        pszNewFieldList );
        rc = sqlite3_exec( hDB, pszCmd, 
                           NULL, NULL, &pszErrMsg );

        CPLDebug( "OGR_SQLITE", "exec(%s)", pszCmd );
    }

/* -------------------------------------------------------------------- */
/*      Copy backup field values into new table.                        */
/* -------------------------------------------------------------------- */
    
    if( rc == SQLITE_OK )
        rc = sqlite3_exec( hDB, 
                           CPLSPrintf( "INSERT INTO '%s' SELECT %s, NULL FROM t1_back",
                                       pszEscapedTableName,
                                       pszOldFieldList ),
                           NULL, NULL, &pszErrMsg );

    CPLFree( pszOldFieldList );
    CPLFree( pszNewFieldList );

/* -------------------------------------------------------------------- */
/*      Cleanup backup table.                                           */
/* -------------------------------------------------------------------- */
    
    if( rc == SQLITE_OK )
        rc = sqlite3_exec( hDB, 
                           CPLSPrintf( "DROP TABLE t1_back" ),
                           NULL, NULL, &pszErrMsg );

/* -------------------------------------------------------------------- */
/*      Recreate existing related tables, triggers and index            */
/* -------------------------------------------------------------------- */

    if( rc == SQLITE_OK )
    {
        int i;

        for(i = 1; i <= nRowTriggerIndexCount && nColTriggerIndexCount == 1 && rc == SQLITE_OK; i++)
        {
            if (papszTriggerIndexResult[i] != NULL && papszTriggerIndexResult[i][0] != '\0')
                rc = sqlite3_exec( hDB, 
                            papszTriggerIndexResult[i],
                            NULL, NULL, &pszErrMsg );
        }
    }

/* -------------------------------------------------------------------- */
/*      COMMIT on success or ROLLBACK on failuire.                      */
/* -------------------------------------------------------------------- */

    sqlite3_free_table( papszTriggerIndexResult );

    if( rc == SQLITE_OK )
    {
        poDS->SoftCommit();
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Failed to add field %s to table %s:\n %s",
                  oField.GetNameRef(), poFeatureDefn->GetName(), 
                  pszErrMsg );
        sqlite3_free( pszErrMsg );

        poDS->SoftRollback();

        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Add the field to the OGRFeatureDefn.                            */
/* -------------------------------------------------------------------- */
    int iNewField;

    poFeatureDefn->AddFieldDefn( &oField );

    iNewField = poFeatureDefn->GetFieldCount() - 1;
    panFieldOrdinals = (int *) 
        CPLRealloc(panFieldOrdinals, (iNewField+1) * sizeof(int) );
    panFieldOrdinals[iNewField] = iNextOrdinal;

    return OGRERR_NONE;
}
OGRErr OGRSQLiteTableLayer::CreateFeature( OGRFeature *poFeature )

{
    sqlite3 *hDB = poDS->GetDB();
    CPLString      osCommand;
    CPLString      osValues;
    int            bNeedComma = FALSE;

    if (bSpatialiteReadOnly || !poDS->GetUpdate())
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Can't create feature on a read-only layer.");
        return OGRERR_FAILURE;
    }

    ResetReading();

/* -------------------------------------------------------------------- */
/*      Form the INSERT command.                                        */
/* -------------------------------------------------------------------- */
    osCommand += CPLSPrintf( "INSERT INTO '%s' (", pszEscapedTableName );

/* -------------------------------------------------------------------- */
/*      Add FID if we have a cleartext FID column.                      */
/* -------------------------------------------------------------------- */
    if( pszFIDColumn != NULL // && !EQUAL(pszFIDColumn,"OGC_FID") 
        && poFeature->GetFID() != OGRNullFID )
    {
        osCommand += pszFIDColumn;

        osValues += CPLSPrintf( "%ld", poFeature->GetFID() );
        bNeedComma = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Add geometry.                                                   */
/* -------------------------------------------------------------------- */
    OGRGeometry *poGeom = poFeature->GetGeometryRef();

    if( osGeomColumn.size() != 0 &&
        poGeom != NULL &&
        eGeomFormat != OSGF_FGF )
    {

        if( bNeedComma )
        {
            osCommand += ",";
            osValues += ",";
        }

        osCommand += osGeomColumn;

        osValues += "?";

        bNeedComma = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Add field values.                                               */
/* -------------------------------------------------------------------- */
    int iField;
    int nFieldCount = poFeatureDefn->GetFieldCount();

    for( iField = 0; iField < nFieldCount; iField++ )
    {
        if( !poFeature->IsFieldSet( iField ) )
            continue;

        if( bNeedComma )
        {
            osCommand += ",";
            osValues += ",";
        }

        osCommand += "'";
        osCommand +=poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
        osCommand += "'";

        osValues += "?";

        bNeedComma = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Merge final command.                                            */
/* -------------------------------------------------------------------- */
    osCommand += ") VALUES (";
    osCommand += osValues;
    osCommand += ")";

/* -------------------------------------------------------------------- */
/*      Prepare the statement.                                          */
/* -------------------------------------------------------------------- */
    int rc;
    sqlite3_stmt *hInsertStmt;

#ifdef DEBUG
    CPLDebug( "OGR_SQLITE", "prepare(%s)", osCommand.c_str() );
#endif

    rc = sqlite3_prepare( hDB, osCommand, -1, &hInsertStmt, NULL );
    if( rc != SQLITE_OK )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "In CreateFeature(): sqlite3_prepare(%s):\n  %s", 
                  osCommand.c_str(), sqlite3_errmsg(hDB) );

        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Bind the geometry                                               */
/* -------------------------------------------------------------------- */
    int nBindField = 1;

    if( osGeomColumn.size() != 0 &&
        poGeom != NULL &&
        eGeomFormat != OSGF_FGF )
    {
        if ( eGeomFormat == OSGF_WKT )
        {
            char *pszWKT = NULL;
            poGeom->exportToWkt( &pszWKT );
            rc = sqlite3_bind_text( hInsertStmt, nBindField++, pszWKT, -1, CPLFree );
        }
        else if( eGeomFormat == OSGF_WKB )
        {
            int nWKBLen = poGeom->WkbSize();
            GByte *pabyWKB = (GByte *) CPLMalloc(nWKBLen + 1);

            poGeom->exportToWkb( wkbNDR, pabyWKB );
            rc = sqlite3_bind_blob( hInsertStmt, nBindField++, pabyWKB, nWKBLen, CPLFree );
        }
        else if ( eGeomFormat == OSGF_SpatiaLite )
        {
            int     nBLOBLen;
            GByte   *pabySLBLOB;

            ExportSpatiaLiteGeometry( poGeom, nSRSId, wkbNDR, bHasM, 
                                      bSpatialite2D, &pabySLBLOB, &nBLOBLen );
            rc = sqlite3_bind_blob( hInsertStmt, nBindField++, pabySLBLOB,
                                    nBLOBLen, CPLFree );
        }
        else
        {
            CPLAssert(0);
        }

        if( rc != SQLITE_OK )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "sqlite3_bind_blob/text() failed:\n  %s", 
                      sqlite3_errmsg(hDB) );
            
            sqlite3_finalize( hInsertStmt );
            return OGRERR_FAILURE;
        }
    }
    
/* -------------------------------------------------------------------- */
/*      Bind field values.                                              */
/* -------------------------------------------------------------------- */
    
    for( iField = 0; iField < nFieldCount; iField++ )
    {
        const char *pszRawValue;

        if( !poFeature->IsFieldSet( iField ) )
            continue;

        switch( poFeatureDefn->GetFieldDefn(iField)->GetType() )
        {
            case OFTInteger:
            {
                int nFieldVal = poFeature->GetFieldAsInteger( iField );
                rc = sqlite3_bind_int(hInsertStmt, nBindField++, nFieldVal);
                break;
            }
            
            case OFTReal:
            {
                double dfFieldVal = poFeature->GetFieldAsDouble( iField );
                rc = sqlite3_bind_double(hInsertStmt, nBindField++, dfFieldVal);
                break;
            }
            
            case OFTBinary:
            {
                int nDataLength = 0;
                GByte* pabyData =
                    poFeature->GetFieldAsBinary( iField, &nDataLength );
                rc = sqlite3_bind_blob(hInsertStmt, nBindField++,
                                       pabyData, nDataLength, SQLITE_TRANSIENT);
                break;
            }
            
            default:
            {
                pszRawValue = poFeature->GetFieldAsString( iField );
                rc = sqlite3_bind_text(hInsertStmt, nBindField++,
                                       pszRawValue, -1, SQLITE_TRANSIENT);
                break;
            }
        }
        
        if( rc != SQLITE_OK )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "sqlite3_bind_() for column %s failed:\n  %s", 
                      poFeatureDefn->GetFieldDefn(iField)->GetNameRef(),
                      sqlite3_errmsg(hDB) );
            
            sqlite3_finalize( hInsertStmt );
            return OGRERR_FAILURE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Execute the insert.                                             */
/* -------------------------------------------------------------------- */
    rc = sqlite3_step( hInsertStmt );

    if( rc != SQLITE_OK && rc != SQLITE_DONE )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "sqlite3_step() failed:\n  %s", 
                  sqlite3_errmsg(hDB) );
                  
        sqlite3_finalize( hInsertStmt );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Capture the FID/rowid.                                          */
/* -------------------------------------------------------------------- */
    const sqlite_int64 nFID = sqlite3_last_insert_rowid( hDB );
    if(nFID > 0)
    {
        poFeature->SetFID( (long)nFID ); /* Possible truncation if nFID is 64bit */
    }

    sqlite3_finalize( hInsertStmt );

    return OGRERR_NONE;
}
void OGRSQLiteTableLayer::BuildWhere()

{
    osWHERE = "";

    if( m_poFilterGeom != NULL && bHasSpatialIndex )
    {
        OGREnvelope  sEnvelope;

        m_poFilterGeom->getEnvelope( &sEnvelope );

        /* We first check that the spatial index table exists */
        if (!bHasCheckedSpatialIndexTable)
        {
            bHasCheckedSpatialIndexTable = TRUE;
            char **papszResult;
            int nRowCount, nColCount;
            char *pszErrMsg = NULL;

            CPLString osSQL;
            osSQL.Printf("SELECT name FROM sqlite_master "
                        "WHERE name='idx_%s_%s'",
                        pszEscapedTableName, osGeomColumn.c_str());

            int  rc = sqlite3_get_table( poDS->GetDB(), osSQL.c_str(),
                                        &papszResult, &nRowCount,
                                        &nColCount, &pszErrMsg );

            if( rc != SQLITE_OK )
            {
                CPLError( CE_Failure, CPLE_AppDefined, "Error: %s",
                        pszErrMsg );
                sqlite3_free( pszErrMsg );
                bHasSpatialIndex = FALSE;
            }
            else
            {
                if (nRowCount != 1)
                {
                    bHasSpatialIndex = FALSE;
                }

                sqlite3_free_table(papszResult);
            }
        }

        if (bHasSpatialIndex)
        {
            osWHERE.Printf("WHERE ROWID IN ( SELECT pkid FROM 'idx_%s_%s' WHERE "
                           "xmax > %.12f AND xmin < %.12f AND ymax > %.12f AND ymin < %.12f) ",
                            pszEscapedTableName, osGeomColumn.c_str(),
                            sEnvelope.MinX - 1e-11, sEnvelope.MaxX + 1e-11,
                            sEnvelope.MinY - 1e-11, sEnvelope.MaxY + 1e-11);
        }
        else
        {
            CPLDebug("SQLITE", "Count not find idx_%s_%s layer. Disabling spatial index",
                     pszEscapedTableName, osGeomColumn.c_str());
        }

    }

    if( m_poFilterGeom != NULL && bSpatialiteLoaded && !bHasSpatialIndex)
    {
        OGREnvelope  sEnvelope;

        m_poFilterGeom->getEnvelope( &sEnvelope );

        /* A bit inefficient but still faster than OGR filtering */
        osWHERE.Printf("WHERE MBRIntersects(\"%s\", BuildMBR(%.12f, %.12f, %.12f, %.12f, %d)) ",
                       osGeomColumn.c_str(),
                       sEnvelope.MinX - 1e-11, sEnvelope.MinY - 1e-11,
                       sEnvelope.MaxX + 1e-11, sEnvelope.MaxY + 1e-11,
                       nSRSId);
    }

    if( strlen(osQuery) > 0 )
    {
        if( strlen(osWHERE) == 0 )
        {
            osWHERE.Printf( "WHERE %s ", osQuery.c_str()  );
        }
        else	
        {
            osWHERE += "AND ";
            osWHERE += osQuery;
        }
    }
}
Example #13
0
/*!
  \brief Add feature

  \param poDataBlock pointer to VFKDataBlock instance
  \param poFeature pointer to VFKFeature instance
*/
OGRErr VFKReaderSQLite::AddFeature(IVFKDataBlock *poDataBlock, VFKFeature *poFeature)
{
    CPLString     osCommand;
    CPLString     osValue;

    const char   *pszBlockName;

    OGRFieldType  ftype;

    const VFKProperty *poProperty;

    VFKFeatureSQLite *poNewFeature;

    pszBlockName = poDataBlock->GetName();
    osCommand.Printf("INSERT INTO '%s' VALUES(", pszBlockName);

    for (int i = 0; i < poDataBlock->GetPropertyCount(); i++) {
        ftype = poDataBlock->GetProperty(i)->GetType();
        poProperty = poFeature->GetProperty(i);
        if (i > 0)
            osCommand += ",";
        if (poProperty->IsNull())
            osValue.Printf("NULL");
        else {
            switch (ftype) {
            case OFTInteger:
                osValue.Printf("%d", poProperty->GetValueI());
                break;
            case OFTReal:
                osValue.Printf("%f", poProperty->GetValueD());
                break;
            case OFTString:
                if (poDataBlock->GetProperty(i)->IsIntBig())
		    osValue.Printf("%s", poProperty->GetValueS());
                else
                    osValue.Printf("'%s'", poProperty->GetValueS(TRUE));
                break;
            default:
                osValue.Printf("'%s'", poProperty->GetValueS());
                break;
            }
        }
        osCommand += osValue;
    }
    osValue.Printf("," CPL_FRMT_GIB, poFeature->GetFID());
    if (poDataBlock->GetGeometryType() != wkbNone) {
	osValue += ",NULL";
    }
    osValue += ")";
    osCommand += osValue;

    if (ExecuteSQL(osCommand.c_str(), TRUE) != OGRERR_NONE)
        return OGRERR_FAILURE;

    if (EQUAL(pszBlockName, "SBP")) {
        poProperty = poFeature->GetProperty("PORADOVE_CISLO_BODU");
        if( poProperty == NULL )
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Cannot find property PORADOVE_CISLO_BODU");
            return OGRERR_FAILURE;
        }
        if (!EQUAL(poProperty->GetValueS(), "1"))
            return OGRERR_NONE;
    }

    poNewFeature = new VFKFeatureSQLite(poDataBlock, poDataBlock->GetRecordCount(RecordValid) + 1,
                                        poFeature->GetFID());
    poDataBlock->AddFeature(poNewFeature);

    return OGRERR_NONE;
}
Example #14
0
/*!
  \brief VFKReaderSQLite constructor
*/
VFKReaderSQLite::VFKReaderSQLite(const char *pszFilename) : VFKReader(pszFilename)
{
    const char *pszDbNameConf;
    CPLString   osDbName;
    CPLString   osCommand;
    VSIStatBufL sStatBufDb, sStatBufVfk;

    /* open tmp SQLite DB (re-use DB file if already exists) */
    pszDbNameConf = CPLGetConfigOption("OGR_VFK_DB_NAME", NULL);
    if (pszDbNameConf) {
	osDbName = pszDbNameConf;
    }
    else {
	osDbName = CPLResetExtension(m_pszFilename, "db");
    }
    size_t nLen = osDbName.length();
    if( nLen > 2048 )
    {
        nLen = 2048;
        osDbName.resize(nLen);
    }
    m_pszDBname = new char [nLen+1];
    std::strncpy(m_pszDBname, osDbName.c_str(), nLen);
    m_pszDBname[nLen] = 0;
    CPLDebug("OGR-VFK", "Using internal DB: %s",
             m_pszDBname);

    if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_SPATIAL", "YES")))
	m_bSpatial = TRUE;    /* build geometry from DB */
    else
	m_bSpatial = FALSE;   /* store also geometry in DB */

    m_bNewDb = TRUE;
    if (VSIStatL(osDbName, &sStatBufDb) == 0) {
	if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_OVERWRITE", "NO"))) {
	    m_bNewDb = TRUE;     /* overwrite existing DB */
            CPLDebug("OGR-VFK", "Internal DB (%s) already exists and will be overwritten",
                     m_pszDBname);
	    VSIUnlink(osDbName);
        }
        else {
            if (VSIStatL(pszFilename, &sStatBufVfk) == 0 &&
                sStatBufVfk.st_mtime > sStatBufDb.st_mtime) {
                CPLDebug("OGR-VFK",
                         "Found %s but ignoring because it appears\n"
                         "be older than the associated VFK file.",
                         osDbName.c_str());
                m_bNewDb = TRUE;
                VSIUnlink(osDbName);
            }
            else {
                m_bNewDb = FALSE;    /* re-use existing DB */
            }
        }
    }

    /*
    if (m_bNewDb) {
      CPLError(CE_Warning, CPLE_AppDefined,
               "INFO: No internal SQLite DB found. Reading VFK data may take some time...");
    }
    */

    CPLDebug("OGR-VFK", "New DB: %s Spatial: %s",
	     m_bNewDb ? "yes" : "no", m_bSpatial ? "yes" : "no");

    if (SQLITE_OK != sqlite3_open(osDbName, &m_poDB)) {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Creating SQLite DB failed");
    }
    else {
        char* pszErrMsg = NULL;
        CPL_IGNORE_RET_VAL(sqlite3_exec(m_poDB, "PRAGMA synchronous = OFF", NULL, NULL, &pszErrMsg));
        sqlite3_free(pszErrMsg);
    }

    if (m_bNewDb) {
        /* new DB, create support metadata tables */
        osCommand.Printf("CREATE TABLE %s (file_name text, table_name text, num_records integer, "
                         "num_features integer, num_geometries integer, table_defn text)",
                         VFK_DB_TABLE);
        ExecuteSQL(osCommand.c_str());

        /* header table */
        osCommand.Printf("CREATE TABLE %s (key text, value text)", VFK_DB_HEADER);
        ExecuteSQL(osCommand.c_str());
    }
}
Example #15
0
int OGRSelafinDataSource::Open( const char * pszFilename, int bUpdateIn,
                                int bCreate )
{
    // Check if a range is set and extract it and the filename.
    const char *pszc = pszFilename;
    if (*pszFilename==0) return FALSE;
    while (*pszc) ++pszc;
    if (*(pszc-1)==']') {
        --pszc;
        while (pszc!=pszFilename && *pszc!='[') pszc--;
        if (pszc==pszFilename) return FALSE;
        poRange.setRange(pszc);
    }
    pszName = CPLStrdup( pszFilename );
    pszName[pszc-pszFilename]=0;
    bUpdate = CPL_TO_BOOL(bUpdateIn);
    if (bCreate && EQUAL(pszName, "/vsistdout/")) return TRUE;
    /* For writable /vsizip/, do nothing more */
    if (bCreate && STARTS_WITH(pszName, "/vsizip/")) return TRUE;
    CPLString osFilename(pszName);
    CPLString osBaseFilename = CPLGetFilename(pszName);
    // Determine what sort of object this is.
    VSIStatBufL sStatBuf;
    if (VSIStatExL( osFilename, &sStatBuf, VSI_STAT_NATURE_FLAG ) != 0) return FALSE;

    // Is this a single Selafin file?
    if (VSI_ISREG(sStatBuf.st_mode)) return OpenTable( pszName );

    // Is this a single a ZIP file with only a Selafin file inside ?
    if( STARTS_WITH(osFilename, "/vsizip/") && VSI_ISREG(sStatBuf.st_mode) ) {
        char** papszFiles = VSIReadDir(osFilename);
        if (CSLCount(papszFiles) != 1) {
            CSLDestroy(papszFiles);
            return FALSE;
        }
        osFilename = CPLFormFilename(osFilename, papszFiles[0], nullptr);
        CSLDestroy(papszFiles);
        return OpenTable( osFilename );
    }

#ifdef notdef
    // Otherwise it has to be a directory.
    if( !VSI_ISDIR(sStatBuf.st_mode) ) return FALSE;

    // Scan through for entries which look like Selafin files
    int nNotSelafinCount = 0, i;
    char **papszNames = VSIReadDir( osFilename );
    for( i = 0; papszNames != NULL && papszNames[i] != NULL; i++ ) {
        CPLString oSubFilename = CPLFormFilename( osFilename, papszNames[i], NULL );
        if( EQUAL(papszNames[i],".") || EQUAL(papszNames[i],"..") ) continue;
        if( VSIStatL( oSubFilename, &sStatBuf ) != 0 || !VSI_ISREG(sStatBuf.st_mode) ) {
            nNotSelafinCount++;
            continue;
        }
        if( !OpenTable( oSubFilename ) ) {
            CPLDebug("Selafin", "Cannot open %s", oSubFilename.c_str());
            nNotSelafinCount++;
            continue;
        }
    }
    CSLDestroy( papszNames );

    // We presume that this is indeed intended to be a Selafin datasource if over half the files were Selafin files.
    return nNotSelafinCount < nLayers;
#else
    return FALSE;
#endif
}
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;
}
Example #17
0
int OGRShapeDataSource::OpenFile( const char *pszNewName, int bUpdate,
                                  int bTestOpen )

{
    SHPHandle   hSHP;
    DBFHandle   hDBF;
    const char *pszExtension = CPLGetExtension( pszNewName );

    (void) bTestOpen;

    if( !EQUAL(pszExtension,"shp") && !EQUAL(pszExtension,"shx")
        && !EQUAL(pszExtension,"dbf") )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      SHPOpen() should include better (CPL based) error reporting,    */
/*      and we should be trying to distinquish at this point whether    */
/*      failure is a result of trying to open a non-shapefile, or       */
/*      whether it was a shapefile and we want to report the error      */
/*      up.                                                             */
/*                                                                      */
/*      Care is taken to suppress the error and only reissue it if      */
/*      we think it is appropriate.                                     */
/* -------------------------------------------------------------------- */
    CPLPushErrorHandler( CPLQuietErrorHandler );
    if( bUpdate )
        hSHP = DS_SHPOpen( pszNewName, "r+" );
    else
        hSHP = DS_SHPOpen( pszNewName, "r" );
    CPLPopErrorHandler();

    if( hSHP == NULL 
        && (!EQUAL(CPLGetExtension(pszNewName),"dbf") 
            || strstr(CPLGetLastErrorMsg(),".shp") == NULL) )
    {
        CPLString osMsg = CPLGetLastErrorMsg();

        CPLError( CE_Failure, CPLE_OpenFailed, "%s", osMsg.c_str() );

        return FALSE;
    }
    CPLErrorReset();
    
/* -------------------------------------------------------------------- */
/*      Open the .dbf file, if it exists.  To open a dbf file, the      */
/*      filename has to either refer to a successfully opened shp       */
/*      file or has to refer to the actual .dbf file.                   */
/* -------------------------------------------------------------------- */
    if( hSHP != NULL || EQUAL(CPLGetExtension(pszNewName),"dbf") )
    {
        if( bUpdate )
        {
            hDBF = DS_DBFOpen( pszNewName, "r+" );
            if( hSHP != NULL && hDBF == NULL )
            {
                for(int i=0;i<2;i++)
                {
                    VSIStatBufL sStat;
                    const char* pszDBFName = CPLResetExtension(pszNewName,
                                                    (i == 0 ) ? "dbf" : "DBF");
                    VSILFILE* fp = NULL;
                    if( VSIStatExL( pszDBFName, &sStat, VSI_STAT_EXISTS_FLAG) == 0 )
                    {
                        fp = VSIFOpenL(pszDBFName, "r+");
                        if (fp == NULL)
                        {
                            CPLError( CE_Failure, CPLE_OpenFailed,
                                    "%s exists, but cannot be opened in update mode",
                                    pszDBFName );
                            SHPClose(hSHP);
                            return FALSE;
                        }
                        VSIFCloseL(fp);
                        break;
                    }
                }
            }
        }
        else
            hDBF = DS_DBFOpen( pszNewName, "r" );
    }
    else
        hDBF = NULL;
        
    if( hDBF == NULL && hSHP == NULL )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Create the layer object.                                        */
/* -------------------------------------------------------------------- */
    OGRShapeLayer       *poLayer;

    poLayer = new OGRShapeLayer( this, pszNewName, hSHP, hDBF, NULL, FALSE, bUpdate,
                                 wkbNone );
    poLayer->SetModificationDate(
            CSLFetchNameValue( papszOpenOptions, "DBF_DATE_LAST_UPDATE" ) );

/* -------------------------------------------------------------------- */
/*      Add layer to data source layer list.                            */
/* -------------------------------------------------------------------- */
    AddLayer(poLayer);

    return TRUE;
}
CPLErr RasterliteDataset::ReloadOverviews()
{
    if (nLevel != 0)
        return CE_Failure;
        
/* -------------------------------------------------------------------- */
/*      Fetch resolutions                                               */
/* -------------------------------------------------------------------- */

    CPLString osSQL;
    OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
    if (hRasterPyramidsLyr)
    {
        osSQL.Printf("SELECT pixel_x_size, pixel_y_size "
                     "FROM raster_pyramids WHERE table_prefix = '%s' "
                     "ORDER BY pixel_x_size ASC",
                     osTableName.c_str());
     }
     else
     {
        osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
                     "FROM \"%s_metadata\" WHERE pixel_x_size != 0  "
                     "ORDER BY pixel_x_size ASC",
                     osTableName.c_str());
     }

    OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    if (hSQLLyr == NULL)
    {
        if (hRasterPyramidsLyr == NULL)
            return CE_Failure;
            
        osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
                     "FROM \"%s_metadata\" WHERE pixel_x_size != 0  "
                     "ORDER BY pixel_x_size ASC",
                     osTableName.c_str());
                     
        hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
        if (hSQLLyr == NULL)
            return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */

    int i;
    for(i=1;i<nResolutions;i++)
        delete papoOverviews[i-1];
    CPLFree(papoOverviews);
    papoOverviews = NULL;
    CPLFree(padfXResolutions);
    padfXResolutions = NULL;
    CPLFree(padfYResolutions);
    padfYResolutions = NULL;
    
/* -------------------------------------------------------------------- */
/*      Rebuild arrays                                                  */
/* -------------------------------------------------------------------- */

    nResolutions = OGR_L_GetFeatureCount(hSQLLyr, TRUE);
    
    padfXResolutions =
        (double*)CPLMalloc(sizeof(double) * nResolutions);
    padfYResolutions =
        (double*)CPLMalloc(sizeof(double) * nResolutions);

    i = 0;
    OGRFeatureH hFeat;
    while((hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL)
    {
        padfXResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 0);
        padfYResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 1);

        OGR_F_Destroy(hFeat);

        i ++;
    }

    OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
    hSQLLyr = NULL;

/* -------------------------------------------------------------------- */
/*      Add overview levels as internal datasets                        */
/* -------------------------------------------------------------------- */
    if (nResolutions > 1)
    {
        CPLString osRasterTableName = osTableName;
        osRasterTableName += "_rasters";
        
        OGRLayerH hRasterLyr = OGR_DS_GetLayerByName(hDS, osRasterTableName.c_str());
        
        papoOverviews = (RasterliteDataset**)
            CPLCalloc(nResolutions - 1, sizeof(RasterliteDataset*));
        int nLev;
        for(nLev=1;nLev<nResolutions;nLev++)
        {
            int nOvrBands;
            GDALDataType eOvrDataType;
            int nBlockXSize, nBlockYSize;
            if (GetBlockParams(hRasterLyr, nLev, &nOvrBands, &eOvrDataType,
                               &nBlockXSize, &nBlockYSize))
            {
                if (eOvrDataType == GDT_Byte && nOvrBands == 1 && nBands == 3)
                    nOvrBands = 3;

                papoOverviews[nLev-1] = new RasterliteDataset(this, nLev);
                  
                int iBand;
                for(iBand=0;iBand<nBands;iBand++)
                {
                    papoOverviews[nLev-1]->SetBand(iBand+1,
                        new RasterliteBand(papoOverviews[nLev-1], iBand+1, eOvrDataType,
                                           nBlockXSize, nBlockYSize));
                }
            }
            else
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Cannot find block characteristics for overview %d", nLev);
                papoOverviews[nLev-1] = NULL;
            }
        }
    }
    
    return CE_None;
}
Example #19
0
OGRErr      OGRGFTTableLayer::ISetFeature( OGRFeature *poFeature )
{
    GetLayerDefn();

    if (!poDS->IsReadWrite())
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Operation not available in read-only mode");
        return OGRERR_FAILURE;
    }

    if (osTableId.size() == 0)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                "Cannot set feature to non-created table");
        return OGRERR_FAILURE;
    }

    if (poDS->GetAccessToken().size() == 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Operation not available in unauthenticated mode");
        return OGRERR_FAILURE;
    }

    if (poFeature->GetFID() == OGRNullFID)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "FID required on features given to SetFeature()." );
        return OGRERR_FAILURE;
    }

    CPLString      osCommand;

    osCommand += "UPDATE ";
    osCommand += osTableId;
    osCommand += " SET ";

    int iField;
    int nFieldCount = poFeatureDefn->GetFieldCount();
    for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++)
    {
        if (iField > 0)
            osCommand += ", ";

        if (iField == nFieldCount)
        {
            osCommand += EscapeAndQuote(GetGeometryColumn());
        }
        else
        {
            const char* pszFieldName =
                poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
            osCommand += EscapeAndQuote(pszFieldName);
        }

        osCommand += " = ";

        OGRGeometry* poGeom = poFeature->GetGeometryRef();
        if (iGeometryField != iLatitudeField && iField == iGeometryField &&
            (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField )))
        {
            if (poGeom == NULL)
                osCommand += "''";
            else
            {
                char* pszKML;
                if (poGeom->getSpatialReference() != NULL &&
                    !poGeom->getSpatialReference()->IsSame(poSRS))
                {
                    OGRGeometry* poGeom4326 = poGeom->clone();
                    poGeom4326->transformTo(poSRS);
                    pszKML = poGeom4326->exportToKML();
                    delete poGeom4326;
                }
                else
                {
                    pszKML = poGeom->exportToKML();
                }
                osCommand += "'";
                osCommand += pszKML;
                osCommand += "'";
                CPLFree(pszKML);
            }
            continue;
        }

        if( !poFeature->IsFieldSet( iField ) )
        {
            osCommand += "''";
        }
        else
        {
            OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType();
            if (eType != OFTInteger && eType != OFTReal)
            {
                CPLString osTmp;
                const char* pszVal = poFeature->GetFieldAsString(iField);

                if (!CPLIsUTF8(pszVal, -1))
                {
                    static int bFirstTime = TRUE;
                    if (bFirstTime)
                    {
                        bFirstTime = FALSE;
                        CPLError(CE_Warning, CPLE_AppDefined,
                                "%s is not a valid UTF-8 string. Forcing it to ASCII.\n"
                                "This warning won't be issued anymore", pszVal);
                    }
                    else
                    {
                        CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII",
                                pszVal);
                    }
                    char* pszEscaped = CPLForceToASCII(pszVal, -1, '?');
                    osTmp = pszEscaped;
                    CPLFree(pszEscaped);
                    pszVal = osTmp.c_str();
                }

                osCommand += EscapeAndQuote(pszVal);
            }
            else
                osCommand += poFeature->GetFieldAsString(iField);
        }
    }

    osCommand += " WHERE ROWID = '";
    osCommand += CPLSPrintf(CPL_FRMT_GIB, poFeature->GetFID());
    osCommand += "'";

    CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
    if (psResult == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed (1)");
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      We expect a response like "affected_rows\n1".                   */
/* -------------------------------------------------------------------- */
    char* pszLine = (char*) psResult->pabyData;
    if (pszLine == NULL ||
        strncmp(pszLine, "affected_rows\n1\n", 16) != 0 ||
        psResult->pszErrBuf != NULL)
    {
        CPLDebug( "GFT", "%s/%s", 
                  pszLine ? pszLine : "null", 
                  psResult->pszErrBuf ? psResult->pszErrBuf : "null");
        CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed (2)");
        CPLHTTPDestroyResult(psResult);
        return OGRERR_FAILURE;
    }

    CPLHTTPDestroyResult(psResult);

    return OGRERR_NONE;
}
Example #20
0
OGRErr OGRIngresTableLayer::CreateFeature( OGRFeature *poFeature )

{
    CPLString           osCommand;
    int                 i, bNeedComma = FALSE;

/* -------------------------------------------------------------------- */
/*      Form the INSERT command.                                        */
/* -------------------------------------------------------------------- */
    osCommand.Printf( "INSERT INTO %s (", poFeatureDefn->GetName() );


/* -------------------------------------------------------------------- */
/*      Accumulate fields to be inserted.                               */
/* -------------------------------------------------------------------- */
    if( poFeature->GetGeometryRef() != NULL && osGeomColumn.size() )
    {
        osCommand = osCommand + osGeomColumn + " ";
        bNeedComma = TRUE;
    }

    if( poFeature->GetFID() != OGRNullFID && osFIDColumn.size() )
    {
        if( bNeedComma )
            osCommand += ", ";
        
        osCommand = osCommand + osFIDColumn + " ";
        bNeedComma = TRUE;
    }

    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( !bNeedComma )
            bNeedComma = TRUE;
        else
            osCommand += ", ";

        osCommand = osCommand 
             + poFeatureDefn->GetFieldDefn(i)->GetNameRef();
    }

    osCommand += ") VALUES (";

/* -------------------------------------------------------------------- */
/*      Insert the geometry (as a place holder)                         */
/* -------------------------------------------------------------------- */
    CPLString osGeomText;

    // Set the geometry 
    bNeedComma = FALSE;
    if( poFeature->GetGeometryRef() != NULL && osGeomColumn.size() )
    {
        bNeedComma = TRUE;
        OGRErr localErr;

        if( poDS->IsNewIngres() )
        {
        	localErr = PrepareNewStyleGeometry( poFeature->GetGeometryRef(), osGeomText );
        }
        else
        {
        	localErr = PrepareOldStyleGeometry( poFeature->GetGeometryRef(), osGeomText );
        }
        if( localErr == OGRERR_NONE )
        {
            if( CSLTestBoolean( 
                     CPLGetConfigOption( "INGRES_INSERT_SUB", "NO") ) )
            {
                osCommand += " ~V";
            }
            else if( poDS->IsNewIngres() == FALSE )
            {
                osCommand += "'";
                osCommand += osGeomText;
                osCommand += "'";
                osGeomText = "";
            }
            else
            {
            	osCommand += osGeomText;
            	//osGeomText = "";
            }
        }
        else
        {
            osGeomText = "";
            osCommand += "NULL"; /* is this sort of empty geometry legal? */
        }
    }

/* -------------------------------------------------------------------- */
/*      Set the FID                                                     */
/* -------------------------------------------------------------------- */
    if( poFeature->GetFID() != OGRNullFID && osFIDColumn.size() )
    {
        if( bNeedComma )
            osCommand += ", ";
        osCommand += CPLString().Printf( "%ld ", poFeature->GetFID() );
        bNeedComma = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Copy in the attribute values.                                   */
/* -------------------------------------------------------------------- */
    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( bNeedComma )
            osCommand += ", ";
        else
            bNeedComma = TRUE;

        const char *pszStrValue = poFeature->GetFieldAsString(i);

        if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTBinary )
        {
            int         iChar;

            //We need to quote and escape string fields. 
            osCommand += "'";

            for( iChar = 0; pszStrValue[iChar] != '\0'; iChar++ )
            {
                if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTIntegerList
                    && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTRealList
                    && poFeatureDefn->GetFieldDefn(i)->GetWidth() > 0
                    && iChar == poFeatureDefn->GetFieldDefn(i)->GetWidth() )
                {
                    CPLDebug( "INGRES",
                              "Truncated %s field value, it was too long.",
                              poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
                    break;
                }

                if( pszStrValue[iChar] == '\'' )
                {
                    osCommand += '\'';
                    osCommand += pszStrValue[iChar];
                }
                else
                    osCommand += pszStrValue[iChar];
            }

            osCommand += "'";
        }
        else if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTBinary )
        {
            int binaryCount = 0;
            GByte* binaryData = poFeature->GetFieldAsBinary(i, &binaryCount);
            char* pszHexValue = CPLBinaryToHex( binaryCount, binaryData );

            osCommand += "x'";
            osCommand += pszHexValue;
            osCommand += "'";

            CPLFree( pszHexValue );
        }
        else
        {
            osCommand += pszStrValue;
        }

    }

    osCommand += ")";

/* -------------------------------------------------------------------- */
/*      Execute it.                                                     */
/* -------------------------------------------------------------------- */
    poDS->EstablishActiveLayer( NULL );
    OGRIngresStatement oStmt( poDS->GetConn() );

    oStmt.bDebug = FALSE; 

    if( osGeomText.size() > 0  && poDS->IsNewIngres() == FALSE )
        oStmt.addInputParameter( IIAPI_LVCH_TYPE, osGeomText.size(),
                                 (GByte *) osGeomText.c_str() );
    if( osGeomText.size() > 0 && poDS->IsNewIngres() == TRUE )
    {
    	GByte * pabyWKB;
    	int nSize = poFeature->GetGeometryRef()->WkbSize();
    	pabyWKB = (GByte *) CPLMalloc(nSize);

    	poFeature->GetGeometryRef()->exportToWkb(wkbNDR, pabyWKB);

    	oStmt.addInputParameter( IIAPI_LBYTE_TYPE, nSize, pabyWKB );
    	CPLFree(pabyWKB);
/*
 * Test code
     	char * pszWKT;
    	poFeature->GetGeometryRef()->exportToWkt(&pszWKT);
    	oStmt.addInputParameter(IIAPI_LVCH_TYPE, strlen(pszWKT), (GByte *) pszWKT);*/
    }

    if( !oStmt.ExecuteSQL( osCommand ) )
        return OGRERR_FAILURE;
    
    return OGRERR_NONE;

}
/***********************************************************************
 * \brief Returns the metadata for this band
 *
 * If the metadata is actually stored in band's properties, simply
 * returns them. Otherwise, it raises a query to fetch metadata
 * FROM db
 **********************************************************************/
GBool PostGISRasterRasterBand::GetBandMetadata(
    GDALDataType * peDataType, GBool * pbHasNoData, double * pdfNoData)
{
    // No need to raise a query
    if (eDataType != GDT_Unknown) {
        if (peDataType)
            *peDataType = eDataType;

        if (pbHasNoData)
            *pbHasNoData = bNoDataValueSet;

        if (pdfNoData)
            *pdfNoData = dfNoDataValue;

        return true;
    }

    /**
     * Queries are expensive. So, we only raise them if all parameters
     * are not null
     **/
    if (!peDataType || !pbHasNoData || !pdfNoData) {
        return false;
    }

    /**
     * It is safe to assume all the tiles will have the same values for
     * metadata properties. That was checked during band's construction
     * (or we simply trusted the user, to avoid expensive checkings).
     * So, we can limit the results to just one.
     **/
    int nTuples = 0;
    CPLString osCommand = NULL;
    PGresult * poResult = NULL;
    PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS;

    osCommand.Printf("st_bandpixeltype(%s, %d), "
        "st_bandnodatavalue(%s, %d) is not null, "
        "st_bandnodatavalue(%s, %d) FROM %s.%s limit 1", pszColumn,
        nBand, pszColumn, nBand, pszColumn, nBand, pszSchema, pszTable);

#ifdef DEBUG_QUERY
    CPLDebug("PostGIS_Raster",
        "PostGISRasterRasterBand::GetBandMetadata(): Query: %s",
        osCommand.c_str());
#endif

    poResult = PQexec(poRDS->poConn, osCommand.c_str());
    nTuples = PQntuples(poResult);

    /* Error getting info FROM database */
    if (poResult == NULL ||
        PQresultStatus(poResult) != PGRES_TUPLES_OK ||
        nTuples <= 0) {

        ReportError(CE_Failure, CPLE_AppDefined,
            "Error getting band metadata while creating raster "
            "bands");

        CPLDebug("PostGIS_Raster",
            "PostGISRasterDataset::GetBandMetadata(): %s",
            PQerrorMessage(poRDS->poConn));

        if (poResult)
            PQclear(poResult);

        return false;
    }

    // Fill band metadata values
    GBool bSignedByte = false;
    int nBitsDepth = 8;
    char* pszDataType = NULL;

    pszDataType = CPLStrdup(PQgetvalue(poResult, 0, 0));

    TranslateDataType(pszDataType, &eDataType, &nBitsDepth,
            &bSignedByte);

    // Add pixeltype to image structure domain
    if (bSignedByte) {
        SetMetadataItem("PIXELTYPE", "SIGNEDBYTE", "IMAGE_STRUCTURE" );
    }

    // Add NBITS to metadata only for sub-byte types
    if (nBitsDepth < 8)
        SetMetadataItem("NBITS", CPLString().Printf( "%d", nBitsDepth ),
            "IMAGE_STRUCTURE" );

    CPLFree(pszDataType);

    bNoDataValueSet =
            EQUALN(PQgetvalue(poResult, 0, 1), "t", sizeof(char));

    dfNoDataValue = CPLAtof(PQgetvalue(poResult, 0, 2));

    // Fill output arguments
    *peDataType = eDataType;
    *pbHasNoData = bNoDataValueSet;
    *pdfNoData = dfNoDataValue;

    return true;
}
Example #22
0
/**
 * \brief Fetch a document from an url and return in a string.
 *
 * @param pszURL valid URL recognized by underlying download library (libcurl)
 * @param papszOptions option list as a NULL-terminated array of strings. May be NULL.
 *                     The following options are handled :
 * <ul>
 * <li>TIMEOUT=val, where val is in seconds</li>
 * <li>HEADERS=val, where val is an extra header to use when getting a web page.
 *                  For example "Accept: application/x-ogcwkt"
 * <li>HTTPAUTH=[BASIC/NTLM/GSSNEGOTIATE/ANY] to specify an authentication scheme to use.
 * <li>USERPWD=userid:password to specify a user and password for authentication
 * <li>POSTFIELDS=val, where val is a nul-terminated string to be passed to the server
 *                     with a POST request.
 * <li>PROXY=val, to make requests go through a proxy server, where val is of the
 *                form proxy.server.com:port_number
 * <li>PROXYUSERPWD=val, where val is of the form username:password
 * <li>CUSTOMREQUEST=val, where val is GET, PUT, POST, DELETE, etc.. (GDAL >= 1.9.0)
 * </ul>
 *
 * Alternatively, if not defined in the papszOptions arguments, the PROXY and 
 * PROXYUSERPWD values are searched in the configuration options named 
 * GDAL_HTTP_PROXY and GDAL_HTTP_PROXYUSERPWD, as proxy configuration belongs 
 * to networking setup and makes more sense at the configuration option level 
 * than at the connection level.
 *
 * @return a CPLHTTPResult* structure that must be freed by 
 * CPLHTTPDestroyResult(), or NULL if libcurl support is disabled
 */
CPLHTTPResult *CPLHTTPFetch( const char *pszURL, char **papszOptions )

{
#ifndef HAVE_CURL
    (void) papszOptions;
    (void) pszURL;

    CPLError( CE_Failure, CPLE_NotSupported,
              "GDAL/OGR not compiled with libcurl support, remote requests not supported." );
    return NULL;
#else
/* -------------------------------------------------------------------- */
/*      Are we using a persistent named session?  If so, search for     */
/*      or create it.                                                   */
/*                                                                      */
/*      Currently this code does not attempt to protect against         */
/*      multiple threads asking for the same named session.  If that    */
/*      occurs it will be in use in multiple threads at once which      */
/*      might have bad consequences depending on what guarantees        */
/*      libcurl gives - which I have not investigated.                  */
/* -------------------------------------------------------------------- */
    CURL *http_handle = NULL;

    const char *pszPersistent = CSLFetchNameValue( papszOptions, "PERSISTENT" );
    const char *pszClosePersistent = CSLFetchNameValue( papszOptions, "CLOSE_PERSISTENT" );
    if (pszPersistent)
    {
        CPLString osSessionName = pszPersistent;
        CPLMutexHolder oHolder( &hSessionMapMutex );

        if( oSessionMap.count( osSessionName ) == 0 )
        {
            oSessionMap[osSessionName] = curl_easy_init();
            CPLDebug( "HTTP", "Establish persistent session named '%s'.",
                      osSessionName.c_str() );
        }

        http_handle = oSessionMap[osSessionName];
    }
/* -------------------------------------------------------------------- */
/*      Are we requested to close a persistent named session?          */
/* -------------------------------------------------------------------- */
    else if (pszClosePersistent)
    {
        CPLString osSessionName = pszClosePersistent;
        CPLMutexHolder oHolder( &hSessionMapMutex );

        std::map<CPLString,CURL*>::iterator oIter = oSessionMap.find( osSessionName );
        if( oIter != oSessionMap.end() )
        {
            curl_easy_cleanup(oIter->second);
            oSessionMap.erase(oIter);
            CPLDebug( "HTTP", "Ended persistent session named '%s'.",
                      osSessionName.c_str() );
        }
        else
        {
            CPLDebug( "HTTP", "Could not find persistent session named '%s'.",
                      osSessionName.c_str() );
        }

        return NULL;
    }
    else
        http_handle = curl_easy_init();

/* -------------------------------------------------------------------- */
/*      Setup the request.                                              */
/* -------------------------------------------------------------------- */
    char szCurlErrBuf[CURL_ERROR_SIZE+1];
    CPLHTTPResult *psResult;
    struct curl_slist *headers=NULL; 

    const char* pszArobase = strchr(pszURL, '@');
    const char* pszSlash = strchr(pszURL, '/');
    const char* pszColon = (pszSlash) ? strchr(pszSlash, ':') : NULL;
    if (pszArobase != NULL && pszColon != NULL && pszArobase - pszColon > 0)
    {
        /* http://user:password@www.example.com */
        char* pszSanitizedURL = CPLStrdup(pszURL);
        pszSanitizedURL[pszColon-pszURL] = 0;
        CPLDebug( "HTTP", "Fetch(%s:#password#%s)", pszSanitizedURL, pszArobase );
        CPLFree(pszSanitizedURL);
    }
    else
    {
        CPLDebug( "HTTP", "Fetch(%s)", pszURL );
    }

    psResult = (CPLHTTPResult *) CPLCalloc(1,sizeof(CPLHTTPResult));

    curl_easy_setopt(http_handle, CURLOPT_URL, pszURL );

    if (CSLTestBoolean(CPLGetConfigOption("CPL_CURL_VERBOSE", "NO")))
        curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1);

    const char *pszHttpVersion = CSLFetchNameValue( papszOptions, "HTTP_VERSION");
    if( pszHttpVersion && strcmp(pszHttpVersion, "1.0") == 0 )
        curl_easy_setopt(http_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 );

    /* Support control over HTTPAUTH */
    const char *pszHttpAuth = CSLFetchNameValue( papszOptions, "HTTPAUTH" );
    if( pszHttpAuth == NULL )
        /* do nothing */;

    /* CURLOPT_HTTPAUTH is defined in curl 7.11.0 or newer */
#if LIBCURL_VERSION_NUM >= 0x70B00
    else if( EQUAL(pszHttpAuth,"BASIC") )
        curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
    else if( EQUAL(pszHttpAuth,"NTLM") )
        curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM );
    else if( EQUAL(pszHttpAuth,"ANY") )
        curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY );
#ifdef CURLAUTH_GSSNEGOTIATE
    else if( EQUAL(pszHttpAuth,"NEGOTIATE") )
        curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_GSSNEGOTIATE );
#endif
    else
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Unsupported HTTPAUTH value '%s', ignored.", 
                  pszHttpAuth );
    }
#else
    else
    {
/*****************************************************
 * \brief Write a natural block of raster band data
 *****************************************************/
CPLErr PostGISRasterRasterBand::IWriteBlock(int nBlockXOff,
        int nBlockYOff, void * pImage)
{
    int nPixelSize = GDALGetDataTypeSize(eDataType) / 8;
    int nNaturalBlockXSize = 0;
    int nNaturalBlockYSize = 0;
    int nDataSize = 0;
    int nBandMetaDataSize = 0;
    PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS;
    CPLDebug("PostGIS_Raster",
        "PostGISRasterRasterBand::IWriteBlock(): Table %s.%s (%s), Srid : %d",
        pszSchema, pszTable, pszColumn,poRDS->nSrid);

    // How much data are we going to copy?
    GetBlockSize(&nNaturalBlockXSize, &nNaturalBlockYSize);
    nDataSize = nNaturalBlockXSize * nNaturalBlockYSize * nPixelSize;

    // Allocating space for band metadata
    nBandMetaDataSize = (nPixelSize + 1);
    char * pszBandMetadata = (char*) VSIMalloc2(2 * nBandMetaDataSize, sizeof (char));

    // Allocate memory for all bands data, if needed
    if (!poRDS->pBufferToInsert) {
        CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(); "
            "Allocating memory for buffer to hold insert query data (%d characters)",
            2 * (nDataSize + nBandMetaDataSize) * poRDS->nBandsToCopy);

        poRDS->pBufferToInsert =
            (char *)VSIMalloc3(poRDS->nBandsToCopy, 2 * (nDataSize + nBandMetaDataSize), sizeof(char));

        poRDS->nPosToCopy = 0;
        poRDS->nBandsCopied = 0;
    }

    CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IWriteBlock(): Block (%d x %d), Metadata %d. We are "
            "copying %d bytes", nNaturalBlockXSize, nNaturalBlockYSize, nBandMetaDataSize, nDataSize+nBandMetaDataSize);

    /**
     * Copy the band data into the dataset buffer. We will raise the query
     * after we have the data of all bands in the buffer.
     *
     * NOTE: At this point, datatype translation between src and dst has been
     * performed by IRasterIO. So, we can use band datatype for both, origin
     * and destination buffers.
     **/

    // GDALCopyWords(pImage, eDataType, 0,
    //     poRDS->pBufferToInsert + poRDS->nPosToCopy, eDataType, 0, nDataSize);

    char cPostGISQueryWKT = TranslateDataTypeGDALtoPostGIS(&eDataType);
    if(cPostGISQueryWKT == '\0'){
        CPLDebug("PostGIS_Raster",
                "PostGISRasterRasterBand::IWriteBlock(): PostGIS Datatype id : %c",
                cPostGISQueryWKT);
        return CE_Failure;
    }
    CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IWriteBlock(): HasNoDataValue = %s, NoDataValue = %f",
            bNoDataValueSet? "True" : "False", dfNoDataValue);

    /* Testing bNoDataValueSet :: Hack */
    // bNoDataValueSet = 1;
    // dfNoDataValue = 0;
    if(bNoDataValueSet)
        pszBandMetadata[0] = '4';
    else
        pszBandMetadata[0] = '0';

    pszBandMetadata[1] = cPostGISQueryWKT;
    strcpy(pszBandMetadata + 2, CPLBinaryToHex(nPixelSize,(GByte *)&dfNoDataValue));
    memcpy(poRDS->pBufferToInsert + poRDS->nPosToCopy, pszBandMetadata, nBandMetaDataSize * 2);
    poRDS->nPosToCopy += nBandMetaDataSize * 2;
    memcpy(poRDS->pBufferToInsert + poRDS->nPosToCopy, CPLBinaryToHex(nDataSize,(GByte *)pImage), nDataSize * 2);
    poRDS->nPosToCopy += nDataSize * 2;
    poRDS->pBufferToInsert[poRDS->nPosToCopy] = '\0';
    poRDS->nBandsCopied++;

    // Check if we're done, to raise the insert query
    if (poRDS->nBandsToCopy == poRDS->nBandsCopied) {

        PGresult * poResult = NULL;
        CPLString osCommand;
/*
        // hack
        pszSchema = "public";
        pszTable = "newtable";
        pszColumn = "rast";
*/
        // Raise insert query
        // TODO: The table may contain more fields
        // FIXME: For some reason, pszSchema, pszTable and pszColumn are NULL.
        // I think it's related with the fact we overwrote GDALDataset::IRasterIO,
        // and we delegate in default implementation. Here, poDS is a simple
        // GDALDataset *, not a PostGISRasterDataset *

        // FIXME: anyway, even hardcoding schema/table/column names here, we
        // still have an error:
        // ERROR:  rt_raster_from_wkb: WKB version 10091 unsupported
        // This is caused because we're not correctly creating the hex string
        // representing PostGIS Raster. Version should be 0, and number 10091
        // is being read instead. We're not including headers in the hex string,
        // just raster data. Need to fix this.
        osCommand.Printf("insert into %s.%s (%s) values('010000",pszSchema, pszTable, pszColumn);
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&poRDS->nBandsToCopy));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_WE_RES]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_NS_RES]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_X]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_Y]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_ROTATION_PARAM1]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_ROTATION_PARAM2]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(4, (GByte*)&poRDS->nSrid));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&nNaturalBlockXSize));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&nNaturalBlockYSize));
        osCommand += poRDS->pBufferToInsert;
        osCommand += "'::raster)";

        CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock: Insert "
            "query raised: %s", osCommand.c_str());

        poResult = PQexec(poRDS->poConn, osCommand.c_str());

        if (poResult == NULL || PQresultStatus(poResult) != PGRES_COMMAND_OK) {

            CPLError(CE_Failure, CPLE_AppDefined,
                "Error inserting raster data in %s.%s: %s", pszSchema,
                pszTable, PQerrorMessage(poRDS->poConn));

            if (poResult != NULL)
                PQclear(poResult);

            // rollback
            poResult = PQexec(poRDS->poConn, "rollback");
            if (poResult == NULL ||
                PQresultStatus(poResult) != PGRES_COMMAND_OK) {

                CPLError(CE_Failure, CPLE_AppDefined,
                    "Error rolling back transaction: %s",
                PQerrorMessage(poRDS->poConn));
            }

            if (poResult != NULL)
                PQclear(poResult);
        }


        // Release memory
        VSIFree(poRDS->pBufferToInsert);
        poRDS->pBufferToInsert = NULL;
    }

    return CE_None;
}
Example #24
0
const char* E00GRIDDataset::GetProjectionRef()

{
    ReadMetadata();
    return osProjection.c_str();
}
Example #25
0
int OGRGFTResultLayer::RunSQL()
{
    CPLString osChangedSQL(osSQL);
    int bHasSetLimit = FALSE;
    OGRGFTTableLayer* poTableLayer = NULL;
    OGRFeatureDefn* poTableDefn = NULL;
    CPLString osTableId;
    if (EQUALN(osSQL.c_str(), "SELECT", 6))
    {
        size_t nPosFROM = osSQL.ifind(" FROM ");
        if (nPosFROM == std::string::npos)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "RunSQL() failed. Missing FROM in SELECT");
            return FALSE;
        }
        CPLString osReminder;
        nPosFROM += 6;
        osTableId = OGRGFTExtractTableID(osSQL.c_str() + nPosFROM, osReminder);

        poTableLayer = (OGRGFTTableLayer*) poDS->GetLayerByName(osTableId);
        if (poTableLayer != NULL)
            poTableDefn = poTableLayer->GetLayerDefn();

        if (poTableLayer != NULL &&
            poTableLayer->GetTableId().size() &&
            !EQUAL(osTableId, poTableLayer->GetTableId()))
        {
            osChangedSQL = osSQL;
            osChangedSQL.resize(nPosFROM);
            osChangedSQL += poTableLayer->GetTableId();
            osChangedSQL += osReminder;
            osSQL = osChangedSQL;
            CPLDebug("GFT", "Patching table name (%s) to table id (%s)",
                     osTableId.c_str(), poTableLayer->GetTableId().c_str());
        }

        int nFeaturesToFetch = GetFeaturesToFetch();
        if (osSQL.ifind(" OFFSET ") == std::string::npos &&
            osSQL.ifind(" LIMIT ") == std::string::npos &&
            nFeaturesToFetch > 0)
        {
            osChangedSQL += CPLSPrintf(" LIMIT %d", nFeaturesToFetch);
            bHasSetLimit = TRUE;
        }
    }
    else
    {
        bGotAllRows = bEOF = TRUE;
        poFeatureDefn->SetGeomType( wkbNone );
    }

    CPLHTTPResult * psResult = poDS->RunSQL(osChangedSQL);

    if (psResult == NULL)
        return FALSE;

    char* pszLine = (char*) psResult->pabyData;
    if (pszLine == NULL ||
        psResult->pszErrBuf != NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "RunSQL() failed");
        CPLHTTPDestroyResult(psResult);
        return FALSE;
    }

    if (EQUALN(osSQL.c_str(), "SELECT", 6) ||
        EQUAL(osSQL.c_str(), "SHOW TABLES") ||
        EQUALN(osSQL.c_str(), "DESCRIBE", 8))
    {
        ParseCSVResponse(pszLine, aosRows);
        if (aosRows.size() > 0)
        {
            char** papszTokens = OGRGFTCSVSplitLine(aosRows[0], ',');
            for(int i=0;papszTokens && papszTokens[i];i++)
            {
                CPLString osLaunderedColName(LaunderColName(papszTokens[i]));
                int iIndex = (poTableDefn) ? poTableDefn->GetFieldIndex(osLaunderedColName) : -1;
                if (iIndex >= 0)
                {
                    poFeatureDefn->AddFieldDefn(poTableDefn->GetFieldDefn(iIndex));
                    if (iIndex == poTableLayer->GetGeometryFieldIndex())
                        iGeometryField = i;
                    if (iIndex == poTableLayer->GetLatitudeFieldIndex())
                        iLatitudeField = i;
                    if (iIndex == poTableLayer->GetLongitudeFieldIndex())
                        iLongitudeField = i;
                }
                else
                {
                    OGRFieldType eType = OFTString;
                    if (EQUAL(osLaunderedColName, "COUNT()"))
                        eType = OFTInteger;
                    OGRFieldDefn oFieldDefn(osLaunderedColName, eType);
                    poFeatureDefn->AddFieldDefn(&oFieldDefn);
                }
            }
            CSLDestroy(papszTokens);

            aosRows.erase(aosRows.begin());
        }

        if (iLatitudeField >= 0 && iLongitudeField >= 0)
        {
            iGeometryField = iLatitudeField;
            poFeatureDefn->SetGeomType( wkbPoint );
        }

        if (bHasSetLimit)
            bGotAllRows = bEOF = (int)aosRows.size() < GetFeaturesToFetch();
        else
            bGotAllRows = bEOF = TRUE;
    }

    SetGeomFieldName();

    CPLHTTPDestroyResult(psResult);

    return TRUE;
}
Example #26
0
OGRCSVLayer::OGRCSVLayer( const char *pszLayerNameIn, 
                          VSILFILE * fp, const char *pszFilename, int bNew, int bInWriteMode,
                          char chDelimiter, const char* pszNfdcGeomField,
                          const char* pszGeonamesGeomFieldPrefix)

{
    fpCSV = fp;

    iWktGeomReadField = -1;
    iNfdcLatitudeS = iNfdcLongitudeS = -1;
    iLatitudeField = iLongitudeField = -1;
    this->bInWriteMode = bInWriteMode;
    this->bNew = bNew;
    this->pszFilename = CPLStrdup(pszFilename);
    this->chDelimiter = chDelimiter;

    bFirstFeatureAppendedDuringSession = TRUE;
    bUseCRLF = FALSE;
    bNeedRewindBeforeRead = FALSE;
    eGeometryFormat = OGR_CSV_GEOM_NONE;

    nNextFID = 1;

    poFeatureDefn = new OGRFeatureDefn( pszLayerNameIn );
    poFeatureDefn->Reference();
    poFeatureDefn->SetGeomType( wkbNone );

    bCreateCSVT = FALSE;
    bDontHonourStrings = FALSE;
    bWriteBOM = FALSE;

    bIsEurostatTSV = FALSE;
    nEurostatDims = 0;

    nTotalFeatures = -1;

/* -------------------------------------------------------------------- */
/*      If this is not a new file, read ahead to establish if it is     */
/*      already in CRLF (DOS) mode, or just a normal unix CR mode.      */
/* -------------------------------------------------------------------- */
    if( !bNew && bInWriteMode )
    {
        int nBytesRead = 0;
        char chNewByte;

        while( nBytesRead < 10000 && VSIFReadL( &chNewByte, 1, 1, fpCSV ) == 1 )
        {
            if( chNewByte == 13 )
            {
                bUseCRLF = TRUE;
                break;
            }
            nBytesRead ++;
        }
        VSIRewindL( fpCSV );
    }

/* -------------------------------------------------------------------- */
/*      Check if the first record seems to be field definitions or      */
/*      not.  We assume it is field definitions if none of the          */
/*      values are strictly numeric.                                    */
/* -------------------------------------------------------------------- */
    char **papszTokens = NULL;
    int nFieldCount=0, iField;
    CPLValueType eType;

    if( !bNew )
    {
        const char *pszLine = NULL;
        char szDelimiter[2];
        szDelimiter[0] = chDelimiter; szDelimiter[1] = '\0';

        pszLine = CPLReadLineL( fpCSV );
        if ( pszLine != NULL )
        {
            /* Detect and remove UTF-8 BOM marker if found (#4623) */
            if (pszLine[0] == (char)0xEF &&
                pszLine[1] == (char)0xBB &&
                pszLine[2] == (char)0xBF)
            {
                pszLine += 3;
            }

            /* tokenize the strings and preserve quotes, so we can separate string from numeric */
            /* this is only used in the test for bHasFeldNames (bug #4361) */
            papszTokens = CSLTokenizeString2( pszLine, szDelimiter, 
                                              (CSLT_HONOURSTRINGS |
                                               CSLT_ALLOWEMPTYTOKENS |
                                               CSLT_PRESERVEQUOTES) );
            nFieldCount = CSLCount( papszTokens );
            bHasFieldNames = TRUE;

            for( iField = 0; iField < nFieldCount && bHasFieldNames; iField++ )
            {
                eType = CPLGetValueType(papszTokens[iField]);
                if ( (eType == CPL_VALUE_INTEGER ||
                      eType == CPL_VALUE_REAL) ) {
                    /* we have a numeric field, therefore do not consider the first line as field names */
                    bHasFieldNames = FALSE;
                }
            }

            CPLString osExt = OGRCSVDataSource::GetRealExtension(pszFilename);

            /* Eurostat .tsv files */
            if( EQUAL(osExt, "tsv") && nFieldCount > 1 &&
                strchr(papszTokens[0], ',') != NULL && strchr(papszTokens[0], '\\') != NULL )
            {
                bHasFieldNames = TRUE;
                bIsEurostatTSV = TRUE;
            }

            /* tokenize without quotes to get the actual values */
            CSLDestroy( papszTokens );
            // papszTokens = OGRCSVReadParseLineL( fpCSV, chDelimiter, FALSE );   
            papszTokens = CSLTokenizeString2( pszLine, szDelimiter, 
                                              (CSLT_HONOURSTRINGS |
                                               CSLT_ALLOWEMPTYTOKENS));
            nFieldCount = CSLCount( papszTokens );
        }
    }
    else
        bHasFieldNames = FALSE;

    if( !bNew && !bHasFieldNames )
        VSIRewindL( fpCSV );

/* -------------------------------------------------------------------- */
/*      Check for geonames.org tables                                   */
/* -------------------------------------------------------------------- */
    if( !bHasFieldNames && nFieldCount == 19 )
    {
        if (CPLGetValueType(papszTokens[0]) == CPL_VALUE_INTEGER &&
            CPLGetValueType(papszTokens[4]) == CPL_VALUE_REAL &&
            CPLGetValueType(papszTokens[5]) == CPL_VALUE_REAL &&
            CPLAtof(papszTokens[4]) >= -90 && CPLAtof(papszTokens[4]) <= 90 &&
            CPLAtof(papszTokens[5]) >= -180 && CPLAtof(papszTokens[4]) <= 180)
        {
            bHasFieldNames = TRUE;
            CSLDestroy(papszTokens);
            papszTokens = NULL;

            static const struct {
                const char* pszName;
                OGRFieldType eType;
            }
            asGeonamesFieldDesc[] =
            {
                { "GEONAMEID", OFTString },
                { "NAME", OFTString },
                { "ASCIINAME", OFTString },
                { "ALTNAMES", OFTString },
                { "LATITUDE", OFTReal },
                { "LONGITUDE", OFTReal },
                { "FEATCLASS", OFTString },
                { "FEATCODE", OFTString },
                { "COUNTRY", OFTString },
                { "CC2", OFTString },
                { "ADMIN1", OFTString },
                { "ADMIN2", OFTString },
                { "ADMIN3", OFTString },
                { "ADMIN4", OFTString },
                { "POPULATION", OFTReal },
                { "ELEVATION", OFTInteger },
                { "GTOPO30", OFTInteger },
                { "TIMEZONE", OFTString },
                { "MODDATE", OFTString }
            };
            for(iField = 0; iField < nFieldCount; iField++)
            {
                OGRFieldDefn oFieldDefn(asGeonamesFieldDesc[iField].pszName,
                                        asGeonamesFieldDesc[iField].eType);
                poFeatureDefn->AddFieldDefn(&oFieldDefn);
            }

            iLatitudeField = 4;
            iLongitudeField = 5;

            nFieldCount = 0;
        }
    }


/* -------------------------------------------------------------------- */
/*      Search a csvt file for types                                */
/* -------------------------------------------------------------------- */
    char** papszFieldTypes = NULL;
    if (!bNew) {
        char* dname = strdup(CPLGetDirname(pszFilename));
        char* fname = strdup(CPLGetBasename(pszFilename));
        VSILFILE* fpCSVT = VSIFOpenL(CPLFormFilename(dname, fname, ".csvt"), "r");
        free(dname);
        free(fname);
        if (fpCSVT!=NULL) {
            VSIRewindL(fpCSVT);
            papszFieldTypes = OGRCSVReadParseLineL(fpCSVT, ',', FALSE);
            VSIFCloseL(fpCSVT);
        }
    }
    

/* -------------------------------------------------------------------- */
/*      Build field definitions.                                        */
/* -------------------------------------------------------------------- */
    for( iField = 0; !bIsEurostatTSV && iField < nFieldCount; iField++ )
    {
        char *pszFieldName = NULL;
        char szFieldNameBuffer[100];

        if( bHasFieldNames )
        {
            pszFieldName = papszTokens[iField];

            // trim white space. 
            while( *pszFieldName == ' ' )
                pszFieldName++;

            while( pszFieldName[0] != '\0' 
                && pszFieldName[strlen(pszFieldName)-1] == ' ' )
                pszFieldName[strlen(pszFieldName)-1] = '\0';

            if (*pszFieldName == '\0')
                pszFieldName = NULL;
        }

        if (pszFieldName == NULL)
        {
            /* Re-read single column CSV files that have a trailing comma */
            /* in the header line */
            if( iField == 1 && nFieldCount == 2 && papszTokens[1][0] == '\0' )
            {
                nFieldCount = 1;
                break;
            }
            pszFieldName = szFieldNameBuffer;
            sprintf( szFieldNameBuffer, "field_%d", iField+1 );
        }

        OGRFieldDefn oField(pszFieldName, OFTString);
        if (papszFieldTypes!=NULL && iField<CSLCount(papszFieldTypes)) {

            char* pszLeftParenthesis = strchr(papszFieldTypes[iField], '(');
            if (pszLeftParenthesis && pszLeftParenthesis != papszFieldTypes[iField] &&
                pszLeftParenthesis[1] >= '0' && pszLeftParenthesis[1] <= '9')
            {
                int nWidth = 0;
                int nPrecision = 0;

                char* pszDot = strchr(pszLeftParenthesis, '.');
                if (pszDot) *pszDot = 0;
                *pszLeftParenthesis = 0;

                if (pszLeftParenthesis[-1] == ' ')
                    pszLeftParenthesis[-1] = 0;

                nWidth = atoi(pszLeftParenthesis+1);
                if (pszDot)
                    nPrecision = atoi(pszDot+1);

                oField.SetWidth(nWidth);
                oField.SetPrecision(nPrecision);
            }

            if (EQUAL(papszFieldTypes[iField], "Integer"))
                oField.SetType(OFTInteger);
            else if (EQUAL(papszFieldTypes[iField], "Real"))
                oField.SetType(OFTReal);
            else if (EQUAL(papszFieldTypes[iField], "String"))
                oField.SetType(OFTString);
            else if (EQUAL(papszFieldTypes[iField], "Date"))
                oField.SetType(OFTDate); 
            else if (EQUAL(papszFieldTypes[iField], "Time"))
                oField.SetType(OFTTime);
            else if (EQUAL(papszFieldTypes[iField], "DateTime"))
                oField.SetType(OFTDateTime);
            else
                CPLError(CE_Warning, CPLE_NotSupported, "Unknown type : %s", papszFieldTypes[iField]);
        }

        if( EQUAL(oField.GetNameRef(),"WKT")
            && oField.GetType() == OFTString 
            && iWktGeomReadField == -1 )
        {
            iWktGeomReadField = iField;
            poFeatureDefn->SetGeomType( wkbUnknown );
        }

        /*http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm specific */
        if ( pszNfdcGeomField != NULL &&
                  EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) &&
                  EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LatitudeS") )
            iNfdcLatitudeS = iField;
        else if ( pszNfdcGeomField != NULL &&
                  EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) &&
                  EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LongitudeS") )
            iNfdcLongitudeS = iField;

        /* GNIS specific */
        else if ( pszGeonamesGeomFieldPrefix != NULL &&
                  EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) &&
                  (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LAT_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE")) )
        {
            oField.SetType(OFTReal);
            iLatitudeField = iField;
        }
        else if ( pszGeonamesGeomFieldPrefix != NULL &&
                  EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) &&
                  (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONG_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE")) )
        {
            oField.SetType(OFTReal);
            iLongitudeField = iField;
        }

        poFeatureDefn->AddFieldDefn( &oField );

    }

    if ( iNfdcLatitudeS != -1 && iNfdcLongitudeS != -1 )
    {
        bDontHonourStrings = TRUE;
        poFeatureDefn->SetGeomType( wkbPoint );
    }
    else if ( iLatitudeField != -1 && iLongitudeField != -1 )
    {
        poFeatureDefn->SetGeomType( wkbPoint );
    }

/* -------------------------------------------------------------------- */
/*      Build field definitions for Eurostat TSV files.                 */
/* -------------------------------------------------------------------- */

    CPLString osSeqDim;
    for( iField = 0; bIsEurostatTSV && iField < nFieldCount; iField++ )
    {
        if( iField == 0 )
        {
            char** papszDims = CSLTokenizeString2( papszTokens[0], ",\\", 0 );
            nEurostatDims = CSLCount(papszDims) - 1;
            for(int iSubField = 0; iSubField < nEurostatDims; iSubField++)
            {
                OGRFieldDefn oField(papszDims[iSubField], OFTString);
                poFeatureDefn->AddFieldDefn( &oField );
            }

            osSeqDim = papszDims[nEurostatDims];
            CSLDestroy(papszDims);
        }
        else
        {
            if( papszTokens[iField][0] != '\0' 
                && papszTokens[iField][strlen(papszTokens[iField])-1] == ' ' )
                papszTokens[iField][strlen(papszTokens[iField])-1] = '\0';

            OGRFieldDefn oField(CPLSPrintf("%s_%s", osSeqDim.c_str(), papszTokens[iField]), OFTReal);
            poFeatureDefn->AddFieldDefn( &oField );

            OGRFieldDefn oField2(CPLSPrintf("%s_%s_flag", osSeqDim.c_str(), papszTokens[iField]), OFTString);
            poFeatureDefn->AddFieldDefn( &oField2 );
        }
    }

/* -------------------------------------------------------------------- */
/*      Cleanup.                                                        */
/* -------------------------------------------------------------------- */

    CSLDestroy( papszTokens );
    CSLDestroy( papszFieldTypes );
}
Example #27
0
/**
 * \brief Fetch a document from an url and return in a string.
 *
 * @param pszURL valid URL recognized by underlying download library (libcurl)
 * @param papszOptions option list as a NULL-terminated array of strings. May be NULL.
 *                     The following options are handled :
 * <ul>
 * <li>TIMEOUT=val, where val is in seconds</li>
 * <li>HEADERS=val, where val is an extra header to use when getting a web page.
 *                  For example "Accept: application/x-ogcwkt"
 * <li>HTTPAUTH=[BASIC/NTLM/ANY] to specify an authentication scheme to use.
 * <li>USERPWD=userid:password to specify a user and password for authentication
 * <li>POSTFIELDS=val, where val is a nul-terminated string to be passed to the server
 *                     with a POST request.
 * <li>PROXY=val, to make requests go through a proxy server, where val is of the
 *                form proxy.server.com:port_number
 * <li>PROXYUSERPWD=val, where val is of the form username:password
 * </ul>
 *
 * Alternatively, if not defined in the papszOptions arguments, the PROXY and PROXYUSERPWD
 * values are searched in the configuration options named GDAL_HTTP_PROXY and GDAL_HTTP_PROXYUSERPWD,
 * as proxy configuration belongs to networking setup and makes more sense at the configuration
 * option level than at the connection level.
 *
 * @return a CPLHTTPResult* structure that must be freed by CPLHTTPDestroyResult(),
 *         or NULL if libcurl support is disabled
 */
CPLHTTPResult *CPLHTTPFetch( const char *pszURL, char **papszOptions )

{
#ifndef HAVE_CURL
    (void) papszOptions;
    (void) pszURL;

    CPLError( CE_Failure, CPLE_NotSupported,
              "GDAL/OGR not compiled with libcurl support, remote requests not supported." );
    return NULL;
#else
    /* -------------------------------------------------------------------- */
    /*      Are we using a persistent named session?  If so, search for     */
    /*      or create it.                                                   */
    /*                                                                      */
    /*      Currently this code does not attempt to protect against         */
    /*      multiple threads asking for the same named session.  If that    */
    /*      occurs it will be in use in multiple threads at once which      */
    /*      might have bad consequences depending on what guarantees        */
    /*      libcurl gives - which I have not investigated.                  */
    /* -------------------------------------------------------------------- */
    CURL *http_handle = NULL;

    const char *pszPersistent = CSLFetchNameValue( papszOptions, "PERSISTENT" );
    if (pszPersistent)
    {
        CPLString osSessionName = pszPersistent;
        CPLMutexHolder oHolder( &hSessionMapMutex );

        if( oSessionMap.count( osSessionName ) == 0 )
        {
            oSessionMap[osSessionName] = curl_easy_init();
            CPLDebug( "HTTP", "Establish persistent session named '%s'.",
                      osSessionName.c_str() );
        }

        http_handle = oSessionMap[osSessionName];
    }
    else
        http_handle = curl_easy_init();

    /* -------------------------------------------------------------------- */
    /*      Setup the request.                                              */
    /* -------------------------------------------------------------------- */
    char szCurlErrBuf[CURL_ERROR_SIZE+1];
    CPLHTTPResult *psResult;
    struct curl_slist *headers=NULL;

    CPLDebug( "HTTP", "Fetch(%s)", pszURL );

    psResult = (CPLHTTPResult *) CPLCalloc(1,sizeof(CPLHTTPResult));

    curl_easy_setopt(http_handle, CURLOPT_URL, pszURL );


    const char *pszHttpVersion = CSLFetchNameValue( papszOptions, "HTTP_VERSION");
    if( pszHttpVersion && strcmp(pszHttpVersion, "1.0") == 0 )
        curl_easy_setopt(http_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 );

    /* Support control over HTTPAUTH */
    const char *pszHttpAuth = CSLFetchNameValue( papszOptions, "HTTPAUTH" );
    if( pszHttpAuth == NULL )
        /* do nothing */;

    /* CURLOPT_HTTPAUTH is defined in curl 7.11.0 or newer */
#if LIBCURL_VERSION_NUM >= 0x70B00
    else if( EQUAL(pszHttpAuth,"BASIC") )
        curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
    else if( EQUAL(pszHttpAuth,"NTLM") )
        curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM );
    else if( EQUAL(pszHttpAuth,"ANY") )
        curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY );
    else
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Unsupported HTTPAUTH value '%s', ignored.",
                  pszHttpAuth );
    }
#else
    else
    {
Example #28
0
CPLErr HFAAuxBuildOverviews( const char *pszOvrFilename,
                             GDALDataset *poParentDS,
                             GDALDataset **ppoODS,
                             int nBands, int *panBandList,
                             int nNewOverviews, int *panNewOverviewList,
                             const char *pszResampling,
                             GDALProgressFunc pfnProgress,
                             void *pProgressData )

{
/* ==================================================================== */
/*      If the .aux file doesn't exist yet then create it now.          */
/* ==================================================================== */
    if( *ppoODS == NULL )
    {
        GDALDataType eDT = GDT_Unknown;
/* -------------------------------------------------------------------- */
/*      Determine the band datatype, and verify that all bands are      */
/*      the same.                                                       */
/* -------------------------------------------------------------------- */
        int iBand;

        for( iBand = 0; iBand < nBands; iBand++ )
        {
            GDALRasterBand *poBand =
                poParentDS->GetRasterBand( panBandList[iBand] );

            if( iBand == 0 )
                eDT = poBand->GetRasterDataType();
            else
            {
                if( eDT != poBand->GetRasterDataType() )
                {
                    CPLError( CE_Failure, CPLE_NotSupported,
                              "HFAAuxBuildOverviews() doesn't support a mixture of band"
                              " data types." );
                    return CE_Failure;
                }
            }
        }

/* -------------------------------------------------------------------- */
/*      Create the HFA (.aux) file.  We create it with                  */
/*      COMPRESSED=YES so that no space will be allocated for the       */
/*      base band.                                                      */
/* -------------------------------------------------------------------- */
        GDALDriver *poHFADriver = (GDALDriver *) GDALGetDriverByName("HFA");
        if (poHFADriver == NULL)
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "HFA driver is unavailable." );
            return CE_Failure;
        }

        const char *apszOptions[4] = { "COMPRESSED=YES", "AUX=YES",
                                       NULL, NULL };

        CPLString osDepFileOpt = "DEPENDENT_FILE=";
        osDepFileOpt += CPLGetFilename(poParentDS->GetDescription());
        apszOptions[2] = osDepFileOpt.c_str();

        *ppoODS =
            poHFADriver->Create( pszOvrFilename,
                                 poParentDS->GetRasterXSize(),
                                 poParentDS->GetRasterYSize(),
                                 poParentDS->GetRasterCount(), eDT, (char **)apszOptions );

        if( *ppoODS == NULL )
            return CE_Failure;
    }

/* ==================================================================== */
/*      Create the layers.  We depend on the normal buildoverviews      */
/*      support for HFA to do this.  But we disable the internal        */
/*      computation of the imagery for these layers.                    */
/*                                                                      */
/*      We avoid regenerating the new layers here, because if we did    */
/*      it would use the base layer from the .aux file as the source    */
/*      data, and that is fake (all invalid tiles).                     */
/* ==================================================================== */
    CPLString oAdjustedResampling = "NO_REGEN:";
    oAdjustedResampling += pszResampling;

    CPLErr eErr =
        (*ppoODS)->BuildOverviews( oAdjustedResampling,
                                   nNewOverviews, panNewOverviewList,
                                   nBands, panBandList,
                                   pfnProgress, pProgressData );

    return eErr;
}
Example #29
0
GDALDataset* HF2Dataset::CreateCopy( const char * pszFilename,
                                     GDALDataset *poSrcDS, 
                                     int bStrict, char ** papszOptions, 
                                     GDALProgressFunc pfnProgress,
                                     void * pProgressData )
{
/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "HF2 driver does not support source dataset with zero band.\n");
        return NULL;
    }

    if (nBands != 1)
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
                  "HF2 driver only uses the first band of the dataset.\n");
        if (bStrict)
            return NULL;
    }

    if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Get source dataset info                                         */
/* -------------------------------------------------------------------- */

    int nXSize = poSrcDS->GetRasterXSize();
    int nYSize = poSrcDS->GetRasterYSize();
    double adfGeoTransform[6];
    poSrcDS->GetGeoTransform(adfGeoTransform);
    int bHasGeoTransform = !(adfGeoTransform[0] == 0 &&
                             adfGeoTransform[1] == 1 &&
                             adfGeoTransform[2] == 0 &&
                             adfGeoTransform[3] == 0 &&
                             adfGeoTransform[4] == 0 &&
                             adfGeoTransform[5] == 1);
    if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "HF2 driver does not support CreateCopy() from skewed or rotated dataset.\n");
        return NULL;
    }

    GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    GDALDataType eReqDT;
    float fVertPres = (float) 0.01;
    if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16)
    {
        fVertPres = 1;
        eReqDT = GDT_Int16;
    }
    else
        eReqDT = GDT_Float32;

/* -------------------------------------------------------------------- */
/*      Read creation options                                           */
/* -------------------------------------------------------------------- */
    const char* pszCompressed = CSLFetchNameValue(papszOptions, "COMPRESS");
    int bCompress = FALSE;
    if (pszCompressed)
        bCompress = CSLTestBoolean(pszCompressed);
    
    const char* pszVerticalPrecision = CSLFetchNameValue(papszOptions, "VERTICAL_PRECISION");
    if (pszVerticalPrecision)
    {
        fVertPres = (float) CPLAtofM(pszVerticalPrecision);
        if (fVertPres <= 0)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Unsupported value for VERTICAL_PRECISION. Defaulting to 0.01");
            fVertPres = (float) 0.01;
        }
        if (eReqDT == GDT_Int16 && fVertPres > 1)
            eReqDT = GDT_Float32;
    }

    const char* pszBlockSize = CSLFetchNameValue(papszOptions, "BLOCKSIZE");
    int nTileSize = 256;
    if (pszBlockSize)
    {
        nTileSize = atoi(pszBlockSize);
        if (nTileSize < 8 || nTileSize > 4096)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Unsupported value for BLOCKSIZE. Defaulting to 256");
            nTileSize = 256;
        }
    }

/* -------------------------------------------------------------------- */
/*      Parse source dataset georeferencing info                        */
/* -------------------------------------------------------------------- */

    int nExtendedHeaderLen = 0;
    if (bHasGeoTransform)
        nExtendedHeaderLen += 58;
    const char* pszProjectionRef = poSrcDS->GetProjectionRef();
    int nDatumCode = -2;
    int nUTMZone = 0;
    int bNorth = FALSE;
    int nEPSGCode = 0;
    int nExtentUnits = 1;
    if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0')
    {
        OGRSpatialReference oSRS;
        char* pszTemp = (char*) pszProjectionRef;
        if (oSRS.importFromWkt(&pszTemp) == OGRERR_NONE)
        {
            const char* pszValue = NULL;
            if( oSRS.GetAuthorityName( "GEOGCS|DATUM" ) != NULL
                && EQUAL(oSRS.GetAuthorityName( "GEOGCS|DATUM" ),"EPSG") )
                nDatumCode = atoi(oSRS.GetAuthorityCode( "GEOGCS|DATUM" ));
            else if ((pszValue = oSRS.GetAttrValue("GEOGCS|DATUM")) != NULL)
            {
                if (strstr(pszValue, "WGS") && strstr(pszValue, "84"))
                    nDatumCode = 6326;
            }

            nUTMZone = oSRS.GetUTMZone(&bNorth);
        }
        if( oSRS.GetAuthorityName( "PROJCS" ) != NULL
            && EQUAL(oSRS.GetAuthorityName( "PROJCS" ),"EPSG") )
            nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" ));

        if( oSRS.IsGeographic() )
        {
            nExtentUnits = 0;
        }
        else
        {
            double dfLinear = oSRS.GetLinearUnits();

            if( ABS(dfLinear - 0.3048) < 0.0000001 )
                nExtentUnits = 2;
            else if( ABS(dfLinear - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 )
                nExtentUnits = 3;
            else
                nExtentUnits = 1;
        }
    }
    if (nDatumCode != -2)
        nExtendedHeaderLen += 26;
    if (nUTMZone != 0)
        nExtendedHeaderLen += 26;
    if (nEPSGCode)
        nExtendedHeaderLen += 26;

/* -------------------------------------------------------------------- */
/*      Create target file                                              */
/* -------------------------------------------------------------------- */

    CPLString osFilename;
    if (bCompress)
    {
        osFilename = "/vsigzip/";
        osFilename += pszFilename;
    }
    else
        osFilename = pszFilename;
    VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "wb");
    if (fp == NULL)
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Cannot create %s", pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Write header                                                    */
/* -------------------------------------------------------------------- */

    VSIFWriteL("HF2\0", 4, 1, fp);
    WriteShort(fp, 0);
    WriteInt(fp, nXSize);
    WriteInt(fp, nYSize);
    WriteShort(fp, (GInt16) nTileSize);
    WriteFloat(fp, fVertPres);
    float fHorizScale = (float) ((fabs(adfGeoTransform[1]) + fabs(adfGeoTransform[5])) / 2);
    WriteFloat(fp, fHorizScale);
    WriteInt(fp, nExtendedHeaderLen);

/* -------------------------------------------------------------------- */
/*      Write extended header                                           */
/* -------------------------------------------------------------------- */

    char szBlockName[16 + 1];
    if (bHasGeoTransform)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-extents");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 34);
        WriteShort(fp, (GInt16) nExtentUnits);
        WriteDouble(fp, adfGeoTransform[0]);
        WriteDouble(fp, adfGeoTransform[0] + nXSize * adfGeoTransform[1]);
        WriteDouble(fp, adfGeoTransform[3] + nYSize * adfGeoTransform[5]);
        WriteDouble(fp, adfGeoTransform[3]);
    }
    if (nUTMZone != 0)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-utm");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) ((bNorth) ? nUTMZone : -nUTMZone));
    }
    if (nDatumCode != -2)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-datum");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) nDatumCode);
    }
    if (nEPSGCode != 0)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-epsg-prj");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) nEPSGCode);
    }

/* -------------------------------------------------------------------- */
/*      Copy imagery                                                    */
/* -------------------------------------------------------------------- */
    int nXBlocks = (nXSize + nTileSize - 1) / nTileSize;
    int nYBlocks = (nYSize + nTileSize - 1) / nTileSize;

    void* pTileBuffer = (void*) VSIMalloc(nTileSize * nTileSize * (GDALGetDataTypeSize(eReqDT) / 8));
    if (pTileBuffer == NULL)
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory");
        VSIFCloseL(fp);
        return NULL;
    }

    int i, j, k, l;
    CPLErr eErr = CE_None;
    for(j=0;j<nYBlocks && eErr == CE_None;j++)
    {
        for(i=0;i<nXBlocks && eErr == CE_None;i++)
        {
            int nReqXSize = MIN(nTileSize, nXSize - i * nTileSize);
            int nReqYSize = MIN(nTileSize, nYSize - j * nTileSize);
            eErr = poSrcDS->GetRasterBand(1)->RasterIO(GF_Read,
                                                i * nTileSize, MAX(0, nYSize - (j + 1) * nTileSize),
                                                nReqXSize, nReqYSize,
                                                pTileBuffer, nReqXSize, nReqYSize,
                                                eReqDT, 0, 0, NULL);
            if (eErr != CE_None)
                break;

            if (eReqDT == GDT_Int16)
            {
                WriteFloat(fp, 1); /* scale */
                WriteFloat(fp, 0); /* offset */
                for(k=0;k<nReqYSize;k++)
                {
                    int nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    GByte nWordSize = 1;
                    for(l=1;l<nReqXSize;l++)
                    {
                        int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        int nDiff = nVal - nLastVal;
                        if (nDiff < -32768 || nDiff > 32767)
                        {
                            nWordSize = 4;
                            break;
                        }
                        if (nDiff < -128 || nDiff > 127)
                            nWordSize = 2;
                        nLastVal = nVal;
                    }

                    VSIFWriteL(&nWordSize, 1, 1, fp);
                    nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    WriteInt(fp, nLastVal);
                    for(l=1;l<nReqXSize;l++)
                    {
                        int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        int nDiff = nVal - nLastVal;
                        if (nWordSize == 1)
                        {
                            CPLAssert(nDiff >= -128 && nDiff <= 127);
                            signed char chDiff = (signed char)nDiff;
                            VSIFWriteL(&chDiff, 1, 1, fp);
                        }
                        else if (nWordSize == 2)
                        {
                            CPLAssert(nDiff >= -32768 && nDiff <= 32767);
                            WriteShort(fp, (short)nDiff);
                        }
                        else
                        {
                            WriteInt(fp, nDiff);
                        }
                        nLastVal = nVal;
                    }
                }
            }
            else
            {
                float fMinVal = ((float*)pTileBuffer)[0];
                float fMaxVal = fMinVal;
                for(k=1;k<nReqYSize*nReqXSize;k++)
                {
                    float fVal = ((float*)pTileBuffer)[k];
                    if (fVal < fMinVal) fMinVal = fVal;
                    if (fVal > fMaxVal) fMaxVal = fVal;
                }

                float fIntRange = (fMaxVal - fMinVal) / fVertPres;
                float fScale = (fMinVal == fMaxVal) ? 1 : (fMaxVal - fMinVal) / fIntRange;
                float fOffset = fMinVal;
                WriteFloat(fp, fScale); /* scale */
                WriteFloat(fp, fOffset); /* offset */
                for(k=0;k<nReqYSize;k++)
                {
                    float fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    float fIntLastVal = (fLastVal - fOffset) / fScale;
                    CPLAssert(fIntLastVal >= -2147483648.0f && fIntLastVal <= 2147483647.0f);
                    int nLastVal = (int)fIntLastVal;
                    GByte nWordSize = 1;
                    for(l=1;l<nReqXSize;l++)
                    {
                        float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        float fIntVal = (fVal - fOffset) / fScale;
                        CPLAssert(fIntVal >= -2147483648.0f && fIntVal <= 2147483647.0f);
                        int nVal = (int)fIntVal;
                        int nDiff = nVal - nLastVal;
                        CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff);
                        if (nDiff < -32768 || nDiff > 32767)
                        {
                            nWordSize = 4;
                            break;
                        }
                        if (nDiff < -128 || nDiff > 127)
                            nWordSize = 2;
                        nLastVal = nVal;
                    }

                    VSIFWriteL(&nWordSize, 1, 1, fp);
                    fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    fIntLastVal = (fLastVal - fOffset) / fScale;
                    nLastVal = (int)fIntLastVal;
                    WriteInt(fp, nLastVal);
                    for(l=1;l<nReqXSize;l++)
                    {
                        float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        float fIntVal = (fVal - fOffset) / fScale;
                        int nVal = (int)fIntVal;
                        int nDiff = nVal - nLastVal;
                        CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff);
                        if (nWordSize == 1)
                        {
                            CPLAssert(nDiff >= -128 && nDiff <= 127);
                            signed char chDiff = (signed char)nDiff;
                            VSIFWriteL(&chDiff, 1, 1, fp);
                        }
                        else if (nWordSize == 2)
                        {
                            CPLAssert(nDiff >= -32768 && nDiff <= 32767);
                            WriteShort(fp, (short)nDiff);
                        }
                        else
                        {
                            WriteInt(fp, nDiff);
                        }
                        nLastVal = nVal;
                    }
                }
            }

            if( pfnProgress && !pfnProgress( (j * nXBlocks + i + 1) * 1.0 / (nXBlocks * nYBlocks), NULL, pProgressData ) )
            {
                eErr = CE_Failure;
                break;
            }
        }
    }

    CPLFree(pTileBuffer);

    VSIFCloseL(fp);

    if (eErr != CE_None)
        return NULL;

    return (GDALDataset*) GDALOpen(osFilename.c_str(), GA_ReadOnly);
}
Example #30
0
int ILI1Reader::ReadTable(CPL_UNUSED const char *layername) {
    char **tokens = NULL;
    int ret = TRUE;
    int warned = FALSE;
    int geomIdx = -1;

    OGRFeatureDefn *featureDef = curLayer->GetLayerDefn();
    OGRFeature *feature = NULL;
    bool bFeatureAdded = false;

    while (ret && (tokens = ReadParseLine()) != NULL)
    {
      const char *firsttok = CSLGetField(tokens, 0);
      if (EQUAL(firsttok, "OBJE"))
      {
        if (featureDef->GetFieldCount() == 0 && curLayer->GetFeatureCount() == 0)
        {
          CPLError( CE_Warning, CPLE_AppDefined,
                    "No field definition found for table: %s",
                    featureDef->GetName() );
          // Model not read - use heuristics.
          for( int fIndex=1; fIndex<CSLCount(tokens); fIndex++ )
          {
            char szFieldName[32];
            snprintf(szFieldName, sizeof(szFieldName), "Field%02d", fIndex);
            OGRFieldDefn oFieldDefn(szFieldName, OFTString);
            featureDef->AddFieldDefn(&oFieldDefn);
          }
        }
        //start new feature
        if( !bFeatureAdded )
            delete feature;
        feature = new OGRFeature(featureDef);

        for( int fIndex=1, fieldno = 0;
             fIndex<CSLCount(tokens) && fieldno < featureDef->GetFieldCount();
             fIndex++, fieldno++ )
        {
          if (!(tokens[fIndex][0] == codeUndefined && tokens[fIndex][1] == '\0')) {
#ifdef DEBUG_VERBOSE
            CPLDebug( "READ TABLE OGR_ILI", "Setting Field %d (Type %d): %s",
                      fieldno, featureDef->GetFieldDefn(fieldno)->GetType(),
                      tokens[fIndex] );
#endif
            if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTString) {
                // Interlis 1 encoding is ISO 8859-1 (Latin1) -> Recode to UTF-8
                char* pszRecoded = CPLRecode(
                    tokens[fIndex], CPL_ENC_ISO8859_1, CPL_ENC_UTF8);
                // Replace space marks
                for( char* pszString = pszRecoded;
                     *pszString != '\0';
                     pszString++ ) {
                    if (*pszString == codeBlank) *pszString = ' ';
                }
                feature->SetField(fieldno, pszRecoded);
                CPLFree(pszRecoded);
            } else {
              feature->SetField(fieldno, tokens[fIndex]);
            }
            if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTReal
                && fieldno > 0
                && featureDef->GetFieldDefn(fieldno-1)->GetType() == OFTReal) {
              // Check for Point geometry (Coord type).
              // If there is no ili model read,
              // we have no chance to detect the
              // geometry column.
              CPLString geomfldname
                  = featureDef->GetFieldDefn(fieldno)->GetNameRef();
              // Check if name ends with _1.
              if (geomfldname.size() >= 2 && geomfldname[geomfldname.size()-2]
                  == '_') {
                geomfldname = geomfldname.substr(0, geomfldname.size()-2);
                geomIdx = featureDef->GetGeomFieldIndex(geomfldname.c_str());
                if (geomIdx == -1)
                {
                  CPLError( CE_Warning, CPLE_AppDefined,
                            "No matching definition for field '%s' of "
                            "table %s found",
                            geomfldname.c_str(), featureDef->GetName() );
                }
              } else {
                geomIdx = -1;
              }
              if (geomIdx >= 0) {
                if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() ==
                    wkbPoint) {
                  // Add Point geometry.
                  OGRPoint *ogrPoint = new OGRPoint(
                      CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex]));
                  feature->SetGeomFieldDirectly(geomIdx, ogrPoint);
                } else if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() ==
                           wkbPoint25D && fieldno > 1 &&
                           featureDef->GetFieldDefn(fieldno-2)->GetType() ==
                           OFTReal) {
                  // Add 3D Point geometry.
                  OGRPoint *ogrPoint = new OGRPoint(
                      CPLAtof(tokens[fIndex-2]), CPLAtof(tokens[fIndex-1]),
                      CPLAtof(tokens[fIndex]) );
                  feature->SetGeomFieldDirectly(geomIdx, ogrPoint);
                }
              }
            }
          }
        }
        if (!warned && featureDef->GetFieldCount() != CSLCount(tokens)-1) {
          CPLError( CE_Warning, CPLE_AppDefined,
                    "Field count of table %s doesn't match. %d declared, "
                    "%d found (e.g. ignored LINEATTR)",
                    featureDef->GetName(), featureDef->GetFieldCount(),
                    CSLCount(tokens) - 1 );
          warned = TRUE;
        }
        if (feature->GetFieldCount() > 0) {
          // USE _TID as FID. TODO: respect IDENT field from model.
          feature->SetFID(feature->GetFieldAsInteger64(0));
        }
        curLayer->AddFeature(feature);
        bFeatureAdded = true;
        geomIdx = -1; //Reset
      }
      else if (EQUAL(firsttok, "STPT") && feature != NULL)
      {
        //Find next non-Point geometry
        if (geomIdx < 0) geomIdx = 0;
        while (geomIdx < featureDef->GetGeomFieldCount() &&
               featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) {
            geomIdx++;
        }
        OGRwkbGeometryType geomType
            = (geomIdx < featureDef->GetGeomFieldCount()) ?
               featureDef->GetGeomFieldDefn(geomIdx)->GetType() : wkbNone;
        if( CSLCount(tokens) >= 3 )
            ReadGeom(tokens, geomIdx, geomType, feature);
      }
      else if (EQUAL(firsttok, "ELIN"))
      {
        // Empty geom.
      }
      else if (EQUAL(firsttok, "EDGE") && feature != NULL)
      {
        CSLDestroy(tokens);
        tokens = ReadParseLine(); //STPT
        //Find next non-Point geometry
        do {
            geomIdx++;
        } while (geomIdx < featureDef->GetGeomFieldCount() &&
                 featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint);
        if( CSLCount(tokens) >= 3 )
            ReadGeom(tokens, geomIdx, wkbMultiLineString, feature);
      }
      else if (EQUAL(firsttok, "PERI"))
      {
      }
      else if (EQUAL(firsttok, "ETAB"))
      {
        CPLDebug( "OGR_ILI", "Total features: " CPL_FRMT_GIB,
                  curLayer->GetFeatureCount() );
        CSLDestroy(tokens);
        if( !bFeatureAdded )
            delete feature;
        return TRUE;
      }
      else
      {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Unexpected token: %s", firsttok );
      }

      CSLDestroy(tokens);
    }

    if( !bFeatureAdded )
        delete feature;

    return ret;
}