Exemplo n.º 1
0
/**********************************************************************
 *                   IMapInfoFile::SmartOpen()
 *
 * Use this static method to automatically open any flavor of MapInfo
 * dataset.  This method will detect the file type, create an object
 * of the right type, and open the file.
 *
 * Call GetFileClass() on the returned object if you need to find out
 * its exact type.  (To access format-specific methods for instance)
 *
 * Returns the new object ptr. , or NULL if the open failed.
 **********************************************************************/
IMapInfoFile *IMapInfoFile::SmartOpen(const char *pszFname,
                                      GBool bUpdate,
                                      GBool bTestOpenNoError /*=FALSE*/)
{
    IMapInfoFile *poFile = nullptr;
    int nLen = 0;

    if (pszFname)
        nLen = static_cast<int>(strlen(pszFname));

    if (nLen > 4 && (EQUAL(pszFname + nLen-4, ".MIF") ||
                     EQUAL(pszFname + nLen-4, ".MID") ) )
    {
        /*-------------------------------------------------------------
         * MIF/MID file
         *------------------------------------------------------------*/
        poFile = new MIFFile;
    }
    else if (nLen > 4 && EQUAL(pszFname + nLen-4, ".TAB"))
    {
        /*-------------------------------------------------------------
         * .TAB file ... is it a TABFileView or a TABFile?
         * We have to read the .tab header to find out.
         *------------------------------------------------------------*/
        char *pszAdjFname = CPLStrdup(pszFname);
        GBool bFoundFields = FALSE;
        GBool bFoundView = FALSE;
        GBool bFoundSeamless = FALSE;

        TABAdjustFilenameExtension(pszAdjFname);
        VSILFILE *fp = VSIFOpenL(pszAdjFname, "r");
        const char *pszLine = nullptr;
        while(fp && (pszLine = CPLReadLineL(fp)) != nullptr)
        {
            while (isspace(static_cast<unsigned char>(*pszLine)))  pszLine++;
            if (STARTS_WITH_CI(pszLine, "Fields"))
                bFoundFields = TRUE;
            else if (STARTS_WITH_CI(pszLine, "create view"))
                bFoundView = TRUE;
            else if (STARTS_WITH_CI(pszLine, "\"\\IsSeamless\" = \"TRUE\""))
                bFoundSeamless = TRUE;
        }

        if (bFoundView)
            poFile = new TABView;
        else if (bFoundFields && bFoundSeamless)
            poFile = new TABSeamless;
        else if (bFoundFields)
            poFile = new TABFile;

        if (fp)
            VSIFCloseL(fp);

        CPLFree(pszAdjFname);
    }

    /*-----------------------------------------------------------------
     * Perform the open() call
     *----------------------------------------------------------------*/
    if (poFile && poFile->Open(pszFname, bUpdate ? TABReadWrite : TABRead, bTestOpenNoError) != 0)
    {
        delete poFile;
        poFile = nullptr;
    }

    if (!bTestOpenNoError && poFile == nullptr)
    {
        CPLError(CE_Failure, CPLE_FileIO,
                 "%s could not be opened as a MapInfo dataset.", pszFname);
    }

    return poFile;
}
Exemplo n.º 2
0
SURF_FETCH_E LandfireClient::FetchBoundingBox( double *bbox, double resolution,
                                               const char *filename,
                                               char **options )
{
    (void)resolution;
    if( NULL == filename )
    {
        return SURF_FETCH_E_BAD_INPUT;
    }

    /*
    ** We have an arbitrary limit on request size, 0.001 degrees
    */
    if( fabs( bbox[0] - bbox[2] ) < 0.001 || fabs( bbox[1] - bbox[3] ) < 0.001 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Bounding box too small, must be greater than " \
                  "0.001 x 0.001 degrees." );
        return SURF_FETCH_E_BAD_INPUT;
    }

    /*-----------------------------------------------------------------------------
     *  Local Variable Declarations
     *-----------------------------------------------------------------------------*/
    int i = 0;
    char *p;
    int nMaxTries = atoi( CPLGetConfigOption( "LCP_MAX_DOWNLOAD_TRIES", "40" ) );
    double dfWait = atof( CPLGetConfigOption( "LCP_DOWNLOAD_WAIT", "3" ) );
    const char *pszProduct = CPLStrdup( CSLFetchNameValue( options, "PRODUCT" ) );
    /*
    ** Stupidly simple heuristics to try to get the 'correct' product.
    */
    if( pszProduct == NULL || EQUAL( pszProduct, "" ) )
    {
        if( EQUAL( pszProduct, "" ) )
            CPLFree( (void*)pszProduct );
        std::string osDataPath = FindDataPath( "landfire.zip" );
        osDataPath = "/vsizip/" + osDataPath;
        const char *pszGeom;
        pszGeom = CPLSPrintf( "POLYGON((%lf %lf,%lf %lf,%lf %lf,%lf %lf,%lf %lf))",
                               bbox[1], bbox[0], bbox[3], bbox[0],
                               bbox[3], bbox[2], bbox[1], bbox[2],
                               bbox[1], bbox[0] );
        CPLDebug( "LCP_CLIENT", "Testing if %s contains %s", osDataPath.c_str(),
                  pszGeom );
        if( NinjaOGRContain( pszGeom, osDataPath.c_str(), "conus" ) )
        {
            pszProduct = CPLStrdup( "F4W21HZ" );
        }
        else if( NinjaOGRContain( pszGeom, osDataPath.c_str(), "ak" ) )
        {
            pszProduct = CPLStrdup( "F7C29HZ" );
        }
        else if( NinjaOGRContain( pszGeom, osDataPath.c_str(), "hi" ) )
        {
            pszProduct = CPLStrdup( "F4825HZ" );
        }
        /* Contiguous US */
        //if( bbox[0] < 52 && bbox[1] < -60 && bbox[2] > 22 && bbox[3] > -136 )
        //    pszProduct = CPLStrdup( "F4W21HZ" );
        /* Alaska */
        //else if( bbox[0] < 75 && bbox[1] < -125 && bbox[2] > 50 && bbox[3] > -179 )
        //    pszProduct = CPLStrdup( "F7C29HZ" );
        /* Hawaii */
        //else if( bbox[0] < 25 && bbox[1] < -150 && bbox[2] > 15 && bbox[3] > -170 )
        //    pszProduct = CPLStrdup( "F4825HZ" );
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Failed to locate product." );
            return SURF_FETCH_E_BAD_INPUT;
        }
    }
    CPLDebug( "LCP_CLIENT", "Using product: %s", pszProduct );
    const char *pszUrl;

    const char *pszTemp = CSLFetchNameValue( options, "OVERRIDE_BEST_UTM" );
    int nEpsgCode = -1;
    if( pszTemp == NULL )
    {
        nEpsgCode = BoundingBoxUtm( bbox );
    }
    else
    {
        nEpsgCode = atoi( pszTemp );
    }
    /*
    ** Better check?
    */
    if( nEpsgCode < 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined, "Invalid EPSG code." );
        CPLFree( (void*)pszProduct );
        return SURF_FETCH_E_BAD_INPUT;
    }

    /*-----------------------------------------------------------------------------
     *  Request a Model via the landfire.cr.usgs.gov REST client
     *-----------------------------------------------------------------------------*/
    pszUrl = CPLSPrintf( LF_REQUEST_TEMPLATE, bbox[0], bbox[2], bbox[3],
                                              bbox[1], pszProduct );

    CPLFree( (void*)pszProduct );
    m_poResult = CPLHTTPFetch( pszUrl, NULL );
    CHECK_HTTP_RESULT( "Failed to get download URL" );
    CPLDebug( "LCP_CLIENT", "Request URL: %s", pszUrl );
     /*-----------------------------------------------------------------------------
     *  Parse the JSON result of the request
     *-----------------------------------------------------------------------------*/
    int nSize = strlen( (char*) m_poResult->pabyData );
    //Create a buffer so we can use sscanf, couldn't find a CPL version
    char *pszResponse = new char[ nSize + 1 ];
    pszResponse[0] = '\0';

    CPLDebug( "LCP_CLIENT", "JSON Response: %s", m_poResult->pabyData );

    /*
    ** Regular expression support if we have C++11 support.  isnan ambiguouity
    ** is causing non-C++11 compliance.  Not tested or used, 0 disables.
    */
#if __cplusplus >= 201103 && 0
    std::string s((const char*) m_poResult->pabyData );
    std::smatch m;
    std::regex e( "\\b(?:(?:https?)://|www\\.)[a-z-A-Z0-9+&@#/%=~_|$?!:,.]" \
                  "*[a-z-A-Z0-9+&@#/%=~_|$]" );
    std::regex_search( s, m, e );
    std::string url = m[0].str(); //retrieve first match
    CPLStrlcpy( pszResponse, url.c_str(), nSize );
#else
    char **papszTokens = NULL;
    papszTokens = CSLTokenizeString2( (const char*)m_poResult->pabyData, ",:",
                                      CSLT_HONOURSTRINGS | CSLT_PRESERVEESCAPES |
                                      CSLT_STRIPENDSPACES | CSLT_STRIPLEADSPACES );
    int nTokens = CSLCount( papszTokens );
    if( nTokens < 2 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to generate valid URL for LCP download." );
        delete [] pszResponse;
        CPLHTTPDestroyResult( m_poResult );
        CSLDestroy( papszTokens );
        return SURF_FETCH_E_IO_ERR;
    }
    for( int i = 1; i < nTokens; i++ )
    {
        if( EQUALN( papszTokens[i], "https://", 6 ) &&
            EQUAL( papszTokens[i - 1], "DOWNLOAD_URL" ) )
        {
            CPLStrlcpy( pszResponse, papszTokens[i], nSize );
            break;
        }
    }
    CSLDestroy( papszTokens );
#endif
    //Grab the download URL from the JSON response, stores in pszResponse
    //std::sscanf( (char*) m_poResult->pabyData, LF_REQUEST_RETURN_TEMPLATE, pszResponse);
    CPLHTTPDestroyResult( m_poResult );

    if( !EQUALN( pszResponse, "https://", 6 ) )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to generate valid URL for LCP download." );
        delete  [] pszResponse;
        return SURF_FETCH_E_IO_ERR;
    }
    p = strstr( pszResponse, "}]" );
    if( p )
        *p = '\0';
    CPLDebug( "LCP_CLIENT", "Download URL: %s", pszResponse );
    // Fix the SRS
    const char *pszNewUrl = ReplaceSRS( nEpsgCode, pszResponse );
    CPLDebug( "LCP_CLIENT", "Sanitized SRS Download URL: %s", pszNewUrl );
    /*-----------------------------------------------------------------------------
     *  Get the Job ID by visiting the download URL
     *-----------------------------------------------------------------------------*/
    m_poResult = CPLHTTPFetch( pszNewUrl, NULL );
    CPLFree( (void*)pszNewUrl );
    delete [] pszResponse;
    CHECK_HTTP_RESULT( "Failed to get Job ID" );   

    nSize = strlen( (char*) m_poResult->pabyData );
    pszResponse = new char[ nSize + 1 ];

    //grabs the Job ID from the Download URL response
    std::sscanf( (char*) m_poResult->pabyData, LF_INIT_RESPONSE_TEMPLATE, pszResponse);
    CPLHTTPDestroyResult( m_poResult );
   //store the Job Id into a class attribute, so we can reuse pszResponse, but keep
    //the Job Id (needed for future parts)
    m_JobId = std::string( pszResponse );
    CPLDebug( "LCP_CLIENT", "Job id: %s", m_JobId.c_str() );
    /*-----------------------------------------------------------------------------
     * Initiate the download by using the obtained Job ID 
     *-----------------------------------------------------------------------------*/
    pszUrl = CPLSPrintf( LF_INIT_DOWNLOAD_TEMPLATE, m_JobId.c_str() );

    //fetch the response of download initiation
    //note: for some reason it alway returns a key error, but download still works
    m_poResult = CPLHTTPFetch( pszUrl, NULL );
    CPLHTTPDestroyResult( m_poResult );
    /*-----------------------------------------------------------------------------
     *  Check the status of the download, able to download when status=400
     *-----------------------------------------------------------------------------*/
    int dl_status = 0;
    //Obtain the readiness status of the current job
    pszUrl = CPLSPrintf( LF_GET_STATUS_TEMPLATE, m_JobId.c_str() );
    CPLDebug( "LCP_CLIENT", "Status url: %s", pszUrl );
    do
    {
        m_poResult = CPLHTTPFetch( pszUrl, NULL );
        delete [] pszResponse;
        CHECK_HTTP_RESULT( "Failed to get job status" );

        nSize = strlen( (char*) m_poResult->pabyData );
        pszResponse = new char[ nSize + 1 ];

        std::sscanf( (char*) m_poResult->pabyData, LF_STATUS_RESPONSE_TEMPLATE,
                      &dl_status, pszResponse );
        CPLHTTPDestroyResult( m_poResult );
        i++;
        CPLSleep( dfWait );
        CPLDebug( "LCP_CLIENT", "Attempting to fetch LCP, try %d of %d, " \
                               "status: %d", i, nMaxTries, dl_status );
    } while( dl_status < 400 && dl_status > 0 && i < nMaxTries );

    delete [] pszResponse;

    if( dl_status >= 900 && dl_status <= 902)
    {
        CPLError( CE_Warning, CPLE_AppDefined, "Failed to download lcp," \
                                               "There was an extraction " \
                                               "error on the server." );
        return SURF_FETCH_E_IO_ERR;
    }
    else if( dl_status != 400 )
    {
        CPLError( CE_Warning, CPLE_AppDefined, "Failed to download lcp, timed " \
                                               "out.  Try increasing " \
                                               "LCP_MAX_DOWNLOAD_TRIES or "
                                               "LCP_DOWNLOAD_WAIT" );
        return SURF_FETCH_E_TIMEOUT;
    }
    /*-----------------------------------------------------------------------------
     *  Download the landfire model
     *-----------------------------------------------------------------------------*/
    pszUrl = CPLSPrintf( LF_DOWNLOAD_JOB_TEMPLATE, m_JobId.c_str() );
    m_poResult = CPLHTTPFetch( pszUrl, NULL );
    CHECK_HTTP_RESULT( "Failed to get job status" ); 

    /*
    ** Parse the URL from the returned string
    */
    std::string ss((const char*) m_poResult->pabyData );
    CPLHTTPDestroyResult( m_poResult );
    std::size_t pos1 = ss.find("https://");
    std::size_t pos2 = ss.find(".zip");
    std::string url = ss.substr(pos1, (pos2+4-pos1));
    pszUrl = url.c_str();
    m_poResult = CPLHTTPFetch( pszUrl, NULL );
    CHECK_HTTP_RESULT( "Failed to get job status" );

    nSize = m_poResult->nDataLen;
    VSILFILE *fout;
    const char *pszTmpZip = CPLFormFilename( NULL, 
                                             CPLGenerateTempFilename( "NINJA_LCP_CLIENT" ),
                                             ".zip" );
    fout = VSIFOpenL( pszTmpZip, "w+" );
    if( NULL == fout )
    {
        CPLError( CE_Warning, CPLE_AppDefined, "Failed to create output file" );
        CPLHTTPDestroyResult( m_poResult );
        return SURF_FETCH_E_IO_ERR;
    }
    VSIFWriteL( m_poResult->pabyData, nSize, 1, fout );
    VSIFCloseL( fout );

    CPLHTTPDestroyResult( m_poResult );

    /*
    ** Extract the lcp and the prj file, and 'save as'
    */
    char **papszFileList = NULL;
    std::string osPathInZip;
    const char *pszVSIZip = CPLSPrintf( "/vsizip/%s", pszTmpZip );
    CPLDebug( "LCP_CLIENT", "Extracting lcp from %s", pszVSIZip );
    papszFileList = VSIReadDirRecursive( pszVSIZip );
    int bFound = FALSE;
    std::string osFullPath;
    for( int i = 0; i < CSLCount( papszFileList ); i++ )
    {
        osFullPath = papszFileList[i];
        if( osFullPath.find( "Landscape_1.lcp" ) != std::string::npos )
        {
            osPathInZip = CPLGetPath( papszFileList[i] );
            CPLDebug( "LCP_CLIENT", "Found lcp in: %s", osPathInZip.c_str() );
            bFound = TRUE;
            break;
        }
    }
    CSLDestroy( papszFileList );
    if( !bFound )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to find lcp in archive" );
        //VSIUnlink( pszTmpZip );
        return SURF_FETCH_E_IO_ERR;
    }
    int nError = 0;
    const char *pszFileToFind = CPLSPrintf( "%s/Landscape_1.lcp",
                                            osPathInZip.c_str() );
    nError = ExtractFileFromZip( pszTmpZip, pszFileToFind, filename );
    if( nError )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to extract LCP from zip." );
        VSIUnlink( pszTmpZip );
        return SURF_FETCH_E_IO_ERR;
    }
    pszFileToFind = CPLSPrintf( "%s/Landscape_1.prj", osPathInZip.c_str() );
    nError = ExtractFileFromZip( pszTmpZip, pszFileToFind,
                                 CPLFormFilename( CPLGetPath( filename ),
                                                  CPLGetBasename( filename ),
                                                  ".prj" ) );
    if( nError )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to extract PRJ from zip." );
        return SURF_FETCH_E_IO_ERR;
    }

    if( !CSLTestBoolean( CPLGetConfigOption( "LCP_KEEP_ARCHIVE", "FALSE" ) ) )
    {
        VSIUnlink( pszTmpZip );
    }

    return SURF_FETCH_E_NONE;
}
Exemplo n.º 3
0
GDALDataset *GSAGDataset::CreateCopy( const char *pszFilename,
				      GDALDataset *poSrcDS,
				      int bStrict, char **papszOptions,
				      GDALProgressFunc pfnProgress,
				      void *pProgressData )
{
    if( pfnProgress == NULL )
	pfnProgress = GDALDummyProgress;

    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GSAG driver does not support source dataset with zero band.\n");
        return NULL;
    }
    else if (nBands > 1)
    {
	if( bStrict )
	{
	    CPLError( CE_Failure, CPLE_NotSupported,
		      "Unable to create copy, Golden Software ASCII Grid "
		      "format only supports one raster band.\n" );
	    return NULL;
	}
	else
	    CPLError( CE_Warning, CPLE_NotSupported,
		      "Golden Software ASCII Grid format only supports one "
		      "raster band, first band will be copied.\n" );
    }

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" );
        return NULL;
    }

    VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" );

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

    int          nXSize = poSrcDS->GetRasterXSize();
    int          nYSize = poSrcDS->GetRasterYSize();
    double	 adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    std::ostringstream ssHeader;
    ssHeader.precision( nFIELD_PRECISION );
    ssHeader.setf( std::ios::uppercase );

    ssHeader << "DSAA\x0D\x0A";

    ssHeader << nXSize << " " << nYSize << "\x0D\x0A";

    ssHeader << adfGeoTransform[0] + adfGeoTransform[1] / 2 << " "
	     << adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0]
	     << "\x0D\x0A";

    ssHeader << adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3] << " "
	     << adfGeoTransform[3] + adfGeoTransform[5] / 2
	     << "\x0D\x0A";

    if( VSIFWriteL( (void *)ssHeader.str().c_str(), 1, ssHeader.str().length(),
		    fp ) != ssHeader.str().length() )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to create copy, writing header failed.\n" );
        return NULL;
    }

    /* Save the location and write placeholders for the min/max Z value */
    vsi_l_offset nRangeStart = VSIFTellL( fp );
    const char *szDummyRange = "0.0000000000001 0.0000000000001\x0D\x0A";
    size_t nDummyRangeLen = strlen( szDummyRange );
    if( VSIFWriteL( (void *)szDummyRange, 1, nDummyRangeLen,
		    fp ) != nDummyRangeLen )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to create copy, writing header failed.\n" );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Copy band data.							*/
