Пример #1
0
OGRLayer *
OGRTABDataSource::ICreateLayer( const char *pszLayerName,
                                OGRSpatialReference *poSRSIn,
                                OGRwkbGeometryType /* eGeomTypeIn */,
                                char **papszOptions )

{
    if( !m_bUpdate )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                    "Cannot create layer on read-only dataset.");
        return nullptr;
    }

    // If it is 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.
    IMapInfoFile *poFile = nullptr;
    char *pszFullFilename = nullptr;

    const char *pszEncoding = CSLFetchNameValue( papszOptions, "ENCODING" );
    const char *pszCharset( IMapInfoFile::EncodingToCharset( pszEncoding ) );


    if( m_bSingleFile )
    {
        if( m_bSingleLayerAlreadyCreated )
        {
            CPLError(
                CE_Failure, CPLE_AppDefined,
                "Unable to create new layers in this single file dataset.");
            return nullptr;
        }

        m_bSingleLayerAlreadyCreated = TRUE;

        poFile = (IMapInfoFile *) m_papoLayers[0];
        if( pszEncoding )
            poFile->SetCharset( pszCharset );
    }

    else
    {
        if( m_bCreateMIF )
        {
            pszFullFilename =
                CPLStrdup(CPLFormFilename(m_pszDirectory, pszLayerName, "mif"));

            poFile = new MIFFile;

            if( poFile->Open(pszFullFilename, TABWrite,
                             FALSE, pszCharset) != 0 )
            {
                CPLFree(pszFullFilename);
                delete poFile;
                return nullptr;
            }
        }
        else
        {
            pszFullFilename =
                CPLStrdup(CPLFormFilename(m_pszDirectory, pszLayerName, "tab"));

            TABFile *poTABFile = new TABFile;

            if( poTABFile->Open(pszFullFilename, TABWrite, FALSE,
                                m_nBlockSize, pszCharset) != 0 )
            {
                CPLFree(pszFullFilename);
                delete poTABFile;
                return nullptr;
            }
            poFile = poTABFile;
        }

        m_nLayerCount++;
        m_papoLayers = static_cast<IMapInfoFile **>(
            CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount));
        m_papoLayers[m_nLayerCount-1] = poFile;

        CPLFree(pszFullFilename);
    }

    poFile->SetDescription(poFile->GetName());

    // Assign the coordinate system (if provided) and set
    // reasonable bounds.
    if( poSRSIn != nullptr )
    {
        poFile->SetSpatialRef(poSRSIn);
        // SetSpatialRef() has cloned the passed geometry
        poFile->GetLayerDefn()->GetGeomFieldDefn(0)->SetSpatialRef(
            poFile->GetSpatialRef());
    }

    // Pull out the bounds if supplied
    const char *pszOpt = nullptr;
    if( (pszOpt = CSLFetchNameValue(papszOptions, "BOUNDS")) != nullptr ) {
        double dfBounds[4];
        if( CPLsscanf(pszOpt, "%lf,%lf,%lf,%lf", &dfBounds[0],
                                          &dfBounds[1],
                                          &dfBounds[2],
                                          &dfBounds[3]) != 4 )
        {
            CPLError(
                CE_Failure, CPLE_IllegalArg,
                "Invalid BOUNDS parameter, expected min_x,min_y,max_x,max_y");
        }
        else
        {
            poFile->SetBounds(dfBounds[0], dfBounds[1], dfBounds[2],
                              dfBounds[3]);
        }
    }

    if( !poFile->IsBoundsSet() && !m_bCreateMIF )
    {
        if( poSRSIn != nullptr && poSRSIn->GetRoot() != nullptr &&
            EQUAL(poSRSIn->GetRoot()->GetValue(),"GEOGCS") )
            poFile->SetBounds(-1000, -1000, 1000, 1000);
        else
            poFile->SetBounds(-30000000, -15000000, 30000000, 15000000);
    }

    if(m_bQuickSpatialIndexMode == TRUE &&
       poFile->SetQuickSpatialIndexMode(TRUE) != 0)
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Setting Quick Spatial Index Mode failed.");
    }
    else if(m_bQuickSpatialIndexMode == FALSE &&
            poFile->SetQuickSpatialIndexMode(FALSE) != 0)
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Setting Normal Spatial Index Mode failed.");
    }

    return poFile;
}
Пример #2
0
int OGRTABDataSource::Open( GDALOpenInfo *poOpenInfo, int bTestOpen )

{
    CPLAssert(m_pszName == nullptr);

    m_pszName = CPLStrdup(poOpenInfo->pszFilename);
    m_bUpdate = poOpenInfo->eAccess == GA_Update;

    // If it is a file, try to open as a Mapinfo file.
    if( !poOpenInfo->bIsDirectory )
    {
        IMapInfoFile *poFile =
            IMapInfoFile::SmartOpen(m_pszName, m_bUpdate, bTestOpen);
        if( poFile == nullptr )
            return FALSE;

        poFile->SetDescription(poFile->GetName());

        m_nLayerCount = 1;
        m_papoLayers = static_cast<IMapInfoFile **>(CPLMalloc(sizeof(void *)));
        m_papoLayers[0] = poFile;

        m_pszDirectory = CPLStrdup(CPLGetPath(m_pszName));

        m_bSingleFile = TRUE;
        m_bSingleLayerAlreadyCreated = TRUE;
    }

    // Otherwise, we need to scan the whole directory for files
    // ending in .tab or .mif.
    else
    {
        char **papszFileList = VSIReadDir(m_pszName);

        m_pszDirectory = CPLStrdup(m_pszName);

        for( int iFile = 0;
             papszFileList != nullptr && papszFileList[iFile] != nullptr;
             iFile++ )
        {
            const char *pszExtension = CPLGetExtension(papszFileList[iFile]);

            if( !EQUAL(pszExtension, "tab") && !EQUAL(pszExtension, "mif") )
                continue;

            char *pszSubFilename = CPLStrdup(
                CPLFormFilename(m_pszDirectory, papszFileList[iFile], nullptr));

            IMapInfoFile *poFile =
                IMapInfoFile::SmartOpen(pszSubFilename, m_bUpdate, bTestOpen);
            CPLFree(pszSubFilename);

            if( poFile == nullptr )
            {
                CSLDestroy(papszFileList);
                return FALSE;
            }
            poFile->SetDescription( poFile->GetName() );

            m_nLayerCount++;
            m_papoLayers = static_cast<IMapInfoFile **>(
                CPLRealloc(m_papoLayers,sizeof(void *) * m_nLayerCount));
            m_papoLayers[m_nLayerCount-1] = poFile;
        }

        CSLDestroy(papszFileList);

        if( m_nLayerCount == 0 )
        {
            if( !bTestOpen )
                CPLError(CE_Failure, CPLE_OpenFailed,
                         "No mapinfo files found in directory %s.",
                         m_pszDirectory);

            return FALSE;
        }
    }

    return TRUE;
}