Ejemplo n.º 1
0
const char *CPLGetBasename( const char *pszFullFilename )

{
    size_t  iFileStart = CPLFindFilenameStart( pszFullFilename );
    size_t  iExtStart, nLength;
    char    *pszStaticResult = CPLGetStaticResult();

    CPLAssert( ! (pszFullFilename >= pszStaticResult && pszFullFilename < pszStaticResult + CPL_PATH_BUF_SIZE) );

    for( iExtStart = strlen(pszFullFilename);
         iExtStart > iFileStart && pszFullFilename[iExtStart] != '.';
         iExtStart-- ) {}

    if( iExtStart == iFileStart )
        iExtStart = strlen(pszFullFilename);

    nLength = iExtStart - iFileStart;

    if (nLength >= CPL_PATH_BUF_SIZE)
        return CPLStaticBufferTooSmall(pszStaticResult);

    CPLStrlcpy( pszStaticResult, pszFullFilename + iFileStart, nLength + 1 );

    return pszStaticResult;
}
Ejemplo n.º 2
0
const char *CPLProjectRelativeFilename( const char *pszProjectDir, 
                                        const char *pszSecondaryFilename )

{
    char *pszStaticResult = CPLGetStaticResult();

    CPLAssert( ! (pszProjectDir >= pszStaticResult && pszProjectDir < pszStaticResult + CPL_PATH_BUF_SIZE) );
    CPLAssert( ! (pszSecondaryFilename >= pszStaticResult && pszSecondaryFilename < pszStaticResult + CPL_PATH_BUF_SIZE) );

    if( !CPLIsFilenameRelative( pszSecondaryFilename ) )
        return pszSecondaryFilename;

    if( pszProjectDir == NULL || strlen(pszProjectDir) == 0 )
        return pszSecondaryFilename;

    if (CPLStrlcpy( pszStaticResult, pszProjectDir, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
        goto error;

    if( pszProjectDir[strlen(pszProjectDir)-1] != '/' 
        && pszProjectDir[strlen(pszProjectDir)-1] != '\\' )
    {
        if (CPLStrlcat( pszStaticResult, SEP_STRING, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
            goto error;
    }

    if (CPLStrlcat( pszStaticResult, pszSecondaryFilename, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
        goto error;

    return pszStaticResult;
error:
    return CPLStaticBufferTooSmall(pszStaticResult);
}
Ejemplo n.º 3
0
const char *CPLGetDirname( const char *pszFilename )

{
    int         iFileStart = CPLFindFilenameStart(pszFilename);
    char       *pszStaticResult = CPLGetStaticResult();

    if( iFileStart >= CPL_PATH_BUF_SIZE )
        return CPLStaticBufferTooSmall(pszStaticResult);

    CPLAssert( ! (pszFilename >= pszStaticResult && pszFilename < pszStaticResult + CPL_PATH_BUF_SIZE) );

    if( iFileStart == 0 )
    {
        strcpy( pszStaticResult, "." );
        return pszStaticResult;
    }

    CPLStrlcpy( pszStaticResult, pszFilename, iFileStart+1 );

    if( iFileStart > 1
        && (pszStaticResult[iFileStart-1] == '/'
            || pszStaticResult[iFileStart-1] == '\\') )
        pszStaticResult[iFileStart-1] = '\0';

    return pszStaticResult;
}
Ejemplo n.º 4
0
const char *CPLFormFilename( const char * pszPath,
                             const char * pszBasename,
                             const char * pszExtension )

{
    char *pszStaticResult = CPLGetStaticResult();
    const char  *pszAddedPathSep = "";
    const char  *pszAddedExtSep = "";

    CPLAssert( ! (pszPath >= pszStaticResult && pszPath < pszStaticResult + CPL_PATH_BUF_SIZE) );
    CPLAssert( ! (pszBasename >= pszStaticResult && pszBasename < pszStaticResult + CPL_PATH_BUF_SIZE) );

    if( pszPath == NULL )
        pszPath = "";
    else if( strlen(pszPath) > 0
             && pszPath[strlen(pszPath)-1] != '/'
             && pszPath[strlen(pszPath)-1] != '\\' )
        pszAddedPathSep = SEP_STRING;

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

    if (CPLStrlcpy( pszStaticResult, pszPath, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE ||
        CPLStrlcat( pszStaticResult, pszAddedPathSep, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE ||
        CPLStrlcat( pszStaticResult, pszBasename, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE ||
        CPLStrlcat( pszStaticResult, pszAddedExtSep, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE ||
        CPLStrlcat( pszStaticResult, pszExtension, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE)
        return CPLStaticBufferTooSmall(pszStaticResult);

    return pszStaticResult;
}
Ejemplo n.º 5
0
/**
 * GDALMDReaderLandsat()
 */
GDALMDReaderLandsat::GDALMDReaderLandsat(const char *pszPath,
        char **papszSiblingFiles) : GDALMDReaderBase(pszPath, papszSiblingFiles)
{
    const char* pszBaseName = CPLGetBasename(pszPath);
    const char* pszDirName = CPLGetDirname(pszPath);
    size_t nBaseNameLen = strlen(pszBaseName);
    if( nBaseNameLen > 511 )
        return;

    // split file name by _B or _b
    char szMetadataName[512] = {0};
    size_t i;
    for(i = 0; i < nBaseNameLen; i++)
    {
        szMetadataName[i] = pszBaseName[i];
        if(STARTS_WITH_CI(pszBaseName + i, "_B") || STARTS_WITH_CI(pszBaseName + i, "_b"))
        {
            break;
        }
    }

    // form metadata file name
    CPLStrlcpy(szMetadataName + i, "_MTL.txt", 9);

    const char* pszIMDSourceFilename = CPLFormFilename( pszDirName,
                                                        szMetadataName, NULL );
    if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
    {
        m_osIMDSourceFilename = pszIMDSourceFilename;
    }
    else
    {
        CPLStrlcpy(szMetadataName + i, "_MTL.TXT", 9);
        pszIMDSourceFilename = CPLFormFilename( pszDirName, szMetadataName, NULL );
        if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
        {
            m_osIMDSourceFilename = pszIMDSourceFilename;
        }
    }

    if( !m_osIMDSourceFilename.empty() )
        CPLDebug( "MDReaderLandsat", "IMD Filename: %s",
                  m_osIMDSourceFilename.c_str() );
}
Ejemplo n.º 6
0
const char *CPLFormFilename( const char * pszPath,
                             const char * pszBasename,
                             const char * pszExtension )

{
    char *pszStaticResult = CPLGetStaticResult();
    const char  *pszAddedPathSep = "";
    const char  *pszAddedExtSep = "";

    CPLAssert( ! (pszPath >= pszStaticResult && pszPath < pszStaticResult + CPL_PATH_BUF_SIZE) );
    CPLAssert( ! (pszBasename >= pszStaticResult && pszBasename < pszStaticResult + CPL_PATH_BUF_SIZE) );

    if( pszBasename[0] == '.' && pszBasename[1] == '/' )
        pszBasename += 2;

    if( pszPath == NULL )
        pszPath = "";
    else if( strlen(pszPath) > 0
             && pszPath[strlen(pszPath)-1] != '/'
             && pszPath[strlen(pszPath)-1] != '\\' )
    {
        /* FIXME? would be better to ask the filesystems what they */
        /* prefer as directory separator */
        if (strncmp(pszPath, "/vsicurl/", 9) == 0)
            pszAddedPathSep = "/";
        else if (strncmp(pszPath, "/vsizip/", 8) == 0)
            pszAddedPathSep = "/";
        else
            pszAddedPathSep = SEP_STRING;
    }

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

    if (CPLStrlcpy( pszStaticResult, pszPath, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE ||
        CPLStrlcat( pszStaticResult, pszAddedPathSep, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE ||
        CPLStrlcat( pszStaticResult, pszBasename, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE ||
        CPLStrlcat( pszStaticResult, pszAddedExtSep, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE ||
        CPLStrlcat( pszStaticResult, pszExtension, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE)
        return CPLStaticBufferTooSmall(pszStaticResult);

    return pszStaticResult;
}
Ejemplo n.º 7
0
const char *CPLCleanTrailingSlash( const char *pszPath )

{
    char       *pszStaticResult = CPLGetStaticResult();
    int        iPathLength = strlen(pszPath);

    CPLAssert( ! (pszPath >= pszStaticResult && pszPath < pszStaticResult + CPL_PATH_BUF_SIZE) );

    if (iPathLength >= CPL_PATH_BUF_SIZE)
        return CPLStaticBufferTooSmall(pszStaticResult);

    CPLStrlcpy( pszStaticResult, pszPath, iPathLength+1 );

    if( iPathLength > 0 
        && (pszStaticResult[iPathLength-1] == '\\' 
            || pszStaticResult[iPathLength-1] == '/'))
        pszStaticResult[iPathLength-1] = '\0';

    return pszStaticResult;
}
Ejemplo n.º 8
0
const char *CPLGetExtension( const char *pszFullFilename )

{
    size_t  iFileStart = CPLFindFilenameStart( pszFullFilename );
    size_t  iExtStart;
    char    *pszStaticResult = CPLGetStaticResult();

    CPLAssert( ! (pszFullFilename >= pszStaticResult && pszFullFilename < pszStaticResult + CPL_PATH_BUF_SIZE) );

    for( iExtStart = strlen(pszFullFilename);
         iExtStart > iFileStart && pszFullFilename[iExtStart] != '.';
         iExtStart-- ) {}

    if( iExtStart == iFileStart )
        iExtStart = strlen(pszFullFilename)-1;

    if (CPLStrlcpy( pszStaticResult, pszFullFilename+iExtStart+1, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
        return CPLStaticBufferTooSmall(pszStaticResult);

    return pszStaticResult;
}
Ejemplo n.º 9
0
const char *CPLResetExtension( const char *pszPath, const char *pszExt )

{
    char    *pszStaticResult = CPLGetStaticResult();
    size_t  i;

    CPLAssert( ! (pszPath >= pszStaticResult && pszPath < pszStaticResult + CPL_PATH_BUF_SIZE) );

/* -------------------------------------------------------------------- */
/*      First, try and strip off any existing extension.                */
/* -------------------------------------------------------------------- */
    if (CPLStrlcpy( pszStaticResult, pszPath, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
        return CPLStaticBufferTooSmall(pszStaticResult);

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

            if( pszStaticResult[i] == '/' || pszStaticResult[i] == '\\' 
                || pszStaticResult[i] == ':' )
                break;
        }
    }

/* -------------------------------------------------------------------- */
/*      Append the new extension.                                       */
/* -------------------------------------------------------------------- */
    if (CPLStrlcat( pszStaticResult, ".", CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE ||
        CPLStrlcat( pszStaticResult, pszExt, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE)
        return CPLStaticBufferTooSmall(pszStaticResult);

    return pszStaticResult;
}
Ejemplo n.º 10
0
const char *CPLProjectRelativeFilename( const char *pszProjectDir, 
                                        const char *pszSecondaryFilename )

{
    char *pszStaticResult = CPLGetStaticResult();

    CPLAssert( ! (pszProjectDir >= pszStaticResult && pszProjectDir < pszStaticResult + CPL_PATH_BUF_SIZE) );
    CPLAssert( ! (pszSecondaryFilename >= pszStaticResult && pszSecondaryFilename < pszStaticResult + CPL_PATH_BUF_SIZE) );

    if( !CPLIsFilenameRelative( pszSecondaryFilename ) )
        return pszSecondaryFilename;

    if( pszProjectDir == NULL || strlen(pszProjectDir) == 0 )
        return pszSecondaryFilename;

    if (CPLStrlcpy( pszStaticResult, pszProjectDir, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
        goto error;

    if( pszProjectDir[strlen(pszProjectDir)-1] != '/' 
        && pszProjectDir[strlen(pszProjectDir)-1] != '\\' )
    {
        /* FIXME? would be better to ask the filesystems what they */
        /* prefer as directory separator */
        const char* pszAddedPathSep;
        if (strncmp(pszStaticResult, "/vsicurl/", 9) == 0)
            pszAddedPathSep = "/";
        else
            pszAddedPathSep = SEP_STRING;
        if (CPLStrlcat( pszStaticResult, pszAddedPathSep, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
            goto error;
    }

    if (CPLStrlcat( pszStaticResult, pszSecondaryFilename, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
        goto error;

    return pszStaticResult;
error:
    return CPLStaticBufferTooSmall(pszStaticResult);
}
Ejemplo n.º 11
0
int OGRSelafinDataSource::TakeLock(CPL_UNUSED const char *pszFilename) {
#ifdef notdef
    // Ideally, we should implement a locking mechanism for Selafin layers because different layers share the same header and file on disk. If two layers are modified at the same time,
    // this would most likely result in data corruption. However, locking the data source causes other problems in QGis which always tries to open the datasource twice, a first time
    // in Update mode, and the second time for the layer inside in Read-only mode (because the lock is taken), and layers therefore can't be changed in QGis.
    // For now, this procedure is deactivated and a warning message is issued when a datasource is opened in update mode.
    //CPLDebug("Selafin","TakeLock(%s)",pszFilename);
    if (pszLockName!=0) CPLFree(pszLockName);
    size_t nLen=strlen(pszFilename)+4;
    pszLockName=(char*)CPLMalloc(sizeof(char)*nLen);
    CPLStrlcpy(pszLockName,pszFilename,nLen-3);
    CPLStrlcat(pszLockName,"~~~",nLen);
    VSILFILE *fpLock = VSIFOpenL(pszLockName, "rb+");
    // This is not thread-safe but I'm not quite sure how to open a file in exclusive mode and in a portable way
    if (fpLock!=NULL) {
        VSIFCloseL(fpLock);
        return 0;
    }
    fpLock=VSIFOpenL(pszLockName,"wb");
    VSIFCloseL(fpLock);
#endif
    return 1;
}
Ejemplo n.º 12
0
void CheckUTM( GTIFDefn * psDefn, const char * pszCtString )
{
    if(!psDefn || !pszCtString)
        return;

    static const char *apszUtmProjCode[] = {
        "PSAD56", "17N", "16017",
        "PSAD56", "18N", "16018",
        "PSAD56", "19N", "16019",
        "PSAD56", "20N", "16020",
        "PSAD56", "21N", "16021",
        "PSAD56", "17S", "16117",
        "PSAD56", "18S", "16118",
        "PSAD56", "19S", "16119",
        "PSAD56", "20S", "16120",
        "PSAD56", "21S", "16121",
        "PSAD56", "22S", "16122",
        NULL, NULL, NULL};

    const char* p = strstr(pszCtString, "Datum = ");
    char datumName[128];
    if(p)
    {
        p += strlen("Datum = ");
        const char* p1 = strchr(p, '|');
        if(p1 && p1-p < (int)sizeof(datumName))
        {
            strncpy(datumName, p, (p1-p));
            datumName[p1-p] = '\0';
        }
        else
            CPLStrlcpy(datumName, p, sizeof(datumName));
    }
    else
    {
        datumName[0] = '\0';
    }

    char utmName[64];
    p = strstr(pszCtString, "UTM Zone ");
    if(p)
    {
        p += strlen("UTM Zone ");
        const char* p1 = strchr(p, '|');
        if(p1 && p1-p < (int)sizeof(utmName))
        {
            strncpy(utmName, p, (p1-p));
            utmName[p1-p] = '\0';
        }
        else
            CPLStrlcpy(utmName, p, sizeof(utmName));

        for(int i=0; apszUtmProjCode[i]!=NULL; i += 3)
        {
            if(EQUALN(utmName, apszUtmProjCode[i+1], strlen(apszUtmProjCode[i+1])) &&
            EQUAL(datumName, apszUtmProjCode[i]) )
            {
                if(psDefn->ProjCode != atoi(apszUtmProjCode[i+2]))
                {
                    psDefn->ProjCode = (short) atoi(apszUtmProjCode[i+2]);
                    GTIFGetProjTRFInfo( psDefn->ProjCode, NULL, &(psDefn->Projection),
                                        psDefn->ProjParm );
                    break;
                }
            }
        }
    }

    return;
}
Ejemplo n.º 13
0
SEXP ogrReadColumn(OGRLayer *poLayer, SEXP FIDs, int iField, int int64, int ENC_DEBUG) {
    // read feature data and return something according to the type
    OGRFeatureDefn *poDefn;
    OGRFieldDefn *poField;
    OGRFeature *poFeature;
    int iRow,nRows;
    SEXP ans = R_NilValue;

    nRows=length(FIDs);
    // get field data from layer
    installErrorHandler();
    poDefn = poLayer->GetLayerDefn();
    poField = poDefn->GetFieldDefn(iField);
    uninstallErrorHandlerAndTriggerError();
    if(poField == NULL) {
        error("Error getting field %d ",iField);
    }
    // allocate an object for the result depending on the feature type:
    installErrorHandler();
    switch(poField->GetType()) {
    case OFTInteger:
        PROTECT(ans=allocVector(INTSXP,nRows));
        break;
#ifdef GDALV2
    case OFTInteger64:
        if (int64 ==3) {
            PROTECT(ans=allocVector(STRSXP,nRows));
        } else {
            PROTECT(ans=allocVector(INTSXP,nRows));
        }
        break;
#endif
    case OFTReal:
        PROTECT(ans=allocVector(REALSXP,nRows));
        break;
    case OFTString:
        PROTECT(ans=allocVector(STRSXP,nRows));
        break;
    case OFTDate:
        PROTECT(ans=allocVector(STRSXP,nRows));
        break;
    case OFTDateTime:
        PROTECT(ans=allocVector(STRSXP,nRows));
        break;
    case OFTTime:
        PROTECT(ans=allocVector(STRSXP,nRows));
        break;
    default:
        const char *desc = poField->GetFieldTypeName(poField->GetType());
        uninstallErrorHandlerAndTriggerError();
        error("unsupported field type: %s", desc);
        break;
    }
    uninstallErrorHandlerAndTriggerError();

    // now go over each row and retrieve data. iRow is an index in a
    // vector of FIDs
    /*#ifndef EJP
        installErrorHandler();
        for(iRow=0;iRow<nRows;iRow++){
          poFeature=poLayer->GetFeature(INTEGER(FIDs)[iRow]);
          if(poFeature == NULL){
    	error("Error getting feature FID: %d",(INTEGER(FIDs)[iRow]));
          }
        }
        uninstallErrorHandlerAndTriggerError();
    #else*/
    // EJP, changed into:
    installErrorHandler();
    poLayer->ResetReading();
    iRow = 0;
    while((poFeature = poLayer->GetNextFeature()) != NULL) {
//#endif
        // now get the value using the right type:
        switch(poField->GetType()) {
        case OFTInteger:
            if (poFeature->IsFieldSet(iField))
                INTEGER(ans)[iRow]=poFeature->GetFieldAsInteger(iField);
            else INTEGER(ans)[iRow]=NA_INTEGER;
            break;
#ifdef GDALV2
        case OFTInteger64:
            if (poFeature->IsFieldSet(iField)) {
                if (int64 == 3) {
                    SET_STRING_ELT(ans, iRow,
                                   mkChar(poFeature->GetFieldAsString(iField)));
                } else {
                    GIntBig nVal64 = poFeature->GetFieldAsInteger64(iField);
                    int nVal = (nVal64 > INT_MAX) ? INT_MAX :
                               (nVal64 < INT_MIN) ? INT_MIN : (int) nVal64;
                    INTEGER(ans)[iRow]=nVal;
                    if (((GIntBig)nVal != nVal64) && int64 == 2) {
                        warning("Integer64 value clamped: feature %d", iRow);
                    }
                }
            } else {
                if (int64 == 3) {
                    SET_STRING_ELT(ans, iRow, NA_STRING);
                } else {
                    INTEGER(ans)[iRow]=NA_INTEGER;
                }
            }
            break;
#endif
        case OFTReal:
            if (poFeature->IsFieldSet(iField))
                REAL(ans)[iRow]=poFeature->GetFieldAsDouble(iField);
            else REAL(ans)[iRow]=NA_REAL;
            break;
        case OFTString:
// ENC
            char str[4096];
            size_t stln;
            if (poFeature->IsFieldSet(iField)) {
                stln = CPLStrnlen(poFeature->GetFieldAsString(iField), 4096);
                CPLStrlcpy(str, (const char *) poFeature->GetFieldAsString(iField),
                           4096);
                SET_STRING_ELT(ans, iRow, mkChar(str));
            } else SET_STRING_ELT(ans, iRow, NA_STRING);
            if (ENC_DEBUG) {
                Rprintf("iField: %d, iRow: %d stln %u Enc %s ", iField,
                        iRow, stln, CPLIsUTF8(str, (int) stln)?"UTF-8":"other");
                for (int si=0; si < (int) stln; si++)
                    Rprintf("%x ", (unsigned char) str[si]);
                Rprintf("\n");
            } /* FIXME */
            break;
        case OFTDate:
            if (poFeature->IsFieldSet(iField))
                SET_STRING_ELT(ans,iRow,mkChar(poFeature->GetFieldAsString(iField)));
            else SET_STRING_ELT(ans, iRow, NA_STRING);
            break;
        case OFTDateTime:
            if (poFeature->IsFieldSet(iField))
                SET_STRING_ELT(ans,iRow,mkChar(poFeature->GetFieldAsString(iField)));
            else SET_STRING_ELT(ans, iRow, NA_STRING);
            break;
        case OFTTime:
            if (poFeature->IsFieldSet(iField))
                SET_STRING_ELT(ans,iRow,mkChar(poFeature->GetFieldAsString(iField)));
            else SET_STRING_ELT(ans, iRow, NA_STRING);
            break;

        default:
            OGRFeature::DestroyFeature( poFeature );
//        delete poFeature;
            uninstallErrorHandlerAndTriggerError();
            error("Unsupported field type. should have been caught before");
        }
        OGRFeature::DestroyFeature( poFeature );
//      delete poFeature;
//#ifdef EJP
        // according to tutorial: OGRFeature::DestroyFeature(poFeature);
        // see comment FW in OGR tutorial: We could just "delete" it,
        // but this can cause problems in windows builds where the GDAL DLL
        // has a different "heap" from the main program. To be on the safe
        // side we use a GDAL function to delete the feature.
        iRow++;
//#endif
    }
    uninstallErrorHandlerAndTriggerError();
    UNPROTECT(1);
    return(ans);
}
Ejemplo n.º 14
0
void OGRCloudantTableLayer::WriteMetadata()
{
    if (pszSpatialDDoc == nullptr)
        OGRCloudantTableLayer::GetSpatialView();
    if( pszSpatialDDoc == nullptr )
        return;

    CPLString osURI;
    osURI = "/";
    osURI += osEscapedName;
    osURI += "/";
    osURI += pszSpatialDDoc;

   json_object* poDDocObj = poDS->GET(osURI);
    if (poDDocObj == nullptr)
        return;

    if ( !json_object_is_type(poDDocObj, json_type_object) )
    {
        CPLError(CE_Failure, CPLE_AppDefined, "WriteMetadata() failed");
        json_object_put(poDDocObj);
        return;
    }

    json_object* poError = CPL_json_object_object_get(poDDocObj, "error");
    const char* pszError = json_object_get_string(poError);
    if (pszError && strcmp(pszError, "not_found") == 0)
    {
        json_object_put(poDDocObj);
        return;
    }

    if (poDS->IsError(poDDocObj, "WriteMetadata() failed"))
    {
        json_object_put(poDDocObj);
        return;
    }

    if (poSRS)
    {
        // epsg codes are supported in Cloudant
        const char * pszEpsg = nullptr;
        const char * pszAuthName = nullptr;
        char szSrid[100];

        if (poSRS->IsProjected())
        {
            pszAuthName = poSRS->GetAuthorityName("PROJCS");
            if ((pszAuthName != nullptr) && (STARTS_WITH(pszAuthName, "EPSG")))
                pszEpsg = poSRS->GetAuthorityCode("PROJCS");
        }
        else
        {
            pszAuthName = poSRS->GetAuthorityName("GEOGCS");
            if ((pszAuthName != nullptr) && (STARTS_WITH(pszAuthName, "EPSG")))
                pszEpsg = poSRS->GetAuthorityCode("GEOGCS");
        }

        if (pszEpsg != nullptr)
        {
            const char * pszUrn = "urn:ogc:def:crs:epsg::";
            CPLStrlcpy(szSrid, pszUrn, sizeof(szSrid));
            if (CPLStrlcpy(szSrid + sizeof(pszUrn), pszEpsg, sizeof(szSrid)) <= sizeof(szSrid))
            {
                json_object_object_add(poDDocObj, "srsid",
                                   json_object_new_string(pszUrn));
            }
        }
    }

    if (eGeomType != wkbNone)
    {
        json_object_object_add(poDDocObj, "geomtype",
                    json_object_new_string(OGRToOGCGeomType(eGeomType)));
        if (wkbHasZ(poFeatureDefn->GetGeomType()))
        {
            json_object_object_add(poDDocObj, "is_25D",
                               json_object_new_boolean(TRUE));
        }
    }
    else
    {
        json_object_object_add(poDDocObj, "geomtype",
                               json_object_new_string("NONE"));
    }

    json_object_object_add(poDDocObj, "geojson_documents",
                           json_object_new_boolean(bGeoJSONDocument));

    json_object* poFields = json_object_new_array();
    json_object_object_add(poDDocObj, "fields", poFields);

    for(int i=COUCHDB_FIRST_FIELD;i<poFeatureDefn->GetFieldCount();i++)
    {
        json_object* poField = json_object_new_object();
        json_object_array_add(poFields, poField);

        json_object_object_add(poField, "name",
            json_object_new_string(poFeatureDefn->GetFieldDefn(i)->GetNameRef()));

        const char* pszType = nullptr;
        switch (poFeatureDefn->GetFieldDefn(i)->GetType())
        {
            case OFTInteger: pszType = "integer"; break;
            case OFTReal: pszType = "real"; break;
            case OFTString: pszType = "string"; break;
            case OFTIntegerList: pszType = "integerlist"; break;
            case OFTRealList: pszType = "reallist"; break;
            case OFTStringList: pszType = "stringlist"; break;
            default: pszType = "string"; break;
        }

        json_object_object_add(poField, "type",
                               json_object_new_string(pszType));
    }

    json_object* poAnswerObj = poDS->PUT(osURI,
                                         json_object_to_json_string(poDDocObj));

    json_object_put(poDDocObj);
    json_object_put(poAnswerObj);
}
Ejemplo n.º 15
0
/**
 * GDALMDReaderGeoEye()
 */
GDALMDReaderGeoEye::GDALMDReaderGeoEye(const char *pszPath, 
        char **papszSiblingFiles) : GDALMDReaderBase(pszPath, papszSiblingFiles)
{
    
    const char* pszBaseName = CPLGetBasename(pszPath);
    const char* pszDirName = CPLGetDirname(pszPath);
    size_t nBaseNameLen = strlen(pszBaseName);
    if( nBaseNameLen > 511 )
        return;

    // get _metadata.txt file
    
    // split file name by _rgb_ or _pan_
    char szMetadataName[512] = {0};
    size_t i;
    for(i = 0; i < nBaseNameLen; i++)
    {
        szMetadataName[i] = pszBaseName[i];
        if(EQUALN(pszBaseName + i, "_rgb_", 5) || EQUALN(pszBaseName + i, "_pan_", 5))
        {
            break;
        }
    }
    
    // form metadata file name
    CPLStrlcpy(szMetadataName + i, "_metadata.txt", 14);
    const char* pszIMDSourceFilename = CPLFormFilename( pszDirName,
                                                        szMetadataName, NULL );
    if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
    {
        m_osIMDSourceFilename = pszIMDSourceFilename;
    }                                                     
    else
    {
        CPLStrlcpy(szMetadataName + i, "_METADATA.TXT", 14);
        pszIMDSourceFilename = CPLFormFilename( pszDirName, szMetadataName, NULL );
        if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
        {
            m_osIMDSourceFilename = pszIMDSourceFilename;
        }
    }

    // get _rpc.txt file
    
    const char* pszRPBSourceFilename = CPLFormFilename( pszDirName,
                                                        CPLSPrintf("%s_rpc",
                                                        pszBaseName),
                                                        "txt" );
    if (CPLCheckForFile((char*)pszRPBSourceFilename, papszSiblingFiles))
    {
        m_osRPBSourceFilename = pszRPBSourceFilename;
    }
    else
    {
        pszRPBSourceFilename = CPLFormFilename( pszDirName, CPLSPrintf("%s_RPC",
                                                pszBaseName), "TXT" );
        if (CPLCheckForFile((char*)pszRPBSourceFilename, papszSiblingFiles))
        {
            m_osRPBSourceFilename = pszRPBSourceFilename;
        }
    }

    if( m_osIMDSourceFilename.size() )
        CPLDebug( "MDReaderGeoEye", "IMD Filename: %s",
                  m_osIMDSourceFilename.c_str() );
    if( m_osRPBSourceFilename.size() )
        CPLDebug( "MDReaderGeoEye", "RPB Filename: %s",
                  m_osRPBSourceFilename.c_str() );
}
Ejemplo n.º 16
0
const char * GDALDefaultCSVFilename( const char *pszBasename )

{
/* -------------------------------------------------------------------- */
/*      Do we already have this file accessed?  If so, just return      */
/*      the existing path without any further probing.                  */
/* -------------------------------------------------------------------- */
    CSVTable **ppsCSVTableList;

    ppsCSVTableList = (CSVTable **) CPLGetTLS( CTLS_CSVTABLEPTR );
    if( ppsCSVTableList != NULL )
    {
        CSVTable *psTable;
        int nBasenameLen = strlen(pszBasename);

        for( psTable = *ppsCSVTableList; 
             psTable != NULL; 
             psTable = psTable->psNext )
        {
            int nFullLen = strlen(psTable->pszFilename);

            if( nFullLen > nBasenameLen 
                && strcmp(psTable->pszFilename+nFullLen-nBasenameLen,
                          pszBasename) == 0 
                && strchr("/\\",psTable->pszFilename[+nFullLen-nBasenameLen-1])
                          != NULL )
            {
                return psTable->pszFilename;
            }
        }
    }
                
/* -------------------------------------------------------------------- */
/*      Otherwise we need to look harder for it.                        */
/* -------------------------------------------------------------------- */
    DefaultCSVFileNameTLS* pTLSData =
            (DefaultCSVFileNameTLS *) CPLGetTLS( CTLS_CSVDEFAULTFILENAME );
    if (pTLSData == NULL)
    {
        pTLSData = (DefaultCSVFileNameTLS*) CPLCalloc(1, sizeof(DefaultCSVFileNameTLS));
        CPLSetTLS( CTLS_CSVDEFAULTFILENAME, pTLSData, TRUE );
    }

    FILE    *fp = NULL;
    const char *pszResult;

    pszResult = CPLFindFile( "epsg_csv", pszBasename );

    if( pszResult != NULL )
        return pszResult;

    if( !pTLSData->bCSVFinderInitialized )
    {
        pTLSData->bCSVFinderInitialized = TRUE;

        if( CPLGetConfigOption("GEOTIFF_CSV",NULL) != NULL )
            CPLPushFinderLocation( CPLGetConfigOption("GEOTIFF_CSV",NULL));
            
        if( CPLGetConfigOption("GDAL_DATA",NULL) != NULL )
            CPLPushFinderLocation( CPLGetConfigOption("GDAL_DATA",NULL) );

        pszResult = CPLFindFile( "epsg_csv", pszBasename );

        if( pszResult != NULL )
            return pszResult;
    }
            
    if( (fp = fopen( "csv/horiz_cs.csv", "rt" )) != NULL )
    {
        strcpy( pTLSData->szPath, "csv/" );
        CPLStrlcat( pTLSData->szPath, pszBasename, sizeof(pTLSData->szPath) );
    }
    else
    {
#ifdef GDAL_PREFIX
  #ifdef MACOSX_FRAMEWORK
        strcpy( pTLSData->szPath, GDAL_PREFIX "/Resources/epsg_csv/" );
        CPLStrlcat( pTLSData->szPath, pszBasename, sizeof(pTLSData->szPath) );
  #else
        strcpy( pTLSData->szPath, GDAL_PREFIX "/share/epsg_csv/" );
        CPLStrlcat( pTLSData->szPath, pszBasename, sizeof(pTLSData->szPath) );
  #endif
#else
        strcpy( pTLSData->szPath, "/usr/local/share/epsg_csv/" );
        CPLStrlcat( pTLSData->szPath, pszBasename, sizeof(pTLSData->szPath) );
#endif
        if( (fp = fopen( pTLSData->szPath, "rt" )) == NULL )
            CPLStrlcpy( pTLSData->szPath, pszBasename, sizeof(pTLSData->szPath) );
    }

    if( fp != NULL )
        fclose( fp );
        
    return( pTLSData->szPath );
}
Ejemplo n.º 17
0
static void CorrectURLs( CPLXMLNode * psRoot, const char *pszURL )

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

    CPLXMLNode *psChild = psRoot->psChild;

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

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

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

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

// search the child elements of psRoot
    for( psChild = psRoot->psChild; psChild != NULL; psChild = psChild->psNext)
        if( psChild->eType == CXT_Element )
            CorrectURLs( psChild, pszURL );
}
Ejemplo n.º 18
0
SURF_FETCH_E LandfireClient::FetchBoundingBox( double *bbox, double resolution,
                                               const char *filename,
                                               char **options )
{
    (void)resolution;
    if( NULL == filename )
    {
        return SURF_FETCH_E_BAD_INPUT;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

    delete [] pszResponse;

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

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

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

    CPLHTTPDestroyResult( m_poResult );

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

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

    return SURF_FETCH_E_NONE;
}