/* -------------------------------------------------------------------- */
    double *pdfData = (double *)VSIMalloc2( nXSize, sizeof( double ) );
    if( pdfData == NULL )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to create copy, unable to allocate line buffer.\n" );
	return NULL;
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand(1);
    int bSrcHasNDValue;
    double dfSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue );
    double dfMin = DBL_MAX;
    double dfMax = -DBL_MAX;
    for( int iRow=0; iRow<nYSize; iRow++ )
    {
	CPLErr eErr = poSrcBand->RasterIO( GF_Read, 0, nYSize-iRow-1,
					   nXSize, 1, pdfData,
					   nXSize, 1, GDT_Float64, 0, 0 );

	if( eErr != CE_None )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    return NULL;
	}

	for( int iCol=0; iCol<nXSize; )
	{
	    for( int iCount=0;
		 iCount<10 && iCol<nXSize;
		 iCount++, iCol++ )
	    {
		double dfValue = pdfData[iCol];

		if( bSrcHasNDValue && AlmostEqual( dfValue, dfSrcNoDataValue ) )
		{
		    dfValue = dfNODATA_VALUE;
		}
		else
		{
		    if( dfValue > dfMax )
			dfMax = dfValue;

		    if( dfValue < dfMin )
			dfMin = dfValue;
		}

		std::ostringstream ssOut;
		ssOut.precision(nFIELD_PRECISION);
		ssOut.setf( std::ios::uppercase );
		ssOut << dfValue << " ";
		CPLString sOut = ssOut.str();

		if( VSIFWriteL( sOut.c_str(), 1, sOut.length(), fp )
		    != sOut.length() )
		{
		    VSIFCloseL( fp );
		    VSIFree( pdfData );
		    CPLError( CE_Failure, CPLE_FileIO,
			      "Unable to write grid cell.  Disk full?\n" );
		    return NULL;
		}
	    }

	    if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 )
	    {
		VSIFCloseL( fp );
		VSIFree( pdfData );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to finish write of grid line. Disk full?\n" );
		return NULL;
	    }
	}

	if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to finish write of grid row. Disk full?\n" );
	    return NULL;
	}

	if( !pfnProgress( static_cast<double>(iRow + 1)/nYSize,
			  NULL, pProgressData ) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
	    return NULL;
	}
    }

    VSIFree( pdfData );

    /* write out the min and max values */
    std::ostringstream ssRange;
    ssRange.precision( nFIELD_PRECISION );
    ssRange.setf( std::ios::uppercase );
    ssRange << dfMin << " " << dfMax << "\x0D\x0A";
    if( ssRange.str().length() != nDummyRangeLen )
    {
	int nShiftSize = ssRange.str().length() - nDummyRangeLen;
	if( ShiftFileContents( fp, nRangeStart + nDummyRangeLen,
			       nShiftSize, "\x0D\x0A" ) != CE_None )
	{
	    VSIFCloseL( fp );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to shift file contents.\n" );
	    return NULL;
	}
    }

    if( VSIFSeekL( fp, nRangeStart, SEEK_SET ) != 0 )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to seek to start of grid file copy.\n" );
	return NULL;
    }

    if( VSIFWriteL( (void *)ssRange.str().c_str(), 1, ssRange.str().length(),
		    fp ) != ssRange.str().length() )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to write range information.\n" );
        return NULL;
    }

    VSIFCloseL( fp );

    GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename,
                                                GA_Update );
    if (poDS)
    {
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
    }
    return poDS;
}
Exemplo n.º 4
0
GDALDataset *E00GRIDDataset::Open( GDALOpenInfo * poOpenInfo )

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

/* -------------------------------------------------------------------- */
/*      Find dataset characteristics                                    */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = poOpenInfo->fpL;
    poOpenInfo->fpL = nullptr;

    if (poOpenInfo->eAccess == GA_Update)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The E00GRID driver does not support update access to existing"
                  " datasets.\n" );
        VSIFCloseL(fp);
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    E00GRIDDataset *poDS = new E00GRIDDataset();
    if (strstr((const char*)poOpenInfo->pabyHeader, "\r\n") != nullptr)
        poDS->nBytesEOL = 2;
    poDS->fp = fp;

    /* read EXP  0 or EXP  1 line */
    const char* pszLine = CPLReadLine2L(fp, 81, nullptr);
    if (pszLine == nullptr)
    {
        CPLDebug("E00GRID", "Bad 1st line");
        delete poDS;
        return nullptr;
    }
    bool bCompressed = STARTS_WITH_CI(pszLine, "EXP  1");

    E00ReadPtr e00ReadPtr = nullptr;
    if (bCompressed)
    {
        VSIRewindL(fp);
        e00ReadPtr = E00ReadCallbackOpen(poDS,
                                         E00GRIDDataset::ReadNextLine,
                                         E00GRIDDataset::Rewind);
        if (e00ReadPtr == nullptr)
        {
            delete poDS;
            return nullptr;
        }
        E00ReadNextLine(e00ReadPtr);
        poDS->e00ReadPtr = e00ReadPtr;
    }

    /* skip GRD  2 line */
    if (e00ReadPtr)
        pszLine = E00ReadNextLine(e00ReadPtr);
    else
        pszLine = CPLReadLine2L(fp, 81, nullptr);
    if (pszLine == nullptr || !STARTS_WITH_CI(pszLine, "GRD  2"))
    {
        CPLDebug("E00GRID", "Bad 2nd line");
        delete poDS;
        return nullptr;
    }

    /* read ncols, nrows and nodata value */
    if (e00ReadPtr)
        pszLine = E00ReadNextLine(e00ReadPtr);
    else
        pszLine = CPLReadLine2L(fp, 81, nullptr);
    if (pszLine == nullptr || strlen(pszLine) <
                E00_INT_SIZE+E00_INT_SIZE+2+E00_DOUBLE_SIZE)
    {
        CPLDebug("E00GRID", "Bad 3rd line");
        delete poDS;
        return nullptr;
    }

    const int nRasterXSize = atoi(pszLine);
    const int nRasterYSize = atoi(pszLine + E00_INT_SIZE);

    if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize) ||
        /* ASCII format. Huge rasters do not make sense */
        nRasterXSize > 100000 ||
        nRasterYSize > 100000 )
    {
        delete poDS;
        return nullptr;
    }

    GDALDataType eDT = GDT_Float32;

    if (STARTS_WITH_CI(pszLine + E00_INT_SIZE + E00_INT_SIZE, " 1"))
        eDT = GDT_Int32;
    else if (STARTS_WITH_CI(pszLine + E00_INT_SIZE + E00_INT_SIZE, " 2"))
        eDT = GDT_Float32;
    else
    {
        CPLDebug("E00GRID", "Unknown data type : %s", pszLine);
    }

    const double dfNoData = CPLAtof(pszLine + E00_INT_SIZE + E00_INT_SIZE + 2);

    /* read pixel size */
    if (e00ReadPtr)
        pszLine = E00ReadNextLine(e00ReadPtr);
    else
        pszLine = CPLReadLine2L(fp, 81, nullptr);
    if (pszLine == nullptr || strlen(pszLine) < 2*E00_DOUBLE_SIZE)
    {
        CPLDebug("E00GRID", "Bad 4th line");
        delete poDS;
        return nullptr;
    }
/*
    double dfPixelX = CPLAtof(pszLine);
    double dfPixelY = CPLAtof(pszLine + E00_DOUBLE_SIZE);
*/

    /* read xmin, ymin */
    if (e00ReadPtr)
        pszLine = E00ReadNextLine(e00ReadPtr);
    else
        pszLine = CPLReadLine2L(fp, 81, nullptr);
    if (pszLine == nullptr || strlen(pszLine) < 2*E00_DOUBLE_SIZE)
    {
        CPLDebug("E00GRID", "Bad 5th line");
        delete poDS;
        return nullptr;
    }
    const double dfMinX = CPLAtof(pszLine);
    const double dfMinY = CPLAtof(pszLine + E00_DOUBLE_SIZE);

    /* read xmax, ymax */
    if (e00ReadPtr)
        pszLine = E00ReadNextLine(e00ReadPtr);
    else
        pszLine = CPLReadLine2L(fp, 81, nullptr);
    if (pszLine == nullptr || strlen(pszLine) < 2*E00_DOUBLE_SIZE)
    {
        CPLDebug("E00GRID", "Bad 6th line");
        delete poDS;
        return nullptr;
    }
    const double dfMaxX = CPLAtof(pszLine);
    const double dfMaxY = CPLAtof(pszLine + E00_DOUBLE_SIZE);

    poDS->nRasterXSize = nRasterXSize;
    poDS->nRasterYSize = nRasterYSize;
    poDS->dfNoData = dfNoData;
    poDS->adfGeoTransform[0] = dfMinX;
    poDS->adfGeoTransform[1] = (dfMaxX - dfMinX) / nRasterXSize;
    poDS->adfGeoTransform[2] = 0;
    poDS->adfGeoTransform[3] = dfMaxY;
    poDS->adfGeoTransform[4] = 0;
    poDS->adfGeoTransform[5] = - (dfMaxY - dfMinY) / nRasterYSize;
    poDS->nDataStart = VSIFTellL(fp);
    if (bCompressed)
    {
        poDS->panOffsets = (vsi_l_offset*)
                        VSIMalloc2(sizeof(vsi_l_offset), nRasterYSize);
        if (poDS->panOffsets == nullptr)
        {
            delete poDS;
            return nullptr;
        }
    }
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 1;
    for( int i = 0; i < poDS->nBands; i++ )
        poDS->SetBand( i+1, new E00GRIDRasterBand( poDS, i+1, eDT ) );

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

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
    return poDS;
}
Exemplo n.º 5
0
OGRLayer * OGRSQLiteExecuteSQL( GDALDataset* poDS,
                                const char *pszStatement,
                                OGRGeometry *poSpatialFilter,
                                CPL_UNUSED const char *pszDialect )
{
    char* pszTmpDBName = (char*) CPLMalloc(256);
    snprintf(pszTmpDBName, 256, "/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 significant cost. So at the first attempt, let's make     */
/*      one and cache it for later use.                                 */
/* -------------------------------------------------------------------- */
#if 1
    static size_t nEmptyDBSize = 0;
    static GByte* pabyEmptyDB = NULL;
    {
        static CPLMutex* hMutex = NULL;
        CPLMutexHolder oMutexHolder(&hMutex);
        static int bTried = FALSE;
        if( !bTried &&
            CPLTestBool(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) )
        {
            bTried = TRUE;
            char* pszCachedFilename = (char*) CPLMalloc(256);
            snprintf(pszCachedFilename, 256, "/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() */
                vsi_l_offset nEmptyDBSizeLarge = 0;
                pabyEmptyDB = VSIGetMemFileBuffer( pszCachedFilename, &nEmptyDBSizeLarge, FALSE );
                nEmptyDBSize = static_cast<size_t>(nEmptyDBSizeLarge);
            }
            CPLFree( pszCachedFilename );
        }
    }

    /* The following configuration option is useful mostly for debugging/testing */
    if( pabyEmptyDB != NULL && CPLTestBool(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) )
    {
        GByte* pabyEmptyDBClone = (GByte*)VSI_MALLOC_VERBOSE(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.               */
/* -------------------------------------------------------------------- */
    OGRLayer* poSingleSrcLayer = NULL;
    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);
        }

        if( oSetLayers.size() == 1 )
            poSingleSrcLayer = poLayer;

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

        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, -1,
                              &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( !STARTS_WITH_CI(pszStatement, "SELECT ") )
        {

            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 );

    if( poSingleSrcLayer != NULL )
        poLayer->SetMetadata( poSingleSrcLayer->GetMetadata( "NATIVE_DATA" ),
                              "NATIVE_DATA" );

    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;
}
Exemplo n.º 6
0
GDALDataset *CTable2Dataset::Create( const char * pszFilename,
                                     int nXSize, int nYSize, int nBands,
                                     GDALDataType eType,
                                     char ** papszOptions )

{
    if( eType != GDT_Float32 )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Attempt to create CTable2 file with unsupported data type '%s'.",
                 GDALGetDataTypeName( eType ) );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Try to open or create file.                                     */
/* -------------------------------------------------------------------- */
    VSILFILE	*fp;

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

/* -------------------------------------------------------------------- */
/*      Create a file header, with a defaulted georeferencing.          */
/* -------------------------------------------------------------------- */
    char achHeader[160];
    int nValue32;
    double dfValue;

    memset( achHeader, 0, sizeof(achHeader));

    memcpy( achHeader+0, "CTABLE V2.0     ", 16 );
    
    if( CSLFetchNameValue( papszOptions, "DESCRIPTION" ) != NULL )
        strncpy( achHeader + 16, 
                 CSLFetchNameValue( papszOptions, "DESCRIPTION" ), 
                 80 );
    
    // lower left origin (longitude, center of pixel, radians)
    dfValue = 0;
    CPL_LSBPTR64( &dfValue );
    memcpy( achHeader + 96, &dfValue, 8 );

    // lower left origin (latitude, center of pixel, radians)
    dfValue = 0;
    CPL_LSBPTR64( &dfValue );
    memcpy( achHeader + 104, &dfValue, 8 );

    // pixel width (radians)
    dfValue = 0.01 * M_PI / 180.0;
    CPL_LSBPTR64( &dfValue );
    memcpy( achHeader + 112, &dfValue, 8 );

    // pixel height (radians)
    dfValue = 0.01 * M_PI / 180.0;
    CPL_LSBPTR64( &dfValue );
    memcpy( achHeader + 120, &dfValue, 8 );

    // raster width in pixels
    nValue32 = nXSize;
    CPL_LSBPTR32( &nValue32 );
    memcpy( achHeader + 128, &nValue32, 4 );

    // raster width in pixels
    nValue32 = nYSize;
    CPL_LSBPTR32( &nValue32 );
    memcpy( achHeader + 132, &nValue32, 4 );

    VSIFWriteL( achHeader, 1, sizeof(achHeader), fp );

/* -------------------------------------------------------------------- */
/*      Write zeroed grid data.                                         */
/* -------------------------------------------------------------------- */
    float *pafLine = (float *) CPLCalloc(sizeof(float)*2,nXSize);
    int i;

    for( i = 0; i < nYSize; i++ )
    {
        if( (int)VSIFWriteL( pafLine, sizeof(float)*2, nXSize, fp ) != nXSize ) 
        {
            CPLError( CE_Failure, CPLE_FileIO, 
                      "Write failed at line %d, perhaps the disk is full?",
                      i );
            return NULL;
        }
    }
    
/* -------------------------------------------------------------------- */
/*      Cleanup and return.                                             */
/* -------------------------------------------------------------------- */
    CPLFree( pafLine );

    VSIFCloseL( fp );

    return (GDALDataset *) GDALOpen( pszFilename, GA_Update );
}
Exemplo n.º 7
0
GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo )
{
/* -------------------------------------------------------------------- */
/*      Does this look like a CUBE or an IMAGE Primary Data Object?     */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) || poOpenInfo->fpL == nullptr )
        return nullptr;

    VSILFILE *fpQube = poOpenInfo->fpL;
    poOpenInfo->fpL = nullptr;

    ISIS2Dataset *poDS = new ISIS2Dataset();

    if( ! poDS->oKeywords.Ingest( fpQube, 0 ) )
    {
        VSIFCloseL( fpQube );
        delete poDS;
        return nullptr;
    }

    VSIFCloseL( fpQube );

