Exemplo n.º 1
0
int OGRGPSBabelDataSource::Open( const char * pszDatasourceName,
                                 const char* pszGPSBabelDriverNameIn,
                                 char** papszOpenOptions )

{
    int bExplicitFeatures = FALSE;
    int bWaypoints = TRUE, bTracks = TRUE, bRoutes = TRUE;

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

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

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

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

    pszName = CPLStrdup( pszDatasourceName );

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

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

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

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

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

            if (bErr)
                return FALSE;

            pszSep = pszNextSep;
        }

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

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

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

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

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

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

        CSLDestroy(argv);
        argv = NULL;

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

        VSIFCloseL(tmpfp);
        tmpfp = NULL;

        VSIFCloseL(fp);
        fp = NULL;

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

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

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


    if (bRet)
    {
        poGPXDS = (GDALDataset*) GDALOpenEx(osTmpFileName.c_str(),
                                            GDAL_OF_VECTOR, NULL, NULL, NULL);
        if (poGPXDS)
        {
            OGRLayer* poLayer;

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

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

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

    return nLayers > 0;
}
Exemplo n.º 2
0
/**********************************************************************
 *                   IMapInfoFile::SmartOpen()
 *
 * Use this static method to automatically open any flavour 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 = NULL;
    int nLen = 0;

    if (pszFname)
        nLen = 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.
         *------------------------------------------------------------*/
        VSILFILE *fp;
        const char *pszLine;
        char *pszAdjFname = CPLStrdup(pszFname);
        GBool bFoundFields = FALSE, bFoundView=FALSE, bFoundSeamless=FALSE;

        TABAdjustFilenameExtension(pszAdjFname);
        fp = VSIFOpenL(pszAdjFname, "r");
        while(fp && (pszLine = CPLReadLineL(fp)) != NULL)
        {
            while (isspace((unsigned char)*pszLine))  pszLine++;
            if (EQUALN(pszLine, "Fields", 6))
                bFoundFields = TRUE;
            else if (EQUALN(pszLine, "create view", 11))
                bFoundView = TRUE;
            else if (EQUALN(pszLine, "\"\\IsSeamless\" = \"TRUE\"", 21))
                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 = NULL;
    }

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

    return poFile;
}
Exemplo n.º 3
0
OGRErr OGRPolygon::exportToWkt( char ** ppszDstText ) const

{
    char        **papszRings;
    int         iRing, nCumulativeLength = 0, nNonEmptyRings = 0;
    OGRErr      eErr;
    int         bMustWriteComma = FALSE;

/* -------------------------------------------------------------------- */
/*      If we have no valid exterior ring, return POLYGON EMPTY.        */
/* -------------------------------------------------------------------- */
    if (getExteriorRing() == NULL ||
        getExteriorRing()->IsEmpty())
    {
        *ppszDstText = CPLStrdup("POLYGON EMPTY");
        return OGRERR_NONE;
    }

/* -------------------------------------------------------------------- */
/*      Build a list of strings containing the stuff for each ring.     */
/* -------------------------------------------------------------------- */
    papszRings = (char **) CPLCalloc(sizeof(char *),nRingCount);

    for( iRing = 0; iRing < nRingCount; iRing++ )
    {
        papoRings[iRing]->setCoordinateDimension( getCoordinateDimension() );
        if( papoRings[iRing]->getNumPoints() == 0 )
        {
            papszRings[iRing] = NULL;
            continue;
        }

        eErr = papoRings[iRing]->exportToWkt( &(papszRings[iRing]) );
        if( eErr != OGRERR_NONE )
            goto error;

        CPLAssert( EQUALN(papszRings[iRing],"LINEARRING (", 12) );
        nCumulativeLength += strlen(papszRings[iRing] + 11);

        nNonEmptyRings++;
    }

/* -------------------------------------------------------------------- */
/*      Allocate exactly the right amount of space for the              */
/*      aggregated string.                                              */
/* -------------------------------------------------------------------- */
    *ppszDstText = (char *) VSIMalloc(nCumulativeLength + nNonEmptyRings + 11);

    if( *ppszDstText == NULL )
    {
        eErr = OGRERR_NOT_ENOUGH_MEMORY;
        goto error;
    }

/* -------------------------------------------------------------------- */
/*      Build up the string, freeing temporary strings as we go.        */
/* -------------------------------------------------------------------- */
    strcpy( *ppszDstText, "POLYGON (" );
    nCumulativeLength = strlen(*ppszDstText);

    for( iRing = 0; iRing < nRingCount; iRing++ )
    {                                                           
        if( papszRings[iRing] == NULL )
        {
            CPLDebug( "OGR", "OGRPolygon::exportToWkt() - skipping empty ring.");
            continue;
        }

        if( bMustWriteComma )
            (*ppszDstText)[nCumulativeLength++] = ',';
        bMustWriteComma = TRUE;
        
        int nRingLen = strlen(papszRings[iRing] + 11);
        memcpy( *ppszDstText + nCumulativeLength, papszRings[iRing] + 11, nRingLen );
        nCumulativeLength += nRingLen;
        VSIFree( papszRings[iRing] );
    }

    (*ppszDstText)[nCumulativeLength++] = ')';
    (*ppszDstText)[nCumulativeLength] = '\0';

    CPLFree( papszRings );

    return OGRERR_NONE;

error:
    for( iRing = 0; iRing < nRingCount; iRing++ )
        CPLFree(papszRings[iRing]);
    CPLFree(papszRings);
    return eErr;
}
Exemplo n.º 4
0
CPLErr GDALWriteRPBFile( const char *pszFilename, char **papszMD )

{
    CPLString osRPBFilename = CPLResetExtension( pszFilename, "RPB" );


/* -------------------------------------------------------------------- */
/*      Read file and parse.                                            */
/* -------------------------------------------------------------------- */
    VSILFILE *fp = VSIFOpenL( osRPBFilename, "w" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Unable to create %s for writing.\n%s",
                  osRPBFilename.c_str(), CPLGetLastErrorMsg() );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Write the prefix information.                                   */
/* -------------------------------------------------------------------- */
    VSIFPrintfL( fp, "%s", "satId = \"QB02\";\n" );
    VSIFPrintfL( fp, "%s", "bandId = \"P\";\n" );
    VSIFPrintfL( fp, "%s", "SpecId = \"RPC00B\";\n" );
    VSIFPrintfL( fp, "%s", "BEGIN_GROUP = IMAGE\n" );
    VSIFPrintfL( fp, "%s", "\terrBias = 0.0;\n" );
    VSIFPrintfL( fp, "%s", "\terrRand = 0.0;\n" );

/* -------------------------------------------------------------------- */
/*      Write RPC values from our RPC metadata.                         */
/* -------------------------------------------------------------------- */
    int i;

    for( i = 0; apszRPBMap[i] != NULL; i += 2 )
    {
        const char *pszRPBVal = CSLFetchNameValue( papszMD, apszRPBMap[i] );
        const char *pszRPBTag;

        if( pszRPBVal == NULL )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "%s field missing in metadata, %s file not written.",
                      apszRPBMap[i], osRPBFilename.c_str() );
            VSIFCloseL( fp );
            VSIUnlink( osRPBFilename );
            return CE_Failure;
        }

        pszRPBTag = apszRPBMap[i+1];
        if( EQUALN(pszRPBTag,"IMAGE.",6) )
            pszRPBTag += 6;

        if( strstr(apszRPBMap[i], "COEF" ) == NULL )
        {
            VSIFPrintfL( fp, "\t%s = %s;\n", pszRPBTag, pszRPBVal );
        }
        else
        {
            // Reformat in brackets with commas over multiple lines.

            VSIFPrintfL( fp, "\t%s = (\n", pszRPBTag );

            char **papszItems = CSLTokenizeStringComplex( pszRPBVal, " ,",
                                                          FALSE, FALSE );

            if( CSLCount(papszItems) != 20 )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "%s field is corrupt (not 20 values), %s file not written.\n%s = %s",
                          apszRPBMap[i], osRPBFilename.c_str(),
                          apszRPBMap[i], pszRPBVal );
                VSIFCloseL( fp );
                VSIUnlink( osRPBFilename );
                CSLDestroy( papszItems );
                return CE_Failure;
            }

            int j;

            for( j = 0; j < 20; j++ )
            {
                if( j < 19 )
                    VSIFPrintfL( fp, "\t\t\t%s,\n", papszItems[j] );
                else
                    VSIFPrintfL( fp, "\t\t\t%s);\n", papszItems[j] );
            }
            CSLDestroy( papszItems );
        }
    }

/* -------------------------------------------------------------------- */
/*      Write end part                                                  */
/* -------------------------------------------------------------------- */
    VSIFPrintfL( fp, "%s", "END_GROUP = IMAGE\n" );
    VSIFPrintfL( fp, "END;\n" );
    VSIFCloseL( fp );

    return CE_None;
}
Exemplo n.º 5
0
GDALDataset *FujiBASDataset::Open( GDALOpenInfo * poOpenInfo )

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

    if( !EQUALN((const char *)poOpenInfo->pabyHeader,"[Raw data]",10)
        || strstr((const char *)poOpenInfo->pabyHeader, "Fuji BAS") == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*	Load the header file.						*/
/* -------------------------------------------------------------------- */
    char	**papszHeader;
    int		nXSize, nYSize;
    const char  *pszOrgFile;

    papszHeader = CSLLoad( poOpenInfo->pszFilename );

    if( papszHeader == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Munge header information into form suitable for CSL functions.  */
/* -------------------------------------------------------------------- */
    int		i;

    for( i = 0; papszHeader[i] != NULL; i++ )
    {
        char	*pszSep = strstr(papszHeader[i]," = ");

        if( pszSep != NULL )
        {
            memmove( pszSep + 1, pszSep + 3, strlen(pszSep+3)+1 );
            *pszSep = '=';
        }
    }

/* -------------------------------------------------------------------- */
/*      Fetch required fields.                                          */
/* -------------------------------------------------------------------- */
    if( CSLFetchNameValue(papszHeader, "width") == NULL
        || CSLFetchNameValue(papszHeader, "height") == NULL
        || CSLFetchNameValue(papszHeader, "OrgFile") == NULL )
    {
        CSLDestroy( papszHeader );
        return NULL;
    }

    nYSize = atoi(CSLFetchNameValue(papszHeader,"width"));
    nXSize = atoi(CSLFetchNameValue(papszHeader,"height"));

    pszOrgFile = CSLFetchNameValue(papszHeader,"OrgFile");

    if( nXSize < 1 || nYSize < 1 )
    {
        CSLDestroy( papszHeader );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The FUJIBAS driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Try to open the original data file.                             */
/* -------------------------------------------------------------------- */
    const char *pszRawFile;
    char       *pszPath = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename));
    FILE       *fpRaw;
    
    pszRawFile = CPLFormCIFilename( pszPath, pszOrgFile, "IMG" );
    CPLFree( pszPath );
    
    fpRaw = VSIFOpen( pszRawFile, "rb" );
    if( fpRaw == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Trying to open Fuji BAS image with the header file:\n"
                  "  Header=%s\n"
                  "but expected raw image file doesn't appear to exist.  Trying to open:\n"
                  "  Raw File=%s\n"
                  "Perhaps the raw file needs to be renamed to match expected?",
                  poOpenInfo->pszFilename, 
                  pszRawFile );
        CSLDestroy( papszHeader );
        return NULL;
    }

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

    poDS = new FujiBASDataset();

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nXSize;
    poDS->nRasterYSize = nYSize;
    poDS->papszHeader = papszHeader;
    poDS->fpImage = fpRaw;

/* -------------------------------------------------------------------- */
/*      Create band information object.                                 */
/* -------------------------------------------------------------------- */
    int bNativeOrder;
#ifdef CPL_MSB
    bNativeOrder = TRUE;
#else
    bNativeOrder = FALSE;
#endif
    poDS->SetBand( 1, 
                   new RawRasterBand( poDS, 1, poDS->fpImage, 
                                      0, 2, nXSize * 2, GDT_UInt16, bNativeOrder ));

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();
    
/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
Exemplo n.º 6
0
/*
** Fetch a nomads forecast from the NWS servers.  The forecasts consist of grib
** files, one forecast for each forecast hour.  The time starts and the nearest
** forecast hour *before* the reference time passed.  If no reference time is
** passed, or it is not valid, now() is used.
**
** The forecasts are downloaded into a temporary directory.  If the entire
** download succeeds, then the files are copied into the path specified.  If
** the path specified is a zip file (ends in *.zip), then the forecast files
** are zipped.
**
** Available compile time configuration options:
**        NOMADS_USE_IP: Use the ip address instead of the hostname.  It
**                       possibly goes around dns lookup, but it's doubtfull.
**        NOMADS_ENABLE_ASYNC: Allow for asynchronous connections to the
**                             server.
**        NOMADS_EXPER_FORECASTS: Compile in forecasts that may not work with
**                                the current configuration, essentially
**                                unsupported (ie NARRE, RTMA).
**        NOMADS_USE_VSI_READ: Use the VSI*L api for downloading.  This will
**                             allow definition of chunk sizes for download,
**                             although it is probably unnecessary.  See
**                             NOMADS_VSI_BLOCK_SIZE below.  If not enabled, a
**                             single fetch is made for each file, which is
**                             faster.
** Available runtime configuration options:
**        NOMADS_THREAD_COUNT: Number of threads to use for downloads if
**                             NOMADS_ENABLE_ASYNC is set to ON during
**                             compilation.  Default is 4.
**        NOMADS_VSI_BLOCK_SIZE: Number of bytes to request at a time when
**                               downloading files if NOMADS_USE_VSI_READ is
**                               set to ON during compilation. Default is 512.
**        NOMADS_MAX_FCST_REWIND: Number of forecast run time steps to go back
**                                to attempt to get a full time frame.
**        GDAL_HTTP_TIMEOUT: Timeout for HTTP requests in seconds.  We should
**                           be able to set this reasonably low.
**
** \param pszModelKey The name key of the model to use, ie "nam_conus".  For a
**                    listing of models, see nomads.ncep.gov or /see nomads.h
**
** \param pszRefTime The reference time to begin searching for forecasts from.
**                   The search starts at refrence time, then goes back until
**                   it hits a valid forecast time.  If the download cannot be
**                   complete, it will step back NOMADS_MAX_FCST_REWIND
**                   foreacst times to attempt to get a full forecast.
**
** \param nHours The extent of hours to download forecasts from the reference
**               time.  If we step back, we will still grab all forecasts up
**               until nHours from the reference time, not the forecast time.
**
** \param nStride The number of forecasts to skip in time steps.  For example,
**                if 12 hours of gfs is requested (normally 5 files/steps (0,
**                3, 6, 9, 12) with a stride of 2, you'd get 0, 6, 12 forecast
**                hours.
**
** \param padfBbox The bounding box of the request in WGS84 decimal degrees.
**                 Order is xmin, xmax, ymax, ymin.
**
** \param pszDstVsiPath The location to write the files.  If the location
**                      has an extension of ".zip", then the output files are
**                      written as a zip archive, otherwise to a path.
**
** \param papszOptions List of key=value options, unused.
**
** \param pfnProgress Optional progress function.
**
** \return NOMADS_OK(0) on success, NOMADS_ERR(1) otherwise.
*/
int NomadsFetch( const char *pszModelKey, const char *pszRefTime,
                 int nHours, int nStride, double *padfBbox,
                 const char *pszDstVsiPath, char ** papszOptions,
                 GDALProgressFunc pfnProgress )
{
    const char **ppszKey = NULL;
    int nFcstHour = 0;
    int *panRunHours = NULL;
    int i = 0;
    int j = 0;
    int k = 0;
    int t = 0;
    int rc = 0;
    char **papszDownloadUrls = NULL;
    char **papszOutputFiles = NULL;
    char **papszFinalFiles = NULL;
    int nFilesToGet = 0;
    const char *pszTmpDir;
    const char *pszConfigOpt;
    int nFcstTries;
    int nMaxFcstRewind;
    int nrc;
    int bZip;
    void **pThreads;
    int nThreads;
    const char *pszThreadCount;

    NomadsThreadData *pasData;
    nomads_utc *ref, *end, *fcst;
    nrc = NOMADS_OK;

    CPLDebug( "NOMADS", "Fetching data for bounding box: %lf, %lf, %lf, %lf",
              padfBbox[0], padfBbox[1], padfBbox[2], padfBbox[3] );

    ppszKey = NomadsFindModel( pszModelKey );
    if( ppszKey == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Could not find model key in nomads data" );
        return NOMADS_ERR;
    }

    NomadsUtcCreate( &ref );
    NomadsUtcCreate( &end );
    rc = NOMADS_OK;
    if( pszRefTime )
    {
        rc = NomadsUtcFromIsoFrmt( ref, pszRefTime );
    }
    if( rc != NOMADS_OK || pszRefTime == NULL )
    {
        NomadsUtcNow( ref );
    }
    NomadsUtcCopy( end, ref );
    NomadsUtcAddHours( end, nHours );

    /* Disable unneeded reading of entire directories, good speedup */
    CPLSetConfigOption( "GDAL_DISABLE_READDIR_ON_OPEN", "TRUE" );

    pszConfigOpt = CPLGetConfigOption( "NOMADS_HTTP_TIMEOUT", "20" );
    if( pszConfigOpt != NULL )
    {
        CPLSetConfigOption( "GDAL_HTTP_TIMEOUT", pszConfigOpt );
    }

    nMaxFcstRewind = atoi( CPLGetConfigOption( "NOMADS_MAX_FCST_REWIND", "2" ) );
    if( nMaxFcstRewind < 1 || nMaxFcstRewind > 24 )
    {
        nMaxFcstRewind = 2;
    }
    /* Go back at least 3 for rap, as it may not get updated all the time. */
    if( EQUALN( pszModelKey, "rap", 3 ) || EQUALN( pszModelKey, "hrrr", 4 ) )
    {
        nMaxFcstRewind = nMaxFcstRewind > 3 ? nMaxFcstRewind : 3;
    }

#ifdef NOMADS_ENABLE_ASYNC
    pszThreadCount = CPLGetConfigOption( "NOMADS_THREAD_COUNT", "4" );
    nThreads = atoi( pszThreadCount );
    if( nThreads < 1 || nThreads > 96 )
    {
        nThreads = 4;
    }
    pThreads = CPLMalloc( sizeof( void * ) * nThreads );
    pasData = CPLMalloc( sizeof( NomadsThreadData ) * nThreads );
#else /* NOMADS_ENABLE_ASYNC */
    /* Unused variables, set to null to so free is no-op */
    nThreads = 1;
    pThreads = NULL;
    pasData = NULL;
#endif /* NOMADS_ENABLE_ASYNC */

    fcst = NULL;
    nFcstTries = 0;
    while( nFcstTries < nMaxFcstRewind )
    {
        nrc = NOMADS_OK;
        fcst = NomadsSetForecastTime( ppszKey, ref, nFcstTries );
        nFcstHour = fcst->ts->tm_hour;
        CPLDebug( "WINDNINJA", "Generated forecast time in utc: %s",
                  NomadsUtcStrfTime( fcst, "%Y%m%dT%HZ" ) );

        if( EQUAL( pszModelKey, "rtma_conus" ) )
        {
            panRunHours = (int*)CPLMalloc( sizeof( int ) );
            nFilesToGet = 1;
        }
        else
        {
            nFilesToGet =
                NomadsBuildForecastRunHours( ppszKey, fcst, end, nHours,
                                             nStride, &panRunHours );
        }

        papszDownloadUrls =
            NomadsBuildForecastFileList( pszModelKey, nFcstHour, panRunHours,
                                         nFilesToGet, fcst, padfBbox );
        if( papszDownloadUrls == NULL )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Could not generate list of URLs to download, invalid data" );
            nFcstTries++;
            NomadsUtcFree( fcst );
            fcst = NULL;
            nrc = NOMADS_ERR;
            continue;
        }
        pszTmpDir = CPLStrdup( CPLGenerateTempFilename( NULL ) );
        CPLDebug( "WINDNINJA", "Creating Temp directory: %s", pszTmpDir );
        VSIMkdir( pszTmpDir, 0777 );
        papszOutputFiles =
            NomadsBuildOutputFileList( pszModelKey, nFcstHour, panRunHours,
                                       nFilesToGet, pszTmpDir, FALSE );
        if( papszOutputFiles == NULL )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Could not generate list of URLs to download, invalid data" );
            nFcstTries++;
            CSLDestroy( papszDownloadUrls );
            NomadsUtcFree( fcst );
            fcst = NULL;
            nrc = NOMADS_ERR;
            continue;
        }

        CPLAssert( CSLCount( papszDownloadUrls ) == nFilesToGet );
        CPLAssert( CSLCount( papszOutputFiles ) == nFilesToGet );

        if( pfnProgress )
        {
            pfnProgress( 0.0, "Starting download...", NULL );
        }

        /* Download one file and start over if it's not there. */
#ifdef NOMADS_USE_VSI_READ
        nrc = NomadsFetchVsi( papszDownloadUrls[0], papszOutputFiles[0] );
#else /* NOMADS_USE_VSI_READ */
        nrc = NomadsFetchHttp( papszDownloadUrls[0], papszOutputFiles[0] );
#endif /* NOMADS_USE_VSI_READ */
        if( nrc != NOMADS_OK )
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Failed to download forecast, " \
                      "stepping back one forecast run time step." );
            nFcstTries++;
            CPLSleep( 1 );
            /*
            ** Don't explicitly break here.  We'll skip the while loop because
            ** nrc != NOMADS_OK, and we can clean up memory and shift times in
            ** one spot to avoid duplicate code.
            */
        }
        /* Get the rest */
        i = 1;
        while( i < nFilesToGet && nrc == NOMADS_OK )
        {
            if( pfnProgress )
            {
                if( pfnProgress( (double)i / nFilesToGet,
                                 CPLSPrintf( "Downloading %s...",
                                             CPLGetFilename( papszOutputFiles[i] ) ),
                                 NULL ) )
                {
                    CPLError( CE_Failure, CPLE_UserInterrupt,
                              "Cancelled by user." );
                    nrc = NOMADS_ERR;
                    nFcstTries = nMaxFcstRewind;
                    break;
                }
            }
#ifdef NOMADS_ENABLE_ASYNC
            k = i > nFilesToGet - nThreads ? (nFilesToGet - 1) % nThreads : nThreads;
            for( t = 0; t < k; t++ )
            {
                pasData[t].pszUrl = papszDownloadUrls[i];
                pasData[t].pszFilename = papszOutputFiles[i];
                pThreads[t] =
                    CPLCreateJoinableThread( NomadsFetchAsync, &pasData[t] );
                i++;
            }
            for( t = 0; t < k; t++ )
            {
                CPLJoinThread( pThreads[t] );
            }
            for( t = 0; t < k; t++ )
            {
                if( pasData[t].nErr )
                {
                    CPLError( CE_Warning, CPLE_AppDefined,
                              "Threaded download failed, attempting " \
                              "serial download for %s",
                              CPLGetFilename( pasData[t].pszFilename ) );
                    /* Try again, serially though */
                    if( CPLCheckForFile( (char *)pasData[t].pszFilename, NULL ) );
                    {
                        VSIUnlink( pasData[t].pszFilename );
                    }
#ifdef NOMADS_USE_VSI_READ
                    rc = NomadsFetchVsi( pasData[t].pszUrl,
                                         pasData[t].pszFilename );
#else /* NOMADS_USE_VSI_READ */
                    rc = NomadsFetchHttp( pasData[t].pszUrl,
                                          pasData[t].pszFilename );
#endif /* NOMADS_USE_VSI_READ */
                    if( rc != NOMADS_OK )
                    {
                        nrc = rc;
                    }
                }
            }
#else /* NOMADS_ENABLE_ASYNC */
#ifdef NOMADS_USE_VSI_READ
            nrc = NomadsFetchVsi( papszDownloadUrls[i], papszOutputFiles[i] );
#else /* NOMADS_USE_VSI_READ */
            nrc = NomadsFetchHttp( papszDownloadUrls[i], papszOutputFiles[i] );
#endif /* NOMADS_USE_VSI_READ */
            i++;
#endif /* NOMADS_ENABLE_ASYNC */
            if( nrc != NOMADS_OK )
            {
                CPLError( CE_Warning, CPLE_AppDefined,
                          "Failed to download forecast, " \
                          "stepping back one forecast run time step." );
                nFcstTries++;
                CPLSleep( 1 );
                break;
            }
        }
        /*
        ** XXX Cleanup XXX
        ** After each loop we can get rid of the urls, but we can only get rid
        ** of the others if they are to be reallocated in the next loop.  Any
        ** cleanup in the else nrc == NOMADS_OK clause should be cleaned up in 
        ** the nrc == NOMADS_OK outside the loop.  Those are held so we can
        ** process the output files and zip them into an archive.
        */
        CSLDestroy( papszDownloadUrls );
        NomadsUtcFree( fcst );
        if( nrc == NOMADS_OK )
        {
            break;
        }
        else
        {
            CPLFree( (void*)panRunHours );
            CSLDestroy( papszOutputFiles );
            CPLUnlinkTree( pszTmpDir );
            CPLFree( (void*)pszTmpDir );
        }
    }
    if( nrc == NOMADS_OK )
    {
        bZip = EQUAL( CPLGetExtension( pszDstVsiPath ), "zip" ) ? TRUE : FALSE;
        papszFinalFiles =
            NomadsBuildOutputFileList( pszModelKey, nFcstHour, panRunHours,
                                       nFilesToGet, pszDstVsiPath,
                                       bZip );
        CPLFree( (void*)panRunHours );
        if( CPLCheckForFile( (char*)pszDstVsiPath, NULL ) )
        {
            CPLUnlinkTree( pszDstVsiPath );
        }
        if( !bZip )
        {
            VSIMkdir( pszDstVsiPath, 0777 );
        }
        nrc = NomadsZipFiles( papszOutputFiles, papszFinalFiles );
        CSLDestroy( papszOutputFiles );
        CSLDestroy( papszFinalFiles );
        if( nrc != NOMADS_OK )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Could not copy files into path, unknown i/o failure" );
            CPLUnlinkTree( pszDstVsiPath );
        }
        CPLUnlinkTree( pszTmpDir );
        CPLFree( (void*)pszTmpDir );
    }
    CPLFree( (void*)pasData );
    CPLFree( (void**)pThreads );

    NomadsUtcFree( ref );
    NomadsUtcFree( end );
    CPLSetConfigOption( "GDAL_HTTP_TIMEOUT", NULL );
    CPLSetConfigOption( "GDAL_DISABLE_READDIR_ON_OPEN", NULL );
    if( nrc == NOMADS_OK && pfnProgress )
    {
        pfnProgress( 1.0, NULL, NULL );
    }
    return nrc;
}
Exemplo n.º 7
0
GDALDataset *GXFDataset::Open( GDALOpenInfo * poOpenInfo )

{
    GXFHandle	hGXF;
    int		i, bFoundKeyword, bFoundIllegal;
    
/* -------------------------------------------------------------------- */
/*      Before trying GXFOpen() we first verify that there is at        */
/*      least one "\n#keyword" type signature in the first chunk of     */
/*      the file.                                                       */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->fp == NULL || poOpenInfo->nHeaderBytes < 50 )
        return NULL;

    bFoundKeyword = FALSE;
    bFoundIllegal = FALSE;
    for( i = 0; i < poOpenInfo->nHeaderBytes-1; i++ )
    {
        if( (poOpenInfo->pabyHeader[i] == 10
             || poOpenInfo->pabyHeader[i] == 13)
            && poOpenInfo->pabyHeader[i+1] == '#' )
        {
            bFoundKeyword = TRUE;
        }
        if( poOpenInfo->pabyHeader[i] == 0 )
        {
            bFoundIllegal = TRUE;
            break;
        }
    }

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

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

    char *pszBigBuf = (char *) CPLMalloc(BIGBUFSIZE);
    nBytesRead = VSIFRead( pszBigBuf, 1, BIGBUFSIZE, fp );
    VSIFClose( fp );

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

    CPLFree( pszBigBuf );

    if( !bGotGrid )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Try opening the dataset.                                        */
/* -------------------------------------------------------------------- */
    
    hGXF = GXFOpen( poOpenInfo->pszFilename );
    
    if( hGXF == NULL )
        return( NULL );
        
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        GXFClose(hGXF);
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The GXF driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    GXFDataset 	*poDS;

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

    poDS->hGXF = hGXF;
    poDS->eDataType = eDT;
    
/* -------------------------------------------------------------------- */
/*	Establish the projection.					*/
/* -------------------------------------------------------------------- */
    poDS->pszProjection = GXFGetMapProjectionAsOGCWKT( hGXF );

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

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

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

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

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

    return( poDS );
}
Exemplo n.º 8
0
CPLErr VRTRasterBand::XMLInit( CPLXMLNode * psTree, 
                               const char *pszVRTPath )

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

/* -------------------------------------------------------------------- */
/*      Set the band if provided as an attribute.                       */
/* -------------------------------------------------------------------- */
    const char* pszBand = CPLGetXMLValue( psTree, "band", NULL);
    if( pszBand != NULL )
    {
        nBand = atoi(pszBand);
    }

/* -------------------------------------------------------------------- */
/*      Set the band if provided as an attribute.                       */
/* -------------------------------------------------------------------- */
    const char *pszDataType = CPLGetXMLValue( psTree, "dataType", NULL);
    if( pszDataType != NULL )
    {
        eDataType = GDALGetDataTypeByName(pszDataType);
    }

/* -------------------------------------------------------------------- */
/*      Apply any band level metadata.                                  */
/* -------------------------------------------------------------------- */
    oMDMD.XMLInit( psTree, TRUE );

/* -------------------------------------------------------------------- */
/*      Collect various other items of metadata.                        */
/* -------------------------------------------------------------------- */
    SetDescription( CPLGetXMLValue( psTree, "Description", "" ) );
    
    if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL )
        SetNoDataValue( CPLAtofM(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );

    if( CPLGetXMLValue( psTree, "HideNoDataValue", NULL ) != NULL )
        bHideNoDataValue = CSLTestBoolean( CPLGetXMLValue( psTree, "HideNoDataValue", "0" ) );

    SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL ) );

    SetOffset( CPLAtof(CPLGetXMLValue( psTree, "Offset", "0.0" )) );
    SetScale( CPLAtof(CPLGetXMLValue( psTree, "Scale", "1.0" )) );

    if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL )
    {
        const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL );
        SetColorInterpretation(GDALGetColorInterpretationByName(pszInterp));
    }

/* -------------------------------------------------------------------- */
/*      Category names.                                                 */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL )
    {
        CPLXMLNode *psEntry;

        CSLDestroy( papszCategoryNames );
        papszCategoryNames = NULL;

        CPLStringList oCategoryNames;

        for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild;
             psEntry != NULL; psEntry = psEntry->psNext )
        {
            if( psEntry->eType != CXT_Element 
                || !EQUAL(psEntry->pszValue,"Category") 
                || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) )
                continue;
            
            oCategoryNames.AddString(
                                (psEntry->psChild) ? psEntry->psChild->pszValue : "");
        }

        papszCategoryNames = oCategoryNames.StealList();
    }

/* -------------------------------------------------------------------- */
/*      Collect a color table.                                          */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL )
    {
        CPLXMLNode *psEntry;
        GDALColorTable oTable;
        int        iEntry = 0;

        for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild;
             psEntry != NULL; psEntry = psEntry->psNext )
        {
            GDALColorEntry sCEntry;

            sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" ));
            sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" ));
            sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" ));
            sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" ));

            oTable.SetColorEntry( iEntry++, &sCEntry );
        }
        
        SetColorTable( &oTable );
    }

/* -------------------------------------------------------------------- */
/*      Histograms                                                      */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" );
    if( psHist != NULL )
    {
        CPLXMLNode *psNext = psHist->psNext;
        psHist->psNext = NULL;

        psSavedHistograms = CPLCloneXMLTree( psHist );
        psHist->psNext = psNext;
    }

/* ==================================================================== */
/*      Overviews                                                       */
/* ==================================================================== */
    CPLXMLNode *psNode;

    for( psNode = psTree->psChild; psNode != NULL; psNode = psNode->psNext )
    {
        if( psNode->eType != CXT_Element
            || !EQUAL(psNode->pszValue,"Overview") )
            continue;

/* -------------------------------------------------------------------- */
/*      Prepare filename.                                               */
/* -------------------------------------------------------------------- */
        char *pszSrcDSName = NULL;
        CPLXMLNode* psFileNameNode=CPLGetXMLNode(psNode,"SourceFilename");
        const char *pszFilename = 
            psFileNameNode ? CPLGetXMLValue(psFileNameNode,NULL, NULL) : NULL;

        if( pszFilename == NULL )
        {
            CPLError( CE_Warning, CPLE_AppDefined, 
                      "Missing <SourceFilename> element in Overview." );
            return CE_Failure;
        }

        if (EQUALN(pszFilename, "MEM:::", 6) && pszVRTPath != NULL &&
            !CSLTestBoolean(CPLGetConfigOption("VRT_ALLOW_MEM_DRIVER", "NO")))
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                    "<SourceFilename> points to a MEM dataset, which is rather suspect! "
                    "If you know what you are doing, define the VRT_ALLOW_MEM_DRIVER configuration option to YES" );
            return CE_Failure;
        }

        if( pszVRTPath != NULL
            && atoi(CPLGetXMLValue( psFileNameNode, "relativetoVRT", "0")) )
        {
            pszSrcDSName = CPLStrdup(
                CPLProjectRelativeFilename( pszVRTPath, pszFilename ) );
        }
        else
            pszSrcDSName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Get the raster band.                                            */
/* -------------------------------------------------------------------- */
        int nSrcBand = atoi(CPLGetXMLValue(psNode,"SourceBand","1"));

        apoOverviews.resize( apoOverviews.size() + 1 );
        apoOverviews[apoOverviews.size()-1].osFilename = pszSrcDSName;
        apoOverviews[apoOverviews.size()-1].nBand = nSrcBand;
        
        CPLFree( pszSrcDSName );
    }

/* ==================================================================== */
/*      Mask band (specific to that raster band)                        */
/* ==================================================================== */
    CPLXMLNode* psMaskBandNode = CPLGetXMLNode(psTree, "MaskBand");
    if (psMaskBandNode)
        psNode = psMaskBandNode->psChild;
    else
        psNode = NULL;
    for( ; psNode != NULL; psNode = psNode->psNext )
    {
        if( psNode->eType != CXT_Element
            || !EQUAL(psNode->pszValue,"VRTRasterBand") )
            continue;

        if( ((VRTDataset*)poDS)->poMaskBand != NULL)
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                       "Illegal mask band at raster band level when a dataset mask band already exists." );
            break;
        }

        const char *pszSubclass = CPLGetXMLValue( psNode, "subclass",
                                                    "VRTSourcedRasterBand" );
        VRTRasterBand  *poBand = NULL;

        if( EQUAL(pszSubclass,"VRTSourcedRasterBand") )
            poBand = new VRTSourcedRasterBand( GetDataset(), 0 );
        else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") )
            poBand = new VRTDerivedRasterBand( GetDataset(), 0 );
        else if( EQUAL(pszSubclass, "VRTRawRasterBand") )
            poBand = new VRTRawRasterBand( GetDataset(), 0 );
        else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") )
            poBand = new VRTWarpedRasterBand( GetDataset(), 0 );
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                        "VRTRasterBand of unrecognised subclass '%s'.",
                        pszSubclass );
            break;
        }


        if( poBand->XMLInit( psNode, pszVRTPath ) == CE_None )
        {
            SetMaskBand(poBand);
        }

        break;
    }

    return CE_None;
}
Exemplo n.º 9
0
GDALDataset *MEMDataset::Open( GDALOpenInfo * poOpenInfo )

{
    char    **papszOptions;

/* -------------------------------------------------------------------- */
/*      Do we have the special filename signature for MEM format        */
/*      description strings?                                            */
/* -------------------------------------------------------------------- */
    if( !EQUALN(poOpenInfo->pszFilename,"MEM:::",6) 
        || poOpenInfo->fpL != NULL )
        return NULL;

    papszOptions = CSLTokenizeStringComplex(poOpenInfo->pszFilename+6, ",",
                                            TRUE, FALSE );

/* -------------------------------------------------------------------- */
/*      Verify we have all required fields                              */
/* -------------------------------------------------------------------- */
    if( CSLFetchNameValue( papszOptions, "PIXELS" ) == NULL
        || CSLFetchNameValue( papszOptions, "LINES" ) == NULL
        || CSLFetchNameValue( papszOptions, "DATAPOINTER" ) == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
              "Missing required field (one of PIXELS, LINES or DATAPOINTER)\n"
              "Unable to access in-memory array." );

        CSLDestroy( papszOptions );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create the new MEMDataset object.                               */
/* -------------------------------------------------------------------- */
    MEMDataset *poDS;

    poDS = new MEMDataset();

    poDS->nRasterXSize = atoi(CSLFetchNameValue(papszOptions,"PIXELS"));
    poDS->nRasterYSize = atoi(CSLFetchNameValue(papszOptions,"LINES"));
    poDS->eAccess = GA_Update;

/* -------------------------------------------------------------------- */
/*      Extract other information.                                      */
/* -------------------------------------------------------------------- */
    const char *pszOption;
    GDALDataType eType;
    int nBands, nPixelOffset, nLineOffset;
    size_t nBandOffset;
    const char *pszDataPointer;
    GByte *pabyData;

    pszOption = CSLFetchNameValue(papszOptions,"BANDS");
    if( pszOption == NULL )
        nBands = 1;
    else
    {
        nBands = atoi(pszOption);
    }

    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
        !GDALCheckBandCount(nBands, TRUE))
    {
        CSLDestroy( papszOptions );
        delete poDS;
        return NULL;
    }

    pszOption = CSLFetchNameValue(papszOptions,"DATATYPE");
    if( pszOption == NULL )
        eType = GDT_Byte;
    else
    {
        if( atoi(pszOption) > 0 && atoi(pszOption) < GDT_TypeCount )
            eType = (GDALDataType) atoi(pszOption);
        else
        {
            int iType;
            
            eType = GDT_Unknown;
            for( iType = 0; iType < GDT_TypeCount; iType++ )
            {
                if( EQUAL(GDALGetDataTypeName((GDALDataType) iType),
                          pszOption) )
                {
                    eType = (GDALDataType) iType;
                    break;
                }
            }
            
            if( eType == GDT_Unknown )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "DATATYPE=%s not recognised.", 
                          pszOption );
                CSLDestroy( papszOptions );
                delete poDS;
                return NULL;
            }
        }
    }

    pszOption = CSLFetchNameValue(papszOptions,"PIXELOFFSET");
    if( pszOption == NULL )
        nPixelOffset = GDALGetDataTypeSize(eType) / 8;
    else
        nPixelOffset = atoi(pszOption);

    pszOption = CSLFetchNameValue(papszOptions,"LINEOFFSET");
    if( pszOption == NULL )
        nLineOffset = poDS->nRasterXSize * nPixelOffset;
    else
        nLineOffset = atoi(pszOption);

    pszOption = CSLFetchNameValue(papszOptions,"BANDOFFSET");
    if( pszOption == NULL )
        nBandOffset = nLineOffset * (size_t) poDS->nRasterYSize;
    else
        nBandOffset = atoi(pszOption);

    pszDataPointer = CSLFetchNameValue(papszOptions,"DATAPOINTER");
    pabyData = (GByte *) CPLScanPointer( pszDataPointer, 
                                         strlen(pszDataPointer) );

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    for( int iBand = 0; iBand < nBands; iBand++ )
    {
        poDS->SetBand( iBand+1, 
                       new MEMRasterBand( poDS, iBand+1, 
                                          pabyData + iBand * nBandOffset,
                                          eType, nPixelOffset, nLineOffset, 
                                          FALSE ) );
    }

/* -------------------------------------------------------------------- */
/*      Try to return a regular handle on the file.                     */
/* -------------------------------------------------------------------- */
    CSLDestroy( papszOptions );
    return poDS;
}
Exemplo n.º 10
0
char* VSIArchiveFilesystemHandler::SplitFilename(const char *pszFilename,
                                                 CPLString &osFileInArchive,
                                                 int bCheckMainFileExists)
{
    int i = 0;

    if (strcmp(pszFilename, GetPrefix()) == 0)
        return NULL;

    /* Allow natural chaining of VSI drivers without requiring double slash */
    
    CPLString osDoubleVsi(GetPrefix());
    osDoubleVsi += "/vsi";
    
    if (strncmp(pszFilename, osDoubleVsi.c_str(), osDoubleVsi.size()) == 0)
        pszFilename += strlen(GetPrefix());
    else
        pszFilename += strlen(GetPrefix()) + 1;

    while(pszFilename[i])
    {
        std::vector<CPLString> oExtensions = GetExtensions();
        std::vector<CPLString>::const_iterator iter;
        int nToSkip = 0;

        for( iter = oExtensions.begin(); iter != oExtensions.end(); ++iter )
        {
            const CPLString& osExtension = *iter;
            if (EQUALN(pszFilename + i, osExtension.c_str(), strlen(osExtension.c_str())))
            {
                nToSkip = strlen(osExtension.c_str());
                break;
            }
        }

        if (nToSkip != 0)
        {
            VSIStatBufL statBuf;
            char* archiveFilename = CPLStrdup(pszFilename);
            int bArchiveFileExists = FALSE;

            if (archiveFilename[i + nToSkip] == '/' ||
                archiveFilename[i + nToSkip] == '\\')
            {
                archiveFilename[i + nToSkip] = 0;
            }

            if (!bCheckMainFileExists)
            {
                bArchiveFileExists = TRUE;
            }
            else
            {
                CPLMutexHolder oHolder( &hMutex );

                if (oFileList.find(archiveFilename) != oFileList.end() )
                {
                    bArchiveFileExists = TRUE;
                }
            }

            if (!bArchiveFileExists)
            {
                VSIFilesystemHandler *poFSHandler = 
                    VSIFileManager::GetHandler( archiveFilename );
                if (poFSHandler->Stat(archiveFilename, &statBuf,
                                      VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG) == 0 &&
                    !VSI_ISDIR(statBuf.st_mode))
                {
                    bArchiveFileExists = TRUE;
                }
            }

            if (bArchiveFileExists)
            {
                if (pszFilename[i + nToSkip] == '/' ||
                    pszFilename[i + nToSkip] == '\\')
                {
                    char* pszArchiveInFileName = CPLStrdup(pszFilename + i + nToSkip + 1);

                    /* Replace a/../b by b and foo/a/../b by foo/b */
                    while(TRUE)
                    {
                        char* pszPrevDir = strstr(pszArchiveInFileName, "/../");
                        if (pszPrevDir == NULL || pszPrevDir == pszArchiveInFileName)
                            break;

                        char* pszPrevSlash = pszPrevDir - 1;
                        while(pszPrevSlash != pszArchiveInFileName &&
                                *pszPrevSlash != '/')
                            pszPrevSlash --;
                        if (pszPrevSlash == pszArchiveInFileName)
                            memmove(pszArchiveInFileName, pszPrevDir + nToSkip, strlen(pszPrevDir + nToSkip) + 1);
                        else
                            memmove(pszPrevSlash + 1, pszPrevDir + nToSkip, strlen(pszPrevDir + nToSkip) + 1);
                    }

                    osFileInArchive = pszArchiveInFileName;
                    CPLFree(pszArchiveInFileName);
                }
                else
                    osFileInArchive = "";

                /* Remove trailing slash */
                if (strlen(osFileInArchive))
                {
                    char lastC = osFileInArchive[strlen(osFileInArchive) - 1];
                    if (lastC == '\\' || lastC == '/')
                        osFileInArchive[strlen(osFileInArchive) - 1] = 0;
                }

                return archiveFilename;
            }
            CPLFree(archiveFilename);
        }
        i++;
    }
    return NULL;
}
Exemplo n.º 11
0
int OGRCARTODBDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (!EQUALN(pszFilename, "CARTODB:", strlen("CARTODB:")))
        return FALSE;

    bReadWrite = bUpdateIn;

    pszName = CPLStrdup( pszFilename );
    pszAccount = CPLStrdup(pszFilename + strlen("CARTODB:"));
    char* pchSpace = strchr(pszAccount, ' ');
    if( pchSpace )
        *pchSpace = '\0';

    osAPIKey = CPLGetConfigOption("CARTODB_API_KEY", "");

    CPLString osTables = OGRCARTODBGetOptionValue(pszFilename, "tables");

    bUseHTTPS = CSLTestBoolean(CPLGetConfigOption("CARTODB_HTTPS", "YES"));

    if (osTables.size() != 0)
    {
        char** papszTables = CSLTokenizeString2(osTables, ",", 0);
        for(int i=0;papszTables && papszTables[i];i++)
        {
            papoLayers = (OGRLayer**) CPLRealloc(
                papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
            papoLayers[nLayers ++] = new OGRCARTODBTableLayer(this, papszTables[i]);
        }
        CSLDestroy(papszTables);
        return TRUE;
    }
    
    if( osAPIKey.size() == 0 )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "When not specifying tables option, CARTODB_API_KEY must be defined");
        return FALSE;
    }

    json_object* poObj = RunSQL("SELECT CDB_UserTables()");
    if( poObj == NULL )
        return FALSE;
    json_object* poRows = json_object_object_get(poObj, "rows");
    if( poRows == NULL || json_object_get_type(poRows) != json_type_array)
    {
        json_object_put(poObj);
        return FALSE;
    }
    for(int i=0; i < json_object_array_length(poRows); i++)
    {
        json_object* poTableNameObj = json_object_array_get_idx(poRows, i);
        if( poTableNameObj != NULL &&
            json_object_get_type(poTableNameObj) == json_type_object )
        {
            json_object* poVal = json_object_object_get(poTableNameObj, "cdb_usertables");
            if( poVal != NULL &&
                json_object_get_type(poVal) == json_type_string )
            {
                papoLayers = (OGRLayer**) CPLRealloc(
                    papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
                papoLayers[nLayers ++] = new OGRCARTODBTableLayer(
                            this, json_object_get_string(poVal));
            }
        }
    }
    json_object_put(poObj);

    return TRUE;
}
Exemplo n.º 12
0
GDALDataset *SDEDataset::Open( GDALOpenInfo * poOpenInfo )

