int main(int nArgc, char* papszArgv[])
{
    const char  *pszFilename = NULL, *pszOutFilename = NULL;
    DDFModule  oModule;

/* -------------------------------------------------------------------- */
/*      Check arguments.                                                */
/* -------------------------------------------------------------------- */
    for( int iArg = 1; iArg < nArgc; iArg++ )
    {
        if( pszFilename == NULL )
            pszFilename = papszArgv[iArg];
        else if( pszOutFilename == NULL )
            pszOutFilename = papszArgv[iArg];
        else
        {
            pszFilename = NULL;
            break;
        }
    }

    if( pszFilename == NULL )
    {
        printf( "Usage: 8211createfromxml filename.xml outfilename\n" );
        exit( 1 );
    }

    CPLXMLNode* poRoot = CPLParseXMLFile( pszFilename );
    if( poRoot == NULL )
    {
        fprintf(stderr, "Cannot parse XML file '%s'\n", pszFilename);
        exit( 1 );
    }

    CPLXMLNode* poXMLDDFModule = CPLSearchXMLNode(poRoot, "=DDFModule");
    if( poXMLDDFModule == NULL )
    {
        fprintf(stderr, "Cannot find DDFModule node in XML file '%s'\n", pszFilename);
        exit( 1 );
    }

    /* Compute the size of the DDFField tag */
    CPLXMLNode* psIter = poXMLDDFModule->psChild;
    int nSizeFieldTag = 0;
    while( psIter != NULL )
    {
        if( psIter->eType == CXT_Element &&
            strcmp(psIter->pszValue, "DDFFieldDefn") == 0 )
        {
            const char* pszTag = CPLGetXMLValue(psIter, "tag", "");
            if( nSizeFieldTag == 0 )
                nSizeFieldTag = (int)strlen(pszTag);
            else if( nSizeFieldTag != (int)strlen(pszTag) )
            {
                fprintf(stderr, "All fields have not the same tag size\n");
                exit( 1 );
            }
        }
        psIter = psIter->psNext;
    }

    char chInterchangeLevel = '3';
    char chLeaderIden = 'L';
    char chCodeExtensionIndicator = 'E';
    char chVersionNumber = '1';
    char chAppIndicator = ' ';
    const char *pszExtendedCharSet = " ! ";
    int nSizeFieldLength = 3;
    int nSizeFieldPos = 4;

    chInterchangeLevel = CPLGetXMLValue(poXMLDDFModule, "_interchangeLevel", CPLSPrintf("%c", chInterchangeLevel))[0];
    chLeaderIden = CPLGetXMLValue(poXMLDDFModule, "_leaderIden", CPLSPrintf("%c", chLeaderIden))[0];
    chCodeExtensionIndicator = CPLGetXMLValue(poXMLDDFModule, "_inlineCodeExtensionIndicator", CPLSPrintf("%c", chCodeExtensionIndicator))[0];
    chVersionNumber = CPLGetXMLValue(poXMLDDFModule, "_versionNumber", CPLSPrintf("%c", chVersionNumber))[0];
    chAppIndicator = CPLGetXMLValue(poXMLDDFModule, "_appIndicator", CPLSPrintf("%c", chAppIndicator))[0];
    char szExtendedCharSet[4];
    snprintf(szExtendedCharSet, sizeof(szExtendedCharSet), "%s", CPLGetXMLValue(poXMLDDFModule, "_extendedCharSet", pszExtendedCharSet));
    pszExtendedCharSet = szExtendedCharSet;
    nSizeFieldLength = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldLength", CPLSPrintf("%d", nSizeFieldLength)));
    nSizeFieldPos = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldPos", CPLSPrintf("%d", nSizeFieldPos)));
    nSizeFieldTag = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldTag", CPLSPrintf("%d", nSizeFieldTag)));

    oModule.Initialize(chInterchangeLevel,
                       chLeaderIden,
                       chCodeExtensionIndicator,
                       chVersionNumber,
                       chAppIndicator,
                       pszExtendedCharSet,
                       nSizeFieldLength,
                       nSizeFieldPos,
                       nSizeFieldTag);
    oModule.SetFieldControlLength(atoi(CPLGetXMLValue(poXMLDDFModule, "_fieldControlLength", CPLSPrintf("%d", oModule.GetFieldControlLength()))));

    int bCreated = FALSE;

    /* Create DDFFieldDefn and DDFRecord elements */
    psIter = poXMLDDFModule->psChild;
    while( psIter != NULL )
    {
        if( psIter->eType == CXT_Element &&
            strcmp(psIter->pszValue, "DDFFieldDefn") == 0 )
        {
            DDFFieldDefn* poFDefn = new DDFFieldDefn();

            DDF_data_struct_code eStructCode = dsc_elementary;
            const char* pszStructCode = CPLGetXMLValue(psIter, "dataStructCode", "");
            if( strcmp(pszStructCode, "elementary") == 0 ) eStructCode = dsc_elementary;
            else if( strcmp(pszStructCode, "vector") == 0 ) eStructCode = dsc_vector;
            else if( strcmp(pszStructCode, "array") == 0 ) eStructCode = dsc_array;
            else if( strcmp(pszStructCode, "concatenated") == 0 ) eStructCode = dsc_concatenated;

            DDF_data_type_code eTypeCode = dtc_char_string;
            const char* pszTypeCode = CPLGetXMLValue(psIter, "dataTypeCode", "");
            if( strcmp(pszTypeCode, "char_string") == 0 ) eTypeCode = dtc_char_string;
            else if( strcmp(pszTypeCode, "implicit_point") == 0 ) eTypeCode = dtc_implicit_point;
            else if( strcmp(pszTypeCode, "explicit_point") == 0 ) eTypeCode = dtc_explicit_point;
            else if( strcmp(pszTypeCode, "explicit_point_scaled") == 0 ) eTypeCode = dtc_explicit_point_scaled;
            else if( strcmp(pszTypeCode, "char_bit_string") == 0 ) eTypeCode = dtc_char_bit_string;
            else if( strcmp(pszTypeCode, "bit_string") == 0 ) eTypeCode = dtc_bit_string;
            else if( strcmp(pszTypeCode, "mixed_data_type") == 0 ) eTypeCode = dtc_mixed_data_type;

            const char* pszFormatControls = CPLGetXMLValue(psIter, "formatControls", NULL);
            if( eStructCode != dsc_elementary )
                pszFormatControls = NULL;

            const char* pszArrayDescr = CPLGetXMLValue(psIter, "arrayDescr", "");
            if( eStructCode == dsc_vector )
                pszArrayDescr = "";
            else if( eStructCode == dsc_array )
                pszArrayDescr = "*";

            poFDefn->Create( CPLGetXMLValue(psIter, "tag", ""),
                             CPLGetXMLValue(psIter, "fieldName", ""),
                             pszArrayDescr,
                             eStructCode, eTypeCode,
                             pszFormatControls );

            CPLXMLNode* psSubIter = psIter->psChild;
            while( psSubIter != NULL )
            {
                if( psSubIter->eType == CXT_Element &&
                    strcmp(psSubIter->pszValue, "DDFSubfieldDefn") == 0 )
                {
                    poFDefn->AddSubfield( CPLGetXMLValue(psSubIter, "name", ""),
                                          CPLGetXMLValue(psSubIter, "format", "") );
                }
                psSubIter = psSubIter->psNext;
            }

            pszFormatControls = CPLGetXMLValue(psIter, "formatControls", NULL);
            if( pszFormatControls )
                poFDefn->SetFormatControls(pszFormatControls);

            oModule.AddField( poFDefn );
        }
        else if( psIter->eType == CXT_Element &&
                 strcmp(psIter->pszValue, "DDFRecord") == 0 )
        {
            //const bool bFirstRecord = !bCreated;
            if( !bCreated )
            {
                oModule.Create( pszOutFilename );
                bCreated = TRUE;
            }

            DDFRecord *poRec = new DDFRecord( &oModule );
            std::map<std::string, int> oMapField;

            //if( !bFirstRecord )
            //    poRec->SetReuseHeader(atoi(CPLGetXMLValue(psIter, "reuseHeader", CPLSPrintf("%d", poRec->GetReuseHeader()))));
            poRec->SetSizeFieldLength(atoi(CPLGetXMLValue(psIter, "_sizeFieldLength", CPLSPrintf("%d", poRec->GetSizeFieldLength()))));
            poRec->SetSizeFieldPos(atoi(CPLGetXMLValue(psIter, "_sizeFieldPos", CPLSPrintf("%d", poRec->GetSizeFieldPos()))));
            poRec->SetSizeFieldTag(atoi(CPLGetXMLValue(psIter, "_sizeFieldTag", CPLSPrintf("%d", poRec->GetSizeFieldTag()))));

            CPLXMLNode* psSubIter = psIter->psChild;
            while( psSubIter != NULL )
            {
                if( psSubIter->eType == CXT_Element &&
                    strcmp(psSubIter->pszValue, "DDFField") == 0 )
                {
                    const char* pszFieldName = CPLGetXMLValue(psSubIter, "name", "");
                    DDFFieldDefn* poFieldDefn = oModule.FindFieldDefn( pszFieldName );
                    if( poFieldDefn == NULL )
                    {
                        fprintf(stderr, "Can't find field '%s'\n", pszFieldName );
                        exit(1);
                    }

                    int nFieldOcc = oMapField[pszFieldName];
                    oMapField[pszFieldName] ++ ;

                    DDFField *poField = poRec->AddField( poFieldDefn );
                    const char* pszValue = CPLGetXMLValue(psSubIter, "value", NULL);
                    if( pszValue != NULL && STARTS_WITH(pszValue, "0x") )
                    {
                        pszValue += 2;
                        int nDataLen = (int)strlen(pszValue)  / 2;
                        char* pabyData = (char*) malloc(nDataLen);
                        for(int i=0;i<nDataLen;i++)
                        {
                            char c;
                            int nHigh, nLow;
                            c = pszValue[2*i];
                            if( c >= 'A' && c <= 'F' )
                                nHigh = 10 + c - 'A';
                            else
                                nHigh = c - '0';
                            c = pszValue[2*i + 1];
                            if( c >= 'A' && c <= 'F' )
                                nLow = 10 + c - 'A';
                            else
                                nLow = c - '0';
                            pabyData[i] = (nHigh << 4) + nLow;
                        }
                        poRec->SetFieldRaw( poField, nFieldOcc, (const char *) pabyData, nDataLen );
                        free(pabyData);
                    }
                    else
                    {
                        CPLXMLNode* psSubfieldIter = psSubIter->psChild;
                        std::map<std::string, int> oMapSubfield;
                        while( psSubfieldIter != NULL )
                        {
                            if( psSubfieldIter->eType == CXT_Element &&
                                strcmp(psSubfieldIter->pszValue, "DDFSubfield") == 0 )
                            {
                                const char* pszSubfieldName = CPLGetXMLValue(psSubfieldIter, "name", "");
                                const char* pszSubfieldType = CPLGetXMLValue(psSubfieldIter, "type", "");
                                const char* pszSubfieldValue = CPLGetXMLValue(psSubfieldIter, NULL, "");
                                int nOcc = oMapSubfield[pszSubfieldName];
                                oMapSubfield[pszSubfieldName] ++ ;
                                if( strcmp(pszSubfieldType, "float") == 0 )
                                {
                                    poRec->SetFloatSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc,
                                                           CPLAtof(pszSubfieldValue) );
                                }
                                else if( strcmp(pszSubfieldType, "integer") == 0 )
                                {
                                    poRec->SetIntSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc,
                                                           atoi(pszSubfieldValue) );
                                }
                                else if( strcmp(pszSubfieldType, "string") == 0 )
                                {
                                    poRec->SetStringSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc,
                                                              pszSubfieldValue );
                                }
                                else if( strcmp(pszSubfieldType, "binary") == 0 &&
                                         STARTS_WITH(pszSubfieldValue, "0x") )
                                {
                                    pszSubfieldValue += 2;
                                    int nDataLen = (int)strlen(pszSubfieldValue) / 2;
                                    char* pabyData = (char*) malloc(nDataLen);
                                    for(int i=0;i<nDataLen;i++)
                                    {
                                        char c;
                                        int nHigh, nLow;
                                        c = pszSubfieldValue[2*i];
                                        if( c >= 'A' && c <= 'F' )
                                            nHigh = 10 + c - 'A';
                                        else
                                            nHigh = c - '0';
                                        c = pszSubfieldValue[2*i + 1];
                                        if( c >= 'A' && c <= 'F' )
                                            nLow = 10 + c - 'A';
                                        else
                                            nLow = c - '0';
                                        pabyData[i] = (nHigh << 4) + nLow;
                                    }
                                    poRec->SetStringSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc,
                                                              pabyData, nDataLen );
                                    free(pabyData);
                                }
                            }
                            psSubfieldIter = psSubfieldIter->psNext;
                        }
                    }
                }
                psSubIter = psSubIter->psNext;
            }

            poRec->Write();
            delete poRec;
        }

        psIter = psIter->psNext;
    }

    CPLDestroyXMLNode(poRoot);

    oModule.Close();

    return 0;
}
int OGRSelafinDataSource::Open( const char * pszFilename, int bUpdateIn,
                                int bCreate )
{
    // Check if a range is set and extract it and the filename.
    const char *pszc = pszFilename;
    if (*pszFilename==0) return FALSE;
    while (*pszc) ++pszc;
    if (*(pszc-1)==']') {
        --pszc;
        while (pszc!=pszFilename && *pszc!='[') pszc--;
        if (pszc==pszFilename) return FALSE;
        poRange.setRange(pszc);
    }
    pszName = CPLStrdup( pszFilename );
    pszName[pszc-pszFilename]=0;
    bUpdate = CPL_TO_BOOL(bUpdateIn);
    if (bCreate && EQUAL(pszName, "/vsistdout/")) return TRUE;
    /* For writable /vsizip/, do nothing more */
    if (bCreate && STARTS_WITH(pszName, "/vsizip/")) return TRUE;
    CPLString osFilename(pszName);
    CPLString osBaseFilename = CPLGetFilename(pszName);
    // Determine what sort of object this is.
    VSIStatBufL sStatBuf;
    if (VSIStatExL( osFilename, &sStatBuf, VSI_STAT_NATURE_FLAG ) != 0) return FALSE;

    // Is this a single Selafin file?
    if (VSI_ISREG(sStatBuf.st_mode)) return OpenTable( pszName );

    // Is this a single a ZIP file with only a Selafin file inside ?
    if( STARTS_WITH(osFilename, "/vsizip/") && VSI_ISREG(sStatBuf.st_mode) ) {
        char** papszFiles = VSIReadDir(osFilename);
        if (CSLCount(papszFiles) != 1) {
            CSLDestroy(papszFiles);
            return FALSE;
        }
        osFilename = CPLFormFilename(osFilename, papszFiles[0], NULL);
        CSLDestroy(papszFiles);
        return OpenTable( osFilename );
    }

#ifdef notdef
    // Otherwise it has to be a directory.
    if( !VSI_ISDIR(sStatBuf.st_mode) ) return FALSE;

    // Scan through for entries which look like Selafin files
    int nNotSelafinCount = 0, i;
    char **papszNames = VSIReadDir( osFilename );
    for( i = 0; papszNames != NULL && papszNames[i] != NULL; i++ ) {
        CPLString oSubFilename = CPLFormFilename( osFilename, papszNames[i], NULL );
        if( EQUAL(papszNames[i],".") || EQUAL(papszNames[i],"..") ) continue;
        if( VSIStatL( oSubFilename, &sStatBuf ) != 0 || !VSI_ISREG(sStatBuf.st_mode) ) {
            nNotSelafinCount++;
            continue;
        }
        if( !OpenTable( oSubFilename ) ) {
            CPLDebug("Selafin", "Cannot open %s", oSubFilename.c_str());
            nNotSelafinCount++;
            continue;
        }
    }
    CSLDestroy( papszNames );

    // We presume that this is indeed intended to be a Selafin datasource if over half the files were Selafin files.
    return nNotSelafinCount < nLayers;
#else
    return FALSE;
#endif
}
GDALDataset *ROIPACDataset::Open( GDALOpenInfo *poOpenInfo )
{
/* -------------------------------------------------------------------- */
/*      Confirm that the header is compatible with a ROIPAC dataset.    */
/* -------------------------------------------------------------------- */
    if ( !Identify(poOpenInfo) )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Open the .rsc file                                              */
/* -------------------------------------------------------------------- */
    CPLString osRscFilename = getRscFilename( poOpenInfo );
    if ( osRscFilename.empty() )
    {
        return NULL;
    }
    VSILFILE *fpRsc;
    if ( poOpenInfo->eAccess == GA_Update )
    {
        fpRsc = VSIFOpenL( osRscFilename, "r+" );
    }
    else
    {
        fpRsc = VSIFOpenL( osRscFilename, "r" );
    }
    if ( fpRsc == NULL )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Load the .rsc information.                                      */
/* -------------------------------------------------------------------- */
    char **papszRsc = NULL;
    while ( true )
    {
        const char *pszLine = CPLReadLineL( fpRsc );
        if (pszLine == NULL)
        {
            break;
        }

        char **papszTokens = CSLTokenizeString2( pszLine, " \t",
                                                 CSLT_STRIPLEADSPACES
                                                 | CSLT_STRIPENDSPACES
                                                 | CSLT_PRESERVEQUOTES
                                                 | CSLT_PRESERVEESCAPES );
        if ( papszTokens == NULL
             || papszTokens[0] == NULL || papszTokens[1] == NULL )
        {
            CSLDestroy ( papszTokens );
            break;
        }
        papszRsc = CSLSetNameValue( papszRsc,
                                       papszTokens[0], papszTokens[1] );

        CSLDestroy ( papszTokens );
    }

/* -------------------------------------------------------------------- */
/*      Fetch required fields.                                          */
/* -------------------------------------------------------------------- */
    if ( CSLFetchNameValue( papszRsc, "WIDTH" ) == NULL
        || CSLFetchNameValue( papszRsc, "FILE_LENGTH" ) == NULL )
    {
        CSLDestroy( papszRsc );
        CPL_IGNORE_RET_VAL(VSIFCloseL( fpRsc ));
        return NULL;
    }
    const int nWidth = atoi( CSLFetchNameValue( papszRsc, "WIDTH" ) );
    const int nFileLength = atoi( CSLFetchNameValue( papszRsc, "FILE_LENGTH" ) );

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    ROIPACDataset *poDS = new ROIPACDataset();
    poDS->nRasterXSize = nWidth;
    poDS->nRasterYSize = nFileLength;
    poDS->eAccess = poOpenInfo->eAccess;
    poDS->fpRsc = fpRsc;
    poDS->pszRscFilename = CPLStrdup( osRscFilename.c_str() );

/* -------------------------------------------------------------------- */
/*      Reopen file in update mode if necessary.                        */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" );
    }
    else
    {
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    }
    if( poDS->fpImage == NULL )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to re-open %s within ROI_PAC driver.\n",
                  poOpenInfo->pszFilename );
        CSLDestroy( papszRsc );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    GDALDataType eDataType;
    int nBands;
    enum Interleave { LINE, PIXEL } eInterleave;
    const char *pszExtension = CPLGetExtension(poOpenInfo->pszFilename);
    if ( strcmp( pszExtension, "raw" ) == 0 )
    {
        /* ------------------------------------------------------------ */
        /* TODO: ROI_PAC raw images are what would be GDT_CInt8 typed,  */
        /* but since that type do not exist, we will have to implement  */
        /* a specific case in the RasterBand to convert it to           */
        /* GDT_CInt16 for example                                       */
        /* ------------------------------------------------------------ */
#if 0
        eDataType = GDT_CInt8;
        nBands = 1;
        eInterleave = PIXEL;
#else
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Reading ROI_PAC raw files is not supported yet." );
        delete poDS;
        CSLDestroy( papszRsc );
        return NULL;
#endif
    }
    else if ( strcmp( pszExtension, "int" ) == 0
                || strcmp( pszExtension, "slc" ) == 0 )
    {
        eDataType = GDT_CFloat32;
        nBands = 1;
        eInterleave = PIXEL;
    }
    else if ( strcmp( pszExtension, "amp" ) == 0 )
    {
        eDataType = GDT_Float32;
        nBands = 2;
        eInterleave = PIXEL;
    }
    else if ( strcmp( pszExtension, "cor" ) == 0
                || strcmp( pszExtension, "hgt" ) == 0
                || strcmp( pszExtension, "unw" ) == 0
                || strcmp( pszExtension, "msk" ) == 0
                || strcmp( pszExtension, "trans" ) == 0 )
    {
        eDataType = GDT_Float32;
        nBands = 2;
        eInterleave = LINE;
    }
    else if ( strcmp( pszExtension, "dem" ) == 0 )
    {
        eDataType = GDT_Int16;
        nBands = 1;
        eInterleave = PIXEL;
    }
    else if ( strcmp( pszExtension, "flg" ) == 0 )
    {
        eDataType = GDT_Byte;
        nBands = 1;
        eInterleave = PIXEL;
    }
    else { /* Eeek */
        delete poDS;
        CSLDestroy( papszRsc );
        return NULL;
    }

    int nPixelOffset;
    int nLineOffset;
    int nBandOffset;
    if (eInterleave == LINE)
    {
        nPixelOffset = GDALGetDataTypeSize(eDataType)/8;
        nLineOffset = nPixelOffset * nWidth * nBands;
        nBandOffset = GDALGetDataTypeSize(eDataType)/8 * nWidth;
    }
    else { /* PIXEL */
        nPixelOffset = GDALGetDataTypeSize(eDataType)/8 * nBands;
        nLineOffset = nPixelOffset * nWidth;
        nBandOffset = GDALGetDataTypeSize(eDataType)/8;

        if( nBands > 1 )
        {
            // GDAL 2.0.[0-3] and 2.1.0  had a value of nLineOffset that was 
            // equal to the theoretical nLineOffset multiplied by nBands...
            VSIFSeekL( poDS->fpImage, 0, SEEK_END );
            const GUIntBig nWrongFileSize = GDALGetDataTypeSizeBytes(eDataType) *
                                            nWidth * (static_cast<GUIntBig>(nFileLength - 1) * nBands * nBands + nBands);
            if( VSIFTellL( poDS->fpImage ) == nWrongFileSize )
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "This file has been incorrectly generated by an older "
                         "GDAL version whose line offset computation was erroneous. "
                         "Taking that into account, but the file should be re-encoded ideally");
                nLineOffset = nLineOffset * nBands;
            }
        }
    }
    poDS->nBands = nBands;
    for (int b = 0; b < nBands; b++)
    {
        poDS->SetBand( b + 1,
                       new ROIPACRasterBand( poDS, b + 1, poDS->fpImage,
                                             nBandOffset * b,
                                             nPixelOffset, nLineOffset,
                                             eDataType, TRUE,
                                             TRUE, FALSE ) );
    }