/* -------------------------------------------------------------------- */
/*      We assume the user is pointing to the label (i.e. .lab) file.   */
/* -------------------------------------------------------------------- */
    // QUBE can be inline or detached and point to an image name
    // ^QUBE = 76
    // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image
    // ^QUBE = "ui31s015.img" - which implies no label or skip value

    const char *pszQube = poDS->GetKeyword( "^QUBE" );
    GUIntBig nQube = 0;
    int bByteLocation = FALSE;
    CPLString osTargetFile = poOpenInfo->pszFilename;

    if( pszQube[0] == '"' )
    {
        const CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename);
        CPLString osFilename = pszQube;
        poDS->CleanString( osFilename );
        osTargetFile = CPLFormCIFilename( osTPath, osFilename, nullptr );
        poDS->osExternalCube = osTargetFile;
    }
    else if( pszQube[0] == '(' )
    {
        const CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename);
        CPLString osFilename = poDS->GetKeywordSub("^QUBE",1,"");
        poDS->CleanString( osFilename );
        osTargetFile = CPLFormCIFilename( osTPath, osFilename, nullptr );
        poDS->osExternalCube = osTargetFile;

        nQube = atoi(poDS->GetKeywordSub("^QUBE",2,"1"));
        if( strstr(poDS->GetKeywordSub("^QUBE",2,"1"),"<BYTES>") != nullptr )
            bByteLocation = true;
    }
    else
    {
        nQube = atoi(pszQube);
        if( strstr(pszQube,"<BYTES>") != nullptr )
            bByteLocation = true;
    }

/* -------------------------------------------------------------------- */
/*      Check if file an ISIS2 header file?  Read a few lines of text   */
/*      searching for something starting with nrows or ncols.           */
/* -------------------------------------------------------------------- */

    /* -------------------------------------------------------------------- */
    /*      Checks to see if this is valid ISIS2 cube                       */
    /*      SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes  */
    /* -------------------------------------------------------------------- */
    const int s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 ));
    const int s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 ));
    const int s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 ));

    if( s_ix != 0 || s_iy != 0 || s_iz != 0 )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n"
                  "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n"
                  "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz );
        delete poDS;
        return nullptr;
    }

    /**************** end SUFFIX_ITEM check ***********************/

    /***********   Grab layout type (BSQ, BIP, BIL) ************/
    //  AXIS_NAME = (SAMPLE,LINE,BAND)
    /***********************************************************/

    char szLayout[10] = "BSQ"; //default to band seq.
    const char *value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" );
    if (EQUAL(value,"(SAMPLE,LINE,BAND)") )
        strcpy(szLayout,"BSQ");
    else if (EQUAL(value,"(BAND,LINE,SAMPLE)") )
        strcpy(szLayout,"BIP");
    else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") )
        strcpy(szLayout,"BSQ");
    else {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "%s layout not supported. Abort\n\n", value);
        delete poDS;
        return nullptr;
    }

    /***********   Grab samples lines band ************/
    const int nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1));
    const int nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2));
    const int nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3));

    /***********   Grab Qube record bytes  **********/
    const int record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES"));

    GUIntBig nSkipBytes = 0;
    if (nQube > 0 && bByteLocation )
        nSkipBytes = (nQube - 1);
    else if( nQube > 0 )
        nSkipBytes = (nQube - 1) * record_bytes;
    else
        nSkipBytes = 0;

    /***********   Grab samples lines band ************/
    char chByteOrder = 'M';  //default to MSB
    CPLString osCoreItemType = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" );
    if( (EQUAL(osCoreItemType,"PC_INTEGER")) ||
        (EQUAL(osCoreItemType,"PC_UNSIGNED_INTEGER")) ||
        (EQUAL(osCoreItemType,"PC_REAL")) ) {
        chByteOrder = 'I';
    }

    /********   Grab format type - isis2 only supports 8,16,32 *******/
    GDALDataType eDataType = GDT_Byte;
    bool bNoDataSet = false;
    double dfNoData = 0.0;

    int itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES",""));
    switch(itype) {
      case 1 :
        eDataType = GDT_Byte;
        dfNoData = NULL1;
        bNoDataSet = true;
        break;
      case 2 :
        if( strstr(osCoreItemType,"UNSIGNED") != nullptr )
        {
            dfNoData = 0;
            eDataType = GDT_UInt16;
        }
        else
        {
            dfNoData = NULL2;
            eDataType = GDT_Int16;
        }
        bNoDataSet = true;
        break;
      case 4 :
        eDataType = GDT_Float32;
        dfNoData = NULL3;
        bNoDataSet = true;
        break;
      case 8 :
        eDataType = GDT_Float64;
        dfNoData = NULL3;
        bNoDataSet = true;
        break;
      default :
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Itype of %d is not supported in ISIS 2.",
                  itype);
        delete poDS;
        return nullptr;
    }

    /***********   Grab Cellsize ************/
    double dfXDim = 1.0;
    double dfYDim = 1.0;

    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE");
    if (strlen(value) > 0 ) {
        // Convert km to m
        dfXDim = static_cast<float>( CPLAtof(value) * 1000.0 );
        dfYDim = static_cast<float>( CPLAtof(value) * 1000.0 * -1 );
    }

    /***********   Grab LINE_PROJECTION_OFFSET ************/
    double dfULYMap = 0.5;
    double yulcenter = 0.0;

    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET");
    if (strlen(value) > 0) {
        yulcenter = static_cast<float>( CPLAtof(value) );
        yulcenter = ((yulcenter) * dfYDim);
        dfULYMap = yulcenter - (dfYDim/2);
    }

    /***********   Grab SAMPLE_PROJECTION_OFFSET ************/
    double dfULXMap = 0.5;
    double xulcenter = 0.0;

    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET");
    if( strlen(value) > 0 ) {
        xulcenter= static_cast<float>( CPLAtof(value) );
        xulcenter = ((xulcenter) * dfXDim);
        dfULXMap = xulcenter - (dfXDim/2);
    }

    /***********  Grab TARGET_NAME  ************/
    /**** This is the planets name i.e. MARS ***/
    CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME");

    /***********   Grab MAP_PROJECTION_TYPE ************/
    CPLString map_proj_name =
        poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE");
    poDS->CleanString( map_proj_name );

    /***********   Grab SEMI-MAJOR ************/
    const double semi_major =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0;

    /***********   Grab semi-minor ************/
    const double semi_minor =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0;

    /***********   Grab CENTER_LAT ************/
    const double center_lat =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE"));

    /***********   Grab CENTER_LON ************/
    const double center_lon =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE"));

    /***********   Grab 1st std parallel ************/
    const double first_std_parallel =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL"));

    /***********   Grab 2nd std parallel ************/
    const double second_std_parallel =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL"));

    /*** grab  PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/
    // Need to further study how ocentric/ographic will effect the gdal library.
    // So far we will use this fact to define a sphere or ellipse for some projections
    // Frank - may need to talk this over
    bool bIsGeographic = true;
    value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE");
    if (EQUAL( value, "\"PLANETOCENTRIC\"" ))
        bIsGeographic = false;

    CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() );

    OGRSpatialReference oSRS;
    bool bProjectionSet = true;

    //Set oSRS projection and parameters
    if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) ||
        (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ||
        (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) {
        oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 );
    } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) {
        oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 );
    } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) ||
               (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) {
        oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "MERCATOR" )) {
        oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) {
        oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) {
        oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) {
        oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "") ) {
        /* no projection */
        bProjectionSet = false;
    } else {
        CPLDebug( "ISIS2",
                  "Dataset projection %s is not supported. Continuing...",
                  map_proj_name.c_str() );
        bProjectionSet = false;
    }

    if (bProjectionSet) {
        //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword
        const CPLString proj_target_name = map_proj_name + " " + target_name;
        oSRS.SetProjCS(proj_target_name); //set ProjCS keyword

        //The geographic/geocentric name will be the same basic name as the body name
        //'GCS' = Geographic/Geocentric Coordinate System
        const CPLString geog_name = "GCS_" + target_name;

        //The datum and sphere names will be the same basic name aas the planet
        const CPLString datum_name = "D_" + target_name;
        // Might not be IAU defined so don't add.
        CPLString sphere_name = target_name; // + "_IAU_IAG");

        //calculate inverse flattening from major and minor axis: 1/f = a/(a-b)
        double iflattening = 0.0;
        if ((semi_major - semi_minor) < 0.0000001)
            iflattening = 0;
        else
            iflattening = semi_major / (semi_major - semi_minor);

        //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility
        //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally
        if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) ||
             (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )))
        {
            if (bIsGeographic) {
                //Geograpraphic, so set an ellipse
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening,
                                "Reference_Meridian", 0.0 );
            } else {
                //Geocentric, so force a sphere using the semi-minor axis. I hope...
                sphere_name += "_polarRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_minor, 0.0,
                                "Reference_Meridian", 0.0 );
            }
        }
        else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ||
                  (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) ||
                  (EQUAL( map_proj_name, "STEREOGRAPHIC" )) ||
                  (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) ||
                  (EQUAL( map_proj_name, "SINUSOIDAL" ))  ) {
            // ISIS uses the spherical equation for these projections so force
            // a sphere.
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            semi_major, 0.0,
                            "Reference_Meridian", 0.0 );
        }
        else if  ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) ||
                  (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) {
            //Calculate localRadius using ISIS3 simple elliptical method
            //  not the more standard Radius of Curvature method
            //PI = 4 * atan(1);
            if (center_lon == 0) { //No need to calculate local radius
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0,
                                "Reference_Meridian", 0.0 );
            } else {
                const double radLat = center_lat * M_PI / 180;  // in radians
                const double localRadius
                    = semi_major * semi_minor
                    / sqrt(pow(semi_minor*cos(radLat),2)
                           + pow(semi_major*sin(radLat),2) );
                sphere_name += "_localRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                localRadius, 0.0,
                                "Reference_Meridian", 0.0 );
                CPLDebug( "ISIS2", "local radius: %f", localRadius);
            }
        }
        else {
            //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc.
            //Geographic, so set an ellipse
            if (bIsGeographic) {
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening,
                                "Reference_Meridian", 0.0 );
            } else {
                //Geocentric, so force a sphere. I hope...
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0,
                                "Reference_Meridian", 0.0 );
            }
        }

        // translate back into a projection string.
        char *pszResult = nullptr;
        oSRS.exportToWkt( &pszResult );
        poDS->osProjection = pszResult;
        CPLFree( pszResult );
    }

/* END ISIS2 Label Read */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

/* -------------------------------------------------------------------- */
/*      Did we get the required keywords?  If not we return with        */
/*      this never having been considered to be a match. This isn't     */
/*      an error!                                                       */
/* -------------------------------------------------------------------- */
    if( !GDALCheckDatasetDimensions(nCols, nRows) ||
        !GDALCheckBandCount(nBands, false) )
    {
        delete poDS;
        return nullptr;
    }

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

/* -------------------------------------------------------------------- */
/*      Open target binary file.                                        */
/* -------------------------------------------------------------------- */

    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fpImage = VSIFOpenL( osTargetFile, "rb" );
    else
        poDS->fpImage = VSIFOpenL( osTargetFile, "r+b" );

    if( poDS->fpImage == nullptr )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to open %s with write permission.\n%s",
                  osTargetFile.c_str(), VSIStrerror( errno ) );
        delete poDS;
        return nullptr;
    }

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Compute the line offset.                                        */
/* -------------------------------------------------------------------- */
    int nItemSize = GDALGetDataTypeSizeBytes(eDataType);
    int nLineOffset, nPixelOffset;
    vsi_l_offset nBandOffset;

    if( EQUAL(szLayout,"BIP") )
    {
        nPixelOffset = nItemSize * nBands;
        if( nPixelOffset > INT_MAX / nBands )
        {
            delete poDS;
            return nullptr;
        }
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = nItemSize;
    }
    else if( EQUAL(szLayout,"BSQ") )
    {
        nPixelOffset = nItemSize;
        if( nPixelOffset > INT_MAX / nCols )
        {
            delete poDS;
            return nullptr;
        }
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = static_cast<vsi_l_offset>(nLineOffset) * nRows;
    }
    else /* assume BIL */
    {
        nPixelOffset = nItemSize;
        if( nPixelOffset > INT_MAX / nBands ||
            nPixelOffset * nBands > INT_MAX / nCols )
        {
            delete poDS;
            return nullptr;
        }
        nLineOffset = nItemSize * nBands * nCols;
        nBandOffset = static_cast<vsi_l_offset>(nItemSize) * nCols;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = nBands;
    for( int i = 0; i < poDS->nBands; i++ )
    {
        RawRasterBand *poBand =
            new RawRasterBand( poDS, i+1, poDS->fpImage,
                               nSkipBytes + nBandOffset * i,
                               nPixelOffset, nLineOffset, eDataType,
#ifdef CPL_LSB
                               chByteOrder == 'I' || chByteOrder == 'L',
#else
                               chByteOrder == 'M',
#endif
                               RawRasterBand::OwnFP::NO );

        if( bNoDataSet )
            poBand->SetNoDataValue( dfNoData );

        poDS->SetBand( i+1, poBand );

        // Set offset/scale values at the PAM level.
        poBand->SetOffset(
            CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0")));
        poBand->SetScale(
            CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0")));
    }

/* -------------------------------------------------------------------- */
/*      Check for a .prj file. For isis2 I would like to keep this in   */
/* -------------------------------------------------------------------- */
    const CPLString osPath = CPLGetPath( poOpenInfo->pszFilename );
    const CPLString osName = CPLGetBasename(poOpenInfo->pszFilename);
    const char  *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" );

    VSILFILE *fp = VSIFOpenL( pszPrjFile, "r" );
    if( fp != nullptr )
    {
        VSIFCloseL( fp );

        char **papszLines = CSLLoad( pszPrjFile );

        OGRSpatialReference oSRS2;
        if( oSRS2.importFromESRI( papszLines ) == OGRERR_NONE )
        {
            char *pszResult = nullptr;
            oSRS2.exportToWkt( &pszResult );
            poDS->osProjection = pszResult;
            CPLFree( pszResult );
        }

        CSLDestroy( papszLines );
    }

    if( dfULXMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = dfULXMap;
        poDS->adfGeoTransform[1] = dfXDim;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfULYMap;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = dfYDim;
    }

    if( !poDS->bGotTransform )
        poDS->bGotTransform =
            GDALReadWorldFile( poOpenInfo->pszFilename, "cbw",
                               poDS->adfGeoTransform );

    if( !poDS->bGotTransform )
        poDS->bGotTransform =
            GDALReadWorldFile( poOpenInfo->pszFilename, "wld",
                               poDS->adfGeoTransform );

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

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

    return poDS;
}
Exemplo n.º 8
0
GDALDataset* SIGDEMDataset::CreateCopy(
    const char * pszFilename,
    GDALDataset * poSrcDS,
    int /*bStrict*/,
    char ** /*papszOptions*/,
    GDALProgressFunc pfnProgress,
    void * pProgressData) {
    const int nBands = poSrcDS->GetRasterCount();
    double adfGeoTransform[6] = { };
    if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) {
        CPLError(CE_Failure, CPLE_NotSupported,
                "SIGDEM driver requires a valid GeoTransform.");
        return nullptr;
    }

    if (nBands != 1) {
        CPLError(CE_Failure, CPLE_NotSupported,
                "SIGDEM driver doesn't support %d bands.  Must be 1 band.",
                nBands);
        return nullptr;
    }

    VSILFILE *fp = VSIFOpenL(pszFilename, "wb");
    if (fp == nullptr) {
        CPLError(CE_Failure, CPLE_OpenFailed,
                "Attempt to create file `%s' failed.", pszFilename);
        return nullptr;
    }

    GDALRasterBand* band = poSrcDS->GetRasterBand(1);
    const char* pszProjection = poSrcDS->GetProjectionRef();

    int32_t nCols = poSrcDS->GetRasterXSize();
    int32_t nRows = poSrcDS->GetRasterYSize();
    int32_t nCoordinateSystemId = GetCoordinateSystemId(pszProjection);

    SIGDEMHeader sHeader;
    sHeader.nCoordinateSystemId = nCoordinateSystemId;
    sHeader.dfMinX = adfGeoTransform[0];
    const char* pszMin = band->GetMetadataItem("STATISTICS_MINIMUM");
    if (pszMin == nullptr) {
        sHeader.dfMinZ = -10000;
    } else {
        sHeader.dfMinZ = CPLAtof(pszMin);
    }
    sHeader.dfMaxY = adfGeoTransform[3];
    const char* pszMax = band->GetMetadataItem("STATISTICS_MAXIMUM");
    if (pszMax == nullptr) {
        sHeader.dfMaxZ = 10000;
    } else {
        sHeader.dfMaxZ = CPLAtof(pszMax);
    }
    sHeader.nCols = poSrcDS->GetRasterXSize();
    sHeader.nRows = poSrcDS->GetRasterYSize();
    sHeader.dfXDim = adfGeoTransform[1];
    sHeader.dfYDim = -adfGeoTransform[5];
    sHeader.dfMaxX = sHeader.dfMinX + sHeader.nCols * sHeader.dfXDim;
    sHeader.dfMinY = sHeader.dfMaxY - sHeader.nRows * sHeader.dfYDim;
    sHeader.dfOffsetX = sHeader.dfMinX;
    sHeader.dfOffsetY = sHeader.dfMinY;

    if( !sHeader.Write(fp) )
    {
        VSIUnlink(pszFilename);
        VSIFCloseL(fp);
        return nullptr;
    }

    // Write fill with all NO_DATA values
    int32_t* row = static_cast<int32_t*>(VSI_MALLOC2_VERBOSE(nCols, sizeof(int32_t)));
    if( !row ) {
        VSIUnlink(pszFilename);
        VSIFCloseL(fp);
        return nullptr;
    }
    std::fill(row, row + nCols, CPL_MSBWORD32(NO_DATA));
    for (int i = 0; i < nRows; i++) {
        if( VSIFWriteL(row, CELL_SIZE_FILE, nCols, fp) !=
                                            static_cast<size_t>(nCols) )
        {
            VSIFree(row);
            VSIUnlink(pszFilename);
            VSIFCloseL(fp);
            return nullptr;
        }
    }
    VSIFree(row);

    if (VSIFCloseL(fp) != 0) {
        return nullptr;
    }

    if (nCoordinateSystemId <= 0) {
        if (!EQUAL(pszProjection, "")) {
            CPLString osPrjFilename = CPLResetExtension(pszFilename, "prj");
            VSILFILE *fpProj = VSIFOpenL(osPrjFilename, "wt");
            if (fpProj != nullptr) {
                OGRSpatialReference oSRS;
                oSRS.importFromWkt(pszProjection);
                oSRS.morphToESRI();
                char *pszESRIProjection = nullptr;
                oSRS.exportToWkt(&pszESRIProjection);
                CPL_IGNORE_RET_VAL(
                        VSIFWriteL(pszESRIProjection, 1,
                                strlen(pszESRIProjection), fpProj));

                CPL_IGNORE_RET_VAL(VSIFCloseL(fpProj));
                CPLFree(pszESRIProjection);
            } else {
                CPLError(CE_Failure, CPLE_FileIO, "Unable to create file %s.",
                        osPrjFilename.c_str());
            }
        }
    }
    GDALOpenInfo oOpenInfo(pszFilename, GA_Update);
    GDALDataset * poDstDS = Open(&oOpenInfo);
    if (poDstDS != nullptr &&
        GDALDatasetCopyWholeRaster(poSrcDS, poDstDS, nullptr, pfnProgress,
            pProgressData) == OGRERR_NONE) {
        return poDstDS;
    } else {
        VSIUnlink(pszFilename);
        return nullptr;
    }
}
Exemplo n.º 9
0
GDALDataset *GTXDataset::Create( const char * pszFilename,
                                 int nXSize, int nYSize, int nBands,
                                 GDALDataType eType,
                                 char ** papszOptions )

{
    if( eType != GDT_Float32 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Attempt to create gtx file with unsupported data type '%s'.",
                  GDALGetDataTypeName( eType ) );
        return NULL;
    }

    if( !EQUAL(CPLGetExtension(pszFilename),"gtx") )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Attempt to create gtx file with extension other than gtx." );
        return NULL;
    }

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

    fp = VSIFOpenL( pszFilename, "wb" );

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

/* -------------------------------------------------------------------- */
/*      Write out the header with stub georeferencing.                  */
/* -------------------------------------------------------------------- */
    unsigned char header[40];
    double dfXOrigin=0, dfYOrigin=0, dfXSize=0.01, dfYSize=0.01;
    GInt32 nXSize32 = nXSize, nYSize32 = nYSize;

    memcpy( header + 0, &dfYOrigin, 8 );
    CPL_MSBPTR64( header + 0 );

    memcpy( header + 8, &dfXOrigin, 8 );
    CPL_MSBPTR64( header + 8 );

    memcpy( header + 16, &dfYSize, 8 );
    CPL_MSBPTR64( header + 16 );

    memcpy( header + 24, &dfXSize, 8 );
    CPL_MSBPTR64( header + 24 );

    memcpy( header + 32, &nYSize32, 4 );
    CPL_MSBPTR32( header + 32 );
    memcpy( header + 36, &nXSize32, 4 );
    CPL_MSBPTR32( header + 36 );

    VSIFWriteL( header, 40, 1, fp );
    VSIFCloseL( fp );

    return (GDALDataset *) GDALOpen( pszFilename, GA_Update );
}
Exemplo n.º 10
0
int OGRSDTSDataSource::Open( const char * pszFilename, int bTestOpen )

{
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Verify that the extension is DDF if we are testopening.         */
/* -------------------------------------------------------------------- */
    if( bTestOpen && !(strlen(pszFilename) > 4 &&
        EQUAL(pszFilename+strlen(pszFilename)-4,".ddf")) )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Check a few bits of the header to see if it looks like an       */
/*      SDTS file (really, if it looks like an ISO8211 file).           */
/* -------------------------------------------------------------------- */
    if( bTestOpen )
    {
        VSILFILE *fp = VSIFOpenL( pszFilename, "rb" );
        if( fp == nullptr )
            return FALSE;

        char pachLeader[10] = {};
        if( VSIFReadL( pachLeader, 1, 10, fp ) != 10
            || (pachLeader[5] != '1' && pachLeader[5] != '2'
                && pachLeader[5] != '3' )
            || pachLeader[6] != 'L'
            || (pachLeader[8] != '1' && pachLeader[8] != ' ') )
        {
            VSIFCloseL( fp );
            return FALSE;
        }

        VSIFCloseL( fp );
    }

/* -------------------------------------------------------------------- */
/*      Create a transfer, and open it.                                 */
/* -------------------------------------------------------------------- */
    poTransfer = new SDTSTransfer();

    if( !poTransfer->Open( pszFilename ) )
    {
        delete poTransfer;
        poTransfer = nullptr;

        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Initialize the projection.                                      */
/* -------------------------------------------------------------------- */
    SDTS_XREF   *poXREF = poTransfer->GetXREF();

    poSRS = new OGRSpatialReference();
    poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);

    if( EQUAL(poXREF->pszSystemName,"UTM") )
    {
        poSRS->SetUTM( poXREF->nZone, TRUE );
    }

    if( EQUAL(poXREF->pszDatum,"NAS") )
        poSRS->SetGeogCS("NAD27", "North_American_Datum_1927",
                         "Clarke 1866", 6378206.4, 294.978698213901 );

    else if( EQUAL(poXREF->pszDatum,"NAX") )
        poSRS->SetGeogCS("NAD83", "North_American_Datum_1983",
                         "GRS 1980", 6378137, 298.257222101 );

    else if( EQUAL(poXREF->pszDatum,"WGC") )
        poSRS->SetGeogCS("WGS 72", "WGS_1972", "NWL 10D", 6378135, 298.26 );

    else /* if( EQUAL(poXREF->pszDatum,"WGE") ) or default case */
        poSRS->SetGeogCS("WGS 84", "WGS_1984",
                         "WGS 84", 6378137, 298.257223563 );

/* -------------------------------------------------------------------- */
/*      Initialize a layer for each source dataset layer.               */
/* -------------------------------------------------------------------- */
    for( int iLayer = 0; iLayer < poTransfer->GetLayerCount(); iLayer++ )
    {
        if( poTransfer->GetLayerType( iLayer ) == SLTRaster )
            continue;

        SDTSIndexedReader *poReader =
            poTransfer->GetLayerIndexedReader( iLayer );
        if( poReader == nullptr )
            continue;

        papoLayers = (OGRSDTSLayer **)
            CPLRealloc( papoLayers, sizeof(void*) * ++nLayers );
        papoLayers[nLayers-1] = new OGRSDTSLayer( poTransfer, iLayer, this );
    }

    return TRUE;
}
Exemplo n.º 11
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 ) );
}
Exemplo n.º 12
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);
}
Exemplo n.º 13
0
GDALDataset *ZMapDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if (!Identify(poOpenInfo))
        return NULL;

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

    const char* pszLine;

    while((pszLine = CPLReadLine2L(fp, 100, NULL)) != NULL)
    {
        if (*pszLine == '!')
        {
            continue;
        }
        else
            break;
    }
    if (pszLine == NULL)
    {
        VSIFCloseL(fp);
        return NULL;
    }

    /* Parse first header line */
    char** papszTokens = CSLTokenizeString2( pszLine, ",", 0 );
    if (CSLCount(papszTokens) != 3)
    {
        CSLDestroy(papszTokens);
        VSIFCloseL(fp);
        return NULL;
    }

    int nValuesPerLine = atoi(papszTokens[2]);
    if (nValuesPerLine <= 0)
    {
        CSLDestroy(papszTokens);
        VSIFCloseL(fp);
        return NULL;
    }

    CSLDestroy(papszTokens);
    papszTokens = NULL;

    /* Parse second header line */
    pszLine = CPLReadLine2L(fp, 100, NULL);
    if (pszLine == NULL)
    {
        VSIFCloseL(fp);
        return NULL;
    }
    papszTokens = CSLTokenizeString2( pszLine, ",", 0 );
    if (CSLCount(papszTokens) != 5)
    {
        CSLDestroy(papszTokens);
        VSIFCloseL(fp);
        return NULL;
    }

    int nFieldSize = atoi(papszTokens[0]);
    double dfNoDataValue = CPLAtofM(papszTokens[1]);
    int nDecimalCount = atoi(papszTokens[3]);
    int nColumnNumber = atoi(papszTokens[4]);

    CSLDestroy(papszTokens);
    papszTokens = NULL;

    if (nFieldSize <= 0 || nFieldSize >= 40 ||
        nDecimalCount <= 0 || nDecimalCount >= nFieldSize ||
        nColumnNumber != 1)
    {
        CPLDebug("ZMap", "nFieldSize=%d, nDecimalCount=%d, nColumnNumber=%d",
                 nFieldSize, nDecimalCount, nColumnNumber);
        VSIFCloseL(fp);
        return NULL;
    }

    /* Parse third header line */
    pszLine = CPLReadLine2L(fp, 100, NULL);
    if (pszLine == NULL)
    {
        VSIFCloseL(fp);
        return NULL;
    }
    papszTokens = CSLTokenizeString2( pszLine, ",", 0 );
    if (CSLCount(papszTokens) != 6)
    {
        CSLDestroy(papszTokens);
        VSIFCloseL(fp);
        return NULL;
    }

    int nRows = atoi(papszTokens[0]);
    int nCols = atoi(papszTokens[1]);
    double dfMinX = CPLAtofM(papszTokens[2]);
    double dfMaxX = CPLAtofM(papszTokens[3]);
    double dfMinY = CPLAtofM(papszTokens[4]);
    double dfMaxY = CPLAtofM(papszTokens[5]);

    CSLDestroy(papszTokens);
    papszTokens = NULL;

    if (!GDALCheckDatasetDimensions(nCols, nRows) ||
        nCols == 1 || nRows == 1)
    {
        VSIFCloseL(fp);
        return NULL;
    }
    
    /* Ignore fourth header line */
    pszLine = CPLReadLine2L(fp, 100, NULL);
    if (pszLine == NULL)
    {
        VSIFCloseL(fp);
        return NULL;
    }

    /* Check fifth header line */
    pszLine = CPLReadLine2L(fp, 100, NULL);
    if (pszLine == NULL || pszLine[0] != '@')
    {
        VSIFCloseL(fp);
        return NULL;
    }

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

    poDS = new ZMapDataset();
    poDS->fp = fp;
    poDS->nDataStartOff = VSIFTellL(fp);
    poDS->nValuesPerLine = nValuesPerLine;
    poDS->nFieldSize = nFieldSize;
    poDS->nDecimalCount = nDecimalCount;
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;
    poDS->dfNoDataValue = dfNoDataValue;

    if (CSLTestBoolean(CPLGetConfigOption("ZMAP_PIXEL_IS_POINT", "FALSE")))
    {
        double dfStepX = (dfMaxX - dfMinX) / (nCols - 1);
        double dfStepY = (dfMaxY - dfMinY) / (nRows - 1);

        poDS->adfGeoTransform[0] = dfMinX - dfStepX / 2;
        poDS->adfGeoTransform[1] = dfStepX;
        poDS->adfGeoTransform[3] = dfMaxY + dfStepY / 2;
        poDS->adfGeoTransform[5] = -dfStepY;
    }
    else
    {
        double dfStepX = (dfMaxX - dfMinX) / nCols ;
        double dfStepY = (dfMaxY - dfMinY) / nRows;

        poDS->adfGeoTransform[0] = dfMinX;
        poDS->adfGeoTransform[1] = dfStepX;
        poDS->adfGeoTransform[3] = dfMaxY;
        poDS->adfGeoTransform[5] = -dfStepY;
    }

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

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

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
    return( poDS );
}
Exemplo n.º 14
0
int OGRGPXDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (bUpdateIn)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GPX driver does not support opening a file in update mode");
        return FALSE;
    }
