/********************************************************************** * DumpTabFile() * * Open a .TAB file and print all the geogr. objects found. **********************************************************************/ static int DumpTabFile(const char *pszFname) { IMapInfoFile *poFile; int nFeatureId; TABFeature *poFeature; /*--------------------------------------------------------------------- * Try to open source file *--------------------------------------------------------------------*/ if ((poFile = IMapInfoFile::SmartOpen(pszFname)) == NULL) { printf("Failed to open %s\n", pszFname); return -1; } poFile->Dump(); /*--------------------------------------------------------------------- * Check for indexed fields *--------------------------------------------------------------------*/ for(int iField=0; iField<poFile->GetLayerDefn()->GetFieldCount(); iField++) { if (poFile->IsFieldIndexed(iField)) printf(" Field %d is indexed\n", iField); } /*--------------------------------------------------------------------- * Read/Dump objects until EOF is reached *--------------------------------------------------------------------*/ nFeatureId = -1; while ( (nFeatureId = poFile->GetNextFeatureId(nFeatureId)) != -1 ) { poFeature = poFile->GetFeatureRef(nFeatureId); if (poFeature) { // poFeature->DumpReadable(stdout); printf("\nFeature %d:\n", nFeatureId); poFeature->DumpMID(); poFeature->DumpMIF(); } else break; // GetFeatureRef() failed: Abort the loop } /*--------------------------------------------------------------------- * Cleanup and exit. *--------------------------------------------------------------------*/ poFile->Close(); delete poFile; return 0; }
/********************************************************************** * Tab2Tab() * * Copy features from source dataset to a new dataset **********************************************************************/ static int Tab2Tab(const char *pszSrcFname, const char *pszDstFname, int nMaxFeatures, GBool bQuickSpatialIndexMode, GBool bOptSpatialIndexMode) { IMapInfoFile *poSrcFile = NULL, *poDstFile = NULL; int nFeatureId, iField, numFeatures=0; TABFeature *poFeature; double dXMin, dYMin, dXMax, dYMax; /*--------------------------------------------------------------------- * If there is a "micdsys.txt" in current directory then load it *--------------------------------------------------------------------*/ MITABLoadCoordSysTable("micdsys.txt"); /*--------------------------------------------------------------------- * Try to open source file *--------------------------------------------------------------------*/ if ((poSrcFile = IMapInfoFile::SmartOpen(pszSrcFname)) == NULL) { printf("Failed to open %s\n", pszSrcFname); return -1; } OGRFeatureDefn *poDefn = poSrcFile->GetLayerDefn(); /*--------------------------------------------------------------------- * The extension of the output filename tells us if we should create * a MIF or a TAB file for output. *--------------------------------------------------------------------*/ if (EQUAL(".mif", pszDstFname + strlen(pszDstFname)-4) || EQUAL(".mid", pszDstFname + strlen(pszDstFname)-4) ) { // Create a MIF file poDstFile = new MIFFile; } else { /*----------------------------------------------------------------- * Create a TAB dataset. * Find out if the file contains at least 1 unique field... if so we * will create a TABView instead of a TABFile *----------------------------------------------------------------*/ GBool bFoundUniqueField = FALSE; for(iField=0; iField< poDefn->GetFieldCount(); iField++) { if (poSrcFile->IsFieldUnique(iField)) bFoundUniqueField = TRUE; } if (bFoundUniqueField) poDstFile = new TABView; else poDstFile = new TABFile; } /*--------------------------------------------------------------------- * Try to open destination file *--------------------------------------------------------------------*/ if (poDstFile->Open(pszDstFname, "wb") != 0) { printf("Failed to open %s\n", pszDstFname); poSrcFile->Close(); delete poSrcFile; delete poDstFile; return -1; } if ( (bQuickSpatialIndexMode && poDstFile->SetQuickSpatialIndexMode(TRUE) != 0) || (bOptSpatialIndexMode && poDstFile->SetQuickSpatialIndexMode(FALSE) != 0) ) { printf("Failed setting Quick Spatial Index Mode (-q|-o) on %s\n", pszDstFname); poSrcFile->Close(); delete poSrcFile; poDstFile->Close(); delete poDstFile; return -1; } // Pass Proj. info directly // TABProjInfo sProjInfo; // if (poSrcFile->GetProjInfo(&sProjInfo) == 0) // poDstFile->SetProjInfo(&sProjInfo); OGRSpatialReference *poSR; poSR = poSrcFile->GetSpatialRef(); if( poSR != NULL ) { poDstFile->SetSpatialRef( poSR ); } // Set bounds (must be done after setting spatialref) if (poSrcFile->GetBounds(dXMin, dYMin, dXMax, dYMax) == 0) poDstFile->SetBounds(dXMin, dYMin, dXMax, dYMax); /*--------------------------------------------------------------------- * Pass compplete fields information *--------------------------------------------------------------------*/ for(iField=0; iField< poDefn->GetFieldCount(); iField++) { OGRFieldDefn *poFieldDefn = poDefn->GetFieldDefn(iField); poDstFile->AddFieldNative(poFieldDefn->GetNameRef(), poSrcFile->GetNativeFieldType(iField), poFieldDefn->GetWidth(), poFieldDefn->GetPrecision(), poSrcFile->IsFieldIndexed(iField), poSrcFile->IsFieldUnique(iField)); } /*--------------------------------------------------------------------- * Copy objects until EOF is reached *--------------------------------------------------------------------*/ nFeatureId = -1; while ( (nFeatureId = poSrcFile->GetNextFeatureId(nFeatureId)) != -1 && (nMaxFeatures < 1 || numFeatures++ < nMaxFeatures )) { poFeature = poSrcFile->GetFeatureRef(nFeatureId); if (poFeature) { // poFeature->DumpReadable(stdout); // poFeature->DumpMIF(); poDstFile->CreateFeature(poFeature); } else { printf( "Failed to read feature %d.\n", nFeatureId ); return -1; // GetFeatureRef() failed: Error } } /*--------------------------------------------------------------------- * Cleanup and exit. *--------------------------------------------------------------------*/ poDstFile->Close(); delete poDstFile; poSrcFile->Close(); delete poSrcFile; MITABFreeCoordSysTable(); return 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; }