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 + -
显示快捷键?