Esempio n. 1
0
int OGRPGeoDataSource::Open( const char * pszNewName, int bUpdate,
                             CPL_UNUSED int bTestOpen )
{
    CPLAssert( nLayers == 0 );

/* -------------------------------------------------------------------- */
/*      If this is the name of an MDB file, then construct the          */
/*      appropriate connection string.  Otherwise clip of PGEO: to      */
/*      get the DSN.                                                    */
/*                                                                      */
/* -------------------------------------------------------------------- */
    char *pszDSN;
    const char* pszOptionName = "";
    const char* pszDSNStringTemplate = NULL;
    if( STARTS_WITH_CI(pszNewName, "PGEO:") )
        pszDSN = CPLStrdup( pszNewName + 5 );
    else
    {
        pszOptionName = "PGEO_DRIVER_TEMPLATE";
        pszDSNStringTemplate = CPLGetConfigOption( pszOptionName, NULL );
        if( pszDSNStringTemplate == NULL )
        {
            pszDSNStringTemplate = "DRIVER=Microsoft Access Driver (*.mdb);DBQ=%s";
        }
        if (!CheckDSNStringTemplate(pszDSNStringTemplate))
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Illegal value for PGEO_DRIVER_TEMPLATE option");
            return FALSE;
        }
        pszDSN = (char *) CPLMalloc(strlen(pszNewName)+strlen(pszDSNStringTemplate)+100);
        /* coverity[tainted_string] */
        snprintf( pszDSN,
                  strlen(pszNewName)+strlen(pszDSNStringTemplate)+100,
                  pszDSNStringTemplate,  pszNewName );
    }

/* -------------------------------------------------------------------- */
/*      Initialize based on the DSN.                                    */
/* -------------------------------------------------------------------- */
    CPLDebug( "PGeo", "EstablishSession(%s)", pszDSN );

    if( !oSession.EstablishSession( pszDSN, NULL, NULL ) )
    {
        int bError = TRUE;
        if( !STARTS_WITH_CI(pszNewName, "PGEO:") )
        {
            // Trying with another template (#5594)
            pszDSNStringTemplate = "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s";
            CPLFree( pszDSN );
            pszDSN = (char *) CPLMalloc(strlen(pszNewName)+strlen(pszDSNStringTemplate)+100);
            snprintf( pszDSN,
                     strlen(pszNewName)+strlen(pszDSNStringTemplate)+100,
                     pszDSNStringTemplate,  pszNewName );
            CPLDebug( "PGeo", "EstablishSession(%s)", pszDSN );
            if( oSession.EstablishSession( pszDSN, NULL, NULL ) )
            {
                bError = FALSE;
            }
        }
        if( bError )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                    "Unable to initialize ODBC connection to DSN for %s,\n"
                    "%s", pszDSN, oSession.GetLastError() );
            CPLFree( pszDSN );
            return FALSE;
        }
    }

    CPLFree( pszDSN );

    pszName = CPLStrdup( pszNewName );

    bDSUpdate = bUpdate;

/* -------------------------------------------------------------------- */
/*      Collect list of tables and their supporting info from           */
/*      GDB_GeomColumns.                                                */
/* -------------------------------------------------------------------- */
    std::vector<char **> apapszGeomColumns;
    CPLODBCStatement oStmt( &oSession );

    oStmt.Append( "SELECT TableName, FieldName, ShapeType, ExtentLeft, ExtentRight, ExtentBottom, ExtentTop, SRID, HasZ FROM GDB_GeomColumns" );

    if( !oStmt.ExecuteSQL() )
    {
        CPLDebug( "PGEO",
                  "SELECT on GDB_GeomColumns fails, perhaps not a personal geodatabase?\n%s",
                  oSession.GetLastError() );
        return FALSE;
    }

    while( oStmt.Fetch() )
    {
        int i, iNew = static_cast<int>(apapszGeomColumns.size());
        char **papszRecord = NULL;
        for( i = 0; i < 9; i++ )
            papszRecord = CSLAddString( papszRecord,
                                        oStmt.GetColData(i) );
        apapszGeomColumns.resize(iNew+1);
        apapszGeomColumns[iNew] = papszRecord;
    }

/* -------------------------------------------------------------------- */
/*      Create a layer for each spatial table.                          */
/* -------------------------------------------------------------------- */
    unsigned int iTable;

    papoLayers = (OGRPGeoLayer **) CPLCalloc(apapszGeomColumns.size(),
                                             sizeof(void*));

    for( iTable = 0; iTable < apapszGeomColumns.size(); iTable++ )
    {
        char **papszRecord = apapszGeomColumns[iTable];
        OGRPGeoTableLayer  *poLayer;

        poLayer = new OGRPGeoTableLayer( this );

        if( poLayer->Initialize( papszRecord[0],         // TableName
                                 papszRecord[1],         // FieldName
                                 atoi(papszRecord[2]),   // ShapeType
                                 CPLAtof(papszRecord[3]),   // ExtentLeft
                                 CPLAtof(papszRecord[4]),   // ExtentRight
                                 CPLAtof(papszRecord[5]),   // ExtentBottom
                                 CPLAtof(papszRecord[6]),   // ExtentTop
                                 atoi(papszRecord[7]),   // SRID
                                 atoi(papszRecord[8]))  // HasZ
            != CE_None )
        {
            delete poLayer;
        }
        else
            papoLayers[nLayers++] = poLayer;

        CSLDestroy( papszRecord );
    }

    return TRUE;
}
Esempio n. 2
0
bool LevellerDataset::load_from_file(VSILFILE* file, const char* pszFilename)
{
    // get hf dimensions
    if(!this->get(nRasterXSize, file, "hf_w"))
	{
		CPLError( CE_Failure, CPLE_OpenFailed,
					  "Cannot determine heightfield width." );
        return false;
	}

    if(!this->get(nRasterYSize, file, "hf_b"))
	{
		CPLError( CE_Failure, CPLE_OpenFailed,
					  "Cannot determine heightfield breadth." );
        return false;
	}

	if(nRasterXSize < 2 || nRasterYSize < 2)
	{
		CPLError( CE_Failure, CPLE_OpenFailed,
					  "Heightfield raster dimensions too small." );
        return false;
	}

    // Record start of pixel data
    size_t datalen;
    if(!this->locate_data(m_nDataOffset, datalen, file, "hf_data"))
	{
		CPLError( CE_Failure, CPLE_OpenFailed,
					  "Cannot locate elevation data." );
        return false;
	}

    // Sanity check: do we have enough pixels?
    if(datalen != nRasterXSize * nRasterYSize * sizeof(float))
	{
		CPLError( CE_Failure, CPLE_OpenFailed,
					  "File does not have enough data." );
        return false;
	}


	// Defaults for raster coordsys.
    m_adfTransform[0] = 0.0;
    m_adfTransform[1] = 1.0;
    m_adfTransform[2] = 0.0;
    m_adfTransform[3] = 0.0;
    m_adfTransform[4] = 0.0;
    m_adfTransform[5] = 1.0;

	m_dElevScale = 1.0;
    m_dElevBase = 0.0;
	strcpy(m_szElevUnits, "");

	if(m_version == 7)
	{
		// Read coordsys info.
		int csclass = LEV_COORDSYS_RASTER;
	    (void)this->get(csclass, file, "csclass");

		if(csclass != LEV_COORDSYS_RASTER)
		{
			// Get projection details and units.

			CPLAssert(m_pszProjection == NULL);

			if(csclass == LEV_COORDSYS_LOCAL)
			{
				UNITLABEL unitcode;
				//char szLocalUnits[8];
                                int unitcode_int;
				if(!this->get(unitcode_int, file, "coordsys_units"))
					unitcode_int = UNITLABEL_M;
                                unitcode = (UNITLABEL) unitcode_int;

				if(!this->make_local_coordsys("Leveller", unitcode))
				{
					CPLError( CE_Failure, CPLE_OpenFailed,
								  "Cannot define local coordinate system." );
					return false;
				}
			}
			else if(csclass == LEV_COORDSYS_GEO)
			{
				char szWKT[1024];
				if(!this->get(szWKT, 1023, file, "coordsys_wkt"))
					return 0;

				m_pszProjection = (char*)CPLMalloc(strlen(szWKT) + 1);
				strcpy(m_pszProjection, szWKT);
			}
			else
			{
				CPLError( CE_Failure, CPLE_OpenFailed,
						  "Unknown coordinate system type in %s.",
						  pszFilename );
				return false;
			}

			// Get ground extents.
			digital_axis axis_ns, axis_ew;

			if(axis_ns.get(*this, file, 0)
				&& axis_ew.get(*this, file, 1))
			{
				m_adfTransform[0] = axis_ew.origin(nRasterXSize);
				m_adfTransform[1] = axis_ew.scaling(nRasterXSize);
				m_adfTransform[2] = 0.0;

				m_adfTransform[3] = axis_ns.origin(nRasterYSize);
				m_adfTransform[4] = 0.0;
				m_adfTransform[5] = axis_ns.scaling(nRasterYSize);
			}
		}

		// Get vertical (elev) coordsys.
		int bHasVertCS = FALSE;
		if(this->get(bHasVertCS, file, "coordsys_haselevm") && bHasVertCS)
		{
			this->get(m_dElevScale, file, "coordsys_em_scale");
			this->get(m_dElevBase, file, "coordsys_em_base");
			UNITLABEL unitcode;
                        int unitcode_int;
			if(this->get(unitcode_int, file, "coordsys_em_units"))
			{
                                unitcode = (UNITLABEL) unitcode_int;
				const char* pszUnitID = this->code_to_id(unitcode);
				if(pszUnitID != NULL)
					strcpy(m_szElevUnits, pszUnitID);
				else
				{
					CPLError( CE_Failure, CPLE_OpenFailed,
								  "Unknown OEM elevation unit of measure (%d)",
									unitcode );
					return false;
				}
			}
			// datum and localcs are currently unused.
		}
	}
	else
	{
		// Legacy files use world units.
	    char szWorldUnits[32];
		strcpy(szWorldUnits, "m");

	    double dWorldscale = 1.0;

		if(this->get(dWorldscale, file, "hf_worldspacing"))
		{
			//m_bHasWorldscale = true;
			if(this->get(szWorldUnits, sizeof(szWorldUnits)-1, file, 
				"hf_worldspacinglabel"))
			{
				// Drop long name, if present.
				char* p = strchr(szWorldUnits, ' ');
				if(p != NULL)
					*p = 0;
			}

#if 0
			// If the units are something besides m/ft/sft, 
			// then convert them to meters.

			if(!str_equal("m", szWorldUnits)
			   && !str_equal("ft", szWorldUnits)
			   && !str_equal("sft", szWorldUnits))
			{
				dWorldscale = this->convert_measure(dWorldscale, szWorldUnits);
				strcpy(szWorldUnits, "m");
			}
#endif

			// Our extents are such that the origin is at the 
			// center of the heightfield.
			m_adfTransform[0] = -0.5 * dWorldscale * (nRasterXSize-1);
			m_adfTransform[3] = -0.5 * dWorldscale * (nRasterYSize-1);
			m_adfTransform[1] = dWorldscale;
			m_adfTransform[5] = dWorldscale;
		}
		m_dElevScale = dWorldscale; // this was 1.0 before because 
		// we were converting to real elevs ourselves, but
		// some callers may want both the raw pixels and the 
		// transform to get real elevs.

		if(!this->make_local_coordsys("Leveller world space", szWorldUnits))
		{
			CPLError( CE_Failure, CPLE_OpenFailed,
						  "Cannot define local coordinate system." );
			return false;
		}
	}

    return true;
}
Esempio n. 3
0
int OGRS57DataSource::Open( const char * pszFilename )

{
    int         iModule;

    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Setup reader options.                                           */
/* -------------------------------------------------------------------- */
    char **papszReaderOptions = NULL;
    S57Reader   *poModule = new S57Reader( pszFilename );

    if( GetOption(S57O_LNAM_REFS) == NULL )
        papszReaderOptions = CSLSetNameValue(papszReaderOptions, 
                                         S57O_LNAM_REFS, "ON" );
    else
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_LNAM_REFS, 
                             GetOption(S57O_LNAM_REFS));

    if( GetOption(S57O_UPDATES) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_UPDATES, 
                             GetOption(S57O_UPDATES));

    if( GetOption(S57O_SPLIT_MULTIPOINT) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_SPLIT_MULTIPOINT,
                             GetOption(S57O_SPLIT_MULTIPOINT) );

    if( GetOption(S57O_ADD_SOUNDG_DEPTH) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_ADD_SOUNDG_DEPTH,
                             GetOption(S57O_ADD_SOUNDG_DEPTH));

    if( GetOption(S57O_PRESERVE_EMPTY_NUMBERS) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_PRESERVE_EMPTY_NUMBERS,
                             GetOption(S57O_PRESERVE_EMPTY_NUMBERS) );

    if( GetOption(S57O_RETURN_PRIMITIVES) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_RETURN_PRIMITIVES,
                             GetOption(S57O_RETURN_PRIMITIVES) );

    if( GetOption(S57O_RETURN_LINKAGES) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_RETURN_LINKAGES,
                             GetOption(S57O_RETURN_LINKAGES) );

    if( GetOption(S57O_RETURN_DSID) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_RETURN_DSID,
                             GetOption(S57O_RETURN_DSID) );

    if( GetOption(S57O_RECODE_BY_DSSI) != NULL )
        papszReaderOptions = 
            CSLSetNameValue( papszReaderOptions, S57O_RECODE_BY_DSSI,
                             GetOption(S57O_RECODE_BY_DSSI) );

    int bRet = poModule->SetOptions( papszReaderOptions );
    CSLDestroy( papszReaderOptions );

    if( !bRet )
    {
        delete poModule;
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Try opening.                                                    */
/*                                                                      */
/*      Eventually this should check for catalogs, and if found         */
/*      instantiate a whole series of modules.                          */
/* -------------------------------------------------------------------- */
    if( !poModule->Open( TRUE ) )
    {
        delete poModule;

        return FALSE;
    }

    int bSuccess = TRUE;

    nModules = 1;
    papoModules = (S57Reader **) CPLMalloc(sizeof(void*));
    papoModules[0] = poModule;

/* -------------------------------------------------------------------- */
/*      Add the header layers if they are called for.                   */
/* -------------------------------------------------------------------- */
    if( GetOption( S57O_RETURN_DSID ) == NULL 
        || CSLTestBoolean(GetOption( S57O_RETURN_DSID )) )
    {
        OGRFeatureDefn  *poDefn = S57GenerateDSIDFeatureDefn();
        AddLayer( new OGRS57Layer( this, poDefn ) );
    }

/* -------------------------------------------------------------------- */
/*      Add the primitive layers if they are called for.                */
/* -------------------------------------------------------------------- */
    if( GetOption( S57O_RETURN_PRIMITIVES ) != NULL )
    {
        OGRFeatureDefn  *poDefn
            = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VI, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VC, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VE, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateVectorPrimitiveFeatureDefn( RCNM_VF, poModule->GetOptionFlags());
        AddLayer( new OGRS57Layer( this, poDefn ) );
    }

/* -------------------------------------------------------------------- */
/*      Initialize a layer for each type of geometry.  Eventually       */
/*      we will do this by object class.                                */
/* -------------------------------------------------------------------- */
    if( OGRS57Driver::GetS57Registrar() == NULL )
    {
        OGRFeatureDefn  *poDefn
            = S57GenerateGeomFeatureDefn( wkbPoint,
                                          poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateGeomFeatureDefn( wkbLineString, 
                                             poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateGeomFeatureDefn( wkbPolygon, 
                                             poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );

        poDefn = S57GenerateGeomFeatureDefn( wkbNone, 
                                             poModule->GetOptionFlags() );
        AddLayer( new OGRS57Layer( this, poDefn ) );
    }

/* -------------------------------------------------------------------- */
/*      Initialize a feature definition for each class that actually    */
/*      occurs in the dataset.                                          */
/* -------------------------------------------------------------------- */
    else
    {
        OGRFeatureDefn  *poDefn;
        std::vector<int> anClassCount;
        int              bGeneric = FALSE;
        unsigned int     iClass;

        poClassContentExplorer =
            new S57ClassContentExplorer( OGRS57Driver::GetS57Registrar() );

        for( iModule = 0; iModule < nModules; iModule++ )
            papoModules[iModule]->SetClassBased( OGRS57Driver::GetS57Registrar(),
                                                 poClassContentExplorer );

        for( iModule = 0; iModule < nModules; iModule++ )
        {
            bSuccess &= 
                papoModules[iModule]->CollectClassList(anClassCount);
        }

        for( iClass = 0; iClass < anClassCount.size(); iClass++ )
        {
            if( anClassCount[iClass] > 0 )
            {
                poDefn = 
                    S57GenerateObjectClassDefn( OGRS57Driver::GetS57Registrar(),
                                                poClassContentExplorer,
                                                iClass, 
                                                poModule->GetOptionFlags() );

                if( poDefn != NULL )
                    AddLayer( new OGRS57Layer( this, poDefn, 
                                               anClassCount[iClass] ) );
                else
                {
                    bGeneric = TRUE;
                    CPLDebug( "S57", 
                              "Unable to find definition for OBJL=%d\n", 
                              iClass );
                }
            }
        }

        if( bGeneric )
        {
            poDefn = S57GenerateGeomFeatureDefn( wkbUnknown, 
                                                 poModule->GetOptionFlags() );
            AddLayer( new OGRS57Layer( this, poDefn ) );
        }
    }

/* -------------------------------------------------------------------- */
/*      Attach the layer definitions to each of the readers.            */
/* -------------------------------------------------------------------- */
    for( iModule = 0; iModule < nModules; iModule++ )
    {
        for( int iLayer = 0; iLayer < nLayers; iLayer++ )
        {
            papoModules[iModule]->AddFeatureDefn(
                papoLayers[iLayer]->GetLayerDefn() );
        }
    }

    return bSuccess;
}
Esempio n. 4
0
int SDTSTransfer::Open( const char * pszFilename )

{
/* -------------------------------------------------------------------- */
/*      Open the catalog.                                               */
/* -------------------------------------------------------------------- */
    if( !oCATD.Read( pszFilename ) )
        return FALSE;

    
/* -------------------------------------------------------------------- */
/*      Read the IREF file.                                             */
/* -------------------------------------------------------------------- */
    if( oCATD.GetModuleFilePath( "IREF" ) == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Can't find IREF module in transfer `%s'.\n",
                  pszFilename );
        return FALSE;
    }
    
    if( !oIREF.Read( oCATD.GetModuleFilePath( "IREF" ) ) )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Read the XREF file.                                             */
/* -------------------------------------------------------------------- */
    if( oCATD.GetModuleFilePath( "XREF" ) == NULL )
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Can't find XREF module in transfer `%s'.\n",
                  pszFilename );
    }
    else if( !oXREF.Read( oCATD.GetModuleFilePath( "XREF" ) ) )
    {
        CPLError( CE_Warning, CPLE_AppDefined,
              "Can't read XREF module, even though found in transfer `%s'.\n",
                  pszFilename );
    }

/* -------------------------------------------------------------------- */
/*      Build an index of layer types we recognise and care about.      */
/* -------------------------------------------------------------------- */
    int iCATDLayer;

    panLayerCATDEntry = (int *) CPLMalloc(sizeof(int) * oCATD.GetEntryCount());

    for( iCATDLayer = 0; iCATDLayer < oCATD.GetEntryCount(); iCATDLayer++ )
    {
        switch( oCATD.GetEntryType(iCATDLayer) )
        {
          case SLTPoint:
          case SLTLine:
          case SLTAttr:
          case SLTPoly:
          case SLTRaster:
            panLayerCATDEntry[nLayers++] = iCATDLayer;
            break;

          default:
            /* ignore */
            break;
        }
    }

/* -------------------------------------------------------------------- */
/*      Initialized the related indexed readers list.                   */
/* -------------------------------------------------------------------- */
    papoLayerReader = (SDTSIndexedReader **)
        CPLCalloc(sizeof(SDTSIndexedReader*),oCATD.GetEntryCount());

    return TRUE;
}
Esempio n. 5
0
GDALDataset *SGIDataset::Create( const char * pszFilename,
                                 int nXSize,
                                 int nYSize,
                                 int nBands,
                                 GDALDataType eType,
                                 CPL_UNUSED char **papszOptions )
{
    if( eType != GDT_Byte )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
              "Attempt to create SGI dataset with an illegal\n"
              "data type (%s), only Byte supported by the format.\n",
              GDALGetDataTypeName(eType) );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Open the file for output.                                       */
/* -------------------------------------------------------------------- */
    VSILFILE *fp = VSIFOpenL( pszFilename, "w" );
    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to create file '%s': %s",
                  pszFilename, VSIStrerror( errno ) );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Prepare and write 512 byte header.                              */
/* -------------------------------------------------------------------- */
    GByte abyHeader[512];

    memset( abyHeader, 0, 512 );

    abyHeader[0] = 1;
    abyHeader[1] = 218;
    abyHeader[2] = 1; // RLE
    abyHeader[3] = 1;  // 8bit

    GInt16 nShortValue;
    if( nBands == 1 )
        nShortValue = CPL_MSBWORD16(2);
    else
        nShortValue = CPL_MSBWORD16(3);
    memcpy( abyHeader + 4, &nShortValue, 2 );

    nShortValue = CPL_MSBWORD16(nXSize);
    memcpy( abyHeader + 6, &nShortValue, 2 );

    nShortValue = CPL_MSBWORD16(nYSize);
    memcpy( abyHeader + 8, &nShortValue, 2 );

    nShortValue = CPL_MSBWORD16(nBands);
    memcpy( abyHeader + 10, &nShortValue, 2 );

    GInt32 nIntValue = CPL_MSBWORD32(0);
    memcpy( abyHeader + 12, &nIntValue, 4 );

    GUInt32 nUIntValue = CPL_MSBWORD32(255);
    memcpy( abyHeader + 16, &nUIntValue, 4 );

    VSIFWriteL( abyHeader, 1, 512, fp );

/* -------------------------------------------------------------------- */
/*      Create our RLE compressed zero-ed dummy line.                   */
/* -------------------------------------------------------------------- */
    GByte *pabyRLELine = reinterpret_cast<GByte *>(
        CPLMalloc( ( nXSize / 127 ) * 2 + 4 ) );

    int nPixelsRemaining = nXSize;
    GInt32 nRLEBytes = 0;
    while( nPixelsRemaining > 0 )
    {
        pabyRLELine[nRLEBytes] = static_cast<GByte>(
            std::min( 127, nPixelsRemaining  ) );
        pabyRLELine[nRLEBytes+1] = 0;
        nPixelsRemaining -= pabyRLELine[nRLEBytes];

        nRLEBytes += 2;
    }

/* -------------------------------------------------------------------- */
/*      Prepare and write RLE offset/size tables with everything        */
/*      zeroed indicating dummy lines.                                  */
/* -------------------------------------------------------------------- */
    const int nTableLen = nYSize * nBands;
    GInt32 nDummyRLEOffset = 512 + 4 * nTableLen * 2;

    CPL_MSBPTR32( &nRLEBytes );
    CPL_MSBPTR32( &nDummyRLEOffset );

    for( int i = 0; i < nTableLen; i++ )
        VSIFWriteL( &nDummyRLEOffset, 1, 4, fp );

    for( int i = 0; i < nTableLen; i++ )
        VSIFWriteL( &nRLEBytes, 1, 4, fp );

/* -------------------------------------------------------------------- */
/*      write the dummy RLE blank line.                                 */
/* -------------------------------------------------------------------- */
    CPL_MSBPTR32( &nRLEBytes );
    if( static_cast<GInt32>( VSIFWriteL( pabyRLELine, 1, nRLEBytes, fp ) )
        != nRLEBytes )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Failure writing SGI file '%s'.\n%s",
                  pszFilename,
                  VSIStrerror( errno ) );
        return NULL;
    }

    VSIFCloseL( fp );
    CPLFree( pabyRLELine );

    return reinterpret_cast<GDALDataset *>(
        GDALOpen( pszFilename, GA_Update ) );
}
Esempio n. 6
0
GDALDataset * SRTMHGTDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
                                          int bStrict, char ** papszOptions, 
                                          GDALProgressFunc pfnProgress, void * pProgressData )

{
    int  nBands = poSrcDS->GetRasterCount();
    int  nXSize = poSrcDS->GetRasterXSize();
    int  nYSize = poSrcDS->GetRasterYSize();

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

/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "SRTMHGT driver does not support source dataset with zero band.\n");
        return NULL;
    }
    else if (nBands != 1)
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
                  "SRTMHGT driver only uses the first band of the dataset.\n");
        if (bStrict)
            return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Checks the input SRS                                            */
/* -------------------------------------------------------------------- */
    OGRSpatialReference ogrsr_input;
    OGRSpatialReference ogrsr_wgs84;
    char* c = (char*)poSrcDS->GetProjectionRef();
    ogrsr_input.importFromWkt(&c);
    ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" );
    if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE)
    {
        CPLError( CE_Warning, CPLE_AppDefined, 
                  "The source projection coordinate system is %s. Only WGS 84 is supported.\n"
                  "The SRTMHGT driver will generate a file as if the source was WGS 84 projection coordinate system.",
                  poSrcDS->GetProjectionRef() );
    }

/* -------------------------------------------------------------------- */
/*      Work out the LL origin.                                         */
/* -------------------------------------------------------------------- */
    int  nLLOriginLat, nLLOriginLong;
    double adfGeoTransform[6];

    if (poSrcDS->GetGeoTransform( adfGeoTransform ) != CE_None)
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Source image must have a geo transform matrix.");
        return NULL;
    }

    nLLOriginLat = (int) 
        floor(adfGeoTransform[3] 
              + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5);

    nLLOriginLong = (int) floor(adfGeoTransform[0] + 0.5);

    if (fabs(nLLOriginLat - (adfGeoTransform[3] 
              + (poSrcDS->GetRasterYSize() - 0.5) * adfGeoTransform[5])) > 1e-10 ||
        fabs(nLLOriginLong - (adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10)
    {
        CPLError( CE_Warning, CPLE_AppDefined, 
               "The corner coordinates of the source are not properly "
               "aligned on plain latitude/longitude boundaries.");
    }

/* -------------------------------------------------------------------- */
/*      Check image dimensions.                                         */
/* -------------------------------------------------------------------- */
    if (!((nXSize == 1201 && nYSize == 1201) || (nXSize == 3601 && nYSize == 3601)))
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Image dimensions should be 1201x1201 or 3601x3601.");
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Check filename.                                                 */
/* -------------------------------------------------------------------- */
    char expectedFileName[12];
    snprintf(expectedFileName, sizeof(expectedFileName), "%c%02d%c%03d.HGT",
             (nLLOriginLat >= 0) ? 'N' : 'S',
             (nLLOriginLat >= 0) ? nLLOriginLat : -nLLOriginLat,
             (nLLOriginLong >= 0) ? 'E' : 'W',
             (nLLOriginLong >= 0) ? nLLOriginLong : -nLLOriginLong);
    if (!EQUAL(expectedFileName, CPLGetFilename(pszFilename)))
    {
        CPLError( CE_Warning, CPLE_AppDefined, 
                  "Expected output filename is %s.", expectedFileName);
    }

/* -------------------------------------------------------------------- */
/*      Write output file.                                              */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(pszFilename, "wb");
    if (fp == NULL)
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Cannot create file %s", pszFilename );
        return NULL;
    }

    GInt16* panData = (GInt16*) CPLMalloc(sizeof(GInt16) * nXSize);
    GDALRasterBand* poSrcBand = poSrcDS->GetRasterBand(1);

    int bSrcBandHasNoData;
    double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData);

    for( int iY = 0; iY < nYSize; iY++ )
    {
        poSrcBand->RasterIO( GF_Read, 0, iY, nXSize, 1,
                            (void *) panData, nXSize, 1,
                            GDT_Int16, 0, 0 );

        /* Translate nodata values */
        if (bSrcBandHasNoData && srcBandNoData != SRTMHG_NODATA_VALUE)
        {
            for( int iX = 0; iX < nXSize; iX++ )
            {
                if (panData[iX] == srcBandNoData)
                    panData[iX] = SRTMHG_NODATA_VALUE;
            }
        }

#ifdef CPL_LSB
        GDALSwapWords(panData, 2, nXSize, 2);
#endif

        if( VSIFWriteL( panData,sizeof(GInt16) * nXSize,1,fp ) != 1)
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Failed to write line %d in SRTMHGT dataset.\n",
                      iY );
            VSIFCloseL(fp);
            CPLFree( panData );
            return NULL;
        }

        if( pfnProgress && !pfnProgress((iY+1) / (double) nYSize, NULL, pProgressData ) )
        {
            CPLError( CE_Failure, CPLE_UserInterrupt, 
                        "User terminated CreateCopy()" );
            VSIFCloseL(fp);
            CPLFree( panData );
            return NULL;
        }
    }

    CPLFree( panData );
    VSIFCloseL(fp);

/* -------------------------------------------------------------------- */
/*      Reopen and copy missing information into a PAM file.            */
/* -------------------------------------------------------------------- */
    GDALPamDataset *poDS = (GDALPamDataset *) 
        GDALOpen( pszFilename, GA_ReadOnly );

    if( poDS )
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT);

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

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

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

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

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

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

    VSILFILE* fp = VSIFOpenL(pszFilename, "wb");
    if (fp == NULL)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Cannot create %s", pszFilename );
        return NULL;
    }

    int nFieldSize = 20;
    int nValuesPerLine = 4;
    int nDecimalCount = 7;

    int bHasNoDataValue = FALSE;
    double dfNoDataValue =
        poSrcDS->GetRasterBand(1)->GetNoDataValue(&bHasNoDataValue);
    if (!bHasNoDataValue)
        dfNoDataValue = 1.e30;

    VSIFPrintfL(fp, "!\n");
    VSIFPrintfL(fp, "! Created by GDAL.\n");
    VSIFPrintfL(fp, "!\n");
    VSIFPrintfL(fp, "@GRID FILE, GRID, %d\n", nValuesPerLine);

    WriteRightJustified(fp, nFieldSize, 10);
    VSIFPrintfL(fp, ",");
    WriteRightJustified(fp, dfNoDataValue, 10);
    VSIFPrintfL(fp, ",");
    WriteRightJustified(fp, "", 10);
    VSIFPrintfL(fp, ",");
    WriteRightJustified(fp, nDecimalCount, 10);
    VSIFPrintfL(fp, ",");
    WriteRightJustified(fp, 1, 10);
    VSIFPrintfL(fp, "\n");

    WriteRightJustified(fp, nYSize, 10);
    VSIFPrintfL(fp, ",");
    WriteRightJustified(fp, nXSize, 10);
    VSIFPrintfL(fp, ",");

    if (CSLTestBoolean(CPLGetConfigOption("ZMAP_PIXEL_IS_POINT", "FALSE")))
    {
        WriteRightJustified(fp, adfGeoTransform[0] + adfGeoTransform[1] / 2, 14, 7);
        VSIFPrintfL(fp, ",");
        WriteRightJustified(fp, adfGeoTransform[0] + adfGeoTransform[1] * nXSize -
                                adfGeoTransform[1] / 2, 14, 7);
        VSIFPrintfL(fp, ",");
        WriteRightJustified(fp, adfGeoTransform[3] + adfGeoTransform[5] * nYSize -
                                adfGeoTransform[5] / 2, 14, 7);
        VSIFPrintfL(fp, ",");
        WriteRightJustified(fp, adfGeoTransform[3] + adfGeoTransform[5] / 2, 14, 7);
    }
    else
    {
        WriteRightJustified(fp, adfGeoTransform[0], 14, 7);
        VSIFPrintfL(fp, ",");
        WriteRightJustified(fp, adfGeoTransform[0] + adfGeoTransform[1] * nXSize, 14, 7);
        VSIFPrintfL(fp, ",");
        WriteRightJustified(fp, adfGeoTransform[3] + adfGeoTransform[5] * nYSize, 14, 7);
        VSIFPrintfL(fp, ",");
        WriteRightJustified(fp, adfGeoTransform[3], 14, 7);
    }

    VSIFPrintfL(fp, "\n");

    VSIFPrintfL(fp, "0.0, 0.0, 0.0\n");
    VSIFPrintfL(fp, "@\n");

/* -------------------------------------------------------------------- */
/*      Copy imagery                                                    */
/* -------------------------------------------------------------------- */
    double* padfLineBuffer = (double*) CPLMalloc(nYSize * sizeof(double));
    int i, j;
    CPLErr eErr = CE_None;
    for(i=0;i<nXSize && eErr == CE_None;i++)
    {
        eErr = poSrcDS->GetRasterBand(1)->RasterIO(
                                            GF_Read, i, 0, 1, nYSize,
                                            padfLineBuffer, 1, nYSize,
                                            GDT_Float64, 0, 0);
        if (eErr != CE_None)
            break;
        int bEOLPrinted = FALSE;
        for(j=0;j<nYSize;j++)
        {
            WriteRightJustified(fp, padfLineBuffer[j], nFieldSize, nDecimalCount);
            if (((j + 1) % nValuesPerLine) == 0)
            {
                bEOLPrinted = TRUE;
                VSIFPrintfL(fp, "\n");
            }
            else
                bEOLPrinted = FALSE;
        }
        if (!bEOLPrinted)
            VSIFPrintfL(fp, "\n");

        if (!pfnProgress( (j+1) * 1.0 / nYSize, NULL, pProgressData))
        {
            eErr = CE_Failure;
            break;
        }
    }
    CPLFree(padfLineBuffer);
    VSIFCloseL(fp);

    if (eErr != CE_None)
        return NULL;

    return (GDALDataset*) GDALOpen(pszFilename, GA_ReadOnly);
}
Esempio n. 8
0
static void CorrectURLs( CPLXMLNode * psRoot, const char *pszURL )

