CPLErr RasdamanRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
				       void * pImage )
  
{
  //cerr << "Read block " << nBlockXOff << " " << nBlockYOff << endl;
  RasdamanDataset *poGDS = (RasdamanDataset *) poDS;
  
  r_Database database;  
  r_Transaction transaction;

  memset(pImage, 0, nRecordSize);

  try {
    database.set_servername(poGDS->host, poGDS->port);
    database.set_useridentification(poGDS->username, poGDS->userpassword);
    database.open(poGDS->databasename);
    transaction.begin();

    char x_lo[11], x_hi[11], y_lo[11], y_hi[11];
    int xPos = poGDS->xPos;
    int yPos = poGDS->yPos;
    
    sprintf(x_lo, "%d", nBlockXOff * nBlockXSize);
    sprintf(x_hi, "%d", (nBlockXOff+1) * nBlockXSize-1);
    sprintf(y_lo, "%d", nBlockYOff * nBlockYSize);
    sprintf(y_hi, "%d", (nBlockYOff+1) * nBlockYSize-1);
    CPLString queryString = getQuery(poGDS->queryParam, x_lo, x_hi, y_lo, y_hi);
  
    r_Set<r_Ref_Any> result_set;
    r_OQL_Query query (queryString);
    r_oql_execute (query, result_set);
    if (result_set.get_element_type_schema()->type_id() == r_Type::MARRAYTYPE) {
      r_Iterator<r_Ref_Any> iter = result_set.create_iterator();
      r_Ref<r_GMarray> gmdd = r_Ref<r_GMarray>(*iter);
      r_Minterval sp = gmdd->spatial_domain();
      r_Point extent = sp.get_extent();
      r_Point base = sp.get_origin();
      int tileX = extent[xPos];
      int tileY = extent[yPos];
      r_Point access = base;
      char *resultPtr;
      for (int j=0; j<tileY; ++j) {
	for (int i=0; i<tileX; ++i) {
	  resultPtr = (char*)pImage + (j*nBlockYSize+i)*typeSize;
	  access[xPos] = base[xPos]+i;
	  access[yPos] = base[yPos]+j;
	  const char *data = (*gmdd)[access] + typeOffset;
	  memcpy(resultPtr, data, typeSize);
	}
      }
    }
    
    transaction.commit();
    database.close();
  } catch (r_Error error) {
    CPLError(CE_Failure, CPLE_AppDefined, "%s", error.what());
    return CPLGetLastErrorType();
  }
  return CE_None;
}
Beispiel #2
0
CPLXMLNode *WCTSCollectRequest()

{
    if( getenv("REQUEST_METHOD") == NULL )
        WCTSEmitServiceException( "REQUEST_METHOD not set." );

    if( EQUAL(getenv("REQUEST_METHOD"),"GET") )
        return WCTSCollectKVPRequest();

/* -------------------------------------------------------------------- */
/*      Read the body of the POST message into a buffer.                */
/* -------------------------------------------------------------------- */
    int nContentLength = 0;
    char *pszXML = NULL;

    if( getenv("CONTENT_LENGTH") != NULL )
    {
        nContentLength = atoi(getenv("CONTENT_LENGTH"));

        pszXML = (char *) CPLMalloc(nContentLength+1);
        
        if( (int) fread(pszXML, 1, nContentLength, stdin) < nContentLength )
            WCTSEmitServiceException( "POST body is short." );

        pszXML[nContentLength] = '\0';
    }

    else
    {
        int nXMLMax, nXMLLen=0;

        nXMLMax = 100;
        pszXML = (char *) CPLMalloc(nXMLMax);
        
        while( !feof(stdin) )
        {
            pszXML[nXMLLen++] = fgetc(stdin);
            if( nXMLLen == nXMLMax )
            {
                nXMLMax = nXMLMax * 2;
                pszXML = (char *) CPLRealloc(pszXML, nXMLMax);
            }
        }

        pszXML[nXMLLen] = '\0';
    }

/* -------------------------------------------------------------------- */
/*      Convert into an XML document.                                   */
/* -------------------------------------------------------------------- */
    CPLErrorReset();

    CPLXMLNode *psTree = CPLParseXMLString( pszXML );
    CPLFree( pszXML );

    if( CPLGetLastErrorType() == CE_Failure )
        WCTSEmitServiceException( CPLGetLastErrorMsg() );

    return psTree;
}
Beispiel #3
0
int IMapInfoFile::TestUtf8Capability() const
{
    const char* pszEncoding( GetEncoding() );
    if( strlen( pszEncoding ) == 0 )
    {
        return FALSE;
    }

    CPLClearRecodeWarningFlags();
    CPLErrorReset();

    CPLPushErrorHandler(CPLQuietErrorHandler);
    char* pszTest( CPLRecode( "test", GetEncoding(), CPL_ENC_UTF8 ) );
    CPLPopErrorHandler();

    if( pszTest == nullptr )
    {
        return FALSE;
    }

    CPLFree( pszTest );

    if( CPLGetLastErrorType() != 0 )
    {
        return FALSE;
    }

    return TRUE;
}
/**********************************************************************
 *                   TABRawBinBlock::CommitAsDeleted()
 *
 * Commit current block to file using block type 4 (garbage block)
 *
 * Returns 0 if succesful or -1 if an error happened, in which case 
 * CPLError() will have been called.
 **********************************************************************/
int     TABRawBinBlock::CommitAsDeleted(GInt32 nNextBlockPtr)
{
    int nStatus = 0;

    CPLErrorReset();

    if ( m_pabyBuf == NULL )
    {
        CPLError(CE_Failure, CPLE_AssertionFailed, 
                 "CommitAsDeleted(): Block has not been initialized yet!");
        return -1;
    }

    /*-----------------------------------------------------------------
     * Create deleted block header
     *----------------------------------------------------------------*/
    GotoByteInBlock(0x000);
    WriteInt32(nNextBlockPtr);

    if( CPLGetLastErrorType() == CE_Failure )
        nStatus = CPLGetLastErrorNo();

    /*-----------------------------------------------------------------
     * OK, call the base class to write the block to disk.
     *----------------------------------------------------------------*/
    if (nStatus == 0)
        nStatus = TABRawBinBlock::CommitToFile();

    return nStatus;
}
Beispiel #5
0
/**********************************************************************
 *                   TABRawBinBlock::CommitAsDeleted()
 *
 * Commit current block to file using block type 4 (garbage block)
 *
 * Returns 0 if successful or -1 if an error happened, in which case
 * CPLError() will have been called.
 **********************************************************************/
int     TABRawBinBlock::CommitAsDeleted(GInt32 nNextBlockPtr)
{
    CPLErrorReset();

    if ( m_pabyBuf == nullptr )
    {
        CPLError(CE_Failure, CPLE_AssertionFailed,
                 "CommitAsDeleted(): Block has not been initialized yet!");
        return -1;
    }

    /*-----------------------------------------------------------------
     * Create deleted block header
     *----------------------------------------------------------------*/
    GotoByteInBlock(0x000);
    WriteInt16(TABMAP_GARB_BLOCK);    // Block type code
    WriteInt32(nNextBlockPtr);

    int nStatus = CPLGetLastErrorType() == CE_Failure ? -1 : 0;

    /*-----------------------------------------------------------------
     * OK, call the base class to write the block to disk.
     *----------------------------------------------------------------*/
    if (nStatus == 0)
    {
#ifdef DEBUG_VERBOSE
        CPLDebug("MITAB", "Committing GARBAGE block to offset %d", m_nFileOffset);
#endif
        nStatus = TABRawBinBlock::CommitToFile();
        m_nSizeUsed = 0;
    }

    return nStatus;
}
CPLErr VRTSourcedRasterBand::XMLInit( CPLXMLNode * psTree, 
                                      const char *pszVRTPath )

{
    CPLErr eErr;

    eErr = VRTRasterBand::XMLInit( psTree, pszVRTPath );
    if( eErr != CE_None )
        return eErr;
    
/* -------------------------------------------------------------------- */
/*      Validate a bit.                                                 */
/* -------------------------------------------------------------------- */
    if( psTree == NULL || psTree->eType != CXT_Element
        || (!EQUAL(psTree->pszValue,"VRTSourcedRasterBand") 
            && !EQUAL(psTree->pszValue,"VRTRasterBand")
	    && !EQUAL(psTree->pszValue,"VRTDerivedRasterBand")) )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Invalid node passed to VRTSourcedRasterBand::XMLInit()." );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Process sources.                                                */
/* -------------------------------------------------------------------- */
    CPLXMLNode  *psChild;
    VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" );
    
    for( psChild = psTree->psChild; 
         psChild != NULL && poDriver != NULL; 
         psChild = psChild->psNext)
    {
        VRTSource *poSource;

        if( psChild->eType != CXT_Element )
            continue;

        CPLErrorReset();
        poSource = poDriver->ParseSource( psChild, pszVRTPath );
        if( poSource != NULL )
            AddSource( poSource );
        else if( CPLGetLastErrorType() != CE_None )
            return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Done.                                                           */
/* -------------------------------------------------------------------- */
    if( nSources == 0 )
        CPLDebug( "VRT", "No valid sources found for band in VRT file:\n%s",
                  pszVRTPath );

    return CE_None;
}
Beispiel #7
0
OGRErr OGR_DS_SyncToDisk( OGRDataSourceH hDS )

{
    VALIDATE_POINTER1( hDS, "OGR_DS_SyncToDisk", OGRERR_INVALID_HANDLE );

    ((GDALDataset *) hDS)->FlushCache();
    if( CPLGetLastErrorType() != 0 )
        return OGRERR_FAILURE;
    else
        return OGRERR_NONE;
}
Beispiel #8
0
CPLErr RasdamanRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                       void * pImage )
{
  RasdamanDataset *poGDS = (RasdamanDataset *) poDS;

  memset(pImage, 0, nRecordSize);

  try {
    int x_lo = nBlockXOff * nBlockXSize,
        x_hi = MIN(poGDS->nRasterXSize, (nBlockXOff + 1) * nBlockXSize),
        y_lo = nBlockYOff * nBlockYSize,
        y_hi = MIN(poGDS->nRasterYSize, (nBlockYOff + 1) * nBlockYSize),
        offsetX = 0, offsetY = 0;
    
    r_Ref<r_GMarray>& gmdd = poGDS->request_array(x_lo, x_hi, y_lo, y_hi, offsetX, offsetY);

    int xPos = poGDS->xPos;
    int yPos = poGDS->yPos;
  
    r_Minterval sp = gmdd->spatial_domain();
    r_Point extent = sp.get_extent();
    r_Point base = sp.get_origin();
    
    int extentX = extent[xPos];
    int extentY = extent[yPos];

    CPLDebug("rasdaman", "Extents (%d, %d).", extentX, extentY);

    r_Point access = base;
    char *resultPtr;

    for(int y = y_lo; y < y_hi; ++y) {
      for(int x = x_lo; x < x_hi; ++x) {
        resultPtr = (char*)pImage + ((y - y_lo) * nBlockXSize + x - x_lo) * typeSize;
        //resultPtr = (char*) pImage
        access[xPos] = x;// base[xPos] + offsetX; TODO: check if required
        access[yPos] = y;// base[yPos] + offsetY;
        const char *data = (*gmdd)[access] + typeOffset;
        memcpy(resultPtr, data, typeSize);
      }
    }
  }
  catch (r_Error error) {
    CPLError(CE_Failure, CPLE_AppDefined, "%s", error.what());
    return CPLGetLastErrorType();
  }
  
  return CE_None;
}
Beispiel #9
0
 // Test that GDALWarp() detects error in flush cache
 template<> template<> void object::test<9>()
 {
     GDALDriver* poDriver = new GDALDriver();
     poDriver->SetDescription("DatasetWithErrorInFlushCache");
     poDriver->pfnCreate = DatasetWithErrorInFlushCache::Create;
     GetGDALDriverManager()->RegisterDriver( poDriver );
     const char* args[] = { "-of", "DatasetWithErrorInFlushCache", NULL };
     GDALWarpAppOptions* psOptions = GDALWarpAppOptionsNew((char**)args, NULL);
     GDALDatasetH hSrcDS = GDALOpen("../gcore/data/byte.tif", GA_ReadOnly);
     CPLErrorReset();
     CPLPushErrorHandler(CPLQuietErrorHandler);
     GDALDatasetH hOutDS = GDALWarp("/", NULL, 1, &hSrcDS, psOptions, NULL);
     CPLPopErrorHandler();
     GDALClose(hSrcDS);
     GDALWarpAppOptionsFree(psOptions);
     ensure(hOutDS == NULL);
     ensure(CPLGetLastErrorType() != CE_None);
     GetGDALDriverManager()->DeregisterDriver( poDriver );
     delete poDriver;
 }
Beispiel #10
0
/*!
  \param     info Object with information about the dataset to open.
  \return    Pointer to newly allocated GDALDataset or 0.

  Returns a nullptr if the file could not be opened.
*/
GDALDataset* PCRasterDataset::open(
         GDALOpenInfo* info)
{
  PCRasterDataset* dataset = NULL;

  if(info->fpL && info->nHeaderBytes >= static_cast<int>(CSF_SIZE_SIG) &&
     strncmp(reinterpret_cast<char*>( info->pabyHeader ), CSF_SIG, CSF_SIZE_SIG) == 0) {
    MOPEN_PERM mode = info->eAccess == GA_Update
         ? M_READ_WRITE
         : M_READ;

    MAP* map = mapOpen(info->pszFilename, mode);

    if(map) {
      CPLErrorReset();
      dataset = new PCRasterDataset(map);
      if( CPLGetLastErrorType() != CE_None )
      {
          delete dataset;
          return NULL;
      }
    }
  }

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information and overviews.                   */
/* -------------------------------------------------------------------- */
  if( dataset )
  {
      dataset->SetDescription( info->pszFilename );
      dataset->TryLoadXML();

      dataset->oOvManager.Initialize( dataset, info->pszFilename );
  }

  return dataset;
}
int SDTSRasterReader::GetBlock( int nXOffset, int nYOffset, void * pData )

{
    DDFRecord   *poRecord = NULL;
    int         nBytesPerValue;
    int         iTry;
    
    CPLAssert( nXOffset == 0 );

/* -------------------------------------------------------------------- */
/*      Analyse the datatype.                                           */
/* -------------------------------------------------------------------- */
    CPLAssert( EQUAL(szFMT,"BI16") || EQUAL(szFMT,"BFP32") );

    if( EQUAL(szFMT,"BI16") )
        nBytesPerValue = 2;
    else
        nBytesPerValue = 4;

    for(iTry=0;iTry<2;iTry++)
    {
    /* -------------------------------------------------------------------- */
    /*      Read through till we find the desired record.                   */
    /* -------------------------------------------------------------------- */
        CPLErrorReset();
        while( (poRecord = oDDFModule.ReadRecord()) != NULL )
        {
            if( poRecord->GetIntSubfield( "CELL", 0, "ROWI", 0 )
                == nYOffset + nYStart )
            {
                break;
            }
        }

        if( CPLGetLastErrorType() == CE_Failure )
            return FALSE;

    /* -------------------------------------------------------------------- */
    /*      If we didn't get what we needed just start over.                */
    /* -------------------------------------------------------------------- */
        if( poRecord == NULL )
        {
            if (iTry == 0)
                oDDFModule.Rewind();
            else
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "Cannot read scanline %d.  Raster access failed.\n",
                          nYOffset );
                return FALSE;
            }
        }
        else
        {
            break;
        }
    }

/* -------------------------------------------------------------------- */
/*      Validate the records size.  Does it represent exactly one       */
/*      scanline?                                                       */
/* -------------------------------------------------------------------- */
    DDFField    *poCVLS;

    poCVLS = poRecord->FindField( "CVLS" );
    if( poCVLS == NULL )
        return FALSE;

    if( poCVLS->GetRepeatCount() != nXSize )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Cell record is %d long, but we expected %d, the number\n"
                  "of pixels in a scanline.  Raster access failed.\n",
                  poCVLS->GetRepeatCount(), nXSize );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Does the CVLS field consist of exactly 1 B(16) field?           */
/* -------------------------------------------------------------------- */
    if( poCVLS->GetDataSize() < nBytesPerValue * nXSize
        || poCVLS->GetDataSize() > nBytesPerValue * nXSize + 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Cell record is not of expected format.  Raster access "
                  "failed.\n" );

        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Copy the data to the application buffer, and byte swap if       */
/*      required.                                                       */
/* -------------------------------------------------------------------- */
    memcpy( pData, poCVLS->GetData(), nXSize * nBytesPerValue );

#ifdef CPL_LSB
    if( nBytesPerValue == 2 )
    {
        for( int i = 0; i < nXSize; i++ )
        {
            ((GInt16 *) pData)[i] = CPL_MSBWORD16(((GInt16 *) pData)[i]);
        }
    }
    else
    {
        for( int i = 0; i < nXSize; i++ )
        {
            CPL_MSBPTR32( ((GByte *)pData) + i*4 );
        }
    }
#endif
    
    return TRUE;
}
Beispiel #12
0
int main( int argc, char ** argv )

{
    GDALDatasetH	hDataset;
    GDALRasterBandH	hBand;
    int			i, iBand;
    double		adfGeoTransform[6];
    GDALDriverH		hDriver;
    char		**papszMetadata;
    int                 bComputeMinMax = FALSE, bSample = FALSE;
    int                 bShowGCPs = TRUE, bShowMetadata = TRUE, bShowRAT=TRUE;
    int                 bStats = FALSE, bApproxStats = TRUE, iMDD;
    int                 bShowColorTable = TRUE, bComputeChecksum = FALSE;
    int                 bReportHistograms = FALSE;
    const char          *pszFilename = NULL;
    char              **papszExtraMDDomains = NULL, **papszFileList;
    const char  *pszProjection = NULL;
    OGRCoordinateTransformationH hTransform = NULL;

    /* Check that we are running against at least GDAL 1.5 */
    /* Note to developers : if we use newer API, please change the requirement */
    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500)
    {
        fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, "
                "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
        exit(1);
    }


    /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */
    /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */
    /* for the --format or --formats options */
    for( i = 1; i < argc; i++ )
    {
        if( EQUAL(argv[i],"--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP") )
        {
            CPLSetConfigOption( argv[i+1], argv[i+2] );

            i += 2;
        }
    }

    GDALAllRegister();

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

/* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
    for( i = 1; i < argc; i++ )
    {
        if( EQUAL(argv[i], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(argv[i], "-mm") )
            bComputeMinMax = TRUE;
        else if( EQUAL(argv[i], "-hist") )
            bReportHistograms = TRUE;
        else if( EQUAL(argv[i], "-stats") )
        {
            bStats = TRUE;
            bApproxStats = FALSE;
        }
        else if( EQUAL(argv[i], "-approx_stats") )
        {
            bStats = TRUE;
            bApproxStats = TRUE;
        }
        else if( EQUAL(argv[i], "-sample") )
            bSample = TRUE;
        else if( EQUAL(argv[i], "-checksum") )
            bComputeChecksum = TRUE;
        else if( EQUAL(argv[i], "-nogcp") )
            bShowGCPs = FALSE;
        else if( EQUAL(argv[i], "-nomd") )
            bShowMetadata = FALSE;
        else if( EQUAL(argv[i], "-norat") )
            bShowRAT = FALSE;
        else if( EQUAL(argv[i], "-noct") )
            bShowColorTable = FALSE;
        else if( EQUAL(argv[i], "-mdd") && i < argc-1 )
            papszExtraMDDomains = CSLAddString( papszExtraMDDomains,
                                                argv[++i] );
        else if( argv[i][0] == '-' )
            Usage();
        else if( pszFilename == NULL )
            pszFilename = argv[i];
        else
            Usage();
    }

    if( pszFilename == NULL )
        Usage();

/* -------------------------------------------------------------------- */
/*      Open dataset.                                                   */
/* -------------------------------------------------------------------- */
    hDataset = GDALOpen( pszFilename, GA_ReadOnly );
    
    if( hDataset == NULL )
    {
        fprintf( stderr,
                 "gdalinfo failed - unable to open '%s'.\n",
                 pszFilename );

        CSLDestroy( argv );
    
        GDALDumpOpenDatasets( stderr );

        GDALDestroyDriverManager();

        CPLDumpSharedList( NULL );

        exit( 1 );
    }
    
/* -------------------------------------------------------------------- */
/*      Report general info.                                            */
/* -------------------------------------------------------------------- */
    hDriver = GDALGetDatasetDriver( hDataset );
    printf( "Driver: %s/%s\n",
            GDALGetDriverShortName( hDriver ),
            GDALGetDriverLongName( hDriver ) );

    papszFileList = GDALGetFileList( hDataset );
    if( CSLCount(papszFileList) == 0 )
    {
        printf( "Files: none associated\n" );
    }
    else
    {
        printf( "Files: %s\n", papszFileList[0] );
        for( i = 1; papszFileList[i] != NULL; i++ )
            printf( "       %s\n", papszFileList[i] );
    }
    CSLDestroy( papszFileList );

    printf( "Size is %d, %d\n",
            GDALGetRasterXSize( hDataset ), 
            GDALGetRasterYSize( hDataset ) );

/* -------------------------------------------------------------------- */
/*      Report projection.                                              */
/* -------------------------------------------------------------------- */
    if( GDALGetProjectionRef( hDataset ) != NULL )
    {
        OGRSpatialReferenceH  hSRS;
        char		      *pszProjection;

        pszProjection = (char *) GDALGetProjectionRef( hDataset );

        hSRS = OSRNewSpatialReference(NULL);
        if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None )
        {
            char	*pszPrettyWkt = NULL;

            OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE );
            printf( "Coordinate System is:\n%s\n", pszPrettyWkt );
            CPLFree( pszPrettyWkt );
        }
        else
            printf( "Coordinate System is `%s'\n",
                    GDALGetProjectionRef( hDataset ) );

        OSRDestroySpatialReference( hSRS );
    }

/* -------------------------------------------------------------------- */
/*      Report Geotransform.                                            */
/* -------------------------------------------------------------------- */
    if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
    {
        if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 )
        {
            printf( "Origin = (%.15f,%.15f)\n",
                    adfGeoTransform[0], adfGeoTransform[3] );

            printf( "Pixel Size = (%.15f,%.15f)\n",
                    adfGeoTransform[1], adfGeoTransform[5] );
        }
        else
            printf( "GeoTransform =\n"
                    "  %.16g, %.16g, %.16g\n"
                    "  %.16g, %.16g, %.16g\n", 
                    adfGeoTransform[0],
                    adfGeoTransform[1],
                    adfGeoTransform[2],
                    adfGeoTransform[3],
                    adfGeoTransform[4],
                    adfGeoTransform[5] );
    }

/* -------------------------------------------------------------------- */
/*      Report GCPs.                                                    */
/* -------------------------------------------------------------------- */
    if( bShowGCPs && GDALGetGCPCount( hDataset ) > 0 )
    {
        if (GDALGetGCPProjection(hDataset) != NULL)
        {
            OGRSpatialReferenceH  hSRS;
            char		      *pszProjection;

            pszProjection = (char *) GDALGetGCPProjection( hDataset );

            hSRS = OSRNewSpatialReference(NULL);
            if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None )
            {
                char	*pszPrettyWkt = NULL;

                OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE );
                printf( "GCP Projection = \n%s\n", pszPrettyWkt );
                CPLFree( pszPrettyWkt );
            }
            else
                printf( "GCP Projection = %s\n",
                        GDALGetGCPProjection( hDataset ) );

            OSRDestroySpatialReference( hSRS );
        }

        for( i = 0; i < GDALGetGCPCount(hDataset); i++ )
        {
            const GDAL_GCP	*psGCP;
            
            psGCP = GDALGetGCPs( hDataset ) + i;

            printf( "GCP[%3d]: Id=%s, Info=%s\n"
                    "          (%.15g,%.15g) -> (%.15g,%.15g,%.15g)\n", 
                    i, psGCP->pszId, psGCP->pszInfo, 
                    psGCP->dfGCPPixel, psGCP->dfGCPLine, 
                    psGCP->dfGCPX, psGCP->dfGCPY, psGCP->dfGCPZ );
        }
    }

/* -------------------------------------------------------------------- */
/*      Report metadata.                                                */
/* -------------------------------------------------------------------- */
    papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, NULL ) : NULL;
    if( bShowMetadata && CSLCount(papszMetadata) > 0 )
    {
        printf( "Metadata:\n" );
        for( i = 0; papszMetadata[i] != NULL; i++ )
        {
            printf( "  %s\n", papszMetadata[i] );
        }
    }

    for( iMDD = 0; bShowMetadata && iMDD < CSLCount(papszExtraMDDomains); iMDD++ )
    {
        papszMetadata = GDALGetMetadata( hDataset, papszExtraMDDomains[iMDD] );
        if( CSLCount(papszMetadata) > 0 )
        {
            printf( "Metadata (%s):\n", papszExtraMDDomains[iMDD]);
            for( i = 0; papszMetadata[i] != NULL; i++ )
            {
                printf( "  %s\n", papszMetadata[i] );
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Report "IMAGE_STRUCTURE" metadata.                              */
/* -------------------------------------------------------------------- */
    papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "IMAGE_STRUCTURE" ) : NULL;
    if( bShowMetadata && CSLCount(papszMetadata) > 0 )
    {
        printf( "Image Structure Metadata:\n" );
        for( i = 0; papszMetadata[i] != NULL; i++ )
        {
            printf( "  %s\n", papszMetadata[i] );
        }
    }

/* -------------------------------------------------------------------- */
/*      Report subdatasets.                                             */
/* -------------------------------------------------------------------- */
    papszMetadata = GDALGetMetadata( hDataset, "SUBDATASETS" );
    if( CSLCount(papszMetadata) > 0 )
    {
        printf( "Subdatasets:\n" );
        for( i = 0; papszMetadata[i] != NULL; i++ )
        {
            printf( "  %s\n", papszMetadata[i] );
        }
    }

/* -------------------------------------------------------------------- */
/*      Report geolocation.                                             */
/* -------------------------------------------------------------------- */
    papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "GEOLOCATION" ) : NULL;
    if( bShowMetadata && CSLCount(papszMetadata) > 0 )
    {
        printf( "Geolocation:\n" );
        for( i = 0; papszMetadata[i] != NULL; i++ )
        {
            printf( "  %s\n", papszMetadata[i] );
        }
    }

/* -------------------------------------------------------------------- */
/*      Report RPCs                                                     */
/* -------------------------------------------------------------------- */
    papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "RPC" ) : NULL;
    if( bShowMetadata && CSLCount(papszMetadata) > 0 )
    {
        printf( "RPC Metadata:\n" );
        for( i = 0; papszMetadata[i] != NULL; i++ )
        {
            printf( "  %s\n", papszMetadata[i] );
        }
    }

/* -------------------------------------------------------------------- */
/*      Setup projected to lat/long transform if appropriate.           */
/* -------------------------------------------------------------------- */
    if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
        pszProjection = GDALGetProjectionRef(hDataset);

    if( pszProjection != NULL && strlen(pszProjection) > 0 )
    {
        OGRSpatialReferenceH hProj, hLatLong = NULL;

        hProj = OSRNewSpatialReference( pszProjection );
        if( hProj != NULL )
            hLatLong = OSRCloneGeogCS( hProj );

        if( hLatLong != NULL )
        {
            CPLPushErrorHandler( CPLQuietErrorHandler );
            hTransform = OCTNewCoordinateTransformation( hProj, hLatLong );
            CPLPopErrorHandler();
            
            OSRDestroySpatialReference( hLatLong );
        }

        if( hProj != NULL )
            OSRDestroySpatialReference( hProj );
    }

/* -------------------------------------------------------------------- */
/*      Report corners.                                                 */
/* -------------------------------------------------------------------- */
    printf( "Corner Coordinates:\n" );
    GDALInfoReportCorner( hDataset, hTransform, "Upper Left", 
                          0.0, 0.0 );
    GDALInfoReportCorner( hDataset, hTransform, "Lower Left", 
                          0.0, GDALGetRasterYSize(hDataset));
    GDALInfoReportCorner( hDataset, hTransform, "Upper Right", 
                          GDALGetRasterXSize(hDataset), 0.0 );
    GDALInfoReportCorner( hDataset, hTransform, "Lower Right", 
                          GDALGetRasterXSize(hDataset), 
                          GDALGetRasterYSize(hDataset) );
    GDALInfoReportCorner( hDataset, hTransform, "Center", 
                          GDALGetRasterXSize(hDataset)/2.0, 
                          GDALGetRasterYSize(hDataset)/2.0 );

    if( hTransform != NULL )
    {
        OCTDestroyCoordinateTransformation( hTransform );
        hTransform = NULL;
    }
    
/* ==================================================================== */
/*      Loop over bands.                                                */
/* ==================================================================== */
    for( iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ )
    {
        double      dfMin, dfMax, adfCMinMax[2], dfNoData;
        int         bGotMin, bGotMax, bGotNodata, bSuccess;
        int         nBlockXSize, nBlockYSize, nMaskFlags;
        double      dfMean, dfStdDev;
        GDALColorTableH	hTable;
        CPLErr      eErr;

        hBand = GDALGetRasterBand( hDataset, iBand+1 );

        if( bSample )
        {
            float afSample[10000];
            int   nCount;

            nCount = GDALGetRandomRasterSample( hBand, 10000, afSample );
            printf( "Got %d samples.\n", nCount );
        }
        
        GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize );
        printf( "Band %d Block=%dx%d Type=%s, ColorInterp=%s\n", iBand+1,
                nBlockXSize, nBlockYSize,
                GDALGetDataTypeName(
                    GDALGetRasterDataType(hBand)),
                GDALGetColorInterpretationName(
                    GDALGetRasterColorInterpretation(hBand)) );

        if( GDALGetDescription( hBand ) != NULL 
            && strlen(GDALGetDescription( hBand )) > 0 )
            printf( "  Description = %s\n", GDALGetDescription(hBand) );

        dfMin = GDALGetRasterMinimum( hBand, &bGotMin );
        dfMax = GDALGetRasterMaximum( hBand, &bGotMax );
        if( bGotMin || bGotMax || bComputeMinMax )
        {
            printf( "  " );
            if( bGotMin )
                printf( "Min=%.3f ", dfMin );
            if( bGotMax )
                printf( "Max=%.3f ", dfMax );
        
            if( bComputeMinMax )
            {
                CPLErrorReset();
                GDALComputeRasterMinMax( hBand, FALSE, adfCMinMax );
                if (CPLGetLastErrorType() == CE_None)
                {
                  printf( "  Computed Min/Max=%.3f,%.3f", 
                          adfCMinMax[0], adfCMinMax[1] );
                }
            }

            printf( "\n" );
        }

        eErr = GDALGetRasterStatistics( hBand, bApproxStats, bStats, 
                                        &dfMin, &dfMax, &dfMean, &dfStdDev );
        if( eErr == CE_None )
        {
            printf( "  Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f\n",
                    dfMin, dfMax, dfMean, dfStdDev );
        }

        if( bReportHistograms )
        {
            int nBucketCount, *panHistogram = NULL;

            eErr = GDALGetDefaultHistogram( hBand, &dfMin, &dfMax, 
                                            &nBucketCount, &panHistogram, 
                                            TRUE, GDALTermProgress, NULL );
            if( eErr == CE_None )
            {
                int iBucket;

                printf( "  %d buckets from %g to %g:\n  ",
                        nBucketCount, dfMin, dfMax );
                for( iBucket = 0; iBucket < nBucketCount; iBucket++ )
                    printf( "%d ", panHistogram[iBucket] );
                printf( "\n" );
                CPLFree( panHistogram );
            }
        }

        if ( bComputeChecksum)
        {
            printf( "  Checksum=%d\n",
                    GDALChecksumImage(hBand, 0, 0,
                                      GDALGetRasterXSize(hDataset),
                                      GDALGetRasterYSize(hDataset)));
        }

        dfNoData = GDALGetRasterNoDataValue( hBand, &bGotNodata );
        if( bGotNodata )
        {
            printf( "  NoData Value=%.18g\n", dfNoData );
        }

        if( GDALGetOverviewCount(hBand) > 0 )
        {
            int		iOverview;

            printf( "  Overviews: " );
            for( iOverview = 0; 
                 iOverview < GDALGetOverviewCount(hBand);
                 iOverview++ )
            {
                GDALRasterBandH	hOverview;
                const char *pszResampling = NULL;

                if( iOverview != 0 )
                    printf( ", " );

                hOverview = GDALGetOverview( hBand, iOverview );
                printf( "%dx%d", 
                        GDALGetRasterBandXSize( hOverview ),
                        GDALGetRasterBandYSize( hOverview ) );

                pszResampling = 
                    GDALGetMetadataItem( hOverview, "RESAMPLING", "" );

                if( pszResampling != NULL 
                    && EQUALN(pszResampling,"AVERAGE_BIT2",12) )
                    printf( "*" );
            }
            printf( "\n" );

            if ( bComputeChecksum)
            {
                printf( "  Overviews checksum: " );
                for( iOverview = 0; 
                    iOverview < GDALGetOverviewCount(hBand);
                    iOverview++ )
                {
                    GDALRasterBandH	hOverview;

                    if( iOverview != 0 )
                        printf( ", " );

                    hOverview = GDALGetOverview( hBand, iOverview );
                    printf( "%d",
                            GDALChecksumImage(hOverview, 0, 0,
                                      GDALGetRasterBandXSize(hOverview),
                                      GDALGetRasterBandYSize(hOverview)));
                }
                printf( "\n" );
            }
        }

        if( GDALHasArbitraryOverviews( hBand ) )
        {
            printf( "  Overviews: arbitrary\n" );
        }
        
        nMaskFlags = GDALGetMaskFlags( hBand );
        if( (nMaskFlags & (GMF_NODATA|GMF_ALL_VALID)) == 0 )
        {
            GDALRasterBandH hMaskBand = GDALGetMaskBand(hBand) ;

            printf( "  Mask Flags: " );
            if( nMaskFlags & GMF_PER_DATASET )
                printf( "PER_DATASET " );
            if( nMaskFlags & GMF_ALPHA )
                printf( "ALPHA " );
            if( nMaskFlags & GMF_NODATA )
                printf( "NODATA " );
            if( nMaskFlags & GMF_ALL_VALID )
                printf( "ALL_VALID " );
            printf( "\n" );

            if( hMaskBand != NULL &&
                GDALGetOverviewCount(hMaskBand) > 0 )
            {
                int		iOverview;

                printf( "  Overviews of mask band: " );
                for( iOverview = 0; 
                     iOverview < GDALGetOverviewCount(hMaskBand);
                     iOverview++ )
                {
                    GDALRasterBandH	hOverview;

                    if( iOverview != 0 )
                        printf( ", " );

                    hOverview = GDALGetOverview( hMaskBand, iOverview );
                    printf( "%dx%d", 
                            GDALGetRasterBandXSize( hOverview ),
                            GDALGetRasterBandYSize( hOverview ) );
                }
                printf( "\n" );
            }
        }

        if( strlen(GDALGetRasterUnitType(hBand)) > 0 )
        {
            printf( "  Unit Type: %s\n", GDALGetRasterUnitType(hBand) );
        }

        if( GDALGetRasterCategoryNames(hBand) != NULL )
        {
            char **papszCategories = GDALGetRasterCategoryNames(hBand);
            int i;

            printf( "  Categories:\n" );
            for( i = 0; papszCategories[i] != NULL; i++ )
                printf( "    %3d: %s\n", i, papszCategories[i] );
        }

        if( GDALGetRasterScale( hBand, &bSuccess ) != 1.0 
            || GDALGetRasterOffset( hBand, &bSuccess ) != 0.0 )
            printf( "  Offset: %.15g,   Scale:%.15g\n",
                    GDALGetRasterOffset( hBand, &bSuccess ),
                    GDALGetRasterScale( hBand, &bSuccess ) );

        papszMetadata = (bShowMetadata) ? GDALGetMetadata( hBand, NULL ) : NULL;
        if( bShowMetadata && CSLCount(papszMetadata) > 0 )
        {
            printf( "  Metadata:\n" );
            for( i = 0; papszMetadata[i] != NULL; i++ )
            {
                printf( "    %s\n", papszMetadata[i] );
            }
        }

        papszMetadata = (bShowMetadata) ? GDALGetMetadata( hBand, "IMAGE_STRUCTURE" ) : NULL;
        if( bShowMetadata && CSLCount(papszMetadata) > 0 )
        {
            printf( "  Image Structure Metadata:\n" );
            for( i = 0; papszMetadata[i] != NULL; i++ )
            {
                printf( "    %s\n", papszMetadata[i] );
            }
        }

        if( GDALGetRasterColorInterpretation(hBand) == GCI_PaletteIndex 
            && (hTable = GDALGetRasterColorTable( hBand )) != NULL )
        {
            int			i;

            printf( "  Color Table (%s with %d entries)\n", 
                    GDALGetPaletteInterpretationName(
                        GDALGetPaletteInterpretation( hTable )), 
                    GDALGetColorEntryCount( hTable ) );

            if (bShowColorTable)
            {
                for( i = 0; i < GDALGetColorEntryCount( hTable ); i++ )
                {
                    GDALColorEntry	sEntry;
    
                    GDALGetColorEntryAsRGB( hTable, i, &sEntry );
                    printf( "  %3d: %d,%d,%d,%d\n", 
                            i, 
                            sEntry.c1,
                            sEntry.c2,
                            sEntry.c3,
                            sEntry.c4 );
                }
            }
        }

        if( bShowRAT && GDALGetDefaultRAT( hBand ) != NULL )
        {
            GDALRasterAttributeTableH hRAT = GDALGetDefaultRAT( hBand );
            
            GDALRATDumpReadable( hRAT, NULL );
        }
    }

    GDALClose( hDataset );
    
    CSLDestroy( papszExtraMDDomains );
    CSLDestroy( argv );
    
    GDALDumpOpenDatasets( stderr );

    GDALDestroyDriverManager();

    CPLDumpSharedList( NULL );
    CPLCleanupTLS();

    exit( 0 );
}
Beispiel #13
0
GDALDataset *LANDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      We assume the user is pointing to the header (.pcb) file.       */
/*      Does this appear to be a pcb file?                              */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < ERD_HEADER_SIZE )
        return NULL;

    if( !STARTS_WITH_CI( reinterpret_cast<char *>(poOpenInfo->pabyHeader),
                         "HEADER" )
        && !STARTS_WITH_CI( reinterpret_cast<char *>(poOpenInfo->pabyHeader),
                            "HEAD74" ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    LANDataset *poDS = new LANDataset();

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Adopt the openinfo file pointer for use with this file.         */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    else
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" );

    if( poDS->fpImage == NULL )
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Do we need to byte swap the headers to local machine order?     */
/* -------------------------------------------------------------------- */
    int bBigEndian = poOpenInfo->pabyHeader[8] == 0;

    memcpy( poDS->pachHeader, poOpenInfo->pabyHeader, ERD_HEADER_SIZE );

#ifdef CPL_LSB
    const int bNeedSwap = bBigEndian;
#else
    const int bNeedSwap = !bBigEndian;
#endif

    if( bNeedSwap )
    {
        CPL_SWAP16PTR( poDS->pachHeader + 6 );
        CPL_SWAP16PTR( poDS->pachHeader + 8 );

        CPL_SWAP32PTR( poDS->pachHeader + 16 );
        CPL_SWAP32PTR( poDS->pachHeader + 20 );
        CPL_SWAP32PTR( poDS->pachHeader + 24 );
        CPL_SWAP32PTR( poDS->pachHeader + 28 );

        CPL_SWAP16PTR( poDS->pachHeader + 88 );
        CPL_SWAP16PTR( poDS->pachHeader + 90 );

        CPL_SWAP16PTR( poDS->pachHeader + 106 );
        CPL_SWAP32PTR( poDS->pachHeader + 108 );
        CPL_SWAP32PTR( poDS->pachHeader + 112 );
        CPL_SWAP32PTR( poDS->pachHeader + 116 );
        CPL_SWAP32PTR( poDS->pachHeader + 120 );
        CPL_SWAP32PTR( poDS->pachHeader + 124 );
    }

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    if( STARTS_WITH_CI(poDS->pachHeader,"HEADER") )
    {
        float fTmp = 0.0;
        memcpy(&fTmp, poDS->pachHeader + 16, 4);
        CPL_LSBPTR32(&fTmp);
        poDS->nRasterXSize = (int) fTmp;
        memcpy(&fTmp, poDS->pachHeader + 20, 4);
        CPL_LSBPTR32(&fTmp);
        poDS->nRasterYSize = (int) fTmp;
    }
    else
    {
        GInt32 nTmp = 0;
        memcpy(&nTmp, poDS->pachHeader + 16, 4);
        CPL_LSBPTR32(&nTmp);
        poDS->nRasterXSize = nTmp;
        memcpy(&nTmp, poDS->pachHeader + 20, 4);
        CPL_LSBPTR32(&nTmp);
        poDS->nRasterYSize = nTmp;
    }

    GInt16 nTmp16 = 0;
    memcpy(&nTmp16, poDS->pachHeader + 6, 2);
    CPL_LSBPTR16(&nTmp16);

    int nPixelOffset = 0;
    GDALDataType eDataType = GDT_Unknown;
    if( nTmp16 == 0 )
    {
        eDataType = GDT_Byte;
        nPixelOffset = 1;
    }
    else if( nTmp16 == 1 )  // 4 bit
    {
        eDataType = GDT_Byte;
        nPixelOffset = -1;
    }
    else if( nTmp16 == 2 )
    {
        nPixelOffset = 2;
        eDataType = GDT_Int16;
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unsupported pixel type (%d).",
                  nTmp16 );

        delete poDS;
        return NULL;
    }

    memcpy(&nTmp16, poDS->pachHeader + 8, 2);
    CPL_LSBPTR16(&nTmp16);
    const int nBandCount = nTmp16;

    if( !GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
        !GDALCheckBandCount(nBandCount, FALSE) )
    {
        delete poDS;
        return NULL;
    }

    if( nPixelOffset != -1 &&
        poDS->nRasterXSize > INT_MAX / (nPixelOffset * nBandCount) )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Int overflow occurred." );
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create band information object.                                 */
/* -------------------------------------------------------------------- */
    CPLErrorReset();
    for( int iBand = 1; iBand <= nBandCount; iBand++ )
    {
        if( nPixelOffset == -1 ) /* 4 bit case */
            poDS->SetBand( iBand,
                           new LAN4BitRasterBand( poDS, iBand ) );
        else
            poDS->SetBand(
                iBand,
                new RawRasterBand( poDS, iBand, poDS->fpImage,
                                   ERD_HEADER_SIZE + (iBand-1)
                                   * nPixelOffset * poDS->nRasterXSize,
                                   nPixelOffset,
                                   poDS->nRasterXSize*nPixelOffset*nBandCount,
                                   eDataType, !bNeedSwap, TRUE ));
        if( CPLGetLastErrorType() != CE_None )
        {
            delete poDS;
            return NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->CheckForStatistics();
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

/* -------------------------------------------------------------------- */
/*      Try to interpret georeferencing.                                */
/* -------------------------------------------------------------------- */
    float fTmp = 0.0;

    memcpy(&fTmp, poDS->pachHeader + 112, 4);
    CPL_LSBPTR32(&fTmp);
    poDS->adfGeoTransform[0] = fTmp;
    memcpy(&fTmp, poDS->pachHeader + 120, 4);
    CPL_LSBPTR32(&fTmp);
    poDS->adfGeoTransform[1] = fTmp;
    poDS->adfGeoTransform[2] = 0.0;
    memcpy(&fTmp, poDS->pachHeader + 116, 4);
    CPL_LSBPTR32(&fTmp);
    poDS->adfGeoTransform[3] = fTmp;
    poDS->adfGeoTransform[4] = 0.0;
    memcpy(&fTmp, poDS->pachHeader + 124, 4);
    CPL_LSBPTR32(&fTmp);
    poDS->adfGeoTransform[5] = - fTmp;

    // adjust for center of pixel vs. top left corner of pixel.
    poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5;
    poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5;

/* -------------------------------------------------------------------- */
/*      If we didn't get any georeferencing, try for a worldfile.       */
/* -------------------------------------------------------------------- */
    if( poDS->adfGeoTransform[1] == 0.0
        || poDS->adfGeoTransform[5] == 0.0 )
    {
        if( !GDALReadWorldFile( poOpenInfo->pszFilename, NULL,
                                poDS->adfGeoTransform ) )
            GDALReadWorldFile( poOpenInfo->pszFilename, ".wld",
                               poDS->adfGeoTransform );
    }

/* -------------------------------------------------------------------- */
/*      Try to come up with something for the coordinate system.        */
/* -------------------------------------------------------------------- */
    memcpy(&nTmp16, poDS->pachHeader + 88, 2);
    CPL_LSBPTR16(&nTmp16);
    int nCoordSys = nTmp16;

    if( nCoordSys == 0 )
    {
        poDS->pszProjection = CPLStrdup(SRS_WKT_WGS84);
    }
    else if( nCoordSys == 1 )
    {
        poDS->pszProjection =
            CPLStrdup( "LOCAL_CS[\"UTM - Zone Unknown\",UNIT[\"Meter\",1]]" );
    }
    else if( nCoordSys == 2 )
    {
        poDS->pszProjection =
            CPLStrdup(
                "LOCAL_CS[\"State Plane - Zone Unknown\","
                "UNIT[\"US survey foot\",0.3048006096012192]]" );
    }
    else
    {
        poDS->pszProjection =
            CPLStrdup( "LOCAL_CS[\"Unknown\",UNIT[\"Meter\",1]]" );
    }

/* -------------------------------------------------------------------- */
/*      Check for a trailer file with a colormap in it.                 */
/* -------------------------------------------------------------------- */
    char *pszPath = CPLStrdup( CPLGetPath(poOpenInfo->pszFilename) );
    char *pszBasename = CPLStrdup( CPLGetBasename(poOpenInfo->pszFilename) );
    const char *pszTRLFilename =
        CPLFormCIFilename( pszPath, pszBasename, "trl" );
    VSILFILE *fpTRL = VSIFOpenL( pszTRLFilename, "rb" );
    if( fpTRL != NULL )
    {
        char szTRLData[896] = { '\0' };

        CPL_IGNORE_RET_VAL(VSIFReadL( szTRLData, 1, 896, fpTRL ));
        CPL_IGNORE_RET_VAL(VSIFCloseL( fpTRL ));

        GDALColorTable *poCT = new GDALColorTable();
        for( int iColor = 0; iColor < 256; iColor++ )
        {
            GDALColorEntry sEntry = { 0, 0, 0, 0};

            sEntry.c2 = reinterpret_cast<GByte *>(szTRLData)[iColor+128];
            sEntry.c1 = reinterpret_cast<GByte *>(szTRLData)[iColor+128+256];
            sEntry.c3 = reinterpret_cast<GByte *>(szTRLData)[iColor+128+512];
            sEntry.c4 = 255;
            poCT->SetColorEntry( iColor, &sEntry );

            // Only 16 colors in 4bit files.
            if( nPixelOffset == -1 && iColor == 15 )
                break;
        }

        poDS->GetRasterBand(1)->SetColorTable( poCT );
        poDS->GetRasterBand(1)->SetColorInterpretation( GCI_PaletteIndex );

        delete poCT;
    }

    CPLFree( pszPath );
    CPLFree( pszBasename );

    return poDS;
}
int OGRGPSBabelDataSource::Open( const char * pszDatasourceName, int bUpdateIn)

{
    int bExplicitFeatures = FALSE;
    int bWaypoints = TRUE, bTracks = TRUE, bRoutes = TRUE;
    if (bUpdateIn)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GPSBabel driver does not support opening a file in update mode");
        return FALSE;
    }

    if (!EQUALN(pszDatasourceName, "GPSBABEL:", 9))
    {
        VSILFILE* fp = VSIFOpenL(pszDatasourceName, "rb");
        if (fp == NULL)
            return FALSE;

        char szHeader[1024 + 1];
        memset(szHeader, 0, 1024+1);
        VSIFReadL(szHeader, 1, 1024, fp);
        if (memcmp(szHeader, "MsRcd", 5) == 0)
            pszGPSBabelDriverName = CPLStrdup("mapsource");
        else if (memcmp(szHeader, "MsRcf", 5) == 0)
            pszGPSBabelDriverName = CPLStrdup("gdb");
        else if (strstr(szHeader, "<osm") != NULL)
            pszGPSBabelDriverName = CPLStrdup("osm");
        else if (strstr(szHeader, "$GPGSA") != NULL ||
                 strstr(szHeader, "$GPGGA") != NULL)
            pszGPSBabelDriverName = CPLStrdup("nmea");
        else if (EQUALN(szHeader, "OziExplorer",11))
            pszGPSBabelDriverName = CPLStrdup("ozi");
        else if (strstr(szHeader, "Grid") && strstr(szHeader, "Datum") && strstr(szHeader, "Header"))
            pszGPSBabelDriverName = CPLStrdup("garmin_txt");
        else if (szHeader[0] == 13 && szHeader[10] == 'M' && szHeader[11] == 'S' &&
                 (szHeader[12] >= '0' && szHeader[12] <= '9') &&
                 (szHeader[13] >= '0' && szHeader[13] <= '9') &&
                 szHeader[12] * 10 + szHeader[13] >= 30 &&
                 (szHeader[14] == 1 || szHeader[14] == 2) && szHeader[15] == 0 &&
                 szHeader[16] == 0 && szHeader[17] == 0)
            pszGPSBabelDriverName = CPLStrdup("mapsend");
        else if (strstr(szHeader, "$PMGNWPL") != NULL ||
                 strstr(szHeader, "$PMGNRTE") != NULL)
            pszGPSBabelDriverName = CPLStrdup("magellan");

        VSIFCloseL(fp);

        if (pszGPSBabelDriverName == NULL)
        {
            return FALSE;
        }

        pszFilename = CPLStrdup(pszDatasourceName);
    }

    pszName = CPLStrdup( pszDatasourceName );

    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 optionnal features= option */
        if (EQUALN(pszSep+1, "features=", 9))
        {
            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;
            int bErr = FALSE;
            bExplicitFeatures = TRUE;
            bWaypoints = bTracks = 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;
        }

        pszFilename = CPLStrdup(pszSep+1);
    }

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

    int 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();
        int 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 = OGRSFDriverRegistrar::Open(osTmpFileName.c_str());
        if (poGPXDS)
        {
            OGRLayer* poLayer;

            if (bWaypoints)
            {
                poLayer = poGPXDS->GetLayerByName("waypoints");
                if (poLayer != NULL && poLayer->GetFeatureCount() != 0)
                    apoLayers[nLayers++] = poLayer;
            }

            if (bRoutes)
            {
                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)
            {
                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;
}
Beispiel #15
0
int OGRNASDataSource::Open( const char * pszNewName )

{
    poReader = CreateNASReader();
    if( poReader == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "File %s appears to be NAS but the NAS reader cannot\n"
                  "be instantiated, likely because Xerces support was not\n"
                  "configured in.",
                  pszNewName );
        return FALSE;
    }

    poReader->SetSourceFile( pszNewName );

    pszName = CPLStrdup( pszNewName );

/* -------------------------------------------------------------------- */
/*      Can we find a NAS Feature Schema (.gfs) for the input file?     */
/* -------------------------------------------------------------------- */
    bool bHaveSchema = false;

    const char *pszGFSFilename = CPLResetExtension( pszNewName, "gfs" );
    VSIStatBuf sGFSStatBuf;
    if( CPLStat( pszGFSFilename, &sGFSStatBuf ) == 0 )
    {
        VSIStatBuf sNASStatBuf;
        if( CPLStat( pszNewName, &sNASStatBuf ) == 0 &&
            sNASStatBuf.st_mtime > sGFSStatBuf.st_mtime )
        {
            CPLDebug( "NAS",
                      "Found %s but ignoring because it appears\n"
                      "be older than the associated NAS file.",
                      pszGFSFilename );
        }
        else
        {
            bHaveSchema = poReader->LoadClasses( pszGFSFilename );
        }
    }

/* -------------------------------------------------------------------- */
/*      Force a first pass to establish the schema.  Eventually we      */
/*      will have mechanisms for remembering the schema and related     */
/*      information.                                                    */
/* -------------------------------------------------------------------- */
    CPLErrorReset();
    if( !bHaveSchema
        && !poReader->PrescanForSchema( TRUE )
        && CPLGetLastErrorType() == CE_Failure )
    {
        // Assume an error has been reported.
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Save the schema file if possible.  Do not make a fuss if we     */
/*      cannot.  It could be read-only directory or something.          */
/* -------------------------------------------------------------------- */
    if( !bHaveSchema && poReader->GetClassCount() > 0 )
    {
        FILE *fp = NULL;

        pszGFSFilename = CPLResetExtension( pszNewName, "gfs" );
        if( CPLStat( pszGFSFilename, &sGFSStatBuf ) != 0
            && (fp = VSIFOpen( pszGFSFilename, "wt" )) != NULL )
        {
            VSIFClose( fp );
            poReader->SaveClasses( pszGFSFilename );
        }
        else
        {
            CPLDebug( "NAS",
                      "Not saving %s files already exists or can't be created.",
                      pszGFSFilename );
        }
    }

/* -------------------------------------------------------------------- */
/*      Translate the NASFeatureClasses into layers.                    */
/* -------------------------------------------------------------------- */
    papoLayers = (OGRLayer **)
        CPLCalloc( sizeof(OGRNASLayer *), poReader->GetClassCount()+1 );
    nLayers = 0;

    while( nLayers < poReader->GetClassCount() )
    {
        papoLayers[nLayers] = TranslateNASSchema(poReader->GetClass(nLayers));
        nLayers++;
    }

    poRelationLayer = new OGRNASRelationLayer( this );

    // keep delete the last layer
    if( nLayers>0 && EQUAL( papoLayers[nLayers-1]->GetName(), "Delete" ) )
    {
      papoLayers[nLayers]   = papoLayers[nLayers-1];
      papoLayers[nLayers-1] = poRelationLayer;
    }
    else
    {
      papoLayers[nLayers] = poRelationLayer;
    }

    nLayers++;

    return TRUE;
}
Beispiel #16
0
GDALDataset *KRODataset::Open( GDALOpenInfo * poOpenInfo )

{
    if( !Identify( poOpenInfo ) || poOpenInfo->fpL == nullptr )
        return nullptr;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    KRODataset *poDS = new KRODataset();
    poDS->eAccess = poOpenInfo->eAccess;
    poDS->fpImage = poOpenInfo->fpL;
    poOpenInfo->fpL = nullptr;

/* -------------------------------------------------------------------- */
/*      Read the file header.                                           */
/* -------------------------------------------------------------------- */
    char achHeader[20] = { '\0' };
    CPL_IGNORE_RET_VAL(VSIFReadL( achHeader, 1, 20, poDS->fpImage ));

    int nXSize;
    memcpy(&nXSize, achHeader + 4, 4);
    CPL_MSBPTR32( &nXSize );

    int nYSize = 0;
    memcpy(&nYSize, achHeader + 8, 4);
    CPL_MSBPTR32( &nYSize );

    int nDepth = 0;
    memcpy(&nDepth, achHeader + 12, 4);
    CPL_MSBPTR32( &nDepth );

    int nComp = 0;
    memcpy(&nComp, achHeader + 16, 4);
    CPL_MSBPTR32( &nComp );

    if( !GDALCheckDatasetDimensions(nXSize, nYSize) ||
        !GDALCheckBandCount(nComp, FALSE) )
    {
        delete poDS;
        return nullptr;
    }

    poDS->nRasterXSize = nXSize;
    poDS->nRasterYSize = nYSize;

    GDALDataType eDT = GDT_Unknown;
    if( nDepth == 8 )
    {
        eDT = GDT_Byte;
    }
    else if( nDepth == 16 )
    {
        eDT = GDT_UInt16;
    }
    else if( nDepth == 32 )
    {
        eDT = GDT_Float32;
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unhandled depth : %d", nDepth );
        delete poDS;
        return nullptr;
    }

    const int nDataTypeSize = nDepth / 8;

    if( nComp == 0 || nDataTypeSize == 0 ||
        poDS->nRasterXSize > INT_MAX / (nComp * nDataTypeSize) )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Too large width / number of bands" );
        delete poDS;
        return nullptr;
    }

    vsi_l_offset nExpectedSize = static_cast<vsi_l_offset>(poDS->nRasterXSize)
        * poDS->nRasterYSize * nComp * nDataTypeSize + 20;
    VSIFSeekL(poDS->fpImage, 0, SEEK_END);
    if( VSIFTellL(poDS->fpImage) < nExpectedSize )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "File too short" );
        delete poDS;
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Create bands.                                                   */
/* -------------------------------------------------------------------- */
    CPLErrorReset();
    for( int iBand = 0; iBand < nComp; iBand++ )
    {
        RawRasterBand *poBand =
            new RawRasterBand( poDS, iBand+1, poDS->fpImage,
                               20 + nDataTypeSize * iBand,
                               nComp * nDataTypeSize,
                               poDS->nRasterXSize * nComp * nDataTypeSize,
                               eDT, !CPL_IS_LSB, RawRasterBand::OwnFP::NO );
        if( nComp == 3 || nComp == 4 )
        {
            poBand->SetColorInterpretation( static_cast<GDALColorInterp>(GCI_RedBand + iBand) );
        }
        poDS->SetBand( iBand+1, poBand );
        if( CPLGetLastErrorType() != CE_None )
        {
            delete poDS;
            return nullptr;
        }
    }

    if( nComp > 1 )
        poDS->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return poDS;
}
Beispiel #17
0
bool GMLASConfiguration::Load(const char* pszFilename)
{
    // Allow configuration to be inlined
    CPLXMLNode* psRoot = STARTS_WITH(pszFilename, "<Configuration>") ?
                                CPLParseXMLString(pszFilename) :
                                CPLParseXMLFile(pszFilename);
    if( psRoot == NULL )
    {
        Finalize();
        return false;
    }
    CPLXMLTreeCloser oCloser(psRoot);

    // Validate the configuration file
    if( CPLTestBool(CPLGetConfigOption("GDAL_XML_VALIDATION", "YES")) )
    {
        const char* pszXSD = CPLFindFile( "gdal", "gmlasconf.xsd" );
        if( pszXSD != NULL )
        {
            std::vector<CPLString> aosErrors;
            const CPLErr eErrClass = CPLGetLastErrorType();
            const CPLErrorNum nErrNum = CPLGetLastErrorNo();
            const CPLString osErrMsg = CPLGetLastErrorMsg();
            CPLPushErrorHandlerEx(GMLASConfigurationErrorHandler, &aosErrors);
            int bRet = CPLValidateXML(pszFilename, pszXSD, NULL);
            CPLPopErrorHandler();
            if( !bRet && aosErrors.size() > 0 &&
                strstr(aosErrors[0].c_str(), "missing libxml2 support") == NULL )
            {
                for(size_t i = 0; i < aosErrors.size(); i++)
                {
                    CPLError(CE_Warning, CPLE_AppDefined,
                             "%s", aosErrors[i].c_str());
                }
            }
            else
            {
                CPLErrorSetState(eErrClass, nErrNum, osErrMsg);
            }
        }
    }

    m_bAllowRemoteSchemaDownload = CPLGetXMLBoolValue(psRoot,
                                "=Configuration.AllowRemoteSchemaDownload",
                                ALLOW_REMOTE_SCHEMA_DOWNLOAD_DEFAULT );

    m_bAllowXSDCache = CPLGetXMLBoolValue( psRoot,
                                           "=Configuration.SchemaCache.enabled",
                                           ALLOW_XSD_CACHE_DEFAULT );
    if( m_bAllowXSDCache )
    {
        m_osXSDCacheDirectory =
            CPLGetXMLValue(psRoot, "=Configuration.SchemaCache.Directory",
                           "");
    }

    m_bValidate = CPLGetXMLBoolValue( psRoot,
                                      "=Configuration.Validation.enabled",
                                      VALIDATE_DEFAULT );

    if( m_bValidate )
    {
        m_bFailIfValidationError = CPLGetXMLBoolValue(psRoot,
                                        "=Configuration.Validation.FailIfError",
                                        FAIL_IF_VALIDATION_ERROR_DEFAULT );
    }

    m_bExposeMetadataLayers = CPLGetXMLBoolValue( psRoot,
                                      "=Configuration.ExposeMetadataLayers",
                                      EXPOSE_METADATA_LAYERS_DEFAULT );

    m_bAlwaysGenerateOGRId = CPLGetXMLBoolValue( psRoot,
                                "=Configuration.LayerBuildingRules.AlwaysGenerateOGRId",
                                ALWAYS_GENERATE_OGR_ID_DEFAULT );

    m_bRemoveUnusedLayers = CPLGetXMLBoolValue( psRoot,
                                "=Configuration.LayerBuildingRules.RemoveUnusedLayers",
                                REMOVE_UNUSED_LAYERS_DEFAULT );

    m_bRemoveUnusedFields = CPLGetXMLBoolValue( psRoot,
                                "=Configuration.LayerBuildingRules.RemoveUnusedFields",
                                REMOVE_UNUSED_FIELDS_DEFAULT );

    m_bUseArrays = CPLGetXMLBoolValue( psRoot,
                                "=Configuration.LayerBuildingRules.UseArrays",
                                USE_ARRAYS_DEFAULT );
    m_bIncludeGeometryXML = CPLGetXMLBoolValue( psRoot,
                       "=Configuration.LayerBuildingRules.GML.IncludeGeometryXML",
                       INCLUDE_GEOMETRY_XML_DEFAULT );
    m_bInstantiateGMLFeaturesOnly = CPLGetXMLBoolValue( psRoot,
                "=Configuration.LayerBuildingRules.GML.InstantiateGMLFeaturesOnly",
                INSTANTIATE_GML_FEATURES_ONLY_DEFAULT );
    m_nIdentifierMaxLength = atoi( CPLGetXMLValue( psRoot,
                "=Configuration.LayerBuildingRules.IdentifierMaxLength",
                "0" ) );
    m_bCaseInsensitiveIdentifier = CPLGetXMLBoolValue( psRoot,
                "=Configuration.LayerBuildingRules.CaseInsensitiveIdentifier",
                CASE_INSENSITIVE_IDENTIFIER_DEFAULT );

    CPLXMLNode* psIgnoredXPaths = CPLGetXMLNode(psRoot,
                                            "=Configuration.IgnoredXPaths");
    if( psIgnoredXPaths )
    {
        const bool bGlobalWarnIfIgnoredXPathFound = CPLGetXMLBoolValue(
                       psIgnoredXPaths,
                       "WarnIfIgnoredXPathFoundInDocInstance",
                       WARN_IF_EXCLUDED_XPATH_FOUND_DEFAULT );

        CPLXMLNode* psNamespaces = CPLGetXMLNode(psIgnoredXPaths,
                                                 "Namespaces");
        if( psNamespaces != NULL )
        {
            for( CPLXMLNode* psIter = psNamespaces->psChild;
                             psIter != NULL;
                             psIter = psIter->psNext )
            {
                if( psIter->eType == CXT_Element &&
                    EQUAL(psIter->pszValue, "Namespace") )
                {
                    CPLString osPrefix = CPLGetXMLValue(psIter, "prefix", "");
                    CPLString osURI = CPLGetXMLValue(psIter, "uri", "");
                    if( !osPrefix.empty() && !osURI.empty() )
                    {
                        if( m_oMapPrefixToURIIgnoredXPaths.find(osPrefix) ==
                            m_oMapPrefixToURIIgnoredXPaths.end() )
                        {
                            m_oMapPrefixToURIIgnoredXPaths[osPrefix] = osURI;
                        }
                        else
                        {
                            CPLError(CE_Warning, CPLE_AppDefined,
                                     "Prefix %s was already mapped to %s. "
                                     "Attempt to map it to %s ignored",
                                     osPrefix.c_str(),
                                     m_oMapPrefixToURIIgnoredXPaths[osPrefix].
                                                                        c_str(),
                                     osURI.c_str());
                        }
                    }
                }
            }
        }

        for( CPLXMLNode* psIter = psIgnoredXPaths->psChild;
                         psIter != NULL;
                         psIter = psIter->psNext )
        {
            if( psIter->eType == CXT_Element &&
                EQUAL(psIter->pszValue, "XPath") )
            {
                const CPLString& osXPath( CPLGetXMLValue(psIter, "", "") );
                if( IsValidXPath(osXPath) )
                {
                    m_aosIgnoredXPaths.push_back( osXPath );

                    const bool bWarnIfIgnoredXPathFound = CPLGetXMLBoolValue(
                                psIter,
                                "warnIfIgnoredXPathFoundInDocInstance",
                                bGlobalWarnIfIgnoredXPathFound );
                    m_oMapIgnoredXPathToWarn[ osXPath ] = bWarnIfIgnoredXPathFound;
                }
                else
                {
                    CPLError(CE_Warning, CPLE_AppDefined,
                             "XPath syntax %s not supported",
                             osXPath.c_str());
                }
            }
        }
    }

    CPLXMLNode* psXLinkResolutionNode = CPLGetXMLNode( psRoot,
                                            "=Configuration.XLinkResolution");
    if( psXLinkResolutionNode != NULL )
        m_oXLinkResolution.LoadFromXML( psXLinkResolutionNode );

    Finalize();

    return true;
}
Beispiel #18
0
bool CreateSubRaster( wxGISRasterDatasetSPtr pSrcRasterDataSet, OGREnvelope &Env, const OGRGeometry *pGeom, GDALDriver* pDriver, CPLString &szDstPath, GDALDataType eOutputType, int nBandCount, int *panBandList, double dfOutResX, double dfOutResY, bool bCopyNodata, bool bSkipSourceMetadata, char** papszOptions, ITrackCancel* pTrackCancel )
{
	GDALDataset* pDset = pSrcRasterDataSet->GetRaster();
	if(!pDset)
	{
		if(pTrackCancel)
			pTrackCancel->PutMessage(_("Get raster failed"), -1, enumGISMessageErr);
		return false;
	}

    double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 };
	CPLErr err = pDset->GetGeoTransform(adfGeoTransform);
	if(err == CE_Fatal)
	{
		if(pTrackCancel)
			pTrackCancel->PutMessage(_("Get raster failed"), -1, enumGISMessageErr);
		return false;
	}
	if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 )
	{
		if(pTrackCancel)
			pTrackCancel->PutMessage(_("The geotransform is rotated. This configuration is not supported."), -1, enumGISMessageErr);
		return false;
    }
	int anSrcWin[4] = {0, 0, 0, 0};

    anSrcWin[0] = floor ((Env.MinX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001);
    anSrcWin[1] = floor ((Env.MaxY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001);
	anSrcWin[2] = ceil ((Env.MaxX - Env.MinX) / adfGeoTransform[1]);
	anSrcWin[3] = ceil ((Env.MinY - Env.MaxY) / adfGeoTransform[5]);
	if(pTrackCancel)
		pTrackCancel->PutMessage(wxString::Format(_("Computed source pixel window %d %d %d %d from geographic window."), anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3] ), -1, enumGISMessageInfo);

	if( anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[0] + anSrcWin[2] > pSrcRasterDataSet->GetWidth() || anSrcWin[1] + anSrcWin[3] > pSrcRasterDataSet->GetHeight() )
    {
		if(pTrackCancel)
			pTrackCancel->PutMessage(wxString::Format(_("Computed source pixel window falls outside raster size of %dx%d."), pSrcRasterDataSet->GetWidth(), pSrcRasterDataSet->GetHeight()), -1, enumGISMessageErr);
		return false;
    }

	int nOXSize = 0, nOYSize = 0;

    if(IsDoubleEquil(dfOutResX, -1) && IsDoubleEquil(dfOutResY, -1))
    {
        nOXSize = anSrcWin[2];
        nOYSize = anSrcWin[3];
    }
    else
    {
        nOXSize = ceil ((Env.MaxX - Env.MinX) / dfOutResX);
        nOYSize = ceil ((Env.MinY - Env.MaxY) / (adfGeoTransform[5] < 0 ? dfOutResY * -1 : dfOutResY));
    }

/* ==================================================================== */
/*      Create a virtual dataset.                                       */
/* ==================================================================== */
    VRTDataset *poVDS;
/* -------------------------------------------------------------------- */
/*      Make a virtual clone.                                           */
/* -------------------------------------------------------------------- */
    poVDS = (VRTDataset *) VRTCreate( nOXSize, nOYSize );

    if( pSrcRasterDataSet->GetSpatialReference() != NULL )
    {
		poVDS->SetProjection( pDset->GetProjectionRef() );
    }

	adfGeoTransform[0] += anSrcWin[0] * adfGeoTransform[1] + anSrcWin[1] * adfGeoTransform[2];
    adfGeoTransform[3] += anSrcWin[0] * adfGeoTransform[4] + anSrcWin[1] * adfGeoTransform[5];

    adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize;
    adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize;
    adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize;
    adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize;

    poVDS->SetGeoTransform( adfGeoTransform );

    int nGCPs = pDset->GetGCPCount();
    if( nGCPs > 0 )
    {
        GDAL_GCP *pasGCPs = GDALDuplicateGCPs( nGCPs, pDset->GetGCPs() );

        for(size_t i = 0; i < nGCPs; ++i )
        {
            pasGCPs[i].dfGCPPixel -= anSrcWin[0];
            pasGCPs[i].dfGCPLine  -= anSrcWin[1];
            pasGCPs[i].dfGCPPixel *= (nOXSize / (double) anSrcWin[2] );
            pasGCPs[i].dfGCPLine  *= (nOYSize / (double) anSrcWin[3] );
        }

        poVDS->SetGCPs( nGCPs, pasGCPs, pDset->GetGCPProjection() );
        GDALDeinitGCPs( nGCPs, pasGCPs );
        CPLFree( pasGCPs );
    }

/* -------------------------------------------------------------------- */
/*      Transfer generally applicable metadata.                         */
/* -------------------------------------------------------------------- */
    if(!bSkipSourceMetadata)
        poVDS->SetMetadata( pDset->GetMetadata() );

/* ==================================================================== */
/*      Process all bands.                                              */
/* ==================================================================== */
    for(size_t i = 0; i < nBandCount; ++i )
    {
        VRTSourcedRasterBand *poVRTBand;
        GDALRasterBand *poSrcBand;
        GDALDataType eBandType;
        int nComponent = 0;

        poSrcBand = pDset->GetRasterBand(panBandList[i]);

/* -------------------------------------------------------------------- */
/*      Select output data type to match source.                        */
/* -------------------------------------------------------------------- */
        if( eOutputType == GDT_Unknown )
            eBandType = poSrcBand->GetRasterDataType();
        else
            eBandType = eOutputType;
/* -------------------------------------------------------------------- */
/*      Create this band.                                               */
/* -------------------------------------------------------------------- */
        poVDS->AddBand( eBandType, NULL );
        poVRTBand = (VRTSourcedRasterBand *) poVDS->GetRasterBand( i + 1 );
/* -------------------------------------------------------------------- */
/*      Create a simple data source depending on the                    */
/*      translation type required.                                      */
/* -------------------------------------------------------------------- */
        //if( bUnscale || bScale || (nRGBExpand != 0 && i < nRGBExpand) )
        //{
        //    poVRTBand->AddComplexSource( poSrcBand,
        //                                 anSrcWin[0], anSrcWin[1],
        //                                 anSrcWin[2], anSrcWin[3],
        //                                 0, 0, nOXSize, nOYSize,
        //                                 dfOffset, dfScale,
        //                                 VRT_NODATA_UNSET,
        //                                 nComponent );
        //}
        //else
        CPLString pszResampling = CSLFetchNameValueDef(papszOptions, "DEST_RESAMPLING", "near");
        poVRTBand->AddSimpleSource( poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize, pszResampling );

/* -------------------------------------------------------------------- */
/*      copy some other information of interest.                        */
/* -------------------------------------------------------------------- */
		CopyBandInfo( poSrcBand, poVRTBand, bCopyNodata );
/* -------------------------------------------------------------------- */
/*      Set a forcable nodata value?                                    */
/* -------------------------------------------------------------------- */
//        if( bSetNoData )
//        {
//            double dfVal = dfNoDataReal;
//            int bClamped = FALSE, bRounded = FALSE;
//
//#define CLAMP(val,type,minval,maxval) \
//    do { if (val < minval) { bClamped = TRUE; val = minval; } \
//    else if (val > maxval) { bClamped = TRUE; val = maxval; } \
//    else if (val != (type)val) { bRounded = TRUE; val = (type)(val + 0.5); } } \
//    while(0)
//
//            switch(eBandType)
//            {
//                case GDT_Byte:
//                    CLAMP(dfVal, GByte, 0.0, 255.0);
//                    break;
//                case GDT_Int16:
//                    CLAMP(dfVal, GInt16, -32768.0, 32767.0);
//                    break;
//                case GDT_UInt16:
//                    CLAMP(dfVal, GUInt16, 0.0, 65535.0);
//                    break;
//                case GDT_Int32:
//                    CLAMP(dfVal, GInt32, -2147483648.0, 2147483647.0);
//                    break;
//                case GDT_UInt32:
//                    CLAMP(dfVal, GUInt32, 0.0, 4294967295.0);
//                    break;
//                default:
//                    break;
//            }
//
//            if (bClamped)
//            {
//                printf( "for band %d, nodata value has been clamped "
//                       "to %.0f, the original value being out of range.\n",
//                       i + 1, dfVal);
//            }
//            else if(bRounded)
//            {
//                printf("for band %d, nodata value has been rounded "
//                       "to %.0f, %s being an integer datatype.\n",
//                       i + 1, dfVal,
//                       GDALGetDataTypeName(eBandType));
//            }
//
//            poVRTBand->SetNoDataValue( dfVal );
//        }

        //if (eMaskMode == MASK_AUTO &&
        //    (GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) & GMF_PER_DATASET) == 0 &&
        //    (poSrcBand->GetMaskFlags() & (GMF_ALL_VALID | GMF_NODATA)) == 0)
        //{
        //    if (poVRTBand->CreateMaskBand(poSrcBand->GetMaskFlags()) == CE_None)
        //    {
        //        VRTSourcedRasterBand* hMaskVRTBand =
        //            (VRTSourcedRasterBand*)poVRTBand->GetMaskBand();
        //        hMaskVRTBand->AddMaskBandSource(poSrcBand,
        //                                anSrcWin[0], anSrcWin[1],
        //                                anSrcWin[2], anSrcWin[3],
        //                                0, 0, nOXSize, nOYSize );
        //    }
        //}
    }

    //if (eMaskMode == MASK_USER)
    //{
    //    GDALRasterBand *poSrcBand =
    //        (GDALRasterBand*)GDALGetRasterBand(hDataset, ABS(nMaskBand));
    //    if (poSrcBand && poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None)
    //    {
    //        VRTSourcedRasterBand* hMaskVRTBand = (VRTSourcedRasterBand*)
    //            GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1));
    //        if (nMaskBand > 0)
    //            hMaskVRTBand->AddSimpleSource(poSrcBand,
    //                                    anSrcWin[0], anSrcWin[1],
    //                                    anSrcWin[2], anSrcWin[3],
    //                                    0, 0, nOXSize, nOYSize );
    //        else
    //            hMaskVRTBand->AddMaskBandSource(poSrcBand,
    //                                    anSrcWin[0], anSrcWin[1],
    //                                    anSrcWin[2], anSrcWin[3],
    //                                    0, 0, nOXSize, nOYSize );
    //    }
    //}
    //else
    //if (eMaskMode == MASK_AUTO && nSrcBandCount > 0 &&
    //    GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) == GMF_PER_DATASET)
    //{
    //    if (poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None)
    //    {
    //        VRTSourcedRasterBand* hMaskVRTBand = (VRTSourcedRasterBand*)
    //            GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1));
    //        hMaskVRTBand->AddMaskBandSource((GDALRasterBand*)GDALGetRasterBand(hDataset, 1),
    //                                    anSrcWin[0], anSrcWin[1],
    //                                    anSrcWin[2], anSrcWin[3],
    //                                    0, 0, nOXSize, nOYSize );
    //    }
    //}

/* -------------------------------------------------------------------- */
/*      Write to the output file using CopyCreate().                    */
/* -------------------------------------------------------------------- */
    GDALDataset* pOutDS = pDriver->CreateCopy(szDstPath, poVDS, false, papszOptions, GDALDummyProgress, NULL);

    //hOutDS = GDALCreateCopy( hDriver, pszDest, (GDALDatasetH) poVDS, bStrict, papszCreateOptions, pfnProgress, NULL );
    if( pOutDS )
    {
        CPLErrorReset();
        GDALFlushCache( pOutDS );
        if (CPLGetLastErrorType() != CE_None)
        {
		    if(pTrackCancel)
			    pTrackCancel->PutMessage(_("GDALFlushCache failed!"), -1, enumGISMessageErr);
        }
        GDALClose( pOutDS );

        GDALClose( poVDS );
        return true;
    }
    else
    {
        GDALClose( poVDS );
        return false;
    }


    //CPLFree( panBandList );
    //
    //CPLFree( pszOutputSRS );

    //if( !bSubCall )
    //{
    //    GDALDumpOpenDatasets( stderr );
    //    GDALDestroyDriverManager();
    //}
    //CSLDestroy( papszCreateOptions );

	return true;
}
Beispiel #19
0
int main( int argc, char ** argv )

