ogrfmedatasource.cpp

来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 1,716 行 · 第 1/5 页

CPP
1,716
字号
/****************************************************************************** * $Id: ogrfmedatasource.cpp 10646 2007-01-18 02:38:10Z warmerdam $ * * Project:  FMEObjects Translator * Purpose:  Implementations of the OGRFMEDataSource class. * Author:   Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, 2001, 2002 Safe Software Inc. * All Rights Reserved * * This software may not be copied or reproduced, in all or in part,  * without the prior written consent of Safe Software Inc. * * The entire risk as to the results and performance of the software, * supporting text and other information contained in this file * (collectively called the "Software") is with the user.  Although * Safe Software Incorporated has used considerable efforts in preparing  * the Software, Safe Software Incorporated does not warrant the * accuracy or completeness of the Software. In no event will Safe Software  * Incorporated be liable for damages, including loss of profits or  * consequential damages, arising out of the use of the Software. ****************************************************************************/#include "fme2ogr.h"//#include "ogr2fme.h"#include "cpl_conv.h"#include "cpl_string.h"//#include "ogrfme_cdsys.h"#include "cpl_multiproc.h"#include <idialog.h>#include <ilogfile.h>#include <icrdsysmgr.h>const char* kPROVIDERNAME = "FME_OLEDB";CPL_CVSID("$Id: ogrfmedatasource.cpp 10646 2007-01-18 02:38:10Z warmerdam $");#ifdef WIN32#define FMEDLL_NAME "fme.dll"#define PATH_CHAR '\\'#else#define FMEDLL_NAME "libfmeobj.so"#define PATH_CHAR '/'#endifstatic IFMESession      *poSharedSession = NULL;static int               nSharedSessionRefCount = 0;static void             *hSessionMutex = NULL;typedef struct {    IFMEUniversalReader      *poReader;    char                     *pszReaderType;    char                     *pszDefinition;} CachedConnection;static int              nCachedConnectionCount = 0;static CachedConnection *pasCachedConnections = NULL;typedef struct {    OGREnvelope  sExtent;    char         *pszIndFile;    char         *pszCoordSys;    IFMESpatialIndex *poIndex;    OGRwkbGeometryType eBestGeomType;} CacheLayerInfo;/************************************************************************//*                             FME_Logger()                             *//*                                                                      *//*      Output that would normally go to the FME log file will          *//*      instead be redirected through this function.                    *//************************************************************************/void FME_Logger( FME_MsgLevel severity, const char *message ){    char *pszMessageCopy = CPLStrdup(message);    if( pszMessageCopy[strlen(pszMessageCopy)-1] == '\n' )        pszMessageCopy[strlen(pszMessageCopy)-1] = '\0';            CPLDebug( "FME_LOG", "%d:%s", severity, pszMessageCopy );    CPLFree( pszMessageCopy );}/************************************************************************//*                             GetTmpDir()                              *//************************************************************************/static const char *GetTmpDir(){    const char     *pszTmpDir;    pszTmpDir = getenv("OGRFME_TMPDIR");    if( pszTmpDir == NULL )        pszTmpDir = getenv("TMPDIR");    if( pszTmpDir == NULL )        pszTmpDir = getenv("TEMPDIR");    if( pszTmpDir == NULL ) //20020419 - ryan        pszTmpDir = getenv("TMP");    if( pszTmpDir == NULL )        pszTmpDir = getenv("TEMP");    if( pszTmpDir == NULL )    {#ifdef WIN32        pszTmpDir = "C:\\";#else        pszTmpDir = "/tmp";#endif    }    return pszTmpDir;}/************************************************************************//*                            BuildTmpNam()                             *//*                                                                      *//*      Create a basename for the temporary file for a given layer      *//*      on this dataset.                                                *//************************************************************************/static char *BuildTmpNam( const char *pszLayerName ){    int            i;    char           szFilename[2048];    VSIStatBuf     sStat;    const char     *pszTmpDir = GetTmpDir();/* -------------------------------------------------------------------- *//*      Look for an unused name.                                        *//* -------------------------------------------------------------------- */    for( i = -1; TRUE; i++ )    {        if( i == -1 )            sprintf( szFilename, "%s%c%s_%s",                      pszTmpDir, PATH_CHAR, kPROVIDERNAME, pszLayerName );        else            sprintf( szFilename, "%s%c%s_%s_%d",                      pszTmpDir, PATH_CHAR, kPROVIDERNAME, pszLayerName, i );                if( VSIStat( szFilename, &sStat ) != 0 )            break;    }    return CPLStrdup( szFilename );}/************************************************************************//*                          OGRFMEDataSource()                          *//************************************************************************/OGRFMEDataSource::OGRFMEDataSource(){    pszName = NULL;    pszDataset = NULL;    pszReaderName = NULL;    poSession = NULL;    poReader = NULL;    poFMEFeature = NULL;    nLayers = 0;    papoLayers = NULL;    poUserDirectives = NULL;    bUseCaching = FALSE;}/************************************************************************//*                         ~OGRFMEDataSource()                          *//************************************************************************/OGRFMEDataSource::~OGRFMEDataSource(){    CPLDebug( kPROVIDERNAME, "~OGRFMEDataSource(): %p", this );    if( poSharedSession == NULL )        return;    AcquireSession();/* -------------------------------------------------------------------- *//*      Destroy the layers, so we know we don't still have the          *//*      caches open when we dereference them.                           *//* -------------------------------------------------------------------- */    for( int i = 0; i < nLayers; i++ )        delete papoLayers[i];        CPLFree( papoLayers );/* -------------------------------------------------------------------- *//*      If we have a cached instances, decrement the reference count.   *//* -------------------------------------------------------------------- */#ifdef SUPPORT_PERSISTENT_CACHE    {        OGRFMECacheIndex   oCacheIndex(             CPLFormFilename(GetTmpDir(), "ogrfmeds", "ind" ) );        if( pszReaderName != NULL && nLayers > 0             && bUseCaching && oCacheIndex.Lock() && oCacheIndex.Load() )        {            CPLXMLNode        *psMatchDS = NULL;            psMatchDS = oCacheIndex.FindMatch( pszReaderName, pszDataset,                                                *poUserDirectives );            if( psMatchDS != NULL )                oCacheIndex.Dereference( psMatchDS );            if( oCacheIndex.ExpireOldCaches( poSession ) || psMatchDS != NULL )                oCacheIndex.Save();            oCacheIndex.Unlock();        }    }#endif /* def SUPPORT_PERSISTENT_CACHE *//* -------------------------------------------------------------------- *//*      Cleanup up various resources.                                   *//* -------------------------------------------------------------------- */    if( poFMEFeature != NULL )        poSession->destroyFeature( poFMEFeature );    if( poUserDirectives != NULL )        poSession->destroyStringArray( poUserDirectives );    if( poReader != NULL )    {        if( !IsPartOfConnectionCache( poReader ) )            poSession->destroyReader( poReader );        else            CPLDebug( kPROVIDERNAME, "Preserving cached reader on destructor");    }        if( poSession != NULL )    {        if( --nSharedSessionRefCount == 0 )        {#ifdef SUPPORT_CLEANUP_SESSION#ifdef SUPPORT_INDIRECT_FMEDLL            int (*pfnFME_destroySession)(void *);            pfnFME_destroySession = (int (*)(void*))                 CPLGetSymbol(FMEDLL_NAME, "FME_DestroySession" );            if( pfnFME_destroySession == NULL )                CPLError( CE_Warning, CPLE_AppDefined,                           "Failed to fetch FME_DestroySession entry point." );            else                pfnFME_destroySession( (void *) (&poSession) );#else            FME_destroySession( poSession );#endif // def SUPPORT_INDIRECT_FMEDLL            poSharedSession = NULL;#else // ndef SUPPORT_CLEANUP_SESSION            CPLDebug( kPROVIDERNAME, "no active datasources left, but preserving session." );#endif        }    }    CPLFree( pszName );    CPLFree( pszDataset );    CPLFree( pszReaderName );    ReleaseSession();}/************************************************************************//*                          PromptForSource()                           *//************************************************************************/char *OGRFMEDataSource::PromptForSource(){    IFMEDialog      *poDialog = NULL;    IFMEString      *poSourceFormat, *poSourceDSName;    char            *pszResult = NULL;    poSourceFormat = poSession->createString();    poSourceDSName = poSession->createString();    if( poSession->createDialog( poDialog ) != 0 )        return NULL;    poUserDirectives->append( "SPATIAL_SETTINGS" );    poUserDirectives->append( "no" );    if( poDialog->sourcePrompt( NULL, NULL, *poSourceFormat, *poSourceDSName,                                *poUserDirectives ) )    {        pszResult = CPLStrdup(CPLSPrintf("%s:%s",                                          poSourceFormat->data(),                                          poSourceDSName->data()));    }    poSession->destroyString( poSourceFormat );    poSession->destroyString( poSourceDSName );            return pszResult;}/************************************************************************//*                           ReadFileSource()                           *//************************************************************************/char *OGRFMEDataSource::ReadFileSource( const char *pszFilename ){    FILE            *fp;    char            **papszLines = NULL;    const char      *pszLine;/* -------------------------------------------------------------------- *//*      Read the definition file.                                       *//* -------------------------------------------------------------------- */    fp = VSIFOpen( pszFilename, "rt" );    if( fp == NULL )    {        CPLError( CE_Failure, CPLE_AppDefined,                   "Failed to open file %s.",                   pszFilename );        return NULL;    }    while( (pszLine = CPLReadLine(fp)) != NULL )    {        if( *pszLine != '#' )            papszLines = CSLAddString( papszLines, pszLine );    }    VSIFClose( fp );/* -------------------------------------------------------------------- *//*      verify minimal requirements.                                    *//* -------------------------------------------------------------------- */    if( CSLCount(papszLines) < 2 )    {        CPLError( CE_Failure, CPLE_AppDefined,                   "Insufficient lines in FME Data Definition file."                  "At least a readername and data source name is required." );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?