Example #1
0
/**********************************************************************
 *                          SearchIndex()
 *
 * Search a TAB dataset's .IND file for pszVal in index nIndexNo
 **********************************************************************/
static int SearchIndex(const char *pszFname, int nIndexNo, const char *pszVal)
{
    TABFile     oTABFile;
    TABINDFile  *poINDFile;

    /*---------------------------------------------------------------------
     * Try to open source file
     *--------------------------------------------------------------------*/
    if (oTABFile.Open(pszFname, "rb") != 0)
    {
        printf("Failed to open %s as a TABFile.\n", pszFname);
        return -1;
    }

    /*---------------------------------------------------------------------
     * Fetch IND file handle
     *--------------------------------------------------------------------*/
    if ((poINDFile = oTABFile.GetINDFileRef()) == NULL)
    {
        printf("Dataset %s has no .IND file\n", pszFname);
        return -1;
    }

    /*---------------------------------------------------------------------
     * Search the index.
     * For now we search only 'char' index types!!!
     *--------------------------------------------------------------------*/
    GByte *pKey;
    int nRecordNo;

    pKey = poINDFile->BuildKey(nIndexNo, pszVal);
    nRecordNo = poINDFile->FindFirst(nIndexNo, pKey);

    if (nRecordNo < 1)
    {
        printf("Value '%s' not found in index #%d\n", pszVal, nIndexNo);
    }
    else
    {
        while(nRecordNo > 0)
        {
            printf("Record %d...\n", nRecordNo);

            nRecordNo = poINDFile->FindNext(nIndexNo, pKey);
        }
    }

    /*---------------------------------------------------------------------
     * Cleanup and exit.
     *--------------------------------------------------------------------*/
    oTABFile.Close();

    return 0;

}
Example #2
0
int OGRTABDataSource::Create( const char * pszName, char **papszOptions )

{
    CPLAssert(m_pszName == nullptr);

    m_pszName = CPLStrdup(pszName);
    m_papszOptions = CSLDuplicate(papszOptions);
    m_bUpdate = TRUE;

    const char *pszOpt = CSLFetchNameValue(papszOptions, "FORMAT");
    if( pszOpt != nullptr && EQUAL(pszOpt, "MIF") )
        m_bCreateMIF = TRUE;
    else if( EQUAL(CPLGetExtension(pszName),"mif") ||
             EQUAL(CPLGetExtension(pszName),"mid") )
        m_bCreateMIF = TRUE;

    if( (pszOpt = CSLFetchNameValue(papszOptions,"SPATIAL_INDEX_MODE")) != nullptr )
    {
        if( EQUAL(pszOpt, "QUICK") )
            m_bQuickSpatialIndexMode = TRUE;
        else if( EQUAL(pszOpt, "OPTIMIZED") )
            m_bQuickSpatialIndexMode = FALSE;
    }

    m_nBlockSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKSIZE", "512"));


    // Create a new empty directory.
    VSIStatBufL sStat;

    if( strlen(CPLGetExtension(pszName)) == 0 )
    {
        if( VSIStatL( pszName, &sStat ) == 0 )
        {
            if( !VSI_ISDIR(sStat.st_mode) )
            {
                CPLError(CE_Failure, CPLE_OpenFailed,
                         "Attempt to create dataset named %s,\n"
                         "but that is an existing file.",
                         pszName);
                return FALSE;
            }
        }
        else
        {
            if( VSIMkdir(pszName, 0755) != 0 )
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Unable to create directory %s.",
                         pszName);
                return FALSE;
            }
        }

        m_pszDirectory = CPLStrdup(pszName);
    }


    // Create a new single file.
    else
    {
        IMapInfoFile *poFile = nullptr;
        const char *pszEncoding( CSLFetchNameValue( papszOptions, "ENCODING" ) );
        const char *pszCharset( IMapInfoFile::EncodingToCharset( pszEncoding ) );

        if( m_bCreateMIF )
        {
            poFile = new MIFFile;
            if( poFile->Open(m_pszName, TABWrite, FALSE, pszCharset) != 0 )
            {
                delete poFile;
                return FALSE;
            }
        }
        else
        {
            TABFile *poTabFile = new TABFile;
            if( poTabFile->Open(m_pszName, TABWrite, FALSE,
                                m_nBlockSize, pszCharset) != 0 )
            {
                delete poTabFile;
                return FALSE;
            }
            poFile = poTabFile;
        }

        m_nLayerCount = 1;
        m_papoLayers = static_cast<IMapInfoFile **>(CPLMalloc(sizeof(void *)));
        m_papoLayers[0] = poFile;

        m_pszDirectory = CPLStrdup(CPLGetPath(pszName));
        m_bSingleFile = TRUE;
    }

    return TRUE;
}
Example #3
0
OGRLayer *
OGRTABDataSource::ICreateLayer( const char *pszLayerName,
                                OGRSpatialReference *poSRSIn,
                                OGRwkbGeometryType /* eGeomTypeIn */,
                                char **papszOptions )

{
    if( !m_bUpdate )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                    "Cannot create layer on read-only dataset.");
        return nullptr;
    }

    // If it is a single file mode file, then we may have already
    // instantiated the low level layer.   We would just need to
    // reset the coordinate system and (potentially) bounds.
    IMapInfoFile *poFile = nullptr;
    char *pszFullFilename = nullptr;

    const char *pszEncoding = CSLFetchNameValue( papszOptions, "ENCODING" );
    const char *pszCharset( IMapInfoFile::EncodingToCharset( pszEncoding ) );


    if( m_bSingleFile )
    {
        if( m_bSingleLayerAlreadyCreated )
        {
            CPLError(
                CE_Failure, CPLE_AppDefined,
                "Unable to create new layers in this single file dataset.");
            return nullptr;
        }

        m_bSingleLayerAlreadyCreated = TRUE;

        poFile = (IMapInfoFile *) m_papoLayers[0];
        if( pszEncoding )
            poFile->SetCharset( pszCharset );
    }

    else
    {
        if( m_bCreateMIF )
        {
            pszFullFilename =
                CPLStrdup(CPLFormFilename(m_pszDirectory, pszLayerName, "mif"));

            poFile = new MIFFile;

            if( poFile->Open(pszFullFilename, TABWrite,
                             FALSE, pszCharset) != 0 )
            {
                CPLFree(pszFullFilename);
                delete poFile;
                return nullptr;
            }
        }
        else
        {
            pszFullFilename =
                CPLStrdup(CPLFormFilename(m_pszDirectory, pszLayerName, "tab"));

            TABFile *poTABFile = new TABFile;

            if( poTABFile->Open(pszFullFilename, TABWrite, FALSE,
                                m_nBlockSize, pszCharset) != 0 )
            {
                CPLFree(pszFullFilename);
                delete poTABFile;
                return nullptr;
            }
            poFile = poTABFile;
        }

        m_nLayerCount++;
        m_papoLayers = static_cast<IMapInfoFile **>(
            CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount));
        m_papoLayers[m_nLayerCount-1] = poFile;

        CPLFree(pszFullFilename);
    }

    poFile->SetDescription(poFile->GetName());

    // Assign the coordinate system (if provided) and set
    // reasonable bounds.
    if( poSRSIn != nullptr )
    {
        poFile->SetSpatialRef(poSRSIn);
        // SetSpatialRef() has cloned the passed geometry
        poFile->GetLayerDefn()->GetGeomFieldDefn(0)->SetSpatialRef(
            poFile->GetSpatialRef());
    }

    // Pull out the bounds if supplied
    const char *pszOpt = nullptr;
    if( (pszOpt = CSLFetchNameValue(papszOptions, "BOUNDS")) != nullptr ) {
        double dfBounds[4];
        if( CPLsscanf(pszOpt, "%lf,%lf,%lf,%lf", &dfBounds[0],
                                          &dfBounds[1],
                                          &dfBounds[2],
                                          &dfBounds[3]) != 4 )
        {
            CPLError(
                CE_Failure, CPLE_IllegalArg,
                "Invalid BOUNDS parameter, expected min_x,min_y,max_x,max_y");
        }
        else
        {
            poFile->SetBounds(dfBounds[0], dfBounds[1], dfBounds[2],
                              dfBounds[3]);
        }
    }

    if( !poFile->IsBoundsSet() && !m_bCreateMIF )
    {
        if( poSRSIn != nullptr && poSRSIn->GetRoot() != nullptr &&
            EQUAL(poSRSIn->GetRoot()->GetValue(),"GEOGCS") )
            poFile->SetBounds(-1000, -1000, 1000, 1000);
        else
            poFile->SetBounds(-30000000, -15000000, 30000000, 15000000);
    }

    if(m_bQuickSpatialIndexMode == TRUE &&
       poFile->SetQuickSpatialIndexMode(TRUE) != 0)
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Setting Quick Spatial Index Mode failed.");
    }
    else if(m_bQuickSpatialIndexMode == FALSE &&
            poFile->SetQuickSpatialIndexMode(FALSE) != 0)
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Setting Normal Spatial Index Mode failed.");
    }

    return poFile;
}