/* -------------------------------------------------------------------- */
/*      Interpret georeferencing, if present.                           */
/* -------------------------------------------------------------------- */
    if ( CSLFetchNameValue( papszRsc, "X_FIRST" ) != NULL
          && CSLFetchNameValue( papszRsc, "X_STEP" ) != NULL
          && CSLFetchNameValue( papszRsc, "Y_FIRST" ) != NULL
          && CSLFetchNameValue( papszRsc, "Y_STEP" ) != NULL )
    {
        poDS->adfGeoTransform[0] = CPLAtof( CSLFetchNameValue( papszRsc,
                                                               "X_FIRST" ) );
        poDS->adfGeoTransform[1] = CPLAtof( CSLFetchNameValue( papszRsc,
                                                               "X_STEP" ) );
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = CPLAtof( CSLFetchNameValue( papszRsc,
                                                               "Y_FIRST" ) );
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = CPLAtof( CSLFetchNameValue( papszRsc,
                                                               "Y_STEP" ) );
        poDS->bValidGeoTransform = true;
    }
    if ( CSLFetchNameValue( papszRsc, "PROJECTION" ) != NULL )
    {
        /* ------------------------------------------------------------ */
        /* In ROI_PAC, images are georeferenced either with lat/long or */
        /* UTM projection. However, using UTM projection is dangerous   */
        /* because there is no North/South field, or use of latitude    */
        /* bands!                                                       */
        /* ------------------------------------------------------------ */
        OGRSpatialReference oSRS;
        if ( strcmp( CSLFetchNameValue( papszRsc, "PROJECTION" ),
                     "LL" ) == 0 )
        {
            if ( CSLFetchNameValue( papszRsc, "DATUM" ) != NULL )
            {
                oSRS.SetWellKnownGeogCS( CSLFetchNameValue( papszRsc,
                                                            "DATUM" ) );
            }
            else {
                oSRS.SetWellKnownGeogCS( "WGS84" );
            }
        }
        else if( STARTS_WITH(CSLFetchNameValue( papszRsc, "PROJECTION" ), "UTM") )
        {
            const char *pszZone = CSLFetchNameValue( papszRsc,
                                                     "PROJECTION" ) + 3;
            oSRS.SetUTM( atoi( pszZone ), TRUE ); /* FIXME: north/south? */
            if ( CSLFetchNameValue( papszRsc, "DATUM" ) != NULL )
            {
                oSRS.SetWellKnownGeogCS( CSLFetchNameValue( papszRsc,
                                                            "DATUM" ) );
            }
            else {
                oSRS.SetWellKnownGeogCS( "NAD27" );
            }
        }
        oSRS.exportToWkt( &poDS->pszProjection );
    }
    if ( CSLFetchNameValue( papszRsc, "Z_OFFSET" ) != NULL )
    {
        const double dfOffset
            = strtod( CSLFetchNameValue( papszRsc, "Z_OFFSET" ), NULL);
        for (int b = 1; b <= nBands; b++)
        {
            GDALRasterBand *poBand = poDS->GetRasterBand(b);
            poBand->SetOffset( dfOffset );
        }
    }
    if ( CSLFetchNameValue( papszRsc, "Z_SCALE" ) != NULL )
    {
        const double dfScale
            = strtod( CSLFetchNameValue( papszRsc, "Z_SCALE" ), NULL);
        for (int b = 1; b <= nBands; b++)
        {
            GDALRasterBand *poBand = poDS->GetRasterBand(b);
            poBand->SetScale( dfScale );
        }
    }


/* -------------------------------------------------------------------- */
/*      Set all the other header metadata into the ROI_PAC domain       */
/* -------------------------------------------------------------------- */
    for (int i = 0; i < CSLCount( papszRsc ); i++)
    {
        char **papszTokens = CSLTokenizeString2( papszRsc[i],
                                                 "=",
                                                 CSLT_STRIPLEADSPACES
                                                 | CSLT_STRIPENDSPACES);
        if ( strcmp( papszTokens[0], "WIDTH" ) == 0
              || strcmp( papszTokens[0], "FILE_LENGTH" ) == 0
              || strcmp( papszTokens[0], "X_FIRST" ) == 0
              || strcmp( papszTokens[0], "X_STEP" ) == 0
              || strcmp( papszTokens[0], "Y_FIRST" ) == 0
              || strcmp( papszTokens[0], "Y_STEP" ) == 0
              || strcmp( papszTokens[0], "PROJECTION" ) == 0
              || strcmp( papszTokens[0], "DATUM" ) == 0
              || strcmp( papszTokens[0], "Z_OFFSET" ) == 0
              || strcmp( papszTokens[0], "Z_SCALE" ) == 0 )
        {
            CSLDestroy( papszTokens );
            continue;
        }
        poDS->SetMetadataItem(papszTokens[0], papszTokens[1], "ROI_PAC");
        CSLDestroy( papszTokens );
    }

/* -------------------------------------------------------------------- */
/*      Free papszRsc                                                   */
/* -------------------------------------------------------------------- */
    CSLDestroy( papszRsc );

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

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

    return( poDS );
}
json_object* OGRCARTODataSource::RunSQL(const char* pszUnescapedSQL)
{
    CPLString osSQL("POSTFIELDS=q=");
    /* Do post escaping */
    for(int i=0;pszUnescapedSQL[i] != 0;i++)
    {
        const int ch = ((unsigned char*)pszUnescapedSQL)[i];
        if (ch != '&' && ch >= 32 && ch < 128)
            osSQL += (char)ch;
        else
            osSQL += CPLSPrintf("%%%02X", ch);
    }

/* -------------------------------------------------------------------- */
/*      Provide the API Key                                             */
/* -------------------------------------------------------------------- */
    if( osAPIKey.size() )
    {
        osSQL += "&api_key=";
        osSQL += osAPIKey;
    }

/* -------------------------------------------------------------------- */
/*      Collection the header options and execute request.              */
/* -------------------------------------------------------------------- */
    const char* pszAPIURL = GetAPIURL();
    char** papszOptions = CSLAddString(
        !STARTS_WITH(pszAPIURL, "/vsimem/") ? AddHTTPOptions(): NULL, osSQL);
    CPLHTTPResult * psResult = CPLHTTPFetch( GetAPIURL(), papszOptions);
    CSLDestroy(papszOptions);
    if( psResult == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Check for some error conditions and report.  HTML Messages      */
/*      are transformed info failure.                                   */
/* -------------------------------------------------------------------- */
    if (psResult->pszContentType &&
        STARTS_WITH(psResult->pszContentType, "text/html"))
    {
        CPLDebug( "CARTO", "RunSQL HTML Response:%s", psResult->pabyData );
        CPLError(CE_Failure, CPLE_AppDefined,
                 "HTML error page returned by server");
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }
    if (psResult->pszErrBuf != NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "RunSQL Error Message:%s", psResult->pszErrBuf );
    }
    else if (psResult->nStatus != 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "RunSQL Error Status:%d", psResult->nStatus );
    }

    if( psResult->pabyData == NULL )
    {
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }

    if( strlen((const char*)psResult->pabyData) < 1000 )
        CPLDebug( "CARTO", "RunSQL Response:%s", psResult->pabyData );

    json_tokener* jstok = NULL;
    json_object* poObj = NULL;

    jstok = json_tokener_new();
    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
    if( jstok->err != json_tokener_success)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                    "JSON parsing error: %s (at offset %d)",
                    json_tokener_error_desc(jstok->err), jstok->char_offset);
        json_tokener_free(jstok);
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }
    json_tokener_free(jstok);

    CPLHTTPDestroyResult(psResult);

    if( poObj != NULL )
    {
        if( json_object_get_type(poObj) == json_type_object )
        {
            json_object* poError = json_object_object_get(poObj, "error");
            if( poError != NULL && json_object_get_type(poError) == json_type_array &&
                json_object_array_length(poError) > 0 )
            {
                poError = json_object_array_get_idx(poError, 0);
                if( poError != NULL && json_object_get_type(poError) == json_type_string )
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                            "Error returned by server : %s", json_object_get_string(poError));
                    json_object_put(poObj);
                    return NULL;
                }
            }
        }
        else
        {
            json_object_put(poObj);
            return NULL;
        }
    }

    return poObj;
}
Beispiel #5
0
int OGRSEGUKOOADataSource::Open( const char * pszFilename )

{
    pszName = CPLStrdup( pszFilename );

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

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

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

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

    if (STARTS_WITH(pszLine, "H0100 "))
    {
        VSIFSeekL( fp, 0, SEEK_SET );

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

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

        return TRUE;
    }

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

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

        if (iLine == 20)
            break;

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

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

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

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

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

        return TRUE;
    }

    VSIFCloseL(fp);
    return FALSE;
}
Beispiel #6
0
GDALDataset *GXFDataset::Open( GDALOpenInfo * poOpenInfo )

{
    GXFHandle	l_hGXF;
    int		i, bFoundKeyword, bFoundIllegal;

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

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

    if( !bFoundKeyword || bFoundIllegal )
        return NULL;

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

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

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

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

    CPLFree( pszBigBuf );

    if( !bGotGrid )
        return NULL;

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

    l_hGXF = GXFOpen( poOpenInfo->pszFilename );

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

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

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

    poDS = new GXFDataset();

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

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

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

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

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

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

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

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

    return( poDS );
}
Beispiel #7
0
static int MEMDatasetIdentify( GDALOpenInfo * poOpenInfo )
{
    return (STARTS_WITH(poOpenInfo->pszFilename, "MEM:::") &&
            poOpenInfo->fpL == NULL);
}
Beispiel #8
0
OGRErr      OGRGFTTableLayer::ISetFeature( OGRFeature *poFeature )
{
    GetLayerDefn();

    if (!poDS->IsReadWrite())
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Operation not available in read-only mode");
        return OGRERR_FAILURE;
    }

    if (osTableId.size() == 0)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                "Cannot set feature to non-created table");
        return OGRERR_FAILURE;
    }

    if (poDS->GetAccessToken().size() == 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Operation not available in unauthenticated mode");
        return OGRERR_FAILURE;
    }

    if (poFeature->GetFID() == OGRNullFID)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "FID required on features given to SetFeature()." );
        return OGRERR_FAILURE;
    }

    CPLString      osCommand;

    osCommand += "UPDATE ";
    osCommand += osTableId;
    osCommand += " SET ";

    int iField;
    int nFieldCount = poFeatureDefn->GetFieldCount();
    for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++)
    {
        if (iField > 0)
            osCommand += ", ";

        if (iField == nFieldCount)
        {
            osCommand += EscapeAndQuote(GetGeometryColumn());
        }
        else
        {
            const char* pszFieldName =
                poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
            osCommand += EscapeAndQuote(pszFieldName);
        }

        osCommand += " = ";

        OGRGeometry* poGeom = poFeature->GetGeometryRef();
        if (iGeometryField != iLatitudeField && iField == iGeometryField &&
            (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField )))
        {
            if (poGeom == NULL)
                osCommand += "''";
            else
            {
                char* pszKML;
                if (poGeom->getSpatialReference() != NULL &&
                    !poGeom->getSpatialReference()->IsSame(poSRS))
                {
                    OGRGeometry* poGeom4326 = poGeom->clone();
                    poGeom4326->transformTo(poSRS);
                    pszKML = poGeom4326->exportToKML();
                    delete poGeom4326;
                }
                else
                {
                    pszKML = poGeom->exportToKML();
                }
                osCommand += "'";
                osCommand += pszKML;
                osCommand += "'";
                CPLFree(pszKML);
            }
            continue;
        }

        if( !poFeature->IsFieldSet( iField ) )
        {
            osCommand += "''";
        }
        else
        {
            OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType();
            if (eType != OFTInteger && eType != OFTReal)
            {
                CPLString osTmp;
                const char* pszVal = poFeature->GetFieldAsString(iField);

                if (!CPLIsUTF8(pszVal, -1))
                {
                    static int bFirstTime = TRUE;
                    if (bFirstTime)
                    {
                        bFirstTime = FALSE;
                        CPLError(CE_Warning, CPLE_AppDefined,
                                "%s is not a valid UTF-8 string. Forcing it to ASCII.\n"
                                "This warning won't be issued anymore", pszVal);
                    }
                    else
                    {
                        CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII",
                                pszVal);
                    }
                    char* pszEscaped = CPLForceToASCII(pszVal, -1, '?');
                    osTmp = pszEscaped;
                    CPLFree(pszEscaped);
                    pszVal = osTmp.c_str();
                }

                osCommand += EscapeAndQuote(pszVal);
            }
            else
                osCommand += poFeature->GetFieldAsString(iField);
        }
    }

    osCommand += " WHERE ROWID = '";
    osCommand += CPLSPrintf(CPL_FRMT_GIB, poFeature->GetFID());
    osCommand += "'";

    CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
    if (psResult == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed (1)");
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      We expect a response like "affected_rows\n1".                   */
/* -------------------------------------------------------------------- */
    char* pszLine = (char*) psResult->pabyData;
    if (pszLine == NULL ||
        !STARTS_WITH(pszLine, "affected_rows\n1\n") ||
        psResult->pszErrBuf != NULL)
    {
        CPLDebug( "GFT", "%s/%s",
                  pszLine ? pszLine : "null",
                  psResult->pszErrBuf ? psResult->pszErrBuf : "null");
        CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed (2)");
        CPLHTTPDestroyResult(psResult);
        return OGRERR_FAILURE;
    }

    CPLHTTPDestroyResult(psResult);

    return OGRERR_NONE;
}
Beispiel #9
0
CPLErr GDALWMSDataset::Initialize(CPLXMLNode *config, char **l_papszOpenOptions) {
    CPLErr ret = CE_None;

    char* pszXML = CPLSerializeXMLTree( config );
    if (pszXML)
    {
        m_osXML = pszXML;
        CPLFree(pszXML);
    }

    // Generic options that apply to all minidrivers

    // UserPwd
    const char *pszUserPwd = CPLGetXMLValue(config, "UserPwd", "");
    if (pszUserPwd[0] != '\0')
        m_osUserPwd = pszUserPwd;

    const char *pszUserAgent = CPLGetXMLValue(config, "UserAgent", "");
    if (pszUserAgent[0] != '\0')
        m_osUserAgent = pszUserAgent;
    else
        m_osUserAgent = CPLGetConfigOption("GDAL_HTTP_USERAGENT", "");

    const char *pszReferer = CPLGetXMLValue(config, "Referer", "");
    if (pszReferer[0] != '\0')
        m_osReferer = pszReferer;

    if (ret == CE_None) {
        const char *pszHttpZeroBlockCodes = CPLGetXMLValue(config, "ZeroBlockHttpCodes", "");
        if (pszHttpZeroBlockCodes[0] == '\0') {
            m_http_zeroblock_codes.insert(204);
        }
        else {
            char **kv = CSLTokenizeString2(pszHttpZeroBlockCodes, ",", CSLT_HONOURSTRINGS);
            for (int i = 0; i < CSLCount(kv); i++) {
                int code = atoi(kv[i]);
                if (code <= 0) {
                    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ZeroBlockHttpCodes "
                        "\"%s\", comma separated HTTP response codes expected.", kv[i]);
                    ret = CE_Failure;
                    break;
                }
                m_http_zeroblock_codes.insert(code);
            }
            CSLDestroy(kv);
        }
    }

    if (ret == CE_None) {
        const char *pszZeroExceptions = CPLGetXMLValue(config, "ZeroBlockOnServerException", "");
        if (pszZeroExceptions[0] != '\0') {
            m_zeroblock_on_serverexceptions = StrToBool(pszZeroExceptions);
            if (m_zeroblock_on_serverexceptions == -1) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ZeroBlockOnServerException "
                    "\"%s\", true/false expected.", pszZeroExceptions);
                ret = CE_Failure;
            }
        }
    }

    if (ret == CE_None) {
        const char *max_conn = CPLGetXMLValue(config, "MaxConnections", "");
        if (max_conn[0] != '\0') {
            m_http_max_conn = atoi(max_conn);
        }
        else {
            m_http_max_conn = 2;
        }
    }

    if (ret == CE_None) {
        const char *timeout = CPLGetXMLValue(config, "Timeout", "");
        if (timeout[0] != '\0') {
            m_http_timeout = atoi(timeout);
        }
        else {
            m_http_timeout = 300;
        }
    }

    if (ret == CE_None) {
        const char *offline_mode = CPLGetXMLValue(config, "OfflineMode", "");
        if (offline_mode[0] != '\0') {
            const int offline_mode_bool = StrToBool(offline_mode);
            if (offline_mode_bool == -1) {
                CPLError(CE_Failure, CPLE_AppDefined,
                    "GDALWMS: Invalid value of OfflineMode, true / false expected.");
                ret = CE_Failure;
            }
            else {
                m_offline_mode = offline_mode_bool;
            }
        }
        else {
            m_offline_mode = 0;
        }
    }

    if (ret == CE_None) {
        const char *advise_read = CPLGetXMLValue(config, "AdviseRead", "");
        if (advise_read[0] != '\0') {
            const int advise_read_bool = StrToBool(advise_read);
            if (advise_read_bool == -1) {
                CPLError(CE_Failure, CPLE_AppDefined,
                    "GDALWMS: Invalid value of AdviseRead, true / false expected.");
                ret = CE_Failure;
            }
            else {
                m_use_advise_read = advise_read_bool;
            }
        }
        else {
            m_use_advise_read = 0;
        }
    }

    if (ret == CE_None) {
        const char *verify_advise_read = CPLGetXMLValue(config, "VerifyAdviseRead", "");
        if (m_use_advise_read) {
            if (verify_advise_read[0] != '\0') {
                const int verify_advise_read_bool = StrToBool(verify_advise_read);
                if (verify_advise_read_bool == -1) {
                    CPLError(CE_Failure, CPLE_AppDefined,
                        "GDALWMS: Invalid value of VerifyAdviseRead, true / false expected.");
                    ret = CE_Failure;
                }
                else {
                    m_verify_advise_read = verify_advise_read_bool;
                }
            }
            else {
                m_verify_advise_read = 1;
            }
        }
    }

    if (ret == CE_None) {
        CPLXMLNode *cache_node = CPLGetXMLNode(config, "Cache");
        if (cache_node != NULL) {
            m_cache = new GDALWMSCache();
            if (m_cache->Initialize(cache_node) != CE_None) {
                delete m_cache;
                m_cache = NULL;
                CPLError(CE_Failure, CPLE_AppDefined,
                    "GDALWMS: Failed to initialize cache.");
                ret = CE_Failure;
            }
        }
    }

    if (ret == CE_None) {
        const int v = StrToBool(CPLGetXMLValue(config, "UnsafeSSL", "false"));
        if (v == -1) {
            CPLError(CE_Failure, CPLE_AppDefined,
                "GDALWMS: Invalid value of UnsafeSSL: true or false expected.");
            ret = CE_Failure;
        }
        else {
            m_unsafeSsl = v;
        }
    }

    // Initialize the minidriver, which can set parameters for the dataset using member functions
    CPLXMLNode *service_node = CPLGetXMLNode(config, "Service");
    if (service_node == NULL) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "GDALWMS: No Service specified.");
        return CE_Failure;
    }

    const CPLString service_name = CPLGetXMLValue(service_node, "name", "");
    if (service_name.empty()) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "GDALWMS: No Service name specified.");
        return CE_Failure;
    }

    m_mini_driver = NewWMSMiniDriver(service_name);
    if (m_mini_driver == NULL) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "GDALWMS: No mini-driver registered for '%s'.", service_name.c_str());
        return CE_Failure;
    }

    // Set up minidriver
    m_mini_driver->m_parent_dataset = this;
    if (m_mini_driver->Initialize(service_node, l_papszOpenOptions) != CE_None)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize minidriver.");
        delete m_mini_driver;
        m_mini_driver = NULL;
        ret = CE_Failure;
    }
    else
    {
        m_mini_driver->GetCapabilities(&m_mini_driver_caps);
    }

    /*
      Parameters that could be set by minidriver already
      If the size is set, minidriver has done this already
      A "server" side minidriver needs to set at least:
      - Blocksize (x and y)
      - Clamp flag (defaults to true)
      - DataWindow
      - Band Count
      - Data Type
      It should also initialize and register the bands and overviews.
    */

    if (m_data_window.m_sx<1)
    {
        int nOverviews = 0;

        if (ret == CE_None)
        {
            m_block_size_x = atoi(CPLGetXMLValue(config, "BlockSizeX",
                CPLString().Printf("%d", m_default_block_size_x)));
            m_block_size_y = atoi(CPLGetXMLValue(config, "BlockSizeY",
                CPLString().Printf("%d", m_default_block_size_y)));
            if (m_block_size_x <= 0 || m_block_size_y <= 0)
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                    "GDALWMS: Invalid value in BlockSizeX or BlockSizeY" );
                ret = CE_Failure;
            }
        }

        if (ret == CE_None)
        {
            m_clamp_requests = StrToBool(CPLGetXMLValue(config, "ClampRequests", "true"));
            if (m_clamp_requests<0)
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                    "GDALWMS: Invalid value of ClampRequests, true/false expected.");
                ret = CE_Failure;
            }
        }

        if (ret == CE_None)
        {
            CPLXMLNode *data_window_node = CPLGetXMLNode(config, "DataWindow");
            if (data_window_node == NULL && m_bNeedsDataWindow)
            {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow missing.");
                ret = CE_Failure;
            }
            else
            {
                CPLString osDefaultX0, osDefaultX1, osDefaultY0, osDefaultY1;
                CPLString osDefaultTileCountX, osDefaultTileCountY, osDefaultTileLevel;
                CPLString osDefaultOverviewCount;
                osDefaultX0.Printf("%.8f", m_default_data_window.m_x0);
                osDefaultX1.Printf("%.8f", m_default_data_window.m_x1);
                osDefaultY0.Printf("%.8f", m_default_data_window.m_y0);
                osDefaultY1.Printf("%.8f", m_default_data_window.m_y1);
                osDefaultTileCountX.Printf("%d", m_default_tile_count_x);
                osDefaultTileCountY.Printf("%d", m_default_tile_count_y);
                if (m_default_data_window.m_tlevel >= 0)
                    osDefaultTileLevel.Printf("%d", m_default_data_window.m_tlevel);
                if (m_default_overview_count >= 0)
                    osDefaultOverviewCount.Printf("%d", m_default_overview_count);
                const char *overview_count = CPLGetXMLValue(config, "OverviewCount", osDefaultOverviewCount);
                const char *ulx = CPLGetXMLValue(data_window_node, "UpperLeftX", osDefaultX0);
                const char *uly = CPLGetXMLValue(data_window_node, "UpperLeftY", osDefaultY0);
                const char *lrx = CPLGetXMLValue(data_window_node, "LowerRightX", osDefaultX1);
                const char *lry = CPLGetXMLValue(data_window_node, "LowerRightY", osDefaultY1);
                const char *sx = CPLGetXMLValue(data_window_node, "SizeX", "");
                const char *sy = CPLGetXMLValue(data_window_node, "SizeY", "");
                const char *tx = CPLGetXMLValue(data_window_node, "TileX", "0");
                const char *ty = CPLGetXMLValue(data_window_node, "TileY", "0");
                const char *tlevel =
                    CPLGetXMLValue(data_window_node, "TileLevel", osDefaultTileLevel);
                const char *str_tile_count_x =
                    CPLGetXMLValue(data_window_node, "TileCountX", osDefaultTileCountX);
                const char *str_tile_count_y =
                    CPLGetXMLValue(data_window_node, "TileCountY", osDefaultTileCountY);
                const char *y_origin = CPLGetXMLValue(data_window_node, "YOrigin", "default");

                if (ret == CE_None)
                {
                    if ((ulx[0] != '\0') && (uly[0] != '\0') && (lrx[0] != '\0') && (lry[0] != '\0'))
                    {
                        m_data_window.m_x0 = CPLAtof(ulx);
                        m_data_window.m_y0 = CPLAtof(uly);
                        m_data_window.m_x1 = CPLAtof(lrx);
                        m_data_window.m_y1 = CPLAtof(lry);
                    }
                    else
                    {
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "GDALWMS: Mandatory elements of DataWindow missing: "
                                 "UpperLeftX, UpperLeftY, LowerRightX, LowerRightY.");
                        ret = CE_Failure;
                    }
                }

                m_data_window.m_tlevel = atoi(tlevel);

                if (ret == CE_None)
                {
                    if ((sx[0] != '\0') && (sy[0] != '\0'))
                    {
                        m_data_window.m_sx = atoi(sx);
                        m_data_window.m_sy = atoi(sy);
                    }
                    else if ((tlevel[0] != '\0') && (str_tile_count_x[0] != '\0') && (str_tile_count_y[0] != '\0'))
                    {
                        int tile_count_x = atoi(str_tile_count_x);
                        int tile_count_y = atoi(str_tile_count_y);
                        m_data_window.m_sx = tile_count_x * m_block_size_x * (1 << m_data_window.m_tlevel);
                        m_data_window.m_sy = tile_count_y * m_block_size_y * (1 << m_data_window.m_tlevel);
                    }
                    else
                    {
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "GDALWMS: Mandatory elements of DataWindow missing: SizeX, SizeY.");
                        ret = CE_Failure;
                    }
                }
                if (ret == CE_None)
                {
                    if ((tx[0] != '\0') && (ty[0] != '\0'))
                    {
                        m_data_window.m_tx = atoi(tx);
                        m_data_window.m_ty = atoi(ty);
                    }
                    else
                    {
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "GDALWMS: Mandatory elements of DataWindow missing: TileX, TileY.");
                        ret = CE_Failure;
                    }
                }

                if (ret == CE_None)
                {
                    if (overview_count[0] != '\0')
                    {
                        nOverviews = atoi(overview_count);
                    }
                    else if (tlevel[0] != '\0')
                    {
                        nOverviews = m_data_window.m_tlevel;
                    }
                    else
                    {
                        const int min_overview_size =
                            std::max(32, std::min(m_block_size_x,
                                                  m_block_size_y));
                        double a =
                            log(static_cast<double>(
                                std::min(m_data_window.m_sx,
                                         m_data_window.m_sy))) / log(2.0)
                            - log(static_cast<double>(min_overview_size)) /
                            log(2.0);
                        nOverviews =
                            std::max(0,
                                     std::min(static_cast<int>(ceil(a)), 32));
                    }
                }
                if (ret == CE_None)
                {
                    CPLString y_origin_str = y_origin;
                    if (y_origin_str == "top") {
                        m_data_window.m_y_origin = GDALWMSDataWindow::TOP;
                    } else if (y_origin_str == "bottom") {
                        m_data_window.m_y_origin = GDALWMSDataWindow::BOTTOM;
                    } else if (y_origin_str == "default") {
                        m_data_window.m_y_origin = GDALWMSDataWindow::DEFAULT;
                    } else {
                        CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow YOrigin must be set to "
                                 "one of 'default', 'top', or 'bottom', not '%s'.", y_origin_str.c_str());
                        ret = CE_Failure;
                    }
                }
            }
        }

        if (ret == CE_None)
        {
            if (nBands<1)
                nBands=atoi(CPLGetXMLValue(config,"BandsCount","3"));
            if (nBands<1)
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "GDALWMS: Bad number of bands.");
                ret = CE_Failure;
            }
        }

        if (ret == CE_None)
        {
            const char *data_type = CPLGetXMLValue(config, "DataType", "Byte");
            m_data_type = GDALGetDataTypeByName(data_type);
            if (m_data_type == GDT_Unknown || m_data_type >= GDT_TypeCount)
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                    "GDALWMS: Invalid value in DataType. Data type \"%s\" is not supported.", data_type);
                ret = CE_Failure;
            }
            else if (!STARTS_WITH(data_type, "Byte")) { // Valid, non-byte
                m_tileOO = CSLSetNameValue(m_tileOO, "@DATATYPE", data_type);
            }
        }

        // Initialize the bands and the overviews.  Assumes overviews are powers of two
        if (ret == CE_None)
        {
            nRasterXSize = m_data_window.m_sx;
            nRasterYSize = m_data_window.m_sy;

            if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize) ||
                !GDALCheckBandCount(nBands, TRUE))
            {
                return CE_Failure;
            }

            GDALColorInterp default_color_interp[4][4] = {
                { GCI_GrayIndex, GCI_Undefined, GCI_Undefined, GCI_Undefined },
                { GCI_GrayIndex, GCI_AlphaBand, GCI_Undefined, GCI_Undefined },
                { GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_Undefined },
                { GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_AlphaBand }
            };
            for (int i = 0; i < nBands; ++i)
            {
                GDALColorInterp color_interp = (nBands <= 4 && i <= 3 ? default_color_interp[nBands - 1][i] : GCI_Undefined);
                GDALWMSRasterBand *band = new GDALWMSRasterBand(this, i, 1.0);
                band->m_color_interp = color_interp;
                SetBand(i + 1, band);
                double scale = 0.5;
                for (int j = 0; j < nOverviews; ++j)
                {
                    band->AddOverview(scale);
                    band->m_color_interp = color_interp;
                    scale *= 0.5;
                }
            }
        }
    }

    // Let the local configuration override the minidriver supplied projection
    if (ret == CE_None) {
        const char *proj = CPLGetXMLValue(config, "Projection", "");
        if (proj[0] != '\0') {
            m_projection = ProjToWKT(proj);
            if (m_projection.empty()) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Bad projection specified.");
                ret = CE_Failure;
            }
        }
    }

    // Same for Min, Max and NoData, defined per band or per dataset
    // If they are set as null strings, they clear the server declared values
    if (ret == CE_None) {
        // Data values are attributes, they include NoData Min and Max
        // TODO: document those options
        if (NULL!=CPLGetXMLNode(config,"DataValues")) {
            const char *nodata=CPLGetXMLValue(config,"DataValues.NoData",NULL);
            if (nodata!=NULL) WMSSetNoDataValue(nodata);
            const char *min=CPLGetXMLValue(config,"DataValues.min",NULL);
            if (min!=NULL) WMSSetMinValue(min);
            const char *max=CPLGetXMLValue(config,"DataValues.max",NULL);
            if (max!=NULL) WMSSetMaxValue(max);
        }
    }

    if (ret == CE_None) {
        if (!m_projection.size()) {
            const char *proj = m_mini_driver->GetProjectionInWKT();
            if (proj != NULL) {
                m_projection = proj;
            }
        }
    }

    // Finish the minidriver initialization
    if (ret == CE_None)
        m_mini_driver->EndInit();

    return ret;
}
Beispiel #10
0
void OGRGFTTableLayer::CreateTableIfNecessary()
{
    if (bHasTriedCreateTable || osTableId.size() != 0)
        return;

    bHasTriedCreateTable = TRUE;

    CPLString osSQL("CREATE TABLE '");
    osSQL += osTableName;
    osSQL += "' (";

    /* If there are longitude and latitude fields, use the latitude */
    /* field as the LOCATION field */
    for( int i=0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef();
        if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") ||
            EQUAL(pszName, "latdec"))
            iLatitudeField = i;
        else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") ||
                 EQUAL(pszName, "londec") || EQUAL(pszName, "long"))
            iLongitudeField = i;
    }

    if (iLatitudeField >= 0 && iLongitudeField >= 0)
    {
        iGeometryField = iLatitudeField;
        poFeatureDefn->SetGeomType( wkbPoint );
    }
    /* If no longitude/latitude field exist, let's look at a column */
    /* named 'geometry' and use it as the LOCATION column if the layer */
    /* hasn't been created with a none geometry type */
    else if (iGeometryField < 0 && eGTypeForCreation != wkbNone)
    {
        iGeometryField = poFeatureDefn->GetFieldIndex(GetDefaultGeometryColumnName());
        poFeatureDefn->SetGeomType( eGTypeForCreation );
    }
    /* The user doesn't want geometries, so don't create one */
    else if (eGTypeForCreation == wkbNone)
    {
        poFeatureDefn->SetGeomType( eGTypeForCreation );
    }

    int i = 0;
    for( ; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if (i > 0)
            osSQL += ", ";

        const char* pszFieldName =
            poFeatureDefn->GetFieldDefn(i)->GetNameRef();
        osSQL += EscapeAndQuote(pszFieldName);
        osSQL += ": ";

        if (iGeometryField == i)
        {
            osSQL += "LOCATION";
        }
        else
        {
            switch(poFeatureDefn->GetFieldDefn(i)->GetType())
            {
                case OFTInteger:
                case OFTReal:
                    osSQL += "NUMBER";
                    break;
                default:
                    osSQL += "STRING";
            }
        }
    }

    /* If there's not yet a geometry field and the user didn't forbid */
    /* the creation of one, then let's add it to the CREATE TABLE, but */
    /* DO NOT add it to the feature defn as a feature might already have */
    /* been created with it, so it is not safe to alter it at that point. */
    /* So we set the bHiddenGeometryField flag to be able to fetch/set this */
    /* column but not try to get/set a related feature field */
    if (iGeometryField < 0 && eGTypeForCreation != wkbNone)
    {
        if (i > 0)
            osSQL += ", ";
        osSQL += EscapeAndQuote(GetDefaultGeometryColumnName());
        osSQL += ": LOCATION";

        iGeometryField = poFeatureDefn->GetFieldCount();
        bHiddenGeometryField = TRUE;
    }
    osSQL += ")";

    CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
    if (psResult == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
        return;
    }

    char* pszLine = (char*) psResult->pabyData;
    if (pszLine == NULL ||
        !STARTS_WITH(pszLine, "tableid") ||
        psResult->pszErrBuf != NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
        CPLHTTPDestroyResult(psResult);
        return;
    }

    pszLine = OGRGFTGotoNextLine(pszLine);
    if (pszLine == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
        CPLHTTPDestroyResult(psResult);
        return;
    }

    char* pszNextLine = OGRGFTGotoNextLine(pszLine);
    if (pszNextLine)
        pszNextLine[-1] = 0;

    osTableId = pszLine;
    CPLDebug("GFT", "Table %s --> id = %s", osTableName.c_str(), osTableId.c_str());

    CPLHTTPDestroyResult(psResult);
}
Beispiel #11
0
OGRErr OGRGFTTableLayer::ICreateFeature( OGRFeature *poFeature )

{
    if (!poDS->IsReadWrite())
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Operation not available in read-only mode");
        return OGRERR_FAILURE;
    }

    if (osTableId.size() == 0)
    {
        CreateTableIfNecessary();
        if (osTableId.size() == 0)
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "Cannot add feature to non-created table");
            return OGRERR_FAILURE;
        }
    }

    if (poDS->GetAccessToken().size() == 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Operation not available in unauthenticated mode");
        return OGRERR_FAILURE;
    }

    CPLString      osCommand;

    osCommand += "INSERT INTO ";
    osCommand += osTableId;
    osCommand += " (";

    int iField;
    int nFieldCount = poFeatureDefn->GetFieldCount();
    for(iField = 0; iField < nFieldCount; iField++)
    {
        if (iField > 0)
            osCommand += ", ";

        const char* pszFieldName =
            poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
        osCommand += EscapeAndQuote(pszFieldName);
    }
    if (bHiddenGeometryField)
    {
        if (iField > 0)
            osCommand += ", ";
        osCommand += EscapeAndQuote(GetGeometryColumn());
    }
    osCommand += ") VALUES (";
    for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++)
    {
        if (iField > 0)
            osCommand += ", ";

        OGRGeometry* poGeom = poFeature->GetGeometryRef();
        /* If there's a geometry, let's use it in priority over the textual */
        /* content of the field. */
        if (iGeometryField != iLatitudeField && iField == iGeometryField &&
            (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField )))
        {
            if (poGeom == NULL)
                osCommand += "''";
            else
            {
                char* pszKML;
                if (poGeom->getSpatialReference() != NULL &&
                    !poGeom->getSpatialReference()->IsSame(poSRS))
                {
                    OGRGeometry* poGeom4326 = poGeom->clone();
                    poGeom4326->transformTo(poSRS);
                    pszKML = poGeom4326->exportToKML();
                    delete poGeom4326;
                }
                else
                {
                    pszKML = poGeom->exportToKML();
                }
                osCommand += "'";
                osCommand += pszKML;
                osCommand += "'";
                CPLFree(pszKML);
            }
            continue;
        }

        if( !poFeature->IsFieldSet( iField ) )
        {
            osCommand += "''";
        }
        else
        {
            OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType();
            if (eType != OFTInteger && eType != OFTReal)
            {
                CPLString osTmp;
                const char* pszVal = poFeature->GetFieldAsString(iField);

                if (!CPLIsUTF8(pszVal, -1))
                {
                    static int bFirstTime = TRUE;
                    if (bFirstTime)
                    {
                        bFirstTime = FALSE;
                        CPLError(CE_Warning, CPLE_AppDefined,
                                "%s is not a valid UTF-8 string. Forcing it to ASCII.\n"
                                "This warning won't be issued anymore", pszVal);
                    }
                    else
                    {
                        CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII",
                                pszVal);
                    }
                    char* pszEscaped = CPLForceToASCII(pszVal, -1, '?');
                    osTmp = pszEscaped;
                    CPLFree(pszEscaped);
                    pszVal = osTmp.c_str();
                }

                osCommand += EscapeAndQuote(pszVal);
            }
            else
                osCommand += poFeature->GetFieldAsString(iField);
        }
    }

    osCommand += ")";

    //CPLDebug("GFT", "%s",  osCommand.c_str());

    if (bInTransaction)
    {
        nFeaturesInTransaction ++;
        if (nFeaturesInTransaction > 1)
            osTransaction += "; ";
        osTransaction += osCommand;
        return OGRERR_NONE;
    }

    CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
    if (psResult == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
        return OGRERR_FAILURE;
    }

    char* pszLine = (char*) psResult->pabyData;
    if (pszLine == NULL ||
        !STARTS_WITH(pszLine, "rowid") ||
        psResult->pszErrBuf != NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
        CPLHTTPDestroyResult(psResult);
        return OGRERR_FAILURE;
    }

    pszLine = OGRGFTGotoNextLine(pszLine);
    if (pszLine == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
        CPLHTTPDestroyResult(psResult);
        return OGRERR_FAILURE;
    }

    char* pszNextLine = OGRGFTGotoNextLine(pszLine);
    if (pszNextLine)
        pszNextLine[-1] = 0;

    CPLDebug("GFT", "Feature id = %s",  pszLine);

    int nFID = atoi(pszLine);
    if (strcmp(CPLSPrintf("%d", nFID), pszLine) == 0)
        poFeature->SetFID(nFID);

    CPLHTTPDestroyResult(psResult);

    return OGRERR_NONE;
}
Beispiel #12
0
int OGRGFTTableLayer::FetchDescribe()
{
    poFeatureDefn = new OGRFeatureDefn( osTableName );
    poFeatureDefn->Reference();
    poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);

    const CPLString& osAuth = poDS->GetAccessToken();
    std::vector<CPLString> aosHeaderAndFirstDataLine;
    if (osAuth.size())
    {
        CPLString osSQL("DESCRIBE ");
        osSQL += osTableId;
        CPLHTTPResult * psResult = poDS->RunSQL(osSQL);

        if (psResult == NULL)
            return FALSE;

        char* pszLine = (char*) psResult->pabyData;
        if (pszLine == NULL ||
            psResult->pszErrBuf != NULL ||
            !STARTS_WITH(pszLine, "column id,name,type"))        {
            CPLHTTPDestroyResult(psResult);
            return FALSE;
        }

        pszLine = OGRGFTGotoNextLine(pszLine);

        std::vector<CPLString> aosLines;
        ParseCSVResponse(pszLine, aosLines);
        for(int i=0;i<(int)aosLines.size();i++)
        {
            char** papszTokens = OGRGFTCSVSplitLine(aosLines[i], ',');
            if (CSLCount(papszTokens) == 3)
            {
                aosColumnInternalName.push_back(papszTokens[0]);

                //CPLDebug("GFT", "%s %s %s", papszTokens[0], papszTokens[1], papszTokens[2]);
                OGRFieldType eType = OFTString;
                if (EQUAL(papszTokens[2], "number"))
                    eType = OFTReal;
                else if (EQUAL(papszTokens[2], "datetime"))
                    eType = OFTDateTime;

                if (EQUAL(papszTokens[2], "location") && osGeomColumnName.size() == 0)
                {
                    if (iGeometryField < 0)
                        iGeometryField = poFeatureDefn->GetFieldCount();
                    else
                        CPLDebug("GFT", "Multiple geometry fields detected. "
                                         "Only first encountered one is handled");
                }

                CPLString osLaunderedColName(LaunderColName(papszTokens[1]));
                OGRFieldDefn oFieldDefn(osLaunderedColName, eType);
                poFeatureDefn->AddFieldDefn(&oFieldDefn);
            }
            CSLDestroy(papszTokens);
        }

        CPLHTTPDestroyResult(psResult);
    }
    else
    {
        /* http://code.google.com/intl/fr/apis/fusiontables/docs/developers_guide.html#Exploring states */
        /* that DESCRIBE should work on public tables without authentication, but it is not true... */
        CPLString osSQL("SELECT * FROM ");
        osSQL += osTableId;
        osSQL += " OFFSET 0 LIMIT 1";

        CPLHTTPResult * psResult = poDS->RunSQL(osSQL);

        if (psResult == NULL)
            return FALSE;

        char* pszLine = (char*) psResult->pabyData;
        if (pszLine == NULL || psResult->pszErrBuf != NULL)
        {
            CPLHTTPDestroyResult(psResult);
            return FALSE;
        }

        ParseCSVResponse(pszLine, aosHeaderAndFirstDataLine);
        if (aosHeaderAndFirstDataLine.size() > 0)
        {
            char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[0], ',');
            for(int i=0;papszTokens && papszTokens[i];i++)
            {
                CPLString osLaunderedColName(LaunderColName(papszTokens[i]));
                OGRFieldDefn oFieldDefn(osLaunderedColName, OFTString);
                poFeatureDefn->AddFieldDefn(&oFieldDefn);
            }
            CSLDestroy(papszTokens);
        }

        CPLHTTPDestroyResult(psResult);
    }

    if (osGeomColumnName.size() > 0)
    {
        iGeometryField = poFeatureDefn->GetFieldIndex(osGeomColumnName);
        if (iGeometryField < 0)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Cannot find column called %s", osGeomColumnName.c_str());
        }
    }

    for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
    {
        const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef();
        if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") ||
            EQUAL(pszName, "latdec"))
            iLatitudeField = i;
        else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") ||
                 EQUAL(pszName, "londec") || EQUAL(pszName, "long"))
            iLongitudeField = i;
    }

    if (iLatitudeField >= 0 && iLongitudeField >= 0)
    {
        if (iGeometryField < 0)
            iGeometryField = iLatitudeField;
        poFeatureDefn->GetFieldDefn(iLatitudeField)->SetType(OFTReal);
        poFeatureDefn->GetFieldDefn(iLongitudeField)->SetType(OFTReal);
        poFeatureDefn->SetGeomType( wkbPoint );
    }
    else if (iGeometryField < 0 && osGeomColumnName.size() == 0)
    {
        iLatitudeField = iLongitudeField = -1;

        /* In the unauthenticated case, we try to parse the first record to */
        /* auto-detect the geometry field. */
        OGRwkbGeometryType eType = wkbUnknown;
        if (aosHeaderAndFirstDataLine.size() == 2)
        {
            char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[1], ',');
            if (CSLCount(papszTokens) == poFeatureDefn->GetFieldCount())
            {
                for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
                {
                    const char* pszVal = papszTokens[i];
                    if (pszVal != NULL &&
                        (STARTS_WITH(pszVal, "<Point>") ||
                         STARTS_WITH(pszVal, "<LineString>") ||
                         STARTS_WITH(pszVal, "<Polygon>") ||
                         STARTS_WITH(pszVal, "<MultiGeometry>")))
                    {
                        if (iGeometryField < 0)
                        {
                            iGeometryField = i;
                        }
                        else
                        {
                            CPLDebug("GFT", "Multiple geometry fields detected. "
                                     "Only first encountered one is handled");
                        }
                    }
                    else if (pszVal)
                    {
                        /* http://www.google.com/fusiontables/DataSource?dsrcid=423292 */
                        char** papszTokens2 = CSLTokenizeString2(pszVal, " ,", 0);
                        if (CSLCount(papszTokens2) == 2 &&
                            CPLGetValueType(papszTokens2[0]) == CPL_VALUE_REAL &&
                            CPLGetValueType(papszTokens2[1]) == CPL_VALUE_REAL &&
                            fabs(CPLAtof(papszTokens2[0])) <= 90 &&
                            fabs(CPLAtof(papszTokens2[1])) <= 180 )
                        {
                            if (iGeometryField < 0)
                            {
                                iGeometryField = i;
                                eType = wkbPoint;
                            }
                            else
                            {
                                CPLDebug("GFT", "Multiple geometry fields detected. "
                                         "Only first encountered one is handled");
                            }
                        }
                        CSLDestroy(papszTokens2);
                    }
                }
            }
            CSLDestroy(papszTokens);
        }

        if (iGeometryField < 0)
            poFeatureDefn->SetGeomType( wkbNone );
        else
            poFeatureDefn->SetGeomType( eType );
    }

    SetGeomFieldName();

    return TRUE;
}
Beispiel #13
0
OGRErr OGRGFTTableLayer::DeleteFeature( GIntBig nFID )
{
    GetLayerDefn();

    if (!poDS->IsReadWrite())
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Operation not available in read-only mode");
        return OGRERR_FAILURE;
    }

    if (osTableId.size() == 0)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                "Cannot delete feature in non-created table");
        return OGRERR_FAILURE;
    }

    if (poDS->GetAccessToken().size() == 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Operation not available in unauthenticated mode");
        return OGRERR_FAILURE;
    }

    CPLString      osCommand;

    osCommand += "DELETE FROM ";
    osCommand += osTableId;
    osCommand += " WHERE ROWID = '";
    osCommand += CPLSPrintf(CPL_FRMT_GIB, nFID);
    osCommand += "'";

    //CPLDebug("GFT", "%s",  osCommand.c_str());

    CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
    if (psResult == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Feature deletion failed (1)");
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      We expect a response like "affected_rows\n1".                   */
/* -------------------------------------------------------------------- */
    char* pszLine = (char*) psResult->pabyData;
    if (pszLine == NULL ||
        !STARTS_WITH(pszLine, "affected_rows\n1\n") ||
        psResult->pszErrBuf != NULL)
    {
        CPLDebug( "GFT", "%s/%s",
                  pszLine ? pszLine : "null",
                  psResult->pszErrBuf ? psResult->pszErrBuf : "null");
        CPLError(CE_Failure, CPLE_AppDefined, "Feature deletion failed (2)");
        CPLHTTPDestroyResult(psResult);
        return OGRERR_FAILURE;
    }

    CPLHTTPDestroyResult(psResult);

    return OGRERR_NONE;
}
Beispiel #14
0
CPLErr CPLHTTPFetchMulti(CPLHTTPRequest *pasRequest, int nRequestCount, const char *const *papszOptions) {
    CPLErr ret = CE_None;
    CURLM *curl_multi = NULL;
    int still_running;
    int max_conn;
    int i, conn_i;

    if( nRequestCount > 0 &&
        STARTS_WITH(pasRequest[0].pszURL, "/vsimem/") &&
        /* Disabled by default for potential security issues */
        CPLTestBool(CPLGetConfigOption("CPL_CURL_ENABLE_VSIMEM", "FALSE")) )
    {
        for(i = 0; i< nRequestCount;i++)
        {
            CPLHTTPResult* psResult = CPLHTTPFetch(pasRequest[i].pszURL, (char**)papszOptions);
            pasRequest[i].pabyData = psResult->pabyData;
            pasRequest[i].nDataLen = psResult->nDataLen;
            pasRequest[i].pszError = psResult->pszErrBuf;
            // Conventions a bit different between this module and cpl_http...
            if( psResult->pszErrBuf != NULL &&
                strcmp(psResult->pszErrBuf, "HTTP error code : 404") == 0 )
                pasRequest[i].nStatus = 404;
            else
                pasRequest[i].nStatus = 200;
            pasRequest[i].pszContentType = psResult->pszContentType;
            psResult->pabyData = NULL;
            psResult->nDataLen = 0;
            psResult->pszErrBuf = NULL;
            psResult->pszContentType = NULL;
            CPLHTTPDestroyResult(psResult);
        }
        return CE_None;
    }

    const char *max_conn_opt = CSLFetchNameValue(const_cast<char **>(papszOptions), "MAXCONN");
    if (max_conn_opt && (max_conn_opt[0] != '\0')) {
        max_conn = MAX(1, MIN(atoi(max_conn_opt), 1000));
    } else {
        max_conn = 5;
    }

    curl_multi = curl_multi_init();
    if (curl_multi == NULL) {
        CPLError(CE_Fatal, CPLE_AppDefined, "CPLHTTPFetchMulti(): Unable to create CURL multi-handle.");
    }

    // add at most max_conn requests
    for (conn_i = 0; conn_i < MIN(nRequestCount, max_conn); ++conn_i) {
        CPLHTTPRequest *const psRequest = &pasRequest[conn_i];
        CPLDebug("HTTP", "Requesting [%d/%d] %s", conn_i + 1, nRequestCount, pasRequest[conn_i].pszURL);
        curl_multi_add_handle(curl_multi, psRequest->m_curl_handle);
    }

    while (curl_multi_perform(curl_multi, &still_running) == CURLM_CALL_MULTI_PERFORM);
    while (still_running || (conn_i != nRequestCount)) {
        struct timeval timeout;
        fd_set fdread, fdwrite, fdexcep;
        int maxfd;
        CURLMsg *msg;
        int msgs_in_queue;

        do {
            msg = curl_multi_info_read(curl_multi, &msgs_in_queue);
            if (msg != NULL) {
                if (msg->msg == CURLMSG_DONE) { // transfer completed, check if we have more waiting and add them
                    if (conn_i < nRequestCount) {
                        CPLHTTPRequest *const psRequest = &pasRequest[conn_i];
                        CPLDebug("HTTP", "Requesting [%d/%d] %s", conn_i + 1, nRequestCount, pasRequest[conn_i].pszURL);
                        curl_multi_add_handle(curl_multi, psRequest->m_curl_handle);
                        ++conn_i;
                    }
                }
            }
        } while (msg != NULL);
        FD_ZERO(&fdread);
        FD_ZERO(&fdwrite);
        FD_ZERO(&fdexcep);
        curl_multi_fdset(curl_multi, &fdread, &fdwrite, &fdexcep, &maxfd);
        if( maxfd >= 0 )
        {
            timeout.tv_sec = 0;
            timeout.tv_usec = 100000;
            if( select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) < 0 )
            {
                CPLError(CE_Failure, CPLE_AppDefined, "select() failed");
                break;
            }
        }
        while (curl_multi_perform(curl_multi, &still_running) == CURLM_CALL_MULTI_PERFORM);
    }

    if (conn_i != nRequestCount) { // something gone really really wrong
        CPLError(CE_Fatal, CPLE_AppDefined, "CPLHTTPFetchMulti(): conn_i != nRequestCount, this should never happen ...");
    }
    for (i = 0; i < nRequestCount; ++i) {
        CPLHTTPRequest *const psRequest = &pasRequest[i];

        long response_code = 0;
        curl_easy_getinfo(psRequest->m_curl_handle, CURLINFO_RESPONSE_CODE, &response_code);
        psRequest->nStatus = static_cast<int>(response_code);

        char *content_type = NULL;
        curl_easy_getinfo(psRequest->m_curl_handle, CURLINFO_CONTENT_TYPE, &content_type);
        if (content_type) psRequest->pszContentType = CPLStrdup(content_type);

        if ((psRequest->pszError == NULL) && (psRequest->m_curl_error != NULL) && (psRequest->m_curl_error[0] != '\0')) {
            psRequest->pszError = CPLStrdup(psRequest->m_curl_error);
        }

        /* In the case of a file:// URL, curl will return a status == 0, so if there's no */
        /* error returned, patch the status code to be 200, as it would be for http:// */
        if (STARTS_WITH(psRequest->pszURL, "file://") && psRequest->nStatus == 0 &&
            psRequest->pszError == NULL)
        {
            psRequest->nStatus = 200;
        }

        CPLDebug("HTTP", "Request [%d] %s : status = %d, content type = %s, error = %s",
                 i, psRequest->pszURL, psRequest->nStatus,
                 (psRequest->pszContentType) ? psRequest->pszContentType : "(null)",
                 (psRequest->pszError) ? psRequest->pszError : "(null)");

        curl_multi_remove_handle(curl_multi, pasRequest[i].m_curl_handle);
    }
    curl_multi_cleanup(curl_multi);

    return ret;
}
Beispiel #15
0
bool VSIOSSHandleHelper::CanRestartOnError( const char* pszErrorMsg,
                                            const char*,
                                            bool bSetError,
                                            bool* pbUpdateMap )
{
#ifdef DEBUG_VERBOSE
    CPLDebug("OSS", "%s", pszErrorMsg);
#endif

    if( pbUpdateMap != nullptr )
        *pbUpdateMap = true;

    if( !STARTS_WITH(pszErrorMsg, "<?xml") )
    {
        if( bSetError )
        {
            VSIError(VSIE_AWSError, "Invalid AWS response: %s", pszErrorMsg);
        }
        return false;
    }

    CPLXMLNode* psTree = CPLParseXMLString(pszErrorMsg);
    if( psTree == nullptr )
    {
        if( bSetError )
        {
            VSIError(VSIE_AWSError,
                     "Malformed AWS XML response: %s", pszErrorMsg);
        }
        return false;
    }

    const char* pszCode = CPLGetXMLValue(psTree, "=Error.Code", nullptr);
    if( pszCode == nullptr )
    {
        CPLDestroyXMLNode(psTree);
        if( bSetError )
        {
            VSIError(VSIE_AWSError,
                     "Malformed AWS XML response: %s", pszErrorMsg);
        }
        return false;
    }

    if( EQUAL(pszCode, "AccessDenied") )
    {
        const char* pszEndpoint =
            CPLGetXMLValue(psTree, "=Error.Endpoint", nullptr);
        if( pszEndpoint && pszEndpoint != m_osEndpoint )
        {
            SetEndpoint(pszEndpoint);
            CPLDebug("OSS", "Switching to endpoint %s", m_osEndpoint.c_str());
            CPLDestroyXMLNode(psTree);
            return true;
        }
    }

    if( bSetError )
    {
        // Translate AWS errors into VSI errors.
        const char* pszMessage = CPLGetXMLValue(psTree, "=Error.Message", nullptr);

        if( pszMessage == nullptr ) {
            VSIError(VSIE_AWSError, "%s", pszErrorMsg);
        } else if( EQUAL(pszCode, "AccessDenied") ) {
            VSIError(VSIE_AWSAccessDenied, "%s", pszMessage);
        } else if( EQUAL(pszCode, "NoSuchBucket") ) {
            VSIError(VSIE_AWSBucketNotFound, "%s", pszMessage);
        } else if( EQUAL(pszCode, "NoSuchKey") ) {
            VSIError(VSIE_AWSObjectNotFound, "%s", pszMessage);
        } else if( EQUAL(pszCode, "SignatureDoesNotMatch") ) {
            VSIError(VSIE_AWSSignatureDoesNotMatch, "%s", pszMessage);
        } else {
            VSIError(VSIE_AWSError, "%s", pszMessage);
        }
    }

    CPLDestroyXMLNode(psTree);

    return false;
}
Beispiel #16
0
static
GMLFeatureClass* GMLParseFeatureType(CPLXMLNode *psSchemaNode,
                                     const char* pszName,
                                     CPLXMLNode *psComplexType)
{

/* -------------------------------------------------------------------- */
/*      Grab the sequence of extensions greatgrandchild.                */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psAttrSeq =
        CPLGetXMLNode( psComplexType,
                        "complexContent.extension.sequence" );

    if( psAttrSeq == NULL )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      We are pretty sure this going to be a valid Feature class       */
/*      now, so create it.                                              */
/* -------------------------------------------------------------------- */
    GMLFeatureClass *poClass = new GMLFeatureClass( pszName );

/* -------------------------------------------------------------------- */
/*      Loop over each of the attribute elements being defined for      */
/*      this feature class.                                             */
/* -------------------------------------------------------------------- */
    int nAttributeIndex = 0;

    bool bGotUnrecognizedType = false;

    CPLXMLNode *psAttrDef = psAttrSeq->psChild;
    for( ; psAttrDef != NULL; psAttrDef = psAttrDef->psNext )
    {
        if( strcmp(psAttrDef->pszValue,"group") == 0 )
        {
            /* Too complex schema for us. Aborts parsing */
            delete poClass;
            return NULL;
        }

        /* Parse stuff like :
        <xs:choice>
            <xs:element ref="gml:polygonProperty"/>
            <xs:element ref="gml:multiPolygonProperty"/>
        </xs:choice>
        as found in https://downloadagiv.blob.core.windows.net/overstromingsgebieden-en-oeverzones/2014_01/Overstromingsgebieden_en_oeverzones_2014_01_GML.zip
        */
        if( strcmp(psAttrDef->pszValue,"choice") == 0 )
        {
            CPLXMLNode* psChild = psAttrDef->psChild;
            bool bPolygon = false;
            bool bMultiPolygon = false;
            for( ; psChild; psChild = psChild->psNext )
            {
                if( psChild->eType != CXT_Element )
                    continue;
                if( strcmp(psChild->pszValue,"element") == 0 )
                {
                    const char* pszRef = CPLGetXMLValue( psChild, "ref", NULL );
                    if( pszRef != NULL )
                    {
                        if( strcmp(pszRef, "gml:polygonProperty") == 0 )
                            bPolygon = true;
                        else if( strcmp(pszRef, "gml:multiPolygonProperty") == 0 )
                            bMultiPolygon = true;
                        else
                        {
                            delete poClass;
                            return NULL;
                        }
                    }
                    else
                    {
                        delete poClass;
                        return NULL;
                    }
                }
            }
            if( bPolygon && bMultiPolygon )
            {
                poClass->AddGeometryProperty( new GMLGeometryPropertyDefn(
                    "", "", wkbMultiPolygon, nAttributeIndex, true ) );

                nAttributeIndex ++;
            }
            continue;
        }

        if( !EQUAL(psAttrDef->pszValue,"element") )
            continue;

        /* MapServer WFS writes element type as an attribute of element */
        /* not as a simpleType definition */
        const char* pszType = CPLGetXMLValue( psAttrDef, "type", NULL );
        const char* pszElementName = CPLGetXMLValue( psAttrDef, "name", NULL );
        bool bNullable = EQUAL(CPLGetXMLValue( psAttrDef, "minOccurs", "1" ), "0");
        const char* pszMaxOccurs = CPLGetXMLValue( psAttrDef, "maxOccurs", NULL );
        if (pszType != NULL)
        {
            const char* pszStrippedNSType = StripNS(pszType);
            int nWidth = 0, nPrecision = 0;

            GMLPropertyType gmlType = GMLPT_Untyped;
            if (EQUAL(pszStrippedNSType, "string") ||
                EQUAL(pszStrippedNSType, "Character"))
                gmlType = GMLPT_String;
            /* TODO: Would be nice to have a proper date type */
            else if (EQUAL(pszStrippedNSType, "date") ||
                     EQUAL(pszStrippedNSType, "dateTime"))
                gmlType = GMLPT_String;
            else if (EQUAL(pszStrippedNSType, "real") ||
                     EQUAL(pszStrippedNSType, "double") ||
                     EQUAL(pszStrippedNSType, "decimal"))
                gmlType = GMLPT_Real;
            else if (EQUAL(pszStrippedNSType, "float") )
                gmlType = GMLPT_Float;
            else if (EQUAL(pszStrippedNSType, "int") ||
                     EQUAL(pszStrippedNSType, "integer"))
                gmlType = GMLPT_Integer;
            else if (EQUAL(pszStrippedNSType, "long"))
                gmlType = GMLPT_Integer64;
            else if (EQUAL(pszStrippedNSType, "short") )
                gmlType = GMLPT_Short;
            else if (EQUAL(pszStrippedNSType, "boolean") )
                gmlType = GMLPT_Boolean;
            else if (strcmp(pszType, "gml:FeaturePropertyType") == 0 )
            {
                gmlType = GMLPT_FeatureProperty;
            }
            else if (STARTS_WITH(pszType, "gml:"))
            {
                const AssocNameType* psIter = apsPropertyTypes;
                while(psIter->pszName)
                {
                    if (strncmp(pszType + 4, psIter->pszName, strlen(psIter->pszName)) == 0)
                    {
                        OGRwkbGeometryType eType = psIter->eType;

                        /* Look if there's a comment restricting to subclasses */
                        if( psAttrDef->psNext != NULL && psAttrDef->psNext->eType == CXT_Comment )
                        {
                            if( strstr(psAttrDef->psNext->pszValue, "restricted to Polygon") )
                                eType = wkbPolygon;
                            else if( strstr(psAttrDef->psNext->pszValue, "restricted to LineString") )
                                eType = wkbLineString;
                            else if( strstr(psAttrDef->psNext->pszValue, "restricted to MultiPolygon") )
                                eType = wkbMultiPolygon;
                            else if( strstr(psAttrDef->psNext->pszValue, "restricted to MultiLineString") )
                                eType = wkbMultiLineString;
                        }

                        poClass->AddGeometryProperty( new GMLGeometryPropertyDefn(
                            pszElementName, pszElementName, eType, nAttributeIndex, bNullable ) );

                        nAttributeIndex ++;

                        break;
                    }

                    psIter ++;
                }

                if (psIter->pszName == NULL)
                {
                    /* Can be a non geometry gml type */
                    /* Too complex schema for us. Aborts parsing */
                    delete poClass;
                    return NULL;
                }

                if (poClass->GetGeometryPropertyCount() == 0)
                    bGotUnrecognizedType = true;

                continue;
            }

            /* Integraph stuff */
            else if (strcmp(pszType, "G:Point_MultiPointPropertyType") == 0 ||
                     strcmp(pszType, "gmgml:Point_MultiPointPropertyType") == 0)
            {
                poClass->AddGeometryProperty( new GMLGeometryPropertyDefn(
                    pszElementName, pszElementName, wkbMultiPoint, nAttributeIndex,
                    bNullable ) );

                nAttributeIndex ++;
                continue;
            }
            else if (strcmp(pszType, "G:LineString_MultiLineStringPropertyType") == 0 ||
                     strcmp(pszType, "gmgml:LineString_MultiLineStringPropertyType") == 0)
            {
                poClass->AddGeometryProperty( new GMLGeometryPropertyDefn(
                    pszElementName, pszElementName, wkbMultiLineString, nAttributeIndex,
                    bNullable ) );

                nAttributeIndex ++;
                continue;
            }
            else if (strcmp(pszType, "G:Polygon_MultiPolygonPropertyType") == 0 ||
                     strcmp(pszType, "gmgml:Polygon_MultiPolygonPropertyType") == 0 ||
                     strcmp(pszType, "gmgml:Polygon_Surface_MultiSurface_CompositeSurfacePropertyType") == 0)
            {
                poClass->AddGeometryProperty( new GMLGeometryPropertyDefn(
                    pszElementName, pszElementName, wkbMultiPolygon, nAttributeIndex,
                    bNullable ) );

                nAttributeIndex ++;
                continue;
            }

            /* ERDAS Apollo stuff (like in http://apollo.erdas.com/erdas-apollo/vector/WORLDWIDE?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=wfs:cntry98) */
            else if (strcmp(pszType, "wfs:MixedPolygonPropertyType") == 0)
            {
                poClass->AddGeometryProperty( new GMLGeometryPropertyDefn(
                    pszElementName, pszElementName, wkbMultiPolygon, nAttributeIndex,
                    bNullable) );

                nAttributeIndex ++;
                continue;
            }

            else
            {
                gmlType = GMLPT_Untyped;
                if ( ! LookForSimpleType(psSchemaNode, pszStrippedNSType,
                                         &gmlType, &nWidth, &nPrecision) )
                {
                    /* Too complex schema for us. Aborts parsing */
                    delete poClass;
                    return NULL;
                }
            }

            if (pszElementName == NULL)
                pszElementName = "unnamed";
            const char* pszPropertyName = pszElementName;
            if( gmlType == GMLPT_FeatureProperty )
            {
                pszPropertyName = CPLSPrintf("%s_href", pszElementName);
            }
            GMLPropertyDefn *poProp = new GMLPropertyDefn(
                pszPropertyName, pszElementName );

            if( pszMaxOccurs != NULL && strcmp(pszMaxOccurs, "1") != 0 )
                gmlType = GetListTypeFromSingleType(gmlType);

            poProp->SetType( gmlType );
            poProp->SetWidth( nWidth );
            poProp->SetPrecision( nPrecision );
            poProp->SetNullable( bNullable );

            if (poClass->AddProperty( poProp ) < 0)
                delete poProp;
            else
                nAttributeIndex ++;

            continue;
        }

        // For now we skip geometries .. fixup later.
        CPLXMLNode* psSimpleType = CPLGetXMLNode( psAttrDef, "simpleType" );
        if( psSimpleType == NULL )
        {
            const char* pszRef = CPLGetXMLValue( psAttrDef, "ref", NULL );

            /* FME .xsd */
            if (pszRef != NULL && STARTS_WITH(pszRef, "gml:"))
            {
                const AssocNameType* psIter = apsRefTypes;
                while(psIter->pszName)
                {
                    if (strncmp(pszRef + 4, psIter->pszName, strlen(psIter->pszName)) == 0)
                    {
                        if (poClass->GetGeometryPropertyCount() > 0)
                        {
                            OGRwkbGeometryType eNewType = psIter->eType;
                            OGRwkbGeometryType eOldType = (OGRwkbGeometryType)poClass->GetGeometryProperty(0)->GetType();
                            if ((eNewType == wkbMultiPoint && eOldType == wkbPoint) ||
                                (eNewType == wkbMultiLineString && eOldType == wkbLineString) ||
                                (eNewType == wkbMultiPolygon && eOldType == wkbPolygon))
                            {
                                poClass->GetGeometryProperty(0)->SetType(eNewType);
                            }
                            else
                            {
                                CPLDebug("GML", "Geometry field already found ! Ignoring the following ones");
                            }
                        }
                        else
                        {
                            poClass->AddGeometryProperty( new GMLGeometryPropertyDefn(
                                pszElementName, pszElementName, psIter->eType, nAttributeIndex, true ) );

                            nAttributeIndex ++;
                        }

                        break;
                    }

                    psIter ++;
                }

                if (psIter->pszName == NULL)
                {
                    /* Can be a non geometry gml type */
                    /* Too complex schema for us. Aborts parsing */
                    delete poClass;
                    return NULL;
                }

                if (poClass->GetGeometryPropertyCount() == 0)
                    bGotUnrecognizedType = true;

                continue;
            }

            /* Parse stuff like the following found in http://199.29.1.81:8181/miwfs/GetFeature.ashx?REQUEST=GetFeature&MAXFEATURES=1&SERVICE=WFS&VERSION=1.0.0&TYPENAME=miwfs:World :
            <xs:element name="Obj" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element ref="gml:_Geometry"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            */
            CPLXMLNode* l_psComplexType = GetSingleChildElement( psAttrDef, "complexType" );
            CPLXMLNode* psComplexTypeSequence = GetSingleChildElement( l_psComplexType, "sequence" );
            CPLXMLNode* psComplexTypeSequenceElement = GetSingleChildElement( psComplexTypeSequence, "element" );

            if( pszElementName != NULL &&
                CheckMinMaxOccursCardinality(psAttrDef) &&
                psComplexTypeSequenceElement != NULL &&
                CheckMinMaxOccursCardinality(psComplexTypeSequence) &&
                strcmp(CPLGetXMLValue( psComplexTypeSequenceElement, "ref", "" ), "gml:_Geometry") == 0 )
            {
                poClass->AddGeometryProperty( new GMLGeometryPropertyDefn(
                    pszElementName, pszElementName, wkbUnknown, nAttributeIndex, bNullable ) );

                nAttributeIndex ++;

                continue;
            }
            else
            {
                /* Too complex schema for us. Aborts parsing */
                delete poClass;
                return NULL;
            }
        }

        if (pszElementName == NULL)
            pszElementName = "unnamed";
        GMLPropertyDefn *poProp = new GMLPropertyDefn(
            pszElementName, pszElementName );

        GMLPropertyType eType = GMLPT_Untyped;
        int nWidth = 0, nPrecision = 0;
        GetSimpleTypeProperties(psSimpleType, &eType, &nWidth, &nPrecision);

        if( pszMaxOccurs != NULL && strcmp(pszMaxOccurs, "1") != 0 )
            eType = GetListTypeFromSingleType(eType);

        poProp->SetType( eType );
        poProp->SetWidth( nWidth );
        poProp->SetPrecision( nPrecision );
        poProp->SetNullable( bNullable );

        if (poClass->AddProperty( poProp ) < 0)
            delete poProp;
        else
            nAttributeIndex ++;
    }

    /* If we have found an unknown types, let's be on the side of caution and */
    /* create a geometry field */
    if( poClass->GetGeometryPropertyCount() == 0 &&
        bGotUnrecognizedType )
    {
        poClass->AddGeometryProperty( new GMLGeometryPropertyDefn( "", "", wkbUnknown, -1, true ) );
    }

/* -------------------------------------------------------------------- */
/*      Class complete, add to reader class list.                       */
/* -------------------------------------------------------------------- */
    poClass->SetSchemaLocked( true );

    return poClass;
}
Beispiel #17
0
GDALDataset *ACE2Dataset::Open( GDALOpenInfo * poOpenInfo )

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

    const char* pszBasename = CPLGetBasename(poOpenInfo->pszFilename);

    if (strlen(pszBasename) < 7)
        return NULL;

    /* Determine southwest coordinates from filename */

    /* e.g. 30S120W_5M.ACE2 */
    char pszLatLonValueString[4] = { '\0' };
    memset(pszLatLonValueString, 0, 4);
    // cppcheck-suppress redundantCopy
    strncpy(pszLatLonValueString, &pszBasename[0], 2);
    int southWestLat = atoi(pszLatLonValueString);
    memset(pszLatLonValueString, 0, 4);
    // cppcheck-suppress redundantCopy
    strncpy(pszLatLonValueString, &pszBasename[3], 3);
    int southWestLon = atoi(pszLatLonValueString);

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

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

    GDALDataType eDT = GDT_Unknown;
    if (strstr(pszBasename, "_CONF_") ||
        strstr(pszBasename, "_QUALITY_") ||
        strstr(pszBasename, "_SOURCE_"))
        eDT = GDT_Int16;
    else
        eDT = GDT_Float32;
    int nWordSize = GDALGetDataTypeSize(eDT) / 8;

    VSIStatBufL sStat;
    if (strstr(pszBasename, "_5M"))
        sStat.st_size = 180 * 180 * nWordSize;
    else if (strstr(pszBasename, "_30S"))
        sStat.st_size = 1800 * 1800 * nWordSize;
    else if (strstr(pszBasename, "_9S"))
        sStat.st_size = 6000 * 6000 * nWordSize;
    else if (strstr(pszBasename, "_3S"))
        sStat.st_size = 18000 * 18000 * nWordSize;
    /* Check file size otherwise */
    else if(VSIStatL(poOpenInfo->pszFilename, &sStat) != 0)
    {
        return NULL;
    }

    int nXSize = 0;
    int nYSize = 0;

    double dfPixelSize = 0;
    if (sStat.st_size == 180 * 180 * nWordSize)
    {
        /* 5 minute */
        nXSize = 180;
        nYSize = 180;
        dfPixelSize = 5.0 / 60;
    }
    else if (sStat.st_size == 1800 * 1800 * nWordSize)
    {
        /* 30 s */
        nXSize = 1800;
        nYSize = 1800;
        dfPixelSize = 30.0 / 3600;
    }
    else if (sStat.st_size == 6000 * 6000 * nWordSize)
    {
        /* 9 s */
        nXSize = 6000;
        nYSize = 6000;
        dfPixelSize = 9.0 / 3600;
    }
    else if (sStat.st_size == 18000 * 18000 * nWordSize)
    {
        /* 3 s */
        nXSize = 18000;
        nYSize = 18000;
        dfPixelSize = 3.0 / 3600;
    }
    else
        return NULL;

