Example #1
0
int VSIMemFilesystemHandler::Rename( const char *pszOldPath,
                                     const char *pszNewPath )

{
    CPLMutexHolder oHolder( &hMutex );

    CPLString osOldPath = pszOldPath;
    CPLString osNewPath = pszNewPath;

    NormalizePath( osOldPath );
    NormalizePath( osNewPath );

    if ( osOldPath.compare(osNewPath) == 0 )
        return 0;

    if( oFileList.find(osOldPath) == oFileList.end() )
    {
        errno = ENOENT;
        return -1;
    }
    else
    {
        VSIMemFile* poFile = oFileList[osOldPath];

        oFileList.erase( oFileList.find(osOldPath) );

        Unlink(osNewPath);

        oFileList[osNewPath] = poFile;
        poFile->osFilename = osNewPath;

        return 0;
    }
}
// This is a performance critical function, especially on geosciml schemas,
// and we make careful to not do any string copy or other memory allocation
// in it.
bool GMLASXPathMatcher::MatchesRefXPath(
                        const CPLString& osXPath,
                        const std::vector<XPathComponent>& oRefXPath) const
{
    size_t iPos = 0;
    size_t iIdxInRef = 0;

    bool bDirectChild = oRefXPath[0].m_bDirectChild;
    while( iPos < osXPath.size() && iIdxInRef < oRefXPath.size() )
    {
        bDirectChild = oRefXPath[iIdxInRef].m_bDirectChild;
        size_t iPosNextSlash = osXPath.find('/', iPos);

        bool bNodeMatch;
        if( iPosNextSlash == std::string::npos )
        {
            bNodeMatch = osXPath.compare(iPos, std::string::npos,
                                         oRefXPath[iIdxInRef].m_osValue) == 0;
        }
        else
        {
            bNodeMatch = osXPath.compare(iPos, iPosNextSlash - iPos,
                                         oRefXPath[iIdxInRef].m_osValue) == 0;
        }

        if( !bNodeMatch )
        {
            if( bDirectChild )
                return false;

            if( iPosNextSlash == std::string::npos )
                return false;
            iPos = iPosNextSlash + 1;
            continue;
        }

        if( iPosNextSlash == std::string::npos )
            iPos = osXPath.size();
        else
            iPos = iPosNextSlash + 1;
        iIdxInRef ++;
        bDirectChild = true;
    }

    return (!bDirectChild || iPos == osXPath.size()) &&
            iIdxInRef == oRefXPath.size();
}
Example #3
0
int VSIMemFilesystemHandler::Rename( const char *pszOldPath,
                                     const char *pszNewPath )

{
    CPLMutexHolder oHolder( &hMutex );

    CPLString osOldPath = pszOldPath;
    CPLString osNewPath = pszNewPath;

    NormalizePath( osOldPath );
    NormalizePath( osNewPath );

    if( osOldPath.compare(osNewPath) == 0 )
        return 0;

    if( oFileList.find(osOldPath) == oFileList.end() )
    {
        errno = ENOENT;
        return -1;
    }

    std::map<CPLString, VSIMemFile*>::iterator it = oFileList.find(osOldPath);
    while( it != oFileList.end() && it->first.ifind(osOldPath) == 0 )
    {
        const CPLString osRemainder = it->first.substr(osOldPath.size());
        if( osRemainder.empty() || osRemainder[0] == '/' )
        {
            const CPLString osNewFullPath = osNewPath + osRemainder;
            Unlink_unlocked(osNewFullPath);
            oFileList[osNewFullPath] = it->second;
            it->second->osFilename = osNewFullPath;
            oFileList.erase(it++);
        }
        else
        {
            ++it;
        }
    }

    return 0;
}
Example #4
0
OGRErr OGRShapeLayer::Repack()

{
    if( !bUpdateAccess )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
            "The REPACK operation is not permitted on a read-only shapefile." );
        return OGRERR_FAILURE;
    }
    
    if( hDBF == NULL )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Attempt to repack a shapefile with no .dbf file not supported.");
        return OGRERR_FAILURE;
    }
    
/* -------------------------------------------------------------------- */
/*      Build a list of records to be dropped.                          */
/* -------------------------------------------------------------------- */
    int *panRecordsToDelete = (int *) 
        CPLMalloc(sizeof(int)*(nTotalShapeCount+1));
    int nDeleteCount = 0;
    int iShape = 0;
    OGRErr eErr = OGRERR_NONE;

    for( iShape = 0; iShape < nTotalShapeCount; iShape++ )
    {
        if( DBFIsRecordDeleted( hDBF, iShape ) )
            panRecordsToDelete[nDeleteCount++] = iShape;
    }
    panRecordsToDelete[nDeleteCount] = -1;

/* -------------------------------------------------------------------- */
/*      If there are no records marked for deletion, we take no         */
/*      action.                                                         */
/* -------------------------------------------------------------------- */
    if( nDeleteCount == 0 )
    {
        CPLFree( panRecordsToDelete );
        return OGRERR_NONE;
    }