#ifdef HAVE_EXPAT
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Try to open the file.                                           */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp == NULL)
        return FALSE;
    
    validity = GPX_VALIDITY_UNKNOWN;
    CPLFree(pszVersion);
    pszVersion = NULL;
    bUseExtensions = FALSE;
    nElementsRead = 0;
    
    XML_Parser oParser = OGRCreateExpatXMLParser();
    oCurrentParser = oParser;
    XML_SetUserData(oParser, this);
    XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL);
    XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);
    
    char aBuf[BUFSIZ];
    int nDone;
    unsigned int nLen;
    int nCount = 0;
    
    /* Begin to parse the file and look for the <gpx> element */
    /* It *MUST* be the first element of an XML file */
    /* So once we have read the first element, we know if we can */
    /* handle the file or not with that driver */
    do
    {
        nDataHandlerCounter = 0;
        nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp );
        nDone = VSIFEofL(fp);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            if (nLen <= BUFSIZ-1)
                aBuf[nLen] = 0;
            else
                aBuf[BUFSIZ-1] = 0;
            if (strstr(aBuf, "<?xml") && strstr(aBuf, "<gpx"))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "XML parsing of GPX file failed : %s at line %d, column %d",
                        XML_ErrorString(XML_GetErrorCode(oParser)),
                        (int)XML_GetCurrentLineNumber(oParser),
                        (int)XML_GetCurrentColumnNumber(oParser));
            }
            validity = GPX_VALIDITY_INVALID;
            break;
        }
        if (validity == GPX_VALIDITY_INVALID)
        {
            break;
        }
        else if (validity == GPX_VALIDITY_VALID)
        {
            /* If we have recognized the <gpx> element, now we try */
            /* to recognize if they are <extensions> tags */
            /* But we stop to look for after an arbitrary number of tags */
            if (bUseExtensions)
                break;
            else if (nElementsRead > 200)
                break;
        }
        else
        {
            /* After reading 50 * BUFSIZE bytes, and not finding whether the file */
            /* is GPX or not, we give up and fail silently */
            nCount ++;
            if (nCount == 50)
                break;
        }
    } while (!nDone && nLen > 0 );
    
    XML_ParserFree(oParser);
    
    VSIFCloseL(fp);
    
    if (validity == GPX_VALIDITY_VALID)
    {
        CPLDebug("GPX", "%s seems to be a GPX file.", pszFilename);
        if (bUseExtensions)
            CPLDebug("GPX", "It uses <extensions>");

        if (pszVersion == NULL)
        {
            /* Default to 1.1 */
            CPLError(CE_Warning, CPLE_AppDefined, "GPX schema version is unknown. "
                     "The driver may not be able to handle the file correctly and will behave as if it is GPX 1.1.");
            pszVersion = CPLStrdup("1.1");
        }
        else if (strcmp(pszVersion, "1.0") == 0 || strcmp(pszVersion, "1.1") == 0)
        {
            /* Fine */
        }
        else
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "GPX schema version '%s' is not handled by the driver. "
                     "The driver may not be able to handle the file correctly and will behave as if it is GPX 1.1.", pszVersion);
        }

        nLayers = 5;
        papoLayers = (OGRGPXLayer **) CPLRealloc(papoLayers, nLayers * sizeof(OGRGPXLayer*));
        papoLayers[0] = new OGRGPXLayer( pszName, "waypoints", GPX_WPT, this, FALSE );
        papoLayers[1] = new OGRGPXLayer( pszName, "routes", GPX_ROUTE, this, FALSE );
        papoLayers[2] = new OGRGPXLayer( pszName, "tracks", GPX_TRACK, this, FALSE );
        papoLayers[3] = new OGRGPXLayer( pszName, "route_points", GPX_ROUTE_POINT, this, FALSE );
        papoLayers[4] = new OGRGPXLayer( pszName, "track_points", GPX_TRACK_POINT, this, FALSE );
    }

    return (validity == GPX_VALIDITY_VALID);
#else
    char aBuf[256];
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp)
    {
        unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp );
        aBuf[nLen] = 0;
        if (strstr(aBuf, "<?xml") && strstr(aBuf, "<gpx"))
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GPX driver has not been built with read support. Expat library required");
        }
        VSIFCloseL(fp);
    }
    return FALSE;
#endif
}
Exemplo n.º 15
0
GDALDataset *
EpsilonDatasetCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
                       int bStrict, char ** papszOptions, 
                       GDALProgressFunc pfnProgress, void * pProgressData )
{
    int nBands = poSrcDS->GetRasterCount();
    if ((nBands != 1 && nBands != 3) ||
        (nBands > 0 && poSrcDS->GetRasterBand(1)->GetColorTable() != NULL))
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "The EPSILON driver only supports 1 band (grayscale) "
                 "or 3 band (RGB) data");
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Fetch and check creation options                                */
/* -------------------------------------------------------------------- */

    int nBlockXSize =
        atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));
    int nBlockYSize =
        atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));
    if ((nBlockXSize != 32 && nBlockXSize != 64 && nBlockXSize != 128 &&
         nBlockXSize != 256 && nBlockXSize != 512 && nBlockXSize != 1024) ||
        (nBlockYSize != 32 && nBlockYSize != 64 && nBlockYSize != 128 &&
         nBlockYSize != 256 && nBlockYSize != 512 && nBlockYSize != 1024))
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                "Block size must be a power of 2 between 32 et 1024");
        return NULL;
    }         
    
    const char* pszFilter =
        CSLFetchNameValueDef(papszOptions, "FILTER", "daub97lift");
    char** papszFBID = eps_get_fb_info(EPS_FB_ID);
    char** papszFBIDIter = papszFBID;
    int bFound = FALSE;
    int nIndexFB = 0;
    while(papszFBIDIter && *papszFBIDIter && !bFound)
    {
        if (strcmp(*papszFBIDIter, pszFilter) == 0)
            bFound = TRUE;
        else
            nIndexFB ++;
        papszFBIDIter ++;
    }
    eps_free_fb_info(papszFBID);
    if (!bFound)
    {
        CPLError(CE_Failure, CPLE_NotSupported, "FILTER='%s' not supported",
                 pszFilter);
        return NULL;
    }
    
    int eMode = EPS_MODE_OTLPF;
    const char* pszMode = CSLFetchNameValueDef(papszOptions, "MODE", "OTLPF");
    if (EQUAL(pszMode, "NORMAL"))
        eMode = EPS_MODE_NORMAL;
    else if (EQUAL(pszMode, "OTLPF"))
        eMode = EPS_MODE_OTLPF;
    else
    {
        CPLError(CE_Failure, CPLE_NotSupported, "MODE='%s' not supported",
                 pszMode);
        return NULL;
    }
    
    char** papszFBType = eps_get_fb_info(EPS_FB_TYPE);
    int bIsBiOrthogonal = EQUAL(papszFBType[nIndexFB], "biorthogonal");
    eps_free_fb_info(papszFBType);
    
    if (eMode == EPS_MODE_OTLPF && !bIsBiOrthogonal)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "MODE=OTLPF can only be used with biorthogonal filters. "
                 "Use MODE=NORMAL instead");
        return NULL;
    }    
    
    int bRasterliteOutput =
        CSLTestBoolean(CSLFetchNameValueDef(papszOptions,
                                            "RASTERLITE_OUTPUT", "NO"));
             
    int nYRatio = EPS_Y_RT;
    int nCbRatio = EPS_Cb_RT;
    int nCrRatio = EPS_Cr_RT;
    
    int eResample;
    if (CSLTestBoolean(CSLFetchNameValueDef(papszOptions,
                                            "RGB_RESAMPLE", "YES")))
        eResample = EPS_RESAMPLE_420;
    else
        eResample = EPS_RESAMPLE_444;
    
    const char* pszTarget = CSLFetchNameValueDef(papszOptions, "TARGET", "96");
    double dfReductionFactor = 1 - atof(pszTarget) / 100;
    if (dfReductionFactor > 1)
        dfReductionFactor = 1;
    else if (dfReductionFactor < 0)
        dfReductionFactor = 0;
    
/* -------------------------------------------------------------------- */
/*      Open file                                                       */
/* -------------------------------------------------------------------- */

    VSILFILE* fp = VSIFOpenL(pszFilename, "wb");
    if (fp == NULL)
        return NULL;

/* -------------------------------------------------------------------- */
/*      Compute number of blocks, block size, etc...                    */
/* -------------------------------------------------------------------- */

    int nXSize = poSrcDS->GetRasterXSize();
    int nYSize = poSrcDS->GetRasterYSize();
    if (eMode == EPS_MODE_OTLPF)
    {
        nBlockXSize ++;
        nBlockYSize ++;
    }
    int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize;
    int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize;
    int nBlocks = nXBlocks * nYBlocks;
    int nUncompressedFileSize = nXSize * nYSize * nBands;
    int nUncompressedBlockSize = nUncompressedFileSize / nBlocks;
    int nTargetBlockSize = (int) (dfReductionFactor * nUncompressedBlockSize);
    if (nBands == 1)
        nTargetBlockSize = MAX (nTargetBlockSize, EPS_MIN_GRAYSCALE_BUF + 1);
    else
        nTargetBlockSize = MAX (nTargetBlockSize, EPS_MIN_TRUECOLOR_BUF + 1);

/* -------------------------------------------------------------------- */
/*      Allocate work buffers                                           */
/* -------------------------------------------------------------------- */

    GByte* pabyBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands);
    if (pabyBuffer == NULL)
    {
        VSIFCloseL(fp);
        return NULL;
    }
    
    GByte* pabyOutBuf = (GByte*)VSIMalloc(nTargetBlockSize);
    if (pabyOutBuf == NULL)
    {
        VSIFree(pabyBuffer);
        VSIFCloseL(fp);
        return NULL;
    }
    
    GByte** apapbyRawBuffer[3];
    int i, j;
    for(i=0;i<nBands;i++)
    {
        apapbyRawBuffer[i] = (GByte**) VSIMalloc(sizeof(GByte*) * nBlockYSize);
        for(j=0;j<nBlockYSize;j++)
        {
            apapbyRawBuffer[i][j] =
                            pabyBuffer + (i * nBlockXSize + j) * nBlockYSize;
        }
    }
    
    if (bRasterliteOutput)
    {
        const char* pszHeader = RASTERLITE_WAVELET_HEADER;
        VSIFWriteL(pszHeader, 1, strlen(pszHeader) + 1, fp);
    }

/* -------------------------------------------------------------------- */
/*      Iterate over blocks                                             */
/* -------------------------------------------------------------------- */

    int nBlockXOff, nBlockYOff;
    CPLErr eErr = CE_None;
    for(nBlockYOff = 0;
        eErr == CE_None && nBlockYOff < nYBlocks; nBlockYOff ++)
    {
        for(nBlockXOff = 0;
            eErr == CE_None && nBlockXOff < nXBlocks; nBlockXOff ++)
        {
            int bMustMemset = FALSE;
            int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
            if ((nBlockXOff+1) * nBlockXSize > nXSize)
            {
                bMustMemset = TRUE;
                nReqXSize = nXSize - nBlockXOff * nBlockXSize;
            }
            if ((nBlockYOff+1) * nBlockYSize > nYSize)
            {
                bMustMemset = TRUE;
                nReqYSize = nYSize - nBlockYOff * nBlockYSize;
            }
            if (bMustMemset)
                memset(pabyBuffer, 0, nBands * nBlockXSize * nBlockYSize);
            
            eErr = poSrcDS->RasterIO(GF_Read,
                              nBlockXOff * nBlockXSize,
                              nBlockYOff * nBlockYSize,
                              nReqXSize, nReqYSize,
                              pabyBuffer,
                              nReqXSize, nReqYSize,
                              GDT_Byte, nBands, NULL,
                              1,
                              nBlockXSize,
                              nBlockXSize * nBlockYSize);
            
            int nOutBufSize = nTargetBlockSize;
            if (eErr == CE_None && nBands == 1)
            {
                if (EPS_OK != eps_encode_grayscale_block(apapbyRawBuffer[0],
                                           nXSize, nYSize,
                                           nReqXSize, nReqYSize,
                                           nBlockXOff * nBlockXSize,
                                           nBlockYOff * nBlockYSize,
                                           pabyOutBuf, &nOutBufSize,
                                           (char*) pszFilter, eMode))
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Error occured when encoding block (%d, %d)",
                             nBlockXOff, nBlockYOff);
                    eErr = CE_Failure;
                }
            }
            else if (eErr == CE_None)
            {
                if (EPS_OK != eps_encode_truecolor_block(
                                           apapbyRawBuffer[0],
                                           apapbyRawBuffer[1],
                                           apapbyRawBuffer[2],
                                           nXSize, nYSize,
                                           nReqXSize, nReqYSize,
                                           nBlockXOff * nBlockXSize,
                                           nBlockYOff * nBlockYSize,
                                           eResample,
                                           pabyOutBuf, &nOutBufSize,
                                           nYRatio, nCbRatio, nCrRatio,
                                           (char*) pszFilter, eMode))
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Error occured when encoding block (%d, %d)",
                             nBlockXOff, nBlockYOff);
                    eErr = CE_Failure;
                }
            }
            
            if (eErr == CE_None)
            {
                if ((int)VSIFWriteL(pabyOutBuf, 1, nOutBufSize, fp) !=
                                                                nOutBufSize)
                    eErr = CE_Failure;

                char chEPSMarker = EPS_MARKER;
                VSIFWriteL(&chEPSMarker, 1, 1, fp);
                
                if (pfnProgress && !pfnProgress(
                      1.0 * (nBlockYOff * nXBlocks + nBlockXOff + 1) / nBlocks,
                      NULL, pProgressData))
                {
                    eErr = CE_Failure;
                }
            }
        }
    }
    
    if (bRasterliteOutput)
    {
        const char* pszFooter = RASTERLITE_WAVELET_FOOTER;
        VSIFWriteL(pszFooter, 1, strlen(pszFooter) + 1, fp);
    }

/* -------------------------------------------------------------------- */
/*      Cleanup work buffers                                            */
/* -------------------------------------------------------------------- */
    
    for(i=0;i<nBands;i++)
    {
        VSIFree(apapbyRawBuffer[i]);
    }
    
    VSIFree(pabyOutBuf);
    VSIFree(pabyBuffer);
        
    VSIFCloseL(fp);
    
    if (eErr != CE_None)
        return NULL;

/* -------------------------------------------------------------------- */
/*      Reopen the dataset, unless asked for not (Rasterlite optim)     */
/* -------------------------------------------------------------------- */
    return (GDALDataset*) GDALOpen(pszFilename, GA_ReadOnly);
}
Exemplo n.º 16
0
int OGRGeoRSSDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (bUpdateIn)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GeoRSS driver does not support opening a file in update mode");
        return FALSE;
    }
#ifdef HAVE_EXPAT
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Try to open the file.                                           */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp == NULL)
        return FALSE;
    
    validity = GEORSS_VALIDITY_UNKNOWN;
    
    XML_Parser oParser = OGRCreateExpatXMLParser();
    XML_SetUserData(oParser, this);
    XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL);
    XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);
    oCurrentParser = oParser;
    
    char aBuf[BUFSIZ];
    int nDone;
    unsigned int nLen;
    int nCount = 0;
    
    /* Begin to parse the file and look for the <rss> or <feed> element */
    /* It *MUST* be the first element of an XML file */
    /* So once we have read the first element, we know if we can */
    /* handle the file or not with that driver */
    do
    {
        nDataHandlerCounter = 0;
        nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp );
        nDone = VSIFEofL(fp);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            if (nLen <= BUFSIZ-1)
                aBuf[nLen] = 0;
            else
                aBuf[BUFSIZ-1] = 0;
            if (strstr(aBuf, "<?xml") && (strstr(aBuf, "<rss") || strstr(aBuf, "<feed") || strstr(aBuf, "<atom:feed")))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "XML parsing of GeoRSS file failed : %s at line %d, column %d",
                        XML_ErrorString(XML_GetErrorCode(oParser)),
                        (int)XML_GetCurrentLineNumber(oParser),
                        (int)XML_GetCurrentColumnNumber(oParser));
            }
            validity = GEORSS_VALIDITY_INVALID;
            break;
        }
        if (validity == GEORSS_VALIDITY_INVALID)
        {
            break;
        }
        else if (validity == GEORSS_VALIDITY_VALID)
        {
            break;
        }
        else
        {
            /* After reading 50 * BUFSIZ bytes, and not finding whether the file */
            /* is GeoRSS or not, we give up and fail silently */
            nCount ++;
            if (nCount == 50)
                break;
        }
    } while (!nDone && nLen > 0 );
    
    XML_ParserFree(oParser);
    
    VSIFCloseL(fp);
    
    if (validity == GEORSS_VALIDITY_VALID)
    {
        CPLDebug("GeoRSS", "%s seems to be a GeoRSS file.", pszFilename);

        nLayers = 1;
        papoLayers = (OGRGeoRSSLayer **) CPLRealloc(papoLayers, nLayers * sizeof(OGRGeoRSSLayer*));
        papoLayers[0] = new OGRGeoRSSLayer( pszName, "georss", this, NULL, FALSE );
    }

    return (validity == GEORSS_VALIDITY_VALID);
#else
    char aBuf[256];
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp)
    {
        unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp );
        aBuf[nLen] = 0;
        if (strstr(aBuf, "<?xml") && (strstr(aBuf, "<rss") || strstr(aBuf, "<atom:feed") || strstr(aBuf, "<feed")))
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GeoRSS driver has not been built with read support. Expat library required");
        }
        VSIFCloseL(fp);
    }
    return FALSE;
#endif
}
Exemplo n.º 17
0
GDALDataset *DOQ2Dataset::Open( GDALOpenInfo * poOpenInfo )

{
    int		nWidth=0, nHeight=0, nBandStorage=0, nBandTypes=0;
    
/* -------------------------------------------------------------------- */
/*	We assume the user is pointing to the binary (ie. .bil) file.	*/
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 212 )
        return NULL;

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

    if(! EQUALN((const char *) poOpenInfo->pabyHeader,
                "BEGIN_USGS_DOQ_HEADER", 21) )
        return NULL;

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

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

    while( (pszLine = CPLReadLineL( fp )) != NULL )
    {
	char    **papszTokens;

        nLineCount++;

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

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

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

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

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

    CPLReadLineL( NULL );

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

/* -------------------------------------------------------------------- */
/*      Check the configuration.  We don't currently handle all         */
/*      variations, only the common ones.                               */
/* -------------------------------------------------------------------- */
    if( nBandTypes > 5 )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "DOQ Data Type (%d) is not a supported configuration.\n",
                  nBandTypes );
        CSLDestroy( papszMetadata );
        VSIFCloseL(fp);
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CSLDestroy( papszMetadata );
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The DOQ2 driver does not support update access to existing"
                  " datasets.\n" );
        VSIFCloseL(fp);
        return NULL;
    }