/* -------------------------------------------------------------------- */
/*      Open file.                                                      */
/* -------------------------------------------------------------------- */

    CPLString osFilename = poOpenInfo->pszFilename;
    if ((strstr(poOpenInfo->pszFilename, ".ACE2.gz") ||
         strstr(poOpenInfo->pszFilename, ".ace2.gz")) &&
        !STARTS_WITH(poOpenInfo->pszFilename, "/vsigzip/"))
        osFilename = "/vsigzip/" + osFilename;

    VSILFILE* fpImage = VSIFOpenL( osFilename, "rb+" );
    if (fpImage == NULL)
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
    ACE2Dataset  *poDS = new ACE2Dataset();

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

    poDS->adfGeoTransform[0] = southWestLon;
    poDS->adfGeoTransform[1] = dfPixelSize;
    poDS->adfGeoTransform[2] = 0.0;
    poDS->adfGeoTransform[3] = southWestLat + nYSize * dfPixelSize;
    poDS->adfGeoTransform[4] = 0.0;
    poDS->adfGeoTransform[5] = -dfPixelSize;

/* -------------------------------------------------------------------- */
/*      Create band information objects                                 */
/* -------------------------------------------------------------------- */
    poDS->SetBand( 1, new ACE2RasterBand(fpImage, eDT, nXSize, nYSize ) );

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

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

    return poDS;
}
Beispiel #18
0
static
void CPLXMLSchemaResolveInclude( const char* pszMainSchemaLocation,
                                 CPLXMLNode *psSchemaNode )
{
    std::set<CPLString> osAlreadyIncluded;

    bool bTryAgain;
    do
    {
        CPLXMLNode *psLast = NULL;
        bTryAgain = false;

        CPLXMLNode *psThis = psSchemaNode->psChild;
        for( ; psThis != NULL; psThis = psThis->psNext )
        {
            if( psThis->eType == CXT_Element &&
                EQUAL(psThis->pszValue,"include") )
            {
                const char* pszSchemaLocation =
                        CPLGetXMLValue(psThis, "schemaLocation", NULL);
                if( pszSchemaLocation != NULL &&
                    osAlreadyIncluded.count( pszSchemaLocation) == 0 )
                {
                    osAlreadyIncluded.insert( pszSchemaLocation );

                    if( !STARTS_WITH(pszSchemaLocation, "http://") &&
                        !STARTS_WITH(pszSchemaLocation, "https://") &&
                        CPLIsFilenameRelative(pszSchemaLocation ) )
                    {
                        pszSchemaLocation = CPLFormFilename(
                            CPLGetPath(pszMainSchemaLocation), pszSchemaLocation, NULL );
                    }

                    CPLXMLNode *psIncludedXSDTree =
                                GMLParseXMLFile( pszSchemaLocation );
                    if( psIncludedXSDTree != NULL )
                    {
                        CPLStripXMLNamespace( psIncludedXSDTree, NULL, TRUE );
                        CPLXMLNode *psIncludedSchemaNode =
                                CPLGetXMLNode( psIncludedXSDTree, "=schema" );
                        if( psIncludedSchemaNode != NULL )
                        {
                            /* Substitute de <include> node by its content */
                            CPLXMLNode* psFirstChildElement =
                                CPLGetFirstChildNode(psIncludedSchemaNode);
                            if( psFirstChildElement != NULL )
                            {
                                CPLXMLNode* psCopy = CPLCloneXMLTree(psFirstChildElement);
                                if( psLast != NULL )
                                    psLast->psNext = psCopy;
                                else
                                    psSchemaNode->psChild = psCopy;
                                CPLXMLNode* psNext = psThis->psNext;
                                psThis->psNext = NULL;
                                CPLDestroyXMLNode(psThis);
                                psThis = CPLGetLastNode(psCopy);
                                psThis->psNext = psNext;

                                /* In case the included schema also contains */
                                /* includes */
                                bTryAgain = true;
                            }

                        }
                        CPLDestroyXMLNode( psIncludedXSDTree );
                    }
                }
            }

            psLast = psThis;
        }
    } while( bTryAgain );

    const char* pszSchemaOutputName =
        CPLGetConfigOption("GML_SCHEMA_OUTPUT_NAME", NULL);
    if( pszSchemaOutputName != NULL )
    {
        CPLSerializeXMLTreeToFile( psSchemaNode, pszSchemaOutputName );
    }
}
Beispiel #19
0
void GTMWaypointLayer::WriteFeatureAttributes( OGRFeature *poFeature, float altitude )
{
    char psNameField[] = "          "; // 10 spaces
    char* pszcomment = nullptr;
    int icon = 48;
    int date = 0;
    for (int i = 0; i < poFeatureDefn->GetFieldCount(); ++i)
    {
        OGRFieldDefn *poFieldDefn = poFeatureDefn->GetFieldDefn( i );
        if( poFeature->IsFieldSetAndNotNull( i ) )
        {
            const char* l_pszName = poFieldDefn->GetNameRef();
            /* Waypoint name */
            if (STARTS_WITH(l_pszName, "name"))
            {
                strncpy (psNameField, poFeature->GetFieldAsString( i ), 10);
                CPLStrlcat (psNameField, "          ", sizeof(psNameField));
            }
            /* Waypoint comment */
            else if (STARTS_WITH(l_pszName, "comment"))
            {
                CPLFree(pszcomment);
                pszcomment = CPLStrdup( poFeature->GetFieldAsString( i ) );
            }
            /* Waypoint icon */
            else if (STARTS_WITH(l_pszName, "icon"))
            {
                icon = poFeature->GetFieldAsInteger( i );
                // Check if it is a valid icon
                if (icon < 1 || icon > 220)
                    icon = 48;
            }
            /* Waypoint date */
            else if (EQUAL(l_pszName, "time"))
            {
                struct tm brokendowndate;
                int year, month, day, hour, min, sec, TZFlag;
                if (poFeature->GetFieldAsDateTime( i, &year, &month, &day, &hour, &min, &sec, &TZFlag))
                {
                    brokendowndate.tm_year = year - 1900;
                    brokendowndate.tm_mon = month - 1;
                    brokendowndate.tm_mday = day;
                    brokendowndate.tm_hour = hour;
                    brokendowndate.tm_min = min;
                    brokendowndate.tm_sec = sec;
                    GIntBig unixTime = CPLYMDHMSToUnixTime(&brokendowndate);
                    if (TZFlag != 0)
                        unixTime -= (TZFlag - 100) * 15;
                    if (unixTime <= GTM_EPOCH || (unixTime - GTM_EPOCH) != (int)(unixTime - GTM_EPOCH))
                    {
                        CPLError(CE_Warning, CPLE_AppDefined,
                                  "%04d/%02d/%02d %02d:%02d:%02d is not a valid datetime for GTM",
                                  year, month, day, hour, min, sec);
                    }
                    else
                    {
                        date = (int)(unixTime - GTM_EPOCH);
                    }
                }
            }
        }
    }

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

    const size_t commentLength = strlen(pszcomment);

    const size_t bufferSize = 27 + commentLength;
    void* pBuffer = CPLMalloc(bufferSize);
    void* pBufferAux = pBuffer;
    /* Write waypoint name to buffer */
    memcpy((char*)pBufferAux, psNameField, 10);

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

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

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

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

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

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

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

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

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

    CPLFree(pszcomment);
    CPLFree(pBuffer);
}
Beispiel #20
0
bool GMLParseXSD( const char *pszFile,
                 std::vector<GMLFeatureClass*> & aosClasses,
                 bool& bFullyUnderstood)

{
    bFullyUnderstood = false;

    if( pszFile == NULL )
        return false;

/* -------------------------------------------------------------------- */
/*      Load the raw XML file.                                          */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psXSDTree = GMLParseXMLFile( pszFile );

    if( psXSDTree == NULL )
        return false;

/* -------------------------------------------------------------------- */
/*      Strip off any namespace qualifiers.                             */
/* -------------------------------------------------------------------- */
    CPLStripXMLNamespace( psXSDTree, NULL, TRUE );

/* -------------------------------------------------------------------- */
/*      Find <schema> root element.                                     */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psSchemaNode = CPLGetXMLNode( psXSDTree, "=schema" );
    if( psSchemaNode == NULL )
    {
        CPLDestroyXMLNode( psXSDTree );
        return false;
    }

/* ==================================================================== */
/*      Process each include directive.                                 */
/* ==================================================================== */
    CPLXMLSchemaResolveInclude( pszFile, psSchemaNode );

    //CPLSerializeXMLTreeToFile(psSchemaNode, "/vsistdout/");

    bFullyUnderstood = true;

/* ==================================================================== */
/*      Process each feature class definition.                          */
/* ==================================================================== */
    CPLXMLNode *psThis = psSchemaNode->psChild;
    for( ; psThis != NULL; psThis = psThis->psNext )
    {
/* -------------------------------------------------------------------- */
/*      Check for <xs:element> node.                                    */
/* -------------------------------------------------------------------- */
        if( psThis->eType != CXT_Element
            || !EQUAL(psThis->pszValue,"element") )
            continue;

/* -------------------------------------------------------------------- */
/*      Check the substitution group.                                   */
/* -------------------------------------------------------------------- */
        const char *pszSubGroup =
            StripNS(CPLGetXMLValue(psThis,"substitutionGroup",""));

        // Old OGR produced elements for the feature collection.
        if( EQUAL(pszSubGroup, "_FeatureCollection") )
            continue;

        if( !EQUAL(pszSubGroup, "_Feature") &&
            !EQUAL(pszSubGroup, "AbstractFeature") /* AbstractFeature used by GML 3.2 */ )
        {
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Get name                                                        */
/* -------------------------------------------------------------------- */
        const char *pszName = CPLGetXMLValue( psThis, "name", NULL );
        if( pszName == NULL )
        {
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Get type and verify relationship with name.                     */
/* -------------------------------------------------------------------- */
        const char *pszType = CPLGetXMLValue( psThis, "type", NULL );
        if (pszType == NULL)
        {
            CPLXMLNode *psComplexType = CPLGetXMLNode( psThis, "complexType" );
            if (psComplexType)
            {
                GMLFeatureClass* poClass =
                        GMLParseFeatureType(psSchemaNode, pszName, psComplexType);
                if (poClass)
                    aosClasses.push_back(poClass);
                else
                    bFullyUnderstood = false;
            }
            continue;
        }
        if( strstr( pszType, ":" ) != NULL )
            pszType = strstr( pszType, ":" ) + 1;
        if( EQUAL(pszType, pszName) )
        {
            /* A few WFS servers return a type name which is the element name */
            /* without any _Type or Type suffix */
            /* e.g. : http://apollo.erdas.com/erdas-apollo/vector/Cherokee?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=iwfs:Air */
        }

        /* <element name="RekisteriyksikonPalstanTietoja" type="ktjkiiwfs:PalstanTietojaType" substitutionGroup="gml:_Feature" /> */
        else if(  strlen(pszType) > 4 &&
                  strcmp(pszType + strlen(pszType) - 4, "Type") == 0 &&
                  strlen(pszName) > strlen(pszType) - 4 &&
                  strncmp(pszName + strlen(pszName) - (strlen(pszType) - 4),
                          pszType,
                          strlen(pszType) - 4) == 0 )        {
        }

        else if( !EQUALN(pszType,pszName,strlen(pszName))
            || !(EQUAL(pszType+strlen(pszName),"_Type") ||
                    EQUAL(pszType+strlen(pszName),"Type")) )
        {
            continue;
        }

        /* CanVec .xsd contains weird types that are not used in the related GML */
        if (STARTS_WITH(pszName, "XyZz") ||
            STARTS_WITH(pszName, "XyZ1") ||
            STARTS_WITH(pszName, "XyZ2"))
            continue;

        GMLFeatureClass* poClass =
                GMLParseFeatureType(psSchemaNode, pszName, pszType);
        if (poClass)
            aosClasses.push_back(poClass);
        else
            bFullyUnderstood = false;
    }

    CPLDestroyXMLNode( psXSDTree );

    if( aosClasses.size() > 0 )
    {
        return true;
    }
    else
        return false;
}
Beispiel #21
0
void GDALPamProxyDB::LoadDB()

{
/* -------------------------------------------------------------------- */
/*      Open the database relating original names to proxy .aux.xml     */
/*      file names.                                                     */
/* -------------------------------------------------------------------- */
    CPLString osDBName =
        CPLFormFilename( osProxyDBDir, "gdal_pam_proxy", "dat" );
    VSILFILE *fpDB = VSIFOpenL( osDBName, "r" );

    nUpdateCounter = 0;
    if( fpDB == NULL )
        return;

/* -------------------------------------------------------------------- */
/*      Read header, verify and extract update counter.                 */
/* -------------------------------------------------------------------- */
    const size_t nHeaderSize = 100;
    GByte abyHeader[nHeaderSize] = { '\0' };

    if( VSIFReadL( abyHeader, 1, nHeaderSize, fpDB ) != nHeaderSize
        || !STARTS_WITH(reinterpret_cast<char *>(abyHeader), "GDAL_PROXY") )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Problem reading %s header - short or corrupt?",
                  osDBName.c_str() );
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpDB));
        return;
    }

    nUpdateCounter = atoi(reinterpret_cast<char *>(abyHeader) + 10);

/* -------------------------------------------------------------------- */
/*      Read the file in one gulp.                                      */
/* -------------------------------------------------------------------- */
    if( VSIFSeekL( fpDB, 0, SEEK_END ) != 0 )
    {
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpDB));
        return;
    }
    const int nBufLength = static_cast<int>(VSIFTellL(fpDB) - nHeaderSize);
    if( VSIFSeekL( fpDB, nHeaderSize, SEEK_SET ) != 0 )
    {
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpDB));
        return;
    }
    char *pszDBData = static_cast<char *>( CPLCalloc(1,nBufLength+1) );
    if( VSIFReadL( pszDBData, 1, nBufLength, fpDB ) !=
        static_cast<size_t>(nBufLength) )
    {
        CPLFree(pszDBData);
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpDB));
        return;
    }

    CPL_IGNORE_RET_VAL(VSIFCloseL( fpDB ));

/* -------------------------------------------------------------------- */
/*      Parse the list of in/out names.                                 */
/* -------------------------------------------------------------------- */
    int iNext = 0;

    while( iNext < nBufLength )
    {
        CPLString osOriginal;
        osOriginal.assign( pszDBData + iNext );

        for( ; iNext < nBufLength && pszDBData[iNext] != '\0'; iNext++ ) {}

        if( iNext == nBufLength )
            break;

        iNext++;

        CPLString osProxy = osProxyDBDir;
        osProxy += "/";
        osProxy += pszDBData + iNext;

        for( ; iNext < nBufLength && pszDBData[iNext] != '\0'; iNext++ ) {}
        iNext++;

        aosOriginalFiles.push_back( osOriginal );
        aosProxyFiles.push_back( osProxy );
    }

    CPLFree( pszDBData );
}
OGRLayer *
OGRPGDumpDataSource::ICreateLayer( const char * pszLayerName,
                                  OGRSpatialReference *poSRS,
                                  OGRwkbGeometryType eType,
                                  char ** papszOptions )

{
    CPLString            osCommand;
    const char          *pszGeomType = NULL;
    char                *pszTableName = NULL;
    char                *pszSchemaName = NULL;
    int                  bHavePostGIS = TRUE;
    int                 GeometryTypeFlags = 0;

    const char* pszFIDColumnNameIn = CSLFetchNameValue(papszOptions, "FID");
    CPLString osFIDColumnName, osFIDColumnNameEscaped;
    if (pszFIDColumnNameIn == NULL)
        osFIDColumnName = "ogc_fid";
    else
    {
        if( CSLFetchBoolean(papszOptions,"LAUNDER", TRUE) )
        {
            char* pszLaunderedFid = OGRPGCommonLaunderName(pszFIDColumnNameIn, "PGDump");
            osFIDColumnName = pszLaunderedFid;
            CPLFree(pszLaunderedFid);
        }
        else
        {
            osFIDColumnName = pszFIDColumnNameIn;
        }
    }
    osFIDColumnNameEscaped = OGRPGDumpEscapeColumnName(osFIDColumnName);

    if (STARTS_WITH(pszLayerName, "pg"))
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "The layer name should not begin by 'pg' as it is a reserved prefix");
    }
    
    //bHavePostGIS = CSLFetchBoolean(papszOptions,"POSTGIS", TRUE);

    int bCreateTable = CSLFetchBoolean(papszOptions,"CREATE_TABLE", TRUE);
    int bCreateSchema = CSLFetchBoolean(papszOptions,"CREATE_SCHEMA", TRUE);
    const char* pszDropTable = CSLFetchNameValueDef(papszOptions,"DROP_TABLE", "IF_EXISTS");

    if( OGR_GT_HasZ((OGRwkbGeometryType)eType) )
        GeometryTypeFlags |= OGRGeometry::OGR_G_3D;
    if( OGR_GT_HasM((OGRwkbGeometryType)eType) )
        GeometryTypeFlags |= OGRGeometry::OGR_G_MEASURED;

    int ForcedGeometryTypeFlags = -1;
    const char* pszDim = CSLFetchNameValue( papszOptions, "DIM");
    if( pszDim != NULL )
    {
        if( EQUAL(pszDim, "XY") || EQUAL(pszDim, "2") )
        {
            GeometryTypeFlags = 0;
            ForcedGeometryTypeFlags = GeometryTypeFlags;
        }
        else if( EQUAL(pszDim, "XYZ") || EQUAL(pszDim, "3") )
        {
            GeometryTypeFlags = OGRGeometry::OGR_G_3D;
            ForcedGeometryTypeFlags = GeometryTypeFlags;
        }
        else if( EQUAL(pszDim, "XYM") )
        {
            GeometryTypeFlags = OGRGeometry::OGR_G_MEASURED;
            ForcedGeometryTypeFlags = GeometryTypeFlags;
        }
        else if( EQUAL(pszDim, "XYZM") || EQUAL(pszDim, "4") )
        {
            GeometryTypeFlags = OGRGeometry::OGR_G_3D | OGRGeometry::OGR_G_MEASURED;
            ForcedGeometryTypeFlags = GeometryTypeFlags;
        }
        else
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Invalid value for DIM");
        }
    }

    const int nDimension = 2 + ((GeometryTypeFlags & OGRGeometry::OGR_G_3D) ? 1 : 0)
                       + ((GeometryTypeFlags & OGRGeometry::OGR_G_MEASURED) ? 1 : 0);

    /* Should we turn layers with None geometry type as Unknown/GEOMETRY */
    /* so they are still recorded in geometry_columns table ? (#4012) */
    int bNoneAsUnknown = CPLTestBool(CSLFetchNameValueDef(
                                    papszOptions, "NONE_AS_UNKNOWN", "NO"));
    if (bNoneAsUnknown && eType == wkbNone)
        eType = wkbUnknown;
    else if (eType == wkbNone)
        bHavePostGIS = FALSE;

    int bExtractSchemaFromLayerName = CPLTestBool(CSLFetchNameValueDef(
                                    papszOptions, "EXTRACT_SCHEMA_FROM_LAYER_NAME", "YES"));

    /* Postgres Schema handling:
       Extract schema name from input layer name or passed with -lco SCHEMA.
       Set layer name to "schema.table" or to "table" if schema == current_schema()
       Usage without schema name is backwards compatible
    */
    const char* pszDotPos = strstr(pszLayerName,".");
    if ( pszDotPos != NULL && bExtractSchemaFromLayerName )
    {
      int length = static_cast<int>(pszDotPos - pszLayerName);
      pszSchemaName = (char*)CPLMalloc(length+1);
      strncpy(pszSchemaName, pszLayerName, length);
      pszSchemaName[length] = '\0';

      if( CSLFetchBoolean(papszOptions,"LAUNDER", TRUE) )
          pszTableName = OGRPGCommonLaunderName( pszDotPos + 1, "PGDump" ); //skip "."
      else
          pszTableName = CPLStrdup( pszDotPos + 1 ); //skip "."
    }
    else
    {
      pszSchemaName = NULL;
      if( CSLFetchBoolean(papszOptions,"LAUNDER", TRUE) )
          pszTableName = OGRPGCommonLaunderName( pszLayerName, "PGDump" ); //skip "."
      else
          pszTableName = CPLStrdup( pszLayerName ); //skip "."
    }

    LogCommit();

/* -------------------------------------------------------------------- */
/*      Set the default schema for the layers.                          */
/* -------------------------------------------------------------------- */
    if( CSLFetchNameValue( papszOptions, "SCHEMA" ) != NULL )
    {
        CPLFree(pszSchemaName);
        pszSchemaName = CPLStrdup(CSLFetchNameValue( papszOptions, "SCHEMA" ));
        if (bCreateSchema)
        {
            osCommand.Printf("CREATE SCHEMA \"%s\"", pszSchemaName);
            Log(osCommand);
        }
    }

    if ( pszSchemaName == NULL)
    {
        pszSchemaName = CPLStrdup("public");
    }

/* -------------------------------------------------------------------- */
/*      Do we already have this layer?                                  */
/* -------------------------------------------------------------------- */
    int iLayer;

    for( iLayer = 0; iLayer < nLayers; iLayer++ )
    {
        if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Layer %s already exists, CreateLayer failed.\n", 
                      pszLayerName );
            CPLFree( pszTableName );
            CPLFree( pszSchemaName );
            return NULL;
        }
    }


    if (bCreateTable && (EQUAL(pszDropTable, "YES") ||
                         EQUAL(pszDropTable, "ON") ||
                         EQUAL(pszDropTable, "TRUE") ||
                         EQUAL(pszDropTable, "IF_EXISTS")))
    {
        if (EQUAL(pszDropTable, "IF_EXISTS"))
            osCommand.Printf("DROP TABLE IF EXISTS \"%s\".\"%s\" CASCADE", pszSchemaName, pszTableName );
        else
            osCommand.Printf("DROP TABLE \"%s\".\"%s\" CASCADE", pszSchemaName, pszTableName );
        Log(osCommand);
    }
    
/* -------------------------------------------------------------------- */
/*      Handle the GEOM_TYPE option.                                    */
/* -------------------------------------------------------------------- */
    pszGeomType = CSLFetchNameValue( papszOptions, "GEOM_TYPE" );
    if( pszGeomType == NULL )
    {
        pszGeomType = "geometry";
    }

    if( !EQUAL(pszGeomType,"geometry") && !EQUAL(pszGeomType, "geography"))
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                    "GEOM_TYPE in PostGIS enabled databases must be 'geometry' or 'geography'.\n"
                    "Creation of layer %s with GEOM_TYPE %s has failed.",
                    pszLayerName, pszGeomType );
        CPLFree( pszTableName );
        CPLFree( pszSchemaName );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Try to get the SRS Id of this spatial reference system,         */
/*      adding tot the srs table if needed.                             */
/* -------------------------------------------------------------------- */
    int nUnknownSRSId = -1;
    const char* pszPostgisVersion = CSLFetchNameValue( papszOptions, "POSTGIS_VERSION" );
    int nPostGISMajor = 1;
    int nPostGISMinor = 5;
    if( pszPostgisVersion != NULL && atoi(pszPostgisVersion) >= 2 )
    {
        nPostGISMajor = atoi(pszPostgisVersion);
        if( strchr(pszPostgisVersion, '.') )
            nPostGISMinor = atoi(strchr(pszPostgisVersion, '.')+1);
        else
            nPostGISMinor = 0;
        nUnknownSRSId = 0;
    }

    int nSRSId = nUnknownSRSId;
    int nForcedSRSId = -2;
    if( CSLFetchNameValue( papszOptions, "SRID") != NULL )
    {
        nSRSId = atoi(CSLFetchNameValue( papszOptions, "SRID"));
        nForcedSRSId = nSRSId;
    }
    else
    {
        if (poSRS)
        {
            const char* pszAuthorityName = poSRS->GetAuthorityName(NULL);
            if( pszAuthorityName != NULL && EQUAL( pszAuthorityName, "EPSG" ) )
            {
                /* Assume the EPSG Id is the SRS ID. Might be a wrong guess ! */
                nSRSId = atoi( poSRS->GetAuthorityCode(NULL) );
            }
            else
            {
                const char* pszGeogCSName = poSRS->GetAttrValue("GEOGCS");
                if (pszGeogCSName != NULL && EQUAL(pszGeogCSName, "GCS_WGS_1984"))
                    nSRSId = 4326;
            }
        }
    }

    CPLString osEscapedTableNameSingleQuote = OGRPGDumpEscapeString(pszTableName);
    const char* pszEscapedTableNameSingleQuote = osEscapedTableNameSingleQuote.c_str();

    const char *pszGeometryType = OGRToOGCGeomType(eType);

    const char *pszGFldName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME");
    if( bHavePostGIS && !EQUAL(pszGeomType, "geography"))
    {
        if( pszGFldName == NULL )
            pszGFldName = "wkb_geometry";

        if( nPostGISMajor < 2 )
        {
            /* Sometimes there is an old cruft entry in the geometry_columns
            * table if things were not properly cleaned up before.  We make
            * an effort to clean out such cruft.
            * Note: PostGIS 2.0 defines geometry_columns as a view (no clean up is needed)
            */
            osCommand.Printf(
                    "DELETE FROM geometry_columns WHERE f_table_name = %s AND f_table_schema = '%s'",
                    pszEscapedTableNameSingleQuote, pszSchemaName );
            if (bCreateTable)
                Log(osCommand);
        }
    }


    LogStartTransaction();

/* -------------------------------------------------------------------- */
/*      Create a basic table with the FID.  Also include the            */
/*      geometry if this is not a PostGIS enabled table.                */
/* -------------------------------------------------------------------- */
    int bFID64 = CSLFetchBoolean(papszOptions, "FID64", FALSE);
    const char* pszSerialType = bFID64 ? "BIGSERIAL": "SERIAL";
    
    CPLString osCreateTable;
    int bTemporary = CSLFetchBoolean( papszOptions, "TEMPORARY", FALSE );
    if (bTemporary)
    {
        CPLFree(pszSchemaName);
        pszSchemaName = CPLStrdup("pg_temp_1");
        osCreateTable.Printf("CREATE TEMPORARY TABLE \"%s\"", pszTableName);
    }
    else
        osCreateTable.Printf("CREATE TABLE%s \"%s\".\"%s\"",
                             CSLFetchBoolean( papszOptions, "UNLOGGED", FALSE ) ? " UNLOGGED": "",
                             pszSchemaName, pszTableName);

    if( !bHavePostGIS )
    {
        if (eType == wkbNone)
            osCommand.Printf(
                    "%s ( "
                    "   %s %s, "
                    "   CONSTRAINT \"%s_pk\" PRIMARY KEY (%s) )",
                    osCreateTable.c_str(), osFIDColumnNameEscaped.c_str(), pszSerialType, pszTableName, osFIDColumnNameEscaped.c_str() );
        else
            osCommand.Printf(
                    "%s ( "
                    "   %s %s, "
                    "   WKB_GEOMETRY %s, "
                    "   CONSTRAINT \"%s_pk\" PRIMARY KEY (%s) )",
                    osCreateTable.c_str(), osFIDColumnNameEscaped.c_str(), pszSerialType, pszGeomType, pszTableName, osFIDColumnNameEscaped.c_str() );
    }
    else if ( EQUAL(pszGeomType, "geography") )
    {
        if( CSLFetchNameValue( papszOptions, "GEOMETRY_NAME") != NULL )
            pszGFldName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME");
        else
            pszGFldName = "the_geog";

        const char *suffix = "";
        if( (GeometryTypeFlags & OGRGeometry::OGR_G_MEASURED) && (GeometryTypeFlags & OGRGeometry::OGR_G_3D) )
        {
            suffix = "ZM";
        }
        else if( (GeometryTypeFlags & OGRGeometry::OGR_G_MEASURED) )
        {
            suffix = "M";
        }
        else if( (GeometryTypeFlags & OGRGeometry::OGR_G_3D) )
        {
            suffix = "Z";
        }

        if (nSRSId)
            osCommand.Printf(
                     "%s ( %s %s, \"%s\" geography(%s%s,%d), CONSTRAINT \"%s_pk\" PRIMARY KEY (%s) )",
                     osCreateTable.c_str(), osFIDColumnNameEscaped.c_str(), pszSerialType, pszGFldName, pszGeometryType, suffix, nSRSId, pszTableName, osFIDColumnNameEscaped.c_str() );
        else
            osCommand.Printf(
                     "%s ( %s %s, \"%s\" geography(%s%s), CONSTRAINT \"%s_pk\" PRIMARY KEY (%s) )",
                     osCreateTable.c_str(), osFIDColumnNameEscaped.c_str(), pszSerialType, pszGFldName, pszGeometryType, suffix, pszTableName, osFIDColumnNameEscaped.c_str() );
    }
    else
    {
        osCommand.Printf(
                 "%s ( %s %s, CONSTRAINT \"%s_pk\" PRIMARY KEY (%s) )",
                 osCreateTable.c_str(), osFIDColumnNameEscaped.c_str(), pszSerialType, pszTableName, osFIDColumnNameEscaped.c_str() );
    }

    if (bCreateTable)
        Log(osCommand);

/* -------------------------------------------------------------------- */
/*      Eventually we should be adding this table to a table of         */
/*      "geometric layers", capturing the WKT projection, and           */
/*      perhaps some other housekeeping.                                */
/* -------------------------------------------------------------------- */
    if( bCreateTable && bHavePostGIS && !EQUAL(pszGeomType, "geography"))
    {
        const char *suffix = "";
        if( GeometryTypeFlags == static_cast<int>(OGRGeometry::OGR_G_MEASURED) &&
            wkbFlatten(eType) != wkbUnknown )
        {
            suffix = "M";
        }

        osCommand.Printf(
                "SELECT AddGeometryColumn('%s',%s,'%s',%d,'%s%s',%d)",
                pszSchemaName, pszEscapedTableNameSingleQuote, pszGFldName,
                nSRSId, pszGeometryType, suffix, nDimension );
        Log(osCommand);
    }

    const char *pszSI = CSLFetchNameValue( papszOptions, "SPATIAL_INDEX" );
    int bCreateSpatialIndex = ( pszSI == NULL || CPLTestBool(pszSI) );
    if( bCreateTable && bHavePostGIS && bCreateSpatialIndex )
    {
/* -------------------------------------------------------------------- */
/*      Create the spatial index.                                       */
/*                                                                      */
/*      We're doing this before we add geometry and record to the table */
/*      so this may not be exactly the best way to do it.               */
/* -------------------------------------------------------------------- */
        osCommand.Printf("CREATE INDEX \"%s_%s_geom_idx\" "
                        "ON \"%s\".\"%s\" "
                        "USING GIST (\"%s\")",
                pszTableName, pszGFldName, pszSchemaName, pszTableName, pszGFldName);

        Log(osCommand);
    }

/* -------------------------------------------------------------------- */
/*      Create the layer object.                                        */
/* -------------------------------------------------------------------- */
    OGRPGDumpLayer     *poLayer;

    int bWriteAsHex = !CSLFetchBoolean(papszOptions,"WRITE_EWKT_GEOM",FALSE);

    poLayer = new OGRPGDumpLayer( this, pszSchemaName, pszTableName,
                                  osFIDColumnName, bWriteAsHex, bCreateTable );
    poLayer->SetLaunderFlag( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) );
    poLayer->SetPrecisionFlag( CSLFetchBoolean(papszOptions,"PRECISION",TRUE));

    const char* pszOverrideColumnTypes = CSLFetchNameValue( papszOptions, "COLUMN_TYPES" );
    poLayer->SetOverrideColumnTypes(pszOverrideColumnTypes);
    poLayer->SetUnknownSRSId(nUnknownSRSId);
    poLayer->SetForcedSRSId(nForcedSRSId);
    poLayer->SetCreateSpatialIndexFlag(bCreateSpatialIndex);
    poLayer->SetPostGISVersion(nPostGISMajor, nPostGISMinor);
    poLayer->SetForcedGeometryTypeFlags(ForcedGeometryTypeFlags);

    const char* pszDescription = CSLFetchNameValue(papszOptions, "DESCRIPTION");
    if( pszDescription != NULL )
        poLayer->SetForcedDescription( pszDescription );

    if( bHavePostGIS )
    {
        OGRGeomFieldDefn oTmp( pszGFldName, eType );
        OGRPGDumpGeomFieldDefn *poGeomField =
            new OGRPGDumpGeomFieldDefn(&oTmp);
        poGeomField->nSRSId = nSRSId;
        poGeomField->GeometryTypeFlags = GeometryTypeFlags;
        poLayer->GetLayerDefn()->AddGeomFieldDefn(poGeomField, FALSE);
    }
    else if( pszGFldName )
        poLayer->SetGeometryFieldName(pszGFldName);

/* -------------------------------------------------------------------- */
/*      Add layer to data source layer list.                            */
/* -------------------------------------------------------------------- */
    papoLayers = (OGRPGDumpLayer **)
        CPLRealloc( papoLayers,  sizeof(OGRPGDumpLayer *) * (nLayers+1) );

    papoLayers[nLayers++] = poLayer;

    CPLFree( pszTableName );
    CPLFree( pszSchemaName );

    return poLayer;
}
Beispiel #23
0
json_object* OGRPLScenesDataV1Dataset::RunRequest(const char* pszURL,
                                              int bQuiet404Error,
                                              const char* pszHTTPVerb,
                                              bool bExpectJSonReturn,
                                              const char* pszPostContent)
{
    char** papszOptions = CSLAddString(GetBaseHTTPOptions(), nullptr);
    // We need to set it each time as CURL would reuse the previous value
    // if reusing the same connection
    papszOptions = CSLSetNameValue(papszOptions, "CUSTOMREQUEST", pszHTTPVerb);
    if( pszPostContent != nullptr )
    {
        CPLString osHeaders = CSLFetchNameValueDef(papszOptions, "HEADERS", "");
        if( !osHeaders.empty() )
            osHeaders += "\r\n";
        osHeaders += "Content-Type: application/json";
        papszOptions = CSLSetNameValue(papszOptions, "HEADERS", osHeaders);
        papszOptions = CSLSetNameValue(papszOptions, "POSTFIELDS", pszPostContent);
    }
    papszOptions = CSLSetNameValue(papszOptions, "MAX_RETRY", "3");
    CPLHTTPResult *psResult = nullptr;
    if( STARTS_WITH(m_osBaseURL, "/vsimem/") &&
        STARTS_WITH(pszURL, "/vsimem/") )
    {
        psResult = (CPLHTTPResult*) CPLCalloc(1, sizeof(CPLHTTPResult));
        vsi_l_offset nDataLengthLarge = 0;
        CPLString osURL(pszURL);
        if( osURL[osURL.size()-1 ] == '/' )
            osURL.resize(osURL.size()-1);
        if( pszPostContent != nullptr )
        {
            osURL += "&POSTFIELDS=";
            osURL += pszPostContent;
        }
        CPLDebug("PLSCENES", "Fetching %s", osURL.c_str());
        GByte* pabyBuf = VSIGetMemFileBuffer(osURL, &nDataLengthLarge, FALSE);
        size_t nDataLength = static_cast<size_t>(nDataLengthLarge);
        if( pabyBuf )
        {
            psResult->pabyData = (GByte*) VSI_MALLOC_VERBOSE(1 + nDataLength);
            if( psResult->pabyData )
            {
                memcpy(psResult->pabyData, pabyBuf, nDataLength);
                psResult->pabyData[nDataLength] = 0;
            }
        }
        else
        {
            psResult->pszErrBuf =
                CPLStrdup(CPLSPrintf("Error 404. Cannot find %s", osURL.c_str()));
        }
    }
    else
    {
        if( bQuiet404Error )
            CPLPushErrorHandler(CPLQuietErrorHandler);
        psResult = CPLHTTPFetch( pszURL, papszOptions);
        if( bQuiet404Error )
            CPLPopErrorHandler();
    }
    CSLDestroy(papszOptions);

    if( pszPostContent != nullptr && m_bMustCleanPersistent )
    {
        papszOptions = CSLSetNameValue(nullptr, "CLOSE_PERSISTENT", CPLSPrintf("PLSCENES:%p", this));
        CPLHTTPDestroyResult(CPLHTTPFetch(m_osBaseURL, papszOptions));
        CSLDestroy(papszOptions);
        m_bMustCleanPersistent = false;
    }

    if( psResult->pszErrBuf != nullptr )
    {
        if( !(bQuiet404Error && strstr(psResult->pszErrBuf, "404")) )
        {
            CPLError(CE_Failure, CPLE_AppDefined, "%s",
                    psResult->pabyData ? (const char*) psResult->pabyData :
                    psResult->pszErrBuf);
        }
        CPLHTTPDestroyResult(psResult);
        return nullptr;
    }

    if( !bExpectJSonReturn && (psResult->pabyData == nullptr || psResult->nDataLen == 0) )
    {
        CPLHTTPDestroyResult(psResult);
        return nullptr;
    }

    if( psResult->pabyData == nullptr )
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Empty content returned by server");
        CPLHTTPDestroyResult(psResult);
        return nullptr;
    }

    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
#ifdef DEBUG_VERBOSE
    CPLDebug("PLScenes", "%s", pszText);
#endif

    json_object* poObj = nullptr;
    if( !OGRJSonParse(pszText, &poObj, true) )
    {
        CPLHTTPDestroyResult(psResult);
        return nullptr;
    }

    CPLHTTPDestroyResult(psResult);

    if( json_object_get_type(poObj) != json_type_object )
    {
        CPLError( CE_Failure, CPLE_AppDefined, "Return is not a JSON dictionary");
        json_object_put(poObj);
        poObj = nullptr;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Finalize();

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

{
    EarlySetConfigOptions(argc, argv);

    GDALAllRegister();

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

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

    GDALInfoOptionsForBinary* psOptionsForBinary = GDALInfoOptionsForBinaryNew();

    GDALInfoOptions *psOptions
        = GDALInfoOptionsNew(argv + 1, psOptionsForBinary);
    if( psOptions == NULL )
        Usage();

    if( psOptionsForBinary->pszFilename == NULL )
        Usage("No datasource specified.");

    /* -------------------------------------------------------------------- */
    /*      Open dataset.                                                   */
    /* -------------------------------------------------------------------- */
    GDALDatasetH hDataset
        = GDALOpenEx( psOptionsForBinary->pszFilename, GDAL_OF_READONLY | GDAL_OF_RASTER, NULL,
                      (const char* const* )psOptionsForBinary->papszOpenOptions, NULL );

    if( hDataset == NULL )
    {
        fprintf( stderr,
                 "gdalinfo failed - unable to open '%s'.\n",
                 psOptionsForBinary->pszFilename );

        /* -------------------------------------------------------------------- */
        /*      If argument is a VSIFILE, then print its contents               */
        /* -------------------------------------------------------------------- */
        if ( STARTS_WITH(psOptionsForBinary->pszFilename, "/vsizip/") ||
                STARTS_WITH(psOptionsForBinary->pszFilename, "/vsitar/") )
        {
            char** papszFileList = VSIReadDirRecursive( psOptionsForBinary->pszFilename );
            if ( papszFileList )
            {
                int nCount = CSLCount( papszFileList );
                fprintf( stdout,
                         "Unable to open source `%s' directly.\n"
                         "The archive contains %d files:\n",
                         psOptionsForBinary->pszFilename, nCount );
                for ( int i = 0; i < nCount; i++ )
                {
                    fprintf( stdout, "       %s/%s\n", psOptionsForBinary->pszFilename, papszFileList[i] );
                }
                CSLDestroy( papszFileList );
            }
        }

        CSLDestroy( argv );

        GDALInfoOptionsForBinaryFree(psOptionsForBinary);

        GDALInfoOptionsFree( psOptions );

        GDALDumpOpenDatasets( stderr );

        GDALDestroyDriverManager();

        CPLDumpSharedList( NULL );

        exit( 1 );
    }

    /* -------------------------------------------------------------------- */
    /*      Read specified subdataset if requested.                         */
    /* -------------------------------------------------------------------- */
    if ( psOptionsForBinary->nSubdataset > 0 )
    {
        char **papszSubdatasets = GDALGetMetadata( hDataset, "SUBDATASETS" );
        int nSubdatasets = CSLCount( papszSubdatasets );

        if ( nSubdatasets > 0 && psOptionsForBinary->nSubdataset <= nSubdatasets )
        {
            char szKeyName[1024];
            char *pszSubdatasetName;

            snprintf( szKeyName, sizeof(szKeyName),
                      "SUBDATASET_%d_NAME", psOptionsForBinary->nSubdataset );
            szKeyName[sizeof(szKeyName) - 1] = '\0';
            pszSubdatasetName =
                CPLStrdup( CSLFetchNameValue( papszSubdatasets, szKeyName ) );
            GDALClose( hDataset );
            hDataset = GDALOpen( pszSubdatasetName, GA_ReadOnly );
            CPLFree( pszSubdatasetName );
        }
        else
        {
            fprintf( stderr,
                     "gdalinfo warning: subdataset %d of %d requested. "
                     "Reading the main dataset.\n",
                     psOptionsForBinary->nSubdataset, nSubdatasets );

        }
    }

    GDALInfoOptionsForBinaryFree(psOptionsForBinary);

    char* pszGDALInfoOutput = GDALInfo( hDataset, psOptions );

    printf( "%s", pszGDALInfoOutput );

    CPLFree( pszGDALInfoOutput );

    GDALInfoOptionsFree( psOptions );

    GDALClose( hDataset );

    CSLDestroy( argv );

    GDALDumpOpenDatasets( stderr );

    GDALDestroyDriverManager();

    CPLDumpSharedList( NULL );
    CPLCleanupTLS();

    exit( 0 );

}
Beispiel #26
0
void Msg_reader_core::read_metadata_block(VSILFILE* fin) {
    _open_success = true;

    unsigned int i;

    CPL_IGNORE_RET_VAL(VSIFReadL(&_main_header, sizeof(_main_header), 1, fin));
    CPL_IGNORE_RET_VAL(VSIFReadL(&_sec_header, sizeof(_sec_header), 1, fin));

#ifdef DEBUG
    // print out all the fields in the header
    PH_DATA* hd = (PH_DATA*)&_main_header;
    for (int i=0; i < 6; i++) {
        to_string(*hd);
        printf("[%02d] %s %s", i, hd->name, hd->value);/*ok*/
        hd++;
    }
    PH_DATA_ID* hdi = (PH_DATA_ID*)&_main_header.dataSetIdentification;

    for (i=0; i < 5; i++) {
        printf("%s %s %s", hdi->name, hdi->size, hdi->address);/*ok*/
        hdi++;
    }
    hd = (PH_DATA*)(&_main_header.totalFileSize);
    for (int i=0; i < 19; i++) {
        to_string(*hd);
        printf("[%02d] %s %s", i, hd->name, hd->value);/*ok*/
        hd++;
    }
#endif // DEBUG

    // extract data & header positions

    for (i=0; i < 5; i++) {
        PH_DATA_ID* hdi = (PH_DATA_ID*)&_main_header.dataSetIdentification[i];
        if (STARTS_WITH(hdi->name, "15Header")) {
            sscanf(hdi->size, "%u", &_f_header_size);
            sscanf(hdi->address, "%u", &_f_header_offset);
        } else
            if (STARTS_WITH(hdi->name, "15Data")) {
            sscanf(hdi->size, "%u", &_f_data_size);
            sscanf(hdi->address, "%u", &_f_data_offset);
        }
    }
#ifdef DEBUG
    printf("Data: %u %u\n", _f_data_offset, _f_data_size);/*ok*/
    printf("Header: %u %u\n", _f_header_offset, _f_header_size);/*ok*/
#endif // DEBUG

    unsigned int lines;
    sscanf(_sec_header.northLineSelectedRectangle.value, "%u", &_lines);
    sscanf(_sec_header.southLineSelectedRectangle.value, "%u", &lines);
    _line_start = lines;
    _lines -= lines - 1;

    unsigned int cols;
    sscanf(_sec_header.westColumnSelectedRectangle.value, "%u", &_columns);
    sscanf(_sec_header.eastColumnSelectedRectangle.value, "%u", &cols);
    _col_start = cols;
    _columns -= cols - 1;

#ifdef DEBUG
    printf("lines = %u, cols = %u\n", _lines, _columns);/*ok*/
#endif // DEBUG

    int records_per_line = 0;
    for (i=0; i < MSG_NUM_CHANNELS; i++) {
        if (_sec_header.selectedBandIds.value[i] == 'X') {
            _bands[i] = 1;
            records_per_line += (i == (MSG_NUM_CHANNELS-1)) ? 3 : 1;
        } else {
            _bands[i] = 0;
        }
    }

#ifdef DEBUG
    printf("reading a total of %d records per line\n", records_per_line);/*ok*/
#endif // DEBUG

    // extract time fields, assume that SNIT is the correct field:
    sscanf(_main_header.snit.value +  0, "%04u", &_year);
    sscanf(_main_header.snit.value +  4, "%02u", &_month);
    sscanf(_main_header.snit.value +  6, "%02u", &_day);
    sscanf(_main_header.snit.value +  8, "%02u", &_hour);
    sscanf(_main_header.snit.value + 10, "%02u", &_minute);

    // read radiometric block
    RADIOMETRIC_PROCESSING_RECORD rad;
    off_t offset = RADIOMETRICPROCESSING_RECORD_OFFSET + _f_header_offset + sizeof(GP_PK_HEADER) + sizeof(GP_PK_SH1) + 1;
    CPL_IGNORE_RET_VAL(VSIFSeekL(fin, offset, SEEK_SET));
    CPL_IGNORE_RET_VAL(VSIFReadL(&rad, sizeof(RADIOMETRIC_PROCESSING_RECORD), 1, fin));
    to_native(rad);
    memcpy((void*)_calibration, (void*)&rad.level1_5ImageCalibration,sizeof(_calibration));

#ifdef DEBUG
    for (unsigned int i=0; i < MSG_NUM_CHANNELS; i++) {
        if (_calibration[i].cal_slope < 0 || _calibration[i].cal_slope > 0.4)
        {
            printf("Warning: calibration slope (%f) out of nominal range. MSG reader probably broken\n", _calibration[i].cal_slope);/*ok*/
        }
        if (_calibration[i].cal_offset > 0 || _calibration[i].cal_offset < -20) {
            printf("Warning: calibration offset (%f) out of nominal range. MSG reader probably broken\n",/*ok*/ _calibration[i].cal_offset);
        }
    }
#endif

    // read image description block
    IMAGE_DESCRIPTION_RECORD idr;
    offset = RADIOMETRICPROCESSING_RECORD_OFFSET  - IMAGEDESCRIPTION_RECORD_LENGTH + _f_header_offset + sizeof(GP_PK_HEADER) + sizeof(GP_PK_SH1) + 1;
    CPL_IGNORE_RET_VAL(VSIFSeekL(fin, offset, SEEK_SET));
    CPL_IGNORE_RET_VAL(VSIFReadL(&idr, sizeof(IMAGE_DESCRIPTION_RECORD), 1, fin));
    to_native(idr);
    _line_dir_step = idr.referencegrid_visir.lineDirGridStep;
    _col_dir_step = idr.referencegrid_visir.columnDirGridStep;

    // Rather convoluted, but this code is required to compute the real data block sizes
    // It does this by reading in the first line of every band, to get to the packet size field
    GP_PK_HEADER gp_header;
    GP_PK_SH1    sub_header;
    SUB_VISIRLINE visir_line;

    CPL_IGNORE_RET_VAL(VSIFSeekL(fin, _f_data_offset, SEEK_SET));

    _hrv_packet_size = 0;
    _interline_spacing = 0;
    visir_line.channelId = 0;

    int scanned_bands[MSG_NUM_CHANNELS];
    int band_count = 0;
    for (i=0; i < MSG_NUM_CHANNELS; i++) {
        scanned_bands[i] = _bands[i];
        band_count += _bands[i];
    }

    do {
        if( VSIFReadL(&gp_header, sizeof(GP_PK_HEADER), 1, fin) != 1 ||
            VSIFReadL(&sub_header, sizeof(GP_PK_SH1), 1, fin) != 1 ||
            VSIFReadL(&visir_line, sizeof(SUB_VISIRLINE), 1, fin) != 1 )
        {
            _open_success = false;
            break;
        }
        to_native(visir_line);
        to_native(gp_header);

        // skip over the actual line data
        CPL_IGNORE_RET_VAL(VSIFSeekL(fin,
            gp_header.packetLength - (sizeof(GP_PK_SH1) + sizeof(SUB_VISIRLINE) - 1),
            SEEK_CUR
        ));

        if (visir_line.channelId == 0 || visir_line.channelId > MSG_NUM_CHANNELS) {
            _open_success = false;
            break;
        }

        if (scanned_bands[visir_line.channelId - 1]) {
            scanned_bands[visir_line.channelId - 1] = 0;
            band_count--;

            if (visir_line.channelId != 12) { // not the HRV channel
                _visir_bytes_per_line = gp_header.packetLength - (unsigned int)(sizeof(GP_PK_SH1) + sizeof(SUB_VISIRLINE) - 1);
                _visir_packet_size = gp_header.packetLength + (unsigned int)sizeof(GP_PK_HEADER) + 1;
                _interline_spacing += _visir_packet_size;
            } else {
                _hrv_bytes_per_line = gp_header.packetLength - (unsigned int)(sizeof(GP_PK_SH1) + sizeof(SUB_VISIRLINE) - 1);
                _hrv_packet_size = gp_header.packetLength + (unsigned int)sizeof(GP_PK_HEADER) + 1;
                _interline_spacing +=  3*_hrv_packet_size;
                CPL_IGNORE_RET_VAL(VSIFSeekL(fin, 2*gp_header.packetLength, SEEK_CUR ));
            }
        }
    } while (band_count > 0);
}
int OGRSelafinDataSource::OpenTable(const char * pszFilename) {
#ifdef DEBUG_VERBOSE
    CPLDebug("Selafin", "OpenTable(%s,%i)",
             pszFilename, static_cast<int>(bUpdate));
#endif
    // Open the file
    VSILFILE *fp = NULL;
    if( bUpdate )
    {
        // We have to implement this locking feature for write access because
        // the same file may hold several layers, and some programs (like QGIS)
        // open each layer in a single datasource, so the same file might be
        // opened several times for write access.
        if (TakeLock(pszFilename)==0) {
            CPLError(CE_Failure, CPLE_OpenFailed,
                     "Failed to open %s for write access, "
                     "lock file found %s.",
                     pszFilename, pszLockName);
            return FALSE;
        }
        fp = VSIFOpenL( pszFilename, "rb+" );
    }
    else
    {
        fp = VSIFOpenL( pszFilename, "rb" );
    }

    if( fp == NULL ) {
        CPLError( CE_Warning, CPLE_OpenFailed, "Failed to open %s, %s.", pszFilename, VSIStrerror( errno ) );
        return FALSE;
    }
    if( !bUpdate && strstr(pszFilename, "/vsigzip/") == NULL && strstr(pszFilename, "/vsizip/") == NULL ) fp = (VSILFILE*) VSICreateBufferedReaderHandle((VSIVirtualHandle*)fp);

    // Quickly check if the file is in Selafin format, before actually starting to read to make it faster
    char szBuf[9];
    VSIFReadL(szBuf,1,4,fp);
    if (szBuf[0]!=0 || szBuf[1]!=0 || szBuf[2]!=0 || szBuf[3]!=0x50) {
        VSIFCloseL(fp);
        return FALSE;
    }
    VSIFSeekL(fp,84,SEEK_SET);
    VSIFReadL(szBuf,1,8,fp);
    if (szBuf[0]!=0 || szBuf[1]!=0 || szBuf[2]!=0 || szBuf[3]!=0x50 || szBuf[4]!=0 || szBuf[5]!=0 || szBuf[6]!=0 || szBuf[7]!=8) {
        VSIFCloseL(fp);
        return FALSE;
    }
    /* VSIFSeekL(fp,76,SEEK_SET);
    VSIFReadL(szBuf,1,8,fp);
    if (STRNCASECMP(szBuf,"Seraphin",8)!=0 && STRNCASECMP(szBuf,"Serafin",7)!=0) {
        VSIFCloseL(fp);
        return FALSE;
    } */

    // Get layer base name
    CPLString osBaseLayerName = CPLGetBasename(pszFilename);
    CPLString osExt = CPLGetExtension(pszFilename);
    if( STARTS_WITH(pszFilename, "/vsigzip/") && EQUAL(osExt, "gz") ) {
        size_t nPos=std::string::npos;
        if (strlen(pszFilename)>3) nPos=osExt.find_last_of('.',strlen(pszFilename)-4);
        if (nPos!=std::string::npos) {
            osExt=osExt.substr(nPos+1,strlen(pszFilename)-4-nPos);
            osBaseLayerName=osBaseLayerName.substr(0,nPos);
        } else {
            osExt="";
        }
    }

    // Read header of file to get common information for all layers
    poHeader=Selafin::read_header(fp,pszFilename);
    if (poHeader==NULL) {
        VSIFCloseL(fp);
        CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s, wrong format.\n", pszFilename);
        return FALSE;
    }
    if (poHeader->nEpsg!=0) {
        poSpatialRef=new OGRSpatialReference();
        if (poSpatialRef->importFromEPSG(poHeader->nEpsg)!=OGRERR_NONE) {
            CPLError( CE_Warning, CPLE_AppDefined, "EPSG %d not found. Could not set datasource SRS.\n", poHeader->nEpsg);
            delete poSpatialRef;
            poSpatialRef=NULL;
        }
    }

    // Create two layers for each selected time step: one for points, the other for elements
    poRange.setMaxValue(poHeader->nSteps);
    const int nNewLayers = static_cast<int>(poRange.getSize());
    if (EQUAL(pszFilename, "/vsistdin/")) osBaseLayerName = "layer";
    CPLString osLayerName;
    papoLayers = (OGRSelafinLayer **) CPLRealloc(papoLayers, sizeof(void*) * (nLayers+nNewLayers));
    for (size_t j=0;j<2;++j) {
        SelafinTypeDef eType=(j==0)?POINTS:ELEMENTS;
        for (int i=0;i<poHeader->nSteps;++i) {
            if (poRange.contains(eType,i)) {
                char szTemp[30];
                double dfTime = 0.0;
                if( VSIFSeekL(fp, poHeader->getPosition(i)+4, SEEK_SET)!=0 ||
                    Selafin::read_float(fp, dfTime)==0 )
                {
                    VSIFCloseL(fp);
                    CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s, wrong format.\n", pszFilename);
                    return FALSE;
                }
                if (poHeader->panStartDate==NULL) snprintf(szTemp,29,"%d",i); else {
                    struct tm sDate;
                    memset(&sDate, 0, sizeof(sDate));
                    sDate.tm_year=poHeader->panStartDate[0]-1900;
                    sDate.tm_mon=poHeader->panStartDate[1]-1;
                    sDate.tm_mday=poHeader->panStartDate[2];
                    sDate.tm_hour=poHeader->panStartDate[3];
                    sDate.tm_min=poHeader->panStartDate[4];
                    sDate.tm_sec=poHeader->panStartDate[5]+(int)dfTime;
                    mktime(&sDate);
                    strftime(szTemp,29,"%Y_%m_%d_%H_%M_%S",&sDate);
                }
                if (eType==POINTS) osLayerName=osBaseLayerName+"_p"+szTemp; else osLayerName=osBaseLayerName+"_e"+szTemp;
                papoLayers[nLayers++] =
                    new OGRSelafinLayer( osLayerName, bUpdate, poSpatialRef,
                                         poHeader, i, eType);
                //poHeader->nRefCount++;
            }
        }
    }

    // Free allocated variables and exit
    return TRUE;
}
Beispiel #28
0
int OGRGFTDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    bReadWrite = bUpdateIn;

    pszName = CPLStrdup( pszFilename );

    osAuth = OGRGFTGetOptionValue(pszFilename, "auth");
    if (osAuth.empty())
        osAuth = CPLGetConfigOption("GFT_AUTH", "");

    osRefreshToken = OGRGFTGetOptionValue(pszFilename, "refresh");
    if (osRefreshToken.empty())
        osRefreshToken = CPLGetConfigOption("GFT_REFRESH_TOKEN", "");

    osAPIKey = CPLGetConfigOption("GFT_APIKEY", GDAL_API_KEY);

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

    bUseHTTPS = TRUE;

    osAccessToken = OGRGFTGetOptionValue(pszFilename, "access");
    if (osAccessToken.empty())
        osAccessToken = CPLGetConfigOption("GFT_ACCESS_TOKEN","");
    if (osAccessToken.empty() && !osRefreshToken.empty())
    {
        osAccessToken.Seize(GOA2GetAccessToken(osRefreshToken,
                                               FUSION_TABLE_SCOPE));
        if (osAccessToken.empty())
            return FALSE;
    }
    /* coverity[copy_paste_error] */
    if (osAccessToken.empty() && !osAuth.empty())
    {
        osRefreshToken.Seize(GOA2GetRefreshToken(osAuth, FUSION_TABLE_SCOPE));
        if (osRefreshToken.empty())
            return FALSE;
    }

    if (osAccessToken.empty())
    {
        if (osTables.empty())
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                    "Unauthenticated access requires explicit tables= parameter");
            return FALSE;
        }
    }

    if (!osTables.empty())
    {
        char** papszTables = CSLTokenizeString2(osTables, ",", 0);
        for(int i=0;papszTables && papszTables[i];i++)
        {
            papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
            papoLayers[nLayers ++] = new OGRGFTTableLayer(this, papszTables[i], papszTables[i]);
        }
        CSLDestroy(papszTables);
        return TRUE;
    }

    /* Get list of tables */
    CPLHTTPResult * psResult = RunSQL("SHOW TABLES");

    if (psResult == nullptr)
        return FALSE;

    char* pszLine = (char*) psResult->pabyData;
    if (pszLine == nullptr ||
        psResult->pszErrBuf != nullptr ||
        !STARTS_WITH(pszLine, "table id,name"))
    {
        CPLHTTPDestroyResult(psResult);
        return FALSE;
    }

    pszLine = OGRGFTGotoNextLine(pszLine);
    while(pszLine != nullptr && *pszLine != 0)
    {
        char* pszNextLine = OGRGFTGotoNextLine(pszLine);
        if (pszNextLine)
            pszNextLine[-1] = 0;

        char** papszTokens = CSLTokenizeString2(pszLine, ",", 0);
        if (CSLCount(papszTokens) == 2)
        {
            CPLString osTableId(papszTokens[0]);
            CPLString osLayerName(papszTokens[1]);
            for(int i=0;i<nLayers;i++)
            {
                if (strcmp(papoLayers[i]->GetName(), osLayerName) == 0)
                {
                    osLayerName += " (";
                    osLayerName += osTableId;
                    osLayerName += ")";
                    break;
                }
            }
            papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
            papoLayers[nLayers ++] = new OGRGFTTableLayer(this, osLayerName, osTableId);
        }
        CSLDestroy(papszTokens);

        pszLine = pszNextLine;
    }

    CPLHTTPDestroyResult(psResult);

    return TRUE;
}
Beispiel #29
0
GDALDataset* SRTMHGTDataset::Open(GDALOpenInfo* poOpenInfo)
{
  if (!Identify(poOpenInfo))
      return nullptr;

  const char* fileName = CPLGetFilename(poOpenInfo->pszFilename);
  CPLString osLCFilename(CPLString(fileName).tolower());
  if( !STARTS_WITH(fileName, "/vsizip/") &&
      osLCFilename.endsWith(".hgt.zip") )
  {
      CPLString osFilename ("/vsizip/");
      osFilename += poOpenInfo->pszFilename;
      osFilename += "/";
      osFilename += CPLString(fileName).substr(0, 7);
      osFilename += ".hgt";
      GDALOpenInfo oOpenInfo(osFilename, poOpenInfo->eAccess);
      GDALDataset* poDS = Open(&oOpenInfo);
      if( poDS != nullptr )
      {
          // override description with the main one
          poDS->SetDescription(poOpenInfo->pszFilename);
      }
      return poDS;
  }

  if( !STARTS_WITH(fileName, "/vsizip/") &&
      osLCFilename.endsWith(".srtmswbd.raw.zip") )
  {
      CPLString osFilename("/vsizip/");
      osFilename += poOpenInfo->pszFilename;
      osFilename += "/";
      osFilename += CPLString(fileName).substr(0, 7);
      osFilename += ".raw";
      GDALOpenInfo oOpenInfo(osFilename, poOpenInfo->eAccess);
      GDALDataset* poDS = Open(&oOpenInfo);
      if( poDS != nullptr )
      {
          // override description with the main one
          poDS->SetDescription(poOpenInfo->pszFilename);
      }
      return poDS;
  }

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

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

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

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

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

  VSIStatBufL fileStat;
  if(VSIStatL(poOpenInfo->pszFilename, &fileStat) != 0)
  {
      delete poDS;
      return nullptr;
  }

  int numPixels_x, numPixels_y;

  GDALDataType eDT = GDT_Int16;
  switch (fileStat.st_size) {
  case 3601 * 3601:
    numPixels_x = numPixels_y = 3601;
    eDT = GDT_Byte;
    break;
  case 3601 * 3601 * 2:
    numPixels_x = numPixels_y = 3601;
    break;
  case 1801 * 3601 * 2:
    numPixels_x = 1801;
    numPixels_y = 3601;
    break;
  case 1201 * 1201 * 2:
    numPixels_x = numPixels_y = 1201;
    break;
  default:
    numPixels_x = numPixels_y = 0;
    break;
  }

  poDS->eAccess = poOpenInfo->eAccess;
#ifdef CPL_LSB
  if(poDS->eAccess == GA_Update && eDT == GDT_Int16)
  {
      poDS->panBuffer
          = reinterpret_cast<GInt16 *>( CPLMalloc(numPixels_x * sizeof(GInt16)) );
  }
#endif

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

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

  poDS->SetMetadataItem( GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT );

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

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

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

  return poDS;
}
Beispiel #30
0
OGRHTFSoundingLayer::OGRHTFSoundingLayer( const char* pszFilename, int nZone,
                                          int bIsNorth,
                                          int nTotalSoundingsIn ) :
    OGRHTFLayer(pszFilename, nZone, bIsNorth),
    bHasFPK(false),
    nFieldsPresent(0),
    panFieldPresence(NULL),
    nEastingIndex(-1),
    nNorthingIndex(-1),
    nTotalSoundings(nTotalSoundingsIn)
{
    poFeatureDefn = new OGRFeatureDefn( "sounding" );
    SetDescription( poFeatureDefn->GetName() );
    poFeatureDefn->Reference();
    poFeatureDefn->SetGeomType( wkbPoint  );
    poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);

    const char* pszLine;
    bool bSoundingHeader = false;
    while( fpHTF != NULL &&
           (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
    {
        if (STARTS_WITH(pszLine, "SOUNDING HEADER"))
            bSoundingHeader = true;
        else if (bSoundingHeader && strlen(pszLine) > 10 &&
                 pszLine[0] == '[' && pszLine[3] == ']' &&
                 pszLine[4] == ' ' &&
                 strstr(pszLine + 5, " =") != NULL)
        {
            char* pszName = CPLStrdup(pszLine + 5);
            *strstr(pszName, " =") = 0;
            char* pszPtr = pszName;
            for(;*pszPtr;pszPtr++)
            {
                if (*pszPtr == ' ')
                    *pszPtr = '_';
            }
            OGRFieldType eType;
            if (strcmp(pszName, "REJECTED_SOUNDING") == 0 ||
                strcmp(pszName, "FIX_NUMBER") == 0 ||
                strcmp(pszName, "NBA_FLAG") == 0 ||
                strcmp(pszName, "SOUND_VELOCITY") == 0 ||
                strcmp(pszName, "PLOTTED_SOUNDING") == 0)
                eType = OFTInteger;
            else if (strcmp(pszName, "LATITUDE") == 0 ||
                     strcmp(pszName, "LONGITUDE") == 0 ||
                     strcmp(pszName, "EASTING") == 0 ||
                     strcmp(pszName, "NORTHING") == 0 ||
                     strcmp(pszName, "DEPTH") == 0 ||
                     strcmp(pszName, "TPE_POSITION") == 0 ||
                     strcmp(pszName, "TPE_DEPTH") == 0 ||
                     strcmp(pszName, "TIDE") == 0 ||
                     strcmp(pszName, "DEEP_WATER_CORRECTION") == 0 ||
                     strcmp(pszName, "VERTICAL_BIAS_CORRECTION") == 0)
                eType = OFTReal;
            else
                eType = OFTString;
            OGRFieldDefn    oField( pszName, eType);
            poFeatureDefn->AddFieldDefn( &oField);
            CPLFree(pszName);
        }
        else if (strcmp(pszLine, "END OF SOUNDING HEADER") == 0)
        {
            bSoundingHeader = false;
        }
        else if (strcmp(pszLine, "SOUNDING DATA") == 0)
        {
            pszLine = CPLReadLine2L(fpHTF, 1024, NULL);
            if (pszLine == NULL)
                break;
            if (pszLine[0] == '[' &&
                static_cast<int>(strlen(pszLine)) ==
                2 + poFeatureDefn->GetFieldCount())
            {
                bHasFPK = true;
                panFieldPresence = static_cast<bool *>(
                    CPLMalloc(sizeof(int) * poFeatureDefn->GetFieldCount()) );
                for( int i=0;i<poFeatureDefn->GetFieldCount();i++)
                {
                    panFieldPresence[i] = pszLine[1 + i] != '0';
                    nFieldsPresent += panFieldPresence[i] ? 1 : 0;
                }
            }
            break;
        }
    }

    if( !bHasFPK )
    {
        panFieldPresence = static_cast<bool *>(
            CPLMalloc(sizeof(int) * poFeatureDefn->GetFieldCount()) );
        for( int i=0; i < poFeatureDefn->GetFieldCount(); i++ )
            panFieldPresence[i] = true;
        nFieldsPresent = poFeatureDefn->GetFieldCount();
    }

    int nIndex = poFeatureDefn->GetFieldIndex("EASTING");
    if (nIndex < 0 || !panFieldPresence[nIndex])
    {
        CPLError(CE_Failure, CPLE_NotSupported, "Cannot find EASTING field");
        VSIFCloseL( fpHTF );
        fpHTF = NULL;
        return;
    }
    nEastingIndex = nIndex;
    nIndex = poFeatureDefn->GetFieldIndex("NORTHING");
    if (nIndex < 0 || !panFieldPresence[nIndex])
    {
        CPLError(CE_Failure, CPLE_NotSupported, "Cannot find NORTHING field");
        VSIFCloseL( fpHTF );
        fpHTF = NULL;
        return;
    }
    nNorthingIndex = nIndex;

    ResetReading();
}