{
    if( psRoot == NULL || pszURL == NULL )
        return;
    if( pszURL[0] == '\0' )
        return;

    CPLXMLNode *psChild = psRoot->psChild;

// check for xlink:href attribute
    while( psChild != NULL && !( ( psChild->eType == CXT_Attribute ) &&
                                 ( EQUAL(psChild->pszValue, "xlink:href") )) )
        psChild = psChild->psNext;

    if( psChild != NULL &&
        !( strstr( psChild->psChild->pszValue, pszURL ) == psChild->psChild->pszValue
        && psChild->psChild->pszValue[strlen(pszURL)] == '#' ) )
    {
        // href has a different url.
        if( psChild->psChild->pszValue[0] == '#' )
        {
        //empty URL: prepend the given URL
            const size_t nLen =
                CPLStrnlen( pszURL, 1024 ) +
                CPLStrnlen( psChild->psChild->pszValue, 1024 ) + 1;
            char *pszNew = (char *)CPLMalloc( nLen * sizeof(char));
            CPLStrlcpy( pszNew, pszURL, nLen );
            CPLStrlcat( pszNew, psChild->psChild->pszValue, nLen );
            CPLSetXMLValue( psRoot, "#xlink:href", pszNew );
            CPLFree( pszNew );
        }
        else
        {
            size_t nPathLen  = strlen(pszURL);  // Used after for.
            for( ;
                 nPathLen > 0 &&
                 pszURL[nPathLen - 1] != '/' &&
                 pszURL[nPathLen - 1] != '\\';
                 nPathLen-- );

            const char* pszDash = strchr( psChild->psChild->pszValue, '#' );
            if( pszDash != NULL &&
                strncmp( pszURL, psChild->psChild->pszValue, nPathLen ) != 0 )
            {
            //different path
                int nURLLen = static_cast<int>(pszDash - psChild->psChild->pszValue);
                char *pszURLWithoutID = (char *)CPLMalloc( (nURLLen+1) * sizeof(char));
                strncpy( pszURLWithoutID, psChild->psChild->pszValue, nURLLen );
                pszURLWithoutID[nURLLen] = '\0';

                if( CPLIsFilenameRelative( pszURLWithoutID ) &&
                    strstr( pszURLWithoutID, ":" ) == NULL )
                {
                    //relative URL: prepend the path of pszURL
                    const size_t nLen =
                        nPathLen +
                        CPLStrnlen( psChild->psChild->pszValue, 1024 ) + 1;
                    char *pszNew = (char *)CPLMalloc( nLen * sizeof(char));
                    for( size_t i = 0; i < nPathLen; i++ )
                        pszNew[i] = pszURL[i];
                    pszNew[nPathLen] = '\0';
                    CPLStrlcat( pszNew, psChild->psChild->pszValue, nLen );
                    CPLSetXMLValue( psRoot, "#xlink:href", pszNew );
                    CPLFree( pszNew );
                }
                CPLFree( pszURLWithoutID );
            }
        }
    }

// search the child elements of psRoot
    for( psChild = psRoot->psChild; psChild != NULL; psChild = psChild->psNext)
        if( psChild->eType == CXT_Element )
            CorrectURLs( psChild, pszURL );
}
CPLErr GDALNoDataValuesMaskBand::IReadBlock( int nXBlockOff, int nYBlockOff,
                                         void * pImage )

{
    int iBand;
    GDALDataType eWrkDT;

/* -------------------------------------------------------------------- */
/*      Decide on a working type.                                       */
/* -------------------------------------------------------------------- */
    switch( poDS->GetRasterBand(1)->GetRasterDataType() )
    {
      case GDT_Byte:
        eWrkDT = GDT_Byte;
        break;

      case GDT_UInt16:
      case GDT_UInt32:
        eWrkDT = GDT_UInt32;
        break;

      case GDT_Int16:
      case GDT_Int32:
      case GDT_CInt16:
      case GDT_CInt32:
        eWrkDT = GDT_Int32;
        break;

      case GDT_Float32:
      case GDT_CFloat32:
        eWrkDT = GDT_Float32;
        break;

      case GDT_Float64:
      case GDT_CFloat64:
        eWrkDT = GDT_Float64;
        break;

      default:
        CPLAssert( FALSE );
        eWrkDT = GDT_Float64;
        break;
    }

/* -------------------------------------------------------------------- */
/*      Read the image data.                                            */
/* -------------------------------------------------------------------- */
    CPLErr eErr;

    int nBands = poDS->GetRasterCount();
    GByte *pabySrc = static_cast<GByte *>(
        VSI_MALLOC3_VERBOSE( nBands * GDALGetDataTypeSizeBytes(eWrkDT),
                             nBlockXSize, nBlockYSize ) );
    if (pabySrc == NULL)
    {
        return CE_Failure;
    }

    int nXSizeRequest = nBlockXSize;
    if (nXBlockOff * nBlockXSize + nBlockXSize > nRasterXSize)
        nXSizeRequest = nRasterXSize - nXBlockOff * nBlockXSize;
    int nYSizeRequest = nBlockYSize;
    if (nYBlockOff * nBlockYSize + nBlockYSize > nRasterYSize)
        nYSizeRequest = nRasterYSize - nYBlockOff * nBlockYSize;

    if (nXSizeRequest != nBlockXSize || nYSizeRequest != nBlockYSize)
    {
        /* memset the whole buffer to avoid Valgrind warnings in case we can't */
        /* fetch a full block */
        memset( pabySrc, 0,
                nBands * GDALGetDataTypeSizeBytes(eWrkDT) *
                nBlockXSize * nBlockYSize );
    }

    int nBlockOffsetPixels = nBlockXSize * nBlockYSize;
    const int nBandOffsetByte =
        GDALGetDataTypeSizeBytes(eWrkDT) * nBlockXSize * nBlockYSize;
    for(iBand=0;iBand<nBands;iBand++)
    {
        eErr = poDS->GetRasterBand(iBand + 1)->RasterIO(
            GF_Read,
            nXBlockOff * nBlockXSize,
            nYBlockOff * nBlockYSize,
            nXSizeRequest,
            nYSizeRequest,
            pabySrc + iBand * nBandOffsetByte,
            nXSizeRequest,
            nYSizeRequest,
            eWrkDT, 0,
            nBlockXSize * GDALGetDataTypeSizeBytes(eWrkDT),
            NULL );
        if( eErr != CE_None )
            return eErr;
    }

/* -------------------------------------------------------------------- */
/*      Process different cases.                                        */
/* -------------------------------------------------------------------- */
    int i;
    switch( eWrkDT )
    {
      case GDT_Byte:
      {
          GByte* pabyNoData = (GByte*) CPLMalloc(nBands * sizeof(GByte));
          for(iBand=0;iBand<nBands;iBand++)
          {
              pabyNoData[iBand] = (GByte)padfNodataValues[iBand];
          }

          for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
          {
              int nCountNoData = 0;
              for(iBand=0;iBand<nBands;iBand++)
              {
                  if( pabySrc[i + iBand * nBlockOffsetPixels] == pabyNoData[iBand] )
                      nCountNoData ++;
              }
              if (nCountNoData == nBands)
                  ((GByte *) pImage)[i] = 0;
              else
                  ((GByte *) pImage)[i] = 255;
          }

          CPLFree(pabyNoData);
      }
      break;

      case GDT_UInt32:
      {
          GUInt32* panNoData = (GUInt32*) CPLMalloc(nBands * sizeof(GUInt32));
          for(iBand=0;iBand<nBands;iBand++)
          {
              panNoData[iBand] = (GUInt32)padfNodataValues[iBand];
          }

          for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
          {
              int nCountNoData = 0;
              for(iBand=0;iBand<nBands;iBand++)
              {
                  if( ((GUInt32 *)pabySrc)[i + iBand * nBlockOffsetPixels] == panNoData[iBand] )
                      nCountNoData ++;
              }
              if (nCountNoData == nBands)
                  ((GByte *) pImage)[i] = 0;
              else
                  ((GByte *) pImage)[i] = 255;
          }

          CPLFree(panNoData);
      }
      break;

      case GDT_Int32:
      {
          GInt32* panNoData = (GInt32*) CPLMalloc(nBands * sizeof(GInt32));
          for(iBand=0;iBand<nBands;iBand++)
          {
              panNoData[iBand] = (GInt32)padfNodataValues[iBand];
          }

          for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
          {
              int nCountNoData = 0;
              for(iBand=0;iBand<nBands;iBand++)
              {
                  if( ((GInt32 *)pabySrc)[i + iBand * nBlockOffsetPixels] == panNoData[iBand] )
                      nCountNoData ++;
              }
              if (nCountNoData == nBands)
                  ((GByte *) pImage)[i] = 0;
              else
                  ((GByte *) pImage)[i] = 255;
          }

          CPLFree(panNoData);
      }
      break;

      case GDT_Float32:
      {
          float* pafNoData = (float*) CPLMalloc(nBands * sizeof(float));
          for(iBand=0;iBand<nBands;iBand++)
          {
              pafNoData[iBand] = (float)padfNodataValues[iBand];
          }

          for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
          {
              int nCountNoData = 0;
              for(iBand=0;iBand<nBands;iBand++)
              {
                  if( ((float *)pabySrc)[i + iBand * nBlockOffsetPixels] == pafNoData[iBand] )
                      nCountNoData ++;
              }
              if (nCountNoData == nBands)
                  ((GByte *) pImage)[i] = 0;
              else
                  ((GByte *) pImage)[i] = 255;
          }

          CPLFree(pafNoData);
      }
      break;

      case GDT_Float64:
      {
          double* padfNoData = (double*) CPLMalloc(nBands * sizeof(double));
          for(iBand=0;iBand<nBands;iBand++)
          {
              padfNoData[iBand] = (double)padfNodataValues[iBand];
          }

          for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
          {
              int nCountNoData = 0;
              for(iBand=0;iBand<nBands;iBand++)
              {
                  if( ((double *)pabySrc)[i + iBand * nBlockOffsetPixels] == padfNoData[iBand] )
                      nCountNoData ++;
              }
              if (nCountNoData == nBands)
                  ((GByte *) pImage)[i] = 0;
              else
                  ((GByte *) pImage)[i] = 255;
          }

          CPLFree(padfNoData);
      }
      break;

      default:
        CPLAssert( FALSE );
        break;
    }

    CPLFree( pabySrc );

    return CE_None;
}
Esempio n. 10
0
int OGRODBCDataSource::OpenMDB( const char * pszNewName, int bUpdate )
{
    const char* pszOptionName = "";
    pszOptionName = "PGEO_DRIVER_TEMPLATE";
    const char* pszDSNStringTemplate = CPLGetConfigOption( pszOptionName, NULL );
    if( pszDSNStringTemplate == NULL )
    {
        pszOptionName = "MDB_DRIVER_TEMPLATE";
        pszDSNStringTemplate = CPLGetConfigOption( pszOptionName, NULL );
        if( pszDSNStringTemplate == NULL )
        {
            pszOptionName = "";
            pszDSNStringTemplate = "DRIVER=Microsoft Access Driver (*.mdb);DBQ=%s";
        }
    }
    if (!CheckDSNStringTemplate(pszDSNStringTemplate))
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                    "Illegal value for %s option", pszOptionName );
        return FALSE;
    }
    char* pszDSN = (char *) CPLMalloc(strlen(pszNewName)+strlen(pszDSNStringTemplate)+100);
    sprintf( pszDSN, pszDSNStringTemplate,  pszNewName );

/* -------------------------------------------------------------------- */
/*      Initialize based on the DSN.                                    */
/* -------------------------------------------------------------------- */
    CPLDebug( "ODBC", "EstablishSession(%s)", pszDSN );

    if( !oSession.EstablishSession( pszDSN, NULL, NULL ) )
    {
        int bError = TRUE;
        if( EQUAL(pszDSN, "") )
        {
            // Trying with another template (#5594)
            pszDSNStringTemplate = "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s";
            CPLFree( pszDSN );
            pszDSN = (char *) CPLMalloc(strlen(pszNewName)+strlen(pszDSNStringTemplate)+100);
            sprintf( pszDSN, pszDSNStringTemplate,  pszNewName );
            CPLDebug( "ODBC", "EstablishSession(%s)", pszDSN );
            if( oSession.EstablishSession( pszDSN, NULL, NULL ) )
            {
                bError = FALSE;
            }
        }
        if( bError )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                    "Unable to initialize ODBC connection to DSN for %s,\n"
                    "%s", pszDSN, oSession.GetLastError() );
            CPLFree( pszDSN );
            return FALSE;
        }
    }

    CPLFree( pszDSN );

    pszName = CPLStrdup( pszNewName );

    bDSUpdate = bUpdate;

/* -------------------------------------------------------------------- */
/*      Check if it is a PGeo MDB.                                      */
/* -------------------------------------------------------------------- */
    {
        CPLODBCStatement oStmt( &oSession );

        oStmt.Append( "SELECT TableName, FieldName, ShapeType, ExtentLeft, ExtentRight, ExtentBottom, ExtentTop, SRID, HasZ FROM GDB_GeomColumns" );

        if( oStmt.ExecuteSQL() )
        {
            return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Check if it is a Geomedia MDB.                                  */
/* -------------------------------------------------------------------- */
    {
        CPLODBCStatement oStmt( &oSession );

        oStmt.Append( "SELECT TableName FROM GAliasTable WHERE TableType = 'INGRFeatures'" );

        if( oStmt.ExecuteSQL() )
        {
            return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Check if it is a Walk MDB.                                      */
/* -------------------------------------------------------------------- */
    {
        CPLODBCStatement oStmt( &oSession );

        oStmt.Append( "SELECT LayerID, LayerName, minE, maxE, minN, maxN, Memo FROM WalkLayers" );

        if( oStmt.ExecuteSQL() )
        {
            return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Return all tables as  non-spatial tables.                       */
/* -------------------------------------------------------------------- */
    CPLODBCStatement oTableList( &oSession );

    if( oTableList.GetTables() )
    {
        while( oTableList.Fetch() )
        {
            const char *pszSchema = oTableList.GetColData(1);
            CPLString osLayerName;

            if( pszSchema != NULL && strlen(pszSchema) > 0 )
            {
                osLayerName = pszSchema;
                osLayerName += ".";
            }

            osLayerName += oTableList.GetColData(2);

            OpenTable( osLayerName, NULL, bUpdate );
        }

        return TRUE;
    }
    else
        return FALSE;
}
Esempio n. 11
0
int OGRODBCDataSource::Open( const char * pszNewName, int bUpdate,
                             CPL_UNUSED int bTestOpen )
{
    CPLAssert( nLayers == 0 );

    if( !EQUALN(pszNewName, "ODBC:",5) && EQUAL(CPLGetExtension(pszNewName), "MDB") )
        return OpenMDB(pszNewName, bUpdate);

/* -------------------------------------------------------------------- */
/*      Start parsing dataset name from the end of string, fetching     */
/*      the name of spatial reference table and names for SRID and      */
/*      SRTEXT columns first.                                           */
/* -------------------------------------------------------------------- */
    char *pszWrkName = CPLStrdup( pszNewName + 5 ); // Skip the 'ODBC:' part
    char **papszTables = NULL;
    char **papszGeomCol = NULL;
    char *pszSRSTableName = NULL;
    char *pszSRIDCol = NULL, *pszSRTextCol = NULL;
    char *pszDelimiter;

    if ( (pszDelimiter = strrchr( pszWrkName, ':' )) != NULL )
    {
        char *pszOBracket = strchr( pszDelimiter + 1, '(' );

        if( strchr(pszDelimiter,'\\') != NULL
            || strchr(pszDelimiter,'/') != NULL )
        {
            /*
            ** if there are special tokens then this isn't really
            ** the srs table name, so avoid further processing.
            */
        }
        else if( pszOBracket == NULL )
        {
            pszSRSTableName = CPLStrdup( pszDelimiter + 1 );
            *pszDelimiter = '\0';
        }
        else
        {
            char *pszCBracket = strchr( pszOBracket, ')' );
            if( pszCBracket != NULL )
                *pszCBracket = '\0';

            char *pszComma = strchr( pszOBracket, ',' );
            if( pszComma != NULL )
            {
                *pszComma = '\0';
                pszSRIDCol = CPLStrdup( pszComma + 1 );
            }
            
            *pszOBracket = '\0';
            pszSRSTableName = CPLStrdup( pszDelimiter + 1 );
            pszSRTextCol = CPLStrdup( pszOBracket + 1 );

            *pszDelimiter = '\0';
        }
    }

/* -------------------------------------------------------------------- */
/*      Strip off any comma delimeted set of tables names to access     */
/*      from the end of the string first.  Also allow an optional       */
/*      bracketed geometry column name after the table name.            */
/* -------------------------------------------------------------------- */
    while( (pszDelimiter = strrchr( pszWrkName, ',' )) != NULL )
    {
        char *pszOBracket = strstr( pszDelimiter + 1, "(" );
        if( pszOBracket == NULL )
        {
            papszTables = CSLAddString( papszTables, pszDelimiter + 1 );
            papszGeomCol = CSLAddString( papszGeomCol, "" );
        }
        else
        {
            char *pszCBracket = strstr(pszOBracket,")");
            
            if( pszCBracket != NULL )
                *pszCBracket = '\0';
            
            *pszOBracket = '\0';
            papszTables = CSLAddString( papszTables, pszDelimiter + 1 );
            papszGeomCol = CSLAddString( papszGeomCol, pszOBracket+1 );
        }
        *pszDelimiter = '\0';
    }

/* -------------------------------------------------------------------- */
/*      Split out userid, password and DSN.  The general form is        */
/*      user/password@dsn.  But if there are no @ characters the        */
/*      whole thing is assumed to be a DSN.                             */
/* -------------------------------------------------------------------- */
    char *pszUserid = NULL;
    char *pszPassword = NULL;
    char *pszDSN = NULL;

    if( strstr(pszWrkName,"@") == NULL )
    {
        pszDSN = CPLStrdup( pszWrkName );
    }
    else
    {
        char *pszTarget;

        pszDSN = CPLStrdup(strstr(pszWrkName, "@") + 1);
        if( *pszWrkName == '/' )
        {
            pszPassword = CPLStrdup(pszWrkName + 1);
            pszTarget = strstr(pszPassword,"@");
            *pszTarget = '\0';
        }
        else
        {
            pszUserid = CPLStrdup(pszWrkName);
            pszTarget = strstr(pszUserid,"@");
            *pszTarget = '\0';

            pszTarget = strstr(pszUserid,"/");
            if( pszTarget != NULL )
            {
                *pszTarget = '\0';
                pszPassword = CPLStrdup(pszTarget+1);
            }
        }
    }

    CPLFree( pszWrkName );

/* -------------------------------------------------------------------- */
/*      Initialize based on the DSN.                                    */
/* -------------------------------------------------------------------- */
    CPLDebug( "OGR_ODBC",
              "EstablishSession(DSN:\"%s\", userid:\"%s\", password:\"%s\")", 
              pszDSN, pszUserid ? pszUserid : "",
              pszPassword ? pszPassword : "" );

    if( !oSession.EstablishSession( pszDSN, pszUserid, pszPassword ) )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Unable to initialize ODBC connection to DSN for %s,\n"
                  "%s", 
                  pszNewName+5, oSession.GetLastError() );
        CSLDestroy( papszTables );
        CSLDestroy( papszGeomCol );
        CPLFree( pszDSN );
        CPLFree( pszUserid );
        CPLFree( pszPassword );
        return FALSE;
    }

    CPLFree( pszDSN );
    CPLFree( pszUserid );
    CPLFree( pszPassword );

    pszName = CPLStrdup( pszNewName );
    
    bDSUpdate = bUpdate;

/* -------------------------------------------------------------------- */
/*      If no explicit list of tables was given, check for a list in    */
/*      a geometry_columns table.                                       */
/* -------------------------------------------------------------------- */
    if( papszTables == NULL )
    {
        CPLODBCStatement oStmt( &oSession );
        
        oStmt.Append( "SELECT f_table_name, f_geometry_column, geometry_type"
                      " FROM geometry_columns" );
        if( oStmt.ExecuteSQL() )
        {
            while( oStmt.Fetch() )
            {
                papszTables = 
                    CSLAddString( papszTables, oStmt.GetColData(0) );
                papszGeomCol = 
                    CSLAddString( papszGeomCol, oStmt.GetColData(1) );
            }
        }
    }
            
/* -------------------------------------------------------------------- */
/*      Otherwise our final resort is to return all tables as           */
/*      non-spatial tables.                                             */
/* -------------------------------------------------------------------- */
    if( papszTables == NULL )
    {
        CPLODBCStatement oTableList( &oSession );
        
        if( oTableList.GetTables() )
        {
            while( oTableList.Fetch() )
            {
                const char *pszSchema = oTableList.GetColData(1);
                CPLString osLayerName;

                if( pszSchema != NULL && strlen(pszSchema) > 0 )
                {
                    osLayerName = pszSchema;
                    osLayerName += ".";
                }

                osLayerName += oTableList.GetColData(2);

                papszTables = CSLAddString( papszTables, osLayerName );

                papszGeomCol = CSLAddString(papszGeomCol,"");
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      If we have an explicit list of requested tables, use them       */
/*      (non-spatial).                                                  */
/* -------------------------------------------------------------------- */
    for( int iTable = 0; 
         papszTables != NULL && papszTables[iTable] != NULL; 
         iTable++ )
    {
        if( strlen(papszGeomCol[iTable]) > 0 )
            OpenTable( papszTables[iTable], papszGeomCol[iTable], bUpdate );
        else
            OpenTable( papszTables[iTable], NULL, bUpdate );
    }

    CSLDestroy( papszTables );
    CSLDestroy( papszGeomCol );

/* -------------------------------------------------------------------- */
/*      If no explicit list of tables was given, check for a list in    */
/*      a geometry_columns table.                                       */
/* -------------------------------------------------------------------- */
    if ( pszSRSTableName )
    {
        CPLODBCStatement oSRSList( &oSession );

        if ( !pszSRTextCol )
            pszSRTextCol = CPLStrdup( "srtext" );
        if ( !pszSRIDCol )
            pszSRIDCol = CPLStrdup( "srid" );

        oSRSList.Append( "SELECT " );
        oSRSList.Append( pszSRIDCol );
        oSRSList.Append( "," );
        oSRSList.Append( pszSRTextCol );
        oSRSList.Append( " FROM " );
        oSRSList.Append( pszSRSTableName );

        CPLDebug( "OGR_ODBC", "ExecuteSQL(%s) to read SRS table",
                  oSRSList.GetCommand() );
        if ( oSRSList.ExecuteSQL() )
        {
            int nRows = 256;     // A reasonable number of SRIDs to start from
            panSRID = (int *)CPLMalloc( nRows * sizeof(int) );
            papoSRS = (OGRSpatialReference **)
                CPLMalloc( nRows * sizeof(OGRSpatialReference*) );

            while ( oSRSList.Fetch() )
            {
                char *pszSRID = (char *) oSRSList.GetColData( pszSRIDCol );
                if ( !pszSRID )
                    continue;

                char *pszSRText = (char *) oSRSList.GetColData( pszSRTextCol );

                if ( pszSRText )
                {
                    if ( nKnownSRID > nRows )
                    {
                        nRows *= 2;
                        panSRID = (int *)CPLRealloc( panSRID,
                                                     nRows * sizeof(int) );
                        papoSRS = (OGRSpatialReference **)
                            CPLRealloc( papoSRS,
                            nRows * sizeof(OGRSpatialReference*) );
                    }
                    panSRID[nKnownSRID] = atoi( pszSRID );
                    papoSRS[nKnownSRID] = new OGRSpatialReference();
                    if ( papoSRS[nKnownSRID]->importFromWkt( &pszSRText )
                         != OGRERR_NONE )
                    {
                        delete papoSRS[nKnownSRID];
                        continue;
                    }
                    nKnownSRID++;
                }
            }
        }
    }

    if ( pszSRIDCol )
        CPLFree( pszSRIDCol );
    if ( pszSRTextCol )
        CPLFree( pszSRTextCol );
    if ( pszSRSTableName )
        CPLFree( pszSRSTableName );

    return TRUE;
}
Esempio n. 12
0
static void CSVIngest( const char *pszFilename )

{
    CSVTable *psTable = CSVAccess( pszFilename );
    int       nFileLen, i, nMaxLineCount, iLine = 0;
    char *pszThisLine;

    if( psTable->pszRawData != NULL )
        return;

/* -------------------------------------------------------------------- */
/*      Ingest whole file.                                              */
/* -------------------------------------------------------------------- */
    VSIFSeek( psTable->fp, 0, SEEK_END );
    nFileLen = VSIFTell( psTable->fp );
    VSIRewind( psTable->fp );

    psTable->pszRawData = (char *) CPLMalloc(nFileLen+1);
    if( (int) VSIFRead( psTable->pszRawData, 1, nFileLen, psTable->fp ) 
        != nFileLen )
    {
        CPLFree( psTable->pszRawData );
        psTable->pszRawData = NULL;

        CPLError( CE_Failure, CPLE_FileIO, "Read of file %s failed.", 
                  psTable->pszFilename );
        return;
    }

    psTable->pszRawData[nFileLen] = '\0';

/* -------------------------------------------------------------------- */
/*      Get count of newlines so we can allocate line array.            */
/* -------------------------------------------------------------------- */
    nMaxLineCount = 0;
    for( i = 0; i < nFileLen; i++ )
    {
        if( psTable->pszRawData[i] == 10 )
            nMaxLineCount++;
    }

    psTable->papszLines = (char **) CPLCalloc(sizeof(char*),nMaxLineCount);
    
/* -------------------------------------------------------------------- */
/*      Build a list of record pointers into the raw data buffer        */
/*      based on line terminators.  Zero terminate the line             */
/*      strings.                                                        */
/* -------------------------------------------------------------------- */
    /* skip header line */
    pszThisLine = CSVFindNextLine( psTable->pszRawData );

    while( pszThisLine != NULL && iLine < nMaxLineCount )
    {
        psTable->papszLines[iLine++] = pszThisLine;
        pszThisLine = CSVFindNextLine( pszThisLine );
    }

    psTable->nLineCount = iLine;

/* -------------------------------------------------------------------- */
/*      Allocate and populate index array.  Ensure they are in          */
/*      ascending order so that binary searches can be done on the      */
/*      array.                                                          */
/* -------------------------------------------------------------------- */
    psTable->panLineIndex = (int *) CPLMalloc(sizeof(int)*psTable->nLineCount);
    for( i = 0; i < psTable->nLineCount; i++ )
    {
        psTable->panLineIndex[i] = atoi(psTable->papszLines[i]);

        if( i > 0 && psTable->panLineIndex[i] < psTable->panLineIndex[i-1] )
        {
            CPLFree( psTable->panLineIndex );
            psTable->panLineIndex = NULL;
            break;
        }
    }

    psTable->iLastLine = -1;

/* -------------------------------------------------------------------- */
/*      We should never need the file handle against, so close it.      */
/* -------------------------------------------------------------------- */
    VSIFClose( psTable->fp );
    psTable->fp = NULL;
}
Esempio n. 13
0
OGRErr OGRIngresTableLayer::ICreateFeature( OGRFeature *poFeature )

{
    CPLString           osCommand;
    int                 i, bNeedComma = FALSE;

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

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

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

        osCommand = osCommand + osFIDColumn + " ";
        bNeedComma = TRUE;
    }

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

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

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

    osCommand += ") VALUES (";

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    osCommand += ")";

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

    oStmt.bDebug = FALSE;

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

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

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

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

    return OGRERR_NONE;
}
Esempio n. 14
0
OGRFeature *OGRIngresTableLayer::GetFeature( GIntBig nFeatureId )

{
    if( pszFIDColumn == NULL )
        return OGRIngresLayer::GetFeature( nFeatureId );

/* -------------------------------------------------------------------- */
/*      Discard any existing resultset.                                 */
/* -------------------------------------------------------------------- */
    ResetReading();

/* -------------------------------------------------------------------- */
/*      Prepare query command that will just fetch the one record of    */
/*      interest.                                                       */
/* -------------------------------------------------------------------- */
    char        *pszFieldList = BuildFields();
    char        *pszCommand = (char *) CPLMalloc(strlen(pszFieldList)+2000);

    sprintf( pszCommand,
             "SELECT %s FROM %s WHERE %s = %ld",
             pszFieldList, poFeatureDefn->GetName(), pszFIDColumn,
             nFeatureId );
    CPLFree( pszFieldList );

/* -------------------------------------------------------------------- */
/*      Issue the command.                                              */
/* -------------------------------------------------------------------- */
    if( ingres_query( poDS->GetConn(), pszCommand ) )
    {
        poDS->ReportError( pszCommand );
        return NULL;
    }
    CPLFree( pszCommand );

    hResultSet = ingres_store_result( poDS->GetConn() );
    if( hResultSet == NULL )
    {
        poDS->ReportError( "ingres_store_result() failed on query." );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Fetch the result record.                                        */
/* -------------------------------------------------------------------- */
    char **papszRow = ingres_fetch_row( hResultSet );
    if( papszRow == NULL )
        return NULL;

    unsigned long *panLengths = ingres_fetch_lengths( hResultSet );

/* -------------------------------------------------------------------- */
/*      Transform into a feature.                                       */
/* -------------------------------------------------------------------- */
    iNextShapeId = nFeatureId;

    OGRFeature *poFeature = RecordToFeature( papszRow, panLengths );

    iNextShapeId = 0;

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
    if( hResultSet != NULL )
        ingres_free_result( hResultSet );
    hResultSet = NULL;

    return poFeature;
}
Esempio n. 15
0
OGRLayer * OGRSQLiteExecuteSQL( GDALDataset* poDS,
                                const char *pszStatement,
                                OGRGeometry *poSpatialFilter,
                                CPL_UNUSED const char *pszDialect )
{
    char* pszTmpDBName = (char*) CPLMalloc(256);
    sprintf(pszTmpDBName, "/vsimem/ogr2sqlite/temp_%p.db", pszTmpDBName);

    OGRSQLiteDataSource* poSQLiteDS = NULL;
    int nRet;
    int bSpatialiteDB = FALSE;

    CPLString osOldVal;
    const char* pszOldVal = CPLGetConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", NULL);
    if( pszOldVal != NULL )
    {
        osOldVal = pszOldVal;
        pszOldVal = osOldVal.c_str();
    }

/* -------------------------------------------------------------------- */
/*      Create in-memory sqlite/spatialite DB                           */
/* -------------------------------------------------------------------- */

#ifdef HAVE_SPATIALITE

/* -------------------------------------------------------------------- */
/*      Creating an empty spatialite DB (with spatial_ref_sys populated */
/*      has a non-neglectable cost. So at the first attempt, let's make */
/*      one and cache it for later use.                                 */
/* -------------------------------------------------------------------- */
#if 1
    static vsi_l_offset nEmptyDBSize = 0;
    static GByte* pabyEmptyDB = NULL;
    {
        static CPLMutex* hMutex = NULL;
        CPLMutexHolder oMutexHolder(&hMutex);
        static int bTried = FALSE;
        if( !bTried &&
            CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) )
        {
            bTried = TRUE;
            char* pszCachedFilename = (char*) CPLMalloc(256);
            sprintf(pszCachedFilename, "/vsimem/ogr2sqlite/reference_%p.db",pszCachedFilename);
            char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES");
            OGRSQLiteDataSource* poCachedDS = new OGRSQLiteDataSource();
            nRet = poCachedDS->Create( pszCachedFilename, papszOptions );
            CSLDestroy(papszOptions);
            papszOptions = NULL;
            delete poCachedDS;
            if( nRet )
                /* Note: the reference file keeps the ownership of the data, so that */
                /* it gets released with VSICleanupFileManager() */
                pabyEmptyDB = VSIGetMemFileBuffer( pszCachedFilename, &nEmptyDBSize, FALSE );
            CPLFree( pszCachedFilename );
        }
    }

    /* The following configuration option is useful mostly for debugging/testing */
    if( pabyEmptyDB != NULL && CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) )
    {
        GByte* pabyEmptyDBClone = (GByte*)VSIMalloc(nEmptyDBSize);
        if( pabyEmptyDBClone == NULL )
        {
            CPLFree(pszTmpDBName);
            return NULL;
        }
        memcpy(pabyEmptyDBClone, pabyEmptyDB, nEmptyDBSize);
        VSIFCloseL(VSIFileFromMemBuffer( pszTmpDBName, pabyEmptyDBClone, nEmptyDBSize, TRUE ));

        poSQLiteDS = new OGRSQLiteDataSource();
        CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO");
        nRet = poSQLiteDS->Open( pszTmpDBName, TRUE, NULL );
        CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal);
        if( !nRet )
        {
            /* should not happen really ! */
            delete poSQLiteDS;
            VSIUnlink(pszTmpDBName);
            CPLFree(pszTmpDBName);
            return NULL;
        }
        bSpatialiteDB = TRUE;
    }
#else
    /* No caching version */
    poSQLiteDS = new OGRSQLiteDataSource();
    char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES");
    CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO");
    nRet = poSQLiteDS->Create( pszTmpDBName, papszOptions );
    CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal);
    CSLDestroy(papszOptions);
    papszOptions = NULL;
    if( nRet )
    {
        bSpatialiteDB = TRUE;
    }
#endif

    else
    {
        delete poSQLiteDS;
        poSQLiteDS = NULL;
#else // HAVE_SPATIALITE
    if( TRUE )
    {
#endif // HAVE_SPATIALITE
        poSQLiteDS = new OGRSQLiteDataSource();
        CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO");
        nRet = poSQLiteDS->Create( pszTmpDBName, NULL );
        CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal);
        if( !nRet )
        {
            delete poSQLiteDS;
            VSIUnlink(pszTmpDBName);
            CPLFree(pszTmpDBName);
            return NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Attach the Virtual Table OGR2SQLITE module to it.               */
/* -------------------------------------------------------------------- */
    OGR2SQLITEModule* poModule = OGR2SQLITE_Setup(poDS, poSQLiteDS);
    sqlite3* hDB = poSQLiteDS->GetDB();

/* -------------------------------------------------------------------- */
/*      Analysze the statement to determine which tables will be used.  */
/* -------------------------------------------------------------------- */
    std::set<LayerDesc> oSetLayers;
    std::set<CPLString> oSetSpatialIndex;
    CPLString osModifiedSQL;
    OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers,
                                     oSetSpatialIndex, osModifiedSQL);
    std::set<LayerDesc>::iterator oIter = oSetLayers.begin();

    if( strcmp(pszStatement, osModifiedSQL.c_str()) != 0 )
        CPLDebug("OGR", "Modified SQL: %s", osModifiedSQL.c_str());
    pszStatement = osModifiedSQL.c_str(); /* do not use it anymore */

    int bFoundOGRStyle = ( osModifiedSQL.ifind("OGR_STYLE") != std::string::npos );

/* -------------------------------------------------------------------- */
/*      For each of those tables, create a Virtual Table.               */
/* -------------------------------------------------------------------- */
    for(; oIter != oSetLayers.end(); ++oIter)
    {
        const LayerDesc& oLayerDesc = *oIter;
        /*CPLDebug("OGR", "Layer desc : %s, %s, %s, %s",
                 oLayerDesc.osOriginalStr.c_str(),
                 oLayerDesc.osSubstitutedName.c_str(),
                 oLayerDesc.osDSName.c_str(),
                 oLayerDesc.osLayerName.c_str());*/

        CPLString osSQL;
        OGRLayer* poLayer = NULL;
        CPLString osTableName;
        int nExtraDS;
        if( oLayerDesc.osDSName.size() == 0 )
        {
            poLayer = poDS->GetLayerByName(oLayerDesc.osLayerName);
            /* Might be a false positive (unlikely) */
            if( poLayer == NULL )
                continue;

            osTableName = oLayerDesc.osLayerName;

            nExtraDS = -1;
        }
        else
        {
            OGRDataSource* poOtherDS = (OGRDataSource* )
                OGROpen(oLayerDesc.osDSName, FALSE, NULL);
            if( poOtherDS == NULL )
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Cannot open datasource '%s'",
                         oLayerDesc.osDSName.c_str() );
                delete poSQLiteDS;
                VSIUnlink(pszTmpDBName);
                CPLFree(pszTmpDBName);
                return NULL;
            }
            
            poLayer = poOtherDS->GetLayerByName(oLayerDesc.osLayerName);
            if( poLayer == NULL )
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Cannot find layer '%s' in '%s'",
                         oLayerDesc.osLayerName.c_str(),
                         oLayerDesc.osDSName.c_str() );
                delete poOtherDS;
                delete poSQLiteDS;
                VSIUnlink(pszTmpDBName);
                CPLFree(pszTmpDBName);
                return NULL;
            }

            osTableName = oLayerDesc.osSubstitutedName;

            nExtraDS = OGR2SQLITE_AddExtraDS(poModule, poOtherDS);
        }

        osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR(%d,'%s',%d)",
                OGRSQLiteEscapeName(osTableName).c_str(),
                nExtraDS,
                OGRSQLiteEscape(oLayerDesc.osLayerName).c_str(),
                bFoundOGRStyle);

        char* pszErrMsg = NULL;
        int rc = sqlite3_exec( hDB, osSQL.c_str(),
                               NULL, NULL, &pszErrMsg );
        if( rc != SQLITE_OK )
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Cannot create virtual table for layer '%s' : %s",
                     osTableName.c_str(), pszErrMsg);
            sqlite3_free(pszErrMsg);
            continue;
        }

        for(int i=0; i<poLayer->GetLayerDefn()->GetGeomFieldCount(); i++)
        {
            OGR2SQLITEDealWithSpatialColumn(poLayer, i, oLayerDesc,
                                            osTableName, poSQLiteDS, hDB,
                                            bSpatialiteDB, oSetLayers,
                                            oSetSpatialIndex);
        }
    }

/* -------------------------------------------------------------------- */
/*      Reload, so that virtual tables are recognized                   */
/* -------------------------------------------------------------------- */
    poSQLiteDS->ReloadLayers();

/* -------------------------------------------------------------------- */
/*      Prepare the statement.                                          */
/* -------------------------------------------------------------------- */
    /* This will speed-up layer creation */
    /* ORDER BY are costly to evaluate and are not necessary to establish */
    /* the layer definition. */
    int bUseStatementForGetNextFeature = TRUE;
    int bEmptyLayer = FALSE;

    sqlite3_stmt *hSQLStmt = NULL;
    int rc = sqlite3_prepare( hDB,
                              pszStatement, strlen(pszStatement),
                              &hSQLStmt, NULL );

    if( rc != SQLITE_OK )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                "In ExecuteSQL(): sqlite3_prepare(%s):\n  %s",
                pszStatement, sqlite3_errmsg(hDB) );

        if( hSQLStmt != NULL )
        {
            sqlite3_finalize( hSQLStmt );
        }

        delete poSQLiteDS;
        VSIUnlink(pszTmpDBName);
        CPLFree(pszTmpDBName);

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Do we get a resultset?                                          */
/* -------------------------------------------------------------------- */
    rc = sqlite3_step( hSQLStmt );
    if( rc != SQLITE_ROW )
    {
        if ( rc != SQLITE_DONE )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                  "In ExecuteSQL(): sqlite3_step(%s):\n  %s",
                  pszStatement, sqlite3_errmsg(hDB) );

            sqlite3_finalize( hSQLStmt );

            delete poSQLiteDS;
            VSIUnlink(pszTmpDBName);
            CPLFree(pszTmpDBName);

            return NULL;
        }

        if( !EQUALN(pszStatement, "SELECT ", 7) )
        {

            sqlite3_finalize( hSQLStmt );

            delete poSQLiteDS;
            VSIUnlink(pszTmpDBName);
            CPLFree(pszTmpDBName);

            return NULL;
        }

        bUseStatementForGetNextFeature = FALSE;
        bEmptyLayer = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Create layer.                                                   */
/* -------------------------------------------------------------------- */
    OGRSQLiteSelectLayer *poLayer = NULL;

    poLayer = new OGRSQLiteExecuteSQLLayer( pszTmpDBName,
                                            poSQLiteDS, pszStatement, hSQLStmt,
                                            bUseStatementForGetNextFeature, bEmptyLayer );

    if( poSpatialFilter != NULL )
        poLayer->SetSpatialFilter( 0, poSpatialFilter );

    return poLayer;
}

/************************************************************************/
/*                   OGRSQLiteGetReferencedLayers()                     */
/************************************************************************/

std::set<LayerDesc> OGRSQLiteGetReferencedLayers(const char* pszStatement)
{
/* -------------------------------------------------------------------- */
/*      Analysze the statement to determine which tables will be used.  */
/* -------------------------------------------------------------------- */
    std::set<LayerDesc> oSetLayers;
    std::set<CPLString> oSetSpatialIndex;
    CPLString osModifiedSQL;
    OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers,
                                     oSetSpatialIndex, osModifiedSQL);

    return oSetLayers;
}
Esempio n. 16
0
int OGRGTMDataSource::Open(const char* pszFilename, int bUpdate)
{
    CPLAssert( pszFilename != NULL );
    
    /* Should not happen as the driver already returned if bUpdate == NULL */
    if (bUpdate)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "GTM driver does not support opening in update mode");
        return FALSE;
    }
    
/* -------------------------------------------------------------------- */
/*      Create a GTM object and open the source file.                   */
/* -------------------------------------------------------------------- */
    poGTMFile = new GTM();

    if ( !poGTMFile->Open( pszFilename ) )
    {
        delete poGTMFile;
        poGTMFile = NULL;
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Validate it by start parsing                                    */
/* -------------------------------------------------------------------- */
    if( !poGTMFile->isValid() )
    {
        delete poGTMFile;
        poGTMFile = NULL;
        return FALSE;
    }

    pszName = CPLStrdup( pszFilename );
/* -------------------------------------------------------------------- */
/*      Now, we are able to read the file header and find the position  */
/*        of the first waypoint and the position of the first track.      */
/* -------------------------------------------------------------------- */
    if ( !poGTMFile->readHeaderNumbers() )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      We can start reading the file elements                          */
/*      We are going to translate GTM features into layers              */
/* -------------------------------------------------------------------- */
    char* pszBaseFileName = CPLStrdup( CPLGetBasename(pszFilename) );
    /* We are going to create two layers, one for storing waypoints and
       another for storing tracks */
    papoLayers = (OGRGTMLayer **) CPLMalloc(sizeof(void*) * 2);
  

    /* Create a spatial reference for WGS8*/
    OGRSpatialReference* poSRS = new OGRSpatialReference(NULL);   
    poSRS->SetWellKnownGeogCS( "WGS84" );


    /* Waypoint layer */
    size_t layerNameSize = strlen(pszBaseFileName) + sizeof("_waypoints");
    char* pszLayerName = (char*) CPLMalloc(layerNameSize);
    /* The layer name will be "<basename>_waypoints" */
    strcpy (pszLayerName, pszBaseFileName);
    CPLStrlcat (pszLayerName, "_waypoints", layerNameSize);

    /* Store the layer of waypoints */

    GTMWaypointLayer* poWaypointLayer = new GTMWaypointLayer ( pszLayerName,
                                                               poSRS,
                                                               FALSE,
                                                               this );
    papoLayers[nLayers++] = poWaypointLayer;
    CPLFree(pszLayerName);

    /* Track layer */
    layerNameSize = strlen(pszBaseFileName) + sizeof("_tracks");
    pszLayerName = (char*) CPLMalloc(layerNameSize);
    /* The layer name will be "<basename>_tracks" */
    strcpy (pszLayerName, pszBaseFileName);
    CPLStrlcat (pszLayerName, "_tracks", layerNameSize);

    CPLFree(pszBaseFileName);
    /* Store the layer of tracks */
    GTMTrackLayer* poTrackLayer = new GTMTrackLayer ( pszLayerName,
                                                      poSRS,
                                                      FALSE,
                                                      this );
    papoLayers[nLayers++] = poTrackLayer;
    CPLFree(pszLayerName);

    poSRS->Release();
    return TRUE;

}
Esempio n. 17
0
GDALDataset* SRTMHGTDataset::Open(GDALOpenInfo* poOpenInfo)
{
  if (!Identify(poOpenInfo))
      return NULL;
  
  const char* fileName = CPLGetFilename(poOpenInfo->pszFilename);

  char latLonValueString[4];
  memset(latLonValueString, 0, 4);
  strncpy(latLonValueString, &fileName[1], 2);
  int southWestLat = atoi(latLonValueString);
  memset(latLonValueString, 0, 4);
  strncpy(latLonValueString, &fileName[4], 3);
  int southWestLon = atoi(latLonValueString);

  if(fileName[0] == 'N' || fileName[0] == 'n')
    /*southWestLat = southWestLat */;
  else if(fileName[0] == 'S' || fileName[0] == 's')
    southWestLat = southWestLat * -1;
  else
    return NULL;

  if(fileName[3] == 'E' || fileName[3] == 'e')
    /*southWestLon = southWestLon */;
  else if(fileName[3] == 'W' || fileName[3] == 'w')
    southWestLon = southWestLon * -1;
  else
    return NULL;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
  SRTMHGTDataset* poDS;

  poDS = new SRTMHGTDataset();

/* -------------------------------------------------------------------- */
/*      Open the file using the large file api.                         */
/* -------------------------------------------------------------------- */
  poDS->fpImage = VSIFOpenL(poOpenInfo->pszFilename, (poOpenInfo->eAccess == GA_Update) ? "rb+" : "rb");
  if(poDS->fpImage == NULL)
  {
    CPLError(CE_Failure, CPLE_OpenFailed, "VSIFOpenL(%s) failed unexpectedly in srtmhgtdataset.cpp", poOpenInfo->pszFilename);
    return NULL;
  }

  VSIStatBufL fileStat;
  if(VSIStatL(poOpenInfo->pszFilename, &fileStat) != 0)
  {
      return NULL;
  }
  int numPixels = (fileStat.st_size == 25934402) ? 3601 : /* 2884802 */ 1201;

  poDS->eAccess = poOpenInfo->eAccess;
#ifdef CPL_LSB
  if(poDS->eAccess == GA_Update)
  {
      poDS->panBuffer = (GInt16*) CPLMalloc(numPixels * sizeof(GInt16));
  }
#endif

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
  poDS->nRasterXSize = numPixels;
  poDS->nRasterYSize = numPixels;
  poDS->nBands = 1;

  poDS->adfGeoTransform[0] = southWestLon - 0.5 / (numPixels - 1);
  poDS->adfGeoTransform[1] = 1.0 / (numPixels-1);
  poDS->adfGeoTransform[2] = 0.0000000000;
  poDS->adfGeoTransform[3] = southWestLat + 1 + 0.5 / (numPixels - 1);
  poDS->adfGeoTransform[4] = 0.0000000000;
  poDS->adfGeoTransform[5] = -1.0 / (numPixels-1);

  poDS->SetMetadataItem( GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT );
  
/* -------------------------------------------------------------------- */
/*      Create band information object.                                 */
/* -------------------------------------------------------------------- */
  SRTMHGTRasterBand* tmpBand = new SRTMHGTRasterBand(poDS, 1);
  poDS->SetBand(1, tmpBand);

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

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

  return poDS;
}
Esempio n. 18
0
const char *CPLFormCIFilename( const char * pszPath,
                               const char * pszBasename,
                               const char * pszExtension )

{
#ifdef WIN32
    return CPLFormFilename( pszPath, pszBasename, pszExtension );
#else
    const char  *pszAddedExtSep = "";
    char        *pszFilename;
    const char  *pszFullPath;
    int         nLen = strlen(pszBasename)+2, i;
    FILE        *fp;

    if( pszExtension != NULL )
        nLen += strlen(pszExtension);

    pszFilename = (char *) CPLMalloc(nLen);

    if( pszExtension == NULL )
        pszExtension = "";
    else if( pszExtension[0] != '.' && strlen(pszExtension) > 0 )
        pszAddedExtSep = ".";

    sprintf( pszFilename, "%s%s%s",
             pszBasename, pszAddedExtSep, pszExtension );

    pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL );
    fp = VSIFOpen( pszFullPath, "r" );
    if( fp == NULL )
    {
        for( i = 0; pszFilename[i] != '\0'; i++ )
        {
            if( pszFilename[i] >= 'a' && pszFilename[i] <= 'z' )
                pszFilename[i] = pszFilename[i] + 'A' - 'a';
        }

        pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL );
        fp = VSIFOpen( pszFullPath, "r" );
    }

    if( fp == NULL )
    {
        for( i = 0; pszFilename[i] != '\0'; i++ )
        {
            if( pszFilename[i] >= 'A' && pszFilename[i] <= 'Z' )
                pszFilename[i] = pszFilename[i] + 'a' - 'A';
        }

        pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL );
        fp = VSIFOpen( pszFullPath, "r" );
    }

    if( fp != NULL )
        VSIFClose( fp );
    else
        pszFullPath = CPLFormFilename( pszPath, pszBasename, pszExtension );

    CPLFree( pszFilename );

    return pszFullPath;
#endif
}
Esempio n. 19
0
GDALDataset *GXFDataset::Open( GDALOpenInfo * poOpenInfo )

{
    GXFHandle	l_hGXF;
    int		i, bFoundKeyword, bFoundIllegal;

/* -------------------------------------------------------------------- */
/*      Before trying GXFOpen() we first verify that there is at        */
/*      least one "\n#keyword" type signature in the first chunk of     */
/*      the file.                                                       */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 50 )
        return NULL;

    bFoundKeyword = FALSE;
    bFoundIllegal = FALSE;
    for( i = 0; i < poOpenInfo->nHeaderBytes-1; i++ )
    {
        if( (poOpenInfo->pabyHeader[i] == 10
             || poOpenInfo->pabyHeader[i] == 13)
            && poOpenInfo->pabyHeader[i+1] == '#' )
        {
            if( STARTS_WITH((const char*)poOpenInfo->pabyHeader + i + 2, "include") )
                return NULL;
            if( STARTS_WITH((const char*)poOpenInfo->pabyHeader + i + 2, "define") )
                return NULL;
            if( STARTS_WITH((const char*)poOpenInfo->pabyHeader + i + 2, "ifdef") )
                return NULL;
            bFoundKeyword = TRUE;
        }
        if( poOpenInfo->pabyHeader[i] == 0 )
        {
            bFoundIllegal = TRUE;
            break;
        }
    }

    if( !bFoundKeyword || bFoundIllegal )
        return NULL;

/* -------------------------------------------------------------------- */
/*      At this point it is plausible that this is a GXF file, but      */
/*      we also now verify that there is a #GRID keyword before         */
/*      passing it off to GXFOpen().  We check in the first 50K.        */
/* -------------------------------------------------------------------- */
#define BIGBUFSIZE 50000
    int nBytesRead, bGotGrid = FALSE;
    FILE *fp;

    fp = VSIFOpen( poOpenInfo->pszFilename, "rb" );
    if( fp == NULL )
        return NULL;

    char *pszBigBuf = (char *) CPLMalloc(BIGBUFSIZE);
    nBytesRead = static_cast<int>(VSIFRead( pszBigBuf, 1, BIGBUFSIZE, fp ));
    VSIFClose( fp );

    for( i = 0; i < nBytesRead - 5 && !bGotGrid; i++ )
    {
        if( pszBigBuf[i] == '#' && STARTS_WITH_CI(pszBigBuf+i+1, "GRID") )
            bGotGrid = TRUE;
    }

    CPLFree( pszBigBuf );

    if( !bGotGrid )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Try opening the dataset.                                        */
/* -------------------------------------------------------------------- */

    l_hGXF = GXFOpen( poOpenInfo->pszFilename );

    if( l_hGXF == NULL )
        return( NULL );

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        GXFClose(l_hGXF);
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The GXF driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    GXFDataset 	*poDS;

    poDS = new GXFDataset();

    const char* pszGXFDataType = CPLGetConfigOption("GXF_DATATYPE", "Float32");
    GDALDataType eDT = GDALGetDataTypeByName(pszGXFDataType);
    if (!(eDT == GDT_Float32 || eDT == GDT_Float64))
    {
        CPLError(CE_Warning, CPLE_NotSupported,
                 "Unsupported value for GXF_DATATYPE : %s", pszGXFDataType);
        eDT = GDT_Float32;
    }

    poDS->hGXF = l_hGXF;
    poDS->eDataType = eDT;

/* -------------------------------------------------------------------- */
/*	Establish the projection.					*/
/* -------------------------------------------------------------------- */
    poDS->pszProjection = GXFGetMapProjectionAsOGCWKT( l_hGXF );

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    GXFGetRawInfo( l_hGXF, &(poDS->nRasterXSize), &(poDS->nRasterYSize), NULL,
                   NULL, NULL, &(poDS->dfNoDataValue) );

    if  (poDS->nRasterXSize <= 0 || poDS->nRasterYSize <= 0)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Invalid dimensions : %d x %d",
                  poDS->nRasterXSize, poDS->nRasterYSize);
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 1;
    poDS->SetBand( 1, new GXFRasterBand( poDS, 1 ));

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

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

    return( poDS );
}
Esempio n. 20
0
GDALDataset *PAuxDataset::Create( const char * pszFilename,
                                  int nXSize, int nYSize, int nBands,
                                  GDALDataType eType,
                                  char **papszOptions )

{
    char	*pszAuxFilename;

	const char *pszInterleave = CSLFetchNameValue( papszOptions, "INTERLEAVE" );
	if( pszInterleave == NULL )
		pszInterleave = "BAND";

/* -------------------------------------------------------------------- */
/*      Verify input options.                                           */
/* -------------------------------------------------------------------- */
    if( eType != GDT_Byte && eType != GDT_Float32 && eType != GDT_UInt16
        && eType != GDT_Int16 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
              "Attempt to create PCI .Aux labelled dataset with an illegal\n"
              "data type (%s).\n",
              GDALGetDataTypeName(eType) );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Sum the sizes of the band pixel types.                          */
/* -------------------------------------------------------------------- */
	int nPixelSizeSum = 0;
	int iBand;

    for( iBand = 0; iBand < nBands; iBand++ )
        nPixelSizeSum += (GDALGetDataTypeSize(eType)/8);

/* -------------------------------------------------------------------- */
/*      Try to create the file.                                         */
/* -------------------------------------------------------------------- */
    VSILFILE	*fp;

    fp = VSIFOpenL( pszFilename, "w" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file `%s' failed.\n",
                  pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Just write out a couple of bytes to establish the binary        */
/*      file, and then close it.                                        */
/* -------------------------------------------------------------------- */
    VSIFWriteL( (void *) "\0\0", 2, 1, fp );
    VSIFCloseL( fp );

/* -------------------------------------------------------------------- */
/*      Create the aux filename.                                        */
/* -------------------------------------------------------------------- */
    pszAuxFilename = (char *) CPLMalloc(strlen(pszFilename)+5);
    strcpy( pszAuxFilename, pszFilename );;

    for( int i = strlen(pszAuxFilename)-1; i > 0; i-- )
    {
        if( pszAuxFilename[i] == '.' )
        {
            pszAuxFilename[i] = '\0';
            break;
        }
    }

    strcat( pszAuxFilename, ".aux" );

/* -------------------------------------------------------------------- */
/*      Open the file.                                                  */
/* -------------------------------------------------------------------- */
    fp = VSIFOpenL( pszAuxFilename, "wt" );
    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file `%s' failed.\n",
                  pszAuxFilename );
        return NULL;
    }
    CPLFree( pszAuxFilename );
    
/* -------------------------------------------------------------------- */
/*      We need to write out the original filename but without any      */
/*      path components in the AuxilaryTarget line.  Do so now.         */
/* -------------------------------------------------------------------- */
    int		iStart;

    iStart = strlen(pszFilename)-1;
    while( iStart > 0 && pszFilename[iStart-1] != '/'
           && pszFilename[iStart-1] != '\\' )
        iStart--;

    VSIFPrintfL( fp, "AuxilaryTarget: %s\n", pszFilename + iStart );

/* -------------------------------------------------------------------- */
/*      Write out the raw definition for the dataset as a whole.        */
/* -------------------------------------------------------------------- */
    VSIFPrintfL( fp, "RawDefinition: %d %d %d\n",
                nXSize, nYSize, nBands );

/* -------------------------------------------------------------------- */
/*      Write out a definition for each band.  We always write band     */
/*      sequential files for now as these are pretty efficiently        */
/*      handled by GDAL.                                                */
/* -------------------------------------------------------------------- */
    vsi_l_offset    nImgOffset = 0;
    
    for( iBand = 0; iBand < nBands; iBand++ )
    {
        const char  *pszTypeName;
        int         nPixelOffset, nLineOffset;
		vsi_l_offset nNextImgOffset;

/* -------------------------------------------------------------------- */
/*      Establish our file layout based on supplied interleaving.       */
/* -------------------------------------------------------------------- */
		if( EQUAL(pszInterleave,"LINE") )
		{
			nPixelOffset = GDALGetDataTypeSize(eType)/8;
			nLineOffset = nXSize * nPixelSizeSum;
			nNextImgOffset = nImgOffset + nPixelOffset * nXSize;
		}
		else if( EQUAL(pszInterleave,"PIXEL") )
		{
			nPixelOffset = nPixelSizeSum;
			nLineOffset = nXSize * nPixelOffset;
			nNextImgOffset = nImgOffset + (GDALGetDataTypeSize(eType)/8);
		}
		else /* default to band */
		{
			nPixelOffset = GDALGetDataTypeSize(eType)/8;
			nLineOffset = nXSize * nPixelOffset;
			nNextImgOffset = nImgOffset + nYSize * (vsi_l_offset) nLineOffset;
		}

/* -------------------------------------------------------------------- */
/*      Write out line indicating layout.                               */
/* -------------------------------------------------------------------- */
        if( eType == GDT_Float32 )
            pszTypeName = "32R";
        else if( eType == GDT_Int16 )
            pszTypeName = "16S";
        else if( eType == GDT_UInt16 )
            pszTypeName = "16U";
        else
            pszTypeName = "8U";

        VSIFPrintfL( fp, "ChanDefinition-%d: %s " CPL_FRMT_GIB " %d %d %s\n", 
					 iBand+1,
					 pszTypeName, (GIntBig) nImgOffset,
					 nPixelOffset, nLineOffset,
#ifdef CPL_LSB
                    "Swapped"
#else
                    "Unswapped"
#endif
                    );

        nImgOffset = nNextImgOffset;
    }

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
    VSIFCloseL( fp );

    return (GDALDataset *) GDALOpen( pszFilename, GA_Update );
}
void GTMWaypointLayer::WriteFeatureAttributes( OGRFeature *poFeature, float altitude )
{
    void* pBuffer = NULL;
    void* pBufferAux = NULL;
    char psNameField[] = "          ";
    char* pszcomment = NULL;
    int icon = 48;
    int date = 0;
    for (int i = 0; i < poFeatureDefn->GetFieldCount(); ++i)
    {
        OGRFieldDefn *poFieldDefn = poFeatureDefn->GetFieldDefn( i );
        if( poFeature->IsFieldSet( i ) )
        {
            const char* pszName = poFieldDefn->GetNameRef();
            /* Waypoint name */
            if (strncmp(pszName, "name", 4) == 0)
            {
                strncpy (psNameField, poFeature->GetFieldAsString( i ), 10);
                CPLStrlcat (psNameField, "          ", sizeof(psNameField));
            }
            /* Waypoint comment */
            else if (strncmp(pszName, "comment", 7) == 0)
            {
                pszcomment = CPLStrdup( poFeature->GetFieldAsString( i ) );
            }
            /* Waypoint icon */
            else if (strncmp(pszName, "icon", 4) == 0)
            {
                icon = poFeature->GetFieldAsInteger( i );
                // Check if it is a valid icon
                if (icon < 1 || icon > 220)
                    icon = 48;
            }
            /* Waypoint date */
            else if (EQUAL(pszName, "time"))
            {
                struct tm brokendowndate;
                int year, month, day, hour, min, sec, TZFlag;
                if (poFeature->GetFieldAsDateTime( i, &year, &month, &day, &hour, &min, &sec, &TZFlag))
                {
                    brokendowndate.tm_year = year - 1900;
                    brokendowndate.tm_mon = month - 1;
                    brokendowndate.tm_mday = day;
                    brokendowndate.tm_hour = hour;
                    brokendowndate.tm_min = min;
                    brokendowndate.tm_sec = sec;
                    GIntBig unixTime = CPLYMDHMSToUnixTime(&brokendowndate);
                    if (TZFlag != 0)
                        unixTime -= (TZFlag - 100) * 15;
                    if (unixTime <= GTM_EPOCH || (unixTime - GTM_EPOCH) != (int)(unixTime - GTM_EPOCH))
                    {
                        CPLError(CE_Warning, CPLE_AppDefined,
                                  "%04d/%02d/%02d %02d:%02d:%02d is not a valid datetime for GTM",
                                  year, month, day, hour, min, sec);
                    }
                    else
                    {
                        date = (int)(unixTime - GTM_EPOCH);
                    }
                }
            }
        }
    }

    if (pszcomment == NULL)
        pszcomment = CPLStrdup( "" );

    int commentLength = 0;
    if (pszcomment != NULL)
        commentLength = strlen(pszcomment);

    int bufferSize = 27 + commentLength;
    pBuffer = CPLMalloc(bufferSize);
    pBufferAux = pBuffer;
    /* Write waypoint name to buffer */
    strncpy((char*)pBufferAux, psNameField, 10);

    /* Write waypoint string comment size to buffer */
    pBufferAux = (char*)pBuffer+10;
    appendUShort(pBufferAux, commentLength);

    /* Write waypoint string comment to buffer */
    strncpy((char*)pBuffer+12, pszcomment, commentLength);

    /* Write icon to buffer */
    pBufferAux = (char*)pBuffer+12+commentLength;
    appendUShort(pBufferAux, icon);

    /* Write dslp to buffer */
    pBufferAux = (char*)pBufferAux + 2;
    appendUChar(pBufferAux, 3);

    /* Date */
    pBufferAux = (char*)pBufferAux + 1;
    appendInt(pBufferAux, date);

    /* wrot */
    pBufferAux = (char*)pBufferAux + 4;
    appendUShort(pBufferAux, 0);

    /* walt */
    pBufferAux = (char*)pBufferAux + 2;
    appendFloat(pBufferAux, altitude);

    /* wlayer */
    pBufferAux = (char*)pBufferAux + 4;
    appendUShort(pBufferAux, 0);

    VSIFWriteL(pBuffer, bufferSize, 1, poDS->getOutputFP());
    poDS->incNumWaypoints();

    if (pszcomment != NULL)
        CPLFree(pszcomment);
    CPLFree(pBuffer);
}
Esempio n. 22
0
GDALProxyPoolCacheEntry* GDALDatasetPool::_RefDataset(const char* pszFileName,
                                                      GDALAccess eAccess,
                                                      char** papszOpenOptions,
                                                      int bShared)
{
    GDALProxyPoolCacheEntry* cur = firstEntry;
    GIntBig responsiblePID = GDALGetResponsiblePIDForCurrentThread();
    GDALProxyPoolCacheEntry* lastEntryWithZeroRefCount = NULL;

    while(cur)
    {
        GDALProxyPoolCacheEntry* next = cur->next;

        if (strcmp(cur->pszFileName, pszFileName) == 0 &&
            ((bShared && cur->responsiblePID == responsiblePID) ||
             (!bShared && cur->refCount == 0)) )
        {
            if (cur != firstEntry)
            {
                /* Move to begin */
                if (cur->next)
                    cur->next->prev = cur->prev;
                else
                    lastEntry = cur->prev;
                cur->prev->next = cur->next;
                cur->prev = NULL;
                firstEntry->prev = cur;
                cur->next = firstEntry;
                firstEntry = cur;

#ifdef DEBUG_PROXY_POOL
                CheckLinks();
#endif
            }

            cur->refCount ++;
            return cur;
        }

        if (cur->refCount == 0)
            lastEntryWithZeroRefCount = cur;

        cur = next;
    }

    if (currentSize == maxSize)
    {
        if (lastEntryWithZeroRefCount == NULL)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Too many threads are running for the current value of the dataset pool size (%d).\n"
                     "or too many proxy datasets are opened in a cascaded way.\n"
                     "Try increasing GDAL_MAX_DATASET_POOL_SIZE.", maxSize);
            return NULL;
        }

        lastEntryWithZeroRefCount->pszFileName[0] = '\0';
        if (lastEntryWithZeroRefCount->poDS)
        {
            /* Close by pretending we are the thread that GDALOpen'ed this */
            /* dataset */
            GDALSetResponsiblePIDForCurrentThread(lastEntryWithZeroRefCount->responsiblePID);

            refCountOfDisableRefCount ++;
            GDALClose(lastEntryWithZeroRefCount->poDS);
            refCountOfDisableRefCount --;

            lastEntryWithZeroRefCount->poDS = NULL;
            GDALSetResponsiblePIDForCurrentThread(responsiblePID);
        }
        CPLFree(lastEntryWithZeroRefCount->pszFileName);

        /* Recycle this entry for the to-be-openeded dataset and */
        /* moves it to the top of the list */
        if (lastEntryWithZeroRefCount->prev)
            lastEntryWithZeroRefCount->prev->next = lastEntryWithZeroRefCount->next;
        else {
            CPLAssert(0);
        }
        if (lastEntryWithZeroRefCount->next)
            lastEntryWithZeroRefCount->next->prev = lastEntryWithZeroRefCount->prev;
        else
        {
            CPLAssert(lastEntryWithZeroRefCount == lastEntry);
            lastEntry->prev->next = NULL;
            lastEntry = lastEntry->prev;
        }
        lastEntryWithZeroRefCount->prev = NULL;
        lastEntryWithZeroRefCount->next = firstEntry;
        firstEntry->prev = lastEntryWithZeroRefCount;
        cur = firstEntry = lastEntryWithZeroRefCount;
#ifdef DEBUG_PROXY_POOL
        CheckLinks();
#endif
    }
    else
    {
        /* Prepend */
        cur = (GDALProxyPoolCacheEntry*) CPLMalloc(sizeof(GDALProxyPoolCacheEntry));
        if (lastEntry == NULL)
            lastEntry = cur;
        cur->prev = NULL;
        cur->next = firstEntry;
        if (firstEntry)
            firstEntry->prev = cur;
        firstEntry = cur;
        currentSize ++;
#ifdef DEBUG_PROXY_POOL
        CheckLinks();
#endif
    }

    cur->pszFileName = CPLStrdup(pszFileName);
    cur->responsiblePID = responsiblePID;
    cur->refCount = 1;

    refCountOfDisableRefCount ++;
    int nFlag = ((eAccess == GA_Update) ? GDAL_OF_UPDATE : GDAL_OF_READONLY) | GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR;
    cur->poDS = (GDALDataset*) GDALOpenEx( pszFileName, nFlag, NULL,
                           (const char* const* )papszOpenOptions, NULL );
    refCountOfDisableRefCount --;

    return cur;
}
Esempio n. 23
0
CPLErr SGIRasterBand::IWriteBlock(CPL_UNUSED int nBlockXOff,
                                  int nBlockYOff,
                                  void*  pImage)
{
    CPLAssert(nBlockXOff == 0);

    SGIDataset* poGDS = reinterpret_cast<SGIDataset *>( poDS);
    ImageRec *image = &(poGDS->image);

/* -------------------------------------------------------------------- */
/*      Handle the fairly trivial non-RLE case.                         */
/* -------------------------------------------------------------------- */
    if( image->type == 0 )
    {
        VSIFSeekL(image->file,
                  512 + (nBlockYOff*static_cast<vsi_l_offset>(image->xsize))
                  + ((nBand-1)*static_cast<vsi_l_offset>(image->xsize)*static_cast<vsi_l_offset>(image->ysize) ),
                  SEEK_SET);
        if(VSIFWriteL(pImage, 1, image->xsize, image->file) != image->xsize)
        {
            CPLError(CE_Failure, CPLE_OpenFailed,
                     "file write error: row (%d)\n", nBlockYOff );
            return CE_Failure;
        }
        return CE_None;
    }

/* -------------------------------------------------------------------- */
/*      Handle RLE case.                                                */
/* -------------------------------------------------------------------- */
    const GByte *pabyRawBuf = reinterpret_cast<const GByte *>( pImage );
    GByte *pabyRLEBuf = reinterpret_cast<GByte *>(
        CPLMalloc( image->xsize * 2 + 6 ) );

    int iX = 0;
    int nRLEBytes = 0;

    while( iX < image->xsize )
    {
        int nRepeatCount = 1;

        while( iX + nRepeatCount < image->xsize
               && nRepeatCount < 127
               && pabyRawBuf[iX + nRepeatCount] == pabyRawBuf[iX] )
            nRepeatCount++;

        if( nRepeatCount > 2
            || iX + nRepeatCount == image->xsize
            || (iX + nRepeatCount < image->xsize - 2
                && pabyRawBuf[iX + nRepeatCount + 1]
                == pabyRawBuf[iX + nRepeatCount + 2]
                && pabyRawBuf[iX + nRepeatCount + 1]
                == pabyRawBuf[iX + nRepeatCount + 3]) )
        { // encode a constant run.
            pabyRLEBuf[nRLEBytes++] = static_cast<GByte>( nRepeatCount );
            pabyRLEBuf[nRLEBytes++] = pabyRawBuf[iX];
            iX += nRepeatCount;
        }
        else
        { // copy over mixed data.
            for( nRepeatCount = 1;
                 iX + nRepeatCount < image->xsize && nRepeatCount < 127;
                 nRepeatCount++ )
            {
                if( iX + nRepeatCount + 3 >= image->xsize )
                    continue;

                // quit if the next 3 pixels match
                if( pabyRawBuf[iX + nRepeatCount]
                    == pabyRawBuf[iX + nRepeatCount+1]
                    && pabyRawBuf[iX + nRepeatCount]
                    == pabyRawBuf[iX + nRepeatCount+2] )
                    break;
            }

            pabyRLEBuf[nRLEBytes++] = static_cast<GByte>( 0x80 | nRepeatCount );
            memcpy( pabyRLEBuf + nRLEBytes,
                    pabyRawBuf + iX,
                    nRepeatCount );

            nRLEBytes += nRepeatCount;
            iX += nRepeatCount;
        }
    }

    // EOL marker.
    pabyRLEBuf[nRLEBytes++] = 0;

/* -------------------------------------------------------------------- */
/*      Write RLE Buffer at end of file.                                */
/* -------------------------------------------------------------------- */
    const int row = (image->ysize - nBlockYOff - 1) + (nBand-1) * image->ysize;

    VSIFSeekL(image->file, 0, SEEK_END );

    image->rowStart[row] = static_cast<GUInt32>( VSIFTellL( image->file ) );
    image->rowSize[row] = nRLEBytes;
    image->rleTableDirty = TRUE;

    if( static_cast<int>( VSIFWriteL(pabyRLEBuf, 1, nRLEBytes, image->file) )
        != nRLEBytes )
    {
        CPLFree( pabyRLEBuf );
        CPLError(CE_Failure, CPLE_OpenFailed,
                 "file write error: row (%d)\n", nBlockYOff );
        return CE_Failure;
    }

    CPLFree( pabyRLEBuf );

    return CE_None;
}
Esempio n. 24
0
GDALDataset *LCPDataset::Open( GDALOpenInfo * poOpenInfo )