/* -------------------------------------------------------------------- */
/*      Find existing filenames with exact case (see #3293).            */
/* -------------------------------------------------------------------- */
    CPLString osDirname(CPLGetPath(pszFullName));
    CPLString osBasename(CPLGetBasename(pszFullName));
    
    CPLString osDBFName, osSHPName, osSHXName;
    char **papszCandidates = CPLReadDir( osDirname );
    int i = 0;
    while(papszCandidates != NULL && papszCandidates[i] != NULL)
    {
        CPLString osCandidateBasename = CPLGetBasename(papszCandidates[i]);
        CPLString osCandidateExtension = CPLGetExtension(papszCandidates[i]);
        if (osCandidateBasename.compare(osBasename) == 0)
        {
            if (EQUAL(osCandidateExtension, "dbf"))
                osDBFName = CPLFormFilename(osDirname, papszCandidates[i], NULL);
            else if (EQUAL(osCandidateExtension, "shp"))
                osSHPName = CPLFormFilename(osDirname, papszCandidates[i], NULL);
            else if (EQUAL(osCandidateExtension, "shx"))
                osSHXName = CPLFormFilename(osDirname, papszCandidates[i], NULL);
        }
        
        i++;
    }
    CSLDestroy(papszCandidates);
    papszCandidates = NULL;
    
    if (osDBFName.size() == 0)
    {
        /* Should not happen, really */
        CPLFree( panRecordsToDelete );
        return OGRERR_FAILURE;
    }
    
/* -------------------------------------------------------------------- */
/*      Cleanup any existing spatial index.  It will become             */
/*      meaningless when the fids change.                               */
/* -------------------------------------------------------------------- */
    if( CheckForQIX() )
        DropSpatialIndex();

/* -------------------------------------------------------------------- */
/*      Create a new dbf file, matching the old.                        */
/* -------------------------------------------------------------------- */
    DBFHandle hNewDBF = NULL;
    
    CPLString oTempFile(CPLFormFilename(osDirname, osBasename, NULL));
    oTempFile += "_packed.dbf";

    hNewDBF = DBFCloneEmpty( hDBF, oTempFile );
    if( hNewDBF == NULL )
    {
        CPLFree( panRecordsToDelete );

        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to create temp file %s.", 
                  oTempFile.c_str() );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Copy over all records that are not deleted.                     */
/* -------------------------------------------------------------------- */
    int iDestShape = 0;
    int iNextDeletedShape = 0;

    for( iShape = 0; 
         iShape < nTotalShapeCount && eErr == OGRERR_NONE; 
         iShape++ )
    {
        if( panRecordsToDelete[iNextDeletedShape] == iShape )
            iNextDeletedShape++;
        else
        {
            void *pTuple = (void *) DBFReadTuple( hDBF, iShape );
            if( pTuple == NULL )
                eErr = OGRERR_FAILURE;
            else if( !DBFWriteTuple( hNewDBF, iDestShape++, pTuple ) )
                eErr = OGRERR_FAILURE;
        }                           
    }

    if( eErr != OGRERR_NONE )
    {
        CPLFree( panRecordsToDelete );
        VSIUnlink( oTempFile );
        return eErr;
    }

/* -------------------------------------------------------------------- */
/*      Cleanup the old .dbf and rename the new one.                    */
/* -------------------------------------------------------------------- */
    DBFClose( hDBF );
    DBFClose( hNewDBF );
    hDBF = hNewDBF = NULL;
    
    VSIUnlink( osDBFName );
        
    if( VSIRename( oTempFile, osDBFName ) != 0 )
    {
        CPLDebug( "Shape", "Can not rename DBF file: %s", VSIStrerror( errno ) );
        CPLFree( panRecordsToDelete );
        return OGRERR_FAILURE;
    }
    
/* -------------------------------------------------------------------- */
/*      Now create a shapefile matching the old one.                    */
/* -------------------------------------------------------------------- */
    if( hSHP != NULL )
    {
        SHPHandle hNewSHP = NULL;
        
        if (osSHPName.size() == 0 || osSHXName.size() == 0)
        {
            /* Should not happen, really */
            CPLFree( panRecordsToDelete );
            return OGRERR_FAILURE;
        }

        oTempFile = CPLFormFilename(osDirname, osBasename, NULL);
        oTempFile += "_packed.shp";

        hNewSHP = SHPCreate( oTempFile, hSHP->nShapeType );
        if( hNewSHP == NULL )
        {
            CPLFree( panRecordsToDelete );
            return OGRERR_FAILURE;
        }

/* -------------------------------------------------------------------- */
/*      Copy over all records that are not deleted.                     */
/* -------------------------------------------------------------------- */
        iNextDeletedShape = 0;

        for( iShape = 0; 
             iShape < nTotalShapeCount && eErr == OGRERR_NONE; 
             iShape++ )
        {
            if( panRecordsToDelete[iNextDeletedShape] == iShape )
                iNextDeletedShape++;
            else
            {
                SHPObject *hObject;

                hObject = SHPReadObject( hSHP, iShape );
                if( hObject == NULL )
                    eErr = OGRERR_FAILURE;
                else if( SHPWriteObject( hNewSHP, -1, hObject ) == -1 )
                    eErr = OGRERR_FAILURE;

                if( hObject )
                    SHPDestroyObject( hObject );
            }
        }

        if( eErr != OGRERR_NONE )
        {
            CPLFree( panRecordsToDelete );
            VSIUnlink( CPLResetExtension( oTempFile, "shp" ) );
            VSIUnlink( CPLResetExtension( oTempFile, "shx" ) );
            return eErr;
        }

/* -------------------------------------------------------------------- */
/*      Cleanup the old .shp/.shx and rename the new one.               */
/* -------------------------------------------------------------------- */
        SHPClose( hSHP );
        SHPClose( hNewSHP );
        hSHP = hNewSHP = NULL;

        VSIUnlink( osSHPName );
        VSIUnlink( osSHXName );

        oTempFile = CPLResetExtension( oTempFile, "shp" );
        if( VSIRename( oTempFile, osSHPName ) != 0 )
        {
            CPLDebug( "Shape", "Can not rename SHP file: %s", VSIStrerror( errno ) );
            CPLFree( panRecordsToDelete );
            return OGRERR_FAILURE;
        }
    
        oTempFile = CPLResetExtension( oTempFile, "shx" );
        if( VSIRename( oTempFile, osSHXName ) != 0 )
        {
            CPLDebug( "Shape", "Can not rename SHX file: %s", VSIStrerror( errno ) );
            CPLFree( panRecordsToDelete );
            return OGRERR_FAILURE;
        }
    }
    
    CPLFree( panRecordsToDelete );
    panRecordsToDelete = NULL;

/* -------------------------------------------------------------------- */
/*      Reopen the shapefile                                            */
/*                                                                      */
/* We do not need to reimplement OGRShapeDataSource::OpenFile() here    */  
/* with the fully featured error checking.                              */
/* If all operations above succeeded, then all necessery files are      */
/* in the right place and accessible.                                   */
/* -------------------------------------------------------------------- */
    CPLAssert( NULL == hSHP );
    CPLAssert( NULL == hDBF && NULL == hNewDBF );
    
    CPLPushErrorHandler( CPLQuietErrorHandler );
    
    const char* pszAccess = NULL;
    if( bUpdateAccess )
        pszAccess = "r+";
    else
        pszAccess = "r";
    
    hSHP = SHPOpen ( CPLResetExtension( pszFullName, "shp" ) , pszAccess );
    hDBF = DBFOpen ( CPLResetExtension( pszFullName, "dbf" ) , pszAccess );
    
    CPLPopErrorHandler();
    
    if( NULL == hSHP || NULL == hDBF )
    {
        CPLString osMsg(CPLGetLastErrorMsg());
        CPLError( CE_Failure, CPLE_OpenFailed, "%s", osMsg.c_str() );

        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Update total shape count.                                       */
/* -------------------------------------------------------------------- */
    nTotalShapeCount = hDBF->nRecords;

    return OGRERR_NONE;
}
int  OGRSOSIDataSource::Open( const char *pszFilename, int bUpdate ) {
    papoBuiltGeometries = NULL;
    poFileadm = NULL;
    poBaseadm = NULL;
    char *pszPos;

    if ( bUpdate ) {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Update access not supported by the SOSI driver." );
        return FALSE;
    }

    /* Check that the file exists otherwise HO_TestSOSI() emits an error */
    VSIStatBuf sStat;
    if( VSIStat(pszFilename, &sStat) != 0 )
        return FALSE;

    pszName = CPLStrdup( pszFilename );
    /* We ignore any layer parameters for now. */
    pszPos = strchr(pszName, ',');
    if (pszPos != NULL) {
        pszPos[0] = '\0';
    }

    /* Confirm that we are dealing with a SOSI file. Used also by data
     * format auto-detection in some ogr utilities. */
    UT_INT64 nEnd = 0;
    int bIsSosi = HO_TestSOSI ( pszName, &nEnd );
    if ( bIsSosi == UT_FALSE ) {
        return FALSE; /* No error message: This is used by file format auto-detection */
    }

    short nStatus = 0, nDetStatus = 0; /* immediate status, detailed status */

    /* open index base and sosi file */
    poBaseadm = LC_OpenBase(LC_BASE);
    nStatus   = LC_OpenSos(pszName, LC_BASE_FRAMGR, LC_GML_IDX, LC_INGEN_STATUS,
                           &poFileadm, &nDetStatus);
    if ( nStatus == UT_FALSE ) {
        char *pszErrorMessage;
        LC_StrError(nDetStatus, &pszErrorMessage);
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "File %s could not be opened by SOSI Driver: %s", pszName, pszErrorMessage );
        return FALSE;
    }

    /* --------------------------------------------------------------------*
     *      Prefetch all the information needed to determine layers        *
     * 	    and prebuild LineString features for later assembly.           *
     * --------------------------------------------------------------------*/

    /* allocate room for one pointer per feature */
    nNumFeatures = static_cast<unsigned int>(poFileadm->lAntGr);
    void* mem = VSI_MALLOC2_VERBOSE(nNumFeatures, sizeof(void*));
    if (mem == NULL) {
        return FALSE;
    } else {
        papoBuiltGeometries = (OGRGeometry**)mem;
    }
    for (unsigned int i=0; i<nNumFeatures; i++) papoBuiltGeometries[i] = NULL;

    /* Various iterators and return values used to iterate through SOSI features */
    short          nName, nNumLines;
    long           nNumCoo;
    unsigned short nInfo;
    LC_SNR_ADM	   oSnradm;
    LC_BGR		   oNextSerial;
    LC_BGR		  *poNextSerial;
    poNextSerial =&oNextSerial;

    bool bPointLayer = FALSE; /* Initialize four layers for the different geometry types */
    bool bCurveLayer = FALSE;
    bool bPolyLayer  = FALSE;
    bool bTextLayer  = FALSE;
    poPolyHeaders  = new S2I();
    poPointHeaders = new S2I();
    poCurveHeaders = new S2I();
    poTextHeaders  = new S2I();

    LC_SBSn(&oSnradm, poFileadm, 0, nNumFeatures); /* Set FYBA search limits  */
    LC_InitNextBgr(poNextSerial);

    /* Prebuilding simple features and extracting layer information. */
    while (LC_NextBgr(poNextSerial,LC_FRAMGR)) {
        /* Fetch next group information */
        nName = LC_RxGr(poNextSerial, LES_OPTIMALT, &nNumLines, &nNumCoo, &nInfo);

        S2S oHeaders;
        S2S::iterator iHeaders;
        int iH;
        /* Extract all strings from group header. */
        for (short i=1; i<=nNumLines; i++) {
            char *pszLine = LC_GetGi(i);      /* Get one header line */
            if ((pszLine[0] == ':')||(pszLine[0] == '(')) continue;  /* If we have a continued REF line, skip it. */
            if (pszLine[0] == '!') continue;  /* If we have a comment line, skip it. */

            char *pszUTFLine = CPLRecode(pszLine, pszEncoding, CPL_ENC_UTF8); /* switch to UTF encoding here, if it is known. */
            char *pszUTFLineIter = pszUTFLine;
            while (pszUTFLineIter[0] == '.') pszUTFLineIter++; /* Skipping the dots at the beginning of a SOSI line */
            char *pszPos2 = strstr(pszUTFLineIter, " "); /* Split header and value */
            if (pszPos2 != NULL) {
                CPLString osKey = CPLString(std::string(pszUTFLineIter,pszPos2)); /* FIXME: clean instantiation of CPLString? */
                CPLString osValue = CPLString(pszPos2+1);

                oHeaders[osKey]=osValue;          /* Add to header map */
                switch (nName) {             /* Add to header list for the corresponding layer, if it is not */
                case L_FLATE: {            /* in there already */
                    if (poPolyHeaders->find(osKey) == poPolyHeaders->end()) {
                        iH = static_cast<int>(poPolyHeaders->size());
                        (*poPolyHeaders)[osKey] = iH;
                    }
                    break;
                }
                case L_KURVE:  
                case L_LINJE:  
                case L_BUEP:  {    /* FIXME: maybe not use the same headers for both */
                    if (poCurveHeaders->find(osKey) == poCurveHeaders->end()) {
                        iH = static_cast<int>(poCurveHeaders->size());
                        (*poCurveHeaders)[osKey] = iH;
                    }
                    break;
                }
                case L_PUNKT: 
                case L_SYMBOL: {
                    if (poPointHeaders->find(osKey) == poPointHeaders->end()) {
                        iH = static_cast<int>(poPointHeaders->size());
                        (*poPointHeaders)[osKey] = iH;
                    }
                    break;
                }
                case L_TEKST: {
                    if (poTextHeaders->find(osKey) == poTextHeaders->end()) {
                        iH = static_cast<int>(poTextHeaders->size());
                        (*poTextHeaders)[osKey] = iH;
                    }
                    break;
                }
                }
            }
            CPLFree(pszUTFLine);
        }

        /* Feature-specific tasks */
        switch (nName) {
        case L_PUNKT: {
            /* Pre-build a point feature. Activate point layer. */
            bPointLayer = TRUE;
            buildOGRPoint(oNextSerial.lNr);
            break;
        }
        case L_FLATE: {
            /* Activate polygon layer. */
            bPolyLayer = TRUE;
            /* cannot build geometries that reference others yet */
            break;
        }
        case L_KURVE: 
        case L_LINJE: {
            /* Pre-build a line feature. Activate line/curve layer. */
            bCurveLayer = TRUE;
            buildOGRLineString(static_cast<int>(nNumCoo), oNextSerial.lNr);
            break;
        }
        case L_BUEP: {
            /* Pre-build a line feature as interpolation from an arc. Activate line/curve layer. */
            bCurveLayer = TRUE;
            buildOGRLineStringFromArc(oNextSerial.lNr);
            break;
        }
        case L_TEKST: {
            /* Pre-build a text line contour feature. Activate text layer. */
            /* Todo: observe only points 2ff if more than one point is given for follow mode */
            bTextLayer = TRUE;
            buildOGRMultiPoint(static_cast<int>(nNumCoo), oNextSerial.lNr);
            break;
        }
        case L_HODE: {
            /* Get SRS from SOSI header. */
            unsigned short nMask = LC_TR_ALLT;
            LC_TRANSPAR oTrans;
            if (LC_GetTransEx(&nMask,&oTrans) == UT_FALSE) {
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "TRANSPAR section not found - No reference system information available.");
                return FALSE;
            }
            poSRS = new OGRSpatialReference();

            /* Get coordinate system from SOSI header. */
            int nEPSG = sosi2epsg(oTrans.sKoordsys);
            if (poSRS->importFromEPSG(nEPSG) != OGRERR_NONE) {
				CPLError( CE_Failure, CPLE_OpenFailed,
                          "OGR could not load coordinate system definition EPSG:%i.", nEPSG);
                return FALSE;
            }

            /* Get character encoding from SOSI header. */
            iHeaders = oHeaders.find("TEGNSETT");
            if (iHeaders != oHeaders.end()) {
                CPLString osLine = iHeaders->second;
                if (osLine.compare("ISO8859-1")==0) {
                    pszEncoding = CPL_ENC_ISO8859_1;
                } else if (osLine.compare("ISO8859-10")==0) {
                    pszEncoding = CPL_ENC_ISO8859_10;
                } else if (osLine.compare("UTF-8")==0) {
                    pszEncoding = CPL_ENC_UTF8;
                }
            }

            break;
        }
        default: {
            break;
        }
        }
    }

    /* -------------------------------------------------------------------- *
     *      Create a corresponding layers. One per geometry type            *
     * -------------------------------------------------------------------- */
    int l_nLayers = 0;
    if (bPolyLayer)  l_nLayers++;
    if (bCurveLayer) l_nLayers++;
    if (bPointLayer) l_nLayers++;
    if (bTextLayer) l_nLayers++;
    this->nLayers = l_nLayers;
    /* allocate some memory for up to three layers */
    papoLayers = (OGRSOSILayer **) VSI_MALLOC2_VERBOSE(sizeof(void*), l_nLayers);
    if( papoLayers == NULL )
    {
        this->nLayers = 0;
        return FALSE;
    }

    /* Define each layer, using a proper feature definition, geometry type,
     * and adding every SOSI header encountered in the file as field. */
    S2I::iterator i;
    if (bPolyLayer) {
        S2I * poHeadersNew = new S2I();
		OGRFeatureDefn *poFeatureDefn = defineLayer("polygons", wkbPolygon, poPolyHeaders, &poHeadersNew);
        delete poPolyHeaders;
        poPolyHeaders = poHeadersNew;
        poFeatureDefn->Reference();
        papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poPolyHeaders );
    } else {
        delete poPolyHeaders;
        poPolyHeaders = NULL;
    }
    if (bCurveLayer) {
        S2I * poHeadersNew = new S2I();
        OGRFeatureDefn *poFeatureDefn = defineLayer("lines", wkbLineString, poCurveHeaders, &poHeadersNew);
        delete poCurveHeaders;
        poCurveHeaders = poHeadersNew;
        poFeatureDefn->Reference();
        papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poCurveHeaders );
    } else {
        delete poCurveHeaders;
        poCurveHeaders = NULL;
    }
    if (bPointLayer) {
        S2I * poHeadersNew = new S2I();
        OGRFeatureDefn *poFeatureDefn = defineLayer("points", wkbPoint, poPointHeaders, &poHeadersNew);
        delete poPointHeaders;
        poPointHeaders = poHeadersNew;
        poFeatureDefn->Reference();
        papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poPointHeaders );
    } else {
        delete poPointHeaders;
        poPointHeaders = NULL;
    }
    if (bTextLayer) {
        S2I * poHeadersNew = new S2I();
        OGRFeatureDefn *poFeatureDefn = defineLayer("text", wkbMultiPoint, poTextHeaders, &poHeadersNew);
        delete poTextHeaders;
        poTextHeaders = poHeadersNew;
        poFeatureDefn->Reference();
        papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poTextHeaders );
    } else {
        delete poTextHeaders;
        poTextHeaders = NULL;
    }
    return TRUE;
}
Example #6
0
int OGRPDSDataSource::Open( const char * pszFilename )

{
    pszName = CPLStrdup( pszFilename );

// --------------------------------------------------------------------
//      Does this appear to be a .PDS table file?
// --------------------------------------------------------------------

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

    char szBuffer[512];
    int nbRead = (int)VSIFReadL(szBuffer, 1, sizeof(szBuffer) - 1, fp);
    szBuffer[nbRead] = '\0';

    const char* pszPos = strstr(szBuffer, "PDS_VERSION_ID");
    int bIsPDS = (pszPos != NULL);

    if (!bIsPDS)
    {
        VSIFCloseL(fp);
        return FALSE;
    }

    if (!oKeywords.Ingest(fp, pszPos - szBuffer))
    {
        VSIFCloseL(fp);
        return FALSE;
    }

    VSIFCloseL(fp);
    CPLString osRecordType = oKeywords.GetKeyword( "RECORD_TYPE", "" );
    CPLString osFileRecords = oKeywords.GetKeyword( "FILE_RECORDS", "" );
    CPLString osRecordBytes = oKeywords.GetKeyword( "RECORD_BYTES", "" );
    int nRecordSize = atoi(osRecordBytes);
    if (osRecordType.size() == 0 || osFileRecords.size() == 0 ||
        osRecordBytes.size() == 0 || nRecordSize <= 0)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "One of RECORD_TYPE, FILE_RECORDS or RECORD_BYTES is missing");
        return FALSE;
    }
    CleanString(osRecordType);
    if (osRecordType.compare("FIXED_LENGTH") != 0)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "Only RECORD_TYPE=FIXED_LENGTH is supported");
        return FALSE;
    }

    CPLString osTable = oKeywords.GetKeyword( "^TABLE", "" );
    if (osTable.size() != 0)
        LoadTable(pszFilename, nRecordSize, "TABLE");
    else
    {
        VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
        if (fp == NULL)
            return FALSE;

        while(TRUE)
        {
            CPLPushErrorHandler(CPLQuietErrorHandler);
            const char* pszLine = CPLReadLine2L(fp, 256, NULL);
            CPLPopErrorHandler();
            CPLErrorReset();
            if (pszLine == NULL)
                break;
            char** papszTokens =
                CSLTokenizeString2( pszLine, " =", CSLT_HONOURSTRINGS );
            int nTokens = CSLCount(papszTokens);
            if (nTokens == 2 &&
                papszTokens[0][0] == '^' &&
                strstr(papszTokens[0], "TABLE") != NULL)
            {
                LoadTable(pszFilename, nRecordSize, papszTokens[0] + 1);
            }
            CSLDestroy(papszTokens);
            papszTokens = NULL;
        }
        VSIFCloseL(fp);
    }

    return nLayers != 0;
}
Example #7
0
int OGRPDSDataSource::LoadTable(const char* pszFilename,
                                     int nRecordSize,
                                     CPLString osTableID )
{

    CPLString osTableFilename;
    int nStartBytes;
    
    CPLString osTableLink = "^";
    osTableLink += osTableID;
    
    CPLString osTable = oKeywords.GetKeyword( osTableLink, "" );
    if( osTable[0] == '(' )
    {
        osTableFilename = GetKeywordSub(osTableLink, 1, "");
        CPLString osStartRecord = GetKeywordSub(osTableLink, 2, "");
        nStartBytes = (atoi(osStartRecord.c_str()) - 1) * nRecordSize;
        if (osTableFilename.size() == 0 || osStartRecord.size() == 0 ||
            nStartBytes < 0)
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "Cannot parse %s line", osTableLink.c_str());
            return FALSE;
        }
        CPLString osTPath = CPLGetPath(pszFilename);
        CleanString( osTableFilename );
        osTableFilename = CPLFormCIFilename( osTPath, osTableFilename, NULL );
    }
    else
    {
        osTableFilename = oKeywords.GetKeyword( osTableLink, "" );
        if (osTableFilename.size() != 0 && osTableFilename[0] >= '0' &&
            osTableFilename[0] <= '9')
        {
            nStartBytes = atoi(osTableFilename.c_str()) - 1;
            if (strstr(osTableFilename.c_str(), "<BYTES>") == NULL)
                nStartBytes *= nRecordSize;
            osTableFilename = pszFilename;
        }
        else
        {
            CPLString osTPath = CPLGetPath(pszFilename);
            CleanString( osTableFilename );
            osTableFilename = CPLFormCIFilename( osTPath, osTableFilename, NULL );
            nStartBytes = 0;
        }
    }

    CPLString osTableName = oKeywords.GetKeyword( MakeAttr(osTableID, "NAME"), "" );
    if (osTableName.size() == 0)
    {
        if (GetLayerByName(osTableID.c_str()) == NULL)
            osTableName = osTableID;
        else
            osTableName = CPLSPrintf("Layer_%d", nLayers+1);
    }
    CleanString(osTableName);
    CPLString osTableInterchangeFormat =
            oKeywords.GetKeyword( MakeAttr(osTableID, "INTERCHANGE_FORMAT"), "" );
    CPLString osTableRows = oKeywords.GetKeyword( MakeAttr(osTableID, "ROWS"), "" );
    int nRecords = atoi(osTableRows);
    if (osTableInterchangeFormat.size() == 0 ||
        osTableRows.size() == 0 || nRecords < 0)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "One of TABLE.INTERCHANGE_FORMAT or TABLE.ROWS is missing");
        return FALSE;
    }
    
    CleanString(osTableInterchangeFormat);
    if (osTableInterchangeFormat.compare("ASCII") != 0 &&
        osTableInterchangeFormat.compare("BINARY") != 0)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "Only INTERCHANGE_FORMAT=ASCII or BINARY is supported");
        return FALSE;
    }

    VSILFILE* fp = VSIFOpenL(osTableFilename, "rb");
    if (fp == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot open %s",
                 osTableFilename.c_str());
        return FALSE;
    }

    CPLString osTableStructure = oKeywords.GetKeyword( MakeAttr(osTableID, "^STRUCTURE"), "" );
    if (osTableStructure.size() != 0)
    {
        CPLString osTPath = CPLGetPath(pszFilename);
        CleanString( osTableStructure );
        osTableStructure = CPLFormCIFilename( osTPath, osTableStructure, NULL );
    }

    GByte* pabyRecord = (GByte*) VSIMalloc(nRecordSize + 1);
    if (pabyRecord == NULL)
    {
        VSIFCloseL(fp);
        return FALSE;
    }
    pabyRecord[nRecordSize] = 0;

    papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
    papoLayers[nLayers] = new OGRPDSLayer(osTableID, osTableName, fp,
                                         pszFilename,
                                         osTableStructure,
                                         nRecords, nStartBytes,
                                         nRecordSize, pabyRecord,
                                         osTableInterchangeFormat.compare("ASCII") == 0);
    nLayers++;

    return TRUE;
}
Example #8
0
static
CPLXMLNode * GDALWMSDatasetGetConfigFromURL(GDALOpenInfo *poOpenInfo)
{
    const char* pszBaseURL = poOpenInfo->pszFilename;
    if (EQUALN(pszBaseURL, "WMS:", 4))
        pszBaseURL += 4;

    CPLString osLayer = CPLURLGetValue(pszBaseURL, "LAYERS");
    CPLString osVersion = CPLURLGetValue(pszBaseURL, "VERSION");
    CPLString osSRS = CPLURLGetValue(pszBaseURL, "SRS");
    CPLString osCRS = CPLURLGetValue(pszBaseURL, "CRS");
    CPLString osBBOX = CPLURLGetValue(pszBaseURL, "BBOX");
    CPLString osFormat = CPLURLGetValue(pszBaseURL, "FORMAT");
    CPLString osTransparent = CPLURLGetValue(pszBaseURL, "TRANSPARENT");

    /* GDAL specific extensions to alter the default settings */
    CPLString osOverviewCount = CPLURLGetValue(pszBaseURL, "OVERVIEWCOUNT");
    CPLString osTileSize = CPLURLGetValue(pszBaseURL, "TILESIZE");
    CPLString osMinResolution = CPLURLGetValue(pszBaseURL, "MINRESOLUTION");
    CPLString osBBOXOrder = CPLURLGetValue(pszBaseURL, "BBOXORDER");

    CPLString osBaseURL = pszBaseURL;
    /* Remove all keywords to get base URL */

    osBaseURL = CPLURLAddKVP(osBaseURL, "VERSION", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "REQUEST", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "LAYERS", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "SRS", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "CRS", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "BBOX", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "FORMAT", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "TRANSPARENT", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "STYLES", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "WIDTH", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "HEIGHT", NULL);

    osBaseURL = CPLURLAddKVP(osBaseURL, "OVERVIEWCOUNT", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "TILESIZE", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "MINRESOLUTION", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "BBOXORDER", NULL);

    if (osBaseURL.size() > 0 && osBaseURL[osBaseURL.size() - 1] == '&')
        osBaseURL.resize(osBaseURL.size() - 1);

    if (osVersion.size() == 0)
        osVersion = "1.1.1";

    CPLString osSRSTag;
    CPLString osSRSValue;
    if(VersionStringToInt(osVersion.c_str())>= VersionStringToInt("1.3.0"))
    {
        if (osSRS.size())
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "WMS version 1.3 and above expects CRS however SRS was set instead.");
        }
        osSRSValue = osCRS;
        osSRSTag = "CRS";
    }
    else
    {
        if (osCRS.size())
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "WMS version 1.1.1 and below expects SRS however CRS was set instead.");
        }
        osSRSValue = osSRS;
        osSRSTag = "SRS";
    }

    if (osSRSValue.size() == 0)
        osSRSValue = "EPSG:4326";
    
    if (osBBOX.size() == 0)
    {
        if (osBBOXOrder.compare("yxYX") == 0)
            osBBOX = "-90,-180,90,180";
        else
            osBBOX = "-180,-90,180,90";
    }

    char** papszTokens = CSLTokenizeStringComplex(osBBOX, ",", 0, 0);
    if (CSLCount(papszTokens) != 4)
    {
        CSLDestroy(papszTokens);
        return NULL;
    }
    const char* pszMinX = papszTokens[0];
    const char* pszMinY = papszTokens[1];
    const char* pszMaxX = papszTokens[2];
    const char* pszMaxY = papszTokens[3];

    if (osBBOXOrder.compare("yxYX") == 0)
    {
        std::swap(pszMinX, pszMinY);
        std::swap(pszMaxX, pszMaxY);
    }

    double dfMinX = CPLAtofM(pszMinX);
    double dfMinY = CPLAtofM(pszMinY);
    double dfMaxX = CPLAtofM(pszMaxX);
    double dfMaxY = CPLAtofM(pszMaxY);

    if (dfMaxY <= dfMinY || dfMaxX <= dfMinX)
    {
        CSLDestroy(papszTokens);
        return NULL;
    }

    int nTileSize = atoi(osTileSize);
    if (nTileSize <= 128 || nTileSize > 2048)
        nTileSize = 1024;

    int nXSize, nYSize;

    int nOverviewCount = (osOverviewCount.size()) ? atoi(osOverviewCount) : 20;

    if (osMinResolution.size() != 0)
    {
        double dfMinResolution = CPLAtofM(osMinResolution);

        while (nOverviewCount > 20)
        {
            nOverviewCount --;
            dfMinResolution *= 2;
        }

        nXSize = (int) ((dfMaxX - dfMinX) / dfMinResolution + 0.5);
        nYSize = (int) ((dfMaxY - dfMinY) / dfMinResolution + 0.5);
    }
    else
    {
        double dfRatio = (dfMaxX - dfMinX) / (dfMaxY - dfMinY);
        if (dfRatio > 1)
        {
            nXSize = nTileSize;
            nYSize = (int) (nXSize / dfRatio);
        }
        else
        {
            nYSize = nTileSize;
            nXSize = (int) (nYSize * dfRatio);
        }

        if (nOverviewCount < 0 || nOverviewCount > 20)
            nOverviewCount = 20;

        nXSize = nXSize * (1 << nOverviewCount);
        nYSize = nYSize * (1 << nOverviewCount);
    }

    int bTransparent = osTransparent.size() ? CSLTestBoolean(osTransparent) : FALSE;

    if (osFormat.size() == 0)
    {
        if (!bTransparent)
        {
            osFormat = "image/jpeg";
        }
        else
        {
            osFormat = "image/png";
        }
    }

    char* pszEscapedURL = CPLEscapeString(osBaseURL.c_str(), -1, CPLES_XML);
    char* pszEscapedLayerURL = CPLEscapeString(osLayer.c_str(), -1, CPLES_URL);
    char* pszEscapedLayerXML = CPLEscapeString(pszEscapedLayerURL, -1, CPLES_XML);

    CPLString osXML = CPLSPrintf(
            "<GDAL_WMS>\n"
            "  <Service name=\"WMS\">\n"
            "    <Version>%s</Version>\n"
            "    <ServerUrl>%s</ServerUrl>\n"
            "    <Layers>%s</Layers>\n"
            "    <%s>%s</%s>\n"
            "    <ImageFormat>%s</ImageFormat>\n"
            "    <Transparent>%s</Transparent>\n"
            "    <BBoxOrder>%s</BBoxOrder>\n"
            "  </Service>\n"
            "  <DataWindow>\n"
            "    <UpperLeftX>%s</UpperLeftX>\n"
            "    <UpperLeftY>%s</UpperLeftY>\n"
            "    <LowerRightX>%s</LowerRightX>\n"
            "    <LowerRightY>%s</LowerRightY>\n"
            "    <SizeX>%d</SizeX>\n"
            "    <SizeY>%d</SizeY>\n"
            "  </DataWindow>\n"
            "  <BandsCount>%d</BandsCount>\n"
            "  <BlockSizeX>%d</BlockSizeX>\n"
            "  <BlockSizeY>%d</BlockSizeY>\n"
            "  <OverviewCount>%d</OverviewCount>\n"
            "</GDAL_WMS>\n",
            osVersion.c_str(),
            pszEscapedURL,
            pszEscapedLayerXML,
            osSRSTag.c_str(),
            osSRSValue.c_str(),
            osSRSTag.c_str(),
            osFormat.c_str(),
            (bTransparent) ? "TRUE" : "FALSE",
            (osBBOXOrder.size()) ? osBBOXOrder.c_str() : "xyXY",
            pszMinX, pszMaxY, pszMaxX, pszMinY,
            nXSize, nYSize,
            (bTransparent) ? 4 : 3,
            nTileSize, nTileSize,
            nOverviewCount);

    CPLFree(pszEscapedURL);
    CPLFree(pszEscapedLayerURL);
    CPLFree(pszEscapedLayerXML);

    CSLDestroy(papszTokens);

    CPLDebug("WMS", "Opening WMS :\n%s", osXML.c_str());

    return CPLParseXMLString(osXML);
}