📄 ogrfmedatasource.cpp
字号:
/* -------------------------------------------------------------------- *//* Is there a Coordsys statement in the user directives? *//* -------------------------------------------------------------------- */ OGRSpatialReference *poSRS = ExtractSRS(); CPLDebug( kPROVIDERNAME, "got the SRS parsed"); bCoordSysOverride = poSRS != NULL;/* -------------------------------------------------------------------- *//* Allocate an FME string, and feature for use here and *//* elsewhere. *//* -------------------------------------------------------------------- */ poFMEFeature = poSession->createFeature(); poFMEString = poSession->createString();/* -------------------------------------------------------------------- *//* Are we going to use the direct access DB mechanism, or the *//* spatiallly cached (dumb reader) mechanism. *//* -------------------------------------------------------------------- */ bUseCaching = !EQUALN(pszReaderName,"SDE",3) && !EQUALN(pszReaderName,"ORACLE",6);/* -------------------------------------------------------------------- *//* Is there already a cache for this dataset? If so, we will *//* use it. *//* -------------------------------------------------------------------- */#ifdef SUPPORT_PERSISTENT_CACHE OGRFMECacheIndex oCacheIndex( CPLFormFilename(GetTmpDir(), "ogrfmeds", "ind" ) ); CPLXMLNode *psMatchDS = NULL; if( bUseCaching && oCacheIndex.Lock() && oCacheIndex.Load() ) { int bNeedSave = oCacheIndex.ExpireOldCaches( poSession ); psMatchDS = oCacheIndex.FindMatch( pszReaderName, pszDataset, *poUserDirectives ); if( psMatchDS != NULL ) { oCacheIndex.Reference( psMatchDS ); oCacheIndex.Save(); psMatchDS = CPLCloneXMLTree( psMatchDS ); oCacheIndex.Unlock(); } else { if( bNeedSave ) oCacheIndex.Save(); oCacheIndex.Unlock(); } if( psMatchDS != NULL ) { if( InitializeFromXML( psMatchDS ) ) { CPLDestroyXMLNode( psMatchDS ); ReleaseSession(); return TRUE; } CPLDestroyXMLNode( psMatchDS ); } }#endif /* def SUPPORT_PERSISTENT_CACHE *//* -------------------------------------------------------------------- *//* Create a reader. *//* -------------------------------------------------------------------- */ IFMEStringArray *poParms = poSession->createStringArray(); for( i = 0; i < (int) poUserDirectives->entries(); i++ ) CPLDebug( kPROVIDERNAME, "oUserDirectives(%d) = '%s'", i, (*poUserDirectives)(i) ); poReader = poSession->createReader(pszReaderName, FME_FALSE, poUserDirectives); if( poReader == NULL ) { CPLFMEError( poSession, "Failed to create reader of type `%s'.\n", pszReaderName ); ReleaseSession(); return FALSE; } CPLDebug( kPROVIDERNAME, "%p:reader created.", this );/* -------------------------------------------------------------------- *//* Now try to open the dataset. *//* -------------------------------------------------------------------- */ err = poReader->open( pszDataset, *poParms ); if( err ) { CPLFMEError( poSession, "Failed to open dataset `%s' with reader of type `%s'.\n", pszDataset, pszReaderName ); ReleaseSession(); return FALSE; } CPLDebug( kPROVIDERNAME, "%p:reader opened.", this );/* -------------------------------------------------------------------- *//* There are some circumstances where we want to keep a *//* "connection" open for a data source. Offer this reader for *//* connection caching. *//* -------------------------------------------------------------------- */ OfferForConnectionCaching( poReader, pszReaderName, pszDataset );/* -------------------------------------------------------------------- *//* Create a layer for each schema feature. *//* -------------------------------------------------------------------- */ FME_Boolean eEndOfSchema; while( TRUE ) { err = poReader->readSchema( *poFMEFeature, eEndOfSchema ); if( err ) { CPLFMEError( poSession, "IFMEReader::readSchema() failed." ); ReleaseSession(); return FALSE; } if( eEndOfSchema == FME_TRUE ) break; CPLDebug( kPROVIDERNAME, "%p:readSchema() got %s.", this, poFMEFeature->getFeatureType() ); OGRFMELayer *poNewLayer = NULL; if( bUseCaching ) poNewLayer = new OGRFMELayerCached( this ); else poNewLayer = new OGRFMELayerDB( this, pszReaderName, pszDataset, poUserDirectives ); if( !poNewLayer->Initialize( poFMEFeature, poSRS ) ) { CPLDebug( kPROVIDERNAME, "%p:Initialize() failed.", this ); delete poNewLayer; ReleaseSession(); return FALSE; } papoLayers = (OGRFMELayer **) CPLRealloc(papoLayers, sizeof(void*) * ++nLayers ); papoLayers[nLayers-1] = poNewLayer; } poSession->destroyStringArray( poParms ); if( poSRS != NULL ) OSRDestroySpatialReference( poSRS ); CPLDebug( kPROVIDERNAME, "%p:schema read.", this );/* -------------------------------------------------------------------- *//* Do we want to build our own index/caches for each layer? *//* -------------------------------------------------------------------- */ if( bUseCaching ) BuildSpatialIndexes(); CPLDebug( kPROVIDERNAME, "%p:Open() successful.", this ); ReleaseSession();/* -------------------------------------------------------------------- *//* If we are caching, add this cache to the cache index. *//* -------------------------------------------------------------------- */#ifdef SUPPORT_PERSISTENT_CACHE if( bUseCaching && oCacheIndex.Lock() && oCacheIndex.Load() ) { CPLXMLNode *psXML = SerializeToXML(); oCacheIndex.Add( psXML ); // cache index takes ownership of tree oCacheIndex.Reference( psXML ); oCacheIndex.Save(); oCacheIndex.Unlock(); }#endif return TRUE;}/************************************************************************//* GetLayer() *//************************************************************************/OGRLayer *OGRFMEDataSource::GetLayer( int iLayer ){ if( iLayer < 0 || iLayer >= nLayers ) return NULL; else return papoLayers[iLayer];}/************************************************************************//* BuildSpatialIndexes() *//* *//* Import all the features, building per-layer spatial *//* caches with indexing. *//************************************************************************/void OGRFMEDataSource::BuildSpatialIndexes(){ CacheLayerInfo *pasCLI; int iLayer; pasCLI = (CacheLayerInfo *) CPLCalloc(sizeof(CacheLayerInfo),nLayers);/* -------------------------------------------------------------------- *//* Create index files with "temp file" names. *//* -------------------------------------------------------------------- */ for( iLayer = 0; iLayer < nLayers; iLayer++ ) { CacheLayerInfo *psCLI = pasCLI + iLayer; psCLI->pszCoordSys = NULL; psCLI->pszIndFile = BuildTmpNam( papoLayers[iLayer]->GetLayerDefn()->GetName() ); psCLI->poIndex = poSession->createSpatialIndex( psCLI->pszIndFile, "WRITE", NULL ); if( psCLI->poIndex == NULL || psCLI->poIndex->open() != 0 ) { CPLDebug( kPROVIDERNAME, "Serious error creating or opening spatial index ... bailing." ); return; } // our special marker meaning unset. psCLI->eBestGeomType = (OGRwkbGeometryType) 500; }/* -------------------------------------------------------------------- *//* Read all features, and store them into appropriate spatial *//* indexes. *//* -------------------------------------------------------------------- */ while( ReadFMEFeature() ) { CacheLayerInfo *psCLI = NULL; poFMEFeature->getFeatureType( *poFMEString ); for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(papoLayers[iLayer]->GetLayerDefn()->GetName(), poFMEString->data()) ) { psCLI = pasCLI + iLayer; break; } } if( psCLI == NULL ) { CPLDebug( "FME_LOG", "Skipping %s feature, doesn't match a layer.", poFMEString->data() ); continue; } psCLI->poIndex->store( *poFMEFeature ); // Aggregate to extents. FME_Real64 dfMinX, dfMaxX, dfMinY, dfMaxY; poFMEFeature->boundingBox( dfMinX, dfMaxX, dfMinY, dfMaxY ); if( psCLI->poIndex->entries() == 1 ) { psCLI->sExtent.MinX = dfMinX; psCLI->sExtent.MaxX = dfMaxX; psCLI->sExtent.MinY = dfMinY; psCLI->sExtent.MaxY = dfMaxY; } else { psCLI->sExtent.MinX = MIN(psCLI->sExtent.MinX,dfMinX); psCLI->sExtent.MaxX = MAX(psCLI->sExtent.MaxX,dfMaxX); psCLI->sExtent.MinY = MIN(psCLI->sExtent.MinY,dfMinY); psCLI->sExtent.MaxY = MAX(psCLI->sExtent.MaxY,dfMaxY); } // Update best geometry type to use based on this geometry. ClarifyGeometryClass( poFMEFeature, psCLI->eBestGeomType ); // Check on coordsys. if( poFMEFeature->getCoordSys() != NULL && strlen(poFMEFeature->getCoordSys()) > 0 ) { if( psCLI->pszCoordSys == NULL ) psCLI->pszCoordSys = CPLStrdup(poFMEFeature->getCoordSys()); else { if( !EQUAL(psCLI->pszCoordSys,poFMEFeature->getCoordSys()) ) CPLDebug( "FME_OLEDB", "Conflicting coordsys %s (vs. %s) on layer %s.", poFMEFeature->getCoordSys(), psCLI->pszCoordSys, papoLayers[iLayer]->GetLayerDefn()->GetName() ); } } }/* -------------------------------------------------------------------- *//* Close indexes and assign to layers. *//* -------------------------------------------------------------------- */ for( iLayer = 0; iLayer < nLayers; iLayer++ ) { OGRFMELayerCached * poLayer = (OGRFMELayerCached *) papoLayers[iLayer]; CacheLayerInfo *psCLI = pasCLI + iLayer; // If there are no features, we destroy the layer. if( psCLI->poIndex->entries() == 0 ) { CPLDebug( "FME_LOG", "Drop layer %s, there are not features.", poLayer->GetLayerDefn()->GetName() ); psCLI->poIndex->close(FME_TRUE); delete poLayer; papoLayers[iLayer] = NULL; } else { OGRSpatialReference *poSpatialRef = NULL; psCLI->poIndex->close(FME_FALSE); poSession->destroySpatialIndex( psCLI->poIndex ); if( psCLI->pszCoordSys != NULL && !bCoordSysOverride ) { CPLDebug("FME_OLEDB", "Applying COORDSYS=%s to layer %s from feature scan.", psCLI->pszCoordSys, papoLayers[iLayer]->GetLayerDefn()->GetName() ); poSpatialRef = FME2OGRSpatialRef( psCLI->pszCoordSys ); } poLayer->AssignIndex( psCLI->pszIndFile, &(psCLI->sExtent), poSpatialRef ); if( psCLI->eBestGeomType != 500 && psCLI->eBestGeomType != poLayer->GetLayerDefn()->GetGeomType() ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -