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;
}
Example #3
0
/**********************************************************************
 *                   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;
}
Example #4
0
/**********************************************************************
 *                   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;
}
Example #5
0
/**********************************************************************
 *                          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;
}