📄 ogrfmedatasource.cpp
字号:
/* -------------------------------------------------------------------- *//* Transfer attributes ... for numeric values assume the string *//* representation is appropriate, and automatically *//* translatable. Eventually we will need special handling for *//* array style fields. *//* -------------------------------------------------------------------- */ for( iAttr = 0; iAttr < poDefn->GetFieldCount(); iAttr++ ) { OGRFieldDefn *poField = poDefn->GetFieldDefn(iAttr); if( poSrcFeature->getAttribute( poField->GetNameRef(), *poFMEString ) == FME_TRUE ) { poFeature->SetField( iAttr, poFMEString->data() ); } }/* -------------------------------------------------------------------- *//* Translate the geometry. *//* -------------------------------------------------------------------- */ OGRGeometry *poOGRGeom = NULL; poOGRGeom = ProcessGeometry( poLayer, poSrcFeature, poLayer->GetLayerDefn()->GetGeomType() ); if( poOGRGeom != NULL ) poFeature->SetGeometryDirectly( poOGRGeom ); return poFeature;}/************************************************************************//* TestCapability() *//************************************************************************/int OGRFMEDataSource::TestCapability( const char * ){ return FALSE;}/************************************************************************//* OfferForConnectionCaching() *//* *//* Sometimes we want to keep a prototype reader open to *//* maintain a connection, for instance to SDE where creating *//* the connection is pretty expensive. *//************************************************************************/void OGRFMEDataSource::OfferForConnectionCaching(IFMEUniversalReader *poReader, const char *pszReaderType, const char *pszDataset){/* -------------------------------------------------------------------- *//* For now we only cache SDE readers. *//* -------------------------------------------------------------------- */ if( !EQUALN(pszReaderType,"SDE",3) && !EQUALN(pszReaderType,"ORACLE",6) ) return;/* -------------------------------------------------------------------- *//* We want to build a definition of this connection that *//* indicates a unique connection. For now we base it on the *//* Server, UserName, Password, and Instance values. We will *//* pick these all out of the RUNTIME_MACROS if present. *//* *//* First find the runtime macros. *//* -------------------------------------------------------------------- */ const char *pszRuntimeMacros = NULL; int i; for( i = 0; i < (int) poUserDirectives->entries()-1; i += 2 ) { if( EQUALN((const char *) (*poUserDirectives)(i),"RUNTIME_MACROS",14) ) pszRuntimeMacros = (*poUserDirectives)(i+1); } /* -------------------------------------------------------------------- *//* Break into name/value pairs. *//* -------------------------------------------------------------------- */ char **papszTokens = NULL; if( pszRuntimeMacros != NULL ) papszTokens = CSLTokenizeStringComplex( pszRuntimeMacros, ",", TRUE, TRUE);/* -------------------------------------------------------------------- *//* Look for Name values we want, and append them to the *//* definition string. *//* -------------------------------------------------------------------- */ char szDefinition[5000]; sprintf( szDefinition, "%s::", pszDataset ); for( i = 0; i < CSLCount(papszTokens)-1; i += 2 ) { if( strstr(papszTokens[i],"Server") != NULL || strstr(papszTokens[i],"Service") != NULL || strstr(papszTokens[i],"UserName") != NULL || strstr(papszTokens[i],"Password") != NULL || strstr(papszTokens[i],"Instance") != NULL ) { if( strlen(papszTokens[i+1]) + strlen(papszTokens[i]) + 20 < sizeof(szDefinition) - strlen(szDefinition) ) { sprintf( szDefinition + strlen(szDefinition), "%s=%s;", papszTokens[i], papszTokens[i+1] ); } } }/* -------------------------------------------------------------------- *//* Do we already have a reader cached for this definition? *//* -------------------------------------------------------------------- */ for( i = 0; i < nCachedConnectionCount; i++ ) { if( strcmp(szDefinition, pasCachedConnections[i].pszDefinition) == 0 ) return; } /* -------------------------------------------------------------------- *//* Added this reader to the cache. *//* -------------------------------------------------------------------- */ CPLDebug( kPROVIDERNAME, "Caching IFMEUniversalReader to maintain connection.\n" "ReaderType=%s, Definition=%s", pszReaderType, szDefinition ); nCachedConnectionCount++; pasCachedConnections = (CachedConnection *) CPLRealloc(pasCachedConnections, sizeof(CachedConnection) * nCachedConnectionCount); pasCachedConnections[nCachedConnectionCount-1].poReader = poReader; pasCachedConnections[nCachedConnectionCount-1].pszReaderType = CPLStrdup(pszReaderType); pasCachedConnections[nCachedConnectionCount-1].pszDefinition = CPLStrdup(szDefinition);}/************************************************************************//* IsPartOfConnectionCache() *//* *//* I this reader being used to maintain a connection cache? *//************************************************************************/int OGRFMEDataSource::IsPartOfConnectionCache( IFMEUniversalReader *poReader ){ int i; for( i = 0; i < nCachedConnectionCount; i++ ) if( poReader == pasCachedConnections[i].poReader ) return TRUE; return FALSE;}/************************************************************************//* AcquireSession() *//* *//* Get unique ownership of the FME session for this thread. *//************************************************************************/IFMESession *OGRFMEDataSource::AcquireSession(){ FME_MsgNum err;/* -------------------------------------------------------------------- *//* Create session mutex if we don't already have one. *//* -------------------------------------------------------------------- */ if( hSessionMutex == NULL ) { hSessionMutex = CPLCreateMutex(); CPLDebug( kPROVIDERNAME, "%p:Creating FME session, mutex=%d.", this, hSessionMutex ); }/* -------------------------------------------------------------------- *//* Try to acquire ownership of the session, even if the session *//* doesn't yet exist. *//* -------------------------------------------------------------------- */ else {#ifdef DEBUG_MUTEX CPLDebug( kPROVIDERNAME, "%p:Wait for session mutex.", this );#endif if( !CPLAcquireMutex( hSessionMutex, 5.0 ) ) { CPLDebug( kPROVIDERNAME, "%p:Failed to acquire session mutex in 5s.", this ); }#ifdef DEBUG_MUTEX else CPLDebug( kPROVIDERNAME, "%p:Got session mutex.", this );#endif }/* -------------------------------------------------------------------- *//* If the session doesn't exist, create it now. *//* -------------------------------------------------------------------- */ if( poSharedSession == NULL ) {#ifdef SUPPORT_INDIRECT_FMEDLL FME_MsgNum (*pfnFME_CreateSession)( void * ); pfnFME_CreateSession = (FME_MsgNum (*)(void*)) CPLGetSymbol( FMEDLL_NAME, "FME_CreateSession" ); if( pfnFME_CreateSession == NULL ) { CPLReleaseMutex( hSessionMutex ); CPLDebug( kPROVIDERNAME, "Unable to load FME_CreateSession from %s, skipping FME Driver.", FMEDLL_NAME ); return NULL; } err = pfnFME_CreateSession( (void *) (&poSharedSession) );#else err = FME_createSession(poSharedSession);#endif if( err ) { poSharedSession = NULL; CPLReleaseMutex( hSessionMutex ); CPLError( CE_Failure, CPLE_AppDefined, "Failed to create FMESession." ); return NULL; } // Dale Nov 26 '01 -- Set up to log "badnews" from FME // to help track down problems IFMEStringArray *poSessionDirectives = poSharedSession->createStringArray(); if( poSessionDirectives == NULL ) { err = 1; CPLError( CE_Warning, CPLE_AppDefined, "Something has gone wonky with createStringArray() on the IFMESession.\n" "Is it possible you built with gcc 3.2 on Linux? This seems problematic." ); } else { poSessionDirectives->append("FME_DEBUG"); poSessionDirectives->append("BADNEWS"); err = poSharedSession->init( poSessionDirectives ); poSharedSession->destroyStringArray( poSessionDirectives ); if( err ) { CPLError( CE_Warning, CPLE_AppDefined, "Failed to initialize FMESession.\n%s", poSharedSession->getLastErrorMsg()); } } if( err ) {#ifdef SUPPORT_INDIRECT_FMEDLL int (*pfnFME_destroySession)(void *); pfnFME_destroySession = (int (*)(void*)) CPLGetSymbol(FMEDLL_NAME, "FME_DestroySession" ); if( pfnFME_destroySession != NULL ) pfnFME_destroySession( (void *) (&poSharedSession) );#else FME_destroySession( poSharedSession );#endif // def SUPPORT_INDIRECT_FMEDLL poSharedSession = NULL; CPLReleaseMutex( hSessionMutex ); return NULL; } } return poSharedSession;}/************************************************************************//* ReleaseSession() *//* *//* Release the lock on the FME session. *//************************************************************************/void OGRFMEDataSource::ReleaseSession(){#ifdef DEBUG_MUTEX CPLDebug( kPROVIDERNAME, "%p:Release session mutex.", this );#endif CPLReleaseMutex( hSessionMutex );}/************************************************************************//* SerializeToXML() *//* *//* Convert the information about this datasource, and it's *//* layers into an XML format that can be stored in the *//* persistent feature cache index. *//************************************************************************/CPLXMLNode *OGRFMEDataSource::SerializeToXML(){ CPLXMLNode *psDS; CPLAssert( bUseCaching );/* -------------------------------------------------------------------- *//* Setup data source information. *//* -------------------------------------------------------------------- */ psDS = CPLCreateXMLNode( NULL, CXT_Element, "DataSource" ); CPLCreateXMLElementAndValue( psDS, "Driver", pszReaderName ); CPLCreateXMLElementAndValue( psDS, "DSName", pszDataset ); CPLCreateXMLElementAndValue( psDS, "RefCount", "0" ); CPLCreateXMLElementAndValue( psDS, "CreationTime", "0" ); CPLCreateXMLElementAndValue( psDS, "LastUseTime", "0" );/* -------------------------------------------------------------------- *//* Append all the FME user directives in force. *//* -------------------------------------------------------------------- */ CPLXMLNode *psUD; psUD = CPLCreateXMLNode( psDS, CXT_Element, "UserDirectives" ); for( int i = 0; i < (int) poUserDirectives->entries(); i++ ) CPLCreateXMLElementAndValue( psUD, "Directive", (*poUserDirectives)(i) );/* -------------------------------------------------------------------- *//* Now append all the layer information. *//* -------------------------------------------------------------------- */ for( int iLayer = 0; iLayer < nLayers; iLayer++ ) { OGRFMELayerCached * poLayer = (OGRFMELayerCached *) papoLayers[iLayer]; CPLXMLNode *psLayer; psLayer = poLayer->SerializeToXML(); CPLAddXMLChild( psDS, psLayer ); } return psDS;}/************************************************************************//* InitializeFromXML() *//************************************************************************/int OGRFMEDataSource::InitializeFromXML( CPLXMLNode *psDS ){ CPLAssert( bUseCaching );/* -----------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -