Ejemplo n.º 1
0
/**********************************************************************
 *                          CreateIndex()
 *
 * Create index for specified field in an existing TAB dataset.
 **********************************************************************/
static int CreateIndex(const char *pszSrcFname, const char *pszField)
{
    IMapInfoFile *poSrcFile = NULL;
    int         nFeatureId, iField;
    TABFeature *poFeature;
    TABINDFile *poINDFile;

    /*---------------------------------------------------------------------
     * Try to open source file
     *--------------------------------------------------------------------*/
    if ((poSrcFile = IMapInfoFile::SmartOpen(pszSrcFname)) == NULL)
    {
        printf("Failed to open %s\n", pszSrcFname);
        return -1;
    }

    if (poSrcFile->GetFileClass() != TABFC_TABFile)
    {
        printf("Indexes cannot be added to this type of TAB datasets\n");
        poSrcFile->Close();
        delete poSrcFile;
        return -1;
    }

    /*---------------------------------------------------------------------
     * Make sure field exists and is not already indexed
     *--------------------------------------------------------------------*/
    OGRFeatureDefn *poDefn = poSrcFile->GetLayerDefn();
    if ( poDefn == NULL ||
         (iField = poDefn->GetFieldIndex(pszField)) == -1 ||
         poSrcFile->IsFieldIndexed(iField))
    {
        printf("Cannot create index: field '%s' not found or is already indexed.\n", 
               pszField);
        poSrcFile->Close();
        delete poSrcFile;
        return -1;
    }

    /*---------------------------------------------------------------------
     * Things seem OK... open IND file for update
     * (Note that TABINDFile automagically adjusts file extension)
     *--------------------------------------------------------------------*/
    poINDFile = new TABINDFile; 
    if ( poINDFile->Open(pszSrcFname, "r+", TRUE) != 0 &&
         poINDFile->Open(pszSrcFname, "w", TRUE) != 0)
    {
        printf("Unable to create IND file for %s.\n", pszSrcFname);
        delete poINDFile;
        poSrcFile->Close();
        delete poSrcFile;
        return -1;
    }

    int nNewIndexNo = -1;
    OGRFieldDefn *poFieldDefn = poDefn->GetFieldDefn(iField);
    TABFieldType eFieldType = poSrcFile->GetNativeFieldType(iField);
    if (poFieldDefn == NULL ||
        (nNewIndexNo = poINDFile->CreateIndex(eFieldType,
                                              poFieldDefn->GetWidth()) ) < 1)
    {
        // Failed... an error has already been reported.
        delete poINDFile;
        poSrcFile->Close();
        delete poSrcFile;
        return -1;
    }

    printf("Index number %d will be created for field %s...\n\n"
           "This program does not update the TAB header file (yet!) so you \n"
           "should edit %s and add 'Index %d' at the end of the definition \n"
           "of field %s.\n\n",
           nNewIndexNo, pszField, pszSrcFname, nNewIndexNo, pszField);

    /*---------------------------------------------------------------------
     * Add index entries until we reach EOF
     *--------------------------------------------------------------------*/
    nFeatureId = -1;
    while ( (nFeatureId = poSrcFile->GetNextFeatureId(nFeatureId)) != -1 )
    {
        poFeature = poSrcFile->GetFeatureRef(nFeatureId);
        if (poFeature)
        {
            GByte *pKey = NULL;
            switch(eFieldType)
            {
              case TABFChar:
                pKey = poINDFile->BuildKey(nNewIndexNo, 
                                        poFeature->GetFieldAsString(iField));
                break;
              case TABFInteger:
              case TABFSmallInt:
                pKey = poINDFile->BuildKey(nNewIndexNo, 
                                        poFeature->GetFieldAsInteger(iField));
                break;
              case TABFDecimal:
              case TABFFloat:
              case TABFLogical:
                pKey = poINDFile->BuildKey(nNewIndexNo, 
                                        poFeature->GetFieldAsDouble(iField));
                break;
              default:
              case TABFDate:
                CPLAssert(FALSE); // Unsupported for now.
            }

            if (poINDFile->AddEntry(nNewIndexNo, pKey, nFeatureId) != 0)
                return -1;
        }
        else
            break;      // GetFeatureRef() failed: Abort the loop
    }

    /*---------------------------------------------------------------------
     * Cleanup and exit.
     *--------------------------------------------------------------------*/
    poINDFile->Close();
    delete poINDFile;

    poSrcFile->Close();
    delete poSrcFile;

    MITABFreeCoordSysTable();

    return 0;
}
Ejemplo n.º 2
0
OGRErr OGRMILayerAttrIndex::LoadConfigFromXML(const char* pszRawXML)