/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    DOQ2Dataset 	*poDS;

    poDS = new DOQ2Dataset();

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

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

    poDS->fpImage = fp;

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

    nBytesPerLine = nBytesPerPixel * nWidth;
    
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nBandCount; i++ )
    {
        poDS->SetBand( i+1, 
            new RawRasterBand( poDS, i+1, poDS->fpImage,
                               nSkipBytes + i, nBytesPerPixel, nBytesPerLine,
                               GDT_Byte, TRUE, TRUE ) );
    }

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

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

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

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

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

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

    return( poDS );
}
Exemplo n.º 18
0
PALSARJaxaRasterBand::~PALSARJaxaRasterBand()
{
    if (fp)
        VSIFCloseL(fp);
}
Exemplo n.º 19
0
int ISIS2Dataset::WriteLabel(
    CPLString osFilename, CPLString osRasterFile, CPLString sObjectTag,
    unsigned int nXSize, unsigned int nYSize, unsigned int nBands,
    GDALDataType eType,
    GUIntBig iRecords, const char * pszInterleaving,
    GUIntBig &iLabelRecords,
    CPL_UNUSED bool bRelaunch)
{
    CPLDebug("ISIS2", "Write Label filename = %s, rasterfile = %s",osFilename.c_str(),osRasterFile.c_str());
    bool bAttachedLabel = EQUAL(osRasterFile, "");

    VSILFILE *fpLabel = VSIFOpenL( osFilename, "w" );

    if( fpLabel == nullptr ){
        CPLError( CE_Failure, CPLE_FileIO,
                  "Failed to create %s:\n%s",
                  osFilename.c_str(), VSIStrerror( errno ) );
        return FALSE;
    }

    const unsigned int iLevel(0);
    unsigned int nWritingBytes(0);

    /* write common header */
    nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "PDS_VERSION_ID", "PDS3" );
    nWritingBytes += ISIS2Dataset::WriteFormatting( fpLabel, "");
    nWritingBytes += ISIS2Dataset::WriteFormatting( fpLabel, "/* File identification and structure */");
    nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "RECORD_TYPE", "FIXED_LENGTH" );
    nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "RECORD_BYTES", CPLString().Printf("%d",RECORD_SIZE));
    nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "FILE_RECORDS", CPLString().Printf(CPL_FRMT_GUIB,iRecords));
    nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "LABEL_RECORDS", CPLString().Printf(CPL_FRMT_GUIB,iLabelRecords));
    if(!bAttachedLabel){
        nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "FILE_NAME", CPLGetFilename(osRasterFile));
    }
    nWritingBytes += ISIS2Dataset::WriteFormatting( fpLabel, "");

    nWritingBytes += ISIS2Dataset::WriteFormatting( fpLabel, "/* Pointers to Data Objects */");

    if(bAttachedLabel){
        nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, CPLString().Printf("^%s",sObjectTag.c_str()), CPLString().Printf(CPL_FRMT_GUIB,iLabelRecords+1));
    }else{
        nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, CPLString().Printf("^%s",sObjectTag.c_str()), CPLString().Printf("(\"%s\",1)",CPLGetFilename(osRasterFile)));
    }

    if(EQUAL(sObjectTag, "QUBE")){
        ISIS2Dataset::WriteQUBE_Information(fpLabel, iLevel, nWritingBytes, nXSize, nYSize, nBands, eType, pszInterleaving);
    }

    nWritingBytes += ISIS2Dataset::WriteFormatting( fpLabel, "END");

    // check if file record is correct
    const unsigned int q = nWritingBytes/RECORD_SIZE;
    if( q <= iLabelRecords){
        // correct we add space after the label end for complete from iLabelRecords
        unsigned int nSpaceBytesToWrite = static_cast<unsigned int>(
            iLabelRecords * RECORD_SIZE - nWritingBytes );
        VSIFPrintfL(fpLabel,"%*c", nSpaceBytesToWrite, ' ');
    }else{
        iLabelRecords = q+1;
        ISIS2Dataset::WriteLabel(osFilename, osRasterFile, sObjectTag, nXSize, nYSize, nBands, eType, iRecords, pszInterleaving, iLabelRecords);
    }
    VSIFCloseL( fpLabel );

    return TRUE;
}
Exemplo n.º 20
0
GDALDataset *PALSARJaxaDataset::Open( GDALOpenInfo * poOpenInfo ) {
    /* Check that this actually is a JAXA PALSAR product */
    if ( !PALSARJaxaDataset::Identify(poOpenInfo) )
        return NULL;

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

    PALSARJaxaDataset *poDS = new PALSARJaxaDataset();

    /* Get the suffix of the filename, we'll need this */
    char *pszSuffix = VSIStrdup( (char *)
                                 (CPLGetFilename( poOpenInfo->pszFilename ) + 3) );

    /* Try to read each of the polarizations */
    const size_t nImgFileLen =
        strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) +
        strlen( pszSuffix ) + 8;
    char *pszImgFile = (char *)CPLMalloc( nImgFileLen );

    int nBandNum = 1;

    /* HH */
    VSILFILE *fpHH;
    snprintf( pszImgFile, nImgFileLen, "%s%sIMG-HH%s",
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpHH = VSIFOpenL( pszImgFile, "rb" );
    if (fpHH != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 0, fpHH ) );
        nBandNum++;
    }

    /* HV */
    VSILFILE *fpHV;
    snprintf( pszImgFile, nImgFileLen, "%s%sIMG-HV%s",
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpHV = VSIFOpenL( pszImgFile, "rb" );
    if (fpHV != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 1, fpHV ) );
        nBandNum++;
    }

    /* VH */
    VSILFILE *fpVH;
    snprintf( pszImgFile, nImgFileLen, "%s%sIMG-VH%s",
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpVH = VSIFOpenL( pszImgFile, "rb" );
    if (fpVH != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 2, fpVH ) );
        nBandNum++;
    }

    /* VV */
    VSILFILE *fpVV;
    snprintf( pszImgFile, nImgFileLen, "%s%sIMG-VV%s",
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpVV = VSIFOpenL( pszImgFile, "rb" );
    if (fpVV != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 3, fpVV ) );
        nBandNum++;
    }

    VSIFree( pszImgFile );

    /* did we get at least one band? */
    if (fpVV == NULL && fpVH == NULL && fpHV == NULL && fpHH == NULL) {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unable to find any image data. Aborting opening as PALSAR image.");
        delete poDS;
        VSIFree( pszSuffix );
        return NULL;
    }

    /* Level 1.0 products are not supported */
    if (poDS->nFileType == level_10) {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "ALOS PALSAR Level 1.0 products are not supported. Aborting opening as PALSAR image.");
        delete poDS;
        VSIFree( pszSuffix );
        return NULL;
    }

    /* read metadata from Leader file. */
    const size_t nLeaderFilenameLen = strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) +
        strlen(pszSuffix) + 5;
    char *pszLeaderFilename = (char *)CPLMalloc( nLeaderFilenameLen );
    snprintf( pszLeaderFilename, nLeaderFilenameLen, "%s%sLED%s",
             CPLGetDirname( poOpenInfo->pszFilename ) , SEP_STRING, pszSuffix );

    VSILFILE *fpLeader = VSIFOpenL( pszLeaderFilename, "rb" );
    /* check if the leader is actually present */
    if (fpLeader != NULL) {
        ReadMetadata(poDS, fpLeader);
        VSIFCloseL(fpLeader);
    }

    VSIFree(pszLeaderFilename);

    VSIFree( pszSuffix );

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

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

    return poDS;
}
Exemplo n.º 21
0
int msSaveImageGDAL( mapObj *map, imageObj *image, char *filename )

{
    int  bFileIsTemporary = MS_FALSE;
    GDALDatasetH hMemDS, hOutputDS;
    GDALDriverH  hMemDriver, hOutputDriver;
    int          nBands = 1;
    int          iLine;
    GByte       *pabyAlphaLine = NULL;
    char        **papszOptions = NULL;
    outputFormatObj *format = image->format;
    rasterBufferObj rb;
    GDALDataType eDataType = GDT_Byte;
    int bUseXmp = MS_FALSE;

    msGDALInitialize();
    memset(&rb,0,sizeof(rasterBufferObj));
    
#ifdef USE_EXEMPI
    bUseXmp = msXmpPresent(map);
#endif        


/* -------------------------------------------------------------------- */
/*      Identify the proposed output driver.                            */
/* -------------------------------------------------------------------- */
    msAcquireLock( TLOCK_GDAL );
    hOutputDriver = GDALGetDriverByName( format->driver+5 );
    if( hOutputDriver == NULL )
    {
        msReleaseLock( TLOCK_GDAL );
        msSetError( MS_MISCERR, "Failed to find %s driver.",
                    "msSaveImageGDAL()", format->driver+5 );
        return MS_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      We will need to write the output to a temporary file and        */
/*      then stream to stdout if no filename is passed.  If the         */
/*      driver supports virtualio then we hold the temporary file in    */
/*      memory, otherwise we try to put it in a reasonable temporary    */
/*      file location.                                                  */
/* -------------------------------------------------------------------- */
    if( filename == NULL )
    {
        const char *pszExtension = format->extension;
        if( pszExtension == NULL )
            pszExtension = "img.tmp";

        if( bUseXmp == MS_FALSE && GDALGetMetadataItem( hOutputDriver, GDAL_DCAP_VIRTUALIO, NULL )
            != NULL )
        {
            CleanVSIDir( "/vsimem/msout" );
            filename = msTmpFile(map, NULL, "/vsimem/msout/", pszExtension );
        }

        if( filename == NULL && map != NULL)
            filename = msTmpFile(map, map->mappath,NULL,pszExtension);
        else if( filename == NULL )
        {
            filename = msTmpFile(map, NULL, NULL, pszExtension );
        }
            
        bFileIsTemporary = MS_TRUE;
    }
    
/* -------------------------------------------------------------------- */
/*      Establish the characteristics of our memory, and final          */
/*      dataset.                                                        */
/* -------------------------------------------------------------------- */

    if( format->imagemode == MS_IMAGEMODE_RGB )
    {
        nBands = 3;
        assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer );
        format->vtable->getRasterBufferHandle(image,&rb);
    }
    else if( format->imagemode == MS_IMAGEMODE_RGBA )
    {
        pabyAlphaLine = (GByte *) calloc(image->width,1);
        if (pabyAlphaLine == NULL)
        {
            msReleaseLock( TLOCK_GDAL );
            msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", image->width);
            return MS_FAILURE;
        }
        nBands = 4;
        assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer );
        format->vtable->getRasterBufferHandle(image,&rb);
    }
    else if( format->imagemode == MS_IMAGEMODE_INT16 )
    {
        nBands = format->bands;
        eDataType = GDT_Int16;
    }
    else if( format->imagemode == MS_IMAGEMODE_FLOAT32 )
    {
        nBands = format->bands;
        eDataType = GDT_Float32;
    }
    else if( format->imagemode == MS_IMAGEMODE_BYTE )
    {
        nBands = format->bands;
        eDataType = GDT_Byte;
    }
    else
    {
        assert( format->imagemode == MS_IMAGEMODE_PC256
                && format->renderer == MS_RENDER_WITH_GD );
    }

/* -------------------------------------------------------------------- */
/*      Create a memory dataset which we can use as a source for a      */
/*      CreateCopy().                                                   */
/* -------------------------------------------------------------------- */
    hMemDriver = GDALGetDriverByName( "MEM" );
    if( hMemDriver == NULL )
    {
        msReleaseLock( TLOCK_GDAL );
        msSetError( MS_MISCERR, "Failed to find MEM driver.",
                    "msSaveImageGDAL()" );
        return MS_FAILURE;
    }
   
    hMemDS = GDALCreate( hMemDriver, "msSaveImageGDAL_temp", 
                         image->width, image->height, nBands, 
                         eDataType, NULL );
    if( hMemDS == NULL )
    {
        msReleaseLock( TLOCK_GDAL );
        msSetError( MS_MISCERR, "Failed to create MEM dataset.",
                    "msSaveImageGDAL()" );
        return MS_FAILURE;
    }
    
/* -------------------------------------------------------------------- */
/*      Copy the gd image into the memory dataset.                      */
/* -------------------------------------------------------------------- */
    for( iLine = 0; iLine < image->height; iLine++ )
    {
        int iBand;

        for( iBand = 0; iBand < nBands; iBand++ )
        {
            GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 );

            if( format->imagemode == MS_IMAGEMODE_INT16 )
            {
                GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, 
                              image->img.raw_16bit + iLine * image->width
                              + iBand * image->width * image->height,
                              image->width, 1, GDT_Int16, 2, 0 );
                
            }
            else if( format->imagemode == MS_IMAGEMODE_FLOAT32 )
            {
                GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, 
                              image->img.raw_float + iLine * image->width
                              + iBand * image->width * image->height,
                              image->width, 1, GDT_Float32, 4, 0 );
            }
            else if( format->imagemode == MS_IMAGEMODE_BYTE )
            {
                GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, 
                              image->img.raw_byte + iLine * image->width
                              + iBand * image->width * image->height,
                              image->width, 1, GDT_Byte, 1, 0 );
            }
            else if(format->renderer == MS_RENDER_WITH_GD) {
               gdImagePtr img = (gdImagePtr)image->img.plugin;
               GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, 
                              img->pixels[iLine], 
                              image->width, 1, GDT_Byte, 0, 0 );
            }
            else {
               GByte *pabyData;
               unsigned char *pixptr = NULL;
               assert( rb.type == MS_BUFFER_BYTE_RGBA );
               switch(iBand) {
               case 0:
                  pixptr = rb.data.rgba.r;
                  break;
               case 1:
                  pixptr = rb.data.rgba.g;
                  break;
               case 2:
                  pixptr = rb.data.rgba.b;
                  break;
               case 3:
                  pixptr = rb.data.rgba.a;
                  break;
               }
               assert(pixptr);
               if( pixptr == NULL )
               {
                   msReleaseLock( TLOCK_GDAL );
                   msSetError( MS_MISCERR, "Missing RGB or A buffer.\n",
                               "msSaveImageGDAL()" );
                   return MS_FAILURE;
               }

               pabyData = (GByte *)(pixptr + iLine*rb.data.rgba.row_step);

               if( rb.data.rgba.a == NULL || iBand == 3 )
               {
                   GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, 
                                 pabyData, image->width, 1, GDT_Byte, 
                                 rb.data.rgba.pixel_step, 0 );
               }
               else /* We need to un-pre-multiple RGB by alpha. */
               {
                   GByte *pabyUPM = (GByte*) malloc(image->width);
                   GByte *pabyAlpha= (GByte *)(rb.data.rgba.a + iLine*rb.data.rgba.row_step);
                   int i;

                   for( i = 0; i < image->width; i++ )
                   {
                       int alpha = pabyAlpha[i*rb.data.rgba.pixel_step];

                       if( alpha == 0 )
                           pabyUPM[i] = 0;
                       else
                       {
                           int result = (pabyData[i*rb.data.rgba.pixel_step] * 255) / alpha;
                           
                           if( result > 255 )
                               result = 255;

                           pabyUPM[i] = result;
                       }
                   }

                   GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, 
                                 pabyUPM, image->width, 1, GDT_Byte, 1, 0 );
                   free( pabyUPM );
               }
            }
        }
    }

    if( pabyAlphaLine != NULL )
        free( pabyAlphaLine );

/* -------------------------------------------------------------------- */
/*      Attach the palette if appropriate.                              */
/* -------------------------------------------------------------------- */
    if( format->renderer == MS_RENDER_WITH_GD )
    {
        GDALColorEntry sEntry;
        int  iColor;
        GDALColorTableH hCT;
        gdImagePtr img = (gdImagePtr)image->img.plugin;
        hCT = GDALCreateColorTable( GPI_RGB );

        for( iColor = 0; iColor < img->colorsTotal; iColor++ )
        {
            sEntry.c1 = img->red[iColor];
            sEntry.c2 = img->green[iColor];
            sEntry.c3 = img->blue[iColor];

            if( iColor == gdImageGetTransparent( img ) )
                sEntry.c4 = 0;
            else if( iColor == 0 
                     && gdImageGetTransparent( img ) == -1 
                     && format->transparent )
                sEntry.c4 = 0;
            else
                sEntry.c4 = 255;

            GDALSetColorEntry( hCT, iColor, &sEntry );
        }
        
        GDALSetRasterColorTable( GDALGetRasterBand( hMemDS, 1 ), hCT );

        GDALDestroyColorTable( hCT );
    }

    else if( format->imagemode == MS_IMAGEMODE_RGB )
    {
        GDALSetRasterColorInterpretation( 
            GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand );
        GDALSetRasterColorInterpretation( 
            GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand );
        GDALSetRasterColorInterpretation( 
            GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand );
    }
    else if( format->imagemode == MS_IMAGEMODE_RGBA )
    {
        GDALSetRasterColorInterpretation( 
            GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand );
        GDALSetRasterColorInterpretation( 
            GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand );
        GDALSetRasterColorInterpretation( 
            GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand );
        GDALSetRasterColorInterpretation( 
            GDALGetRasterBand( hMemDS, 4 ), GCI_AlphaBand );
    }

/* -------------------------------------------------------------------- */
/*      Assign the projection and coordinate system to the memory       */
/*      dataset.                                                        */
/* -------------------------------------------------------------------- */

    if( map != NULL )
    {
        char *pszWKT;

        GDALSetGeoTransform( hMemDS, map->gt.geotransform );

        pszWKT = msProjectionObj2OGCWKT( &(map->projection) );
        if( pszWKT != NULL )
        {
            GDALSetProjection( hMemDS, pszWKT );
            msFree( pszWKT );
        }
    }

/* -------------------------------------------------------------------- */
/*      Possibly assign a nodata value.                                 */
/* -------------------------------------------------------------------- */
    if( msGetOutputFormatOption(format,"NULLVALUE",NULL) != NULL )
    {
        int iBand;
        const char *nullvalue = msGetOutputFormatOption(format,
                                                        "NULLVALUE",NULL);

        for( iBand = 0; iBand < nBands; iBand++ )
        {
            GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 );
            GDALSetRasterNoDataValue( hBand, atof(nullvalue) );
        }
    }

/* -------------------------------------------------------------------- */
/*  Try to save resolution in the output file.                          */
/* -------------------------------------------------------------------- */
    if( image->resolution > 0 )
    {
      char res[30];

      sprintf( res, "%lf", image->resolution );
      GDALSetMetadataItem( hMemDS, "TIFFTAG_XRESOLUTION", res, NULL );
      GDALSetMetadataItem( hMemDS, "TIFFTAG_YRESOLUTION", res, NULL );
      GDALSetMetadataItem( hMemDS, "TIFFTAG_RESOLUTIONUNIT", "2", NULL );
    }
    
/* -------------------------------------------------------------------- */
/*      Create a disk image in the selected output format from the      */
/*      memory image.                                                   */
/* -------------------------------------------------------------------- */
    papszOptions = (char**)calloc(sizeof(char *),(format->numformatoptions+1));
    if (papszOptions == NULL)
    {
        msReleaseLock( TLOCK_GDAL );
        msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", 
                    sizeof(char *)*(format->numformatoptions+1));
        return MS_FAILURE;
    }

    memcpy( papszOptions, format->formatoptions, 
            sizeof(char *) * format->numformatoptions );
   
    hOutputDS = GDALCreateCopy( hOutputDriver, filename, hMemDS, FALSE, 
                                papszOptions, NULL, NULL );

    free( papszOptions );

    if( hOutputDS == NULL )
    {
        GDALClose( hMemDS );
        msReleaseLock( TLOCK_GDAL );
        msSetError( MS_MISCERR, "Failed to create output %s file.\n%s",
                    "msSaveImageGDAL()", format->driver+5, 
                    CPLGetLastErrorMsg() );
        return MS_FAILURE;
    }

    /* closing the memory DS also frees all associated resources. */
    GDALClose( hMemDS );

    GDALClose( hOutputDS );
    msReleaseLock( TLOCK_GDAL );


/* -------------------------------------------------------------------- */
/*      Are we writing license info into the image?                     */
/*      If so, add it to the temp file on disk now.                     */
/* -------------------------------------------------------------------- */
#ifdef USE_EXEMPI
    if ( bUseXmp == MS_TRUE )
    {
        if( msXmpWrite(map, filename) == MS_FAILURE )
        {
            /* Something bad happened. */
            msSetError( MS_MISCERR, "XMP write to %s failed.\n%s",
                        "msSaveImageGDAL()", filename);
            return MS_FAILURE;
        }
    }
#endif

/* -------------------------------------------------------------------- */
/*      Is this supposed to be a temporary file?  If so, stream to      */
/*      stdout and delete the file.                                     */
/* -------------------------------------------------------------------- */
    if( bFileIsTemporary )
    {
        FILE *fp; 
        unsigned char block[4000];
        int bytes_read;

        if( msIO_needBinaryStdout() == MS_FAILURE )
            return MS_FAILURE;

        /* We aren't sure how far back GDAL exports the VSI*L API, so 
           we only use it if we suspect we need it.  But we do need it if
           holding temporary file in memory. */
        fp = VSIFOpenL( filename, "rb" );
        if( fp == NULL )
        {
            msSetError( MS_MISCERR, 
                        "Failed to open %s for streaming to stdout.",
                        "msSaveImageGDAL()", filename );
            return MS_FAILURE;
        }

        while( (bytes_read = VSIFReadL(block, 1, sizeof(block), fp)) > 0 )
            msIO_fwrite( block, 1, bytes_read, stdout );

        VSIFCloseL( fp );

        VSIUnlink( filename );
        CleanVSIDir( "/vsimem/msout" );

        free( filename );
    }
    
    return MS_SUCCESS;
}
Exemplo n.º 22
0
FileDataSource::~FileDataSource()
{
    if (closeFile)
        VSIFCloseL(fp);
}
Exemplo n.º 23
0
bool TerragenDataset::write_header()
{
	char szHeader[16];
	memcpy(szHeader, "TERRAGENTERRAIN ", sizeof(szHeader));

    if(1 != VSIFWriteL( (void *) szHeader, sizeof(szHeader), 1, m_fp ))
	{
        CPLError( CE_Failure, CPLE_FileIO, 
                  "Couldn't write to Terragen file %s.\n"
                  "Is file system full?",
                  m_pszFilename );
        VSIFCloseL( m_fp );

        return false;
    }

    
// -------------------------------------------------------------------- 
//      Write out the heightfield dimensions, etc.
// -------------------------------------------------------------------- 

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

	this->write_next_tag("SIZE");
	this->put((GInt16)(min(nXSize, nYSize)-1));
	this->pad(sizeof(GInt16));

	if(nXSize != nYSize)
	{
		this->write_next_tag("XPTS");
		this->put((GInt16)nXSize); this->pad(sizeof(GInt16));
		this->write_next_tag("YPTS");
		this->put((GInt16)nYSize); this->pad(sizeof(GInt16));
	}

	if(m_bIsGeo)
	{
		/*
			With a geographic projection (degrees),
			m_dGroundScale will be in degrees and
			m_dMetersPerGroundUnit is undefined.
			So we're going to estimate a m_dMetersPerGroundUnit
			value here (i.e., meters per degree).

			We figure out the degree size of one 
			pixel, and then the latitude degrees 
			of the heightfield's center. The circumference of
			the latitude's great circle lets us know how
			wide the pixel is in meters, and we 
			average that with the pixel's meter breadth,
			which is based on the polar circumference.
		*/

		/*const double m_dDegLongPerPixel = 
			fabs(m_adfTransform[1]);*/

		const double m_dDegLatPerPixel = 
			fabs(m_adfTransform[5]);

		/*const double m_dCenterLongitude =
			m_adfTransform[0] + 
			(0.5 * m_dDegLongPerPixel * (nXSize-1));*/

		const double m_dCenterLatitude =
			m_adfTransform[3] + 
			(0.5 * m_dDegLatPerPixel * (nYSize-1));


		const double dLatCircum = kdEarthCircumEquat 
			* sin(degrees_to_radians(90.0 - m_dCenterLatitude));

		const double dMetersPerDegLongitude = dLatCircum / 360;
		/*const double dMetersPerPixelX = 
			(m_dDegLongPerPixel / 360) * dLatCircum;*/

		const double dMetersPerDegLatitude = 
			kdEarthCircumPolar / 360;
		/*const double dMetersPerPixelY = 
			(m_dDegLatPerPixel / 360) * kdEarthCircumPolar;*/

		m_dMetersPerGroundUnit = 
			average(dMetersPerDegLongitude, dMetersPerDegLatitude);

	}
		
	m_dSCAL = m_dGroundScale * m_dMetersPerGroundUnit;

	if(m_dSCAL != 30.0)
	{
		const float sc = (float)m_dSCAL;
		this->write_next_tag("SCAL");
		this->put(sc);
		this->put(sc);
		this->put(sc);
	}

	if(!this->write_next_tag("ALTW"))
	{
        CPLError( CE_Failure, CPLE_FileIO, 
                  "Couldn't write to Terragen file %s.\n"
                  "Is file system full?",
                  m_pszFilename );
        VSIFCloseL( m_fp );

        return false;
	}

	// Compute physical scales and offsets.
	m_span_m[0] = m_dLogSpan[0] * m_dMetersPerElevUnit;
	m_span_m[1] = m_dLogSpan[1] * m_dMetersPerElevUnit;

	m_span_px[0] = m_span_m[0] / m_dSCAL;
	m_span_px[1] = m_span_m[1] / m_dSCAL;

	const double span_px = m_span_px[1] - m_span_px[0];
	m_nHeightScale = (GInt16)span_px;
	if(m_nHeightScale == 0)
		m_nHeightScale++;

	#define P2L_PX(n, hs, bh)	\
		((double)(n) / 65536.0 * (hs) + (bh))

	#define L2P_PX(n, hs, bh)	\
		((int)(((n)-(bh)) * 65536.0 / (hs)))

	// Increase the heightscale until the physical span
	// fits within a 16-bit range. The smaller the logical span,
	// the more necessary this becomes.
	int hs, bh=0;
	for(hs = m_nHeightScale; hs <= 32767; hs++)
	{
		double prevdelta = 1.0e30;
		for(bh = -32768; bh <= 32767; bh++)
		{
			int nValley = L2P_PX(m_span_px[0], hs, bh);
			if(nValley < -32768) continue;
			int nPeak = L2P_PX(m_span_px[1], hs, bh);
			if(nPeak > 32767) continue;

			// now see how closely the baseheight gets
			// to the pixel span.
			double d = P2L_PX(nValley, hs, bh);
			double delta = fabs(d - m_span_px[0]);
			if(delta < prevdelta) // Converging?
				prevdelta = delta;
			else 
			{
				// We're diverging, so use the previous bh
				// and stop looking.
				bh--;
				break;
			}
		}
		if(bh != 32768) break;
	}
	if(hs == 32768)
	{
        CPLError( CE_Failure, CPLE_FileIO, 
                  "Couldn't write to Terragen file %s.\n"
                  "Cannot find adequate heightscale/baseheight combination.",
                  m_pszFilename );
        VSIFCloseL( m_fp );

        return false;
	}
		
	m_nHeightScale = (GInt16) hs;
	m_nBaseHeight = (GInt16) bh;


	// m_nHeightScale is the one that gives us the 
	// widest use of the 16-bit space. However, there
	// might be larger heightscales that, even though
	// the reduce the space usage, give us a better fit
	// for preserving the span extents.


	return (this->put(m_nHeightScale) &&
			this->put(m_nBaseHeight));
}
Exemplo n.º 24
0
int OGRTigerDataSource::Open( const char * pszFilename, int bTestOpen,
                              char ** papszLimitedFileList )

{
    VSIStatBufL     stat;
    char            **papszFileList = NULL;
    int             i;

    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Is the given path a directory or a regular file?                */
/* -------------------------------------------------------------------- */
    if( VSIStatExL( pszFilename, &stat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG ) != 0
        || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) )
    {
        if( !bTestOpen )
            CPLError( CE_Failure, CPLE_AppDefined,
                   "%s is neither a file or directory, Tiger access failed.\n",
                      pszFilename );

        return FALSE;
    }
    
/* -------------------------------------------------------------------- */
/*      Build a list of filenames we figure are Tiger files.            */
/* -------------------------------------------------------------------- */
    if( VSI_ISREG(stat.st_mode) )
    {
        char       szModule[128];
        
        if( strlen(CPLGetFilename(pszFilename)) == 0 )
        {
            return FALSE;
        }

        pszPath = CPLStrdup( CPLGetPath(pszFilename) );

        strncpy( szModule, CPLGetFilename(pszFilename), sizeof(szModule)-1 );
        /* Make sure the buffer is 0 terminated */
        szModule[sizeof(szModule)-1] = '\0';

        /* And now remove last character of filename */
        szModule[strlen(szModule)-1] = '\0';

        papszFileList = CSLAddString( papszFileList, szModule );
    }
    else
    {
        char      **candidateFileList = CPLReadDir( pszFilename );

        pszPath = CPLStrdup( pszFilename );

        for( int i = 0;
             candidateFileList != NULL && candidateFileList[i] != NULL; 
             i++ ) 
        {
            int nCandidateLen = strlen(candidateFileList[i]);

            if( papszLimitedFileList != NULL 
                && CSLFindString(papszLimitedFileList,
                                 CPLGetBasename(candidateFileList[i])) == -1 )
            {
                continue;
            }

            if( nCandidateLen > 4 
                && candidateFileList[i][nCandidateLen-4] == '.'
                && candidateFileList[i][nCandidateLen-1] == '1')
            {
                char       szModule[128];

                strncpy( szModule, candidateFileList[i],
                         strlen(candidateFileList[i])-1 );

                szModule[strlen(candidateFileList[i])-1] = '\0';

                papszFileList = CSLAddString(papszFileList, szModule);
            }
        }

        CSLDestroy( candidateFileList );

        if( CSLCount(papszFileList) == 0 )
        {
            if( !bTestOpen )
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "No candidate Tiger files (TGR*.RT1) found in\n"
                          "directory: %s",
                          pszFilename );
            CSLDestroy(papszFileList);
            return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Loop over all these files trying to open them.  In testopen     */
/*      mode we first read the first 80 characters, to verify that      */
/*      it looks like an Tiger file.  Note that we don't keep the file  */
/*      open ... we don't want to occupy alot of file handles when      */
/*      handling a whole directory.                                     */
/* -------------------------------------------------------------------- */
    papszModules = NULL;
    
    for( i = 0; papszFileList[i] != NULL; i++ )
    {
        if( bTestOpen || i == 0 )
        {
            char        szHeader[500];
            VSILFILE    *fp;
            char        *pszRecStart = NULL;
            int         bIsGDT = FALSE;
            char       *pszFilename;

            pszFilename = BuildFilename( papszFileList[i], "1" );

            fp = VSIFOpenL( pszFilename, "rb" );
            CPLFree( pszFilename );

            if( fp == NULL )
                continue;
            
            if( VSIFReadL( szHeader, sizeof(szHeader)-1, 1, fp ) < 1 )
            {
                VSIFCloseL( fp );
                continue;
            }

            VSIFCloseL( fp );

            pszRecStart = szHeader;
            szHeader[sizeof(szHeader)-1] = '\0';

            if( EQUALN(pszRecStart,"Copyright (C)",13) 
                && strstr(pszRecStart,"Geographic Data Tech") != NULL )
            {
                bIsGDT = TRUE;

                while( *pszRecStart != '\0' 
                       && *pszRecStart != 10 
                       && *pszRecStart != 13 )
                    pszRecStart++;

                while( *pszRecStart == 10 || *pszRecStart == 13 )
                    pszRecStart++;
            }
            
            if( pszRecStart[0] != '1' )
                continue;

            if( !isdigit(pszRecStart[1]) || !isdigit(pszRecStart[2])
                || !isdigit(pszRecStart[3]) || !isdigit(pszRecStart[4]) )
                continue;

            nVersionCode = atoi(TigerFileBase::GetField( pszRecStart, 2, 5 ));
            nVersion = TigerClassifyVersion( nVersionCode );
            nVersion = TigerCheckVersion( nVersion, papszFileList[i] );

            CPLDebug( "OGR", "Tiger Version Code=%d, Classified as %s ", 
                      nVersionCode, TigerVersionString(nVersion) );

            if(    nVersionCode !=  0
                && nVersionCode !=  2
                && nVersionCode !=  3
                && nVersionCode !=  5
                && nVersionCode != 21 
                && nVersionCode != 24
                && pszRecStart[3]  != '9'
                && pszRecStart[3]  != '0'
                && !bIsGDT )
                continue;

            // we could (and should) add a bunch more validation here.
        }

        papszModules = CSLAddString( papszModules, papszFileList[i] );
    }

    CSLDestroy( papszFileList );

    nModules = CSLCount( papszModules );

    if( nModules == 0 )
    {
        if( !bTestOpen )
        {
            if( VSI_ISREG(stat.st_mode) )
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "No TIGER/Line files (TGR*.RT1) found in\n"
                          "directory: %s",
                          pszFilename );
            else
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "File %s does not appear to be a TIGER/Line .RT1 file.",
                          pszFilename );
        }

        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Do we have a user provided version override?                    */
