/********************************************************************** * 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; }
/********************************************************************** * IMapInfoFile::ICreateFeature() * * Standard OGR CreateFeature implementation. This method is used * to create a new feature in current dataset **********************************************************************/ OGRErr IMapInfoFile::ICreateFeature(OGRFeature *poFeature) { TABFeature *poTABFeature = CreateTABFeature(poFeature); if( poTABFeature == nullptr ) /* MultiGeometry */ return OGRERR_NONE; OGRErr eErr = CreateFeature(poTABFeature); if( eErr == OGRERR_NONE ) poFeature->SetFID(poTABFeature->GetFID()); delete poTABFeature; return eErr; }
/********************************************************************** * DumpViaSpatialIndex() * * Open a .TAB file and print all the geogr. objects that match the * specified filter. Scanes the file via the spatial index. **********************************************************************/ static int DumpViaSpatialIndex(const char *pszFname, double dXMin, double dYMin, double dXMax, double dYMax) { IMapInfoFile *poFile; 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); } /*--------------------------------------------------------------------- * Set spatial filter *--------------------------------------------------------------------*/ OGRLinearRing oSpatialFilter; oSpatialFilter.setNumPoints(5); oSpatialFilter.setPoint(0, dXMin, dYMin); oSpatialFilter.setPoint(1, dXMax, dYMin); oSpatialFilter.setPoint(2, dXMax, dYMax); oSpatialFilter.setPoint(3, dXMin, dYMax); oSpatialFilter.setPoint(4, dXMin, dYMin); poFile->SetSpatialFilter( &oSpatialFilter ); /*--------------------------------------------------------------------- * Read/Dump objects until EOF is reached *--------------------------------------------------------------------*/ while ( (poFeature = (TABFeature*)poFile->GetNextFeature()) != NULL ) { // poFeature->DumpReadable(stdout); printf("\nFeature %ld:\n", poFeature->GetFID()); poFeature->DumpMID(); poFeature->DumpMIF(); } /*--------------------------------------------------------------------- * Cleanup and exit. *--------------------------------------------------------------------*/ poFile->Close(); delete poFile; return 0; }
/********************************************************************** * IMapInfoFile::CreateFeature() * * Standard OGR CreateFeature implementation. This method is used * to create a new feature in current dataset **********************************************************************/ OGRErr IMapInfoFile::CreateFeature(OGRFeature *poFeature) { TABFeature *poTABFeature; OGRGeometry *poGeom; OGRwkbGeometryType eGType; OGRErr eErr; TABPoint *poTABPointFeature = NULL; TABRegion *poTABRegionFeature = NULL; TABPolyline *poTABPolylineFeature = NULL; /*----------------------------------------------------------------- * MITAB won't accept new features unless they are in a type derived * from TABFeature... so we have to do our best to map to the right * feature type based on the geometry type. *----------------------------------------------------------------*/ poGeom = poFeature->GetGeometryRef(); if( poGeom != NULL ) eGType = poGeom->getGeometryType(); else eGType = wkbNone; switch( wkbFlatten(eGType) ) { /*------------------------------------------------------------- * POINT *------------------------------------------------------------*/ case wkbPoint: poTABFeature = new TABPoint(poFeature->GetDefnRef()); if(poFeature->GetStyleString()) { poTABPointFeature = (TABPoint*)poTABFeature; poTABPointFeature->SetSymbolFromStyleString( poFeature->GetStyleString()); } break; /*------------------------------------------------------------- * REGION *------------------------------------------------------------*/ case wkbPolygon: case wkbMultiPolygon: poTABFeature = new TABRegion(poFeature->GetDefnRef()); if(poFeature->GetStyleString()) { poTABRegionFeature = (TABRegion*)poTABFeature; poTABRegionFeature->SetPenFromStyleString( poFeature->GetStyleString()); poTABRegionFeature->SetBrushFromStyleString( poFeature->GetStyleString()); } break; /*------------------------------------------------------------- * LINE/PLINE/MULTIPLINE *------------------------------------------------------------*/ case wkbLineString: case wkbMultiLineString: poTABFeature = new TABPolyline(poFeature->GetDefnRef()); if(poFeature->GetStyleString()) { poTABPolylineFeature = (TABPolyline*)poTABFeature; poTABPolylineFeature->SetPenFromStyleString( poFeature->GetStyleString()); } break; /*------------------------------------------------------------- * Collection types that are not directly supported... convert * to multiple features in output file through recursive calls. *------------------------------------------------------------*/ case wkbGeometryCollection: case wkbMultiPoint: { OGRErr eStatus = OGRERR_NONE; int i; OGRGeometryCollection *poColl = (OGRGeometryCollection*)poGeom; OGRFeature *poTmpFeature = poFeature->Clone(); for (i=0; eStatus==OGRERR_NONE && i<poColl->getNumGeometries(); i++) { poTmpFeature->SetGeometry(poColl->getGeometryRef(i)); eStatus = CreateFeature(poTmpFeature); } delete poTmpFeature; return eStatus; } break; /*------------------------------------------------------------- * Unsupported type.... convert to MapInfo geometry NONE *------------------------------------------------------------*/ case wkbUnknown: default: poTABFeature = new TABFeature(poFeature->GetDefnRef()); break; } if( poGeom != NULL ) poTABFeature->SetGeometryDirectly(poGeom->clone()); for (int i=0; i< poFeature->GetDefnRef()->GetFieldCount(); i++) { poTABFeature->SetField(i,poFeature->GetRawFieldRef( i )); } eErr = CreateFeature(poTABFeature); delete poTABFeature; return eErr; }
/********************************************************************** * 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; }