{
    
/* -------------------------------------------------------------------- */
/*      If we aren't prefixed with SDE: then ignore this datasource.    */
/* -------------------------------------------------------------------- */
    if( !EQUALN(poOpenInfo->pszFilename,"SDE:",4) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Parse arguments on comma.  We expect (layer is optional):       */
/*        SDE:server,instance,database,username,password,layer          */
/* -------------------------------------------------------------------- */
    char **papszTokens = CSLTokenizeStringComplex(  poOpenInfo->pszFilename+4, 
                                                    ",",
                                                    TRUE, 
                                                    TRUE );
    CPLDebug(   "SDERASTER", "Open(\"%s\") revealed %d tokens.", 
                poOpenInfo->pszFilename,
                CSLCount( papszTokens ) );


    if( CSLCount( papszTokens ) < 5 || CSLCount( papszTokens ) > 7 )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "SDE connect string had wrong number of arguments.\n"
                  "Expected 'SDE:server,instance,database,username,password,layer'\n"
                  "The layer name value is optional.\n"
                  "Got '%s'", 
                  poOpenInfo->pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */

    SDEDataset *poDS;

    poDS = new SDEDataset();
/* -------------------------------------------------------------------- */
/*      Try to establish connection.                                    */
/* -------------------------------------------------------------------- */
    int         nSDEErr;
    SE_ERROR    hSDEErrorInfo;
    nSDEErr = SE_connection_create( papszTokens[0], 
                                    papszTokens[1], 
                                    papszTokens[2], 
                                    papszTokens[3],
                                    papszTokens[4],
                                    &(hSDEErrorInfo), 
                                    &(poDS->hConnection) );

    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_connection_create" );
        return NULL;
    }


/* -------------------------------------------------------------------- */
/*      Set unprotected concurrency policy, suitable for single         */
/*      threaded access.                                                */
/* -------------------------------------------------------------------- */
    nSDEErr = SE_connection_set_concurrency( poDS->hConnection,
                                             SE_UNPROTECTED_POLICY);

    if( nSDEErr != SE_SUCCESS) {
        IssueSDEError( nSDEErr, NULL );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      If we were given a layer name, use that directly, otherwise     */
/*      query for subdatasets.                                          */
/* -------------------------------------------------------------------- */

    // Get the RASTER column name if it was set
    if (CSLCount (papszTokens) == 7) {
        poDS->pszColumnName = CPLStrdup( papszTokens[6] );
    }
    else {
        poDS->pszColumnName = CPLStrdup( "RASTER" );
    }
    
    CPLDebug ("SDERASTER", "SDE Column name is '%s'", poDS->pszColumnName);

    if (CSLCount( papszTokens ) >= 6 ) {

        poDS->pszLayerName = CPLStrdup( papszTokens[5] );

        
        nSDEErr =   SE_rascolinfo_create  (&(poDS->hRasterColumn));
        if( nSDEErr != SE_SUCCESS )
        {
            IssueSDEError( nSDEErr, "SE_rastercolumn_create" );
            return NULL;
        }
        CPLDebug( "SDERASTER", "'%s' raster layer specified... "\
                               "using it directly with '%s' as the raster column name.", 
                  poDS->pszLayerName,
                  poDS->pszColumnName);
        nSDEErr = SE_rastercolumn_get_info_by_name( poDS->hConnection, 
                                                    poDS->pszLayerName, 
                                                    poDS->pszColumnName, 
                                                    poDS->hRasterColumn);
        if( nSDEErr != SE_SUCCESS )
        {
            IssueSDEError( nSDEErr, "SE_rastercolumn_get_info_by_name" );
            return NULL;
        }
        poDS->ComputeRasterInfo();



    } else {
 
        nSDEErr = SE_rastercolumn_get_info_list(poDS->hConnection, 
                                                &(poDS->paohSDERasterColumns), 
                                                &(poDS->nSubDataCount));
        if( nSDEErr != SE_SUCCESS )
        {
            IssueSDEError( nSDEErr, "SE_rascolinfo_get_info_list" );
            return NULL;
        }

        CPLDebug( "SDERASTER", "No layername specified, %d subdatasets available.", 
                  poDS->nSubDataCount);
                  

        for (int i = 0; i < poDS->nSubDataCount; i++) {

              char         szTableName[SE_QUALIFIED_TABLE_NAME+1];
              char         szColumnName[SE_MAX_COLUMN_LEN+1];
            nSDEErr = SE_rascolinfo_get_raster_column (poDS->paohSDERasterColumns[i], 
                                                       szTableName, 
                                                       szColumnName); 
            CPLDebug(   "SDERASTER", 
                        "Layer '%s' with column '%s' found.", 
                        szTableName, 
                        szColumnName);

            if( nSDEErr != SE_SUCCESS )
            {
                IssueSDEError( nSDEErr, "SE_rascolinfo_get_raster_column" );
                return NULL;
            }
        }

    return NULL;
    }
    CSLDestroy( papszTokens);
    return( poDS );
}
Exemplo n.º 13
0
CPLErr OGRIDBLayer::BuildFeatureDefn( const char *pszLayerName, 
                                    ITCursor *poCurr )

{
    poFeatureDefn = new OGRFeatureDefn( pszLayerName );
    const ITTypeInfo * poInfo = poCurr->RowType();
    int    nRawColumns = poInfo->ColumnCount();

    poFeatureDefn->Reference();

    for( int iCol = 0; iCol < nRawColumns; iCol++ )
    {
        const char * pszColName = poInfo->ColumnName(iCol);
        const ITTypeInfo * poTI = poInfo->ColumnType(iCol);
        const char * pszTypName = poTI->Name();

        OGRFieldDefn    oField( pszColName, OFTString );

        oField.SetWidth( MAX(0,poTI->Bound()) );

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

        if ( EQUALN("st_", pszTypName, 3) && pszGeomColumn == NULL )
        {
            // We found spatial column!
            pszGeomColumn = CPLStrdup(pszColName);

            if ( EQUAL("st_point", pszTypName) )
                poFeatureDefn->SetGeomType( wkbPoint );
            else if ( EQUAL("st_linestring", pszTypName) )
                poFeatureDefn->SetGeomType( wkbLineString );
            else if ( EQUAL("st_polygon", pszTypName) )
                poFeatureDefn->SetGeomType( wkbPolygon );
            else if ( EQUAL("st_multipoint", pszTypName) )
                poFeatureDefn->SetGeomType( wkbMultiPoint );
            else if ( EQUAL("st_multilinestring", pszTypName) )
                poFeatureDefn->SetGeomType( wkbMultiLineString );
            else if ( EQUAL("st_multipolygon", pszTypName) )
                poFeatureDefn->SetGeomType( wkbMultiPolygon );

            continue;
        }

        // Check other field types
        if ( EQUAL( pszTypName, "blob" ) ||
             EQUAL( pszTypName, "byte" ) ||
             EQUAL( pszTypName, "opaque" ) ||
             EQUAL( pszTypName, "text" ) ||
             EQUALN( pszTypName, "list", 4 ) ||
             EQUALN( pszTypName, "collection", 10 ) ||
             EQUALN( pszTypName, "row", 3 ) ||
             EQUALN( pszTypName, "set", 3 ) )
        {
            CPLDebug( "OGR_IDB", "'%s' column type not supported yet. Column '%s'",
                      pszTypName, pszColName );
            continue;
        }

        if ( EQUALN( pszTypName, "st_", 3 ) )
        {
            oField.SetType( OFTBinary );
        }
        else if ( EQUAL( pszTypName, "date" ) )
        {
            oField.SetType( OFTDate );
        }
        else if ( EQUAL( pszTypName, "datetime" ) )
        {
            oField.SetType( OFTDateTime );
        }
        else if ( EQUAL( pszTypName, "decimal" ) ||
                  EQUAL( pszTypName, "money" ) ||
                  EQUAL( pszTypName, "float" ) ||
                  EQUAL( pszTypName, "smallfloat" ) )
        {
            oField.SetType( OFTReal );
            oField.SetPrecision( MAX( 0, poTI->Scale() ) ); // -1 for numeric
        }
        else if ( EQUAL( pszTypName, "integer" ) ||
                  EQUAL( pszTypName, "serial" ) )
        {
            oField.SetType( OFTInteger );
            // 10 as hardcoded max int32 value length + 1 sig bit
            oField.SetWidth( 11 );
        }
        else if ( EQUAL( pszTypName, "smallint" ) )
        {
            oField.SetType( OFTInteger );
            // 5 as hardcoded max int16 value length + 1 sig bit
            oField.SetWidth( 6 );
        }
        else
        {
            // leave as string:
            // *char, character, character varing, *varchar
            // interval. int8, serial8
        }

        poFeatureDefn->AddFieldDefn( &oField );
    }

/* -------------------------------------------------------------------- */
/*      If we don't already have an FID, check if there is a special    */
/*      FID named column available.                                     */
/* -------------------------------------------------------------------- */
    if( pszFIDColumn == NULL )
    {
        const char *pszOGR_FID = CPLGetConfigOption("IDB_OGR_FID","OGR_FID");
        if( poFeatureDefn->GetFieldIndex( pszOGR_FID ) != -1 )
            pszFIDColumn = CPLStrdup(pszOGR_FID);
    }

    if( pszFIDColumn != NULL )
        CPLDebug( "OGR_IDB", "Using column %s as FID for table %s.",
                  pszFIDColumn, poFeatureDefn->GetName() );
    else
        CPLDebug( "OGR_IDB", "Table %s has no identified FID column.",
                  poFeatureDefn->GetName() );

    return CE_None;
}
Exemplo n.º 14
0
CPLErr GDALParseGMLCoverage( CPLXMLNode *psXML, 
                             int *pnXSize, int *pnYSize,
                             double *padfGeoTransform,
                             char **ppszProjection )

{
    CPLStripXMLNamespace( psXML, NULL, TRUE );

/* -------------------------------------------------------------------- */
/*      Isolate RectifiedGrid.  Eventually we will need to support      */
/*      other georeferencing objects.                                   */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRG = CPLSearchXMLNode( psXML, "=RectifiedGrid" );
    CPLXMLNode *psOriginPoint = NULL;
    const char *pszOffset1=NULL, *pszOffset2=NULL;

    if( psRG != NULL )
    {
        psOriginPoint = CPLGetXMLNode( psRG, "origin.Point" );
        if( psOriginPoint == NULL )
            psOriginPoint = CPLGetXMLNode( psRG, "origin" );

        CPLXMLNode *psOffset1 = CPLGetXMLNode( psRG, "offsetVector" );
        if( psOffset1 != NULL )
        {
            pszOffset1 = CPLGetXMLValue( psOffset1, "", NULL );
            pszOffset2 = CPLGetXMLValue( psOffset1->psNext, "=offsetVector", 
                                         NULL );
        }
    }

/* -------------------------------------------------------------------- */
/*      If we are missing any of the origin or 2 offsets then give up.  */
/* -------------------------------------------------------------------- */
    if( psRG == NULL || psOriginPoint == NULL 
        || pszOffset1 == NULL || pszOffset2 == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unable to find GML RectifiedGrid, origin or offset vectors");
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Search for the GridEnvelope and derive the raster size.         */
/* -------------------------------------------------------------------- */
    char **papszLow = CSLTokenizeString(
        CPLGetXMLValue( psRG, "limits.GridEnvelope.low", ""));
    char **papszHigh = CSLTokenizeString(
        CPLGetXMLValue( psRG, "limits.GridEnvelope.high",""));

    if( CSLCount(papszLow) < 2 || CSLCount(papszHigh) < 2 )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Unable to find or parse GridEnvelope.low/high." );
        return CE_Failure;
    }        

    if( pnXSize != NULL )
        *pnXSize = atoi(papszHigh[0]) - atoi(papszLow[0]) + 1;
    if( pnYSize != NULL )
        *pnYSize = atoi(papszHigh[1]) - atoi(papszLow[1]) + 1;

    CSLDestroy( papszLow );
    CSLDestroy( papszHigh );

/* -------------------------------------------------------------------- */
/*      Extract origin location.                                        */
/* -------------------------------------------------------------------- */
    OGRPoint *poOriginGeometry = NULL;
    const char *pszSRSName = NULL;

    if( psOriginPoint != NULL )
    {
        int bOldWrap = FALSE;

        // old coverages (ie. WCS) just have <pos> under <origin> so we
        // may need to temporarily force <origin> to <Point>
        if( psOriginPoint->eType == CXT_Element
            && EQUAL(psOriginPoint->pszValue,"origin") )
        {
            strcpy( psOriginPoint->pszValue, "Point");
            bOldWrap = TRUE;
        }
        poOriginGeometry = (OGRPoint *) 
            OGR_G_CreateFromGMLTree( psOriginPoint );

        if( poOriginGeometry != NULL 
            && wkbFlatten(poOriginGeometry->getGeometryType()) != wkbPoint )
        {
            delete poOriginGeometry;
            poOriginGeometry = NULL;
        }

        if( bOldWrap )
            strcpy( psOriginPoint->pszValue, "origin");

        // SRS?
        pszSRSName = CPLGetXMLValue( psOriginPoint, "srsName", NULL );
    }

/* -------------------------------------------------------------------- */
/*      Extract offset(s)                                               */
/* -------------------------------------------------------------------- */
    char **papszOffset1Tokens = NULL;
    char **papszOffset2Tokens = NULL;
    int bSuccess = FALSE;

    papszOffset1Tokens = 
        CSLTokenizeStringComplex( pszOffset1, " ,", FALSE, FALSE );
    papszOffset2Tokens = 
        CSLTokenizeStringComplex( pszOffset2, " ,", FALSE, FALSE );

    if( CSLCount(papszOffset1Tokens) >= 2
        && CSLCount(papszOffset2Tokens) >= 2
        && poOriginGeometry != NULL )
    {
        padfGeoTransform[0] = poOriginGeometry->getX();
        padfGeoTransform[1] = CPLAtof(papszOffset1Tokens[0]);
        padfGeoTransform[2] = CPLAtof(papszOffset1Tokens[1]);
        padfGeoTransform[3] = poOriginGeometry->getY();
        padfGeoTransform[4] = CPLAtof(papszOffset2Tokens[0]);
        padfGeoTransform[5] = CPLAtof(papszOffset2Tokens[1]);

        // offset from center of pixel.
        padfGeoTransform[0] -= padfGeoTransform[1]*0.5;
        padfGeoTransform[0] -= padfGeoTransform[2]*0.5;
        padfGeoTransform[3] -= padfGeoTransform[4]*0.5;
        padfGeoTransform[3] -= padfGeoTransform[5]*0.5;

        bSuccess = TRUE;
        //bHaveGeoTransform = TRUE;
    }

    CSLDestroy( papszOffset1Tokens );
    CSLDestroy( papszOffset2Tokens );

    if( poOriginGeometry != NULL )
        delete poOriginGeometry;

/* -------------------------------------------------------------------- */
/*      If we have gotten a geotransform, then try to interprete the    */
/*      srsName.                                                        */
/* -------------------------------------------------------------------- */
    if( bSuccess && pszSRSName != NULL 
        && (*ppszProjection == NULL || strlen(*ppszProjection) == 0) )
    {
        if( EQUALN(pszSRSName,"epsg:",5) )
        {
            OGRSpatialReference oSRS;
            if( oSRS.SetFromUserInput( pszSRSName ) == OGRERR_NONE )
                oSRS.exportToWkt( ppszProjection );
        }
        else if( EQUALN(pszSRSName,"urn:ogc:def:crs:",16) )
        {
            OGRSpatialReference oSRS;
            if( oSRS.importFromURN( pszSRSName ) == OGRERR_NONE )
                oSRS.exportToWkt( ppszProjection );
        }
        else
            *ppszProjection = CPLStrdup(pszSRSName);
    }

    if( *ppszProjection )
        CPLDebug( "GDALJP2Metadata", 
                  "Got projection from GML box: %s", 
                  *ppszProjection );

    return CE_None;
}
Exemplo n.º 15
0
GDALDataset *TerragenDataset::Open( GDALOpenInfo * poOpenInfo )

{
    // The file should have at least 32 header bytes
    if( poOpenInfo->nHeaderBytes < 32 )
        return NULL;

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


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

    poDS = new TerragenDataset();

    // Reopen for large file access.
    if( poOpenInfo->eAccess == GA_Update )
        poDS->m_fp = VSIFOpenL( poOpenInfo->pszFilename, "rb+" );
    else
        poDS->m_fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( poDS->m_fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to re-open %s within Terragen driver.\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }
    poDS->eAccess = poOpenInfo->eAccess;

    
/* -------------------------------------------------------------------- */
/*	Read the file.							*/
/* -------------------------------------------------------------------- */
    if( !poDS->LoadFromFile() )
    {
        delete poDS;
        return NULL;
    }

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

    poDS->SetMetadataItem( GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT );

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

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

    return( poDS );
}
Exemplo n.º 16
0
CPLString ACTextUnescape( const char *pszRawInput, const char *pszEncoding )

{
    CPLString osResult;
    CPLString osInput = pszRawInput;
    
/* -------------------------------------------------------------------- */
/*      Translate text from Win-1252 to UTF8.  We approximate this      */
/*      by treating Win-1252 as Latin-1.  Note that we likely ought     */
/*      to be consulting the $DWGCODEPAGE header variable which         */
/*      defaults to ANSI_1252 if not set.                               */
/* -------------------------------------------------------------------- */
    osInput.Recode( pszEncoding, CPL_ENC_UTF8 );

    const char *pszInput = osInput.c_str();

/* -------------------------------------------------------------------- */
/*      Now translate escape sequences.  They are all plain ascii       */
/*      characters and won't have been affected by the UTF8             */
/*      recoding.                                                       */
/* -------------------------------------------------------------------- */
    while( *pszInput != '\0' )
    {
        if( pszInput[0] == '\\' && pszInput[1] == 'P' )
        {
            osResult += '\n';
            pszInput++;
        }
        else if( pszInput[0] == '\\' && pszInput[1] == '~' )
        {
            osResult += ' ';
            pszInput++;
        }
        else if( pszInput[0] == '\\' && pszInput[1] == 'U' 
                 && pszInput[2] == '+' )
        {
            CPLString osHex;
            int iChar;

            osHex.assign( pszInput+3, 4 );
            sscanf( osHex.c_str(), "%x", &iChar );

            wchar_t anWCharString[2];
            anWCharString[0] = (wchar_t) iChar;
            anWCharString[1] = 0;
            
            char *pszUTF8Char = CPLRecodeFromWChar( anWCharString,
                                                    CPL_ENC_UCS2, 
                                                    CPL_ENC_UTF8 );

            osResult += pszUTF8Char;
            CPLFree( pszUTF8Char );
            
            pszInput += 6;
        }
        else if( pszInput[0] == '\\'
                 && (pszInput[1] == 'W' 
                     || pszInput[1] == 'T'
                     || pszInput[1] == 'A' ) )
        {
            // eg. \W1.073172x;\T1.099;Bonneuil de Verrines
            // See data/dwg/EP/42002.dwg
            // Not sure what \W and \T do, but we skip them. 
            // According to qcad rs_text.cpp, \A values are vertical
            // alignment, 0=bottom, 1=mid, 2=top but we ignore for now.
            
            while( *pszInput != ';' && *pszInput != '\0' )
                pszInput++;
        }
        else if( pszInput[0] == '\\' && pszInput[1] == '\\' )
        {
            osResult += '\\';
            pszInput++;
        }
        else if( EQUALN(pszInput,"%%c",3) 
                 || EQUALN(pszInput,"%%d",3)
                 || EQUALN(pszInput,"%%p",3) )
        {
            wchar_t anWCharString[2];

            anWCharString[1] = 0;

            // These are especial symbol representations for autocad.
            if( EQUALN(pszInput,"%%c",3) )
                anWCharString[0] = 0x2300; // diameter (0x00F8 is a good approx)
            else if( EQUALN(pszInput,"%%d",3) )
                anWCharString[0] = 0x00B0; // degree
            else if( EQUALN(pszInput,"%%p",3) )
                anWCharString[0] = 0x00B1; // plus/minus

            char *pszUTF8Char = CPLRecodeFromWChar( anWCharString,
                                                    CPL_ENC_UCS2, 
                                                    CPL_ENC_UTF8 );

            osResult += pszUTF8Char;
            CPLFree( pszUTF8Char );
            
            pszInput += 2;
        }
        else 
            osResult += *pszInput;

        pszInput++;
    }
    
    return osResult;
}
Exemplo n.º 17
0
OGRDataSource *OGRSQLiteDriver::Open( const char * pszFilename,
                                     int bUpdate )

{

/* -------------------------------------------------------------------- */
/*      Check VirtualShape:xxx.shp syntax                               */
/* -------------------------------------------------------------------- */
    int nLen = (int) strlen(pszFilename);
    if (EQUALN(pszFilename, "VirtualShape:", strlen( "VirtualShape:" )) &&
        nLen > 4 && EQUAL(pszFilename + nLen - 4, ".SHP"))
    {
        OGRSQLiteDataSource     *poDS;

        poDS = new OGRSQLiteDataSource();

        char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES");
        int nRet = poDS->Create( ":memory:", papszOptions );
        poDS->SetName(pszFilename);
        CSLDestroy(papszOptions);
        if (!nRet)
        {
            delete poDS;
            return NULL;
        }

        char* pszShapeFilename = CPLStrdup(pszFilename + strlen( "VirtualShape:" ));
        OGRDataSource* poShapeDS = OGRSFDriverRegistrar::Open(pszShapeFilename);
        if (poShapeDS == NULL)
        {
            CPLFree(pszShapeFilename);
            delete poDS;
            return NULL;
        }
        delete poShapeDS;

        char* pszLastDot = strrchr(pszShapeFilename, '.');
        if (pszLastDot)
            *pszLastDot = '\0';

        const char* pszTableName = CPLGetBasename(pszShapeFilename);

        char* pszSQL = CPLStrdup(CPLSPrintf("CREATE VIRTUAL TABLE %s USING VirtualShape(%s, CP1252, -1)",
                                            pszTableName, pszShapeFilename));
        poDS->ExecuteSQL(pszSQL, NULL, NULL);
        CPLFree(pszSQL);
        CPLFree(pszShapeFilename);
        return poDS;
    }

/* -------------------------------------------------------------------- */
/*      Verify that the target is a real file, and has an               */
/*      appropriate magic string at the beginning.                      */
/* -------------------------------------------------------------------- */
    if( !EQUAL(pszFilename, ":memory:") )
    {
        char szHeader[16];

#ifdef HAVE_SQLITE_VFS
        VSILFILE *fpDB;
        fpDB = VSIFOpenL( pszFilename, "rb" );
        if( fpDB == NULL )
            return NULL;
        
        if( VSIFReadL( szHeader, 1, 16, fpDB ) != 16 )
            memset( szHeader, 0, 16 );
        
        VSIFCloseL( fpDB );
#else
        FILE *fpDB;
        fpDB = VSIFOpen( pszFilename, "rb" );
        if( fpDB == NULL )
            return NULL;

        if( VSIFRead( szHeader, 1, 16, fpDB ) != 16 )
            memset( szHeader, 0, 16 );

        VSIFClose( fpDB );
#endif
    
        if( strncmp( szHeader, "SQLite format 3", 15 ) != 0 )
            return NULL;
    }

/* -------------------------------------------------------------------- */
/*      We think this is really an SQLite database, go ahead and try    */
/*      and open it.                                                    */
/* -------------------------------------------------------------------- */
    OGRSQLiteDataSource     *poDS;

    poDS = new OGRSQLiteDataSource();

    if( !poDS->Open( pszFilename, bUpdate ) )
    {
        delete poDS;
        return NULL;
    }
    else
        return poDS;
}
Exemplo n.º 18
0
int main()
{
    FILE *fpIn, *fpOut;
    const char *pszLine = NULL;
    int iFile = 0;

    if ((fpIn = fopen("mapinfow.prj", "r")) == NULL)
    {
        printf("mapinfow.prj not found.\n");
        exit(1);
    }

    while((pszLine = CPLReadLine(fpIn)) != NULL)
    {
        char **papszParams = CSLTokenizeStringComplex(pszLine, " ,", TRUE,FALSE);
        if (CSLCount(papszParams) >= 3 && 
            !EQUALN(papszParams[0], "---", 3))
        {
            int nProj = 0;
            int nDatum= 0;
            int nUnitsParamIndex = 0;

            if ((fpOut = fopen(CPLSPrintf("tttproj%04.4d.mif", iFile), "w")) == NULL)
            {
                printf("Failed creating MIF output file!\n");
                exit(2);
            }

            nProj = atoi(papszParams[1]);
            nDatum = atoi(papszParams[2]);
            if (nProj >= 1000)
            {
                printf("File tttproj%04.4d.mif uses projection %d ... \n"
                       "this case is not handled properly by this version\n",
                       iFile, nProj);
            }

            if (nProj == 1)
                nUnitsParamIndex = -1;  // No units for geographic proj.
            else if (nProj == 0)
            {
                nUnitsParamIndex = 2;   // NonEarth... units only.
                printf("File tttproj%04.4d.mif is NonEarth\n", iFile); 
            }
            else if (nDatum == 999 || nDatum == 9999)
            {
                nUnitsParamIndex = -1;  // Custom datum defn= 9999,x,x,x,x,...
                                        // Units are in numeric fmt
                                        // No conversion required.
                printf("File tttproj%04.4d.mif has custom datum\n", iFile); 
            }
            else
                nUnitsParamIndex = 3;

            fprintf(fpOut, "Version 300\n");
            fprintf(fpOut, "Charset \"WindowsLatin1\"\n");
            fprintf(fpOut, "Delimiter \",\"\n");
            if (nProj == 0)
                fprintf(fpOut, "CoordSys Nonearth ");
            else
                fprintf(fpOut, "CoordSys Earth Projection %d", nProj);

            for(int i=2; papszParams[i]!=NULL; i++)
            {
                if (i == nUnitsParamIndex)
                {
                    // Units string (except for proj=1: geographic)
                    const char *pszUnits = "???";
                    switch(atoi(papszParams[i]))
                    {
                      case 6:
                        pszUnits = "cm";
                        break;
                      case 31:
                        pszUnits = "ch";
                        break;
                      case 3:
                        pszUnits = "ft";
                        break;
                      case 2:
                        pszUnits = "in";
                        break;
                      case 1:
                        pszUnits = "km";
                        break;
                      case 30:
                        pszUnits = "li";
                        break;
                      case 7:
                        pszUnits = "m";
                        break;
                      case 0:
                        pszUnits = "mi";
                        break;
                      case 5:
                        pszUnits = "mm";
                        break;
                      case 9:
                        pszUnits = "nmi";
                        break;
                      case 32:
                        pszUnits = "rd";
                        break;
                      case 8:
                        pszUnits = "survey ft";
                        break;
                      case 4:
                        pszUnits = "yd";
                        break;
                      default:
                        printf("WARNING: Unsupported units type: %s in\n%s\n", papszParams[i], pszLine);
                        pszUnits = "m";
                        break;
                    }
                    if (nProj == 0)
                        fprintf(fpOut, "Units \"%s\" Bounds (-1,-1)(1,1)", pszUnits);
                    else
                        fprintf(fpOut, ", \"%s\"", pszUnits);
                }
                else
                    fprintf(fpOut, ", %s", papszParams[i]);
            }
            fprintf(fpOut, "\n");

            fprintf(fpOut, "Columns 1\n");
            fprintf(fpOut, "  ttt Char(10)\n");
            fprintf(fpOut, "Data\n");
            fprintf(fpOut, "POINT 0 0\n");

            fclose(fpOut);

            if ((fpOut = fopen(CPLSPrintf("tttproj%04.4d.mid", iFile++), "w")))
            {
                fprintf(fpOut, "ttt\n");
                fclose(fpOut);
            }

        }
        CSLDestroy(papszParams);
    }

}