{
    EarlySetConfigOptions(argc, argv);

/* -------------------------------------------------------------------- */
/*      Register standard GDAL drivers, and process generic GDAL        */
/*      command options.                                                */
/* -------------------------------------------------------------------- */
    GDALAllRegister();
    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

    for( int i = 0; argv != NULL && argv[i] != NULL; i++ )
    {
        if( EQUAL(argv[i], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            CSLDestroy( argv );
            return 0;
        }
        else if( EQUAL(argv[i],"--help") )
        {
            Usage(NULL);
        }
    }

    GDALBuildVRTOptionsForBinary* psOptionsForBinary = GDALBuildVRTOptionsForBinaryNew();
    /* coverity[tainted_data] */
    GDALBuildVRTOptions *psOptions = GDALBuildVRTOptionsNew(argv + 1, psOptionsForBinary);
    CSLDestroy( argv );

    if( psOptions == NULL )
    {
        Usage(NULL);
    }

    if( psOptionsForBinary->pszDstFilename == NULL )
    {
        Usage("No target filename specified.");
    }

    if( !(psOptionsForBinary->bQuiet) )
    {
        GDALBuildVRTOptionsSetProgress(psOptions, GDALTermProgress, NULL);
    }

    /* Avoid overwriting a non VRT dataset if the user did not put the */
    /* filenames in the right order */
    VSIStatBuf sBuf;
    if (!psOptionsForBinary->bOverwrite)
    {
        int bExists = (VSIStat(psOptionsForBinary->pszDstFilename, &sBuf) == 0);
        if (bExists)
        {
            GDALDriverH hDriver = GDALIdentifyDriver( psOptionsForBinary->pszDstFilename, NULL );
            if (hDriver && !(EQUAL(GDALGetDriverShortName(hDriver), "VRT") ||
                   (EQUAL(GDALGetDriverShortName(hDriver), "API_PROXY") &&
                    EQUAL(CPLGetExtension(psOptionsForBinary->pszDstFilename), "VRT"))) )
            {
                fprintf(stderr,
                        "'%s' is an existing GDAL dataset managed by %s driver.\n"
                        "There is an high chance you did not put filenames in the right order.\n"
                        "If you want to overwrite %s, add -overwrite option to the command line.\n\n",
                        psOptionsForBinary->pszDstFilename, GDALGetDriverShortName(hDriver), psOptionsForBinary->pszDstFilename);
                Usage();
            }
        }
    }

    int bUsageError = FALSE;
    GDALDatasetH hOutDS = GDALBuildVRT(psOptionsForBinary->pszDstFilename,
                                       psOptionsForBinary->nSrcFiles,
                                       NULL,
                                       (const char* const*)psOptionsForBinary->papszSrcFiles,
                                       psOptions, &bUsageError);
    if( bUsageError )
        Usage();
    int nRetCode = (hOutDS) ? 0 : 1;

    GDALBuildVRTOptionsFree(psOptions);
    GDALBuildVRTOptionsForBinaryFree(psOptionsForBinary);

    CPLErrorReset();
    // The flush to disk is only done at that stage, so check if any error has
    // happened
    GDALClose( hOutDS );
    if( CPLGetLastErrorType() != CE_None )
        nRetCode = 1;

    GDALDumpOpenDatasets( stderr );

    GDALDestroyDriverManager();

    OGRCleanupAll();

    return nRetCode;
}
Beispiel #20
0
GDALDataset *SIGDEMDataset::Open(GDALOpenInfo * poOpenInfo) {
    VSILFILE* fp = poOpenInfo->fpL;

    SIGDEMHeader sHeader;
    if (SIGDEMDataset::Identify(poOpenInfo) != TRUE || fp == nullptr) {
        return nullptr;
    }

    sHeader.Read(poOpenInfo->pabyHeader);

    if (!GDALCheckDatasetDimensions(sHeader.nCols, sHeader.nRows)) {
        return nullptr;
    }

    OGRSpatialReference oSRS;

    if (sHeader.nCoordinateSystemId > 0) {
        if (oSRS.importFromEPSG(sHeader.nCoordinateSystemId) != OGRERR_NONE) {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "SIGDEM unable to find coordinateSystemId=%d.",
                    sHeader.nCoordinateSystemId);
            return nullptr;
        }
    } else {
        CPLString osPrjFilename = CPLResetExtension(poOpenInfo->pszFilename,
                "prj");
        VSIStatBufL sStatBuf;
        int nRet = VSIStatL(osPrjFilename, &sStatBuf);
        if (nRet != 0 && VSIIsCaseSensitiveFS(osPrjFilename)) {
            osPrjFilename = CPLResetExtension(poOpenInfo->pszFilename, "PRJ");
            nRet = VSIStatL(osPrjFilename, &sStatBuf);
        }

        if (nRet == 0) {
            char** papszPrj = CSLLoad(osPrjFilename);
            if (oSRS.importFromESRI(papszPrj) != OGRERR_NONE) {
                CPLError(CE_Failure, CPLE_NotSupported,
                        "SIGDEM unable to read projection from %s.",
                        osPrjFilename.c_str());
                CSLDestroy(papszPrj);
                return nullptr;
            }
            CSLDestroy(papszPrj);
        } else {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "SIGDEM unable to find projection.");
            return nullptr;
        }
    }

    if (sHeader.nCols > std::numeric_limits<int>::max() / (CELL_SIZE_MEM)) {
        CPLError(CE_Failure, CPLE_AppDefined, "Int overflow occurred.");
        return nullptr;
    }

    if( !RAWDatasetCheckMemoryUsage(sHeader.nCols, sHeader.nRows, 1,
                    4, 4, 4 * sHeader.nCols, 0, 0, poOpenInfo->fpL) )
    {
        return nullptr;
    }
    SIGDEMDataset *poDS = new SIGDEMDataset(sHeader);

    CPLFree(poDS->pszProjection);
    oSRS.exportToWkt(&(poDS->pszProjection));

    poDS->fpImage = poOpenInfo->fpL;
    poOpenInfo->fpL = nullptr;
    poDS->eAccess = poOpenInfo->eAccess;

    poDS->SetDescription(poOpenInfo->pszFilename);
    poDS->PamInitialize();

    poDS->nBands = 1;
    CPLErrorReset();
    SIGDEMRasterBand *poBand = new SIGDEMRasterBand(poDS, poDS->fpImage,
            sHeader.dfMinZ, sHeader.dfMaxZ);

    poDS->SetBand(1, poBand);
    if (CPLGetLastErrorType() != CE_None) {
        poDS->nBands = 1;
        delete poDS;
        return nullptr;
    }

// Initialize any PAM information.
    poDS->TryLoadXML();

// Check for overviews.
    poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename);

    return poDS;
}
int OGRNASDataSource::Open( const char * pszNewName, int bTestOpen )

{
    FILE        *fp;
    char        szHeader[8192];

/* -------------------------------------------------------------------- */
/*      Open the source file.                                           */
/* -------------------------------------------------------------------- */
    fp = VSIFOpen( pszNewName, "r" );
    if( fp == NULL )
    {
        if( !bTestOpen )
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "Failed to open NAS file `%s'.",
                      pszNewName );

        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      If we aren't sure it is NAS, load a header chunk and check      */
/*      for signs it is NAS                                             */
/* -------------------------------------------------------------------- */
    if( bTestOpen )
    {
        size_t nRead = VSIFRead( szHeader, 1, sizeof(szHeader), fp );
        if (nRead <= 0)
        {
            VSIFClose( fp );
            return FALSE;
        }
        szHeader[MIN(nRead, sizeof(szHeader))-1] = '\0';

/* -------------------------------------------------------------------- */
/*      Check for a UTF-8 BOM and skip if found                         */
/*                                                                      */
/*      TODO: BOM is variable-length parameter and depends on encoding. */
/*            Add BOM detection for other encodings.                    */
/* -------------------------------------------------------------------- */

        // Used to skip to actual beginning of XML data
        char* szPtr = szHeader;

        if( ( (unsigned char)szHeader[0] == 0xEF )
            && ( (unsigned char)szHeader[1] == 0xBB )
            && ( (unsigned char)szHeader[2] == 0xBF) )
        {
            szPtr += 3;
        }

/* -------------------------------------------------------------------- */
/*      Here, we expect the opening chevrons of NAS tree root element   */
/* -------------------------------------------------------------------- */
        if( szPtr[0] != '<'
            || strstr(szPtr,"opengis.net/gml") == NULL
            || (strstr(szPtr,"NAS-Operationen.xsd") == NULL &&
                strstr(szPtr,"NAS-Operationen_optional.xsd") == NULL &&
                strstr(szPtr,"AAA-Fachschema.xsd") == NULL ) )
        {
            /*CPLDebug( "NAS",
                      "Skipping. No chevrons of NAS found [%s]\n", szPtr );*/
            VSIFClose( fp );
            return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      We assume now that it is NAS.  Close and instantiate a          */
/*      NASReader on it.                                                */
/* -------------------------------------------------------------------- */
    VSIFClose( fp );

    poReader = CreateNASReader();
    if( poReader == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "File %s appears to be NAS but the NAS reader can't\n"
                  "be instantiated, likely because Xerces support wasn't\n"
                  "configured in.",
                  pszNewName );
        return FALSE;
    }

    poReader->SetSourceFile( pszNewName );

    pszName = CPLStrdup( pszNewName );

/* -------------------------------------------------------------------- */
/*      Can we find a NAS Feature Schema (.gfs) for the input file?     */
/* -------------------------------------------------------------------- */
    const char *pszGFSFilename;
    VSIStatBuf sGFSStatBuf, sNASStatBuf;
    int        bHaveSchema = FALSE;

    pszGFSFilename = CPLResetExtension( pszNewName, "gfs" );
    if( CPLStat( pszGFSFilename, &sGFSStatBuf ) == 0 )
    {
        CPLStat( pszNewName, &sNASStatBuf );

        if( sNASStatBuf.st_mtime > sGFSStatBuf.st_mtime )
        {
            CPLDebug( "NAS",
                      "Found %s but ignoring because it appears\n"
                      "be older than the associated NAS file.",
                      pszGFSFilename );
        }
        else
        {
            bHaveSchema = poReader->LoadClasses( pszGFSFilename );
        }
    }

/* -------------------------------------------------------------------- */
/*      Force a first pass to establish the schema.  Eventually we      */
/*      will have mechanisms for remembering the schema and related     */
/*      information.                                                    */
/* -------------------------------------------------------------------- */
    CPLErrorReset();
    if( !bHaveSchema
        && !poReader->PrescanForSchema( TRUE )
        && CPLGetLastErrorType() == CE_Failure )
    {
        // we assume an errors have been reported.
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Save the schema file if possible.  Don't make a fuss if we      */
/*      can't ... could be read-only directory or something.            */
/* -------------------------------------------------------------------- */
    if( !bHaveSchema && poReader->GetClassCount() > 0 )
    {
        FILE    *fp = NULL;

        pszGFSFilename = CPLResetExtension( pszNewName, "gfs" );
        if( CPLStat( pszGFSFilename, &sGFSStatBuf ) != 0
            && (fp = VSIFOpen( pszGFSFilename, "wt" )) != NULL )
        {
            VSIFClose( fp );
            poReader->SaveClasses( pszGFSFilename );
        }
        else
        {
            CPLDebug("NAS",
                     "Not saving %s files already exists or can't be created.",
                     pszGFSFilename );
        }
    }

/* -------------------------------------------------------------------- */
/*      Translate the NASFeatureClasses into layers.                    */
/* -------------------------------------------------------------------- */
    papoLayers = (OGRLayer **)
        CPLCalloc( sizeof(OGRNASLayer *), poReader->GetClassCount()+1 );
    nLayers = 0;

    while( nLayers < poReader->GetClassCount() )
    {
        papoLayers[nLayers] = TranslateNASSchema(poReader->GetClass(nLayers));
        nLayers++;
    }

    poRelationLayer = new OGRNASRelationLayer( this );

    // keep delete the last layer
    if( nLayers>0 && EQUAL( papoLayers[nLayers-1]->GetName(), "Delete" ) )
    {
      papoLayers[nLayers]   = papoLayers[nLayers-1];
      papoLayers[nLayers-1] = poRelationLayer;
    }
    else
    {
      papoLayers[nLayers] = poRelationLayer;
    }

    nLayers++;

    return TRUE;
}
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;
}
Beispiel #23
0
GDALDataset *DOQ2Dataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      We assume the user is pointing to the binary (i.e. .bil) file.  */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 212 )
        return NULL;

    if(! STARTS_WITH_CI( reinterpret_cast<char *>( poOpenInfo->pabyHeader ),
                         "BEGIN_USGS_DOQ_HEADER" ) )
        return NULL;

    VSILFILE* fp = VSIFOpenL(poOpenInfo->pszFilename, "rb");
    if (fp == NULL)
        return NULL;

    int nLineCount = 0;
    int nBytesPerPixel = 0;
    int nWidth = 0;
    int nHeight = 0;
    int nBandStorage = 0;
    int nBandTypes = 0;
    const char *pszDatumLong = NULL;
    const char *pszDatumShort = NULL;
    const char *pszUnits = NULL;
    char *pszQuadname = NULL;
    char *pszQuadquad = NULL;
    char *pszState = NULL;
    int nZone=0, nProjType=0;
    int nSkipBytes = 0;
    int nBandCount = 0;
    double dfULXMap=0.0;
    double dfULYMap = 0.0;
    double dfXDim = 0.0;
    double dfYDim = 0.0;
    char **papszMetadata = NULL;

    /* read and discard the first line */
    CPL_IGNORE_RET_VAL(CPLReadLineL( fp ));

    const char *pszLine = NULL;
    while( (pszLine = CPLReadLineL( fp )) != NULL )
    {
        nLineCount++;

        if( EQUAL(pszLine,"END_USGS_DOQ_HEADER") )
            break;

        char **papszTokens = CSLTokenizeString( pszLine );
        if( CSLCount( papszTokens ) < 2 )
        {
            CSLDestroy( papszTokens );
            break;
        }

        if( EQUAL( papszTokens[0], "SAMPLES_AND_LINES" ) &&
            CSLCount( papszTokens ) >= 3 )
        {
            nWidth = atoi(papszTokens[1]);
            nHeight = atoi(papszTokens[2]);
        }
        else if( EQUAL(papszTokens[0],"BYTE_COUNT") )
        {
            nSkipBytes = atoi(papszTokens[1]);
        }
        else if( EQUAL( papszTokens[0], "XY_ORIGIN" ) &&
                 CSLCount( papszTokens ) >= 3 )
        {
            dfULXMap = CPLAtof(papszTokens[1]);
            dfULYMap = CPLAtof(papszTokens[2]);
        }
        else if( EQUAL( papszTokens[0], "HORIZONTAL_RESOLUTION" ) )
        {
            dfXDim = CPLAtof(papszTokens[1]);
            dfYDim = dfXDim;
        }
        else if( EQUAL(papszTokens[0], "BAND_ORGANIZATION") )
        {
            if( EQUAL(papszTokens[1], "SINGLE FILE") )
                nBandStorage = 1;
            if( EQUAL(papszTokens[1], "BSQ") )
                nBandStorage = 1;
            if( EQUAL(papszTokens[1], "BIL") )
                nBandStorage = 1;
            if( EQUAL(papszTokens[1], "BIP") )
                nBandStorage = 4;
        }
        else if( EQUAL(papszTokens[0], "BAND_CONTENT") )
        {
            if( EQUAL(papszTokens[1], "BLACK&WHITE") )
                nBandTypes = 1;
            else if( EQUAL(papszTokens[1], "COLOR") )
                nBandTypes = 5;
            else if( EQUAL(papszTokens[1], "RGB") )
                nBandTypes = 5;
            else if( EQUAL(papszTokens[1], "RED") )
                nBandTypes = 5;
            else if( EQUAL(papszTokens[1], "GREEN") )
                nBandTypes = 5;
            else if( EQUAL(papszTokens[1], "BLUE") )
                nBandTypes = 5;

            nBandCount++;
        }
        else if( EQUAL(papszTokens[0], "BITS_PER_PIXEL") )
        {
            nBytesPerPixel = atoi(papszTokens[1]) / 8;
        }
        else if( EQUAL(papszTokens[0], "HORIZONTAL_COORDINATE_SYSTEM") )
        {
            if( EQUAL(papszTokens[1], "UTM") )
                nProjType = 1;
            else if( EQUAL(papszTokens[1], "SPCS") )
                nProjType = 2;
            else if( EQUAL(papszTokens[1], "GEOGRAPHIC") )
                nProjType = 0;
        }
        else if( EQUAL(papszTokens[0], "COORDINATE_ZONE") )
        {
            nZone = atoi(papszTokens[1]);
        }
        else if( EQUAL(papszTokens[0], "HORIZONTAL_UNITS") )
        {
            if( EQUAL(papszTokens[1], "METERS") )
                pszUnits = "UNIT[\"metre\",1]";
            else if( EQUAL(papszTokens[1], "FEET") )
                pszUnits = "UNIT[\"US survey foot\",0.304800609601219]";
        }
        else if( EQUAL(papszTokens[0],"HORIZONTAL_DATUM") )
        {
            if( EQUAL(papszTokens[1], "NAD27") )
            {
                pszDatumLong = NAD27_DATUM;
                pszDatumShort = "NAD 27";
            }
            else if( EQUAL(papszTokens[1]," WGS72") )
            {
                pszDatumLong = WGS72_DATUM;
                pszDatumShort = "WGS 72";
            }
            else if( EQUAL(papszTokens[1], "WGS84") )
            {
                pszDatumLong = WGS84_DATUM;
                pszDatumShort = "WGS 84";
            }
            else if( EQUAL(papszTokens[1], "NAD83") )
            {
                pszDatumLong = NAD83_DATUM;
                pszDatumShort = "NAD 83";
            }
            else
            {
                pszDatumLong = "DATUM[\"unknown\"]";
                pszDatumShort = "unknown";
            }
        }
        else
        {
            /* we want to generically capture all the other metadata */
            CPLString osMetaDataValue;

            for( int iToken = 1; papszTokens[iToken] != NULL; iToken++ )
            {
                if( EQUAL(papszTokens[iToken],"*") )
                    continue;

                if( iToken > 1 )
                    osMetaDataValue += " " ;
                osMetaDataValue += papszTokens[iToken];
            }
            papszMetadata = CSLAddNameValue( papszMetadata,
                                             papszTokens[0],
                                             osMetaDataValue );
        }

        CSLDestroy( papszTokens );
    }

    CPLReadLineL( NULL );

/* -------------------------------------------------------------------- */
/*      Do these values look coherent for a DOQ file?  It would be      */
/*      nice to do a more comprehensive test than this!                 */
/* -------------------------------------------------------------------- */
    if( nWidth < 500 || nWidth > 25000
        || nHeight < 500 || nHeight > 25000
        || nBandStorage < 0 || nBandStorage > 4
        || nBandTypes < 1 || nBandTypes > 9 )
    {
        CSLDestroy( papszMetadata );
        CPL_IGNORE_RET_VAL(VSIFCloseL(fp));
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Check the configuration.  We don't currently handle all         */
/*      variations, only the common ones.                               */
/* -------------------------------------------------------------------- */
    if( nBandTypes > 5 )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "DOQ Data Type (%d) is not a supported configuration.",
                  nBandTypes );
        CSLDestroy( papszMetadata );
        CPL_IGNORE_RET_VAL(VSIFCloseL(fp));
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CSLDestroy( papszMetadata );
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The DOQ2 driver does not support update access to existing"
                  " datasets." );
        CPL_IGNORE_RET_VAL(VSIFCloseL(fp));
        return NULL;
    }
/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    DOQ2Dataset *poDS = new DOQ2Dataset();

    poDS->nRasterXSize = nWidth;
    poDS->nRasterYSize = nHeight;

    poDS->SetMetadata( papszMetadata );
    CSLDestroy( papszMetadata );
    papszMetadata = NULL;

    poDS->fpImage = fp;

/* -------------------------------------------------------------------- */
/*      Compute layout of data.                                         */
/* -------------------------------------------------------------------- */
    if( nBandCount < 2 )
        nBandCount = nBytesPerPixel;
    else
        nBytesPerPixel *= nBandCount;

    const int nBytesPerLine = nBytesPerPixel * nWidth;

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    CPLErrorReset();
    for( int i = 0; i < nBandCount; i++ )
    {
        poDS->SetBand( i+1,
            new RawRasterBand( poDS, i+1, poDS->fpImage,
                               nSkipBytes + i, nBytesPerPixel, nBytesPerLine,
                               GDT_Byte, TRUE, TRUE ) );
        if( CPLGetLastErrorType() != CE_None )
        {
            delete poDS;
            CPLFree( pszQuadname );
            CPLFree( pszQuadquad );
            CPLFree( pszState );
            return NULL;
        }
    }

    if (nProjType == 1)
    {
        poDS->pszProjection =
            CPLStrdup( CPLSPrintf(
                UTM_FORMAT, pszDatumShort ? pszDatumShort : "", nZone,
                pszDatumLong ? pszDatumLong : "",
                nZone >= 1 && nZone <= 60 ? nZone * 6 - 183 : 0,
                pszUnits ? pszUnits : "" ) );
    }
    else
    {
        poDS->pszProjection = CPLStrdup("");
    }

    poDS->dfULX = dfULXMap;
    poDS->dfULY = dfULYMap;

    poDS->dfXPixelSize = dfXDim;
    poDS->dfYPixelSize = dfYDim;

    CPLFree( pszQuadname );
    CPLFree( pszQuadquad );
    CPLFree( pszState );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return poDS;
}
Beispiel #24
0
int  OGRAmigoCloudResultLayer::IsOK()
{
    CPLErrorReset();
    poFirstFeature = GetNextFeature();
    return CPLGetLastErrorType() == 0;
}
static int ProxyMain(int argc, char **argv)

{
    GDALDatasetH     hDataset, hOutDS;
    int              i;
    int              nRasterXSize, nRasterYSize;
    const char       *pszSource = NULL, *pszDest = NULL, *pszFormat = "GTiff";
    GDALDriverH      hDriver;
    int              *panBandList = NULL;    /* negative value of panBandList[i] means mask band of ABS(panBandList[i]) */
    int              nBandCount   = 0, bDefBands = TRUE;
    double           adfGeoTransform[6];
    GDALDataType     eOutputType          = GDT_Unknown;
    int              nOXSize              = 0, nOYSize = 0;
    char             *pszOXSize           = NULL, *pszOYSize = NULL;
    char             **papszCreateOptions = NULL;
    int              anSrcWin[4], bStrict = FALSE;
    const char       *pszProjection;
    int              bScale        = FALSE, bHaveScaleSrc = FALSE, bUnscale = FALSE;
    double           dfScaleSrcMin = 0.0, dfScaleSrcMax = 255.0;
    double           dfScaleDstMin = 0.0, dfScaleDstMax = 255.0;
    double           dfULX, dfULY, dfLRX, dfLRY;
    char             **papszMetadataOptions = NULL;
    char             *pszOutputSRS          = NULL;
    int              bQuiet                 = FALSE, bGotBounds = FALSE;
    GDALProgressFunc pfnProgress            = GDALTermProgress;
    int              nGCPCount              = 0;
    GDAL_GCP         *pasGCPs               = NULL;
    int              iSrcFileArg            = -1, iDstFileArg = -1;
    int              bCopySubDatasets       = FALSE;
    double           adfULLR[4]             = { 0, 0, 0, 0 };
    int              bSetNoData             = FALSE;
    int              bUnsetNoData           = FALSE;
    double           dfNoDataReal           = 0.0;
    int              nRGBExpand             = 0;
    int              bParsedMaskArgument    = FALSE;
    int              eMaskMode              = MASK_AUTO;
    int              nMaskBand              = 0; /* negative value means mask band of ABS(nMaskBand) */
    int              bStats                 = FALSE, bApproxStats = FALSE;


    anSrcWin[0] = 0;
    anSrcWin[1] = 0;
    anSrcWin[2] = 0;
    anSrcWin[3] = 0;

    dfULX = dfULY = dfLRX = dfLRY = 0.0;

    /* Check strict compilation and runtime library version as we use C++ API */
    if (!GDAL_CHECK_VERSION(argv[0]))
        exit(1);

    /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */
    /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */
    /* for the --format or --formats options */
    for (i = 1; i < argc; i++)
    {
        if (EQUAL(argv[i], "--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP"))
        {
            CPLSetConfigOption(argv[i + 1], argv[i + 2]);

            i += 2;
        }
    }

/* -------------------------------------------------------------------- */
/*      Register standard GDAL drivers, and process generic GDAL        */
/*      command options.                                                */
/* -------------------------------------------------------------------- */
    GDALAllRegister();
    argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
    if (argc < 1)
        exit(-argc);

/* -------------------------------------------------------------------- */
/*      Handle command line arguments.                                  */
/* -------------------------------------------------------------------- */
    for (i = 1; i < argc; i++)
    {
        if (EQUAL(argv[i], "--utility_version"))
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if (EQUAL(argv[i], "-of") && i < argc - 1)
            pszFormat = argv[++i];

        else if (EQUAL(argv[i], "-q") || EQUAL(argv[i], "-quiet"))
        {
            bQuiet      = TRUE;
            pfnProgress = GDALDummyProgress;
        }

        else if (EQUAL(argv[i], "-ot") && i < argc - 1)
        {
            int iType;

            for (iType = 1; iType < GDT_TypeCount; iType++)
            {
                if (GDALGetDataTypeName((GDALDataType)iType) != NULL
                    && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
                             argv[i + 1]))
                {
                    eOutputType = (GDALDataType) iType;
                }
            }

            if (eOutputType == GDT_Unknown)
            {
                printf("Unknown output pixel type: %s\n", argv[i + 1]);
                Usage();
                GDALDestroyDriverManager();
                exit(2);
            }

            i++;
        }
        else if (EQUAL(argv[i], "-b") && i < argc - 1)
        {
            const char *pszBand = argv[i + 1];
            int        bMask    = FALSE;
            if (EQUAL(pszBand, "mask"))
                pszBand = "mask,1";

            if (EQUALN(pszBand, "mask,", 5))
            {
                bMask    = TRUE;
                pszBand += 5;
                /* If we use tha source mask band as a regular band */
                /* don't create a target mask band by default */
                if (!bParsedMaskArgument)
                    eMaskMode = MASK_DISABLED;
            }

            int nBand = atoi(pszBand);
            if (nBand < 1)
            {
                printf("Unrecognizable band number (%s).\n", argv[i + 1]);
                Usage();
                GDALDestroyDriverManager();
                exit(2);
            }

            i++;

            nBandCount++;
            panBandList = (int*)
                          CPLRealloc(panBandList, sizeof(int) * nBandCount);
            panBandList[nBandCount - 1] = nBand;
            if (bMask)
                panBandList[nBandCount - 1] *= -1;

            if (panBandList[nBandCount - 1] != nBandCount)
                bDefBands = FALSE;
        }
        else if (EQUAL(argv[i], "-mask") && i < argc - 1)
        {
            bParsedMaskArgument = TRUE;
            const char *pszBand = argv[i + 1];
            if (EQUAL(pszBand, "none"))
            {
                eMaskMode = MASK_DISABLED;
            }
            else if (EQUAL(pszBand, "auto"))
            {
                eMaskMode = MASK_AUTO;
            }
            else
            {
                int bMask = FALSE;
                if (EQUAL(pszBand, "mask"))
                    pszBand = "mask,1";

                if (EQUALN(pszBand, "mask,", 5))
                {
                    bMask    = TRUE;
                    pszBand += 5;
                }

                int nBand = atoi(pszBand);
                if (nBand < 1)
                {
                    printf("Unrecognizable band number (%s).\n", argv[i + 1]);
                    Usage();
                    GDALDestroyDriverManager();
                    exit(2);
                }

                eMaskMode = MASK_USER;
                nMaskBand = nBand;
                if (bMask)
                    nMaskBand *= -1;
            }

            i++;
        }
        else if (EQUAL(argv[i], "-not_strict"))
            bStrict = FALSE;

        else if (EQUAL(argv[i], "-strict"))
            bStrict = TRUE;

        else if (EQUAL(argv[i], "-sds"))
            bCopySubDatasets = TRUE;

        else if (EQUAL(argv[i], "-gcp") && i < argc - 4)
        {
            char *endptr = NULL;
            /* -gcp pixel line easting northing [elev] */

            nGCPCount++;
            pasGCPs = (GDAL_GCP*)
                      CPLRealloc(pasGCPs, sizeof(GDAL_GCP) * nGCPCount);
            GDALInitGCPs(1, pasGCPs + nGCPCount - 1);

            pasGCPs[nGCPCount - 1].dfGCPPixel = CPLAtofM(argv[++i]);
            pasGCPs[nGCPCount - 1].dfGCPLine  = CPLAtofM(argv[++i]);
            pasGCPs[nGCPCount - 1].dfGCPX     = CPLAtofM(argv[++i]);
            pasGCPs[nGCPCount - 1].dfGCPY     = CPLAtofM(argv[++i]);
            if (argv[i + 1] != NULL
                && (CPLStrtod(argv[i + 1], &endptr) != 0.0 || argv[i + 1][0] == '0'))
            {
                /* Check that last argument is really a number and not a filename */
                /* looking like a number (see ticket #863) */
                if (endptr && *endptr == 0)
                    pasGCPs[nGCPCount - 1].dfGCPZ = CPLAtofM(argv[++i]);
            }

            /* should set id and info? */
        }

        else if (EQUAL(argv[i], "-a_nodata") && i < argc - 1)
        {
            if (EQUAL(argv[i + 1], "none"))
            {
                bUnsetNoData = TRUE;
            }
            else
            {
                bSetNoData   = TRUE;
                dfNoDataReal = CPLAtofM(argv[i + 1]);
            }

            i += 1;
        }

        else if (EQUAL(argv[i], "-a_ullr") && i < argc - 4)
        {
            adfULLR[0] = CPLAtofM(argv[i + 1]);
            adfULLR[1] = CPLAtofM(argv[i + 2]);
            adfULLR[2] = CPLAtofM(argv[i + 3]);
            adfULLR[3] = CPLAtofM(argv[i + 4]);

            bGotBounds = TRUE;

            i += 4;
        }

        else if (EQUAL(argv[i], "-co") && i < argc - 1)
        {
            papszCreateOptions = CSLAddString(papszCreateOptions, argv[++i]);
        }

        else if (EQUAL(argv[i], "-scale"))
        {
            bScale = TRUE;
            if (i < argc - 2 && ArgIsNumeric(argv[i + 1]))
            {
                bHaveScaleSrc = TRUE;
                dfScaleSrcMin = CPLAtofM(argv[i + 1]);
                dfScaleSrcMax = CPLAtofM(argv[i + 2]);
                i            += 2;
            }

            if (i < argc - 2 && bHaveScaleSrc && ArgIsNumeric(argv[i + 1]))
            {
                dfScaleDstMin = CPLAtofM(argv[i + 1]);
                dfScaleDstMax = CPLAtofM(argv[i + 2]);
                i            += 2;
            }
            else
            {
                dfScaleDstMin = 0.0;
                dfScaleDstMax = 255.999;
            }
        }

        else if (EQUAL(argv[i], "-unscale"))
        {
            bUnscale = TRUE;
        }

        else if (EQUAL(argv[i], "-mo") && i < argc - 1)
        {
            papszMetadataOptions = CSLAddString(papszMetadataOptions,
                                                argv[++i]);
        }

        else if (EQUAL(argv[i], "-outsize") && i < argc - 2)
        {
            pszOXSize = argv[++i];
            pszOYSize = argv[++i];
        }

        else if (EQUAL(argv[i], "-srcwin") && i < argc - 4)
        {
            anSrcWin[0] = atoi(argv[++i]);
            anSrcWin[1] = atoi(argv[++i]);
            anSrcWin[2] = atoi(argv[++i]);
            anSrcWin[3] = atoi(argv[++i]);
        }

        else if (EQUAL(argv[i], "-projwin") && i < argc - 4)
        {
            dfULX = CPLAtofM(argv[++i]);
            dfULY = CPLAtofM(argv[++i]);
            dfLRX = CPLAtofM(argv[++i]);
            dfLRY = CPLAtofM(argv[++i]);
        }

        else if (EQUAL(argv[i], "-a_srs") && i < argc - 1)
        {
            OGRSpatialReference oOutputSRS;

            if (oOutputSRS.SetFromUserInput(argv[i + 1]) != OGRERR_NONE)
            {
                fprintf(stderr, "Failed to process SRS definition: %s\n",
                        argv[i + 1]);
                GDALDestroyDriverManager();
                exit(1);
            }

            oOutputSRS.exportToWkt(&pszOutputSRS);
            i++;
        }

        else if (EQUAL(argv[i], "-expand") && i < argc - 1)
        {
            if (EQUAL(argv[i + 1], "gray"))
                nRGBExpand = 1;
            else if (EQUAL(argv[i + 1], "rgb"))
                nRGBExpand = 3;
            else if (EQUAL(argv[i + 1], "rgba"))
                nRGBExpand = 4;
            else
            {
                printf("Value %s unsupported. Only gray, rgb or rgba are supported.\n\n",
                       argv[i]);
                Usage();
                GDALDestroyDriverManager();
                exit(2);
            }

            i++;
        }

        else if (EQUAL(argv[i], "-stats"))
        {
            bStats       = TRUE;
            bApproxStats = FALSE;
        }
        else if (EQUAL(argv[i], "-approx_stats"))
        {
            bStats       = TRUE;
            bApproxStats = TRUE;
        }

        else if (argv[i][0] == '-')
        {
            printf("Option %s incomplete, or not recognised.\n\n",
                   argv[i]);
            Usage();
            GDALDestroyDriverManager();
            exit(2);
        }
        else if (pszSource == NULL)
        {
            iSrcFileArg = i;
            pszSource   = argv[i];
        }
        else if (pszDest == NULL)
        {
            pszDest     = argv[i];
            iDstFileArg = i;
        }

        else
        {
            printf("Too many command options.\n\n");
            Usage();
            GDALDestroyDriverManager();
            exit(2);
        }
    }

    if (pszDest == NULL)
    {
        Usage();
        GDALDestroyDriverManager();
        exit(10);
    }

    if (strcmp(pszSource, pszDest) == 0)
    {
        fprintf(stderr, "Source and destination datasets must be different.\n");
        GDALDestroyDriverManager();
        exit(1);
    }

    if (strcmp(pszDest, "/vsistdout/") == 0)
    {
        bQuiet      = TRUE;
        pfnProgress = GDALDummyProgress;
    }

/* -------------------------------------------------------------------- */
/*      Attempt to open source file.                                    */
/* -------------------------------------------------------------------- */

    hDataset = GDALOpenShared(pszSource, GA_ReadOnly);

    if (hDataset == NULL)
    {
        fprintf(stderr,
                "GDALOpen failed - %d\n%s\n",
                CPLGetLastErrorNo(), CPLGetLastErrorMsg());
        GDALDestroyDriverManager();
        exit(1);
    }

/* -------------------------------------------------------------------- */
/*      Handle subdatasets.                                             */
/* -------------------------------------------------------------------- */
    if (!bCopySubDatasets
        && CSLCount(GDALGetMetadata(hDataset, "SUBDATASETS")) > 0
        && GDALGetRasterCount(hDataset) == 0)
    {
        fprintf(stderr,
                "Input file contains subdatasets. Please, select one of them for reading.\n");
        GDALClose(hDataset);
        GDALDestroyDriverManager();
        exit(1);
    }

    if (CSLCount(GDALGetMetadata(hDataset, "SUBDATASETS")) > 0
        && bCopySubDatasets)
    {
        char **papszSubdatasets = GDALGetMetadata(hDataset, "SUBDATASETS");
        char *pszSubDest        = (char*) CPLMalloc(strlen(pszDest) + 32);
        int  i;
        int  bOldSubCall    = bSubCall;
        char **papszDupArgv = CSLDuplicate(argv);
        int  nRet           = 0;

        CPLFree(papszDupArgv[iDstFileArg]);
        papszDupArgv[iDstFileArg] = pszSubDest;
        bSubCall                  = TRUE;

        for (i = 0; papszSubdatasets[i] != NULL; i += 2)
        {
            CPLFree(papszDupArgv[iSrcFileArg]);
            papszDupArgv[iSrcFileArg] = CPLStrdup(strstr(papszSubdatasets[i], "=") + 1);
            sprintf(pszSubDest, "%s%d", pszDest, i / 2 + 1);
            nRet = ProxyMain(argc, papszDupArgv);
            if (nRet != 0)
                break;
        }

        CSLDestroy(papszDupArgv);

        bSubCall = bOldSubCall;
        CSLDestroy(argv);

        GDALClose(hDataset);

        if (!bSubCall)
        {
            GDALDumpOpenDatasets(stderr);
            GDALDestroyDriverManager();
        }

        return nRet;
    }

/* -------------------------------------------------------------------- */
/*      Collect some information from the source file.                  */
/* -------------------------------------------------------------------- */
    nRasterXSize = GDALGetRasterXSize(hDataset);
    nRasterYSize = GDALGetRasterYSize(hDataset);

    if (!bQuiet)
        printf("Input file size is %d, %d\n", nRasterXSize, nRasterYSize);

    if (anSrcWin[2] == 0 && anSrcWin[3] == 0)
    {
        anSrcWin[2] = nRasterXSize;
        anSrcWin[3] = nRasterYSize;
    }

/* -------------------------------------------------------------------- */
/*      Build band list to translate                                    */
/* -------------------------------------------------------------------- */
    if (nBandCount == 0)
    {
        nBandCount = GDALGetRasterCount(hDataset);
        if (nBandCount == 0)
        {
            fprintf(stderr, "Input file has no bands, and so cannot be translated.\n");
            GDALDestroyDriverManager();
            exit(1);
        }

        panBandList = (int*) CPLMalloc(sizeof(int) * nBandCount);

        for (i = 0; i < nBandCount; i++)
            panBandList[i] = i + 1;
    }
    else
    {
        for (i = 0; i < nBandCount; i++)
        {
            if (ABS(panBandList[i]) > GDALGetRasterCount(hDataset))
            {
                fprintf(stderr,
                        "Band %d requested, but only bands 1 to %d available.\n",
                        ABS(panBandList[i]), GDALGetRasterCount(hDataset));
                GDALDestroyDriverManager();
                exit(2);
            }
        }

        if (nBandCount != GDALGetRasterCount(hDataset))
            bDefBands = FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Compute the source window from the projected source window      */
/*      if the projected coordinates were provided.  Note that the      */
/*      projected coordinates are in ulx, uly, lrx, lry format,         */
/*      while the anSrcWin is xoff, yoff, xsize, ysize with the         */
/*      xoff,yoff being the ulx, uly in pixel/line.                     */
/* -------------------------------------------------------------------- */
    if (dfULX != 0.0 || dfULY != 0.0
        || dfLRX != 0.0 || dfLRY != 0.0)
    {
        double adfGeoTransform[6];

        GDALGetGeoTransform(hDataset, adfGeoTransform);

        if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0)
        {
            fprintf(stderr,
                    "The -projwin option was used, but the geotransform is\n"
                    "rotated.  This configuration is not supported.\n");
            GDALClose(hDataset);
            CPLFree(panBandList);
            GDALDestroyDriverManager();
            exit(1);
        }

        anSrcWin[0] = (int)
                      ((dfULX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001);
        anSrcWin[1] = (int)
                      ((dfULY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001);

        anSrcWin[2] = (int) ((dfLRX - dfULX) / adfGeoTransform[1] + 0.5);
        anSrcWin[3] = (int) ((dfLRY - dfULY) / adfGeoTransform[5] + 0.5);

        if (!bQuiet)
            fprintf(stdout,
                    "Computed -srcwin %d %d %d %d from projected window.\n",
                    anSrcWin[0],
                    anSrcWin[1],
                    anSrcWin[2],
                    anSrcWin[3]);

        if (anSrcWin[0] < 0 || anSrcWin[1] < 0
            || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset)
            || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset))
        {
            fprintf(stderr,
                    "Computed -srcwin falls outside raster size of %dx%d.\n",
                    GDALGetRasterXSize(hDataset),
                    GDALGetRasterYSize(hDataset));
            exit(1);
        }
    }

/* -------------------------------------------------------------------- */
/*      Verify source window.                                           */
/* -------------------------------------------------------------------- */
    if (anSrcWin[0] < 0 || anSrcWin[1] < 0
        || anSrcWin[2] <= 0 || anSrcWin[3] <= 0
        || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset)
        || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset))
    {
        fprintf(stderr,
                "-srcwin %d %d %d %d falls outside raster size of %dx%d\n"
                "or is otherwise illegal.\n",
                anSrcWin[0],
                anSrcWin[1],
                anSrcWin[2],
                anSrcWin[3],
                GDALGetRasterXSize(hDataset),
                GDALGetRasterYSize(hDataset));
        exit(1);
    }

/* -------------------------------------------------------------------- */
/*      Find the output driver.                                         */
/* -------------------------------------------------------------------- */
    hDriver = GDALGetDriverByName(pszFormat);
    if (hDriver == NULL)
    {
        int iDr;

        printf("Output driver `%s' not recognised.\n", pszFormat);
        printf("The following format drivers are configured and support output:\n");

        for (iDr = 0; iDr < GDALGetDriverCount(); iDr++)
        {
            GDALDriverH hDriver = GDALGetDriver(iDr);

            if (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, NULL) != NULL
                || GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATECOPY,
                                       NULL) != NULL)
            {
                printf("  %s: %s\n",
                       GDALGetDriverShortName(hDriver),
                       GDALGetDriverLongName(hDriver));
            }
        }

        printf("\n");
        Usage();

        GDALClose(hDataset);
        CPLFree(panBandList);
        GDALDestroyDriverManager();
        CSLDestroy(argv);
        CSLDestroy(papszCreateOptions);
        exit(1);
    }

/* -------------------------------------------------------------------- */
/*      The short form is to CreateCopy().  We use this if the input    */
/*      matches the whole dataset.  Eventually we should rewrite        */
/*      this entire program to use virtual datasets to construct a      */
/*      virtual input source to copy from.                              */
/* -------------------------------------------------------------------- */


    int bSpatialArrangementPreserved = (
        anSrcWin[0] == 0 && anSrcWin[1] == 0
        && anSrcWin[2] == GDALGetRasterXSize(hDataset)
        && anSrcWin[3] == GDALGetRasterYSize(hDataset)
        && pszOXSize == NULL && pszOYSize == NULL);

    if (eOutputType == GDT_Unknown
        && !bScale && !bUnscale
        && CSLCount(papszMetadataOptions) == 0 && bDefBands
        && eMaskMode == MASK_AUTO
        && bSpatialArrangementPreserved
        && nGCPCount == 0 && !bGotBounds
        && pszOutputSRS == NULL && !bSetNoData && !bUnsetNoData
        && nRGBExpand == 0 && !bStats)
    {
        hOutDS = GDALCreateCopy(hDriver, pszDest, hDataset,
                                bStrict, papszCreateOptions,
                                pfnProgress, NULL);

        if (hOutDS != NULL)
            GDALClose(hOutDS);

        GDALClose(hDataset);

        CPLFree(panBandList);

        if (!bSubCall)
        {
            GDALDumpOpenDatasets(stderr);
            GDALDestroyDriverManager();
        }

        CSLDestroy(argv);
        CSLDestroy(papszCreateOptions);

        return hOutDS == NULL;
    }

/* -------------------------------------------------------------------- */
/*      Establish some parameters.                                      */
/* -------------------------------------------------------------------- */
    if (pszOXSize == NULL)
    {
        nOXSize = anSrcWin[2];
        nOYSize = anSrcWin[3];
    }
    else
    {
        nOXSize = (int) ((pszOXSize[strlen(pszOXSize) - 1] == '%'
                          ? CPLAtofM(pszOXSize) / 100 * anSrcWin[2] : atoi(pszOXSize)));
        nOYSize = (int) ((pszOYSize[strlen(pszOYSize) - 1] == '%'
                          ? CPLAtofM(pszOYSize) / 100 * anSrcWin[3] : atoi(pszOYSize)));
    }

/* ==================================================================== */
/*      Create a virtual dataset.                                       */
/* ==================================================================== */
    VRTDataset *poVDS;

/* -------------------------------------------------------------------- */
/*      Make a virtual clone.                                           */
/* -------------------------------------------------------------------- */
    poVDS = (VRTDataset*) VRTCreate(nOXSize, nOYSize);

    if (nGCPCount == 0)
    {
        if (pszOutputSRS != NULL)
        {
            poVDS->SetProjection(pszOutputSRS);
        }
        else
        {
            pszProjection = GDALGetProjectionRef(hDataset);
            if (pszProjection != NULL && strlen(pszProjection) > 0)
                poVDS->SetProjection(pszProjection);
        }
    }

    if (bGotBounds)
    {
        adfGeoTransform[0] = adfULLR[0];
        adfGeoTransform[1] = (adfULLR[2] - adfULLR[0]) / nOXSize;
        adfGeoTransform[2] = 0.0;
        adfGeoTransform[3] = adfULLR[1];
        adfGeoTransform[4] = 0.0;
        adfGeoTransform[5] = (adfULLR[3] - adfULLR[1]) / nOYSize;

        poVDS->SetGeoTransform(adfGeoTransform);
    }

    else if (GDALGetGeoTransform(hDataset, adfGeoTransform) == CE_None
             && nGCPCount == 0)
    {
        adfGeoTransform[0] += anSrcWin[0] * adfGeoTransform[1]
                              + anSrcWin[1] * adfGeoTransform[2];
        adfGeoTransform[3] += anSrcWin[0] * adfGeoTransform[4]
                              + anSrcWin[1] * adfGeoTransform[5];

        adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize;
        adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize;
        adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize;
        adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize;

        poVDS->SetGeoTransform(adfGeoTransform);
    }

    if (nGCPCount != 0)
    {
        const char *pszGCPProjection = pszOutputSRS;

        if (pszGCPProjection == NULL)
            pszGCPProjection = GDALGetGCPProjection(hDataset);

        if (pszGCPProjection == NULL)
            pszGCPProjection = "";

        poVDS->SetGCPs(nGCPCount, pasGCPs, pszGCPProjection);

        GDALDeinitGCPs(nGCPCount, pasGCPs);
        CPLFree(pasGCPs);
    }

    else if (GDALGetGCPCount(hDataset) > 0)
    {
        GDAL_GCP *pasGCPs;
        int      nGCPs = GDALGetGCPCount(hDataset);

        pasGCPs = GDALDuplicateGCPs(nGCPs, GDALGetGCPs(hDataset));

        for (i = 0; i < nGCPs; i++)
        {
            pasGCPs[i].dfGCPPixel -= anSrcWin[0];
            pasGCPs[i].dfGCPLine  -= anSrcWin[1];
            pasGCPs[i].dfGCPPixel *= (nOXSize / (double) anSrcWin[2]);
            pasGCPs[i].dfGCPLine  *= (nOYSize / (double) anSrcWin[3]);
        }

        poVDS->SetGCPs(nGCPs, pasGCPs,
                       GDALGetGCPProjection(hDataset));

        GDALDeinitGCPs(nGCPs, pasGCPs);
        CPLFree(pasGCPs);
    }

/* -------------------------------------------------------------------- */
/*      Transfer generally applicable metadata.                         */
/* -------------------------------------------------------------------- */
    poVDS->SetMetadata(((GDALDataset*)hDataset)->GetMetadata());
    AttachMetadata((GDALDatasetH) poVDS, papszMetadataOptions);

    const char *pszInterleave = GDALGetMetadataItem(hDataset, "INTERLEAVE", "IMAGE_STRUCTURE");
    if (pszInterleave)
        poVDS->SetMetadataItem("INTERLEAVE", pszInterleave, "IMAGE_STRUCTURE");

/* -------------------------------------------------------------------- */
/*      Transfer metadata that remains valid if the spatial             */
/*      arrangement of the data is unaltered.                           */
/* -------------------------------------------------------------------- */
    if (bSpatialArrangementPreserved)
    {
        char **papszMD;

        papszMD = ((GDALDataset*)hDataset)->GetMetadata("RPC");
        if (papszMD != NULL)
            poVDS->SetMetadata(papszMD, "RPC");

        papszMD = ((GDALDataset*)hDataset)->GetMetadata("GEOLOCATION");
        if (papszMD != NULL)
            poVDS->SetMetadata(papszMD, "GEOLOCATION");
    }

    int nSrcBandCount = nBandCount;

    if (nRGBExpand != 0)
    {
        GDALRasterBand *poSrcBand;
        poSrcBand = ((GDALDataset*)
                     hDataset)->GetRasterBand(ABS(panBandList[0]));
        if (panBandList[0] < 0)
            poSrcBand = poSrcBand->GetMaskBand();

        GDALColorTable *poColorTable = poSrcBand->GetColorTable();
        if (poColorTable == NULL)
        {
            fprintf(stderr, "Error : band %d has no color table\n", ABS(panBandList[0]));
            GDALClose(hDataset);
            CPLFree(panBandList);
            GDALDestroyDriverManager();
            CSLDestroy(argv);
            CSLDestroy(papszCreateOptions);
            exit(1);
        }

        /* Check that the color table only contains gray levels */
        /* when using -expand gray */
        if (nRGBExpand == 1)
        {
            int nColorCount = poColorTable->GetColorEntryCount();
            int nColor;

            for (nColor = 0; nColor < nColorCount; nColor++)
            {
                const GDALColorEntry *poEntry = poColorTable->GetColorEntry(nColor);
                if (poEntry->c1 != poEntry->c2 || poEntry->c1 != poEntry->c2)
                {
                    fprintf(stderr, "Warning : color table contains non gray levels colors\n");
                    break;
                }
            }
        }

        if (nBandCount == 1)
            nBandCount = nRGBExpand;
        else if (nBandCount == 2 && (nRGBExpand == 3 || nRGBExpand == 4))
            nBandCount = nRGBExpand;
        else
        {
            fprintf(stderr, "Error : invalid use of -expand option.\n");
            exit(1);
        }
    }

    int bFilterOutStatsMetadata =
        (bScale || bUnscale || !bSpatialArrangementPreserved || nRGBExpand != 0);

/* ==================================================================== */
/*      Process all bands.                                              */
/* ==================================================================== */
    for (i = 0; i < nBandCount; i++)
    {
        VRTSourcedRasterBand *poVRTBand;
        GDALRasterBand       *poSrcBand;
        GDALDataType         eBandType;
        int                  nComponent = 0;

        int nSrcBand;
        if (nRGBExpand != 0)
        {
            if (nSrcBandCount == 2 && nRGBExpand == 4 && i == 3)
                nSrcBand = panBandList[1];
            else
            {
                nSrcBand   = panBandList[0];
                nComponent = i + 1;
            }
        }
        else
            nSrcBand = panBandList[i];

        poSrcBand = ((GDALDataset*) hDataset)->GetRasterBand(ABS(nSrcBand));

/* -------------------------------------------------------------------- */
/*      Select output data type to match source.                        */
/* -------------------------------------------------------------------- */
        if (eOutputType == GDT_Unknown)
            eBandType = poSrcBand->GetRasterDataType();
        else
            eBandType = eOutputType;

/* -------------------------------------------------------------------- */
/*      Create this band.                                               */
/* -------------------------------------------------------------------- */
        poVDS->AddBand(eBandType, NULL);
        poVRTBand = (VRTSourcedRasterBand*) poVDS->GetRasterBand(i + 1);
        if (nSrcBand < 0)
        {
            poVRTBand->AddMaskBandSource(poSrcBand);
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Do we need to collect scaling information?                      */
/* -------------------------------------------------------------------- */
        double dfScale = 1.0, dfOffset = 0.0;

        if (bScale && !bHaveScaleSrc)
        {
            double adfCMinMax[2];
            GDALComputeRasterMinMax(poSrcBand, TRUE, adfCMinMax);
            dfScaleSrcMin = adfCMinMax[0];
            dfScaleSrcMax = adfCMinMax[1];
        }

        if (bScale)
        {
            if (dfScaleSrcMax == dfScaleSrcMin)
                dfScaleSrcMax += 0.1;

            if (dfScaleDstMax == dfScaleDstMin)
                dfScaleDstMax += 0.1;

            dfScale = (dfScaleDstMax - dfScaleDstMin)
                      / (dfScaleSrcMax - dfScaleSrcMin);
            dfOffset = -1 * dfScaleSrcMin * dfScale + dfScaleDstMin;
        }

        if (bUnscale)
        {
            dfScale  = poSrcBand->GetScale();
            dfOffset = poSrcBand->GetOffset();
        }

/* -------------------------------------------------------------------- */
/*      Create a simple or complex data source depending on the         */
/*      translation type required.                                      */
/* -------------------------------------------------------------------- */
        if (bUnscale || bScale || (nRGBExpand != 0 && i < nRGBExpand))
        {
            poVRTBand->AddComplexSource(poSrcBand,
                                        anSrcWin[0], anSrcWin[1],
                                        anSrcWin[2], anSrcWin[3],
                                        0, 0, nOXSize, nOYSize,
                                        dfOffset, dfScale,
                                        VRT_NODATA_UNSET,
                                        nComponent);
        }
        else
            poVRTBand->AddSimpleSource(poSrcBand,
                                       anSrcWin[0], anSrcWin[1],
                                       anSrcWin[2], anSrcWin[3],
                                       0, 0, nOXSize, nOYSize);

/* -------------------------------------------------------------------- */
/*      In case of color table translate, we only set the color         */
/*      interpretation other info copied by CopyBandInfo are            */
/*      not relevant in RGB expansion.                                  */
/* -------------------------------------------------------------------- */
        if (nRGBExpand == 1)
        {
            poVRTBand->SetColorInterpretation(GCI_GrayIndex);
        }
        else if (nRGBExpand != 0 && i < nRGBExpand)
        {
            poVRTBand->SetColorInterpretation((GDALColorInterp) (GCI_RedBand + i));
        }

/* -------------------------------------------------------------------- */
/*      copy over some other information of interest.                   */
/* -------------------------------------------------------------------- */
        else
        {
            CopyBandInfo(poSrcBand, poVRTBand,
                         !bStats && !bFilterOutStatsMetadata,
                         !bUnscale,
                         !bSetNoData && !bUnsetNoData);
        }

/* -------------------------------------------------------------------- */
/*      Set a forcable nodata value?                                    */
/* -------------------------------------------------------------------- */
        if (bSetNoData)
        {
            double dfVal    = dfNoDataReal;
            int    bClamped = FALSE, bRounded = FALSE;

#define CLAMP(val, type, minval, maxval)                                          \
    do { if (val < minval) { bClamped = TRUE; val = minval;                       \
         }                                                                        \
         else if (val > maxval) { bClamped = TRUE; val = maxval; }                \
         else if (val != (type)val) { bRounded = TRUE; val = (type)(val + 0.5); } \
    }                                                                             \
    while (0)

            switch (eBandType)
            {
            case GDT_Byte:
                CLAMP(dfVal, GByte, 0.0, 255.0);
                break;

            case GDT_Int16:
                CLAMP(dfVal, GInt16, -32768.0, 32767.0);
                break;

            case GDT_UInt16:
                CLAMP(dfVal, GUInt16, 0.0, 65535.0);
                break;

            case GDT_Int32:
                CLAMP(dfVal, GInt32, -2147483648.0, 2147483647.0);
                break;

            case GDT_UInt32:
                CLAMP(dfVal, GUInt32, 0.0, 4294967295.0);
                break;

            default:
                break;
            }

            if (bClamped)
            {
                printf("for band %d, nodata value has been clamped "
                       "to %.0f, the original value being out of range.\n",
                       i + 1, dfVal);
            }
            else if (bRounded)
            {
                printf("for band %d, nodata value has been rounded "
                       "to %.0f, %s being an integer datatype.\n",
                       i + 1, dfVal,
                       GDALGetDataTypeName(eBandType));
            }

            poVRTBand->SetNoDataValue(dfVal);
        }

        if (eMaskMode == MASK_AUTO &&
            (GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) & GMF_PER_DATASET) == 0 &&
            (poSrcBand->GetMaskFlags() & (GMF_ALL_VALID | GMF_NODATA)) == 0)
        {
            if (poVRTBand->CreateMaskBand(poSrcBand->GetMaskFlags()) == CE_None)
            {
                VRTSourcedRasterBand *hMaskVRTBand =
                    (VRTSourcedRasterBand*)poVRTBand->GetMaskBand();
                hMaskVRTBand->AddMaskBandSource(poSrcBand,
                                                anSrcWin[0], anSrcWin[1],
                                                anSrcWin[2], anSrcWin[3],
                                                0, 0, nOXSize, nOYSize);
            }
        }
    }

    if (eMaskMode == MASK_USER)
    {
        GDALRasterBand *poSrcBand =
            (GDALRasterBand*)GDALGetRasterBand(hDataset, ABS(nMaskBand));
        if (poSrcBand && poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None)
        {
            VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*)
                                                 GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1));
            if (nMaskBand > 0)
                hMaskVRTBand->AddSimpleSource(poSrcBand,
                                              anSrcWin[0], anSrcWin[1],
                                              anSrcWin[2], anSrcWin[3],
                                              0, 0, nOXSize, nOYSize);
            else
                hMaskVRTBand->AddMaskBandSource(poSrcBand,
                                                anSrcWin[0], anSrcWin[1],
                                                anSrcWin[2], anSrcWin[3],
                                                0, 0, nOXSize, nOYSize);
        }
    }
    else if (eMaskMode == MASK_AUTO && nSrcBandCount > 0 &&
             GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) == GMF_PER_DATASET)
    {
        if (poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None)
        {
            VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*)
                                                 GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1));
            hMaskVRTBand->AddMaskBandSource((GDALRasterBand*)GDALGetRasterBand(hDataset, 1),
                                            anSrcWin[0], anSrcWin[1],
                                            anSrcWin[2], anSrcWin[3],
                                            0, 0, nOXSize, nOYSize);
        }
    }

/* -------------------------------------------------------------------- */
/*      Compute stats if required.                                      */
/* -------------------------------------------------------------------- */
    if (bStats)
    {
        for (i = 0; i < poVDS->GetRasterCount(); i++)
        {
            double dfMin, dfMax, dfMean, dfStdDev;
            poVDS->GetRasterBand(i + 1)->ComputeStatistics(bApproxStats,
                                                           &dfMin, &dfMax, &dfMean, &dfStdDev, GDALDummyProgress, NULL);
        }
    }

/* -------------------------------------------------------------------- */
/*      Write to the output file using CopyCreate().                    */
/* -------------------------------------------------------------------- */
    hOutDS = GDALCreateCopy(hDriver, pszDest, (GDALDatasetH) poVDS,
                            bStrict, papszCreateOptions,
                            pfnProgress, NULL);
    if (hOutDS != NULL)
    {
        int bHasGotErr = FALSE;
        CPLErrorReset();
        GDALFlushCache(hOutDS);
        if (CPLGetLastErrorType() != CE_None)
            bHasGotErr = TRUE;

        GDALClose(hOutDS);
        if (bHasGotErr)
            hOutDS = NULL;
    }

    GDALClose((GDALDatasetH) poVDS);

    GDALClose(hDataset);

    CPLFree(panBandList);

    CPLFree(pszOutputSRS);

    if (!bSubCall)
    {
        GDALDumpOpenDatasets(stderr);
        GDALDestroyDriverManager();
    }

    CSLDestroy(argv);
    CSLDestroy(papszCreateOptions);

    return hOutDS == NULL;
}
bool QgsNewGeoPackageLayerDialog::apply()
{
  QString fileName( mDatabase->filePath() );
  if ( !fileName.endsWith( QLatin1String( ".gpkg" ), Qt::CaseInsensitive ) )
    fileName += QLatin1String( ".gpkg" );

  bool createNewDb = false;

  if ( QFile( fileName ).exists( fileName ) )
  {
    bool overwrite = false;

    switch ( mBehavior )
    {
      case Prompt:
      {
        QMessageBox msgBox;
        msgBox.setIcon( QMessageBox::Question );
        msgBox.setWindowTitle( tr( "The File Already Exists." ) );
        msgBox.setText( tr( "Do you want to overwrite the existing file with a new database or add a new layer to it?" ) );
        QPushButton *overwriteButton = msgBox.addButton( tr( "Overwrite" ), QMessageBox::ActionRole );
        QPushButton *addNewLayerButton = msgBox.addButton( tr( "Add new layer" ), QMessageBox::ActionRole );
        msgBox.setStandardButtons( QMessageBox::Cancel );
        msgBox.setDefaultButton( addNewLayerButton );
        bool cancel = false;
        if ( property( "hideDialogs" ).toBool() )
        {
          overwrite = property( "question_existing_db_answer_overwrite" ).toBool();
          if ( !overwrite )
            cancel = !property( "question_existing_db_answer_add_new_layer" ).toBool();
        }
        else
        {
          int ret = msgBox.exec();
          if ( ret == QMessageBox::Cancel )
            cancel = true;
          if ( msgBox.clickedButton() == overwriteButton )
            overwrite = true;
        }
        if ( cancel )
        {
          return false;
        }
        break;
      }

      case Overwrite:
        overwrite = true;
        break;

      case AddNewLayer:
        overwrite = false;
        break;
    }

    if ( overwrite )
    {
      QFile( fileName ).remove();
      createNewDb = true;
    }
  }
  else
  {
    createNewDb = true;
  }

  OGRSFDriverH hGpkgDriver = OGRGetDriverByName( "GPKG" );
  if ( !hGpkgDriver )
  {
    if ( !property( "hideDialogs" ).toBool() )
      QMessageBox::critical( this, tr( "Layer creation failed" ),
                             tr( "GeoPackage driver not found" ) );
    return false;
  }

  gdal::ogr_datasource_unique_ptr hDS;
  if ( createNewDb )
  {
    hDS.reset( OGR_Dr_CreateDataSource( hGpkgDriver, fileName.toUtf8().constData(), nullptr ) );
    if ( !hDS )
    {
      QString msg( tr( "Creation of database failed (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
      if ( !property( "hideDialogs" ).toBool() )
        QMessageBox::critical( this, tr( "Layer creation failed" ), msg );
      return false;
    }
  }
  else
  {
    OGRSFDriverH hDriver = nullptr;
    hDS.reset( OGROpen( fileName.toUtf8().constData(), true, &hDriver ) );
    if ( !hDS )
    {
      QString msg( tr( "Opening of database failed (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
      if ( !property( "hideDialogs" ).toBool() )
        QMessageBox::critical( this, tr( "Layer creation failed" ), msg );
      return false;
    }
    if ( hDriver != hGpkgDriver )
    {
      QString msg( tr( "Opening of file succeeded, but this is not a GeoPackage database" ) );
      if ( !property( "hideDialogs" ).toBool() )
        QMessageBox::critical( this, tr( "Layer creation failed" ), msg );
      return false;
    }
  }

  QString tableName( mTableNameEdit->text() );

  bool overwriteTable = false;
  if ( OGR_DS_GetLayerByName( hDS.get(), tableName.toUtf8().constData() ) )
  {
    if ( property( "hideDialogs" ).toBool() )
    {
      overwriteTable = property( "question_existing_layer_answer_overwrite" ).toBool();
    }
    else if ( QMessageBox::question( this, tr( "Existing layer" ),
                                     tr( "A table with the same name already exists. Do you want to overwrite it?" ),
                                     QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::Yes )
    {
      overwriteTable = true;
    }

    if ( !overwriteTable )
    {
      return false;
    }
  }

  QString layerIdentifier( mLayerIdentifierEdit->text() );
  QString layerDescription( mLayerDescriptionEdit->text() );

  OGRwkbGeometryType wkbType = static_cast<OGRwkbGeometryType>
                               ( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );

  // z-coordinate & m-value.
  if ( mGeometryWithZCheckBox->isChecked() )
    wkbType = OGR_GT_SetZ( wkbType );

  if ( mGeometryWithMCheckBox->isChecked() )
    wkbType = OGR_GT_SetM( wkbType );

  OGRSpatialReferenceH hSRS = nullptr;
  // consider spatial reference system of the layer
  QgsCoordinateReferenceSystem srs = mCrsSelector->crs();
  if ( wkbType != wkbNone && srs.isValid() )
  {
    QString srsWkt = srs.toWkt();
    hSRS = OSRNewSpatialReference( srsWkt.toLocal8Bit().data() );
  }

  // Set options
  char **options = nullptr;

  if ( overwriteTable )
    options = CSLSetNameValue( options, "OVERWRITE", "YES" );
  if ( !layerIdentifier.isEmpty() )
    options = CSLSetNameValue( options, "IDENTIFIER", layerIdentifier.toUtf8().constData() );
  if ( !layerDescription.isEmpty() )
    options = CSLSetNameValue( options, "DESCRIPTION", layerDescription.toUtf8().constData() );

  QString featureId( mFeatureIdColumnEdit->text() );
  if ( !featureId.isEmpty() )
    options = CSLSetNameValue( options, "FID", featureId.toUtf8().constData() );

  QString geometryColumn( mGeometryColumnEdit->text() );
  if ( wkbType != wkbNone && !geometryColumn.isEmpty() )
    options = CSLSetNameValue( options, "GEOMETRY_COLUMN", geometryColumn.toUtf8().constData() );

  if ( wkbType != wkbNone )
    options = CSLSetNameValue( options, "SPATIAL_INDEX", mCheckBoxCreateSpatialIndex->isChecked() ? "YES" : "NO" );

  OGRLayerH hLayer = OGR_DS_CreateLayer( hDS.get(), tableName.toUtf8().constData(), hSRS, wkbType, options );
  CSLDestroy( options );
  if ( hSRS )
    OSRRelease( hSRS );
  if ( !hLayer )
  {
    QString msg( tr( "Creation of layer failed (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
    if ( !property( "hideDialogs" ).toBool() )
      QMessageBox::critical( this, tr( "Layer creation failed" ), msg );
    return false;
  }

  QTreeWidgetItemIterator it( mAttributeView );
  while ( *it )
  {
    QString fieldName( ( *it )->text( 0 ) );
    QString fieldType( ( *it )->text( 1 ) );
    QString fieldWidth( ( *it )->text( 2 ) );

    OGRFieldType ogrType( OFTString );
    if ( fieldType == QLatin1String( "text" ) )
      ogrType = OFTString;
    else if ( fieldType == QLatin1String( "integer" ) )
      ogrType = OFTInteger;
    else if ( fieldType == QLatin1String( "integer64" ) )
      ogrType = OFTInteger64;
    else if ( fieldType == QLatin1String( "real" ) )
      ogrType = OFTReal;
    else if ( fieldType == QLatin1String( "date" ) )
      ogrType = OFTDate;
    else if ( fieldType == QLatin1String( "datetime" ) )
      ogrType = OFTDateTime;

    int ogrWidth = fieldWidth.toInt();

    gdal::ogr_field_def_unique_ptr fld( OGR_Fld_Create( fieldName.toUtf8().constData(), ogrType ) );
    OGR_Fld_SetWidth( fld.get(), ogrWidth );

    if ( OGR_L_CreateField( hLayer, fld.get(), true ) != OGRERR_NONE )
    {
      if ( !property( "hideDialogs" ).toBool() )
      {
        QMessageBox::critical( this, tr( "Layer creation failed" ),
                               tr( "Creation of field %1 failed (OGR error: %2)" )
                               .arg( fieldName, QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
      }
      return false;
    }

    ++it;
  }

  // In GDAL >= 2.0, the driver implements a deferred creation strategy, so
  // issue a command that will force table creation
  CPLErrorReset();
  OGR_L_ResetReading( hLayer );
  if ( CPLGetLastErrorType() != CE_None )
  {
    QString msg( tr( "Creation of layer failed (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
    if ( !property( "hideDialogs" ).toBool() )
      QMessageBox::critical( this, tr( "Layer creation failed" ), msg );
    return false;
  }
  hDS.reset();

  QString uri( QStringLiteral( "%1|layername=%2" ).arg( fileName, tableName ) );
  QString userVisiblelayerName( layerIdentifier.isEmpty() ? tableName : layerIdentifier );
  QgsVectorLayer *layer = new QgsVectorLayer( uri, userVisiblelayerName, QStringLiteral( "ogr" ) );
  if ( layer->isValid() )
  {
    // register this layer with the central layers registry
    QList<QgsMapLayer *> myList;
    myList << layer;
    //addMapLayers returns a list of all successfully added layers
    //so we compare that to our original list.
    if ( myList == QgsProject::instance()->addMapLayers( myList ) )
      return true;
  }
  else
  {
    if ( !property( "hideDialogs" ).toBool() )
      QMessageBox::critical( this, tr( "Invalid Layer" ), tr( "%1 is an invalid layer and cannot be loaded." ).arg( tableName ) );
    delete layer;
  }

  return false;
}
Beispiel #27
0
int db__driver_execute_immediate(dbString * sql)
{
    char *where, *table;
    int res, ncols, i;
    column_info *cols;

    OGRLayerH hLayer;
    OGRFeatureH hFeature;
    OGRFeatureDefnH hFeatureDefn;
    OGRFieldDefnH hFieldDefn;
    
    G_debug(1, "db__driver_execute_immediate():");
    
    G_debug(3, "\tSQL: '%s'", db_get_string(sql));
    
    /* try RDBMS SQL */
    OGR_DS_ExecuteSQL(hDs, db_get_string(sql), NULL, NULL);
    if (CPLGetLastErrorType() == CE_None)
	return DB_OK;
    
    /* parse UPDATE statement */
    res = parse_sql_update(db_get_string(sql), &table, &cols, &ncols, &where);
    G_debug(3, "\tUPDATE: table=%s, where=%s, ncols=%d", table, where ? where : "", ncols);
    if (res != 0)
	return DB_FAILED;
    
    /* get OGR layer */
    hLayer = OGR_DS_GetLayerByName(hDs, table);
    if (!hLayer) {
	db_d_append_error(_("OGR layer <%s> not found"), table);
	db_d_report_error();
	return DB_FAILED;
    }
    
    if (where)
	OGR_L_SetAttributeFilter(hLayer, where);
    
    /* get columns info */
    hFeatureDefn = OGR_L_GetLayerDefn(hLayer);
    for (i = 0; i < ncols; i++) {
	cols[i].index = OGR_FD_GetFieldIndex(hFeatureDefn, cols[i].name);
	if (cols[i].index < 0) {
	    db_d_append_error(_("Column <%s> not found in table <%s>"),
			      cols[i].name, table);
	    db_d_report_error();
	    return DB_FAILED;
	}
	cols[i].qindex = OGR_FD_GetFieldIndex(hFeatureDefn, cols[i].value);
	hFieldDefn = OGR_FD_GetFieldDefn(hFeatureDefn, cols[i].index);
	cols[i].type = OGR_Fld_GetType(hFieldDefn);

	G_debug(3, "\t\tcol=%s, val=%s, idx=%d, type=%d, qidx=%d",
		cols[i].name, cols[i].value, cols[i].index, cols[i].type,
		cols[i].qindex);
    }
    
    /* update features */
    OGR_L_ResetReading(hLayer);
    while(TRUE) {
	char *value;
	
	hFeature = OGR_L_GetNextFeature(hLayer);
	if (!hFeature)
	    break;
	G_debug(5, "\tfid=%ld", OGR_F_GetFID(hFeature));
	
	for (i = 0; i < ncols; i++) {
	    if (cols[i].qindex > -1) {
		value = (char *)OGR_F_GetFieldAsString(hFeature, cols[i].qindex);
	    }
	    else {
		if ((cols[i].type != OFTInteger ||
		     cols[i].type != OFTReal) && *(cols[i].value) == '\'') {
		    value = G_strchg(cols[i].value, '\'', ' ');
		    G_strip(value);
		}
		else {
		    value = cols[i].value;
		}
	    }
	    OGR_F_SetFieldString(hFeature, cols[i].index, value);
	}
	OGR_L_SetFeature(hLayer, hFeature);
	OGR_F_Destroy(hFeature);
    }
    
    G_free(table);
    G_free(where);
    for (i = 0; i < ncols; i++) {
	G_free(cols[i].name);
	G_free(cols[i].value);
    }
    
    return DB_OK;
}