/* -------------------------------------------------------------------- */
    if( CPLGetConfigOption( "TIGER_VERSION", NULL ) != NULL )
    {
        const char *pszRequestedVersion = 
            CPLGetConfigOption( "TIGER_VERSION", NULL );

        if( EQUALN(pszRequestedVersion,"TIGER_",6) )
        {
            int iCode;

            for( iCode = 1; iCode < TIGER_Unknown; iCode++ )
            {
                if( EQUAL(TigerVersionString((TigerVersion)iCode),
                          pszRequestedVersion) )
                {
                    nVersion = (TigerVersion) iCode;
                    break;
                }
            }

            if( iCode == TIGER_Unknown )
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "Failed to recognise TIGER_VERSION setting: %s", 
                          pszRequestedVersion );
                return FALSE;
            }                          

            CPLDebug( "OGR", "OVERRIDE Tiger Version %s ", 
                      TigerVersionString(nVersion) );
        }
        else
        {
            nVersionCode = atoi(pszRequestedVersion);
            nVersion = TigerClassifyVersion( nVersionCode );

            CPLDebug( "OGR", 
                      "OVERRIDE Tiger Version Code=%d, Classified as %s ", 
                      nVersionCode, TigerVersionString(nVersion) );
        }
    }

/* -------------------------------------------------------------------- */
/*      Create the layers which appear to exist.                        */
/* -------------------------------------------------------------------- */
    // RT1, RT2, RT3
    AddLayer( new OGRTigerLayer( this,
                                 new TigerCompleteChain( this,
                                                         papszModules[0]) ));

    /* should we have kept track of whether we encountered an RT4 file? */
    // RT4
    AddLayer( new OGRTigerLayer( this,
                                 new TigerAltName( this,
                                                   papszModules[0]) ));

    // RT5
    AddLayer( new OGRTigerLayer( this,
                                 new TigerFeatureIds( this,
                                                      papszModules[0]) ));

    // RT6
    AddLayer( new OGRTigerLayer( this,
                                 new TigerZipCodes( this,
                                                    papszModules[0]) ));
    // RT7
    AddLayer( new OGRTigerLayer( this,
                                 new TigerLandmarks( this,
                                                     papszModules[0]) ));
    
    // RT8
    AddLayer( new OGRTigerLayer( this,
                                 new TigerAreaLandmarks( this,
                                                     papszModules[0]) ));

    // RT9
    if (nVersion < TIGER_2002) {
      AddLayer( new OGRTigerLayer( this,
                                   new TigerKeyFeatures( this,
                                                         papszModules[0]) ));
    }
    
    // RTA, RTS
    AddLayer( new OGRTigerLayer( this,
                                 new TigerPolygon( this,
                                                   papszModules[0]) ));

    // RTB
    if (nVersion >= TIGER_2002) {
      AddLayer( new OGRTigerLayer( this,
                                   new TigerPolygonCorrections( this,
                                                                papszModules[0]) ));
    }
    
    // RTC
    AddLayer( new OGRTigerLayer( this,
                                 new TigerEntityNames( this,
                                                       papszModules[0]) ));

    // RTE
    if (nVersion >= TIGER_2002) {
      AddLayer( new OGRTigerLayer( this,
                                   new TigerPolygonEconomic( this,
                                                             papszModules[0]) ));
    }

    // RTH
    AddLayer( new OGRTigerLayer( this,
                                 new TigerIDHistory( this,
                                                     papszModules[0]) ));
    
    // RTI
    AddLayer( new OGRTigerLayer( this,
                                 new TigerPolyChainLink( this,
                                                       papszModules[0]) ));
    
    // RTM
    AddLayer( new OGRTigerLayer( this,
                                 new TigerSpatialMetadata( this,
                                                           papszModules[0] ) ) );
    
    // RTP
    AddLayer( new OGRTigerLayer( this,
                                 new TigerPIP( this,
                                               papszModules[0]) ));
    
    // RTR
    AddLayer( new OGRTigerLayer( this,
                                 new TigerTLIDRange( this,
                                                     papszModules[0]) ));
    
    // RTT
    if (nVersion >= TIGER_2002) {
      AddLayer( new OGRTigerLayer( this,
                                   new TigerZeroCellID( this,
                                                        papszModules[0]) ));
    }

    // RTU
    if (nVersion >= TIGER_2002) {
      AddLayer( new OGRTigerLayer( this,
                                   new TigerOverUnder( this,
                                                       papszModules[0]) ));
    }

    // RTZ
    AddLayer( new OGRTigerLayer( this,
                                 new TigerZipPlus4( this,
                                                     papszModules[0]) ));
    
    return TRUE;
}
Exemplo n.º 25
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;
}
Exemplo n.º 26
0
GDALDataset *GSBGDataset::Create( const char * pszFilename,
				  int nXSize, int nYSize, int nBands,
				  GDALDataType eType,
				  char **papszParmList )

{
    if( nXSize <= 0 || nYSize <= 0 )
    {
	CPLError( CE_Failure, CPLE_IllegalArg,
		  "Unable to create grid, both X and Y size must be "
		  "non-negative.\n" );

	return NULL;
    }
    else if( nXSize > SHRT_MAX
	     || nYSize > SHRT_MAX )
    {
	CPLError( CE_Failure, CPLE_IllegalArg,
		  "Unable to create grid, Golden Software Binary Grid format "
		  "only supports sizes up to %dx%d.  %dx%d not supported.\n",
		  SHRT_MAX, SHRT_MAX, nXSize, nYSize );

	return NULL;
    }

    if( eType != GDT_Byte && eType != GDT_Float32 && eType != GDT_UInt16
        && eType != GDT_Int16 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
		  "Golden Software ASCII Grid only supports Byte, Int16, "
		  "Uint16, and Float32 datatypes.  Unable to create with "
		  "type %s.\n", GDALGetDataTypeName( eType ) );

        return NULL;
    }

    VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file '%s' failed.\n",
                  pszFilename );
        return NULL;
    }
    
    CPLErr eErr = WriteHeader( fp, (GInt16) nXSize, (GInt16) nYSize,
			       0.0, nXSize, 0.0, nYSize, 0.0, 0.0 );
    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
	return NULL;
    }

    float fVal = fNODATA_VALUE;
    CPL_LSBPTR32( &fVal );
    for( int iRow = 0; iRow < nYSize; iRow++ )
    {
	for( int iCol=0; iCol<nXSize; iCol++ )
	{
	    if( VSIFWriteL( (void *)&fVal, 4, 1, fp ) != 1 )
	    {
		VSIFCloseL( fp );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to write grid cell.  Disk full?\n" );
		return NULL;
	    }
	}
    }

    VSIFCloseL( fp );

    return (GDALDataset *)GDALOpen( pszFilename, GA_Update );
}
Exemplo n.º 27
0
/**
 * Load json document from file using small chunks of data.
 * @param  osPath      Path to json document file.
 * @param  nChunkSize   Chunk size.
 * @param  pfnProgress  a function to report progress of the json data loading.
 * @param  pProgressArg application data passed into progress function.
 * @return              true on success. If error occurred it can be received using CPLGetLastErrorMsg method.
 *
 * @since GDAL 2.3
 */
bool CPLJSONDocument::LoadChunks(const std::string &osPath, size_t nChunkSize,
                                 GDALProgressFunc pfnProgress,
                                 void *pProgressArg)
{
    VSIStatBufL sStatBuf;
    if(VSIStatL( osPath.c_str(), &sStatBuf ) != 0)
    {
        CPLError(CE_Failure, CPLE_FileIO, "Cannot open %s", osPath.c_str());
        return false;
    }

    VSILFILE *fp = VSIFOpenL( osPath.c_str(), "rb" );
    if( fp == nullptr )
    {
        CPLError(CE_Failure, CPLE_FileIO, "Cannot open %s", osPath.c_str());
        return false;
    }

    void *pBuffer = CPLMalloc( nChunkSize );
    json_tokener *tok = json_tokener_new();
    bool bSuccess = true;
    GUInt32 nFileSize = static_cast<GUInt32>(sStatBuf.st_size);
    double dfTotalRead = 0.0;

    while( true )
    {
        size_t nRead = VSIFReadL( pBuffer, 1, nChunkSize, fp );
        dfTotalRead += nRead;

        if( m_poRootJsonObject )
            json_object_put( TO_JSONOBJ(m_poRootJsonObject) );

        m_poRootJsonObject = json_tokener_parse_ex(tok,
                                                   static_cast<const char*>(pBuffer),
                                                   static_cast<int>(nRead));

        enum json_tokener_error jerr = json_tokener_get_error(tok);
        if(jerr != json_tokener_continue && jerr != json_tokener_success)
        {
            CPLError( CE_Failure, CPLE_AppDefined, "JSON error: %s",
                     json_tokener_error_desc(jerr) );
            bSuccess = false;
            break;
        }

        if( nRead < nChunkSize )
        {
            break;
        }

        if( nullptr != pfnProgress )
        {
            pfnProgress(dfTotalRead / nFileSize, "Loading ...", pProgressArg);
        }
    }

    json_tokener_free(tok);
    CPLFree(pBuffer);
    VSIFCloseL(fp);

    if( nullptr != pfnProgress )
    {
        pfnProgress(1.0, "Loading ...", pProgressArg);
    }

    return bSuccess;
}
Exemplo n.º 28
0
GDALDataset *GSBGDataset::CreateCopy( const char *pszFilename,
				      GDALDataset *poSrcDS,
				      int bStrict, char **papszOptions,
				      GDALProgressFunc pfnProgress,
				      void *pProgressData )
{
    if( pfnProgress == NULL )
	pfnProgress = GDALDummyProgress;

    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GSBG driver does not support source dataset with zero band.\n");
        return NULL;
    }
    else if (nBands > 1)
    {
	if( bStrict )
	{
	    CPLError( CE_Failure, CPLE_NotSupported,
		      "Unable to create copy, Golden Software Binary Grid "
		      "format only supports one raster band.\n" );
	    return NULL;
	}
	else
	    CPLError( CE_Warning, CPLE_NotSupported,
		      "Golden Software Binary Grid format only supports one "
		      "raster band, first band will be copied.\n" );
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 );
    if( poSrcBand->GetXSize() > SHRT_MAX
	|| poSrcBand->GetYSize() > SHRT_MAX )
    {
	CPLError( CE_Failure, CPLE_IllegalArg,
		  "Unable to create grid, Golden Software Binary Grid format "
		  "only supports sizes up to %dx%d.  %dx%d not supported.\n",
		  SHRT_MAX, SHRT_MAX,
		  poSrcBand->GetXSize(), poSrcBand->GetYSize() );

	return NULL;
    }

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" );
        return NULL;
    }

    VSILFILE    *fp = VSIFOpenL( pszFilename, "w+b" );

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

    GInt16  nXSize = (GInt16) poSrcBand->GetXSize();
    GInt16  nYSize = (GInt16) poSrcBand->GetYSize();
    double  adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2;
    double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0];
    double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3];
    double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2;
    CPLErr eErr = WriteHeader( fp, nXSize, nYSize,
			       dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 );

    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Copy band data.							*/
/* -------------------------------------------------------------------- */
    float *pfData = (float *)VSIMalloc2( nXSize, sizeof( float ) );
    if( pfData == NULL )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to create copy, unable to allocate line buffer.\n" );
	return NULL;
    }

    int     bSrcHasNDValue;
    float   fSrcNoDataValue = (float) poSrcBand->GetNoDataValue( &bSrcHasNDValue );
    double  dfMinZ = DBL_MAX;
    double  dfMaxZ = -DBL_MAX;
    for( GInt16 iRow = nYSize - 1; iRow >= 0; iRow-- )
    {
	eErr = poSrcBand->RasterIO( GF_Read, 0, iRow,
				    nXSize, 1, pfData,
				    nXSize, 1, GDT_Float32, 0, 0 );

	if( eErr != CE_None )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    return NULL;
	}

	for( int iCol=0; iCol<nXSize; iCol++ )
	{
	    if( bSrcHasNDValue && pfData[iCol] == fSrcNoDataValue )
	    {
		pfData[iCol] = fNODATA_VALUE;
	    }
	    else
	    {
		if( pfData[iCol] > dfMaxZ )
		    dfMaxZ = pfData[iCol];

		if( pfData[iCol] < dfMinZ )
		    dfMinZ = pfData[iCol];
	    }

	    CPL_LSBPTR32( pfData+iCol );
	}

	if( VSIFWriteL( (void *)pfData, 4, nXSize,
			fp ) != static_cast<unsigned>(nXSize) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write grid row. Disk full?\n" );
	    return NULL;
	}

	if( !pfnProgress( static_cast<double>(nYSize - iRow)/nYSize,
			  NULL, pProgressData ) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
	    return NULL;
	}
    }

    VSIFree( pfData );

    /* write out the min and max values */
    eErr = WriteHeader( fp, nXSize, nYSize,
			dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ );

    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
        return NULL;
    }

    VSIFCloseL( fp );

    GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename,
                                                GA_Update );
    if (poDS)
    {
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
    }
    return poDS;
}
Exemplo n.º 29
0
int OGRSEGUKOOADataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (bUpdateIn)
    {
        return FALSE;
    }

    pszName = CPLStrdup( pszFilename );

    VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
    if (fp == NULL)
        return FALSE;

    const char* pszLine;
    CPLPushErrorHandler(CPLQuietErrorHandler);
    pszLine = CPLReadLine2L(fp,81,NULL);
    CPLPopErrorHandler();
    CPLErrorReset();

    /* Both UKOOA P1/90 and SEG-P1 begins by a H character */
    if (pszLine == NULL || pszLine[0] != 'H')
    {
        VSIFCloseL(fp);
        return FALSE;
    }

// --------------------------------------------------------------------
//      Does this appear to be a UKOOA P1/90 file?
// --------------------------------------------------------------------

    if (strncmp(pszLine, "H0100 ", 6) == 0)
    {
        VSIFSeekL( fp, 0, SEEK_SET );

        VSILFILE* fp2 = VSIFOpenL(pszFilename, "rb");
        if (fp2 == NULL)
        {
            VSIFCloseL(fp);
            return FALSE;
        }

        nLayers = 2;
        papoLayers = (OGRLayer**) CPLMalloc(2 * sizeof(OGRLayer*));
        papoLayers[0] = new OGRUKOOAP190Layer(pszName, fp);
        papoLayers[1] = new OGRSEGUKOOALineLayer(pszName,
                                         new OGRUKOOAP190Layer(pszName, fp2));

        return TRUE;
    }

// --------------------------------------------------------------------
//      Does this appear to be a SEG-P1 file?
// --------------------------------------------------------------------

    /* Check first 20 header lines, and fetch the first point */
    for(int iLine = 0; iLine < 21; iLine ++)
    {
        const char* szPtr = pszLine;
        for(;*szPtr != '\0';szPtr++)
        {
            if (*szPtr != 9 && *szPtr < 32)
            {
                VSIFCloseL(fp);
                return FALSE;
            }
        }

        if (iLine == 20)
            break;

        CPLPushErrorHandler(CPLQuietErrorHandler);
        pszLine = CPLReadLine2L(fp,81,NULL);
        CPLPopErrorHandler();
        CPLErrorReset();
        if (pszLine == NULL)
        {
            VSIFCloseL(fp);
            return FALSE;
        }
    }

    char* pszExpandedLine = OGRSEGP1Layer::ExpandTabs(pszLine);
    int nLatitudeCol = OGRSEGP1Layer::DetectLatitudeColumn(pszExpandedLine);
    CPLFree(pszExpandedLine);

    if (nLatitudeCol > 0)
    {
        VSIFSeekL( fp, 0, SEEK_SET );

        VSILFILE* fp2 = VSIFOpenL(pszFilename, "rb");
        if (fp2 == NULL)
        {
            VSIFCloseL(fp);
            return FALSE;
        }

        nLayers = 2;
        papoLayers = (OGRLayer**) CPLMalloc(2 * sizeof(OGRLayer*));
        papoLayers[0] = new OGRSEGP1Layer(pszName, fp, nLatitudeCol);
        papoLayers[1] = new OGRSEGUKOOALineLayer(pszName,
                                         new OGRSEGP1Layer(pszName, fp2,
                                                           nLatitudeCol));

        return TRUE;
    }

    VSIFCloseL(fp);
    return FALSE;
}
Exemplo n.º 30
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 );
}