int OGRTABDataSource::Create( const char * pszName, char **papszOptions ) { VSIStatBufL sStat; const char *pszOpt; CPLAssert( m_pszName == NULL ); m_pszName = CPLStrdup( pszName ); m_papszOptions = CSLDuplicate( papszOptions ); m_bUpdate = TRUE; if( (pszOpt=CSLFetchNameValue(papszOptions,"FORMAT")) != NULL && 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")) != NULL ) { if ( EQUAL(pszOpt, "QUICK") ) m_bQuickSpatialIndexMode = TRUE; else if ( EQUAL(pszOpt, "OPTIMIZED") ) m_bQuickSpatialIndexMode = FALSE; } /* -------------------------------------------------------------------- */ /* Create a new empty directory. */ /* -------------------------------------------------------------------- */ 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.\n", pszName ); return FALSE; } } else { if( VSIMkdir( pszName, 0755 ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to create directory %s.\n", pszName ); return FALSE; } } m_pszDirectory = CPLStrdup(pszName); } /* -------------------------------------------------------------------- */ /* Create a new single file. */ /* -------------------------------------------------------------------- */ else { IMapInfoFile *poFile; if( m_bCreateMIF ) poFile = new MIFFile; else poFile = new TABFile; if( poFile->Open( m_pszName, TABWrite, FALSE ) != 0 ) { delete poFile; return FALSE; } m_nLayerCount = 1; m_papoLayers = (IMapInfoFile **) CPLMalloc(sizeof(void*)); m_papoLayers[0] = poFile; m_pszDirectory = CPLStrdup( CPLGetPath(pszName) ); m_bSingleFile = TRUE; } return TRUE; }
OGRLayer * OGRTABDataSource::CreateLayer( const char * pszLayerName, OGRSpatialReference *poSRSIn, OGRwkbGeometryType /* eGeomTypeIn */, char ** /* papszOptions */ ) { IMapInfoFile *poFile; char *pszFullFilename; /* -------------------------------------------------------------------- */ /* If it's 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. */ /* -------------------------------------------------------------------- */ if( m_bSingleFile ) { if( m_bSingleLayerAlreadyCreated ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to create new layers in this single file dataset."); return NULL; } m_bSingleLayerAlreadyCreated = TRUE; poFile = (IMapInfoFile *) m_papoLayers[0]; } /* -------------------------------------------------------------------- */ /* We need to initially create the file, and add it as a layer. */ /* -------------------------------------------------------------------- */ else { if( m_bCreateMIF ) { pszFullFilename = CPLStrdup( CPLFormFilename( m_pszDirectory, pszLayerName, "mif" ) ); poFile = new MIFFile; } else { pszFullFilename = CPLStrdup( CPLFormFilename( m_pszDirectory, pszLayerName, "tab" ) ); poFile = new TABFile; } if( poFile->Open( pszFullFilename, "wb", FALSE ) != 0 ) { CPLFree( pszFullFilename ); delete poFile; return FALSE; } m_nLayerCount++; m_papoLayers = (IMapInfoFile **) CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount); m_papoLayers[m_nLayerCount-1] = poFile; CPLFree( pszFullFilename ); } /* -------------------------------------------------------------------- */ /* Assign the coordinate system (if provided) and set */ /* reasonable bounds. */ /* -------------------------------------------------------------------- */ if( poSRSIn != NULL ) poFile->SetSpatialRef( poSRSIn ); if( !poFile->IsBoundsSet() && !m_bCreateMIF ) { if( poSRSIn != NULL && poSRSIn->GetRoot() != NULL && EQUAL(poSRSIn->GetRoot()->GetValue(),"GEOGCS") ) poFile->SetBounds( -1000, -1000, 1000, 1000 ); else poFile->SetBounds( -30000000, -15000000, 30000000, 15000000 ); } if (m_bQuickSpatialIndexMode && poFile->SetQuickSpatialIndexMode() != 0) { CPLError( CE_Warning, CPLE_AppDefined, "Setting Quick Spatial Index Mode failed."); } return poFile; }
/********************************************************************** * IMapInfoFile::SmartOpen() * * Use this static method to automatically open any flavour of MapInfo * dataset. This method will detect the file type, create an object * of the right type, and open the file. * * Call GetFileClass() on the returned object if you need to find out * its exact type. (To access format-specific methods for instance) * * Returns the new object ptr. , or NULL if the open failed. **********************************************************************/ IMapInfoFile *IMapInfoFile::SmartOpen(const char *pszFname, GBool bTestOpenNoError /*=FALSE*/) { IMapInfoFile *poFile = NULL; int nLen = 0; if (pszFname) nLen = strlen(pszFname); if (nLen > 4 && (EQUAL(pszFname + nLen-4, ".MIF") || EQUAL(pszFname + nLen-4, ".MID") ) ) { /*------------------------------------------------------------- * MIF/MID file *------------------------------------------------------------*/ poFile = new MIFFile; } else if (nLen > 4 && EQUAL(pszFname + nLen-4, ".TAB")) { /*------------------------------------------------------------- * .TAB file ... is it a TABFileView or a TABFile? * We have to read the .tab header to find out. *------------------------------------------------------------*/ FILE *fp; const char *pszLine; char *pszAdjFname = CPLStrdup(pszFname); GBool bFoundFields = FALSE, bFoundView=FALSE, bFoundSeamless=FALSE; TABAdjustFilenameExtension(pszAdjFname); fp = VSIFOpen(pszAdjFname, "r"); while(fp && (pszLine = CPLReadLine(fp)) != NULL) { while (isspace((unsigned char)*pszLine)) pszLine++; if (EQUALN(pszLine, "Fields", 6)) bFoundFields = TRUE; else if (EQUALN(pszLine, "create view", 11)) bFoundView = TRUE; else if (EQUALN(pszLine, "\"\\IsSeamless\" = \"TRUE\"", 21)) bFoundSeamless = TRUE; } if (bFoundView) poFile = new TABView; else if (bFoundFields && bFoundSeamless) poFile = new TABSeamless; else if (bFoundFields) poFile = new TABFile; if (fp) VSIFClose(fp); CPLFree(pszAdjFname); } /*----------------------------------------------------------------- * Perform the open() call *----------------------------------------------------------------*/ if (poFile && poFile->Open(pszFname, "r", bTestOpenNoError) != 0) { delete poFile; poFile = NULL; } if (!bTestOpenNoError && poFile == NULL) { CPLError(CE_Failure, CPLE_FileIO, "%s could not be opened as a MapInfo dataset.", pszFname); } return poFile; }
/********************************************************************** * IMapInfoFile::SmartOpen() * * Use this static method to automatically open any flavor of MapInfo * dataset. This method will detect the file type, create an object * of the right type, and open the file. * * Call GetFileClass() on the returned object if you need to find out * its exact type. (To access format-specific methods for instance) * * Returns the new object ptr. , or NULL if the open failed. **********************************************************************/ IMapInfoFile *IMapInfoFile::SmartOpen(const char *pszFname, GBool bUpdate, GBool bTestOpenNoError /*=FALSE*/) { IMapInfoFile *poFile = nullptr; int nLen = 0; if (pszFname) nLen = static_cast<int>(strlen(pszFname)); if (nLen > 4 && (EQUAL(pszFname + nLen-4, ".MIF") || EQUAL(pszFname + nLen-4, ".MID") ) ) { /*------------------------------------------------------------- * MIF/MID file *------------------------------------------------------------*/ poFile = new MIFFile; } else if (nLen > 4 && EQUAL(pszFname + nLen-4, ".TAB")) { /*------------------------------------------------------------- * .TAB file ... is it a TABFileView or a TABFile? * We have to read the .tab header to find out. *------------------------------------------------------------*/ char *pszAdjFname = CPLStrdup(pszFname); GBool bFoundFields = FALSE; GBool bFoundView = FALSE; GBool bFoundSeamless = FALSE; TABAdjustFilenameExtension(pszAdjFname); VSILFILE *fp = VSIFOpenL(pszAdjFname, "r"); const char *pszLine = nullptr; while(fp && (pszLine = CPLReadLineL(fp)) != nullptr) { while (isspace(static_cast<unsigned char>(*pszLine))) pszLine++; if (STARTS_WITH_CI(pszLine, "Fields")) bFoundFields = TRUE; else if (STARTS_WITH_CI(pszLine, "create view")) bFoundView = TRUE; else if (STARTS_WITH_CI(pszLine, "\"\\IsSeamless\" = \"TRUE\"")) bFoundSeamless = TRUE; } if (bFoundView) poFile = new TABView; else if (bFoundFields && bFoundSeamless) poFile = new TABSeamless; else if (bFoundFields) poFile = new TABFile; if (fp) VSIFCloseL(fp); CPLFree(pszAdjFname); } /*----------------------------------------------------------------- * Perform the open() call *----------------------------------------------------------------*/ if (poFile && poFile->Open(pszFname, bUpdate ? TABReadWrite : TABRead, bTestOpenNoError) != 0) { delete poFile; poFile = nullptr; } if (!bTestOpenNoError && poFile == nullptr) { CPLError(CE_Failure, CPLE_FileIO, "%s could not be opened as a MapInfo dataset.", pszFname); } return poFile; }
/********************************************************************** * DumpCoordsys() * * Open a .TAB file and dump coordsys info **********************************************************************/ static int DumpCoordsys(const char *pszFname) { IMapInfoFile *poFile; double dXMin, dYMin, dXMax, dYMax; /*--------------------------------------------------------------------- * Try to open source file *--------------------------------------------------------------------*/ if ((poFile = IMapInfoFile::SmartOpen(pszFname)) == NULL) { printf("Failed to open %s\n", pszFname); return -1; } OGRSpatialReference *poSRS = poFile->GetSpatialRef(); char *pszCoordSys = MITABSpatialRef2CoordSys(poSRS); char *pszProjString=NULL; printf("CoordSys %s\n", pszCoordSys?pszCoordSys:"(null)"); if (poFile->GetBounds(dXMin, dYMin, dXMax, dYMax) == 0) { printf(" Bounds (%.15g %.15g) (%.15g %.15g)\n", dXMin, dYMin, dXMax, dYMax); printf(" dX dY = %.15g %.15g\n", dXMax - dXMin, dYMax - dYMin); } else { printf(" Bounds not available!\n"); } if (poSRS) { // poSRS->exportToWkt(&pszProjString); // printf(" WKT SRS = %s\n", pszProjString); // CPLFree(pszProjString); poSRS->exportToProj4(&pszProjString); printf(" PROJ4 SRS = %s\n", pszProjString); // Write bounds to a file and launch 'proj' to convert them to LAT/LON FILE *fpOut; if (pszProjString && (fpOut = fopen("/tmp/tttbounds.txt", "w"))) { fprintf(fpOut, "%.15g %.15g\n", dXMin, dYMin); fprintf(fpOut, "%.15g %.15g\n", dXMax, dYMax); fclose(fpOut); fflush(stdout); system(CPLSPrintf("proj -I %s /tmp/tttbounds.txt", pszProjString)); } } /*--------------------------------------------------------------------- * Cleanup and exit. *--------------------------------------------------------------------*/ CPLFree(pszProjString); poFile->Close(); delete poFile; return 0; }