{
/* -------------------------------------------------------------------- */
/*      Parse the XML.                                                  */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRoot = CPLParseXMLString( pszRawXML );

    if( psRoot == nullptr )
        return OGRERR_FAILURE;

/* -------------------------------------------------------------------- */
/*      Open the index file.                                            */
/* -------------------------------------------------------------------- */
    poINDFile = new TABINDFile();

    if (pszMIINDFilename == nullptr)
        pszMIINDFilename = CPLStrdup(CPLGetXMLValue(psRoot,"MIIDFilename",""));

    if( pszMIINDFilename == nullptr )
        return OGRERR_FAILURE;

    /* NOTE: Replaced r+ with r according to explanation in Ticket #1620.
     * This change has to be observed if it doesn't cause any
     * problems in future. (mloskot)
     */
    if( poINDFile->Open( pszMIINDFilename, "r" ) != 0 )
    {
        CPLDestroyXMLNode( psRoot );
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to open index file %s.",
                  pszMIINDFilename );
        return OGRERR_FAILURE;
    }
/* -------------------------------------------------------------------- */
/*      Process each attrindex.                                         */
/* -------------------------------------------------------------------- */
    for( CPLXMLNode *psAttrIndex = psRoot->psChild;
         psAttrIndex != nullptr;
         psAttrIndex = psAttrIndex->psNext )
    {
        if( psAttrIndex->eType != CXT_Element
            || !EQUAL(psAttrIndex->pszValue,"OGRMIAttrIndex") )
            continue;

        int iField = atoi(CPLGetXMLValue(psAttrIndex,"FieldIndex","-1"));
        int iIndexIndex = atoi(CPLGetXMLValue(psAttrIndex,"IndexIndex","-1"));

        if( iField == -1 || iIndexIndex == -1 )
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Skipping corrupt OGRMIAttrIndex entry." );
            continue;
        }

        AddAttrInd( iField, iIndexIndex );
    }

    CPLDestroyXMLNode( psRoot );

    CPLDebug( "OGR", "Restored %d field indexes for layer %s from %s on %s.",
              nIndexCount, poLayer->GetLayerDefn()->GetName(),
              pszMetadataFilename ? pszMetadataFilename : "--unknown--",
              pszMIINDFilename );

    return OGRERR_NONE;
}
Ejemplo n.º 3
0
OGRErr OGRMILayerAttrIndex::CreateIndex( int iField )

{
/* -------------------------------------------------------------------- */
/*      Do we have an open .ID file yet?  If not, create it now.        */
/* -------------------------------------------------------------------- */
    if( poINDFile == NULL )
    {
        poINDFile = new TABINDFile();
        if( poINDFile->Open( pszMIINDFilename, "w+" ) != 0 )
        {
            delete poINDFile;
            poINDFile = NULL;

            CPLError( CE_Failure, CPLE_OpenFailed,
                      "Failed to create %s.",
                      pszMIINDFilename );
            return OGRERR_FAILURE;
        }
    }
    else if (bINDAsReadOnly)
    {
        poINDFile->Close();
        if( poINDFile->Open( pszMIINDFilename, "r+" ) != 0 )
        {
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "Failed to open %s as write-only.",
                      pszMIINDFilename );

            if( poINDFile->Open( pszMIINDFilename, "r" ) != 0 )
            {
                CPLError( CE_Failure, CPLE_OpenFailed,
                      "Cannot re-open %s as read-only.",
                      pszMIINDFilename );
                delete poINDFile;
                poINDFile = NULL;
            }

            return OGRERR_FAILURE;
        }
        else
        {
            bINDAsReadOnly = FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Do we have this field indexed already?                          */
/* -------------------------------------------------------------------- */
    OGRFieldDefn *poFldDefn=poLayer->GetLayerDefn()->GetFieldDefn(iField);

    for( int i = 0; i < nIndexCount; i++ )
    {
        if( papoIndexList[i]->iField == iField )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "It seems we already have an index for field %d/%s\n"
                      "of layer %s.",
                      iField, poFldDefn->GetNameRef(),
                      poLayer->GetLayerDefn()->GetName() );
            return OGRERR_FAILURE;
        }
    }

/* -------------------------------------------------------------------- */
/*      What is the corresponding field type in TAB?  Note that we      */
/*      don't allow indexing of any of the list types.                  */
/* -------------------------------------------------------------------- */
    TABFieldType eTABFT;
    int           nFieldWidth = 0;

    switch( poFldDefn->GetType() )
    {
      case OFTInteger:
        eTABFT = TABFInteger;
        break;

      case OFTReal:
        eTABFT = TABFFloat;
        break;

      case OFTString:
        eTABFT = TABFChar;
        if( poFldDefn->GetWidth() > 0 )
            nFieldWidth = poFldDefn->GetWidth();
        else
            nFieldWidth = 64;
        break;

      default:
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Indexing not support for the field type of field %s.",
                  poFldDefn->GetNameRef() );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Create the index.                                               */
/* -------------------------------------------------------------------- */
    int iINDIndex;

    iINDIndex = poINDFile->CreateIndex( eTABFT, nFieldWidth );

    // CreateIndex() reports it's own errors.
    if( iINDIndex < 0 )
        return OGRERR_FAILURE;

    AddAttrInd( iField, iINDIndex );

    bUnlinkINDFile = FALSE;

/* -------------------------------------------------------------------- */
/*      Save the new configuration.                                     */
/* -------------------------------------------------------------------- */
    return SaveConfigToXML();
}