{
    /* -------------------------------------------------------------------- */
    /*      Verify that this is a FARSITE LCP file    */
    /* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return NULL;

    /* -------------------------------------------------------------------- */
    /*      Confirm the requested access is supported.                      */
    /* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The LCP driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Create a corresponding GDALDataset.                             */
    /* -------------------------------------------------------------------- */
    LCPDataset  *poDS;
    VSILFILE        *fpImage;

    fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb");
    if (fpImage == NULL)
        return NULL;

    poDS = new LCPDataset();
    poDS->fpImage = fpImage;

    /* -------------------------------------------------------------------- */
    /*      Read the header and extract some information.                   */
    /* -------------------------------------------------------------------- */
    int bHaveCrownFuels, bHaveGroundFuels;
    int nBands, i;
    long nWidth = -1, nHeight = -1;
    int nTemp, nTemp2;
    char szTemp[32];
    char* pszList;

    VSIFSeekL( poDS->fpImage, 0, SEEK_SET );
    if (VSIFReadL( poDS->pachHeader, 1, LCP_HEADER_SIZE, poDS->fpImage ) != LCP_HEADER_SIZE)
    {
        CPLError(CE_Failure, CPLE_FileIO, "File too short");
        delete poDS;
        return NULL;
    }

    nWidth = CPL_LSBINT32PTR (poDS->pachHeader + 4164);
    nHeight = CPL_LSBINT32PTR (poDS->pachHeader + 4168);

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

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

    // crown fuels = canopy height, canopy base height, canopy bulk density
    // 21 = have them, 20 = don't have them
    bHaveCrownFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 0) - 20 );
    // ground fuels = duff loading, coarse woody
    bHaveGroundFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 4) - 20 );

    if( bHaveCrownFuels )
    {
        if( bHaveGroundFuels )
            nBands = 10;
        else
            nBands = 8;
    }
    else
    {
        if( bHaveGroundFuels )
            nBands = 7;
        else
            nBands = 5;
    }

    // add dataset-level metadata

    nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 8);
    sprintf(szTemp, "%d", nTemp);
    poDS->SetMetadataItem( "LATITUDE", szTemp );

    nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 4204);
    if ( nTemp == 0 )
        poDS->SetMetadataItem( "LINEAR_UNIT", "Meters" );
    if ( nTemp == 1 )
        poDS->SetMetadataItem( "LINEAR_UNIT", "Feet" );

    poDS->pachHeader[LCP_HEADER_SIZE-1] = '\0';
    poDS->SetMetadataItem( "DESCRIPTION", poDS->pachHeader + 6804 );


    /* -------------------------------------------------------------------- */
    /*      Create band information objects.                                */
    /* -------------------------------------------------------------------- */

    int          iPixelSize;
    iPixelSize = nBands * 2;
    int          bNativeOrder;

    if (nWidth > INT_MAX / iPixelSize)
    {
        CPLError( CE_Failure, CPLE_AppDefined,  "Int overflow occured");
        delete poDS;
        return NULL;
    }

#ifdef CPL_LSB
    bNativeOrder = TRUE;
#else
    bNativeOrder = FALSE;
#endif

    pszList = (char*)CPLMalloc(2048);

    for( int iBand = 1; iBand <= nBands; iBand++ )
    {
        GDALRasterBand  *poBand = NULL;

        poBand = new RawRasterBand(
            poDS, iBand, poDS->fpImage, LCP_HEADER_SIZE + ((iBand-1)*2),
            iPixelSize, iPixelSize * nWidth, GDT_Int16, bNativeOrder, TRUE );

        poDS->SetBand(iBand, poBand);

        switch ( iBand ) {
        case 1:
            poBand->SetDescription("Elevation");

            nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4224);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "ELEVATION_UNIT", szTemp );

            if ( nTemp == 0 )
                poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Meters" );
            if ( nTemp == 1 )
                poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Feet" );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 44);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "ELEVATION_MIN", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 48);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "ELEVATION_MAX", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 52);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "ELEVATION_NUM_CLASSES", szTemp );

            *(poDS->pachHeader + 4244 + 255) = '\0';
            poBand->SetMetadataItem( "ELEVATION_FILE", poDS->pachHeader + 4244 );

            break;

        case 2:
            poBand->SetDescription("Slope");

            nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4226);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "SLOPE_UNIT", szTemp );

            if ( nTemp == 0 )
                poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Degrees" );
            if ( nTemp == 1 )
                poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Percent" );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 456);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "SLOPE_MIN", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 460);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "SLOPE_MAX", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 464);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "SLOPE_NUM_CLASSES", szTemp );

            *(poDS->pachHeader + 4500 + 255) = '\0';
            poBand->SetMetadataItem( "SLOPE_FILE", poDS->pachHeader + 4500 );

            break;

        case 3:
            poBand->SetDescription("Aspect");

            nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4228);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "ASPECT_UNIT", szTemp );

            if ( nTemp == 0 )
                poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass categories" );
            if ( nTemp == 1 )
                poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass degrees" );
            if ( nTemp == 2 )
                poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Azimuth degrees" );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 868);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "ASPECT_MIN", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 872);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "ASPECT_MAX", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 876);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "ASPECT_NUM_CLASSES", szTemp );

            *(poDS->pachHeader + 4756 + 255) = '\0';
            poBand->SetMetadataItem( "ASPECT_FILE", poDS->pachHeader + 4756 );

            break;

        case 4:
            int nMinFM, nMaxFM;

            poBand->SetDescription("Fuel models");

            nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4230);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "FUEL_MODEL_OPTION", szTemp );

            if ( nTemp == 0 )
                poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models AND no conversion file needed" );
            if ( nTemp == 1 )
                poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models BUT no conversion file needed" );
            if ( nTemp == 2 )
                poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models BUT conversion file needed" );
            if ( nTemp == 3 )
                poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models AND conversion file needed" );

            nMinFM = CPL_LSBINT32PTR (poDS->pachHeader + 1280);
            sprintf(szTemp, "%d", nMinFM);
            poBand->SetMetadataItem( "FUEL_MODEL_MIN", szTemp );

            nMaxFM = CPL_LSBINT32PTR (poDS->pachHeader + 1284);
            sprintf(szTemp, "%d", nMaxFM);
            poBand->SetMetadataItem( "FUEL_MODEL_MAX", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1288);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "FUEL_MODEL_NUM_CLASSES", szTemp );

            if (nTemp > 0 && nTemp <= 100) {
                strcpy(pszList, "");
                for ( i = 0; i <= nTemp; i++ ) {
                    nTemp2 = CPL_LSBINT32PTR (poDS->pachHeader + (1292+(i*4))) ;
                    if ( nTemp2 >= nMinFM && nTemp2 <= nMaxFM ) {
                        sprintf(szTemp, "%d", nTemp2);
                        strcat(pszList, szTemp);
                        if (i < (nTemp) )
                            strcat(pszList, ",");
                    }
                }
            }
            poBand->SetMetadataItem( "FUEL_MODEL_VALUES", pszList );

            *(poDS->pachHeader + 5012 + 255) = '\0';
            poBand->SetMetadataItem( "FUEL_MODEL_FILE", poDS->pachHeader + 5012 );

            break;

        case 5:
            poBand->SetDescription("Canopy cover");

            nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4232);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CANOPY_COV_UNIT", szTemp );

            if ( nTemp == 0 )
                poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Categories (0-4)" );
            if ( nTemp == 1 )
                poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Percent" );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1692);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CANOPY_COV_MIN", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1696);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CANOPY_COV_MAX", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1700);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CANOPY_COV_NUM_CLASSES", szTemp );

            *(poDS->pachHeader + 5268 + 255) = '\0';
            poBand->SetMetadataItem( "CANOPY_COV_FILE", poDS->pachHeader + 5268 );

            break;

        case 6:
            if(bHaveCrownFuels) {
                poBand->SetDescription("Canopy height");

                nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4234);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CANOPY_HT_UNIT", szTemp );

                if ( nTemp == 1 )
                    poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters" );
                if ( nTemp == 2 )
                    poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet" );
                if ( nTemp == 3 )
                    poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters x 10" );
                if ( nTemp == 4 )
                    poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet x 10" );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2104);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CANOPY_HT_MIN", szTemp );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2108);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CANOPY_HT_MAX", szTemp );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2112);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CANOPY_HT_NUM_CLASSES", szTemp );

                *(poDS->pachHeader + 5524 + 255) = '\0';
                poBand->SetMetadataItem( "CANOPY_HT_FILE", poDS->pachHeader + 5524 );
            }
            else {
                poBand->SetDescription("Duff");

                nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "DUFF_UNIT", szTemp );

                if ( nTemp == 1 )
                    poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" );
                if ( nTemp == 2 )
                    poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "DUFF_MIN", szTemp );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "DUFF_MAX", szTemp );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp );

                *(poDS->pachHeader + 6292 + 255) = '\0';
                poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 );
            }
            break;

        case 7:
            if(bHaveCrownFuels) {
                poBand->SetDescription("Canopy base height");

                nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4236);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CBH_UNIT", szTemp );

                if ( nTemp == 1 )
                    poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters" );
                if ( nTemp == 2 )
                    poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet" );
                if ( nTemp == 3 )
                    poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters x 10" );
                if ( nTemp == 4 )
                    poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet x 10" );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2516);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CBH_MIN", szTemp );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2520);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CBH_MAX", szTemp );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2524);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CBH_NUM_CLASSES", szTemp );

                *(poDS->pachHeader + 5780 + 255) = '\0';
                poBand->SetMetadataItem( "CBH_FILE", poDS->pachHeader + 5780 );
            }
            else {
                poBand->SetDescription("Coarse woody debris");

                nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CWD_OPTION", szTemp );

                //if ( nTemp == 1 )
                //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );
                //if ( nTemp == 2 )
                //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CWD_MIN", szTemp );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CWD_MAX", szTemp );

                nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760);
                sprintf(szTemp, "%d", nTemp);
                poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp );

                *(poDS->pachHeader + 6548 + 255) = '\0';
                poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 );
            }
            break;

        case 8:
            poBand->SetDescription("Canopy bulk density");

            nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4238);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CBD_UNIT", szTemp );

            if ( nTemp == 1 )
                poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3" );
            if ( nTemp == 2 )
                poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3" );
            if ( nTemp == 3 )
                poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3 x 100" );
            if ( nTemp == 4 )
                poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3 x 1000" );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2928);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CBD_MIN", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2932);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CBD_MAX", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2936);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CBD_NUM_CLASSES", szTemp );

            *(poDS->pachHeader + 6036 + 255) = '\0';
            poBand->SetMetadataItem( "CBD_FILE", poDS->pachHeader + 6036 );

            break;

        case 9:
            poBand->SetDescription("Duff");

            nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "DUFF_UNIT", szTemp );

            if ( nTemp == 1 )
                poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" );
            if ( nTemp == 2 )
                poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "DUFF_MIN", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "DUFF_MAX", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp );

            *(poDS->pachHeader + 6292 + 255) = '\0';
            poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 );

            break;

        case 10:
            poBand->SetDescription("Coarse woody debris");

            nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CWD_OPTION", szTemp );

            //if ( nTemp == 1 )
            //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );
            //if ( nTemp == 2 )
            //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CWD_MIN", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CWD_MAX", szTemp );

            nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760);
            sprintf(szTemp, "%d", nTemp);
            poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp );

            *(poDS->pachHeader + 6548 + 255) = '\0';
            poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 );

            break;
        }
    }

    /* -------------------------------------------------------------------- */
    /*      Try to read projection file.                                    */
    /* -------------------------------------------------------------------- */
    char        *pszDirname, *pszBasename;
    VSIStatBufL   sStatBuf;

    pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename));
    pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename));

    poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "prj" );
    int nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf );

    if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename))
    {
        poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "PRJ" );
        nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf );
    }

    if( nRet == 0 )
    {
        OGRSpatialReference     oSRS;

        char** papszPrj = CSLLoad( poDS->osPrjFilename );

        CPLDebug( "LCP", "Loaded SRS from %s",
                  poDS->osPrjFilename.c_str() );

        if( oSRS.importFromESRI( papszPrj ) == OGRERR_NONE )
        {
            oSRS.exportToWkt( &(poDS->pszProjection) );
        }

        CSLDestroy(papszPrj);
    }

    CPLFree( pszDirname );
    CPLFree( pszBasename );

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

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

    CPLFree(pszList);

    return( poDS );
}
Esempio n. 25
0
bool GH5_FetchAttribute( hid_t loc_id, const char *pszAttrName, 
                         double &dfResult, bool bReportError )

{
    hid_t hAttr = H5Aopen_name( loc_id, pszAttrName );

    dfResult = 0.0;
    if( hAttr < 0 )
    {
        if( bReportError )
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Attempt to read attribute %s failed, not found.",
                      pszAttrName );
        return false;
    }

    hid_t hAttrTypeID      = H5Aget_type( hAttr );
    hid_t hAttrNativeType  = H5Tget_native_type( hAttrTypeID, H5T_DIR_DEFAULT );

/* -------------------------------------------------------------------- */
/*      Confirm that we have a single element value.                    */
/* -------------------------------------------------------------------- */

    hid_t hAttrSpace       = H5Aget_space( hAttr );
    hsize_t anSize[64];
    int nAttrDims       = H5Sget_simple_extent_dims( hAttrSpace, anSize, NULL );
    
    int i, nAttrElements = 1;

    for( i=0; i < nAttrDims; i++ ) {
        nAttrElements *= (int) anSize[i];
    }

    if( nAttrElements != 1 )
    {
        if( bReportError )
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Attempt to read attribute %s failed, count=%d, not 1.",
                      pszAttrName, nAttrElements );

        H5Sclose( hAttrSpace );
        H5Tclose( hAttrNativeType );
        H5Tclose( hAttrTypeID );
        H5Aclose( hAttr );
        return false;
    }
    
/* -------------------------------------------------------------------- */
/*      Read the value.                                                 */
/* -------------------------------------------------------------------- */
    void *buf = (void *)CPLMalloc( H5Tget_size( hAttrNativeType ));
    H5Aread( hAttr, hAttrNativeType, buf );

/* -------------------------------------------------------------------- */
/*      Translate to double.                                            */
/* -------------------------------------------------------------------- */
    if( H5Tequal( H5T_NATIVE_INT, hAttrNativeType ) )
        dfResult = *((int *) buf);
    else if( H5Tequal( H5T_NATIVE_FLOAT,    hAttrNativeType ) )
        dfResult = *((float *) buf);
    else if( H5Tequal( H5T_NATIVE_DOUBLE,    hAttrNativeType ) )
        dfResult = *((double *) buf);
    else
    {
        if( bReportError )
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Attribute %s of unsupported type for conversion to double.",
                      pszAttrName );
        CPLFree( buf );

        H5Sclose( hAttrSpace );
        H5Tclose( hAttrNativeType );
        H5Tclose( hAttrTypeID );
        H5Aclose( hAttr );

        return false;
    }

    CPLFree( buf );

    H5Sclose( hAttrSpace );
    H5Tclose( hAttrNativeType );
    H5Tclose( hAttrTypeID );
    H5Aclose( hAttr );
    return true;
}
Esempio n. 26
0
/**
 * Reads an array of double attributes from the HDF5 metadata.
 * It reads the attributes directly on it's binary form directly,
 * thus avoiding string conversions.
 *
 * Important: It allocates the memory for the attributes internally,
 * so the caller must free the returned array after using it.
 * @param pszAttrName Name of the attribute to be read.
 *        the attribute name must be the form:
 *            root attribute name
 *            SUBDATASET/subdataset attribute name
 * @param pdfValues pointer wich will store the array of doubles read.
 * @param nLen it stores the length of the array read. If NULL it doesn't 
 *        inform the lenght of the array.
 * @return CPLErr CE_None in case of success, CE_Failure in case of failure
 */
CPLErr HDF5Dataset::HDF5ReadDoubleAttr(const char* pszAttrFullPath,
                                       double **pdfValues,int *nLen)
{
    CPLErr          retVal = CE_Failure;
    hid_t           hAttrID=-1;
    hid_t           hAttrTypeID=-1;
    hid_t           hAttrNativeType=-1;
    hid_t           hAttrSpace=-1;
    hid_t           hObjAttrID=-1;

    hsize_t         nSize[64];
    unsigned int    nAttrElmts;
    hsize_t         i;
    unsigned int    nAttrDims;

    size_t nSlashPos;

    CPLString osAttrFullPath(pszAttrFullPath);
    CPLString osObjName;
    CPLString osAttrName;

    //Search for the last "/" in order to get the
    //Path to the attribute
    nSlashPos = osAttrFullPath.find_last_of("/");

    //If objects name have been found
    if(nSlashPos != CPLString::npos )
    {
        //Split Object name (dataset, group)
        osObjName = osAttrFullPath.substr(0,nSlashPos);
        //Split attribute name
        osAttrName = osAttrFullPath.substr(nSlashPos+1);
    }
    else
    {
        //By default the group is root, and
        //the attribute is the full path
        osObjName = "/";
        osAttrName = pszAttrFullPath;
    }

    hObjAttrID = H5Oopen( hHDF5, osObjName.c_str(),H5P_DEFAULT);

    if(hObjAttrID < 0)
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Object %s could not be opened\n", pszAttrFullPath);
        retVal = CE_Failure;
    }
    else
    {
        //Open attribute handler by name, from the object handler opened
        //earlier
        hAttrID = H5Aopen_name( hObjAttrID, osAttrName.c_str());

        //Check for errors opening the attribute
        if(hAttrID <0)
        {
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "Attribute %s could not be opened\n", pszAttrFullPath);
            retVal = CE_Failure;
        }
        else
        {
            hAttrTypeID      = H5Aget_type( hAttrID );
            hAttrNativeType  = H5Tget_native_type( hAttrTypeID, H5T_DIR_DEFAULT );
            hAttrSpace       = H5Aget_space( hAttrID );
            nAttrDims        = H5Sget_simple_extent_dims( hAttrSpace, nSize, NULL );

            if( !H5Tequal( H5T_NATIVE_DOUBLE, hAttrNativeType ) )
            {
                 CPLError( CE_Failure, CPLE_OpenFailed,
                                 "Attribute %s is not of type double\n", pszAttrFullPath);
                 retVal = CE_Failure;
            }
            else
            {
                //Get the ammount of elements
                nAttrElmts = 1;
                for( i=0; i < nAttrDims; i++ )
                {
                    //For multidimensional attributes
                     nAttrElmts *= nSize[i];
                }

                if(nLen != NULL)
                    *nLen = nAttrElmts;

                (*pdfValues) = (double *) CPLMalloc(nAttrElmts*sizeof(double));

                //Read the attribute contents
                if(H5Aread( hAttrID, hAttrNativeType, *pdfValues )<0)
                {
                     CPLError( CE_Failure, CPLE_OpenFailed,
                               "Attribute %s could not be opened\n", 
                               pszAttrFullPath);
                     retVal = CE_Failure;
                }
                else
                {
                    retVal = CE_None;
                }
            }

            H5Tclose(hAttrNativeType);
            H5Tclose(hAttrTypeID);
            H5Sclose(hAttrSpace);
            H5Aclose(hAttrID);
        }
        H5Oclose(hObjAttrID);
    }

    return retVal;
}
Esempio n. 27
0
CPLErr OGRMDBLayer::BuildFeatureDefn()

{
    poFeatureDefn = new OGRFeatureDefn( poMDBTable->GetName() );
    SetDescription( poFeatureDefn->GetName() );

    poFeatureDefn->Reference();


    int nRawColumns = poMDBTable->GetColumnCount();
    panFieldOrdinals = (int *) CPLMalloc( sizeof(int) * nRawColumns );

    for( int iCol = 0; iCol < nRawColumns; iCol++ )
    {
        const char* pszColName = poMDBTable->GetColumnName(iCol);
        OGRFieldDefn    oField(pszColName, OFTString );

        if( pszGeomColumn != NULL
            && EQUAL(pszColName,pszGeomColumn) )
            continue;

        if( eGeometryType == MDB_GEOM_PGEO
            && pszFIDColumn == NULL
            && EQUAL(pszColName,"OBJECTID") )
        {
            pszFIDColumn = CPLStrdup(pszColName);
        }

        if( eGeometryType == MDB_GEOM_PGEO
            && pszGeomColumn == NULL
            && EQUAL(pszColName,"Shape") )
        {
            pszGeomColumn = CPLStrdup(pszColName);
            continue;
        }

        switch( poMDBTable->GetColumnType(iCol) )
        {
          case MDB_Boolean:
            oField.SetType( OFTInteger );
            oField.SetWidth(1);
            break;

          case MDB_Byte:
          case MDB_Short:
          case MDB_Int:
            oField.SetType( OFTInteger );
            break;

          case MDB_Binary:
          case MDB_OLE:
            oField.SetType( OFTBinary );
            break;

          case MDB_Float:
          case MDB_Double:
            oField.SetType( OFTReal );
            break;

          case MDB_Text:
            oField.SetWidth(poMDBTable->GetColumnLength(iCol));
            break;

          default:
            /* leave it as OFTString */;
        }

        poFeatureDefn->AddFieldDefn( &oField );
        panFieldOrdinals[poFeatureDefn->GetFieldCount() - 1] = iCol+1;
    }

    if( poFeatureDefn->GetGeomFieldCount() > 0 )
    {
        poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
        if( pszGeomColumn != NULL )
            poFeatureDefn->GetGeomFieldDefn(0)->SetName(pszGeomColumn);
    }

    return CE_None;
}
Esempio n. 28
0
herr_t HDF5AttrIterate( hid_t hH5ObjID,
                        const char *pszAttrName,
                        void *pDS )
{
    hid_t           hAttrID;
    hid_t           hAttrTypeID;
    hid_t           hAttrNativeType;
    hid_t           hAttrSpace;

    char           *szData = NULL;
    hsize_t        nSize[64];
    unsigned int   nAttrElmts;
    hsize_t        nAttrSize;
    hsize_t        i;
    void           *buf = NULL;
    unsigned int   nAttrDims;

    char          **papszTokens;

    HDF5Dataset    *poDS;
    CPLString       osKey;
    char           *szValue = NULL;

    poDS = (HDF5Dataset *) pDS;

    // Convert "/" into "_" for the path component
    const char* pszPath = poDS->poH5CurrentObject->pszUnderscorePath;
    if(pszPath != NULL && strlen(pszPath) > 0)
    {
        papszTokens = CSLTokenizeString2( pszPath, "/", CSLT_HONOURSTRINGS );

        for( i = 0; papszTokens != NULL && papszTokens[i] != NULL; ++i )
        {
            if( i != 0)
                osKey += '_';
            osKey += papszTokens[i];
        }
        CSLDestroy( papszTokens );
    }

    // Convert whitespaces into "_" for the attribute name component
    papszTokens = CSLTokenizeString2( pszAttrName, " ",
                            CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES );
    for( i = 0; papszTokens != NULL && papszTokens[i] != NULL; ++i )
    {
        if(!osKey.empty())
            osKey += '_';
        osKey += papszTokens[i];
    }
    CSLDestroy( papszTokens );

    hAttrID          = H5Aopen_name( hH5ObjID, pszAttrName );
    hAttrTypeID      = H5Aget_type( hAttrID );
    hAttrNativeType  = H5Tget_native_type( hAttrTypeID, H5T_DIR_DEFAULT );
    hAttrSpace       = H5Aget_space( hAttrID );
    nAttrDims        = H5Sget_simple_extent_dims( hAttrSpace, nSize, NULL );

    nAttrElmts = 1;
    for( i=0; i < nAttrDims; i++ ) {
        nAttrElmts *= (int) nSize[i];
    }

    if( H5Tget_class( hAttrNativeType ) == H5T_STRING )
    {
        if ( H5Tis_variable_str(hAttrNativeType) )
        {
            char** papszStrings;
            papszStrings = (char**) CPLMalloc( nAttrElmts * sizeof(char*) );

            // Read the values
            H5Aread( hAttrID, hAttrNativeType, papszStrings );

            // Concatenate all values as one string (separated by a space)
            CPLString osVal = papszStrings[0];
            for( i=1; i < nAttrElmts; i++ ) {
                osVal += " ";
                osVal += papszStrings[i];
            }

            szValue = (char*) CPLMalloc(osVal.length() + 1);
            strcpy( szValue, osVal.c_str() );

            H5Dvlen_reclaim( hAttrNativeType, hAttrSpace, H5P_DEFAULT,
                             papszStrings );
            CPLFree( papszStrings );
        }
        else
        {
            nAttrSize = H5Aget_storage_size( hAttrID );
            szValue = (char*) CPLMalloc((size_t) (nAttrSize+1));
            H5Aread( hAttrID, hAttrNativeType, szValue );
            szValue[nAttrSize] = '\0';
        }
    }
    else {
        if( nAttrElmts > 0 ) {
            buf = (void *) CPLMalloc( nAttrElmts*
                          H5Tget_size( hAttrNativeType ));
            szData = (char*) CPLMalloc( 8192 );
            szValue = (char*) CPLMalloc( MAX_METADATA_LEN );
            szData[0] = '\0';
            szValue[0] ='\0';
            H5Aread( hAttrID, hAttrNativeType, buf );
        }
        if( H5Tequal( H5T_NATIVE_CHAR, hAttrNativeType ) 
            || H5Tequal( H5T_NATIVE_SCHAR,  hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%c ", ((char *) buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_UCHAR,  hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%c", ((char *) buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_SHORT,  hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%d ", ((short *) buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_USHORT, hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%ud ", ((unsigned short *) buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_INT,    hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%d ", ((int *) buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_UINT,   hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%ud ", ((unsigned int *) buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_LONG,   hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%ld ", ((long *)buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_ULONG,  hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                sprintf( szData, "%ld ", ((unsigned long *)buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_FLOAT,  hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                CPLsprintf( szData, "%.8g ",  ((float *)buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        else if( H5Tequal( H5T_NATIVE_DOUBLE, hAttrNativeType ) ) {
            for( i=0; i < nAttrElmts; i++ ) {
                CPLsprintf( szData, "%.15g ",  ((double *)buf)[i] );
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                                                            MAX_METADATA_LEN )
                    CPLError( CE_Warning, CPLE_OutOfMemory,
                              "Header data too long. Truncated\n");
            }
        }
        CPLFree( buf );

    }
    H5Sclose(hAttrSpace);
    H5Tclose(hAttrNativeType);
    H5Tclose(hAttrTypeID);
    H5Aclose( hAttrID );
    poDS->papszMetadata = CSLSetNameValue( poDS->papszMetadata, osKey, szValue);

    CPLFree( szData );
    CPLFree( szValue );

    return 0;
}
Esempio n. 29
0
CPLSpawnedProcess* CPLSpawnAsync(int (*pfnMain)(CPL_FILE_HANDLE, CPL_FILE_HANDLE),
                                 const char * const papszArgv[],
                                 int bCreateInputPipe,
                                 int bCreateOutputPipe,
                                 int bCreateErrorPipe,
                                 char** papszOptions)
{
    HANDLE pipe_in[2] = {NULL, NULL};
    HANDLE pipe_out[2] = {NULL, NULL};
    HANDLE pipe_err[2] = {NULL, NULL};
    SECURITY_ATTRIBUTES saAttr;
    PROCESS_INFORMATION piProcInfo;
    STARTUPINFO siStartInfo;
    CPLString osCommandLine;
    int i;
    CPLSpawnedProcess* p = NULL;

    if( papszArgv == NULL )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "On Windows, papszArgv argument must not be NULL");
        return NULL;
    }

    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    if( bCreateInputPipe )
    {
        if (!CreatePipe(&pipe_in[IN_FOR_PARENT],&pipe_in[OUT_FOR_PARENT],&saAttr, 0))
            goto err_pipe;
        /* The child must not inherit from the write side of the pipe_in */
        if (!SetHandleInformation(pipe_in[OUT_FOR_PARENT],HANDLE_FLAG_INHERIT,0))
            goto err_pipe;
    }

    if( bCreateOutputPipe )
    {
        if (!CreatePipe(&pipe_out[IN_FOR_PARENT],&pipe_out[OUT_FOR_PARENT],&saAttr, 0))
            goto err_pipe;
        /* The child must not inherit from the read side of the pipe_out */
        if (!SetHandleInformation(pipe_out[IN_FOR_PARENT],HANDLE_FLAG_INHERIT,0))
            goto err_pipe;
    }

    if( bCreateErrorPipe )
    {
        if (!CreatePipe(&pipe_err[IN_FOR_PARENT],&pipe_err[OUT_FOR_PARENT],&saAttr, 0))
            goto err_pipe;
        /* The child must not inherit from the read side of the pipe_err */
        if (!SetHandleInformation(pipe_err[IN_FOR_PARENT],HANDLE_FLAG_INHERIT,0))
            goto err_pipe;
    }

    memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION));
    memset(&siStartInfo, 0, sizeof(STARTUPINFO));
    siStartInfo.cb = sizeof(STARTUPINFO); 
    siStartInfo.hStdInput = (bCreateInputPipe) ? pipe_in[IN_FOR_PARENT] : GetStdHandle(STD_INPUT_HANDLE);
    siStartInfo.hStdOutput = (bCreateOutputPipe) ? pipe_out[OUT_FOR_PARENT] : GetStdHandle(STD_OUTPUT_HANDLE);
    siStartInfo.hStdError = (bCreateErrorPipe) ? pipe_err[OUT_FOR_PARENT] : GetStdHandle(STD_ERROR_HANDLE);
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

    for(i=0;papszArgv[i] != NULL;i++)
    {
        if (i > 0)
            osCommandLine += " ";
        /* We need to quote arguments with spaces in them (if not already done) */
        if( strchr(papszArgv[i], ' ') != NULL &&
            papszArgv[i][0] != '"' )
        {
            osCommandLine += "\"";
            osCommandLine += papszArgv[i];
            osCommandLine += "\"";
        }
        else
            osCommandLine += papszArgv[i];
    }

    if (!CreateProcess(NULL, 
                       (CHAR*)osCommandLine.c_str(),
                       NULL,          // process security attributes 
                       NULL,          // primary thread security attributes 
                       TRUE,          // handles are inherited 
                       CREATE_NO_WINDOW|NORMAL_PRIORITY_CLASS,             // creation flags 
                       NULL,          // use parent's environment 
                       NULL,          // use parent's current directory 
                       &siStartInfo,
                       &piProcInfo))
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Could not create process %s",
                 osCommandLine.c_str());
        goto err;
    }

    /* Close unused end of pipe */
    if( bCreateInputPipe )
        CloseHandle(pipe_in[IN_FOR_PARENT]);
    if( bCreateOutputPipe )
        CloseHandle(pipe_out[OUT_FOR_PARENT]);
    if( bCreateErrorPipe )
        CloseHandle(pipe_err[OUT_FOR_PARENT]);

    p = (CPLSpawnedProcess*)CPLMalloc(sizeof(CPLSpawnedProcess));
    p->hProcess = piProcInfo.hProcess;
    p->nProcessId = piProcInfo.dwProcessId;
    p->hThread = piProcInfo.hThread;
    p->fin = pipe_out[IN_FOR_PARENT];
    p->fout = pipe_in[OUT_FOR_PARENT];
    p->ferr = pipe_err[IN_FOR_PARENT];
    return p;

err_pipe:
    CPLError(CE_Failure, CPLE_AppDefined, "Could not create pipe");
err:
    for(i=0;i<2;i++)
    {
        if (pipe_in[i] != NULL)
            CloseHandle(pipe_in[i]);
        if (pipe_out[i] != NULL)
            CloseHandle(pipe_out[i]);
        if (pipe_err[i] != NULL)
            CloseHandle(pipe_err[i]);
    }

    return NULL;
}
Esempio n. 30
0
CPLErr OGRPGeoLayer::BuildFeatureDefn( const char *pszLayerName, 
                                       CPLODBCStatement *poStmt )

{
    poFeatureDefn = new OGRFeatureDefn( pszLayerName );
    int    nRawColumns = poStmt->GetColCount();

    poFeatureDefn->Reference();

    panFieldOrdinals = (int *) CPLMalloc( sizeof(int) * nRawColumns );

    for( int iCol = 0; iCol < nRawColumns; iCol++ )
    {
        OGRFieldDefn    oField( poStmt->GetColName(iCol), OFTString );

        oField.SetWidth( MAX(0,poStmt->GetColSize( iCol )) );

        if( pszGeomColumn != NULL 
            && EQUAL(poStmt->GetColName(iCol),pszGeomColumn) )
            continue;

        if( pszFIDColumn == NULL 
            && EQUAL(poStmt->GetColName(iCol),"OBJECTID") )
        {
            pszFIDColumn = CPLStrdup(poStmt->GetColName(iCol));
        }

        if( pszGeomColumn == NULL 
            && EQUAL(poStmt->GetColName(iCol),"Shape") )
        {
            pszGeomColumn = CPLStrdup(poStmt->GetColName(iCol));
            continue;
        }
        
        switch( poStmt->GetColType(iCol) )
        {
          case SQL_INTEGER:
          case SQL_SMALLINT:
            oField.SetType( OFTInteger );
            break;

          case SQL_BINARY:
          case SQL_VARBINARY:
          case SQL_LONGVARBINARY:
            oField.SetType( OFTBinary );
            break;

          case SQL_DECIMAL:
            oField.SetType( OFTReal );
            oField.SetPrecision( poStmt->GetColPrecision(iCol) );
            break;

          case SQL_FLOAT:
          case SQL_REAL:
          case SQL_DOUBLE:
            oField.SetType( OFTReal );
            oField.SetWidth( 0 );
            break;

          case SQL_C_DATE:
            oField.SetType( OFTDate );
            break;

          case SQL_C_TIME:
            oField.SetType( OFTTime );
            break;

          case SQL_C_TIMESTAMP:
            oField.SetType( OFTDateTime );
            break;

          default:
            /* leave it as OFTString */;
        }

        poFeatureDefn->AddFieldDefn( &oField );
        panFieldOrdinals[poFeatureDefn->GetFieldCount() - 1] = iCol+1;
    }

    return CE_None;
}